]> git.pld-linux.org Git - packages/kernel.git/blame - 2.6.6-rc1-patch-o-matic-ng-extra-20040419.patch
- update for cset 20040707_...
[packages/kernel.git] / 2.6.6-rc1-patch-o-matic-ng-extra-20040419.patch
CommitLineData
69326011 1diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ip_conntrack.h
2--- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ip_conntrack.h 2004-04-19 10:38:50.000000000 +0200
3+++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ip_conntrack.h 2004-04-19 10:44:16.000000000 +0200
4@@ -207,6 +207,10 @@
5 } nat;
6 #endif /* CONFIG_IP_NF_NAT_NEEDED */
7
8+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
9+ unsigned long mark;
10+#endif
11+
12 };
13
14 /* get master conntrack via master expectation */
15diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ip_conntrack_tuple.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
16--- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ip_conntrack_tuple.h 2004-04-15 03:35:20.000000000 +0200
17+++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ip_conntrack_tuple.h 2004-04-19 10:46:18.000000000 +0200
18@@ -25,6 +25,9 @@
19 struct {
20 u_int16_t id;
21 } icmp;
22+ struct {
23+ u_int16_t port;
24+ } sctp;
25 };
26
27 /* The manipulable part of the tuple. */
28@@ -55,6 +58,9 @@
29 struct {
30 u_int8_t type, code;
31 } icmp;
32+ struct {
33+ u_int16_t port;
34+ } sctp;
35 } u;
36
37 /* The protocol. */
38diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_CONNMARK.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_CONNMARK.h
39--- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_CONNMARK.h 1970-01-01 01:00:00.000000000 +0100
40+++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_CONNMARK.h 2004-04-19 10:44:16.000000000 +0200
41@@ -0,0 +1,25 @@
42+#ifndef _IPT_CONNMARK_H_target
43+#define _IPT_CONNMARK_H_target
44+
45+/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
46+ * by Henrik Nordstrom <hno@marasystems.com>
47+ *
48+ * This program is free software; you can redistribute it and/or modify
49+ * it under the terms of the GNU General Public License as published by
50+ * the Free Software Foundation; either version 2 of the License, or
51+ * (at your option) any later version.
52+ */
53+
54+enum {
55+ IPT_CONNMARK_SET = 0,
56+ IPT_CONNMARK_SAVE,
57+ IPT_CONNMARK_RESTORE
58+};
59+
60+struct ipt_connmark_target_info {
61+ unsigned long mark;
62+ unsigned long mask;
63+ u_int8_t mode;
64+};
65+
66+#endif /*_IPT_CONNMARK_H_target*/
67diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_IPMARK.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_IPMARK.h
68--- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_IPMARK.h 1970-01-01 01:00:00.000000000 +0100
69+++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_IPMARK.h 2004-04-19 10:44:26.000000000 +0200
70@@ -0,0 +1,13 @@
71+#ifndef _IPT_IPMARK_H_target
72+#define _IPT_IPMARK_H_target
73+
74+struct ipt_ipmark_target_info {
75+ unsigned long andmask;
76+ unsigned long ormask;
77+ unsigned int addr;
78+};
79+
80+#define IPT_IPMARK_SRC 0
81+#define IPT_IPMARK_DST 1
82+
83+#endif /*_IPT_IPMARK_H_target*/
84diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_XOR.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_XOR.h
85--- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_XOR.h 1970-01-01 01:00:00.000000000 +0100
86+++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_XOR.h 2004-04-19 10:44:34.000000000 +0200
87@@ -0,0 +1,9 @@
88+#ifndef _IPT_XOR_H
89+#define _IPT_XOR_H
90+
91+struct ipt_XOR_info {
92+ char key[30];
93+ u_int8_t block_size;
94+};
95+
96+#endif /* _IPT_XOR_H */
97diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_addrtype.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_addrtype.h
98--- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_addrtype.h 1970-01-01 01:00:00.000000000 +0100
99+++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_addrtype.h 2004-04-19 10:44:36.000000000 +0200
100@@ -0,0 +1,11 @@
101+#ifndef _IPT_ADDRTYPE_H
102+#define _IPT_ADDRTYPE_H
103+
104+struct ipt_addrtype_info {
105+ u_int16_t source; /* source-type mask */
106+ u_int16_t dest; /* dest-type mask */
107+ int invert_source;
108+ int invert_dest;
109+};
110+
111+#endif
112diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_connmark.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_connmark.h
113--- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_connmark.h 1970-01-01 01:00:00.000000000 +0100
114+++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_connmark.h 2004-04-19 10:44:16.000000000 +0200
115@@ -0,0 +1,18 @@
116+#ifndef _IPT_CONNMARK_H
117+#define _IPT_CONNMARK_H
118+
119+/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
120+ * by Henrik Nordstrom <hno@marasystems.com>
121+ *
122+ * This program is free software; you can redistribute it and/or modify
123+ * it under the terms of the GNU General Public License as published by
124+ * the Free Software Foundation; either version 2 of the License, or
125+ * (at your option) any later version.
126+ */
127+
128+struct ipt_connmark_info {
129+ unsigned long mark, mask;
130+ u_int8_t invert;
131+};
132+
133+#endif /*_IPT_CONNMARK_H*/
134diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_policy.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_policy.h
135--- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_policy.h 1970-01-01 01:00:00.000000000 +0100
136+++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_policy.h 2004-04-19 10:46:16.000000000 +0200
137@@ -0,0 +1,52 @@
138+#ifndef _IPT_POLICY_H
139+#define _IPT_POLICY_H
140+
141+#define POLICY_MAX_ELEM 4
142+
143+enum ipt_policy_flags
144+{
145+ POLICY_MATCH_IN = 0x1,
146+ POLICY_MATCH_OUT = 0x2,
147+ POLICY_MATCH_NONE = 0x4,
148+ POLICY_MATCH_STRICT = 0x8,
149+};
150+
151+enum ipt_policy_modes
152+{
153+ POLICY_MODE_TRANSPORT,
154+ POLICY_MODE_TUNNEL
155+};
156+
157+struct ipt_policy_spec
158+{
159+ u_int8_t saddr:1,
160+ daddr:1,
161+ proto:1,
162+ mode:1,
163+ spi:1,
164+ reqid:1;
165+};
166+
167+struct ipt_policy_elem
168+{
169+ u_int32_t saddr;
170+ u_int32_t smask;
171+ u_int32_t daddr;
172+ u_int32_t dmask;
173+ u_int32_t spi;
174+ u_int32_t reqid;
175+ u_int8_t proto;
176+ u_int8_t mode;
177+
178+ struct ipt_policy_spec match;
179+ struct ipt_policy_spec invert;
180+};
181+
182+struct ipt_policy_info
183+{
184+ struct ipt_policy_elem pol[POLICY_MAX_ELEM];
185+ u_int16_t flags;
186+ u_int16_t len;
187+};
188+
189+#endif /* _IPT_POLICY_H */
190diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_string.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_string.h
191--- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_string.h 1970-01-01 01:00:00.000000000 +0100
192+++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_string.h 2004-04-19 10:47:23.000000000 +0200
193@@ -0,0 +1,21 @@
194+#ifndef _IPT_STRING_H
195+#define _IPT_STRING_H
196+
197+/* *** PERFORMANCE TWEAK ***
198+ * Packet size and search string threshold,
199+ * above which sublinear searches is used. */
200+#define IPT_STRING_HAYSTACK_THRESH 100
201+#define IPT_STRING_NEEDLE_THRESH 20
202+
203+#define BM_MAX_NLEN 256
204+#define BM_MAX_HLEN 1024
205+
206+typedef char *(*proc_ipt_search) (char *, char *, int, int);
207+
208+struct ipt_string_info {
209+ char string[BM_MAX_NLEN];
210+ u_int16_t invert;
211+ u_int16_t len;
212+};
213+
214+#endif /* _IPT_STRING_H */
215diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/net/tcp.h linux-2.6.6-rc1/include/net/tcp.h
216--- linux-2.6.6-rc1.org/include/net/tcp.h 2004-04-15 03:33:55.000000000 +0200
217+++ linux-2.6.6-rc1/include/net/tcp.h 2004-04-19 10:46:08.000000000 +0200
218@@ -162,6 +162,7 @@
219 extern void tcp_bucket_unlock(struct sock *sk);
220 extern int tcp_port_rover;
221 extern struct sock *tcp_v4_lookup_listener(u32 addr, unsigned short hnum, int dif);
222+extern struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 hnum, int dif);
223
224 /* These are AF independent. */
225 static __inline__ int tcp_bhashfn(__u16 lport)
226diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/net/udp.h linux-2.6.6-rc1/include/net/udp.h
227--- linux-2.6.6-rc1.org/include/net/udp.h 2004-04-15 03:35:20.000000000 +0200
228+++ linux-2.6.6-rc1/include/net/udp.h 2004-04-19 10:46:08.000000000 +0200
229@@ -74,6 +74,8 @@
230 extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
231 extern int udp_disconnect(struct sock *sk, int flags);
232
233+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
234+
235 DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
236 #define UDP_INC_STATS(field) SNMP_INC_STATS(udp_statistics, field)
237 #define UDP_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_statistics, field)
238diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/linux-2.6.4/net/ipv4/netfilter/ipt_unclean.c linux-2.6.6-rc1/linux-2.6.4/net/ipv4/netfilter/ipt_unclean.c
239--- linux-2.6.6-rc1.org/linux-2.6.4/net/ipv4/netfilter/ipt_unclean.c 1970-01-01 01:00:00.000000000 +0100
240+++ linux-2.6.6-rc1/linux-2.6.4/net/ipv4/netfilter/ipt_unclean.c 2004-04-19 10:47:06.000000000 +0200
241@@ -0,0 +1,604 @@
242+/* Kernel module to match suspect packets. */
243+#include <linux/module.h>
244+#include <linux/skbuff.h>
245+#include <linux/ip.h>
246+#include <linux/udp.h>
247+#include <linux/tcp.h>
248+#include <linux/icmp.h>
249+#include <net/checksum.h>
250+
251+#include <linux/netfilter_ipv4/ip_tables.h>
252+
253+#define limpk(format, args...) \
254+do { \
255+ if (net_ratelimit()) \
256+ printk("ipt_unclean: %s" format, \
257+ embedded ? "(embedded packet) " : "" , ## args); \
258+} while(0)
259+
260+enum icmp_error_status
261+{
262+ ICMP_MAY_BE_ERROR,
263+ ICMP_IS_ERROR,
264+ ICMP_NOT_ERROR
265+};
266+
267+struct icmp_info
268+{
269+ size_t min_len, max_len;
270+ enum icmp_error_status err;
271+ u_int8_t min_code, max_code;
272+};
273+
274+static int
275+check_ip(struct iphdr *iph, size_t length, int embedded);
276+
277+/* ICMP-specific checks. */
278+static int
279+check_icmp(const struct icmphdr *icmph,
280+ u_int16_t datalen,
281+ unsigned int offset,
282+ int more_frags,
283+ int embedded)
284+{
285+ static struct icmp_info info[]
286+ = { [ICMP_ECHOREPLY]
287+ = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
288+ [ICMP_DEST_UNREACH]
289+ = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 15 },
290+ [ICMP_SOURCE_QUENCH]
291+ = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 0 },
292+ [ICMP_REDIRECT]
293+ = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 3 },
294+ [ICMP_ECHO]
295+ = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
296+ /* Router advertisement. */
297+ [9]
298+ = { 8, 8 + 255 * 8, ICMP_NOT_ERROR, 0, 0 },
299+ /* Router solicitation. */
300+ [10]
301+ = { 8, 8, ICMP_NOT_ERROR, 0, 0 },
302+ [ICMP_TIME_EXCEEDED]
303+ = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 1 },
304+ [ICMP_PARAMETERPROB]
305+ = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 1 },
306+ [ICMP_TIMESTAMP]
307+ = { 20, 20, ICMP_NOT_ERROR, 0, 0 },
308+ [ICMP_TIMESTAMPREPLY]
309+ = { 20, 20, ICMP_NOT_ERROR, 0, 0 },
310+ [ICMP_INFO_REQUEST]
311+ = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
312+ [ICMP_INFO_REPLY]
313+ = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
314+ [ICMP_ADDRESS]
315+ = { 12, 12, ICMP_NOT_ERROR, 0, 0 },
316+ [ICMP_ADDRESSREPLY]
317+ = { 12, 12, ICMP_NOT_ERROR, 0, 0 } };
318+
319+ /* Can't do anything if it's a fragment. */
320+ if (offset)
321+ return 1;
322+
323+ /* Must cover type and code. */
324+ if (datalen < 2) {
325+ limpk("ICMP len=%u too short\n", datalen);
326+ return 0;
327+ }
328+
329+ /* If not embedded. */
330+ if (!embedded) {
331+ /* Bad checksum? Don't print, just ignore. */
332+ if (!more_frags
333+ && ip_compute_csum((unsigned char *) icmph, datalen) != 0)
334+ return 0;
335+
336+ /* CHECK: Truncated ICMP (even if first fragment). */
337+ if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
338+ && info[icmph->type].min_len != 0
339+ && datalen < info[icmph->type].min_len) {
340+ limpk("ICMP type %u len %u too short\n",
341+ icmph->type, datalen);
342+ return 0;
343+ }
344+
345+ /* CHECK: Check within known error ICMPs. */
346+ if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
347+ && info[icmph->type].err == ICMP_IS_ERROR) {
348+ /* CHECK: Embedded packet must be at least
349+ length of iph + 8 bytes. */
350+ struct iphdr *inner = (void *)icmph + 8;
351+
352+ /* datalen > 8 since all ICMP_IS_ERROR types
353+ have min length > 8 */
354+ if (datalen - 8 < sizeof(struct iphdr)) {
355+ limpk("ICMP error internal way too short\n");
356+ return 0;
357+ }
358+ if (datalen - 8 < inner->ihl*4 + 8) {
359+ limpk("ICMP error internal too short\n");
360+ return 0;
361+ }
362+ if (!check_ip(inner, datalen - 8, 1))
363+ return 0;
364+ }
365+ } else {
366+ /* CHECK: Can't embed ICMP unless known non-error. */
367+ if (icmph->type >= sizeof(info)/sizeof(struct icmp_info)
368+ || info[icmph->type].err != ICMP_NOT_ERROR) {
369+ limpk("ICMP type %u not embeddable\n",
370+ icmph->type);
371+ return 0;
372+ }
373+ }
374+
375+ /* CHECK: Invalid ICMP codes. */
376+ if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
377+ && (icmph->code < info[icmph->type].min_code
378+ || icmph->code > info[icmph->type].max_code)) {
379+ limpk("ICMP type=%u code=%u\n",
380+ icmph->type, icmph->code);
381+ return 0;
382+ }
383+
384+ /* CHECK: Above maximum length. */
385+ if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
386+ && info[icmph->type].max_len != 0
387+ && datalen > info[icmph->type].max_len) {
388+ limpk("ICMP type=%u too long: %u bytes\n",
389+ icmph->type, datalen);
390+ return 0;
391+ }
392+
393+ switch (icmph->type) {
394+ case ICMP_PARAMETERPROB: {
395+ /* CHECK: Problem param must be within error packet's
396+ * IP header. */
397+ struct iphdr *iph = (void *)icmph + 8;
398+ u_int32_t arg = ntohl(icmph->un.gateway);
399+
400+ if (icmph->code == 0) {
401+ /* Code 0 means that upper 8 bits is pointer
402+ to problem. */
403+ if ((arg >> 24) >= iph->ihl*4) {
404+ limpk("ICMP PARAMETERPROB ptr = %u\n",
405+ ntohl(icmph->un.gateway) >> 24);
406+ return 0;
407+ }
408+ arg &= 0x00FFFFFF;
409+ }
410+
411+ /* CHECK: Rest must be zero. */
412+ if (arg) {
413+ limpk("ICMP PARAMETERPROB nonzero arg = %u\n",
414+ arg);
415+ return 0;
416+ }
417+ break;
418+ }
419+
420+ case ICMP_TIME_EXCEEDED:
421+ case ICMP_SOURCE_QUENCH:
422+ /* CHECK: Unused must be zero. */
423+ if (icmph->un.gateway != 0) {
424+ limpk("ICMP type=%u unused = %u\n",
425+ icmph->type, ntohl(icmph->un.gateway));
426+ return 0;
427+ }
428+ break;
429+ }
430+
431+ return 1;
432+}
433+
434+/* UDP-specific checks. */
435+static int
436+check_udp(const struct iphdr *iph,
437+ const struct udphdr *udph,
438+ u_int16_t datalen,
439+ unsigned int offset,
440+ int more_frags,
441+ int embedded)
442+{
443+ /* Can't do anything if it's a fragment. */
444+ if (offset)
445+ return 1;
446+
447+ /* CHECK: Must cover UDP header. */
448+ if (datalen < sizeof(struct udphdr)) {
449+ limpk("UDP len=%u too short\n", datalen);
450+ return 0;
451+ }
452+
453+ /* Bad checksum? Don't print, just say it's unclean. */
454+ /* FIXME: SRC ROUTE packets won't match checksum --RR */
455+ if (!more_frags && !embedded && udph->check
456+ && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_UDP,
457+ csum_partial((char *)udph, datalen, 0)) != 0)
458+ return 0;
459+
460+ /* CHECK: Destination port can't be zero. */
461+ if (!udph->dest) {
462+ limpk("UDP zero destination port\n");
463+ return 0;
464+ }
465+
466+ if (!more_frags) {
467+ if (!embedded) {
468+ /* CHECK: UDP length must match. */
469+ if (ntohs(udph->len) != datalen) {
470+ limpk("UDP len too short %u vs %u\n",
471+ ntohs(udph->len), datalen);
472+ return 0;
473+ }
474+ } else {
475+ /* CHECK: UDP length be >= this truncated pkt. */
476+ if (ntohs(udph->len) < datalen) {
477+ limpk("UDP len too long %u vs %u\n",
478+ ntohs(udph->len), datalen);
479+ return 0;
480+ }
481+ }
482+ } else {
483+ /* CHECK: UDP length must be > this frag's length. */
484+ if (ntohs(udph->len) <= datalen) {
485+ limpk("UDP fragment len too short %u vs %u\n",
486+ ntohs(udph->len), datalen);
487+ return 0;
488+ }
489+ }
490+
491+ return 1;
492+}
493+
494+#define TH_FIN 0x01
495+#define TH_SYN 0x02
496+#define TH_RST 0x04
497+#define TH_PUSH 0x08
498+#define TH_ACK 0x10
499+#define TH_URG 0x20
500+#define TH_ECE 0x40
501+#define TH_CWR 0x80
502+
503+/* table of valid flag combinations - ECE and CWR are always valid */
504+static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
505+{
506+ [TH_SYN] = 1,
507+ [TH_SYN|TH_ACK] = 1,
508+ [TH_RST] = 1,
509+ [TH_RST|TH_ACK] = 1,
510+ [TH_RST|TH_ACK|TH_PUSH] = 1,
511+ [TH_FIN|TH_ACK] = 1,
512+ [TH_ACK] = 1,
513+ [TH_ACK|TH_PUSH] = 1,
514+ [TH_ACK|TH_URG] = 1,
515+ [TH_ACK|TH_URG|TH_PUSH] = 1,
516+ [TH_FIN|TH_ACK|TH_PUSH] = 1,
517+ [TH_FIN|TH_ACK|TH_URG] = 1,
518+ [TH_FIN|TH_ACK|TH_URG|TH_PUSH] = 1
519+};
520+
521+/* TCP-specific checks. */
522+static int
523+check_tcp(const struct iphdr *iph,
524+ const struct tcphdr *tcph,
525+ u_int16_t datalen,
526+ unsigned int offset,
527+ int more_frags,
528+ int embedded)
529+{
530+ u_int8_t *opt = (u_int8_t *)tcph;
531+ u_int8_t *endhdr = (u_int8_t *)tcph + tcph->doff * 4;
532+ u_int8_t tcpflags;
533+ int end_of_options = 0;
534+ size_t i;
535+
536+ /* CHECK: Can't have offset=1: used to override TCP syn-checks. */
537+ /* In fact, this is caught below (offset < 516). */
538+
539+ /* Can't do anything if it's a fragment. */
540+ if (offset)
541+ return 1;
542+
543+ /* CHECK: Smaller than minimal TCP hdr. */
544+ if (datalen < sizeof(struct tcphdr)) {
545+ if (!embedded) {
546+ limpk("Packet length %u < TCP header.\n", datalen);
547+ return 0;
548+ }
549+ /* Must have ports available (datalen >= 8), from
550+ check_icmp which set embedded = 1 */
551+ /* CHECK: TCP ports inside ICMP error */
552+ if (!tcph->source || !tcph->dest) {
553+ limpk("Zero TCP ports %u/%u.\n",
554+ htons(tcph->source), htons(tcph->dest));
555+ return 0;
556+ }
557+ return 1;
558+ }
559+
560+ /* CHECK: Smaller than actual TCP hdr. */
561+ if (datalen < tcph->doff * 4) {
562+ if (!embedded) {
563+ limpk("Packet length %u < actual TCP header.\n",
564+ datalen);
565+ return 0;
566+ } else
567+ return 1;
568+ }
569+
570+ /* Bad checksum? Don't print, just say it's unclean. */
571+ /* FIXME: SRC ROUTE packets won't match checksum --RR */
572+ if (!more_frags && !embedded
573+ && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_TCP,
574+ csum_partial((char *)tcph, datalen, 0)) != 0)
575+ return 0;
576+
577+ /* CHECK: TCP ports non-zero */
578+ if (!tcph->source || !tcph->dest) {
579+ limpk("Zero TCP ports %u/%u.\n",
580+ htons(tcph->source), htons(tcph->dest));
581+ return 0;
582+ }
583+
584+ /* CHECK: TCP reserved bits zero. */
585+ if(tcp_flag_word(tcph) & TCP_RESERVED_BITS) {
586+ limpk("TCP reserved bits not zero\n");
587+ return 0;
588+ }
589+
590+ /* CHECK: TCP flags. */
591+ tcpflags = (((u_int8_t *)tcph)[13] & ~(TH_ECE|TH_CWR));
592+ if (!tcp_valid_flags[tcpflags]) {
593+ limpk("TCP flags bad: %u\n", tcpflags);
594+ return 0;
595+ }
596+
597+ for (i = sizeof(struct tcphdr); i < tcph->doff * 4; ) {
598+ switch (opt[i]) {
599+ case 0:
600+ end_of_options = 1;
601+ i++;
602+ break;
603+ case 1:
604+ i++;
605+ break;
606+ default:
607+ /* CHECK: options after EOO. */
608+ if (end_of_options) {
609+ limpk("TCP option %u after end\n",
610+ opt[i]);
611+ return 0;
612+ }
613+ /* CHECK: options at tail. */
614+ else if (i+1 >= tcph->doff * 4) {
615+ limpk("TCP option %u at tail\n",
616+ opt[i]);
617+ return 0;
618+ }
619+ /* CHECK: zero-length options. */
620+ else if (opt[i+1] == 0) {
621+ limpk("TCP option %u 0 len\n",
622+ opt[i]);
623+ return 0;
624+ }
625+ /* CHECK: oversize options. */
626+ else if (&opt[i] + opt[i+1] > endhdr) {
627+ limpk("TCP option %u at %Zu too long\n",
628+ (unsigned int) opt[i], i);
629+ return 0;
630+ }
631+ /* Move to next option */
632+ i += opt[i+1];
633+ }
634+ }
635+
636+ return 1;
637+}
638+
639+/* Returns 1 if ok */
640+/* Standard IP checks. */
641+static int
642+check_ip(struct iphdr *iph, size_t length, int embedded)
643+{
644+ u_int8_t *opt = (u_int8_t *)iph;
645+ u_int8_t *endhdr = (u_int8_t *)iph + iph->ihl * 4;
646+ int end_of_options = 0;
647+ void *protoh;
648+ size_t datalen;
649+ unsigned int i;
650+ unsigned int offset;
651+
652+ /* Should only happen for local outgoing raw-socket packets. */
653+ /* CHECK: length >= ip header. */
654+ if (length < sizeof(struct iphdr) || length < iph->ihl * 4) {
655+ limpk("Packet length %Zu < IP header.\n", length);
656+ return 0;
657+ }
658+
659+ offset = ntohs(iph->frag_off) & IP_OFFSET;
660+ protoh = (void *)iph + iph->ihl * 4;
661+ datalen = length - iph->ihl * 4;
662+
663+ /* CHECK: Embedded fragment. */
664+ if (embedded && offset) {
665+ limpk("Embedded fragment.\n");
666+ return 0;
667+ }
668+
669+ for (i = sizeof(struct iphdr); i < iph->ihl * 4; ) {
670+ switch (opt[i]) {
671+ case 0:
672+ end_of_options = 1;
673+ i++;
674+ break;
675+ case 1:
676+ i++;
677+ break;
678+ default:
679+ /* CHECK: options after EOO. */
680+ if (end_of_options) {
681+ limpk("IP option %u after end\n",
682+ opt[i]);
683+ return 0;
684+ }
685+ /* CHECK: options at tail. */
686+ else if (i+1 >= iph->ihl * 4) {
687+ limpk("IP option %u at tail\n",
688+ opt[i]);
689+ return 0;
690+ }
691+ /* CHECK: zero-length or one-length options. */
692+ else if (opt[i+1] < 2) {
693+ limpk("IP option %u %u len\n",
694+ opt[i], opt[i+1]);
695+ return 0;
696+ }
697+ /* CHECK: oversize options. */
698+ else if (&opt[i] + opt[i+1] > endhdr) {
699+ limpk("IP option %u at %u too long\n",
700+ opt[i], i);
701+ return 0;
702+ }
703+ /* Move to next option */
704+ i += opt[i+1];
705+ }
706+ }
707+
708+ /* Fragment checks. */
709+
710+ /* CHECK: More fragments, but doesn't fill 8-byte boundary. */
711+ if ((ntohs(iph->frag_off) & IP_MF)
712+ && (ntohs(iph->tot_len) % 8) != 0) {
713+ limpk("Truncated fragment %u long.\n", ntohs(iph->tot_len));
714+ return 0;
715+ }
716+
717+ /* CHECK: Oversize fragment a-la Ping of Death. */
718+ if (offset * 8 + datalen > 65535) {
719+ limpk("Oversize fragment to %u.\n", offset * 8);
720+ return 0;
721+ }
722+
723+ /* CHECK: DF set and offset or MF set. */
724+ if ((ntohs(iph->frag_off) & IP_DF)
725+ && (offset || (ntohs(iph->frag_off) & IP_MF))) {
726+ limpk("DF set and offset=%u, MF=%u.\n",
727+ offset, ntohs(iph->frag_off) & IP_MF);
728+ return 0;
729+ }
730+
731+ /* CHECK: Zero-sized fragments. */
732+ if ((offset || (ntohs(iph->frag_off) & IP_MF))
733+ && datalen == 0) {
734+ limpk("Zero size fragment offset=%u\n", offset);
735+ return 0;
736+ }
737+
738+ /* Note: we can have even middle fragments smaller than this:
739+ consider a large packet passing through a 600MTU then
740+ 576MTU link: this gives a fragment of 24 data bytes. But
741+ everyone packs fragments largest first, hence a fragment
742+ can't START before 576 - MAX_IP_HEADER_LEN. */
743+
744+ /* Used to be min-size 576: I recall Alan Cox saying ax25 goes
745+ down to 128 (576 taken from RFC 791: All hosts must be
746+ prepared to accept datagrams of up to 576 octets). Use 128
747+ here. */
748+#define MIN_LIKELY_MTU 128
749+ /* CHECK: Min size of first frag = 128. */
750+ if ((ntohs(iph->frag_off) & IP_MF)
751+ && offset == 0
752+ && ntohs(iph->tot_len) < MIN_LIKELY_MTU) {
753+ limpk("First fragment size %u < %u\n", ntohs(iph->tot_len),
754+ MIN_LIKELY_MTU);
755+ return 0;
756+ }
757+
758+ /* CHECK: Min offset of frag = 128 - IP hdr len. */
759+ if (offset && offset * 8 < MIN_LIKELY_MTU - iph->ihl * 4) {
760+ limpk("Fragment starts at %u < %u\n", offset * 8,
761+ MIN_LIKELY_MTU - iph->ihl * 4);
762+ return 0;
763+ }
764+
765+ /* CHECK: Protocol specification non-zero. */
766+ if (iph->protocol == 0) {
767+ limpk("Zero protocol\n");
768+ return 0;
769+ }
770+
771+ /* CHECK: Do not use what is unused.
772+ * First bit of fragmentation flags should be unused.
773+ * May be used by OS fingerprinting tools.
774+ * 04 Jun 2002, Maciej Soltysiak, solt@dns.toxicfilms.tv
775+ */
776+ if (ntohs(iph->frag_off)>>15) {
777+ limpk("IP unused bit set\n");
778+ return 0;
779+ }
780+
781+ /* Per-protocol checks. */
782+ switch (iph->protocol) {
783+ case IPPROTO_ICMP:
784+ return check_icmp(protoh, datalen, offset,
785+ (ntohs(iph->frag_off) & IP_MF),
786+ embedded);
787+
788+ case IPPROTO_UDP:
789+ return check_udp(iph, protoh, datalen, offset,
790+ (ntohs(iph->frag_off) & IP_MF),
791+ embedded);
792+
793+ case IPPROTO_TCP:
794+ return check_tcp(iph, protoh, datalen, offset,
795+ (ntohs(iph->frag_off) & IP_MF),
796+ embedded);
797+ default:
798+ /* Ignorance is bliss. */
799+ return 1;
800+ }
801+}
802+
803+static int
804+match(const struct sk_buff *skb,
805+ const struct net_device *in,
806+ const struct net_device *out,
807+ const void *matchinfo,
808+ int offset,
809+ const void *hdr,
810+ u_int16_t datalen,
811+ int *hotdrop)
812+{
813+ return !check_ip(skb->nh.iph, skb->len, 0);
814+}
815+
816+/* Called when user tries to insert an entry of this type. */
817+static int
818+checkentry(const char *tablename,
819+ const struct ipt_ip *ip,
820+ void *matchinfo,
821+ unsigned int matchsize,
822+ unsigned int hook_mask)
823+{
824+ if (matchsize != IPT_ALIGN(0))
825+ return 0;
826+
827+ return 1;
828+}
829+
830+static struct ipt_match unclean_match
831+= { { NULL, NULL }, "unclean", &match, &checkentry, NULL, THIS_MODULE };
832+
833+static int __init init(void)
834+{
835+ return ipt_register_match(&unclean_match);
836+}
837+
838+static void __exit fini(void)
839+{
840+ ipt_unregister_match(&unclean_match);
841+}
842+
843+module_init(init);
844+module_exit(fini);
845+MODULE_LICENSE("GPL");
846diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/Kconfig linux-2.6.6-rc1/net/ipv4/netfilter/Kconfig
847--- linux-2.6.6-rc1.org/net/ipv4/netfilter/Kconfig 2004-04-19 10:38:53.000000000 +0200
848+++ linux-2.6.6-rc1/net/ipv4/netfilter/Kconfig 2004-04-19 10:47:23.000000000 +0200
849@@ -206,6 +206,11 @@
850
851 To compile it as a module, choose M here. If unsure, say N.
852
853+config IP_NF_MATCH_UNCLEAN
854+ tristate 'unclean match support (EXPERIMENTAL)'
855+ depends on EXPERIMENTAL && IP_NF_IPTABLES
856+ help
857+
858 config IP_NF_MATCH_TTL
859 tristate "TTL match support"
860 depends on IP_NF_IPTABLES
2ef809bd 861@@ -701,5 +706,51 @@
69326011 862 depends on IP_NF_IPTABLES
863 help
864
865+config IP_NF_CONNTRACK_MARK
866+ bool 'Connection mark tracking support'
867+config IP_NF_TARGET_CONNMARK
868+ tristate 'CONNMARK target support'
869+ depends on IP_NF_MANGLE
870+config IP_NF_MATCH_CONNMARK
871+ tristate ' Connection mark match support'
872+ depends on IP_NF_IPTABLES
873+ help
874+
875+config IP_NF_TARGET_IPMARK
876+ tristate 'IPMARK target support'
877+ depends on IP_NF_MANGLE
878+ help
879+
880+config IP_NF_TARGET_TARPIT
881+ tristate 'TARPIT target support'
882+ depends on IP_NF_FILTER
883+ help
884+
885+config IP_NF_TARGET_XOR
886+ tristate 'XOR target support'
887+ depends on IP_NF_MANGLE
888+ help
889+
890+config IP_NF_MATCH_ADDRTYPE
891+ tristate 'address type match support'
892+ depends on IP_NF_IPTABLES
893+ help
894+
895+config IP_NF_MATCH_POLICY
896+ tristate "IPsec policy match support"
897+ depends on IP_NF_IPTABLES && XFRM
898+ help
899+ Policy matching allows you to match packets based on the
900+ IPsec policy that was used during decapsulation/will
901+ be used during encapsulation.
902+
903+ To compile it as a module, choose M here. If unsure, say N.
904+ help
905+
69326011 906+config IP_NF_MATCH_STRING
907+ tristate 'String match support'
908+ depends on IP_NF_IPTABLES
909+ help
910+
911 endmenu
912
913diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/Makefile linux-2.6.6-rc1/net/ipv4/netfilter/Makefile
914--- linux-2.6.6-rc1.org/net/ipv4/netfilter/Makefile 2004-04-19 10:38:53.000000000 +0200
915+++ linux-2.6.6-rc1/net/ipv4/netfilter/Makefile 2004-04-19 10:47:23.000000000 +0200
69326011 916@@ -87,14 +90,19 @@
917 obj-$(CONFIG_IP_NF_MATCH_U32) += ipt_u32.o
918
919
920+obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o
921+obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o
922 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
923 obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
924+obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o
925 obj-$(CONFIG_IP_NF_MATCH_CONNLIMIT) += ipt_connlimit.o
926 obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
927 obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
928+obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
929 obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
930
931 obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
932+obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o
933
934 # targets
935 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
936@@ -102,6 +110,8 @@
937 obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
938 obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o
939 obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o
940+obj-$(CONFIG_IP_NF_TARGET_TARPIT) += ipt_TARPIT.o
941+obj-$(CONFIG_IP_NF_TARGET_IPMARK) += ipt_IPMARK.o
942 obj-$(CONFIG_IP_NF_TARGET_IMQ) += ipt_IMQ.o
943 obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
944 obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
945@@ -110,6 +120,8 @@
946 obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
947 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
948 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
949+obj-$(CONFIG_IP_NF_TARGET_XOR) += ipt_XOR.o
950+obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o
951 obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
952 obj-$(CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP) += ipt_IPV4OPTSSTRIP.o
953 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
954diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ip_conntrack_core.c linux-2.6.6-rc1/net/ipv4/netfilter/ip_conntrack_core.c
955--- linux-2.6.6-rc1.org/net/ipv4/netfilter/ip_conntrack_core.c 2004-04-19 10:38:53.000000000 +0200
956+++ linux-2.6.6-rc1/net/ipv4/netfilter/ip_conntrack_core.c 2004-04-19 10:44:16.000000000 +0200
957@@ -717,6 +717,9 @@
958 __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
959 conntrack->master = expected;
960 expected->sibling = conntrack;
961+#if CONFIG_IP_NF_CONNTRACK_MARK
962+ conntrack->mark = expected->expectant->mark;
963+#endif
964 LIST_DELETE(&ip_conntrack_expect_list, expected);
965 expected->expectant->expecting--;
966 nf_conntrack_get(&master_ct(conntrack)->infos[0]);
69326011 967diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.6-rc1/net/ipv4/netfilter/ip_conntrack_standalone.c
968--- linux-2.6.6-rc1.org/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-04-19 10:38:51.000000000 +0200
969+++ linux-2.6.6-rc1/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-04-19 10:44:16.000000000 +0200
970@@ -110,6 +110,9 @@
971 len += sprintf(buffer + len, "[ASSURED] ");
972 len += sprintf(buffer + len, "use=%u ",
973 atomic_read(&conntrack->ct_general.use));
974+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
975+ len += sprintf(buffer + len, "mark=%ld ", conntrack->mark);
976+#endif
977 len += sprintf(buffer + len, "\n");
978
979 return len;
980diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ip_tables.c linux-2.6.6-rc1/net/ipv4/netfilter/ip_tables.c
981--- linux-2.6.6-rc1.org/net/ipv4/netfilter/ip_tables.c 2004-04-19 10:38:53.000000000 +0200
982+++ linux-2.6.6-rc1/net/ipv4/netfilter/ip_tables.c 2004-04-19 10:45:57.000000000 +0200
983@@ -8,6 +8,10 @@
984 * it under the terms of the GNU General Public License version 2 as
985 * published by the Free Software Foundation.
986 *
987+ * 6 Mar 2002 Robert Olsson <robban@robtex.com>
988+ * 17 Apr 2003 Chris Wilson <chris@netservers.co.uk>
989+ * - mark_source_chains speedup for complex chains
990+ *
991 * 19 Jan 2002 Harald Welte <laforge@gnumonks.org>
992 * - increase module usage count as soon as we have rules inside
993 * a table
994@@ -498,6 +502,9 @@
995 {
996 unsigned int hook;
997
998+ /* keep track of where we have been: */
999+ unsigned char *been = vmalloc(newinfo->size);
1000+
1001 /* No recursion; use packet counter to save back ptrs (reset
1002 to 0 as we leave), and comefrom to save source hook bitmask */
1003 for (hook = 0; hook < NF_IP_NUMHOOKS; hook++) {
1004@@ -510,6 +517,7 @@
1005
1006 /* Set initial back pointer. */
1007 e->counters.pcnt = pos;
1008+ memset(been, 0, newinfo->size);
1009
1010 for (;;) {
1011 struct ipt_standard_target *t
1012@@ -518,6 +526,7 @@
1013 if (e->comefrom & (1 << NF_IP_NUMHOOKS)) {
1014 printk("iptables: loop hook %u pos %u %08X.\n",
1015 hook, pos, e->comefrom);
1016+ vfree(been);
1017 return 0;
1018 }
1019 e->comefrom
1020@@ -565,10 +574,14 @@
1021 } else {
1022 int newpos = t->verdict;
1023
1024- if (strcmp(t->target.u.user.name,
1025+ if ( (pos < 0 || pos >= newinfo->size
1026+ || !been[pos])
1027+ && strcmp(t->target.u.user.name,
1028 IPT_STANDARD_TARGET) == 0
1029 && newpos >= 0) {
1030 /* This a jump; chase it. */
1031+ if (pos >= 0 && pos < newinfo->size)
1032+ been[pos]++;
1033 duprintf("Jump rule %u -> %u\n",
1034 pos, newpos);
1035 } else {
1036@@ -584,6 +597,7 @@
1037 next:
1038 duprintf("Finished chain %u\n", hook);
1039 }
1040+ vfree(been);
1041 return 1;
1042 }
1043
1044diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_CONNMARK.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_CONNMARK.c
1045--- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_CONNMARK.c 1970-01-01 01:00:00.000000000 +0100
1046+++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_CONNMARK.c 2004-04-19 10:44:16.000000000 +0200
1047@@ -0,0 +1,118 @@
1048+/* This kernel module is used to modify the connection mark values, or
1049+ * to optionally restore the skb nfmark from the connection mark
1050+ *
1051+ * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
1052+ * by Henrik Nordstrom <hno@marasystems.com>
1053+ *
1054+ * This program is free software; you can redistribute it and/or modify
1055+ * it under the terms of the GNU General Public License as published by
1056+ * the Free Software Foundation; either version 2 of the License, or
1057+ * (at your option) any later version.
1058+ *
1059+ * This program is distributed in the hope that it will be useful,
1060+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1061+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1062+ * GNU General Public License for more details.
1063+ *
1064+ * You should have received a copy of the GNU General Public License
1065+ * along with this program; if not, write to the Free Software
1066+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1067+ */
1068+#include <linux/module.h>
1069+#include <linux/skbuff.h>
1070+#include <linux/ip.h>
1071+#include <net/checksum.h>
1072+
1073+MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
1074+MODULE_DESCRIPTION("IP tables CONNMARK matching module");
1075+MODULE_LICENSE("GPL");
1076+
1077+#include <linux/netfilter_ipv4/ip_tables.h>
1078+#include <linux/netfilter_ipv4/ipt_CONNMARK.h>
1079+#include <linux/netfilter_ipv4/ip_conntrack.h>
1080+
1081+static unsigned int
1082+target(struct sk_buff **pskb,
1083+ const struct net_device *in,
1084+ const struct net_device *out,
1085+ unsigned int hooknum,
1086+ const void *targinfo,
1087+ void *userinfo)
1088+{
1089+ const struct ipt_connmark_target_info *markinfo = targinfo;
1090+ unsigned long diff;
1091+ unsigned long nfmark;
1092+ unsigned long newmark;
1093+
1094+ enum ip_conntrack_info ctinfo;
1095+ struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo);
1096+ if (ct) {
1097+ switch(markinfo->mode) {
1098+ case IPT_CONNMARK_SET:
1099+ newmark = (ct->mark & ~markinfo->mask) | markinfo->mark;
1100+ if (newmark != ct->mark)
1101+ ct->mark = newmark;
1102+ break;
1103+ case IPT_CONNMARK_SAVE:
1104+ newmark = (ct->mark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask);
1105+ if (ct->mark != newmark)
1106+ ct->mark = newmark;
1107+ break;
1108+ case IPT_CONNMARK_RESTORE:
1109+ nfmark = (*pskb)->nfmark;
1110+ diff = (ct->mark ^ nfmark & markinfo->mask);
1111+ if (diff != 0) {
1112+ (*pskb)->nfmark = nfmark ^ diff;
1113+ (*pskb)->nfcache |= NFC_ALTERED;
1114+ }
1115+ break;
1116+ }
1117+ }
1118+
1119+ return IPT_CONTINUE;
1120+}
1121+
1122+static int
1123+checkentry(const char *tablename,
1124+ const struct ipt_entry *e,
1125+ void *targinfo,
1126+ unsigned int targinfosize,
1127+ unsigned int hook_mask)
1128+{
1129+ struct ipt_connmark_target_info *matchinfo = targinfo;
1130+ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) {
1131+ printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n",
1132+ targinfosize,
1133+ IPT_ALIGN(sizeof(struct ipt_connmark_target_info)));
1134+ return 0;
1135+ }
1136+
1137+ if (matchinfo->mode == IPT_CONNMARK_RESTORE) {
1138+ if (strcmp(tablename, "mangle") != 0) {
1139+ printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1140+ return 0;
1141+ }
1142+ }
1143+
1144+ return 1;
1145+}
1146+
1147+static struct ipt_target ipt_connmark_reg = {
1148+ .name = "CONNMARK",
1149+ .target = &target,
1150+ .checkentry = &checkentry,
1151+ .me = THIS_MODULE
1152+};
1153+
1154+static int __init init(void)
1155+{
1156+ return ipt_register_target(&ipt_connmark_reg);
1157+}
1158+
1159+static void __exit fini(void)
1160+{
1161+ ipt_unregister_target(&ipt_connmark_reg);
1162+}
1163+
1164+module_init(init);
1165+module_exit(fini);
1166diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_IPMARK.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_IPMARK.c
1167--- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_IPMARK.c 1970-01-01 01:00:00.000000000 +0100
1168+++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_IPMARK.c 2004-04-19 10:44:26.000000000 +0200
1169@@ -0,0 +1,81 @@
1170+/* This is a module which is used for setting the NFMARK field of an skb. */
1171+#include <linux/module.h>
1172+#include <linux/skbuff.h>
1173+#include <linux/ip.h>
1174+#include <net/checksum.h>
1175+
1176+#include <linux/netfilter_ipv4/ip_tables.h>
1177+#include <linux/netfilter_ipv4/ipt_IPMARK.h>
1178+
1179+MODULE_AUTHOR("Grzegorz Janoszka <Grzegorz.Janoszka@pro.onet.pl>");
1180+MODULE_DESCRIPTION("IP tables IPMARK: mark based on ip address");
1181+MODULE_LICENSE("GPL");
1182+
1183+static unsigned int
1184+target(struct sk_buff **pskb,
1185+ const struct net_device *in,
1186+ const struct net_device *out,
1187+ unsigned int hooknum,
1188+ const void *targinfo,
1189+ void *userinfo)
1190+{
1191+ const struct ipt_ipmark_target_info *ipmarkinfo = targinfo;
1192+ struct iphdr *iph = (*pskb)->nh.iph;
1193+ unsigned long mark;
1194+
1195+ if (ipmarkinfo->addr == IPT_IPMARK_SRC)
1196+ mark = (unsigned long) ntohl(iph->saddr);
1197+ else
1198+ mark = (unsigned long) ntohl(iph->daddr);
1199+
1200+ mark &= ipmarkinfo->andmask;
1201+ mark |= ipmarkinfo->ormask;
1202+
1203+ if ((*pskb)->nfmark != mark) {
1204+ (*pskb)->nfmark = mark;
1205+ (*pskb)->nfcache |= NFC_ALTERED;
1206+ }
1207+ return IPT_CONTINUE;
1208+}
1209+
1210+static int
1211+checkentry(const char *tablename,
1212+ const struct ipt_entry *e,
1213+ void *targinfo,
1214+ unsigned int targinfosize,
1215+ unsigned int hook_mask)
1216+{
1217+ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ipmark_target_info))) {
1218+ printk(KERN_WARNING "IPMARK: targinfosize %u != %Zu\n",
1219+ targinfosize,
1220+ IPT_ALIGN(sizeof(struct ipt_ipmark_target_info)));
1221+ return 0;
1222+ }
1223+
1224+ if (strcmp(tablename, "mangle") != 0) {
1225+ printk(KERN_WARNING "IPMARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1226+ return 0;
1227+ }
1228+
1229+ return 1;
1230+}
1231+
1232+static struct ipt_target ipt_ipmark_reg = {
1233+ .name = "IPMARK",
1234+ .target = target,
1235+ .checkentry = checkentry,
1236+ .me = THIS_MODULE
1237+};
1238+
1239+static int __init init(void)
1240+{
1241+ return ipt_register_target(&ipt_ipmark_reg);
1242+}
1243+
1244+static void __exit fini(void)
1245+{
1246+ ipt_unregister_target(&ipt_ipmark_reg);
1247+}
1248+
1249+module_init(init);
1250+module_exit(fini);
1251diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_TARPIT.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_TARPIT.c
1252--- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_TARPIT.c 1970-01-01 01:00:00.000000000 +0100
1253+++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_TARPIT.c 2004-04-19 10:44:29.000000000 +0200
2ef809bd 1254@@ -0,0 +1,289 @@
69326011 1255+/*
1256+ * Kernel module to capture and hold incoming TCP connections using
1257+ * no local per-connection resources.
1258+ *
1259+ * Based on ipt_REJECT.c and offering functionality similar to
1260+ * LaBrea <http://www.hackbusters.net/LaBrea/>.
1261+ *
1262+ * Copyright (c) 2002 Aaron Hopkins <tools@die.net>
1263+ *
1264+ * This program is free software; you can redistribute it and/or modify
1265+ * it under the terms of the GNU General Public License as published by
1266+ * the Free Software Foundation; either version 2 of the License, or
1267+ * (at your option) any later version.
1268+ *
1269+ * This program is distributed in the hope that it will be useful,
1270+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1271+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1272+ * GNU General Public License for more details.
1273+ *
1274+ * You should have received a copy of the GNU General Public License
1275+ * along with this program; if not, write to the Free Software
1276+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1277+ *
1278+ * Goal:
1279+ * - Allow incoming TCP connections to be established.
1280+ * - Passing data should result in the connection being switched to the
1281+ * persist state (0 byte window), in which the remote side stops sending
1282+ * data and asks to continue every 60 seconds.
1283+ * - Attempts to shut down the connection should be ignored completely, so
1284+ * the remote side ends up having to time it out.
1285+ *
1286+ * This means:
1287+ * - Reply to TCP SYN,!ACK,!RST,!FIN with SYN-ACK, window 5 bytes
1288+ * - Reply to TCP SYN,ACK,!RST,!FIN with RST to prevent spoofing
1289+ * - Reply to TCP !SYN,!RST,!FIN with ACK, window 0 bytes, rate-limited
1290+ */
1291+
1292+#include <linux/config.h>
1293+#include <linux/module.h>
1294+#include <linux/skbuff.h>
1295+#include <linux/ip.h>
1296+#include <net/ip.h>
1297+#include <net/tcp.h>
1298+#include <net/icmp.h>
1299+struct in_device;
1300+#include <net/route.h>
1301+#include <linux/random.h>
1302+#include <linux/netfilter_ipv4/ip_tables.h>
1303+
1304+#if 0
1305+#define DEBUGP printk
1306+#else
1307+#define DEBUGP(format, args...)
1308+#endif
1309+
1310+MODULE_LICENSE("GPL");
1311+MODULE_AUTHOR("Aaron Hopkins <tools@die.net>");
1312+
1313+/* Stolen from ip_finish_output2 */
1314+static int ip_direct_send(struct sk_buff *skb)
1315+{
1316+ struct dst_entry *dst = skb->dst;
1317+ struct hh_cache *hh = dst->hh;
1318+
1319+ if (hh) {
1320+ read_lock_bh(&hh->hh_lock);
1321+ memcpy(skb->data - 16, hh->hh_data, 16);
1322+ read_unlock_bh(&hh->hh_lock);
1323+ skb_push(skb, hh->hh_len);
1324+ return hh->hh_output(skb);
1325+ } else if (dst->neighbour)
1326+ return dst->neighbour->output(skb);
1327+
1328+ if (net_ratelimit())
1329+ printk(KERN_DEBUG "TARPIT ip_direct_send: no header cache and no neighbor!\n");
1330+ kfree_skb(skb);
1331+ return -EINVAL;
1332+}
1333+
1334+
1335+/* Send reply */
1336+static void tarpit_tcp(struct sk_buff *oskb,struct rtable *ort,int local)
1337+{
1338+ struct sk_buff *nskb;
1339+ struct rtable *nrt;
1340+ struct tcphdr *otcph, *ntcph;
1341+ unsigned int otcplen;
1342+ u_int16_t tmp;
2ef809bd 1343+ struct flowi fl = {};
69326011 1344+
1345+ /* A truncated TCP header isn't going to be useful */
1346+ if (oskb->len < (oskb->nh.iph->ihl*4) + sizeof(struct tcphdr))
1347+ return;
1348+
1349+ otcph = (struct tcphdr *)((u_int32_t*)oskb->nh.iph
1350+ + oskb->nh.iph->ihl);
1351+ otcplen = oskb->len - oskb->nh.iph->ihl*4;
1352+
1353+ /* No replies for RST or FIN */
1354+ if (otcph->rst || otcph->fin)
1355+ return;
1356+
1357+ /* No reply to !SYN,!ACK. Rate-limit replies to !SYN,ACKs */
1358+ if (!otcph->syn && (!otcph->ack || !xrlim_allow(&ort->u.dst, 1*HZ)))
1359+ return;
1360+
1361+ /* Check checksum. */
1362+ if (tcp_v4_check(otcph, otcplen, oskb->nh.iph->saddr,
1363+ oskb->nh.iph->daddr,
1364+ csum_partial((char *)otcph, otcplen, 0)) != 0)
1365+ return;
1366+
1367+ /* Copy skb (even if skb is about to be dropped, we can't just
1368+ clone it because there may be other things, such as tcpdump,
1369+ interested in it) */
1370+ nskb = skb_copy(oskb, GFP_ATOMIC);
1371+ if (!nskb)
1372+ return;
1373+
1374+ /* This packet will not be the same as the other: clear nf fields */
1375+ nf_conntrack_put(nskb->nfct);
1376+ nskb->nfct = NULL;
1377+ nskb->nfcache = 0;
1378+#ifdef CONFIG_NETFILTER_DEBUG
1379+ nskb->nf_debug = 0;
1380+#endif
1381+
1382+ ntcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
1383+
1384+ /* Truncate to length (no data) */
1385+ ntcph->doff = sizeof(struct tcphdr)/4;
1386+ skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
1387+ nskb->nh.iph->tot_len = htons(nskb->len);
1388+
1389+ /* Swap source and dest */
1390+ nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
1391+ tmp = ntcph->source;
1392+ ntcph->source = ntcph->dest;
1393+ ntcph->dest = tmp;
1394+
1395+ /* Use supplied sequence number or make a new one */
1396+ ntcph->seq = otcph->ack ? otcph->ack_seq
1397+ : htonl(secure_tcp_sequence_number(nskb->nh.iph->saddr,
1398+ nskb->nh.iph->daddr,
1399+ ntcph->source,
1400+ ntcph->dest));
1401+
1402+ /* Our SYN-ACKs must have a >0 window */
1403+ ntcph->window = (otcph->syn && !otcph->ack) ? htons(5) : 0;
1404+
1405+ ntcph->urg_ptr = 0;
1406+
1407+ /* Reset flags */
1408+ ((u_int8_t *)ntcph)[13] = 0;
1409+
1410+ if (otcph->syn && otcph->ack) {
1411+ ntcph->rst = 1;
1412+ ntcph->ack_seq = 0;
1413+ } else {
1414+ ntcph->syn = otcph->syn;
1415+ ntcph->ack = 1;
1416+ ntcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn);
1417+ }
1418+
1419+ /* Adjust TCP checksum */
1420+ ntcph->check = 0;
1421+ ntcph->check = tcp_v4_check(ntcph, sizeof(struct tcphdr),
1422+ nskb->nh.iph->saddr,
1423+ nskb->nh.iph->daddr,
1424+ csum_partial((char *)ntcph,
1425+ sizeof(struct tcphdr), 0));
1426+
1427+ /* Adjust IP TTL */
1428+ nskb->nh.iph->ttl = sysctl_ip_default_ttl;
1429+
1430+ /* Set DF, id = 0 */
1431+ nskb->nh.iph->frag_off = htons(IP_DF);
1432+ nskb->nh.iph->id = 0;
1433+
1434+ /* Adjust IP checksum */
1435+ nskb->nh.iph->check = 0;
1436+ nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
1437+ nskb->nh.iph->ihl);
1438+
2ef809bd 1439+ fl.nl_u.ip4_u.daddr = nskb->nh.iph->daddr;
1440+ fl.nl_u.ip4_u.saddr = (local ? nskb->nh.iph->saddr : 0);
1441+ fl.nl_u.ip4_u.tos = RT_TOS(nskb->nh.iph->tos) | RTO_CONN;
1442+ fl.oif = 0;
1443+ if (ip_route_output_key(&nrt, &fl) != 0)
69326011 1444+ goto free_nskb;
1445+
1446+ dst_release(nskb->dst);
1447+ nskb->dst = &nrt->u.dst;
1448+
1449+ /* "Never happens" */
2ef809bd 1450+ if (nskb->len > dst_pmtu(nskb->dst))
69326011 1451+ goto free_nskb;
1452+
1453+ ip_direct_send (nskb);
1454+
1455+ return;
1456+
1457+ free_nskb:
1458+ kfree_skb(nskb);
1459+}
1460+
1461+
1462+static unsigned int tarpit(struct sk_buff **pskb,
1463+ const struct net_device *in,
1464+ const struct net_device *out,
1465+ unsigned int hooknum,
1466+ const void *targinfo,
1467+ void *userinfo)
1468+{
1469+ struct sk_buff *skb = *pskb;
1470+ struct rtable *rt = (struct rtable*)skb->dst;
1471+
1472+ /* Do we have an input route cache entry? */
1473+ if (!rt)
1474+ return NF_DROP;
1475+
1476+ /* No replies to physical multicast/broadcast */
1477+ if (skb->pkt_type != PACKET_HOST && skb->pkt_type != PACKET_OTHERHOST)
1478+ return NF_DROP;
1479+
1480+ /* Now check at the protocol level */
1481+ if (rt->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST))
1482+ return NF_DROP;
1483+
1484+ /* Our naive response construction doesn't deal with IP
1485+ options, and probably shouldn't try. */
1486+ if (skb->nh.iph->ihl*4 != sizeof(struct iphdr))
1487+ return NF_DROP;
1488+
1489+ /* We aren't interested in fragments */
1490+ if (skb->nh.iph->frag_off & htons(IP_OFFSET))
1491+ return NF_DROP;
1492+
1493+ tarpit_tcp(skb,rt,hooknum == NF_IP_LOCAL_IN);
1494+
1495+ return NF_DROP;
1496+}
1497+
1498+
1499+static int check(const char *tablename,
1500+ const struct ipt_entry *e,
1501+ void *targinfo,
1502+ unsigned int targinfosize,
1503+ unsigned int hook_mask)
1504+{
1505+ /* Only allow these for input/forward packet filtering. */
1506+ if (strcmp(tablename, "filter") != 0) {
1507+ DEBUGP("TARPIT: bad table %s'.\n", tablename);
1508+ return 0;
1509+ }
1510+ if ((hook_mask & ~((1 << NF_IP_LOCAL_IN)
1511+ | (1 << NF_IP_FORWARD))) != 0) {
1512+ DEBUGP("TARPIT: bad hook mask %X\n", hook_mask);
1513+ return 0;
1514+ }
1515+
1516+ /* Must specify that it's a TCP packet */
1517+ if (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & IPT_INV_PROTO)) {
1518+ DEBUGP("TARPIT: not valid for non-tcp\n");
1519+ return 0;
1520+ }
1521+
1522+ return 1;
1523+}
1524+
1525+static struct ipt_target ipt_tarpit_reg = {
1526+ .name = "TARPIT",
1527+ .target = tarpit,
1528+ .checkentry = check,
1529+ .me = THIS_MODULE
1530+};
1531+
1532+static int __init init(void)
1533+{
1534+ return ipt_register_target(&ipt_tarpit_reg);
1535+}
1536+
1537+static void __exit fini(void)
1538+{
1539+ ipt_unregister_target(&ipt_tarpit_reg);
1540+}
1541+
1542+module_init(init);
1543+module_exit(fini);
1544diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_XOR.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_XOR.c
1545--- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_XOR.c 1970-01-01 01:00:00.000000000 +0100
1546+++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_XOR.c 2004-04-19 10:44:34.000000000 +0200
1547@@ -0,0 +1,117 @@
1548+/* XOR target for IP tables
1549+ * (C) 2000 by Tim Vandermeersch <Tim.Vandermeersch@pandora.be>
1550+ * Based on ipt_TTL.c
1551+ *
1552+ * Version 1.0
1553+ *
1554+ * This software is distributed under the terms of GNU GPL
1555+ */
1556+
1557+#include <linux/module.h>
1558+#include <linux/skbuff.h>
1559+#include <linux/ip.h>
1560+#include <linux/tcp.h>
1561+#include <linux/udp.h>
1562+
1563+#include <linux/netfilter_ipv4/ip_tables.h>
1564+#include <linux/netfilter_ipv4/ipt_XOR.h>
1565+
1566+MODULE_AUTHOR("Tim Vandermeersch <Tim.Vandermeersch@pandora.be>");
1567+MODULE_DESCRIPTION("IP tables XOR module");
1568+MODULE_LICENSE("GPL");
1569+
1570+static unsigned int
1571+ipt_xor_target(struct sk_buff **pskb,
1572+ const struct net_device *in, const struct net_device *out,
1573+ unsigned int hooknum, const void *targinfo, void *userinfo)
1574+{
1575+ struct ipt_XOR_info *info = (void *) targinfo;
1576+ struct iphdr *iph;
1577+ struct tcphdr *tcph;
1578+ struct udphdr *udph;
1579+ int i, j, k;
1580+
1581+ if (!skb_ip_make_writable(pskb, (*pskb)->len))
1582+ return NF_DROP;
1583+
1584+ iph = (*pskb)->nh.iph;
1585+
1586+ if (iph->protocol == IPPROTO_TCP) {
1587+ tcph = (struct tcphdr *) ((*pskb)->data + iph->ihl*4);
1588+ for (i=0, j=0; i<(ntohs(iph->tot_len) - iph->ihl*4 - tcph->doff*4); ) {
1589+ for (k=0; k<=info->block_size; k++) {
1590+ (char) (*pskb)->data[ iph->ihl*4 + tcph->doff*4 + i ] ^=
1591+ info->key[j];
1592+ i++;
1593+ }
1594+ j++;
1595+ if (info->key[j] == 0x00)
1596+ j = 0;
1597+ }
1598+ } else if (iph->protocol == IPPROTO_UDP) {
1599+ udph = (struct udphdr *) ((*pskb)->data + iph->ihl*4);
1600+ for (i=0, j=0; i<(ntohs(udph->len)-8); ) {
1601+ for (k=0; k<=info->block_size; k++) {
1602+ (char) (*pskb)->data[ iph->ihl*4 + sizeof(struct udphdr) + i ] ^=
1603+ info->key[j];
1604+ i++;
1605+ }
1606+ j++;
1607+ if (info->key[j] == 0x00)
1608+ j = 0;
1609+ }
1610+ }
1611+
1612+ return IPT_CONTINUE;
1613+}
1614+
1615+static int ipt_xor_checkentry(const char *tablename, const struct ipt_entry *e,
1616+ void *targinfo, unsigned int targinfosize,
1617+ unsigned int hook_mask)
1618+{
1619+ struct ipt_XOR_info *info = targinfo;
1620+
1621+ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_XOR_info))) {
1622+ printk(KERN_WARNING "XOR: targinfosize %u != %Zu\n",
1623+ targinfosize, IPT_ALIGN(sizeof(struct ipt_XOR_info)));
1624+ return 0;
1625+ }
1626+
1627+ if (strcmp(tablename, "mangle")) {
1628+ printk(KERN_WARNING "XOR: can only be called from"
1629+ "\"mangle\" table, not \"%s\"\n", tablename);
1630+ return 0;
1631+ }
1632+
1633+ if (!strcmp(info->key, "")) {
1634+ printk(KERN_WARNING "XOR: You must specify a key");
1635+ return 0;
1636+ }
1637+
1638+ if (info->block_size == 0) {
1639+ printk(KERN_WARNING "XOR: You must specify a block-size");
1640+ return 0;
1641+ }
1642+
1643+ return 1;
1644+}
1645+
1646+static struct ipt_target ipt_XOR = {
1647+ .name = "XOR",
1648+ .target = ipt_xor_target,
1649+ .checkentry = ipt_xor_checkentry,
1650+ .me = THIS_MODULE,
1651+};
1652+
1653+static int __init init(void)
1654+{
1655+ return ipt_register_target(&ipt_XOR);
1656+}
1657+
1658+static void __exit fini(void)
1659+{
1660+ ipt_unregister_target(&ipt_XOR);
1661+}
1662+
1663+module_init(init);
1664+module_exit(fini);
1665diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_addrtype.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_addrtype.c
1666--- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_addrtype.c 1970-01-01 01:00:00.000000000 +0100
1667+++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_addrtype.c 2004-04-19 10:44:36.000000000 +0200
1668@@ -0,0 +1,68 @@
1669+/*
1670+ * iptables module to match inet_addr_type() of an ip.
1671+ */
1672+
1673+#include <linux/module.h>
1674+#include <linux/skbuff.h>
1675+#include <linux/netdevice.h>
1676+#include <net/route.h>
1677+
1678+#include <linux/netfilter_ipv4/ipt_addrtype.h>
1679+#include <linux/netfilter_ipv4/ip_tables.h>
1680+
1681+MODULE_LICENSE("GPL");
1682+
1683+static inline int match_type(u_int32_t addr, u_int16_t mask)
1684+{
1685+ return !!(mask & (1 << inet_addr_type(addr)));
1686+}
1687+
1688+static int match(const struct sk_buff *skb, const struct net_device *in,
1689+ const struct net_device *out, const void *matchinfo,
1690+ int offset, int *hotdrop)
1691+{
1692+ const struct ipt_addrtype_info *info = matchinfo;
1693+ const struct iphdr *iph = skb->nh.iph;
1694+ int ret = 1;
1695+
1696+ if (info->source)
1697+ ret &= match_type(iph->saddr, info->source)^info->invert_source;
1698+ if (info->dest)
1699+ ret &= match_type(iph->daddr, info->dest)^info->invert_dest;
1700+
1701+ return ret;
1702+}
1703+
1704+static int checkentry(const char *tablename, const struct ipt_ip *ip,
1705+ void *matchinfo, unsigned int matchsize,
1706+ unsigned int hook_mask)
1707+{
1708+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info))) {
1709+ printk(KERN_ERR "ipt_addrtype: invalid size (%u != %u)\n.",
1710+ matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info)));
1711+ return 0;
1712+ }
1713+
1714+ return 1;
1715+}
1716+
1717+static struct ipt_match addrtype_match = {
1718+ .name = "addrtype",
1719+ .match = match,
1720+ .checkentry = checkentry,
1721+ .me = THIS_MODULE
1722+};
1723+
1724+static int __init init(void)
1725+{
1726+ return ipt_register_match(&addrtype_match);
1727+}
1728+
1729+static void __exit fini(void)
1730+{
1731+ ipt_unregister_match(&addrtype_match);
1732+
1733+}
1734+
1735+module_init(init);
1736+module_exit(fini);
1737diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_connmark.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_connmark.c
1738--- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_connmark.c 1970-01-01 01:00:00.000000000 +0100
1739+++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_connmark.c 2004-04-19 10:44:16.000000000 +0200
1740@@ -0,0 +1,81 @@
1741+/* This kernel module matches connection mark values set by the
1742+ * CONNMARK target
1743+ *
1744+ * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
1745+ * by Henrik Nordstrom <hno@marasystems.com>
1746+ *
1747+ * This program is free software; you can redistribute it and/or modify
1748+ * it under the terms of the GNU General Public License as published by
1749+ * the Free Software Foundation; either version 2 of the License, or
1750+ * (at your option) any later version.
1751+ *
1752+ * This program is distributed in the hope that it will be useful,
1753+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1754+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1755+ * GNU General Public License for more details.
1756+ *
1757+ * You should have received a copy of the GNU General Public License
1758+ * along with this program; if not, write to the Free Software
1759+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1760+ */
1761+
1762+#include <linux/module.h>
1763+#include <linux/skbuff.h>
1764+
1765+MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
1766+MODULE_DESCRIPTION("IP tables connmark match module");
1767+MODULE_LICENSE("GPL");
1768+
1769+#include <linux/netfilter_ipv4/ip_tables.h>
1770+#include <linux/netfilter_ipv4/ipt_connmark.h>
1771+#include <linux/netfilter_ipv4/ip_conntrack.h>
1772+
1773+static int
1774+match(const struct sk_buff *skb,
1775+ const struct net_device *in,
1776+ const struct net_device *out,
1777+ const void *matchinfo,
1778+ int offset,
1779+ int *hotdrop)
1780+{
1781+ const struct ipt_connmark_info *info = matchinfo;
1782+ enum ip_conntrack_info ctinfo;
1783+ struct ip_conntrack *ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
1784+ if (!ct)
1785+ return 0;
1786+
1787+ return ((ct->mark & info->mask) == info->mark) ^ info->invert;
1788+}
1789+
1790+static int
1791+checkentry(const char *tablename,
1792+ const struct ipt_ip *ip,
1793+ void *matchinfo,
1794+ unsigned int matchsize,
1795+ unsigned int hook_mask)
1796+{
1797+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info)))
1798+ return 0;
1799+
1800+ return 1;
1801+}
1802+
1803+static struct ipt_match connmark_match = {
1804+ .name = "connmark",
1805+ .match = &match,
1806+ .checkentry = &checkentry,
1807+ .me = THIS_MODULE
1808+};
1809+
1810+static int __init init(void)
1811+{
1812+ return ipt_register_match(&connmark_match);
1813+}
1814+
1815+static void __exit fini(void)
1816+{
1817+ ipt_unregister_match(&connmark_match);
1818+}
1819+
1820+module_init(init);
1821+module_exit(fini);
1822diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_owner.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_owner.c
1823--- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_owner.c 2004-04-15 03:35:57.000000000 +0200
1824+++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_owner.c 2004-04-19 10:46:08.000000000 +0200
1825@@ -6,12 +6,19 @@
1826 * This program is free software; you can redistribute it and/or modify
1827 * it under the terms of the GNU General Public License version 2 as
1828 * published by the Free Software Foundation.
1829+ *
1830+ * 03/26/2003 Patrick McHardy <kaber@trash.net> : LOCAL_IN support
1831 */
1832
1833 #include <linux/module.h>
1834 #include <linux/skbuff.h>
1835 #include <linux/file.h>
1836+#include <linux/ip.h>
1837+#include <linux/tcp.h>
1838+#include <linux/udp.h>
1839 #include <net/sock.h>
1840+#include <net/tcp.h>
1841+#include <net/udp.h>
1842
1843 #include <linux/netfilter_ipv4/ipt_owner.h>
1844 #include <linux/netfilter_ipv4/ip_tables.h>
1845@@ -21,7 +28,7 @@
1846 MODULE_DESCRIPTION("iptables owner match");
1847
1848 static int
1849-match_comm(const struct sk_buff *skb, const char *comm)
1850+match_comm(const struct sock *sk, const char *comm)
1851 {
1852 struct task_struct *g, *p;
1853 struct files_struct *files;
1854@@ -38,7 +45,7 @@
1855 spin_lock(&files->file_lock);
1856 for (i=0; i < files->max_fds; i++) {
1857 if (fcheck_files(files, i) ==
1858- skb->sk->sk_socket->file) {
1859+ sk->sk_socket->file) {
1860 spin_unlock(&files->file_lock);
1861 task_unlock(p);
1862 read_unlock(&tasklist_lock);
1863@@ -54,7 +61,7 @@
1864 }
1865
1866 static int
1867-match_pid(const struct sk_buff *skb, pid_t pid)
1868+match_pid(const struct sock *sk, pid_t pid)
1869 {
1870 struct task_struct *p;
1871 struct files_struct *files;
1872@@ -70,7 +77,7 @@
1873 spin_lock(&files->file_lock);
1874 for (i=0; i < files->max_fds; i++) {
1875 if (fcheck_files(files, i) ==
1876- skb->sk->sk_socket->file) {
1877+ sk->sk_socket->file) {
1878 spin_unlock(&files->file_lock);
1879 task_unlock(p);
1880 read_unlock(&tasklist_lock);
1881@@ -86,10 +93,10 @@
1882 }
1883
1884 static int
1885-match_sid(const struct sk_buff *skb, pid_t sid)
1886+match_sid(const struct sock *sk, pid_t sid)
1887 {
1888 struct task_struct *g, *p;
1889- struct file *file = skb->sk->sk_socket->file;
1890+ struct file *file = sk->sk_socket->file;
1891 int i, found=0;
1892
1893 read_lock(&tasklist_lock);
1894@@ -129,41 +136,71 @@
1895 int *hotdrop)
1896 {
1897 const struct ipt_owner_info *info = matchinfo;
1898+ struct iphdr *iph = skb->nh.iph;
1899+ struct sock *sk = NULL;
1900+ int ret = 0;
1901+
1902+ if (out) {
1903+ sk = skb->sk;
1904+ } else {
1905+ if (iph->protocol == IPPROTO_TCP) {
1906+ struct tcphdr *tcph =
1907+ (struct tcphdr *)((u_int32_t *)iph + iph->ihl);
1908+ sk = tcp_v4_lookup(iph->saddr, tcph->source,
1909+ iph->daddr, tcph->dest,
1910+ skb->dev->ifindex);
1911+ if (sk && sk->sk_state == TCP_TIME_WAIT) {
1912+ tcp_tw_put((struct tcp_tw_bucket *)sk);
1913+ return ret;
1914+ }
1915+ } else if (iph->protocol == IPPROTO_UDP) {
1916+ struct udphdr *udph =
1917+ (struct udphdr *)((u_int32_t *)iph + iph->ihl);
1918+ sk = udp_v4_lookup(iph->saddr, udph->source, iph->daddr,
1919+ udph->dest, skb->dev->ifindex);
1920+ }
1921+ }
1922
1923- if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
1924- return 0;
1925+ if (!sk || !sk->sk_socket || !sk->sk_socket->file)
1926+ goto out;
1927
1928 if(info->match & IPT_OWNER_UID) {
1929- if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
1930+ if ((sk->sk_socket->file->f_uid != info->uid) ^
1931 !!(info->invert & IPT_OWNER_UID))
1932- return 0;
1933+ goto out;
1934 }
1935
1936 if(info->match & IPT_OWNER_GID) {
1937- if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
1938+ if ((sk->sk_socket->file->f_gid != info->gid) ^
1939 !!(info->invert & IPT_OWNER_GID))
1940- return 0;
1941+ goto out;
1942 }
1943
1944 if(info->match & IPT_OWNER_PID) {
1945- if (!match_pid(skb, info->pid) ^
1946+ if (!match_pid(sk, info->pid) ^
1947 !!(info->invert & IPT_OWNER_PID))
1948- return 0;
1949+ goto out;
1950 }
1951
1952 if(info->match & IPT_OWNER_SID) {
1953- if (!match_sid(skb, info->sid) ^
1954+ if (!match_sid(sk, info->sid) ^
1955 !!(info->invert & IPT_OWNER_SID))
1956- return 0;
1957+ goto out;
1958 }
1959
1960 if(info->match & IPT_OWNER_COMM) {
1961- if (!match_comm(skb, info->comm) ^
1962+ if (!match_comm(sk, info->comm) ^
1963 !!(info->invert & IPT_OWNER_COMM))
1964- return 0;
1965+ goto out;
1966 }
1967
1968- return 1;
1969+ ret = 1;
1970+
1971+out:
1972+ if (in && sk)
1973+ sock_put(sk);
1974+
1975+ return ret;
1976 }
1977
1978 static int
1979@@ -173,11 +210,19 @@
1980 unsigned int matchsize,
1981 unsigned int hook_mask)
1982 {
1983- if (hook_mask
1984- & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) {
1985- printk("ipt_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
1986- return 0;
1987- }
1988+ if (hook_mask
1989+ & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING) |
1990+ (1 << NF_IP_LOCAL_IN))) {
1991+ printk("ipt_owner: only valid for LOCAL_IN, LOCAL_OUT "
1992+ "or POST_ROUTING.\n");
1993+ return 0;
1994+ }
1995+
1996+ if ((hook_mask & (1 << NF_IP_LOCAL_IN))
1997+ && ip->proto != IPPROTO_TCP && ip->proto != IPPROTO_UDP) {
1998+ printk("ipt_owner: only TCP or UDP can be used in LOCAL_IN\n");
1999+ return 0;
2000+ }
2001
2002 if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info))) {
2003 printk("Matchsize %u != %Zu\n", matchsize,
2004diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_policy.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_policy.c
2005--- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_policy.c 1970-01-01 01:00:00.000000000 +0100
2006+++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_policy.c 2004-04-19 10:46:16.000000000 +0200
2007@@ -0,0 +1,176 @@
2008+/* IP tables module for matching IPsec policy
2009+ *
2010+ * Copyright (c) 2004 Patrick McHardy, <kaber@trash.net>
2011+ *
2012+ * This program is free software; you can redistribute it and/or modify
2013+ * it under the terms of the GNU General Public License version 2 as
2014+ * published by the Free Software Foundation.
2015+ */
2016+
2017+#include <linux/kernel.h>
2018+#include <linux/config.h>
2019+#include <linux/module.h>
2020+#include <linux/skbuff.h>
2021+#include <linux/init.h>
2022+#include <net/xfrm.h>
2023+
2024+#include <linux/netfilter_ipv4.h>
2025+#include <linux/netfilter_ipv4/ipt_policy.h>
2026+#include <linux/netfilter_ipv4/ip_tables.h>
2027+
2028+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
2029+MODULE_DESCRIPTION("IPtables IPsec policy matching module");
2030+MODULE_LICENSE("GPL");
2031+
2032+
2033+static inline int
2034+match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e)
2035+{
2036+#define MISMATCH(x,y) (e->match.x && ((e->x != (y)) ^ e->invert.x))
2037+
2038+ if (MISMATCH(saddr, x->props.saddr.a4 & e->smask) ||
2039+ MISMATCH(daddr, x->id.daddr.a4 & e->dmask) ||
2040+ MISMATCH(proto, x->id.proto) ||
2041+ MISMATCH(mode, x->props.mode) ||
2042+ MISMATCH(spi, x->id.spi) ||
2043+ MISMATCH(reqid, x->props.reqid))
2044+ return 0;
2045+ return 1;
2046+}
2047+
2048+static int
2049+match_policy_in(const struct sk_buff *skb, const struct ipt_policy_info *info)
2050+{
2051+ const struct ipt_policy_elem *e;
2052+ struct sec_path *sp = skb->sp;
2053+ int strict = info->flags & POLICY_MATCH_STRICT;
2054+ int i, pos;
2055+
2056+ if (sp == NULL)
2057+ return -1;
2058+ if (strict && info->len != sp->len)
2059+ return 0;
2060+
2061+ for (i = sp->len - 1; i >= 0; i--) {
2062+ pos = strict ? i - sp->len + 1 : 0;
2063+ if (pos >= info->len)
2064+ return 0;
2065+ e = &info->pol[pos];
2066+
2067+ if (match_xfrm_state(sp->x[i].xvec, e)) {
2068+ if (!strict)
2069+ return 1;
2070+ } else if (strict)
2071+ return 0;
2072+ }
2073+
2074+ return strict ? 1 : 0;
2075+}
2076+
2077+static int
2078+match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info)
2079+{
2080+ const struct ipt_policy_elem *e;
2081+ struct dst_entry *dst = skb->dst;
2082+ int strict = info->flags & POLICY_MATCH_STRICT;
2083+ int i, pos;
2084+
2085+ if (dst->xfrm == NULL)
2086+ return -1;
2087+
2088+ for (i = 0; dst && dst->xfrm; dst = dst->child, i++) {
2089+ pos = strict ? i : 0;
2090+ if (pos >= info->len)
2091+ return 0;
2092+ e = &info->pol[pos];
2093+
2094+ if (match_xfrm_state(dst->xfrm, e)) {
2095+ if (!strict)
2096+ return 1;
2097+ } else if (strict)
2098+ return 0;
2099+ }
2100+
2101+ return strict ? 1 : 0;
2102+}
2103+
2104+static int match(const struct sk_buff *skb,
2105+ const struct net_device *in,
2106+ const struct net_device *out,
2107+ const void *matchinfo, int offset, int *hotdrop)
2108+{
2109+ const struct ipt_policy_info *info = matchinfo;
2110+ int ret;
2111+
2112+ if (info->flags & POLICY_MATCH_IN)
2113+ ret = match_policy_in(skb, info);
2114+ else
2115+ ret = match_policy_out(skb, info);
2116+
2117+ if (ret < 0) {
2118+ if (info->flags & POLICY_MATCH_NONE)
2119+ ret = 1;
2120+ else
2121+ ret = 0;
2122+ } else if (info->flags & POLICY_MATCH_NONE)
2123+ ret = 0;
2124+
2125+ return ret;
2126+}
2127+
2128+static int checkentry(const char *tablename, const struct ipt_ip *ip,
2129+ void *matchinfo, unsigned int matchsize,
2130+ unsigned int hook_mask)
2131+{
2132+ struct ipt_policy_info *info = matchinfo;
2133+
2134+ if (matchsize != IPT_ALIGN(sizeof(*info))) {
2135+ printk(KERN_ERR "ipt_policy: matchsize %u != %u\n",
2136+ matchsize, IPT_ALIGN(sizeof(*info)));
2137+ return 0;
2138+ }
2139+ if (!(info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT))) {
2140+ printk(KERN_ERR "ipt_policy: neither incoming nor "
2141+ "outgoing policy selected\n");
2142+ return 0;
2143+ }
2144+ if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
2145+ && info->flags & POLICY_MATCH_OUT) {
2146+ printk(KERN_ERR "ipt_policy: output policy not valid in "
2147+ "PRE_ROUTING and INPUT\n");
2148+ return 0;
2149+ }
2150+ if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
2151+ && info->flags & POLICY_MATCH_IN) {
2152+ printk(KERN_ERR "ipt_policy: input policy not valid in "
2153+ "POST_ROUTING and OUTPUT\n");
2154+ return 0;
2155+ }
2156+ if (info->len > POLICY_MAX_ELEM) {
2157+ printk(KERN_ERR "ipt_policy: too many policy elements\n");
2158+ return 0;
2159+ }
2160+
2161+ return 1;
2162+}
2163+
2164+static struct ipt_match policy_match =
2165+{
2166+ .name = "policy",
2167+ .match = match,
2168+ .checkentry = checkentry,
2169+ .me = THIS_MODULE,
2170+};
2171+
2172+static int __init init(void)
2173+{
2174+ return ipt_register_match(&policy_match);
2175+}
2176+
2177+static void __exit fini(void)
2178+{
2179+ ipt_unregister_match(&policy_match);
2180+}
2181+
2182+module_init(init);
2183+module_exit(fini);
2184diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_string.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_string.c
2185--- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_string.c 1970-01-01 01:00:00.000000000 +0100
2186+++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_string.c 2004-04-19 10:47:23.000000000 +0200
2187@@ -0,0 +1,178 @@
2188+/* Kernel module to match a string into a packet.
2189+ *
2190+ * Copyright (C) 2000 Emmanuel Roger <winfield@freegates.be>
2191+ *
2192+ * ChangeLog
2193+ * 19.02.2002: Gianni Tedesco <gianni@ecsc.co.uk>
2194+ * Fixed SMP re-entrancy problem using per-cpu data areas
2195+ * for the skip/shift tables.
2196+ * 02.05.2001: Gianni Tedesco <gianni@ecsc.co.uk>
2197+ * Fixed kernel panic, due to overrunning boyer moore string
2198+ * tables. Also slightly tweaked heuristic for deciding what
2199+ * search algo to use.
2200+ * 27.01.2001: Gianni Tedesco <gianni@ecsc.co.uk>
2201+ * Implemented Boyer Moore Sublinear search algorithm
2202+ * alongside the existing linear search based on memcmp().
2203+ * Also a quick check to decide which method to use on a per
2204+ * packet basis.
2205+ */
2206+
2207+#include <linux/smp.h>
2208+#include <linux/percpu.h>
2209+#include <linux/module.h>
2210+#include <linux/skbuff.h>
2211+#include <linux/file.h>
2212+#include <net/sock.h>
2213+
2214+#include <linux/netfilter_ipv4/ip_tables.h>
2215+#include <linux/netfilter_ipv4/ipt_string.h>
2216+
2217+MODULE_LICENSE("GPL");
2218+
2219+struct string_per_cpu {
2220+ int skip[BM_MAX_HLEN];
2221+ int shift[BM_MAX_HLEN];
2222+ int len[BM_MAX_HLEN];
2223+};
2224+
2225+static DEFINE_PER_CPU(struct string_per_cpu, bm_string_data);
2226+
2227+/* Boyer Moore Sublinear string search - VERY FAST */
2228+char *search_sublinear (char *needle, char *haystack, int needle_len, int haystack_len)
2229+{
2230+ int M1, right_end, sk, sh;
2231+ int ended, j, i;
2232+
2233+ int *skip, *shift, *len;
2234+
2235+ /* use data suitable for this CPU */
2ef809bd 2236+ shift=__get_cpu_var(bm_string_data).shift;
2237+ skip=__get_cpu_var(bm_string_data).skip;
2238+ len=__get_cpu_var(bm_string_data).len;
69326011 2239+
2240+ /* Setup skip/shift tables */
2241+ M1 = right_end = needle_len-1;
2242+ for (i = 0; i < BM_MAX_HLEN; i++) skip[i] = needle_len;
2243+ for (i = 0; needle[i]; i++) skip[(int)needle[i]] = M1 - i;
2244+
2245+ for (i = 1; i < needle_len; i++) {
2246+ for (j = 0; j < needle_len && needle[M1 - j] == needle[M1 - i - j]; j++);
2247+ len[i] = j;
2248+ }
2249+
2250+ shift[0] = 1;
2251+ for (i = 1; i < needle_len; i++) shift[i] = needle_len;
2252+ for (i = M1; i > 0; i--) shift[len[i]] = i;
2253+ ended = 0;
2254+
2255+ for (i = 0; i < needle_len; i++) {
2256+ if (len[i] == M1 - i) ended = i;
2257+ if (ended) shift[i] = ended;
2258+ }
2259+
2260+ /* Do the search*/
2261+ while (right_end < haystack_len)
2262+ {
2263+ for (i = 0; i < needle_len && haystack[right_end - i] == needle[M1 - i]; i++);
2264+ if (i == needle_len) {
2265+ return haystack+(right_end - M1);
2266+ }
2267+
2268+ sk = skip[(int)haystack[right_end - i]];
2269+ sh = shift[i];
2270+ right_end = max(right_end - i + sk, right_end + sh);
2271+ }
2272+
2273+ return NULL;
2274+}
2275+
2276+/* Linear string search based on memcmp() */
2277+char *search_linear (char *needle, char *haystack, int needle_len, int haystack_len)
2278+{
2279+ char *k = haystack + (haystack_len-needle_len);
2280+ char *t = haystack;
2281+
2282+ while ( t <= k ) {
2283+ if (memcmp(t, needle, needle_len) == 0)
2284+ return t;
2285+ t++;
2286+ }
2287+
2288+ return NULL;
2289+}
2290+
2291+static int
2292+match(const struct sk_buff *skb,
2293+ const struct net_device *in,
2294+ const struct net_device *out,
2295+ const void *matchinfo,
2296+ int offset,
2297+ int *hotdrop)
2298+{
2299+ const struct ipt_string_info *info = matchinfo;
2300+ struct iphdr *ip = skb->nh.iph;
2301+ int hlen, nlen;
2302+ char *needle, *haystack;
2303+ proc_ipt_search search=search_linear;
2304+
2305+ if ( !ip ) return 0;
2306+
2307+ /* get lenghts, and validate them */
2308+ nlen=info->len;
2309+ hlen=ntohs(ip->tot_len)-(ip->ihl*4);
2310+ if ( nlen > hlen ) return 0;
2311+
2312+ needle=(char *)&info->string;
2313+ haystack=(char *)ip+(ip->ihl*4);
2314+
2315+ /* The sublinear search comes in to its own
2316+ * on the larger packets */
2317+ if ( (hlen>IPT_STRING_HAYSTACK_THRESH) &&
2318+ (nlen>IPT_STRING_NEEDLE_THRESH) ) {
2319+ if ( hlen < BM_MAX_HLEN ) {
2320+ search=search_sublinear;
2321+ }else{
2322+ if (net_ratelimit())
2323+ printk(KERN_INFO "ipt_string: Packet too big "
2324+ "to attempt sublinear string search "
2325+ "(%d bytes)\n", hlen );
2326+ }
2327+ }
2328+
2329+ return ((search(needle, haystack, nlen, hlen)!=NULL) ^ info->invert);
2330+}
2331+
2332+static int
2333+checkentry(const char *tablename,
2334+ const struct ipt_ip *ip,
2335+ void *matchinfo,
2336+ unsigned int matchsize,
2337+ unsigned int hook_mask)
2338+{
2339+
2340+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_string_info)))
2341+ return 0;
2342+
2343+ return 1;
2344+}
2345+
2346+
2347+static struct ipt_match string_match = {
2348+ .name = "string",
2349+ .match = &match,
2350+ .checkentry = &checkentry,
2351+ .me = THIS_MODULE
2352+};
2353+
2354+static int __init init(void)
2355+{
2356+ return ipt_register_match(&string_match);
2357+}
2358+
2359+static void __exit fini(void)
2360+{
2361+ ipt_unregister_match(&string_match);
2362+}
2363+
2364+module_init(init);
2365+module_exit(fini);
2366diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_unclean.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_unclean.c
2367--- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_unclean.c 1970-01-01 01:00:00.000000000 +0100
2368+++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_unclean.c 2004-04-19 10:47:12.000000000 +0200
2369@@ -0,0 +1,604 @@
2370+/* Kernel module to match suspect packets. */
2371+#include <linux/module.h>
2372+#include <linux/skbuff.h>
2373+#include <linux/ip.h>
2374+#include <linux/udp.h>
2375+#include <linux/tcp.h>
2376+#include <linux/icmp.h>
2377+#include <net/checksum.h>
2378+
2379+#include <linux/netfilter_ipv4/ip_tables.h>
2380+
2381+#define limpk(format, args...) \
2382+do { \
2383+ if (net_ratelimit()) \
2384+ printk("ipt_unclean: %s" format, \
2385+ embedded ? "(embedded packet) " : "" , ## args); \
2386+} while(0)
2387+
2388+enum icmp_error_status
2389+{
2390+ ICMP_MAY_BE_ERROR,
2391+ ICMP_IS_ERROR,
2392+ ICMP_NOT_ERROR
2393+};
2394+
2395+struct icmp_info
2396+{
2397+ size_t min_len, max_len;
2398+ enum icmp_error_status err;
2399+ u_int8_t min_code, max_code;
2400+};
2401+
2402+static int
2403+check_ip(struct iphdr *iph, size_t length, int embedded);
2404+
2405+/* ICMP-specific checks. */
2406+static int
2407+check_icmp(const struct icmphdr *icmph,
2408+ u_int16_t datalen,
2409+ unsigned int offset,
2410+ int more_frags,
2411+ int embedded)
2412+{
2413+ static struct icmp_info info[]
2414+ = { [ICMP_ECHOREPLY]
2415+ = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
2416+ [ICMP_DEST_UNREACH]
2417+ = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 15 },
2418+ [ICMP_SOURCE_QUENCH]
2419+ = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 0 },
2420+ [ICMP_REDIRECT]
2421+ = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 3 },
2422+ [ICMP_ECHO]
2423+ = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
2424+ /* Router advertisement. */
2425+ [9]
2426+ = { 8, 8 + 255 * 8, ICMP_NOT_ERROR, 0, 0 },
2427+ /* Router solicitation. */
2428+ [10]
2429+ = { 8, 8, ICMP_NOT_ERROR, 0, 0 },
2430+ [ICMP_TIME_EXCEEDED]
2431+ = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 1 },
2432+ [ICMP_PARAMETERPROB]
2433+ = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 1 },
2434+ [ICMP_TIMESTAMP]
2435+ = { 20, 20, ICMP_NOT_ERROR, 0, 0 },
2436+ [ICMP_TIMESTAMPREPLY]
2437+ = { 20, 20, ICMP_NOT_ERROR, 0, 0 },
2438+ [ICMP_INFO_REQUEST]
2439+ = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
2440+ [ICMP_INFO_REPLY]
2441+ = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
2442+ [ICMP_ADDRESS]
2443+ = { 12, 12, ICMP_NOT_ERROR, 0, 0 },
2444+ [ICMP_ADDRESSREPLY]
2445+ = { 12, 12, ICMP_NOT_ERROR, 0, 0 } };
2446+
2447+ /* Can't do anything if it's a fragment. */
2448+ if (offset)
2449+ return 1;
2450+
2451+ /* Must cover type and code. */
2452+ if (datalen < 2) {
2453+ limpk("ICMP len=%u too short\n", datalen);
2454+ return 0;
2455+ }
2456+
2457+ /* If not embedded. */
2458+ if (!embedded) {
2459+ /* Bad checksum? Don't print, just ignore. */
2460+ if (!more_frags
2461+ && ip_compute_csum((unsigned char *) icmph, datalen) != 0)
2462+ return 0;
2463+
2464+ /* CHECK: Truncated ICMP (even if first fragment). */
2465+ if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
2466+ && info[icmph->type].min_len != 0
2467+ && datalen < info[icmph->type].min_len) {
2468+ limpk("ICMP type %u len %u too short\n",
2469+ icmph->type, datalen);
2470+ return 0;
2471+ }
2472+
2473+ /* CHECK: Check within known error ICMPs. */
2474+ if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
2475+ && info[icmph->type].err == ICMP_IS_ERROR) {
2476+ /* CHECK: Embedded packet must be at least
2477+ length of iph + 8 bytes. */
2478+ struct iphdr *inner = (void *)icmph + 8;
2479+
2480+ /* datalen > 8 since all ICMP_IS_ERROR types
2481+ have min length > 8 */
2482+ if (datalen - 8 < sizeof(struct iphdr)) {
2483+ limpk("ICMP error internal way too short\n");
2484+ return 0;
2485+ }
2486+ if (datalen - 8 < inner->ihl*4 + 8) {
2487+ limpk("ICMP error internal too short\n");
2488+ return 0;
2489+ }
2490+ if (!check_ip(inner, datalen - 8, 1))
2491+ return 0;
2492+ }
2493+ } else {
2494+ /* CHECK: Can't embed ICMP unless known non-error. */
2495+ if (icmph->type >= sizeof(info)/sizeof(struct icmp_info)
2496+ || info[icmph->type].err != ICMP_NOT_ERROR) {
2497+ limpk("ICMP type %u not embeddable\n",
2498+ icmph->type);
2499+ return 0;
2500+ }
2501+ }
2502+
2503+ /* CHECK: Invalid ICMP codes. */
2504+ if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
2505+ && (icmph->code < info[icmph->type].min_code
2506+ || icmph->code > info[icmph->type].max_code)) {
2507+ limpk("ICMP type=%u code=%u\n",
2508+ icmph->type, icmph->code);
2509+ return 0;
2510+ }
2511+
2512+ /* CHECK: Above maximum length. */
2513+ if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
2514+ && info[icmph->type].max_len != 0
2515+ && datalen > info[icmph->type].max_len) {
2516+ limpk("ICMP type=%u too long: %u bytes\n",
2517+ icmph->type, datalen);
2518+ return 0;
2519+ }
2520+
2521+ switch (icmph->type) {
2522+ case ICMP_PARAMETERPROB: {
2523+ /* CHECK: Problem param must be within error packet's
2524+ * IP header. */
2525+ struct iphdr *iph = (void *)icmph + 8;
2526+ u_int32_t arg = ntohl(icmph->un.gateway);
2527+
2528+ if (icmph->code == 0) {
2529+ /* Code 0 means that upper 8 bits is pointer
2530+ to problem. */
2531+ if ((arg >> 24) >= iph->ihl*4) {
2532+ limpk("ICMP PARAMETERPROB ptr = %u\n",
2533+ ntohl(icmph->un.gateway) >> 24);
2534+ return 0;
2535+ }
2536+ arg &= 0x00FFFFFF;
2537+ }
2538+
2539+ /* CHECK: Rest must be zero. */
2540+ if (arg) {
2541+ limpk("ICMP PARAMETERPROB nonzero arg = %u\n",
2542+ arg);
2543+ return 0;
2544+ }
2545+ break;
2546+ }
2547+
2548+ case ICMP_TIME_EXCEEDED:
2549+ case ICMP_SOURCE_QUENCH:
2550+ /* CHECK: Unused must be zero. */
2551+ if (icmph->un.gateway != 0) {
2552+ limpk("ICMP type=%u unused = %u\n",
2553+ icmph->type, ntohl(icmph->un.gateway));
2554+ return 0;
2555+ }
2556+ break;
2557+ }
2558+
2559+ return 1;
2560+}
2561+
2562+/* UDP-specific checks. */
2563+static int
2564+check_udp(const struct iphdr *iph,
2565+ const struct udphdr *udph,
2566+ u_int16_t datalen,
2567+ unsigned int offset,
2568+ int more_frags,
2569+ int embedded)
2570+{
2571+ /* Can't do anything if it's a fragment. */
2572+ if (offset)
2573+ return 1;
2574+
2575+ /* CHECK: Must cover UDP header. */
2576+ if (datalen < sizeof(struct udphdr)) {
2577+ limpk("UDP len=%u too short\n", datalen);
2578+ return 0;
2579+ }
2580+
2581+ /* Bad checksum? Don't print, just say it's unclean. */
2582+ /* FIXME: SRC ROUTE packets won't match checksum --RR */
2583+ if (!more_frags && !embedded && udph->check
2584+ && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_UDP,
2585+ csum_partial((char *)udph, datalen, 0)) != 0)
2586+ return 0;
2587+
2588+ /* CHECK: Destination port can't be zero. */
2589+ if (!udph->dest) {
2590+ limpk("UDP zero destination port\n");
2591+ return 0;
2592+ }
2593+
2594+ if (!more_frags) {
2595+ if (!embedded) {
2596+ /* CHECK: UDP length must match. */
2597+ if (ntohs(udph->len) != datalen) {
2598+ limpk("UDP len too short %u vs %u\n",
2599+ ntohs(udph->len), datalen);
2600+ return 0;
2601+ }
2602+ } else {
2603+ /* CHECK: UDP length be >= this truncated pkt. */
2604+ if (ntohs(udph->len) < datalen) {
2605+ limpk("UDP len too long %u vs %u\n",
2606+ ntohs(udph->len), datalen);
2607+ return 0;
2608+ }
2609+ }
2610+ } else {
2611+ /* CHECK: UDP length must be > this frag's length. */
2612+ if (ntohs(udph->len) <= datalen) {
2613+ limpk("UDP fragment len too short %u vs %u\n",
2614+ ntohs(udph->len), datalen);
2615+ return 0;
2616+ }
2617+ }
2618+
2619+ return 1;
2620+}
2621+
2622+#define TH_FIN 0x01
2623+#define TH_SYN 0x02
2624+#define TH_RST 0x04
2625+#define TH_PUSH 0x08
2626+#define TH_ACK 0x10
2627+#define TH_URG 0x20
2628+#define TH_ECE 0x40
2629+#define TH_CWR 0x80
2630+
2631+/* table of valid flag combinations - ECE and CWR are always valid */
2632+static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
2633+{
2634+ [TH_SYN] = 1,
2635+ [TH_SYN|TH_ACK] = 1,
2636+ [TH_RST] = 1,
2637+ [TH_RST|TH_ACK] = 1,
2638+ [TH_RST|TH_ACK|TH_PUSH] = 1,
2639+ [TH_FIN|TH_ACK] = 1,
2640+ [TH_ACK] = 1,
2641+ [TH_ACK|TH_PUSH] = 1,
2642+ [TH_ACK|TH_URG] = 1,
2643+ [TH_ACK|TH_URG|TH_PUSH] = 1,
2644+ [TH_FIN|TH_ACK|TH_PUSH] = 1,
2645+ [TH_FIN|TH_ACK|TH_URG] = 1,
2646+ [TH_FIN|TH_ACK|TH_URG|TH_PUSH] = 1
2647+};
2648+
2649+/* TCP-specific checks. */
2650+static int
2651+check_tcp(const struct iphdr *iph,
2652+ const struct tcphdr *tcph,
2653+ u_int16_t datalen,
2654+ unsigned int offset,
2655+ int more_frags,
2656+ int embedded)
2657+{
2658+ u_int8_t *opt = (u_int8_t *)tcph;
2659+ u_int8_t *endhdr = (u_int8_t *)tcph + tcph->doff * 4;
2660+ u_int8_t tcpflags;
2661+ int end_of_options = 0;
2662+ size_t i;
2663+
2664+ /* CHECK: Can't have offset=1: used to override TCP syn-checks. */
2665+ /* In fact, this is caught below (offset < 516). */
2666+
2667+ /* Can't do anything if it's a fragment. */
2668+ if (offset)
2669+ return 1;
2670+
2671+ /* CHECK: Smaller than minimal TCP hdr. */
2672+ if (datalen < sizeof(struct tcphdr)) {
2673+ if (!embedded) {
2674+ limpk("Packet length %u < TCP header.\n", datalen);
2675+ return 0;
2676+ }
2677+ /* Must have ports available (datalen >= 8), from
2678+ check_icmp which set embedded = 1 */
2679+ /* CHECK: TCP ports inside ICMP error */
2680+ if (!tcph->source || !tcph->dest) {
2681+ limpk("Zero TCP ports %u/%u.\n",
2682+ htons(tcph->source), htons(tcph->dest));
2683+ return 0;
2684+ }
2685+ return 1;
2686+ }
2687+
2688+ /* CHECK: Smaller than actual TCP hdr. */
2689+ if (datalen < tcph->doff * 4) {
2690+ if (!embedded) {
2691+ limpk("Packet length %u < actual TCP header.\n",
2692+ datalen);
2693+ return 0;
2694+ } else
2695+ return 1;
2696+ }
2697+
2698+ /* Bad checksum? Don't print, just say it's unclean. */
2699+ /* FIXME: SRC ROUTE packets won't match checksum --RR */
2700+ if (!more_frags && !embedded
2701+ && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_TCP,
2702+ csum_partial((char *)tcph, datalen, 0)) != 0)
2703+ return 0;
2704+
2705+ /* CHECK: TCP ports non-zero */
2706+ if (!tcph->source || !tcph->dest) {
2707+ limpk("Zero TCP ports %u/%u.\n",
2708+ htons(tcph->source), htons(tcph->dest));
2709+ return 0;
2710+ }
2711+
2712+ /* CHECK: TCP reserved bits zero. */
2713+ if(tcp_flag_word(tcph) & TCP_RESERVED_BITS) {
2714+ limpk("TCP reserved bits not zero\n");
2715+ return 0;
2716+ }
2717+
2718+ /* CHECK: TCP flags. */
2719+ tcpflags = (((u_int8_t *)tcph)[13] & ~(TH_ECE|TH_CWR));
2720+ if (!tcp_valid_flags[tcpflags]) {
2721+ limpk("TCP flags bad: %u\n", tcpflags);
2722+ return 0;
2723+ }
2724+
2725+ for (i = sizeof(struct tcphdr); i < tcph->doff * 4; ) {
2726+ switch (opt[i]) {
2727+ case 0:
2728+ end_of_options = 1;
2729+ i++;
2730+ break;
2731+ case 1:
2732+ i++;
2733+ break;
2734+ default:
2735+ /* CHECK: options after EOO. */
2736+ if (end_of_options) {
2737+ limpk("TCP option %u after end\n",
2738+ opt[i]);
2739+ return 0;
2740+ }
2741+ /* CHECK: options at tail. */
2742+ else if (i+1 >= tcph->doff * 4) {
2743+ limpk("TCP option %u at tail\n",
2744+ opt[i]);
2745+ return 0;
2746+ }
2747+ /* CHECK: zero-length options. */
2748+ else if (opt[i+1] == 0) {
2749+ limpk("TCP option %u 0 len\n",
2750+ opt[i]);
2751+ return 0;
2752+ }
2753+ /* CHECK: oversize options. */
2754+ else if (&opt[i] + opt[i+1] > endhdr) {
2755+ limpk("TCP option %u at %Zu too long\n",
2756+ (unsigned int) opt[i], i);
2757+ return 0;
2758+ }
2759+ /* Move to next option */
2760+ i += opt[i+1];
2761+ }
2762+ }
2763+
2764+ return 1;
2765+}
2766+
2767+/* Returns 1 if ok */
2768+/* Standard IP checks. */
2769+static int
2770+check_ip(struct iphdr *iph, size_t length, int embedded)
2771+{
2772+ u_int8_t *opt = (u_int8_t *)iph;
2773+ u_int8_t *endhdr = (u_int8_t *)iph + iph->ihl * 4;
2774+ int end_of_options = 0;
2775+ void *protoh;
2776+ size_t datalen;
2777+ unsigned int i;
2778+ unsigned int offset;
2779+
2780+ /* Should only happen for local outgoing raw-socket packets. */
2781+ /* CHECK: length >= ip header. */
2782+ if (length < sizeof(struct iphdr) || length < iph->ihl * 4) {
2783+ limpk("Packet length %Zu < IP header.\n", length);
2784+ return 0;
2785+ }
2786+
2787+ offset = ntohs(iph->frag_off) & IP_OFFSET;
2788+ protoh = (void *)iph + iph->ihl * 4;
2789+ datalen = length - iph->ihl * 4;
2790+
2791+ /* CHECK: Embedded fragment. */
2792+ if (embedded && offset) {
2793+ limpk("Embedded fragment.\n");
2794+ return 0;
2795+ }
2796+
2797+ for (i = sizeof(struct iphdr); i < iph->ihl * 4; ) {
2798+ switch (opt[i]) {
2799+ case 0:
2800+ end_of_options = 1;
2801+ i++;
2802+ break;
2803+ case 1:
2804+ i++;
2805+ break;
2806+ default:
2807+ /* CHECK: options after EOO. */
2808+ if (end_of_options) {
2809+ limpk("IP option %u after end\n",
2810+ opt[i]);
2811+ return 0;
2812+ }
2813+ /* CHECK: options at tail. */
2814+ else if (i+1 >= iph->ihl * 4) {
2815+ limpk("IP option %u at tail\n",
2816+ opt[i]);
2817+ return 0;
2818+ }
2819+ /* CHECK: zero-length or one-length options. */
2820+ else if (opt[i+1] < 2) {
2821+ limpk("IP option %u %u len\n",
2822+ opt[i], opt[i+1]);
2823+ return 0;
2824+ }
2825+ /* CHECK: oversize options. */
2826+ else if (&opt[i] + opt[i+1] > endhdr) {
2827+ limpk("IP option %u at %u too long\n",
2828+ opt[i], i);
2829+ return 0;
2830+ }
2831+ /* Move to next option */
2832+ i += opt[i+1];
2833+ }
2834+ }
2835+
2836+ /* Fragment checks. */
2837+
2838+ /* CHECK: More fragments, but doesn't fill 8-byte boundary. */
2839+ if ((ntohs(iph->frag_off) & IP_MF)
2840+ && (ntohs(iph->tot_len) % 8) != 0) {
2841+ limpk("Truncated fragment %u long.\n", ntohs(iph->tot_len));
2842+ return 0;
2843+ }
2844+
2845+ /* CHECK: Oversize fragment a-la Ping of Death. */
2846+ if (offset * 8 + datalen > 65535) {
2847+ limpk("Oversize fragment to %u.\n", offset * 8);
2848+ return 0;
2849+ }
2850+
2851+ /* CHECK: DF set and offset or MF set. */
2852+ if ((ntohs(iph->frag_off) & IP_DF)
2853+ && (offset || (ntohs(iph->frag_off) & IP_MF))) {
2854+ limpk("DF set and offset=%u, MF=%u.\n",
2855+ offset, ntohs(iph->frag_off) & IP_MF);
2856+ return 0;
2857+ }
2858+
2859+ /* CHECK: Zero-sized fragments. */
2860+ if ((offset || (ntohs(iph->frag_off) & IP_MF))
2861+ && datalen == 0) {
2862+ limpk("Zero size fragment offset=%u\n", offset);
2863+ return 0;
2864+ }
2865+
2866+ /* Note: we can have even middle fragments smaller than this:
2867+ consider a large packet passing through a 600MTU then
2868+ 576MTU link: this gives a fragment of 24 data bytes. But
2869+ everyone packs fragments largest first, hence a fragment
2870+ can't START before 576 - MAX_IP_HEADER_LEN. */
2871+
2872+ /* Used to be min-size 576: I recall Alan Cox saying ax25 goes
2873+ down to 128 (576 taken from RFC 791: All hosts must be
2874+ prepared to accept datagrams of up to 576 octets). Use 128
2875+ here. */
2876+#define MIN_LIKELY_MTU 128
2877+ /* CHECK: Min size of first frag = 128. */
2878+ if ((ntohs(iph->frag_off) & IP_MF)
2879+ && offset == 0
2880+ && ntohs(iph->tot_len) < MIN_LIKELY_MTU) {
2881+ limpk("First fragment size %u < %u\n", ntohs(iph->tot_len),
2882+ MIN_LIKELY_MTU);
2883+ return 0;
2884+ }
2885+
2886+ /* CHECK: Min offset of frag = 128 - IP hdr len. */
2887+ if (offset && offset * 8 < MIN_LIKELY_MTU - iph->ihl * 4) {
2888+ limpk("Fragment starts at %u < %u\n", offset * 8,
2889+ MIN_LIKELY_MTU - iph->ihl * 4);
2890+ return 0;
2891+ }
2892+
2893+ /* CHECK: Protocol specification non-zero. */
2894+ if (iph->protocol == 0) {
2895+ limpk("Zero protocol\n");
2896+ return 0;
2897+ }
2898+
2899+ /* CHECK: Do not use what is unused.
2900+ * First bit of fragmentation flags should be unused.
2901+ * May be used by OS fingerprinting tools.
2902+ * 04 Jun 2002, Maciej Soltysiak, solt@dns.toxicfilms.tv
2903+ */
2904+ if (ntohs(iph->frag_off)>>15) {
2905+ limpk("IP unused bit set\n");
2906+ return 0;
2907+ }
2908+
2909+ /* Per-protocol checks. */
2910+ switch (iph->protocol) {
2911+ case IPPROTO_ICMP:
2912+ return check_icmp(protoh, datalen, offset,
2913+ (ntohs(iph->frag_off) & IP_MF),
2914+ embedded);
2915+
2916+ case IPPROTO_UDP:
2917+ return check_udp(iph, protoh, datalen, offset,
2918+ (ntohs(iph->frag_off) & IP_MF),
2919+ embedded);
2920+
2921+ case IPPROTO_TCP:
2922+ return check_tcp(iph, protoh, datalen, offset,
2923+ (ntohs(iph->frag_off) & IP_MF),
2924+ embedded);
2925+ default:
2926+ /* Ignorance is bliss. */
2927+ return 1;
2928+ }
2929+}
2930+
2931+static int
2932+match(const struct sk_buff *skb,
2933+ const struct net_device *in,
2934+ const struct net_device *out,
2935+ const void *matchinfo,
2936+ int offset,
2937+ const void *hdr,
2938+ u_int16_t datalen,
2939+ int *hotdrop)
2940+{
2941+ return !check_ip(skb->nh.iph, skb->len, 0);
2942+}
2943+
2944+/* Called when user tries to insert an entry of this type. */
2945+static int
2946+checkentry(const char *tablename,
2947+ const struct ipt_ip *ip,
2948+ void *matchinfo,
2949+ unsigned int matchsize,
2950+ unsigned int hook_mask)
2951+{
2952+ if (matchsize != IPT_ALIGN(0))
2953+ return 0;
2954+
2955+ return 1;
2956+}
2957+
2958+static struct ipt_match unclean_match
2959+= { { NULL, NULL }, "unclean", &match, &checkentry, NULL, THIS_MODULE };
2960+
2961+static int __init init(void)
2962+{
2963+ return ipt_register_match(&unclean_match);
2964+}
2965+
2966+static void __exit fini(void)
2967+{
2968+ ipt_unregister_match(&unclean_match);
2969+}
2970+
2971+module_init(init);
2972+module_exit(fini);
2973+MODULE_LICENSE("GPL");
2974diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/tcp_ipv4.c linux-2.6.6-rc1/net/ipv4/tcp_ipv4.c
2975--- linux-2.6.6-rc1.org/net/ipv4/tcp_ipv4.c 2004-04-15 03:34:35.000000000 +0200
2976+++ linux-2.6.6-rc1/net/ipv4/tcp_ipv4.c 2004-04-19 10:46:08.000000000 +0200
2977@@ -2670,6 +2670,7 @@
2978 EXPORT_SYMBOL(tcp_v4_connect);
2979 EXPORT_SYMBOL(tcp_v4_do_rcv);
2980 EXPORT_SYMBOL(tcp_v4_lookup_listener);
2981+EXPORT_SYMBOL(tcp_v4_lookup);
2982 EXPORT_SYMBOL(tcp_v4_rebuild_header);
2983 EXPORT_SYMBOL(tcp_v4_remember_stamp);
2984 EXPORT_SYMBOL(tcp_v4_send_check);
2985diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/udp.c linux-2.6.6-rc1/net/ipv4/udp.c
2986--- linux-2.6.6-rc1.org/net/ipv4/udp.c 2004-04-19 10:38:52.000000000 +0200
2987+++ linux-2.6.6-rc1/net/ipv4/udp.c 2004-04-19 10:46:08.000000000 +0200
2988@@ -1558,6 +1558,7 @@
2989 EXPORT_SYMBOL(udp_port_rover);
2990 EXPORT_SYMBOL(udp_prot);
2991 EXPORT_SYMBOL(udp_sendmsg);
2992+EXPORT_SYMBOL(udp_v4_lookup);
2993
2994 #ifdef CONFIG_PROC_FS
2995 EXPORT_SYMBOL(udp_proc_register);
This page took 0.356677 seconds and 4 git commands to generate.