]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.suse/netfilter-ipv4options
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.suse / netfilter-ipv4options
CommitLineData
2cb7cef9
BS
1From: Fabrice MARIE <fabrice@netfilter.org>
2From: Harald Welte <laforge@netfilter.org>
3Subject: netfilter ipv4options match from patch-o-matic-ng
4References: bnc#131728 - FATE#182
5
6This is a module which is used to match ipv4 options.
7
8Updated-by: Jeff Mahoney <jeffm@suse.com>
9
10Acked-by: Olaf Kirch <okir@suse.de>
11Acked-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);