blob: b8640f97295007166a27d31eb9db1d8e4255b766 [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 Engelhardtd3c5ee62007-12-04 23:24:03 -080024length_mt(const struct sk_buff *skb, const struct net_device *in,
25 const struct net_device *out, const struct xt_match *match,
26 const void *matchinfo, int offset, unsigned int protoff,
27 bool *hotdrop)
Harald Welte2e4e6a12006-01-12 13:30:04 -080028{
29 const struct xt_length_info *info = matchinfo;
Arnaldo Carvalho de Meloeddc9ec2007-04-20 22:47:35 -070030 u_int16_t pktlen = ntohs(ip_hdr(skb)->tot_len);
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -080031
Harald Welte2e4e6a12006-01-12 13:30:04 -080032 return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
33}
34
Jan Engelhardt1d93a9c2007-07-07 22:15:35 -070035static bool
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080036length_mt6(const struct sk_buff *skb, const struct net_device *in,
37 const struct net_device *out, const struct xt_match *match,
38 const void *matchinfo, int offset, unsigned int protoff,
39 bool *hotdrop)
Harald Welte2e4e6a12006-01-12 13:30:04 -080040{
41 const struct xt_length_info *info = matchinfo;
Jan Engelhardt7c4e36b2007-07-07 22:19:08 -070042 const u_int16_t pktlen = ntohs(ipv6_hdr(skb)->payload_len) +
43 sizeof(struct ipv6hdr);
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -080044
Harald Welte2e4e6a12006-01-12 13:30:04 -080045 return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
46}
47
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080048static struct xt_match length_mt_reg[] __read_mostly = {
Patrick McHardy4470bbc2006-08-22 00:34:04 -070049 {
50 .name = "length",
51 .family = AF_INET,
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080052 .match = length_mt,
Patrick McHardy4470bbc2006-08-22 00:34:04 -070053 .matchsize = sizeof(struct xt_length_info),
54 .me = THIS_MODULE,
55 },
56 {
57 .name = "length",
58 .family = AF_INET6,
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080059 .match = length_mt6,
Patrick McHardy4470bbc2006-08-22 00:34:04 -070060 .matchsize = sizeof(struct xt_length_info),
61 .me = THIS_MODULE,
62 },
Harald Welte2e4e6a12006-01-12 13:30:04 -080063};
64
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080065static int __init length_mt_init(void)
Harald Welte2e4e6a12006-01-12 13:30:04 -080066{
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080067 return xt_register_matches(length_mt_reg, ARRAY_SIZE(length_mt_reg));
Harald Welte2e4e6a12006-01-12 13:30:04 -080068}
69
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080070static void __exit length_mt_exit(void)
Harald Welte2e4e6a12006-01-12 13:30:04 -080071{
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080072 xt_unregister_matches(length_mt_reg, ARRAY_SIZE(length_mt_reg));
Harald Welte2e4e6a12006-01-12 13:30:04 -080073}
74
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080075module_init(length_mt_init);
76module_exit(length_mt_exit);