1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 22e4e6a17SHarald Welte /* Kernel module to match packet length. */ 32e4e6a17SHarald Welte /* (C) 1999-2001 James Morris <jmorros@intercode.com.au> 42e4e6a17SHarald Welte */ 52e4e6a17SHarald Welte 62e4e6a17SHarald Welte #include <linux/module.h> 72e4e6a17SHarald Welte #include <linux/skbuff.h> 837d8dc82SDavid S. Miller #include <linux/ipv6.h> 92e4e6a17SHarald Welte #include <net/ip.h> 102e4e6a17SHarald Welte 112e4e6a17SHarald Welte #include <linux/netfilter/xt_length.h> 122e4e6a17SHarald Welte #include <linux/netfilter/x_tables.h> 132e4e6a17SHarald Welte 142e4e6a17SHarald Welte MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); 152ae15b64SJan Engelhardt MODULE_DESCRIPTION("Xtables: Packet length (Layer3,4,5) match"); 162e4e6a17SHarald Welte MODULE_LICENSE("GPL"); 172e4e6a17SHarald Welte MODULE_ALIAS("ipt_length"); 182e4e6a17SHarald Welte MODULE_ALIAS("ip6t_length"); 192e4e6a17SHarald Welte 201d93a9cbSJan Engelhardt static bool 2162fc8051SJan Engelhardt length_mt(const struct sk_buff *skb, struct xt_action_param *par) 222e4e6a17SHarald Welte { 23f7108a20SJan Engelhardt const struct xt_length_info *info = par->matchinfo; 24eddc9ec5SArnaldo Carvalho de Melo u_int16_t pktlen = ntohs(ip_hdr(skb)->tot_len); 252e4e6a17SHarald Welte 262e4e6a17SHarald Welte return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; 272e4e6a17SHarald Welte } 282e4e6a17SHarald Welte 291d93a9cbSJan Engelhardt static bool 3062fc8051SJan Engelhardt length_mt6(const struct sk_buff *skb, struct xt_action_param *par) 312e4e6a17SHarald Welte { 32f7108a20SJan Engelhardt const struct xt_length_info *info = par->matchinfo; 337c4e36bcSJan Engelhardt const u_int16_t pktlen = ntohs(ipv6_hdr(skb)->payload_len) + 347c4e36bcSJan Engelhardt sizeof(struct ipv6hdr); 352e4e6a17SHarald Welte 362e4e6a17SHarald Welte return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; 372e4e6a17SHarald Welte } 382e4e6a17SHarald Welte 39d3c5ee6dSJan Engelhardt static struct xt_match length_mt_reg[] __read_mostly = { 404470bbc7SPatrick McHardy { 412e4e6a17SHarald Welte .name = "length", 42ee999d8bSJan Engelhardt .family = NFPROTO_IPV4, 43d3c5ee6dSJan Engelhardt .match = length_mt, 445d04bff0SPatrick McHardy .matchsize = sizeof(struct xt_length_info), 452e4e6a17SHarald Welte .me = THIS_MODULE, 464470bbc7SPatrick McHardy }, 474470bbc7SPatrick McHardy { 482e4e6a17SHarald Welte .name = "length", 49ee999d8bSJan Engelhardt .family = NFPROTO_IPV6, 50d3c5ee6dSJan Engelhardt .match = length_mt6, 515d04bff0SPatrick McHardy .matchsize = sizeof(struct xt_length_info), 522e4e6a17SHarald Welte .me = THIS_MODULE, 534470bbc7SPatrick McHardy }, 542e4e6a17SHarald Welte }; 552e4e6a17SHarald Welte 56d3c5ee6dSJan Engelhardt static int __init length_mt_init(void) 572e4e6a17SHarald Welte { 58d3c5ee6dSJan Engelhardt return xt_register_matches(length_mt_reg, ARRAY_SIZE(length_mt_reg)); 592e4e6a17SHarald Welte } 602e4e6a17SHarald Welte 61d3c5ee6dSJan Engelhardt static void __exit length_mt_exit(void) 622e4e6a17SHarald Welte { 63d3c5ee6dSJan Engelhardt xt_unregister_matches(length_mt_reg, ARRAY_SIZE(length_mt_reg)); 642e4e6a17SHarald Welte } 652e4e6a17SHarald Welte 66d3c5ee6dSJan Engelhardt module_init(length_mt_init); 67d3c5ee6dSJan Engelhardt module_exit(length_mt_exit); 68