blob: 176e5570a9991727c8613de3bd8fe3341a852501 [file] [log] [blame]
Harald Welte2e4e6a12006-01-12 13:30:04 -08001/* Kernel module to match packet length. */
2/* (C) 1999-2001 James Morris <jmorros@intercode.com.au>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/module.h>
10#include <linux/skbuff.h>
David S. Miller37d8dc82006-01-13 16:19:44 -080011#include <linux/ipv6.h>
Harald Welte2e4e6a12006-01-12 13:30:04 -080012#include <net/ip.h>
13
14#include <linux/netfilter/xt_length.h>
15#include <linux/netfilter/x_tables.h>
16
17MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
Jan Engelhardt2ae15b62008-01-14 23:42:28 -080018MODULE_DESCRIPTION("Xtables: Packet length (Layer3,4,5) match");
Harald Welte2e4e6a12006-01-12 13:30:04 -080019MODULE_LICENSE("GPL");
20MODULE_ALIAS("ipt_length");
21MODULE_ALIAS("ip6t_length");
22
Jan Engelhardt1d93a9c2007-07-07 22:15:35 -070023static bool
Jan Engelhardt62fc8052009-07-07 20:42:08 +020024length_mt(const struct sk_buff *skb, struct xt_action_param *par)
Harald Welte2e4e6a12006-01-12 13:30:04 -080025{
Jan Engelhardtf7108a22008-10-08 11:35:18 +020026 const struct xt_length_info *info = par->matchinfo;
Arnaldo Carvalho de Meloeddc9ec2007-04-20 22:47:35 -070027 u_int16_t pktlen = ntohs(ip_hdr(skb)->tot_len);
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -080028
Harald Welte2e4e6a12006-01-12 13:30:04 -080029 return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
30}
31
Jan Engelhardt1d93a9c2007-07-07 22:15:35 -070032static bool
Jan Engelhardt62fc8052009-07-07 20:42:08 +020033length_mt6(const struct sk_buff *skb, struct xt_action_param *par)
Harald Welte2e4e6a12006-01-12 13:30:04 -080034{
Jan Engelhardtf7108a22008-10-08 11:35:18 +020035 const struct xt_length_info *info = par->matchinfo;
Jan Engelhardt7c4e36b2007-07-07 22:19:08 -070036 const u_int16_t pktlen = ntohs(ipv6_hdr(skb)->payload_len) +
37 sizeof(struct ipv6hdr);
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -080038
Harald Welte2e4e6a12006-01-12 13:30:04 -080039 return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
40}
41
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080042static struct xt_match length_mt_reg[] __read_mostly = {
Patrick McHardy4470bbc2006-08-22 00:34:04 -070043 {
44 .name = "length",
Jan Engelhardtee999d82008-10-08 11:35:01 +020045 .family = NFPROTO_IPV4,
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080046 .match = length_mt,
Patrick McHardy4470bbc2006-08-22 00:34:04 -070047 .matchsize = sizeof(struct xt_length_info),
48 .me = THIS_MODULE,
49 },
50 {
51 .name = "length",
Jan Engelhardtee999d82008-10-08 11:35:01 +020052 .family = NFPROTO_IPV6,
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080053 .match = length_mt6,
Patrick McHardy4470bbc2006-08-22 00:34:04 -070054 .matchsize = sizeof(struct xt_length_info),
55 .me = THIS_MODULE,
56 },
Harald Welte2e4e6a12006-01-12 13:30:04 -080057};
58
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080059static int __init length_mt_init(void)
Harald Welte2e4e6a12006-01-12 13:30:04 -080060{
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080061 return xt_register_matches(length_mt_reg, ARRAY_SIZE(length_mt_reg));
Harald Welte2e4e6a12006-01-12 13:30:04 -080062}
63
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080064static void __exit length_mt_exit(void)
Harald Welte2e4e6a12006-01-12 13:30:04 -080065{
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080066 xt_unregister_matches(length_mt_reg, ARRAY_SIZE(length_mt_reg));
Harald Welte2e4e6a12006-01-12 13:30:04 -080067}
68
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080069module_init(length_mt_init);
70module_exit(length_mt_exit);