1diff -uNr original/linux/include/linux/netfilter_ipv4/ipt_ipv4options.h linuxd/include/linux/netfilter_ipv4/ipt_ipv4options.h
2--- original/linux/include/linux/netfilter_ipv4/ipt_ipv4options.h	Thu Jan  1 07:30:00 1970
3+++ linuxd/include/linux/netfilter_ipv4/ipt_ipv4options.h	Mon Nov 19 14:49:43 2001
4@@ -0,0 +1,21 @@
5+#ifndef __ipt_ipv4options_h_included__
6+#define __ipt_ipv4options_h_included__
7+
8+#define IPT_IPV4OPTION_MATCH_SSRR		0x01  /* For strict source routing */
9+#define IPT_IPV4OPTION_MATCH_LSRR		0x02  /* For loose source routing */
10+#define IPT_IPV4OPTION_DONT_MATCH_SRR		0x04  /* any source routing */
11+#define IPT_IPV4OPTION_MATCH_RR			0x08  /* For Record route */
12+#define IPT_IPV4OPTION_DONT_MATCH_RR		0x10
13+#define IPT_IPV4OPTION_MATCH_TIMESTAMP		0x20  /* For timestamp request */
14+#define IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP	0x40
15+#define IPT_IPV4OPTION_MATCH_ROUTER_ALERT	0x80  /* For router-alert */
16+#define IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT	0x100
17+#define IPT_IPV4OPTION_MATCH_ANY_OPT		0x200 /* match packet with any option */
18+#define IPT_IPV4OPTION_DONT_MATCH_ANY_OPT	0x400 /* match packet with no option */
19+
20+struct ipt_ipv4options_info {
21+	u_int16_t options;
22+};
23+
24+
25+#endif /* __ipt_ipv4options_h_included__ */
26diff -uNr original/linux/net/ipv4/netfilter/ipt_ipv4options.c linuxd/net/ipv4/netfilter/ipt_ipv4options.c
27--- original/linux/net/ipv4/netfilter/ipt_ipv4options.c	Thu Jan  1 07:30:00 1970
28+++ linuxd/net/ipv4/netfilter/ipt_ipv4options.c	Mon Nov 19 14:51:30 2001
29@@ -0,0 +1,170 @@
30+/*
31+  This is a module which is used to match ipv4 options.
32+  This file is distributed under the terms of the GNU General Public
33+  License (GPL). Copies of the GPL can be obtained from:
34+  ftp://prep.ai.mit.edu/pub/gnu/GPL
35+
36+  11-mars-2001 Fabrice MARIE <fabrice@netfilter.org> : initial development.
37+  12-july-2001 Fabrice MARIE <fabrice@netfilter.org> : added router-alert otions matching. Fixed a bug with no-srr
38+  12-august-2001 Imran Patel <ipatel@crosswinds.net> : optimization of the match.
39+  18-november-2001 Fabrice MARIE <fabrice@netfilter.org> : added [!] 'any' option match.
40+*/
41+
42+#include <linux/module.h>
43+#include <linux/skbuff.h>
44+#include <net/ip.h>
45+
46+#include <linux/netfilter_ipv4/ip_tables.h>
47+#include <linux/netfilter_ipv4/ipt_ipv4options.h>
48+
49+MODULE_LICENSE("GPL");
50+
51+static int
52+match(const struct sk_buff *skb,
53+      const struct net_device *in,
54+      const struct net_device *out,
55+      const void *matchinfo,
56+      int offset,
57+      const void *hdr,
58+      u_int16_t datalen,
59+      int *hotdrop)
60+{
61+	const struct ipt_ipv4options_info *info = matchinfo;   /* match info for rule */
62+	const struct iphdr *iph = skb->nh.iph;
63+	const struct ip_options *opt;
64+
65+	if (iph->ihl * 4 == sizeof(struct iphdr)) {
66+		/* No options, so we match only the "DONTs" and the "IGNOREs" */
67+
68+		if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) ||
69+		    ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
70+		    ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
71+		    ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
72+		    ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
73+                    ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
74+			return 0;
75+		return 1;
76+	}
77+	else {
78+		if ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)
79+			/* there are options, and we don't need to care which one */
80+			return 1;
81+		else {
82+			if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
83+				/* there are options but we don't want any ! */
84+				return 0;
85+		}
86+	}
87+
88+	opt = &(IPCB(skb)->opt);
89+
90+	/* source routing */
91+	if ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) {
92+		if (!((opt->srr) & (opt->is_strictroute)))
93+			return 0;
94+	}
95+	else if ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) {
96+		if (!((opt->srr) & (!opt->is_strictroute)))
97+			return 0;
98+	}
99+	else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) {
100+		if (opt->srr)
101+			return 0;
102+	}
103+	/* record route */
104+	if ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) {
105+		if (!opt->rr)
106+			return 0;
107+	}
108+	else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) {
109+		if (opt->rr)
110+			return 0;
111+	}
112+	/* timestamp */
113+	if ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) {
114+		if (!opt->ts)
115+			return 0;
116+	}
117+	else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) {
118+		if (opt->ts)
119+			return 0;
120+	}
121+	/* router-alert option  */
122+	if ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) {
123+		if (!opt->router_alert)
124+			return 0;
125+	}
126+	else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) {
127+		if (opt->router_alert)
128+			return 0;
129+	}
130+
131+	/* we match ! */
132+	return 1;
133+}
134+
135+static int
136+checkentry(const char *tablename,
137+	   const struct ipt_ip *ip,
138+	   void *matchinfo,
139+	   unsigned int matchsize,
140+	   unsigned int hook_mask)
141+{
142+	const struct ipt_ipv4options_info *info = matchinfo;   /* match info for rule */
143+	/* Check the size */
144+	if (matchsize != IPT_ALIGN(sizeof(struct ipt_ipv4options_info)))
145+		return 0;
146+	/* Now check the coherence of the data ... */
147+	if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) &&
148+	    (((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) ||
149+	     ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) ||
150+	     ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) ||
151+	     ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) ||
152+	     ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)))
153+		return 0; /* opposites */
154+	if (((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) &&
155+	    (((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
156+	     ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
157+	     ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
158+	     ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
159+	     ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) ||
160+	     ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)))
161+		return 0; /* opposites */
162+	if (((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) &&
163+	    ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR))
164+		return 0; /* cannot match in the same time loose and strict source routing */
165+	if ((((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
166+	     ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR)) &&
167+	    ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR))
168+		return 0; /* opposites */
169+	if (((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) &&
170+	    ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR))
171+		return 0; /* opposites */
172+	if (((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) &&
173+	    ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
174+		return 0; /* opposites */
175+	if (((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) &&
176+	    ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
177+		return 0; /* opposites */
178+
179+	/* everything looks ok. */
180+	return 1;
181+}
182+
183+static struct ipt_match ipv4options_match
184+= { { NULL, NULL }, "ipv4options", &match, &checkentry, NULL, THIS_MODULE };
185+
186+static int __init init(void)
187+{
188+	printk("ipt_ipv4options loading\n");
189+	return ipt_register_match(&ipv4options_match);
190+}
191+
192+static void __exit fini(void)
193+{
194+	ipt_unregister_match(&ipv4options_match);
195+	printk("ipt_ipv4options unloaded\n");
196+}
197+
198+module_init(init);
199+module_exit(fini);
200