1/* Kernel module to match packet length. */
2#include <linux/module.h>
3#include <linux/skbuff.h>
4
5#include <linux/netfilter_ipv4/ipt_length.h>
6#include <linux/netfilter_ipv4/ip_tables.h>
7
8MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
9MODULE_DESCRIPTION("IP tables packet length matching module");
10MODULE_LICENSE("GPL");
11
12static int
13match(const struct sk_buff *skb,
14      const struct net_device *in,
15      const struct net_device *out,
16      const void *matchinfo,
17      int offset,
18      const void *hdr,
19      u_int16_t datalen,
20      int *hotdrop)
21{
22	const struct ipt_length_info *info = matchinfo;
23	u_int16_t pktlen = ntohs(skb->nh.iph->tot_len);
24
25	return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
26}
27
28static int
29checkentry(const char *tablename,
30           const struct ipt_ip *ip,
31           void *matchinfo,
32           unsigned int matchsize,
33           unsigned int hook_mask)
34{
35	if (matchsize != IPT_ALIGN(sizeof(struct ipt_length_info)))
36		return 0;
37
38	return 1;
39}
40
41static struct ipt_match length_match
42= { { NULL, NULL }, "length", &match, &checkentry, NULL, THIS_MODULE };
43
44static int __init init(void)
45{
46	return ipt_register_match(&length_match);
47}
48
49static void __exit fini(void)
50{
51	ipt_unregister_match(&length_match);
52}
53
54module_init(init);
55module_exit(fini);
56