diff options
author | Masahide NAKAMURA <nakam@linux-ipv6.org> | 2007-02-07 18:12:57 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-02-08 15:39:21 -0500 |
commit | a0ca215a730b2c4d5024143e64b0d80d50858667 (patch) | |
tree | aa577de7d8032740e3340029ae35a56f79b6a61a | |
parent | e60a13e030867078f3c9fef8dca6cd8a5b883478 (diff) |
[NETFILTER]: ip6_tables: support MH match
This introduces match for Mobility Header (MH) described by Mobile IPv6
specification (RFC3775). User can specify the MH type or its range to be
matched.
Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
Signed-off-by: Yasuyuki Kozakai <kozakai@linux-ipv6.org>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/netfilter_ipv6/ip6t_mh.h | 15 | ||||
-rw-r--r-- | net/ipv6/netfilter/Kconfig | 8 | ||||
-rw-r--r-- | net/ipv6/netfilter/Makefile | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_mh.c | 108 |
4 files changed, 132 insertions, 0 deletions
diff --git a/include/linux/netfilter_ipv6/ip6t_mh.h b/include/linux/netfilter_ipv6/ip6t_mh.h new file mode 100644 index 000000000000..b9ca9a5f74d0 --- /dev/null +++ b/include/linux/netfilter_ipv6/ip6t_mh.h | |||
@@ -0,0 +1,15 @@ | |||
1 | #ifndef _IP6T_MH_H | ||
2 | #define _IP6T_MH_H | ||
3 | |||
4 | /* MH matching stuff */ | ||
5 | struct ip6t_mh | ||
6 | { | ||
7 | u_int8_t types[2]; /* MH type range */ | ||
8 | u_int8_t invflags; /* Inverse flags */ | ||
9 | }; | ||
10 | |||
11 | /* Values for "invflags" field in struct ip6t_mh. */ | ||
12 | #define IP6T_MH_INV_TYPE 0x01 /* Invert the sense of type. */ | ||
13 | #define IP6T_MH_INV_MASK 0x01 /* All possible flags. */ | ||
14 | |||
15 | #endif /*_IP6T_MH_H*/ | ||
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index adcd6131df2a..cd549aea84f0 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
@@ -114,6 +114,14 @@ config IP6_NF_MATCH_AH | |||
114 | 114 | ||
115 | To compile it as a module, choose M here. If unsure, say N. | 115 | To compile it as a module, choose M here. If unsure, say N. |
116 | 116 | ||
117 | config IP6_NF_MATCH_MH | ||
118 | tristate "MH match support" | ||
119 | depends on IP6_NF_IPTABLES | ||
120 | help | ||
121 | This module allows one to match MH packets. | ||
122 | |||
123 | To compile it as a module, choose M here. If unsure, say N. | ||
124 | |||
117 | config IP6_NF_MATCH_EUI64 | 125 | config IP6_NF_MATCH_EUI64 |
118 | tristate "EUI64 address check" | 126 | tristate "EUI64 address check" |
119 | depends on IP6_NF_IPTABLES | 127 | depends on IP6_NF_IPTABLES |
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index ac1dfebde175..4513eab77397 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile | |||
@@ -19,6 +19,7 @@ obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o | |||
19 | obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o | 19 | obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o |
20 | obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o | 20 | obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o |
21 | obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o | 21 | obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o |
22 | obj-$(CONFIG_IP6_NF_MATCH_MH) += ip6t_mh.o | ||
22 | 23 | ||
23 | # objects for l3 independent conntrack | 24 | # objects for l3 independent conntrack |
24 | nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o | 25 | nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o |
diff --git a/net/ipv6/netfilter/ip6t_mh.c b/net/ipv6/netfilter/ip6t_mh.c new file mode 100644 index 000000000000..2c7efc6a506d --- /dev/null +++ b/net/ipv6/netfilter/ip6t_mh.c | |||
@@ -0,0 +1,108 @@ | |||
1 | /* | ||
2 | * Copyright (C)2006 USAGI/WIDE Project | ||
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 | * Author: | ||
9 | * Masahide NAKAMURA @USAGI <masahide.nakamura.cz@hitachi.com> | ||
10 | * | ||
11 | * Based on net/netfilter/xt_tcpudp.c | ||
12 | * | ||
13 | */ | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <net/ip.h> | ||
17 | #include <linux/ipv6.h> | ||
18 | #include <net/ipv6.h> | ||
19 | #include <net/mip6.h> | ||
20 | |||
21 | #include <linux/netfilter/x_tables.h> | ||
22 | #include <linux/netfilter_ipv6/ip6t_mh.h> | ||
23 | |||
24 | MODULE_DESCRIPTION("ip6t_tables match for MH"); | ||
25 | MODULE_LICENSE("GPL"); | ||
26 | |||
27 | #ifdef DEBUG_IP_FIREWALL_USER | ||
28 | #define duprintf(format, args...) printk(format , ## args) | ||
29 | #else | ||
30 | #define duprintf(format, args...) | ||
31 | #endif | ||
32 | |||
33 | /* Returns 1 if the type is matched by the range, 0 otherwise */ | ||
34 | static inline int | ||
35 | type_match(u_int8_t min, u_int8_t max, u_int8_t type, int invert) | ||
36 | { | ||
37 | int ret; | ||
38 | |||
39 | ret = (type >= min && type <= max) ^ invert; | ||
40 | return ret; | ||
41 | } | ||
42 | |||
43 | static int | ||
44 | match(const struct sk_buff *skb, | ||
45 | const struct net_device *in, | ||
46 | const struct net_device *out, | ||
47 | const struct xt_match *match, | ||
48 | const void *matchinfo, | ||
49 | int offset, | ||
50 | unsigned int protoff, | ||
51 | int *hotdrop) | ||
52 | { | ||
53 | struct ip6_mh _mh, *mh; | ||
54 | const struct ip6t_mh *mhinfo = matchinfo; | ||
55 | |||
56 | /* Must not be a fragment. */ | ||
57 | if (offset) | ||
58 | return 0; | ||
59 | |||
60 | mh = skb_header_pointer(skb, protoff, sizeof(_mh), &_mh); | ||
61 | if (mh == NULL) { | ||
62 | /* We've been asked to examine this packet, and we | ||
63 | can't. Hence, no choice but to drop. */ | ||
64 | duprintf("Dropping evil MH tinygram.\n"); | ||
65 | *hotdrop = 1; | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | return type_match(mhinfo->types[0], mhinfo->types[1], mh->ip6mh_type, | ||
70 | !!(mhinfo->invflags & IP6T_MH_INV_TYPE)); | ||
71 | } | ||
72 | |||
73 | /* Called when user tries to insert an entry of this type. */ | ||
74 | static int | ||
75 | mh_checkentry(const char *tablename, | ||
76 | const void *entry, | ||
77 | const struct xt_match *match, | ||
78 | void *matchinfo, | ||
79 | unsigned int hook_mask) | ||
80 | { | ||
81 | const struct ip6t_mh *mhinfo = matchinfo; | ||
82 | |||
83 | /* Must specify no unknown invflags */ | ||
84 | return !(mhinfo->invflags & ~IP6T_MH_INV_MASK); | ||
85 | } | ||
86 | |||
87 | static struct xt_match mh_match = { | ||
88 | .name = "mh", | ||
89 | .family = AF_INET6, | ||
90 | .checkentry = mh_checkentry, | ||
91 | .match = match, | ||
92 | .matchsize = sizeof(struct ip6t_mh), | ||
93 | .proto = IPPROTO_MH, | ||
94 | .me = THIS_MODULE, | ||
95 | }; | ||
96 | |||
97 | static int __init ip6t_mh_init(void) | ||
98 | { | ||
99 | return xt_register_match(&mh_match); | ||
100 | } | ||
101 | |||
102 | static void __exit ip6t_mh_fini(void) | ||
103 | { | ||
104 | xt_unregister_match(&mh_match); | ||
105 | } | ||
106 | |||
107 | module_init(ip6t_mh_init); | ||
108 | module_exit(ip6t_mh_fini); | ||