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