12e4e6a17SHarald Welte /* Kernel module to match packet length. */ 22e4e6a17SHarald Welte /* (C) 1999-2001 James Morris <jmorros@intercode.com.au> 32e4e6a17SHarald Welte * 42e4e6a17SHarald Welte * This program is free software; you can redistribute it and/or modify 52e4e6a17SHarald Welte * it under the terms of the GNU General Public License version 2 as 62e4e6a17SHarald Welte * published by the Free Software Foundation. 72e4e6a17SHarald Welte */ 82e4e6a17SHarald Welte 92e4e6a17SHarald Welte #include <linux/module.h> 102e4e6a17SHarald Welte #include <linux/skbuff.h> 1137d8dc82SDavid S. Miller #include <linux/ipv6.h> 122e4e6a17SHarald Welte #include <net/ip.h> 132e4e6a17SHarald Welte 142e4e6a17SHarald Welte #include <linux/netfilter/xt_length.h> 152e4e6a17SHarald Welte #include <linux/netfilter/x_tables.h> 162e4e6a17SHarald Welte 172e4e6a17SHarald Welte MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); 182ae15b64SJan Engelhardt MODULE_DESCRIPTION("Xtables: Packet length (Layer3,4,5) match"); 192e4e6a17SHarald Welte MODULE_LICENSE("GPL"); 202e4e6a17SHarald Welte MODULE_ALIAS("ipt_length"); 212e4e6a17SHarald Welte MODULE_ALIAS("ip6t_length"); 222e4e6a17SHarald Welte 231d93a9cbSJan Engelhardt static bool 2462fc8051SJan Engelhardt length_mt(const struct sk_buff *skb, struct xt_action_param *par) 252e4e6a17SHarald Welte { 26f7108a20SJan Engelhardt const struct xt_length_info *info = par->matchinfo; 27eddc9ec5SArnaldo Carvalho de Melo u_int16_t pktlen = ntohs(ip_hdr(skb)->tot_len); 282e4e6a17SHarald Welte 292e4e6a17SHarald Welte return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; 302e4e6a17SHarald Welte } 312e4e6a17SHarald Welte 321d93a9cbSJan Engelhardt static bool 3362fc8051SJan Engelhardt length_mt6(const struct sk_buff *skb, struct xt_action_param *par) 342e4e6a17SHarald Welte { 35f7108a20SJan Engelhardt const struct xt_length_info *info = par->matchinfo; 367c4e36bcSJan Engelhardt const u_int16_t pktlen = ntohs(ipv6_hdr(skb)->payload_len) + 377c4e36bcSJan Engelhardt sizeof(struct ipv6hdr); 382e4e6a17SHarald Welte 392e4e6a17SHarald Welte return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; 402e4e6a17SHarald Welte } 412e4e6a17SHarald Welte 42d3c5ee6dSJan Engelhardt static struct xt_match length_mt_reg[] __read_mostly = { 434470bbc7SPatrick McHardy { 442e4e6a17SHarald Welte .name = "length", 45ee999d8bSJan Engelhardt .family = NFPROTO_IPV4, 46d3c5ee6dSJan Engelhardt .match = length_mt, 475d04bff0SPatrick McHardy .matchsize = sizeof(struct xt_length_info), 482e4e6a17SHarald Welte .me = THIS_MODULE, 494470bbc7SPatrick McHardy }, 504470bbc7SPatrick McHardy { 512e4e6a17SHarald Welte .name = "length", 52ee999d8bSJan Engelhardt .family = NFPROTO_IPV6, 53d3c5ee6dSJan Engelhardt .match = length_mt6, 545d04bff0SPatrick McHardy .matchsize = sizeof(struct xt_length_info), 552e4e6a17SHarald Welte .me = THIS_MODULE, 564470bbc7SPatrick McHardy }, 572e4e6a17SHarald Welte }; 582e4e6a17SHarald Welte 59d3c5ee6dSJan Engelhardt static int __init length_mt_init(void) 602e4e6a17SHarald Welte { 61d3c5ee6dSJan Engelhardt return xt_register_matches(length_mt_reg, ARRAY_SIZE(length_mt_reg)); 622e4e6a17SHarald Welte } 632e4e6a17SHarald Welte 64d3c5ee6dSJan Engelhardt static void __exit length_mt_exit(void) 652e4e6a17SHarald Welte { 66d3c5ee6dSJan Engelhardt xt_unregister_matches(length_mt_reg, ARRAY_SIZE(length_mt_reg)); 672e4e6a17SHarald Welte } 682e4e6a17SHarald Welte 69d3c5ee6dSJan Engelhardt module_init(length_mt_init); 70d3c5ee6dSJan Engelhardt module_exit(length_mt_exit); 71