]>
Commit | Line | Data |
---|---|---|
85847b80 | 1 | include/linux/netfilter_ipv4/ipt_ipv4options.h | 21 ++ |
2 | net/ipv4/netfilter/Kconfig | 13 + | |
3 | net/ipv4/netfilter/Makefile | 1 | |
4 | net/ipv4/netfilter/ipt_ipv4options.c | 176 +++++++++++++++++++++++++ | |
5 | 4 files changed, 211 insertions(+) | |
6 | ||
7 | diff -Nur --exclude '*.orig' linux.org/include/linux/netfilter_ipv4/ipt_ipv4options.h linux/include/linux/netfilter_ipv4/ipt_ipv4options.h | |
8 | --- linux.org/include/linux/netfilter_ipv4/ipt_ipv4options.h 1970-01-01 00:00:00.000000000 +0000 | |
9 | +++ linux/include/linux/netfilter_ipv4/ipt_ipv4options.h 2006-08-29 12:07:39.000000000 +0000 | |
10 | @@ -0,0 +1,21 @@ | |
11 | +#ifndef __ipt_ipv4options_h_included__ | |
12 | +#define __ipt_ipv4options_h_included__ | |
13 | + | |
14 | +#define IPT_IPV4OPTION_MATCH_SSRR 0x01 /* For strict source routing */ | |
15 | +#define IPT_IPV4OPTION_MATCH_LSRR 0x02 /* For loose source routing */ | |
16 | +#define IPT_IPV4OPTION_DONT_MATCH_SRR 0x04 /* any source routing */ | |
17 | +#define IPT_IPV4OPTION_MATCH_RR 0x08 /* For Record route */ | |
18 | +#define IPT_IPV4OPTION_DONT_MATCH_RR 0x10 | |
19 | +#define IPT_IPV4OPTION_MATCH_TIMESTAMP 0x20 /* For timestamp request */ | |
20 | +#define IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP 0x40 | |
21 | +#define IPT_IPV4OPTION_MATCH_ROUTER_ALERT 0x80 /* For router-alert */ | |
22 | +#define IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT 0x100 | |
23 | +#define IPT_IPV4OPTION_MATCH_ANY_OPT 0x200 /* match packet with any option */ | |
24 | +#define IPT_IPV4OPTION_DONT_MATCH_ANY_OPT 0x400 /* match packet with no option */ | |
25 | + | |
26 | +struct ipt_ipv4options_info { | |
27 | + u_int16_t options; | |
28 | +}; | |
29 | + | |
30 | + | |
31 | +#endif /* __ipt_ipv4options_h_included__ */ | |
32 | diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/ipt_ipv4options.c linux/net/ipv4/netfilter/ipt_ipv4options.c | |
33 | --- linux.org/net/ipv4/netfilter/ipt_ipv4options.c 1970-01-01 00:00:00.000000000 +0000 | |
34 | +++ linux/net/ipv4/netfilter/ipt_ipv4options.c 2006-08-29 12:07:39.000000000 +0000 | |
35 | @@ -0,0 +1,176 @@ | |
36 | +/* | |
37 | + This is a module which is used to match ipv4 options. | |
38 | + This file is distributed under the terms of the GNU General Public | |
39 | + License (GPL). Copies of the GPL can be obtained from: | |
40 | + ftp://prep.ai.mit.edu/pub/gnu/GPL | |
41 | + | |
42 | + 11-mars-2001 Fabrice MARIE <fabrice@netfilter.org> : initial development. | |
43 | + 12-july-2001 Fabrice MARIE <fabrice@netfilter.org> : added router-alert otions matching. Fixed a bug with no-srr | |
44 | + 12-august-2001 Imran Patel <ipatel@crosswinds.net> : optimization of the match. | |
45 | + 18-november-2001 Fabrice MARIE <fabrice@netfilter.org> : added [!] 'any' option match. | |
46 | + 19-february-2004 Harald Welte <laforge@netfilter.org> : merge with 2.6.x | |
47 | +*/ | |
48 | + | |
49 | +#include <linux/module.h> | |
50 | +#include <linux/skbuff.h> | |
51 | +#include <net/ip.h> | |
52 | + | |
53 | +#include <linux/netfilter_ipv4/ip_tables.h> | |
54 | +#include <linux/netfilter_ipv4/ipt_ipv4options.h> | |
55 | + | |
56 | +MODULE_LICENSE("GPL"); | |
57 | +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>"); | |
58 | + | |
59 | +static int | |
60 | +match(const struct sk_buff *skb, | |
61 | + const struct net_device *in, | |
62 | + const struct net_device *out, | |
63 | + const struct xt_match *match, | |
64 | + const void *matchinfo, | |
65 | + int offset, | |
66 | + unsigned int protoff, | |
67 | + int *hotdrop) | |
68 | +{ | |
69 | + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */ | |
70 | + const struct iphdr *iph = skb->nh.iph; | |
71 | + const struct ip_options *opt; | |
72 | + | |
73 | + if (iph->ihl * 4 == sizeof(struct iphdr)) { | |
74 | + /* No options, so we match only the "DONTs" and the "IGNOREs" */ | |
75 | + | |
76 | + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) || | |
77 | + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) || | |
78 | + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) || | |
79 | + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) || | |
80 | + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) || | |
81 | + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT)) | |
82 | + return 0; | |
83 | + return 1; | |
84 | + } | |
85 | + else { | |
86 | + if ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) | |
87 | + /* there are options, and we don't need to care which one */ | |
88 | + return 1; | |
89 | + else { | |
90 | + if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) | |
91 | + /* there are options but we don't want any ! */ | |
92 | + return 0; | |
93 | + } | |
94 | + } | |
95 | + | |
96 | + opt = &(IPCB(skb)->opt); | |
97 | + | |
98 | + /* source routing */ | |
99 | + if ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) { | |
100 | + if (!((opt->srr) && (opt->is_strictroute))) | |
101 | + return 0; | |
102 | + } | |
103 | + else if ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) { | |
104 | + if (!((opt->srr) && (!opt->is_strictroute))) | |
105 | + return 0; | |
106 | + } | |
107 | + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) { | |
108 | + if (opt->srr) | |
109 | + return 0; | |
110 | + } | |
111 | + /* record route */ | |
112 | + if ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) { | |
113 | + if (!opt->rr) | |
114 | + return 0; | |
115 | + } | |
116 | + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) { | |
117 | + if (opt->rr) | |
118 | + return 0; | |
119 | + } | |
120 | + /* timestamp */ | |
121 | + if ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) { | |
122 | + if (!opt->ts) | |
123 | + return 0; | |
124 | + } | |
125 | + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) { | |
126 | + if (opt->ts) | |
127 | + return 0; | |
128 | + } | |
129 | + /* router-alert option */ | |
130 | + if ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) { | |
131 | + if (!opt->router_alert) | |
132 | + return 0; | |
133 | + } | |
134 | + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) { | |
135 | + if (opt->router_alert) | |
136 | + return 0; | |
137 | + } | |
138 | + | |
139 | + /* we match ! */ | |
140 | + return 1; | |
141 | +} | |
142 | + | |
143 | +static int | |
144 | +checkentry(const char *tablename, | |
145 | + const void *ip, | |
146 | + const struct xt_match *match, | |
147 | + void *matchinfo, | |
148 | + unsigned int matchsize, | |
149 | + unsigned int hook_mask) | |
150 | +{ | |
151 | + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */ | |
152 | + /* Check the size */ | |
153 | + if (matchsize != IPT_ALIGN(sizeof(struct ipt_ipv4options_info))) | |
154 | + return 0; | |
155 | + /* Now check the coherence of the data ... */ | |
156 | + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) && | |
157 | + (((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) || | |
158 | + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) || | |
159 | + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) || | |
160 | + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) || | |
161 | + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT))) | |
162 | + return 0; /* opposites */ | |
163 | + if (((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) && | |
164 | + (((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) || | |
165 | + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) || | |
166 | + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) || | |
167 | + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) || | |
168 | + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) || | |
169 | + ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT))) | |
170 | + return 0; /* opposites */ | |
171 | + if (((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) && | |
172 | + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR)) | |
173 | + return 0; /* cannot match in the same time loose and strict source routing */ | |
174 | + if ((((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) || | |
175 | + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR)) && | |
176 | + ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR)) | |
177 | + return 0; /* opposites */ | |
178 | + if (((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) && | |
179 | + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR)) | |
180 | + return 0; /* opposites */ | |
181 | + if (((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) && | |
182 | + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)) | |
183 | + return 0; /* opposites */ | |
184 | + if (((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) && | |
185 | + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)) | |
186 | + return 0; /* opposites */ | |
187 | + | |
188 | + /* everything looks ok. */ | |
189 | + return 1; | |
190 | +} | |
191 | + | |
192 | +static struct ipt_match ipv4options_match = { | |
193 | + .name = "ipv4options", | |
194 | + .match = match, | |
195 | + .matchsize = sizeof(struct ipt_ipv4options_info), | |
196 | + .checkentry = checkentry, | |
197 | + .me = THIS_MODULE | |
198 | +}; | |
199 | + | |
200 | +static int __init init(void) | |
201 | +{ | |
202 | + return ipt_register_match(&ipv4options_match); | |
203 | +} | |
204 | + | |
205 | +static void __exit fini(void) | |
206 | +{ | |
207 | + ipt_unregister_match(&ipv4options_match); | |
208 | +} | |
209 | + | |
210 | +module_init(init); | |
211 | +module_exit(fini); | |
212 | diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/Kconfig linux/net/ipv4/netfilter/Kconfig | |
213 | --- linux.org/net/ipv4/netfilter/Kconfig 2006-06-18 01:49:35.000000000 +0000 | |
214 | +++ linux/net/ipv4/netfilter/Kconfig 2006-08-29 12:07:39.000000000 +0000 | |
215 | @@ -613,5 +613,18 @@ | |
216 | Allows altering the ARP packet payload: source and destination | |
217 | hardware and network addresses. | |
218 | ||
219 | +config IP_NF_MATCH_IPV4OPTIONS | |
220 | + tristate 'IPV4OPTIONS match support' | |
221 | + depends on IP_NF_IPTABLES | |
222 | + help | |
223 | + This option adds a IPV4OPTIONS match. | |
224 | + It allows you to filter options like source routing, | |
225 | + record route, timestamp and router-altert. | |
226 | + | |
227 | + If you say Y here, try iptables -m ipv4options --help for more information. | |
228 | + | |
229 | + If you want to compile it as a module, say M here and read | |
230 | + Documentation/modules.txt. If unsure, say `N'. | |
231 | + | |
232 | endmenu | |
233 | ||
234 | diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/Makefile linux/net/ipv4/netfilter/Makefile | |
235 | --- linux.org/net/ipv4/netfilter/Makefile 2006-06-18 01:49:35.000000000 +0000 | |
236 | +++ linux/net/ipv4/netfilter/Makefile 2006-08-29 12:07:39.000000000 +0000 | |
237 | @@ -0,0 +0,1 @@ | |
238 | +obj-$(CONFIG_IP_NF_MATCH_IPV4OPTIONS) += ipt_ipv4options.o |