]> git.pld-linux.org Git - packages/kernel.git/blame - 2.6-p-o-m-ng-20040130.patch
- obsolete
[packages/kernel.git] / 2.6-p-o-m-ng-20040130.patch
CommitLineData
8098cf9b 1diff -Nur linux-2.6.2-rc2.org/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.2-rc2/include/linux/netfilter_ipv4/ip_conntrack.h
2--- linux-2.6.2-rc2.org/include/linux/netfilter_ipv4/ip_conntrack.h 2004-01-26 03:31:19.000000000 +0100
3+++ linux-2.6.2-rc2/include/linux/netfilter_ipv4/ip_conntrack.h 2004-01-30 12:25:22.000000000 +0100
4@@ -206,6 +206,9 @@
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 /* get master conntrack via master expectation */
14diff -Nur linux-2.6.2-rc2.org/include/linux/netfilter_ipv4/ipt_CONNMARK.h linux-2.6.2-rc2/include/linux/netfilter_ipv4/ipt_CONNMARK.h
15--- linux-2.6.2-rc2.org/include/linux/netfilter_ipv4/ipt_CONNMARK.h 1970-01-01 01:00:00.000000000 +0100
16+++ linux-2.6.2-rc2/include/linux/netfilter_ipv4/ipt_CONNMARK.h 2004-01-30 12:25:22.000000000 +0100
17@@ -0,0 +1,15 @@
18+#ifndef _IPT_CONNMARK_H_target
19+#define _IPT_CONNMARK_H_target
20+
21+enum {
22+ IPT_CONNMARK_SET = 0,
23+ IPT_CONNMARK_SAVE,
24+ IPT_CONNMARK_RESTORE
25+};
26+
27+struct ipt_connmark_target_info {
28+ unsigned long mark;
29+ u_int8_t mode;
30+};
31+
32+#endif /*_IPT_CONNMARK_H_target*/
33diff -Nur linux-2.6.2-rc2.org/include/linux/netfilter_ipv4/ipt_TTL.h linux-2.6.2-rc2/include/linux/netfilter_ipv4/ipt_TTL.h
34--- linux-2.6.2-rc2.org/include/linux/netfilter_ipv4/ipt_TTL.h 1970-01-01 01:00:00.000000000 +0100
35+++ linux-2.6.2-rc2/include/linux/netfilter_ipv4/ipt_TTL.h 2004-01-30 12:25:07.000000000 +0100
36@@ -0,0 +1,21 @@
37+/* TTL modification module for IP tables
38+ * (C) 2000 by Harald Welte <laforge@gnumonks.org> */
39+
40+#ifndef _IPT_TTL_H
41+#define _IPT_TTL_H
42+
43+enum {
44+ IPT_TTL_SET = 0,
45+ IPT_TTL_INC,
46+ IPT_TTL_DEC
47+};
48+
49+#define IPT_TTL_MAXMODE IPT_TTL_DEC
50+
51+struct ipt_TTL_info {
52+ u_int8_t mode;
53+ u_int8_t ttl;
54+};
55+
56+
57+#endif
58diff -Nur linux-2.6.2-rc2.org/include/linux/netfilter_ipv4/ipt_connlimit.h linux-2.6.2-rc2/include/linux/netfilter_ipv4/ipt_connlimit.h
59--- linux-2.6.2-rc2.org/include/linux/netfilter_ipv4/ipt_connlimit.h 1970-01-01 01:00:00.000000000 +0100
60+++ linux-2.6.2-rc2/include/linux/netfilter_ipv4/ipt_connlimit.h 2004-01-30 12:25:34.000000000 +0100
61@@ -0,0 +1,12 @@
62+#ifndef _IPT_CONNLIMIT_H
63+#define _IPT_CONNLIMIT_H
64+
65+struct ipt_connlimit_data;
66+
67+struct ipt_connlimit_info {
68+ int limit;
69+ int inverse;
70+ u_int32_t mask;
71+ struct ipt_connlimit_data *data;
72+};
73+#endif /* _IPT_CONNLIMIT_H */
74diff -Nur linux-2.6.2-rc2.org/include/linux/netfilter_ipv4/ipt_connmark.h linux-2.6.2-rc2/include/linux/netfilter_ipv4/ipt_connmark.h
75--- linux-2.6.2-rc2.org/include/linux/netfilter_ipv4/ipt_connmark.h 1970-01-01 01:00:00.000000000 +0100
76+++ linux-2.6.2-rc2/include/linux/netfilter_ipv4/ipt_connmark.h 2004-01-30 12:25:22.000000000 +0100
77@@ -0,0 +1,9 @@
78+#ifndef _IPT_CONNMARK_H
79+#define _IPT_CONNMARK_H
80+
81+struct ipt_connmark_info {
82+ unsigned long mark, mask;
83+ u_int8_t invert;
84+};
85+
86+#endif /*_IPT_CONNMARK_H*/
87diff -Nur linux-2.6.2-rc2.org/include/linux/netfilter_ipv4/ipt_mport.h linux-2.6.2-rc2/include/linux/netfilter_ipv4/ipt_mport.h
88--- linux-2.6.2-rc2.org/include/linux/netfilter_ipv4/ipt_mport.h 1970-01-01 01:00:00.000000000 +0100
89+++ linux-2.6.2-rc2/include/linux/netfilter_ipv4/ipt_mport.h 2004-01-30 12:25:56.000000000 +0100
90@@ -0,0 +1,24 @@
91+#ifndef _IPT_MPORT_H
92+#define _IPT_MPORT_H
93+#include <linux/netfilter_ipv4/ip_tables.h>
94+
95+#define IPT_MPORT_SOURCE (1<<0)
96+#define IPT_MPORT_DESTINATION (1<<1)
97+#define IPT_MPORT_EITHER (IPT_MPORT_SOURCE|IPT_MPORT_DESTINATION)
98+
99+#define IPT_MULTI_PORTS 15
100+
101+/* Must fit inside union ipt_matchinfo: 32 bytes */
102+/* every entry in ports[] except for the last one has one bit in pflags
103+ * associated with it. If this bit is set, the port is the first port of
104+ * a portrange, with the next entry being the last.
105+ * End of list is marked with pflags bit set and port=65535.
106+ * If 14 ports are used (last one does not have a pflag), the last port
107+ * is repeated to fill the last entry in ports[] */
108+struct ipt_mport
109+{
110+ u_int8_t flags:2; /* Type of comparison */
111+ u_int16_t pflags:14; /* Port flags */
112+ u_int16_t ports[IPT_MULTI_PORTS]; /* Ports */
113+};
114+#endif /*_IPT_MPORT_H*/
115diff -Nur linux-2.6.2-rc2.org/include/linux/netfilter_ipv4/ipt_nth.h linux-2.6.2-rc2/include/linux/netfilter_ipv4/ipt_nth.h
116--- linux-2.6.2-rc2.org/include/linux/netfilter_ipv4/ipt_nth.h 1970-01-01 01:00:00.000000000 +0100
117+++ linux-2.6.2-rc2/include/linux/netfilter_ipv4/ipt_nth.h 2004-01-30 12:26:19.000000000 +0100
118@@ -0,0 +1,19 @@
119+#ifndef _IPT_NTH_H
120+#define _IPT_NTH_H
121+
122+#include <linux/param.h>
123+#include <linux/types.h>
124+
125+#ifndef IPT_NTH_NUM_COUNTERS
126+#define IPT_NTH_NUM_COUNTERS 16
127+#endif
128+
129+struct ipt_nth_info {
130+ u_int8_t every;
131+ u_int8_t not;
132+ u_int8_t startat;
133+ u_int8_t counter;
134+ u_int8_t packet;
135+};
136+
137+#endif /*_IPT_NTH_H*/
138diff -Nur linux-2.6.2-rc2.org/include/linux/netfilter_ipv4/ipt_u32.h linux-2.6.2-rc2/include/linux/netfilter_ipv4/ipt_u32.h
139--- linux-2.6.2-rc2.org/include/linux/netfilter_ipv4/ipt_u32.h 1970-01-01 01:00:00.000000000 +0100
140+++ linux-2.6.2-rc2/include/linux/netfilter_ipv4/ipt_u32.h 2004-01-30 12:25:44.000000000 +0100
141@@ -0,0 +1,40 @@
142+#ifndef _IPT_U32_H
143+#define _IPT_U32_H
144+#include <linux/netfilter_ipv4/ip_tables.h>
145+
146+enum ipt_u32_ops
147+{
148+ IPT_U32_AND,
149+ IPT_U32_LEFTSH,
150+ IPT_U32_RIGHTSH,
151+ IPT_U32_AT
152+};
153+
154+struct ipt_u32_location_element
155+{
156+ u_int32_t number;
157+ u_int8_t nextop;
158+};
159+struct ipt_u32_value_element
160+{
161+ u_int32_t min;
162+ u_int32_t max;
163+};
164+/* *** any way to allow for an arbitrary number of elements?
165+ for now I settle for a limit of 10 of each */
166+#define U32MAXSIZE 10
167+struct ipt_u32_test
168+{
169+ u_int8_t nnums;
170+ struct ipt_u32_location_element location[U32MAXSIZE+1];
171+ u_int8_t nvalues;
172+ struct ipt_u32_value_element value[U32MAXSIZE+1];
173+};
174+
175+struct ipt_u32
176+{
177+ u_int8_t ntests;
178+ struct ipt_u32_test tests[U32MAXSIZE+1];
179+};
180+
181+#endif /*_IPT_U32_H*/
182diff -Nur linux-2.6.2-rc2.org/include/linux/netfilter_ipv6/ip6t_REJECT.h linux-2.6.2-rc2/include/linux/netfilter_ipv6/ip6t_REJECT.h
183--- linux-2.6.2-rc2.org/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-01-26 03:29:50.000000000 +0100
184+++ linux-2.6.2-rc2/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-01-30 12:26:08.000000000 +0100
185@@ -2,15 +2,17 @@
186 #define _IP6T_REJECT_H
187
188 enum ip6t_reject_with {
189- IP6T_ICMP_NET_UNREACHABLE,
190- IP6T_ICMP_HOST_UNREACHABLE,
191- IP6T_ICMP_PROT_UNREACHABLE,
192- IP6T_ICMP_PORT_UNREACHABLE,
193- IP6T_ICMP_ECHOREPLY
194+ IP6T_ICMP6_NO_ROUTE,
195+ IP6T_ICMP6_ADM_PROHIBITED,
196+ IP6T_ICMP6_NOT_NEIGHBOUR,
197+ IP6T_ICMP6_ADDR_UNREACH,
198+ IP6T_ICMP6_PORT_UNREACH,
199+ IP6T_ICMP6_ECHOREPLY,
200+ IP6T_TCP_RESET
201 };
202
203 struct ip6t_reject_info {
204 enum ip6t_reject_with with; /* reject type */
205 };
206
207-#endif /*_IPT_REJECT_H*/
208+#endif /*_IP6T_REJECT_H*/
209diff -Nur linux-2.6.2-rc2.org/include/linux/netfilter_ipv6/ip6t_nth.h linux-2.6.2-rc2/include/linux/netfilter_ipv6/ip6t_nth.h
210--- linux-2.6.2-rc2.org/include/linux/netfilter_ipv6/ip6t_nth.h 1970-01-01 01:00:00.000000000 +0100
211+++ linux-2.6.2-rc2/include/linux/netfilter_ipv6/ip6t_nth.h 2004-01-30 12:26:19.000000000 +0100
212@@ -0,0 +1,19 @@
213+#ifndef _IP6T_NTH_H
214+#define _IP6T_NTH_H
215+
216+#include <linux/param.h>
217+#include <linux/types.h>
218+
219+#ifndef IP6T_NTH_NUM_COUNTERS
220+#define IP6T_NTH_NUM_COUNTERS 16
221+#endif
222+
223+struct ip6t_nth_info {
224+ u_int8_t every;
225+ u_int8_t not;
226+ u_int8_t startat;
227+ u_int8_t counter;
228+ u_int8_t packet;
229+};
230+
231+#endif /*_IP6T_NTH_H*/
232diff -Nur linux-2.6.2-rc2.org/net/ipv4/netfilter/Kconfig linux-2.6.2-rc2/net/ipv4/netfilter/Kconfig
233--- linux-2.6.2-rc2.org/net/ipv4/netfilter/Kconfig 2004-01-26 03:31:15.000000000 +0100
234+++ linux-2.6.2-rc2/net/ipv4/netfilter/Kconfig 2004-01-30 12:26:19.000000000 +0100
235@@ -579,5 +579,140 @@
236
237 To compile it as a module, choose M here. If unsure, say N.
238
239+config IP_NF_TARGET_TTL
240+ tristate 'TTL target support'
241+ depends on IP_NF_MANGLE
242+ help
243+ This adds an iptables TTL manipulation target, which enables the user
244+ to set the TTL value of an IP packet or to increment / decrement it
245+ by a given value.
246+
247+config IP_NF_CONNTRACK_MARK
248+ bool 'Connection mark tracking support'
249+config IP_NF_TARGET_CONNMARK
250+ tristate 'CONNMARK target support'
251+ depends on IP_NF_MANGLE
252+config IP_NF_MATCH_CONNMARK
253+ tristate ' Connection mark match support'
254+ depends on IP_NF_IPTABLES
255+ help
256+
257+ This patch adds per connection marks, and a target (CONNMARK)
258+ respective a match (connmark) for using these.
259+
260+ Usage:
261+
262+ connmark
263+ This module matches the netfilter mark field associated
264+ with a connection (which can be set using the CONNMARK
265+ target below).
266+
267+ --mark value[/mask]
268+ Matches packets in connections with the given
269+ unsigned mark value (if a mask is specified, this
270+ is logically ANDed with the mark before the comparison).
271+
272+
273+ CONNMARK
274+ This is used to set the netfilter mark value associated
275+ with the connection
276+
277+ --set-mark mark
278+ Set connection mark
279+
280+ --save-mark
281+ Set connection mark to the same as the one on the
282+ packet
283+
284+ --restore-mark
285+ Set the netfilter packet mark value to the one
286+ associated with the connection. This is only valid
287+ in the mangle table.
288+
289+config IP_NF_MATCH_CONNLIMIT
290+ tristate 'Connections/IP limit match support'
291+ depends on IP_NF_IPTABLES
292+ help
293+ This adds an iptables match which allows you to restrict the
294+ number of parallel TCP connections to a server per client IP address
295+ (or address block).
296+
297+ Examples:
298+
299+ # allow 2 telnet connections per client host
300+ iptables -p tcp --syn --dport 23 -m connlimit --connlimit-above 2 -j REJECT
301+
302+ # you can also match the other way around:
303+ iptables -p tcp --syn --dport 23 -m connlimit ! --connlimit-above 2 -j ACCEPT
304+
305+ # limit the nr of parallel http requests to 16 per class C sized
306+ # network (24 bit netmask)
307+ iptables -p tcp --syn --dport 80 -m connlimit --connlimit-above 16 \
308+ --connlimit-mask 24 -j REJECT
309+
310+config IP_NF_MATCH_U32
311+ tristate 'U32 match support'
312+ depends on IP_NF_IPTABLES
313+ help
314+
315+ U32 allows you to extract quantities of up to 4 bytes from a packet,
316+ AND them with specified masks, shift them by specified amounts and
317+ test whether the results are in any of a set of specified ranges.
318+ The specification of what to extract is general enough to skip over
319+ headers with lengths stored in the packet, as in IP or TCP header
320+ lengths.
321+ Details and examples are in the kernel module source.
322+
323+config IP_NF_MATCH_MPORT
324+ tristate 'Multiple port with ranges match support'
325+ depends on IP_NF_IPTABLES
326+ help
327+ This module is an enhanced multiport match. It has support for byte
328+ ranges as well as for single ports.
329+ Up to 15 ports are allowed. Note that a portrange uses up 2 port values.
330+
331+ Examples:
332+ # iptables -A FORWARD -p tcp -m mport --ports 23:42,65
333+
334+config IP_NF_MATCH_NTH
335+ tristate 'Nth match support'
336+ depends on IP_NF_IPTABLES
337+ help
338+ This option adds an iptables `Nth' match, which allows you to match every Nth
339+ packet encountered. By default there are 16 different counters that can be
340+ used.
341+
342+ This match functions in one of two ways
343+ 1) Match ever Nth packet, and only the Nth packet.
344+ example:
345+ iptables -t mangle -A PREROUTING -m nth --every 10 -j DROP
346+ This rule will drop every 10th packet.
347+ 2) Unique rule for every packet. This is an easy and quick
348+ method to produce load-balancing for both inbound and outbound.
349+ example:
350+ iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
351+ --every 3 --packet 0 -j SNAT --to-source 10.0.0.5
352+ iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
353+ --every 3 --packet 1 -j SNAT --to-source 10.0.0.6
354+ iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
355+ --every 3 --packet 2 -j SNAT --to-source 10.0.0.7
356+ This example evenly splits connections between the three SNAT
357+ addresses.
358+
359+ By using the mangle table and iproute2, you can setup complex
360+ load-balanced routing. There's lot of other uses. Be creative!
361+
362+ Suppported options are:
363+ --every Nth Match every Nth packet
364+ [--counter] num Use counter 0-15 (default:0)
365+ [--start] num Initialize the counter at the number 'num'
366+ instead of 0. Must be between 0 and Nth-1
367+ [--packet] num Match on 'num' packet. Must be between 0
368+ and Nth-1.
369+ If --packet is used for a counter than
370+ there must be Nth number of --packet
371+ rules, covering all values between 0 and
372+ Nth-1 inclusively.
373+
374 endmenu
375
376diff -Nur linux-2.6.2-rc2.org/net/ipv4/netfilter/Makefile linux-2.6.2-rc2/net/ipv4/netfilter/Makefile
377--- linux-2.6.2-rc2.org/net/ipv4/netfilter/Makefile 2004-01-26 03:30:09.000000000 +0100
378+++ linux-2.6.2-rc2/net/ipv4/netfilter/Makefile 2004-01-30 12:26:19.000000000 +0100
379@@ -48,9 +48,14 @@
380
381 obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
382 obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
383+
384+obj-$(CONFIG_IP_NF_MATCH_MPORT) += ipt_mport.o
385+
386 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
387 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
388
389+obj-$(CONFIG_IP_NF_MATCH_NTH) += ipt_nth.o
390+
391 obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
392
393 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
394@@ -59,8 +64,12 @@
395
396 obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o
397
398+obj-$(CONFIG_IP_NF_MATCH_U32) += ipt_u32.o
399+
400+
401 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
402 obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
403+obj-$(CONFIG_IP_NF_MATCH_CONNLIMIT) += ipt_connlimit.o
404 obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
405 obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
406
407@@ -79,6 +88,8 @@
408 obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
409 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
410 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
411+obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o
412+obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
413 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
414 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
415
416diff -Nur linux-2.6.2-rc2.org/net/ipv4/netfilter/ip_conntrack_core.c linux-2.6.2-rc2/net/ipv4/netfilter/ip_conntrack_core.c
417--- linux-2.6.2-rc2.org/net/ipv4/netfilter/ip_conntrack_core.c 2004-01-26 03:29:48.000000000 +0100
418+++ linux-2.6.2-rc2/net/ipv4/netfilter/ip_conntrack_core.c 2004-01-30 12:25:22.000000000 +0100
419@@ -713,6 +713,9 @@
420 __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
421 conntrack->master = expected;
422 expected->sibling = conntrack;
423+#if CONFIG_IP_NF_CONNTRACK_MARK
424+ conntrack->mark = expected->expectant->mark;
425+#endif
426 LIST_DELETE(&ip_conntrack_expect_list, expected);
427 expected->expectant->expecting--;
428 nf_conntrack_get(&master_ct(conntrack)->infos[0]);
429diff -Nur linux-2.6.2-rc2.org/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.2-rc2/net/ipv4/netfilter/ip_conntrack_standalone.c
430--- linux-2.6.2-rc2.org/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-01-26 03:30:37.000000000 +0100
431+++ linux-2.6.2-rc2/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-01-30 12:25:22.000000000 +0100
432@@ -105,6 +105,9 @@
433 len += sprintf(buffer + len, "[ASSURED] ");
434 len += sprintf(buffer + len, "use=%u ",
435 atomic_read(&conntrack->ct_general.use));
436+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
437+ len += sprintf(buffer + len, "mark=%ld ", conntrack->mark);
438+#endif
439 len += sprintf(buffer + len, "\n");
440
441 return len;
442diff -Nur linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_CONNMARK.c linux-2.6.2-rc2/net/ipv4/netfilter/ipt_CONNMARK.c
443--- linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_CONNMARK.c 1970-01-01 01:00:00.000000000 +0100
444+++ linux-2.6.2-rc2/net/ipv4/netfilter/ipt_CONNMARK.c 2004-01-30 12:25:22.000000000 +0100
445@@ -0,0 +1,91 @@
446+/* This is a module which is used for setting/remembering the mark field of
447+ * an connection, or optionally restore it to the skb
448+ */
449+#include <linux/module.h>
450+#include <linux/skbuff.h>
451+#include <linux/ip.h>
452+#include <net/checksum.h>
453+
454+#include <linux/netfilter_ipv4/ip_tables.h>
455+#include <linux/netfilter_ipv4/ipt_CONNMARK.h>
456+#include <linux/netfilter_ipv4/ip_conntrack.h>
457+
458+static unsigned int
459+target(struct sk_buff **pskb,
460+ unsigned int hooknum,
461+ const struct net_device *in,
462+ const struct net_device *out,
463+ const void *targinfo,
464+ void *userinfo)
465+{
466+ const struct ipt_connmark_target_info *markinfo = targinfo;
467+
468+ enum ip_conntrack_info ctinfo;
469+ struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo);
470+ if (ct) {
471+ switch(markinfo->mode) {
472+ case IPT_CONNMARK_SET:
473+ ct->mark = markinfo->mark;
474+ break;
475+ case IPT_CONNMARK_SAVE:
476+ ct->mark = (*pskb)->nfmark;
477+ break;
478+ case IPT_CONNMARK_RESTORE:
479+ if (ct->mark != (*pskb)->nfmark) {
480+ (*pskb)->nfmark = ct->mark;
481+ (*pskb)->nfcache |= NFC_ALTERED;
482+ }
483+ break;
484+ }
485+ }
486+
487+ return IPT_CONTINUE;
488+}
489+
490+static int
491+checkentry(const char *tablename,
492+ const struct ipt_entry *e,
493+ void *targinfo,
494+ unsigned int targinfosize,
495+ unsigned int hook_mask)
496+{
497+ struct ipt_connmark_target_info *matchinfo = targinfo;
498+ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) {
499+ printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n",
500+ targinfosize,
501+ IPT_ALIGN(sizeof(struct ipt_connmark_target_info)));
502+ return 0;
503+ }
504+
505+ if (matchinfo->mode == IPT_CONNMARK_RESTORE) {
506+ if (strcmp(tablename, "mangle") != 0) {
507+ printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename);
508+ return 0;
509+ }
510+ }
511+
512+ return 1;
513+}
514+
515+static struct ipt_target ipt_connmark_reg = {
516+ .name = "CONNMARK",
517+ .target = target,
518+ .checkentry = checkentry,
519+ .me = THIS_MODULE
520+ };
521+
522+static int __init init(void)
523+{
524+ if (ipt_register_target(&ipt_connmark_reg))
525+ return -EINVAL;
526+
527+ return 0;
528+}
529+
530+static void __exit fini(void)
531+{
532+ ipt_unregister_target(&ipt_connmark_reg);
533+}
534+
535+module_init(init);
536+module_exit(fini);
537diff -Nur linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_TTL.c linux-2.6.2-rc2/net/ipv4/netfilter/ipt_TTL.c
538--- linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_TTL.c 1970-01-01 01:00:00.000000000 +0100
539+++ linux-2.6.2-rc2/net/ipv4/netfilter/ipt_TTL.c 2004-01-30 12:25:07.000000000 +0100
540@@ -0,0 +1,114 @@
541+/* TTL modification target for IP tables
542+ * (C) 2000 by Harald Welte <laforge@gnumonks.org>
543+ *
544+ * Version: 1.8
545+ *
546+ * This software is distributed under the terms of GNU GPL
547+ */
548+
549+#include <linux/module.h>
550+#include <linux/skbuff.h>
551+#include <linux/ip.h>
552+#include <net/checksum.h>
553+
554+#include <linux/netfilter_ipv4/ip_tables.h>
555+#include <linux/netfilter_ipv4/ipt_TTL.h>
556+
557+MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
558+MODULE_DESCRIPTION("IP tables TTL modification module");
559+MODULE_LICENSE("GPL");
560+
561+static unsigned int ipt_ttl_target(struct sk_buff **pskb, unsigned int hooknum,
562+ const struct net_device *in, const struct net_device *out,
563+ const void *targinfo, void *userinfo)
564+{
565+ struct iphdr *iph = (*pskb)->nh.iph;
566+ const struct ipt_TTL_info *info = targinfo;
567+ u_int16_t diffs[2];
568+ int new_ttl;
569+
570+ switch (info->mode) {
571+ case IPT_TTL_SET:
572+ new_ttl = info->ttl;
573+ break;
574+ case IPT_TTL_INC:
575+ new_ttl = iph->ttl + info->ttl;
576+ if (new_ttl > 255)
577+ new_ttl = 255;
578+ break;
579+ case IPT_TTL_DEC:
580+ new_ttl = iph->ttl + info->ttl;
581+ if (new_ttl < 0)
582+ new_ttl = 0;
583+ break;
584+ default:
585+ new_ttl = iph->ttl;
586+ break;
587+ }
588+
589+ if (new_ttl != iph->ttl) {
590+ diffs[0] = htons(((unsigned)iph->ttl) << 8) ^ 0xFFFF;
591+ iph->ttl = new_ttl;
592+ diffs[1] = htons(((unsigned)iph->ttl) << 8);
593+ iph->check = csum_fold(csum_partial((char *)diffs,
594+ sizeof(diffs),
595+ iph->check^0xFFFF));
596+ (*pskb)->nfcache |= NFC_ALTERED;
597+ }
598+
599+ return IPT_CONTINUE;
600+}
601+
602+static int ipt_ttl_checkentry(const char *tablename,
603+ const struct ipt_entry *e,
604+ void *targinfo,
605+ unsigned int targinfosize,
606+ unsigned int hook_mask)
607+{
608+ struct ipt_TTL_info *info = targinfo;
609+
610+ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_TTL_info))) {
611+ printk(KERN_WARNING "TTL: targinfosize %u != %Zu\n",
612+ targinfosize,
613+ IPT_ALIGN(sizeof(struct ipt_TTL_info)));
614+ return 0;
615+ }
616+
617+ if (strcmp(tablename, "mangle")) {
618+ printk(KERN_WARNING "TTL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
619+ return 0;
620+ }
621+
622+ if (info->mode > IPT_TTL_MAXMODE) {
623+ printk(KERN_WARNING "TTL: invalid or unknown Mode %u\n",
624+ info->mode);
625+ return 0;
626+ }
627+
628+ if ((info->mode != IPT_TTL_SET) && (info->ttl == 0)) {
629+ printk(KERN_WARNING "TTL: increment/decrement doesn't make sense with value 0\n");
630+ return 0;
631+ }
632+
633+ return 1;
634+}
635+
636+static struct ipt_target ipt_TTL = {
637+ .name = "TTL",
638+ .target = ipt_ttl_target,
639+ .checkentry = ipt_ttl_checkentry,
640+ .me = THIS_MODULE,
641+};
642+
643+static int __init init(void)
644+{
645+ return ipt_register_target(&ipt_TTL);
646+}
647+
648+static void __exit fini(void)
649+{
650+ ipt_unregister_target(&ipt_TTL);
651+}
652+
653+module_init(init);
654+module_exit(fini);
655diff -Nur linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_connlimit.c linux-2.6.2-rc2/net/ipv4/netfilter/ipt_connlimit.c
656--- linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_connlimit.c 1970-01-01 01:00:00.000000000 +0100
657+++ linux-2.6.2-rc2/net/ipv4/netfilter/ipt_connlimit.c 2004-01-30 12:25:34.000000000 +0100
658@@ -0,0 +1,232 @@
659+/*
660+ * netfilter module to limit the number of parallel tcp
661+ * connections per IP address.
662+ * (c) 2000 Gerd Knorr <kraxel@bytesex.org>
663+ * Nov 2002: Martin Bene <martin.bene@icomedias.com>:
664+ * only ignore TIME_WAIT or gone connections
665+ *
666+ * based on ...
667+ *
668+ * Kernel module to match connection tracking information.
669+ * GPL (C) 1999 Rusty Russell (rusty@rustcorp.com.au).
670+ */
671+#include <linux/module.h>
672+#include <linux/skbuff.h>
673+#include <linux/list.h>
674+#include <linux/netfilter_ipv4/ip_conntrack.h>
675+#include <linux/netfilter_ipv4/ip_conntrack_core.h>
676+#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
677+#include <linux/netfilter_ipv4/ip_tables.h>
678+#include <linux/netfilter_ipv4/ipt_connlimit.h>
679+
680+#define DEBUG 0
681+
682+MODULE_LICENSE("GPL");
683+
684+/* we'll save the tuples of all connections we care about */
685+struct ipt_connlimit_conn
686+{
687+ struct list_head list;
688+ struct ip_conntrack_tuple tuple;
689+};
690+
691+struct ipt_connlimit_data {
692+ spinlock_t lock;
693+ struct list_head iphash[256];
694+};
695+
696+static int ipt_iphash(u_int32_t addr)
697+{
698+ int hash;
699+
700+ hash = addr & 0xff;
701+ hash ^= (addr >> 8) & 0xff;
702+ hash ^= (addr >> 16) & 0xff;
703+ hash ^= (addr >> 24) & 0xff;
704+ return hash;
705+}
706+
707+static int count_them(struct ipt_connlimit_data *data,
708+ u_int32_t addr, u_int32_t mask,
709+ struct ip_conntrack *ct)
710+{
711+#if DEBUG
712+ const static char *tcp[] = { "none", "established", "syn_sent", "syn_recv",
713+ "fin_wait", "time_wait", "close", "close_wait",
714+ "last_ack", "listen" };
715+#endif
716+ int addit = 1, matches = 0;
717+ struct ip_conntrack_tuple tuple;
718+ struct ip_conntrack_tuple_hash *found;
719+ struct ipt_connlimit_conn *conn;
720+ struct list_head *hash,*lh;
721+
722+ spin_lock(&data->lock);
723+ tuple = ct->tuplehash[0].tuple;
724+ hash = &data->iphash[ipt_iphash(addr & mask)];
725+
726+ /* check the saved connections */
727+ for (lh = hash->next; lh != hash; lh = lh->next) {
728+ conn = list_entry(lh,struct ipt_connlimit_conn,list);
729+ found = ip_conntrack_find_get(&conn->tuple,ct);
730+ if (0 == memcmp(&conn->tuple,&tuple,sizeof(tuple)) &&
731+ found != NULL &&
732+ found->ctrack->proto.tcp.state != TCP_CONNTRACK_TIME_WAIT) {
733+ /* Just to be sure we have it only once in the list.
734+ We should'nt see tuples twice unless someone hooks this
735+ into a table without "-p tcp --syn" */
736+ addit = 0;
737+ }
738+#if DEBUG
739+ printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d %s\n",
740+ ipt_iphash(addr & mask),
741+ NIPQUAD(conn->tuple.src.ip), ntohs(conn->tuple.src.u.tcp.port),
742+ NIPQUAD(conn->tuple.dst.ip), ntohs(conn->tuple.dst.u.tcp.port),
743+ (NULL != found) ? tcp[found->ctrack->proto.tcp.state] : "gone");
744+#endif
745+ if (NULL == found) {
746+ /* this one is gone */
747+ lh = lh->prev;
748+ list_del(lh->next);
749+ kfree(conn);
750+ continue;
751+ }
752+ if (found->ctrack->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT) {
753+ /* we don't care about connections which are
754+ closed already -> ditch it */
755+ lh = lh->prev;
756+ list_del(lh->next);
757+ kfree(conn);
758+ nf_conntrack_put(&found->ctrack->infos[0]);
759+ continue;
760+ }
761+ if ((addr & mask) == (conn->tuple.src.ip & mask)) {
762+ /* same source IP address -> be counted! */
763+ matches++;
764+ }
765+ nf_conntrack_put(&found->ctrack->infos[0]);
766+ }
767+ if (addit) {
768+ /* save the new connection in our list */
769+#if DEBUG
770+ printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d new\n",
771+ ipt_iphash(addr & mask),
772+ NIPQUAD(tuple.src.ip), ntohs(tuple.src.u.tcp.port),
773+ NIPQUAD(tuple.dst.ip), ntohs(tuple.dst.u.tcp.port));
774+#endif
775+ conn = kmalloc(sizeof(*conn),GFP_ATOMIC);
776+ if (NULL == conn)
777+ return -1;
778+ memset(conn,0,sizeof(*conn));
779+ INIT_LIST_HEAD(&conn->list);
780+ conn->tuple = tuple;
781+ list_add(&conn->list,hash);
782+ matches++;
783+ }
784+ spin_unlock(&data->lock);
785+ return matches;
786+}
787+
788+static int
789+match(const struct sk_buff *skb,
790+ const struct net_device *in,
791+ const struct net_device *out,
792+ const void *matchinfo,
793+ int offset,
794+ const void *hdr,
795+ u_int16_t datalen,
796+ int *hotdrop)
797+{
798+ const struct ipt_connlimit_info *info = matchinfo;
799+ int connections, match;
800+ struct ip_conntrack *ct;
801+ enum ip_conntrack_info ctinfo;
802+
803+ ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
804+ if (NULL == ct) {
805+ printk("ipt_connlimit: Oops: invalid ct state ?\n");
806+ *hotdrop = 1;
807+ return 0;
808+ }
809+ connections = count_them(info->data,skb->nh.iph->saddr,info->mask,ct);
810+ if (-1 == connections) {
811+ printk("ipt_connlimit: Hmm, kmalloc failed :-(\n");
812+ *hotdrop = 1; /* let's free some memory :-) */
813+ return 0;
814+ }
815+ match = (info->inverse) ? (connections <= info->limit) : (connections > info->limit);
816+#if DEBUG
817+ printk("ipt_connlimit: src=%u.%u.%u.%u mask=%u.%u.%u.%u "
818+ "connections=%d limit=%d match=%s\n",
819+ NIPQUAD(skb->nh.iph->saddr), NIPQUAD(info->mask),
820+ connections, info->limit, match ? "yes" : "no");
821+#endif
822+
823+ return match;
824+}
825+
826+static int check(const char *tablename,
827+ const struct ipt_ip *ip,
828+ void *matchinfo,
829+ unsigned int matchsize,
830+ unsigned int hook_mask)
831+{
832+ struct ipt_connlimit_info *info = matchinfo;
833+ int i;
834+
835+ /* verify size */
836+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_connlimit_info)))
837+ return 0;
838+
839+ /* refuse anything but tcp */
840+ if (ip->proto != IPPROTO_TCP)
841+ return 0;
842+
843+ /* init private data */
844+ info->data = kmalloc(sizeof(struct ipt_connlimit_data),GFP_KERNEL);
845+ spin_lock_init(&(info->data->lock));
846+ for (i = 0; i < 256; i++)
847+ INIT_LIST_HEAD(&(info->data->iphash[i]));
848+
849+ return 1;
850+}
851+
852+static void destroy(void *matchinfo, unsigned int matchinfosize)
853+{
854+ struct ipt_connlimit_info *info = matchinfo;
855+ struct ipt_connlimit_conn *conn;
856+ struct list_head *hash;
857+ int i;
858+
859+ /* cleanup */
860+ for (i = 0; i < 256; i++) {
861+ hash = &(info->data->iphash[i]);
862+ while (hash != hash->next) {
863+ conn = list_entry(hash->next,struct ipt_connlimit_conn,list);
864+ list_del(hash->next);
865+ kfree(conn);
866+ }
867+ }
868+ kfree(info->data);
869+}
870+
871+static struct ipt_match connlimit_match
872+= { { NULL, NULL }, "connlimit", &match, &check, &destroy, THIS_MODULE };
873+
874+static int __init init(void)
875+{
876+ /* NULL if ip_conntrack not a module */
877+ if (ip_conntrack_module)
878+ __MOD_INC_USE_COUNT(ip_conntrack_module);
879+ return ipt_register_match(&connlimit_match);
880+}
881+
882+static void __exit fini(void)
883+{
884+ ipt_unregister_match(&connlimit_match);
885+ if (ip_conntrack_module)
886+ __MOD_DEC_USE_COUNT(ip_conntrack_module);
887+}
888+
889+module_init(init);
890+module_exit(fini);
891diff -Nur linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_connmark.c linux-2.6.2-rc2/net/ipv4/netfilter/ipt_connmark.c
892--- linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_connmark.c 1970-01-01 01:00:00.000000000 +0100
893+++ linux-2.6.2-rc2/net/ipv4/netfilter/ipt_connmark.c 2004-01-30 12:25:22.000000000 +0100
894@@ -0,0 +1,59 @@
895+/* Kernel module to match connection mark values. */
896+#include <linux/module.h>
897+#include <linux/skbuff.h>
898+
899+#include <linux/netfilter_ipv4/ip_tables.h>
900+#include <linux/netfilter_ipv4/ipt_connmark.h>
901+#include <linux/netfilter_ipv4/ip_conntrack.h>
902+
903+static int
904+match(const struct sk_buff *skb,
905+ const struct net_device *in,
906+ const struct net_device *out,
907+ const void *matchinfo,
908+ int offset,
909+ const void *hdr,
910+ u_int16_t datalen,
911+ int *hotdrop)
912+{
913+ const struct ipt_connmark_info *info = matchinfo;
914+ enum ip_conntrack_info ctinfo;
915+ struct ip_conntrack *ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
916+ if (!ct)
917+ return 0;
918+
919+ return ((ct->mark & info->mask) == info->mark) ^ info->invert;
920+}
921+
922+static int
923+checkentry(const char *tablename,
924+ const struct ipt_ip *ip,
925+ void *matchinfo,
926+ unsigned int matchsize,
927+ unsigned int hook_mask)
928+{
929+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info)))
930+ return 0;
931+
932+ return 1;
933+}
934+
935+static struct ipt_match connmark_match = {
936+ .name = "connmark",
937+ .match = &match,
938+ .checkentry = &checkentry,
939+ .me = THIS_MODULE
940+};
941+
942+static int __init init(void)
943+{
944+ return ipt_register_match(&connmark_match);
945+}
946+
947+static void __exit fini(void)
948+{
949+ ipt_unregister_match(&connmark_match);
950+}
951+
952+module_init(init);
953+module_exit(fini);
954diff -Nur linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_mport.c linux-2.6.2-rc2/net/ipv4/netfilter/ipt_mport.c
955--- linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_mport.c 1970-01-01 01:00:00.000000000 +0100
956+++ linux-2.6.2-rc2/net/ipv4/netfilter/ipt_mport.c 2004-01-30 12:25:56.000000000 +0100
957@@ -0,0 +1,112 @@
958+/* Kernel module to match one of a list of TCP/UDP ports: ports are in
959+ the same place so we can treat them as equal. */
960+#include <linux/module.h>
961+#include <linux/types.h>
962+#include <linux/udp.h>
963+#include <linux/skbuff.h>
964+
965+#include <linux/netfilter_ipv4/ipt_mport.h>
966+#include <linux/netfilter_ipv4/ip_tables.h>
967+
968+MODULE_LICENSE("GPL");
969+
970+#if 0
971+#define duprintf(format, args...) printk(format , ## args)
972+#else
973+#define duprintf(format, args...)
974+#endif
975+
976+/* Returns 1 if the port is matched by the test, 0 otherwise. */
977+static inline int
978+ports_match(const struct ipt_mport *minfo, u_int16_t src, u_int16_t dst)
979+{
980+ unsigned int i;
981+ unsigned int m;
982+ u_int16_t pflags = minfo->pflags;
983+ for (i=0, m=1; i<IPT_MULTI_PORTS; i++, m<<=1) {
984+ u_int16_t s, e;
985+
986+ if (pflags & m
987+ && minfo->ports[i] == 65535)
988+ return 0;
989+
990+ s = minfo->ports[i];
991+
992+ if (pflags & m) {
993+ e = minfo->ports[++i];
994+ m <<= 1;
995+ } else
996+ e = s;
997+
998+ if (minfo->flags & IPT_MPORT_SOURCE
999+ && src >= s && src <= e)
1000+ return 1;
1001+
1002+ if (minfo->flags & IPT_MPORT_DESTINATION
1003+ && dst >= s && dst <= e)
1004+ return 1;
1005+ }
1006+
1007+ return 0;
1008+}
1009+
1010+static int
1011+match(const struct sk_buff *skb,
1012+ const struct net_device *in,
1013+ const struct net_device *out,
1014+ const void *matchinfo,
1015+ int offset,
1016+ const void *hdr,
1017+ u_int16_t datalen,
1018+ int *hotdrop)
1019+{
1020+ const struct udphdr *udp = hdr;
1021+ const struct ipt_mport *minfo = matchinfo;
1022+
1023+ /* Must be big enough to read ports. */
1024+ if (offset == 0 && datalen < sizeof(struct udphdr)) {
1025+ /* We've been asked to examine this packet, and we
1026+ can't. Hence, no choice but to drop. */
1027+ duprintf("ipt_mport:"
1028+ " Dropping evil offset=0 tinygram.\n");
1029+ *hotdrop = 1;
1030+ return 0;
1031+ }
1032+
1033+ /* Must not be a fragment. */
1034+ return !offset
1035+ && ports_match(minfo, ntohs(udp->source), ntohs(udp->dest));
1036+}
1037+
1038+/* Called when user tries to insert an entry of this type. */
1039+static int
1040+checkentry(const char *tablename,
1041+ const struct ipt_ip *ip,
1042+ void *matchinfo,
1043+ unsigned int matchsize,
1044+ unsigned int hook_mask)
1045+{
1046+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_mport)))
1047+ return 0;
1048+
1049+ /* Must specify proto == TCP/UDP, no unknown flags or bad count */
1050+ return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
1051+ && !(ip->invflags & IPT_INV_PROTO)
1052+ && matchsize == IPT_ALIGN(sizeof(struct ipt_mport));
1053+}
1054+
1055+static struct ipt_match mport_match
1056+= { { NULL, NULL }, "mport", &match, &checkentry, NULL, THIS_MODULE };
1057+
1058+static int __init init(void)
1059+{
1060+ return ipt_register_match(&mport_match);
1061+}
1062+
1063+static void __exit fini(void)
1064+{
1065+ ipt_unregister_match(&mport_match);
1066+}
1067+
1068+module_init(init);
1069+module_exit(fini);
1070diff -Nur linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_nth.c linux-2.6.2-rc2/net/ipv4/netfilter/ipt_nth.c
1071--- linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_nth.c 1970-01-01 01:00:00.000000000 +0100
1072+++ linux-2.6.2-rc2/net/ipv4/netfilter/ipt_nth.c 2004-01-30 12:26:19.000000000 +0100
1073@@ -0,0 +1,172 @@
1074+/*
1075+ This is a module which is used for match support for every Nth packet
1076+ This file is distributed under the terms of the GNU General Public
1077+ License (GPL). Copies of the GPL can be obtained from:
1078+ ftp://prep.ai.mit.edu/pub/gnu/GPL
1079+
1080+ 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
1081+ 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
1082+ * added support for multiple counters
1083+ * added support for matching on individual packets
1084+ in the counter cycle
1085+
1086+*/
1087+
1088+#include <linux/module.h>
1089+#include <linux/skbuff.h>
1090+#include <linux/ip.h>
1091+#include <net/tcp.h>
1092+#include <linux/spinlock.h>
1093+#include <linux/netfilter_ipv4/ip_tables.h>
1094+#include <linux/netfilter_ipv4/ipt_nth.h>
1095+
1096+MODULE_LICENSE("GPL");
1097+
1098+/*
1099+ * State information.
1100+ */
1101+struct state {
1102+ spinlock_t lock;
1103+ u_int16_t number;
1104+};
1105+
1106+static struct state states[IPT_NTH_NUM_COUNTERS];
1107+
1108+static int
1109+ipt_nth_match(const struct sk_buff *pskb,
1110+ const struct net_device *in,
1111+ const struct net_device *out,
1112+ const void *matchinfo,
1113+ int offset,
1114+ const void *hdr,
1115+ u_int16_t datalen,
1116+ int *hotdrop)
1117+{
1118+ /* Parameters from userspace */
1119+ const struct ipt_nth_info *info = matchinfo;
1120+ unsigned counter = info->counter;
1121+ if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
1122+ {
1123+ printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
1124+ return 0;
1125+ };
1126+
1127+ spin_lock(&states[counter].lock);
1128+
1129+ /* Are we matching every nth packet?*/
1130+ if (info->packet == 0xFF)
1131+ {
1132+ /* We're matching every nth packet and only every nth packet*/
1133+ /* Do we match or invert match? */
1134+ if (info->not == 0)
1135+ {
1136+ if (states[counter].number == 0)
1137+ {
1138+ ++states[counter].number;
1139+ goto match;
1140+ }
1141+ if (states[counter].number >= info->every)
1142+ states[counter].number = 0; /* reset the counter */
1143+ else
1144+ ++states[counter].number;
1145+ goto dontmatch;
1146+ }
1147+ else
1148+ {
1149+ if (states[counter].number == 0)
1150+ {
1151+ ++states[counter].number;
1152+ goto dontmatch;
1153+ }
1154+ if (states[counter].number >= info->every)
1155+ states[counter].number = 0;
1156+ else
1157+ ++states[counter].number;
1158+ goto match;
1159+ }
1160+ }
1161+ else
1162+ {
1163+ /* We're using the --packet, so there must be a rule for every value */
1164+ if (states[counter].number == info->packet)
1165+ {
1166+ /* only increment the counter when a match happens */
1167+ if (states[counter].number >= info->every)
1168+ states[counter].number = 0; /* reset the counter */
1169+ else
1170+ ++states[counter].number;
1171+ goto match;
1172+ }
1173+ else
1174+ goto dontmatch;
1175+ }
1176+
1177+ dontmatch:
1178+ /* don't match */
1179+ spin_unlock(&states[counter].lock);
1180+ return 0;
1181+
1182+ match:
1183+ spin_unlock(&states[counter].lock);
1184+ return 1;
1185+}
1186+
1187+static int
1188+ipt_nth_checkentry(const char *tablename,
1189+ const struct ipt_ip *e,
1190+ void *matchinfo,
1191+ unsigned int matchsize,
1192+ unsigned int hook_mask)
1193+{
1194+ /* Parameters from userspace */
1195+ const struct ipt_nth_info *info = matchinfo;
1196+ unsigned counter = info->counter;
1197+ if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
1198+ {
1199+ printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
1200+ return 0;
1201+ };
1202+
1203+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_nth_info))) {
1204+ printk("nth: matchsize %u != %u\n", matchsize,
1205+ IPT_ALIGN(sizeof(struct ipt_nth_info)));
1206+ return 0;
1207+ }
1208+
1209+ states[counter].number = info->startat;
1210+
1211+ return 1;
1212+}
1213+
1214+static struct ipt_match ipt_nth_reg = {
1215+ {NULL, NULL},
1216+ "nth",
1217+ ipt_nth_match,
1218+ ipt_nth_checkentry,
1219+ NULL,
1220+ THIS_MODULE };
1221+
1222+static int __init init(void)
1223+{
1224+ unsigned counter;
1225+ memset(&states, 0, sizeof(states));
1226+ if (ipt_register_match(&ipt_nth_reg))
1227+ return -EINVAL;
1228+
1229+ for(counter = 0; counter < IPT_NTH_NUM_COUNTERS; counter++)
1230+ {
1231+ spin_lock_init(&(states[counter].lock));
1232+ };
1233+
1234+ printk("ipt_nth match loaded\n");
1235+ return 0;
1236+}
1237+
1238+static void __exit fini(void)
1239+{
1240+ ipt_unregister_match(&ipt_nth_reg);
1241+ printk("ipt_nth match unloaded\n");
1242+}
1243+
1244+module_init(init);
1245+module_exit(fini);
1246diff -Nur linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_u32.c linux-2.6.2-rc2/net/ipv4/netfilter/ipt_u32.c
1247--- linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_u32.c 1970-01-01 01:00:00.000000000 +0100
1248+++ linux-2.6.2-rc2/net/ipv4/netfilter/ipt_u32.c 2004-01-30 12:25:44.000000000 +0100
1249@@ -0,0 +1,211 @@
1250+/* Kernel module to match u32 packet content. */
1251+
1252+/*
1253+U32 tests whether quantities of up to 4 bytes extracted from a packet
1254+have specified values. The specification of what to extract is general
1255+enough to find data at given offsets from tcp headers or payloads.
1256+
1257+ --u32 tests
1258+ The argument amounts to a program in a small language described below.
1259+ tests := location = value | tests && location = value
1260+ value := range | value , range
1261+ range := number | number : number
1262+ a single number, n, is interpreted the same as n:n
1263+ n:m is interpreted as the range of numbers >=n and <=m
1264+ location := number | location operator number
1265+ operator := & | << | >> | @
1266+
1267+ The operators &, <<, >>, && mean the same as in c. The = is really a set
1268+ membership operator and the value syntax describes a set. The @ operator
1269+ is what allows moving to the next header and is described further below.
1270+
1271+ *** Until I can find out how to avoid it, there are some artificial limits
1272+ on the size of the tests:
1273+ - no more than 10 ='s (and 9 &&'s) in the u32 argument
1274+ - no more than 10 ranges (and 9 commas) per value
1275+ - no more than 10 numbers (and 9 operators) per location
1276+
1277+ To describe the meaning of location, imagine the following machine that
1278+ interprets it. There are three registers:
1279+ A is of type char*, initially the address of the IP header
1280+ B and C are unsigned 32 bit integers, initially zero
1281+
1282+ The instructions are:
1283+ number B = number;
1284+ C = (*(A+B)<<24)+(*(A+B+1)<<16)+(*(A+B+2)<<8)+*(A+B+3)
1285+ &number C = C&number
1286+ <<number C = C<<number
1287+ >>number C = C>>number
1288+ @number A = A+C; then do the instruction number
1289+ Any access of memory outside [skb->head,skb->end] causes the match to fail.
1290+ Otherwise the result of the computation is the final value of C.
1291+
1292+ Whitespace is allowed but not required in the tests.
1293+ However the characters that do occur there are likely to require
1294+ shell quoting, so it's a good idea to enclose the arguments in quotes.
1295+
1296+Example:
1297+ match IP packets with total length >= 256
1298+ The IP header contains a total length field in bytes 2-3.
1299+ --u32 "0&0xFFFF=0x100:0xFFFF"
1300+ read bytes 0-3
1301+ AND that with FFFF (giving bytes 2-3),
1302+ and test whether that's in the range [0x100:0xFFFF]
1303+
1304+Example: (more realistic, hence more complicated)
1305+ match icmp packets with icmp type 0
1306+ First test that it's an icmp packet, true iff byte 9 (protocol) = 1
1307+ --u32 "6&0xFF=1 && ...
1308+ read bytes 6-9, use & to throw away bytes 6-8 and compare the result to 1
1309+ Next test that it's not a fragment.
1310+ (If so it might be part of such a packet but we can't always tell.)
1311+ n.b. This test is generally needed if you want to match anything
1312+ beyond the IP header.
1313+ The last 6 bits of byte 6 and all of byte 7 are 0 iff this is a complete
1314+ packet (not a fragment). Alternatively, you can allow first fragments
1315+ by only testing the last 5 bits of byte 6.
1316+ ... 4&0x3FFF=0 && ...
1317+ Last test: the first byte past the IP header (the type) is 0
1318+ This is where we have to use the @syntax. The length of the IP header
1319+ (IHL) in 32 bit words is stored in the right half of byte 0 of the
1320+ IP header itself.
1321+ ... 0>>22&0x3C@0>>24=0"
1322+ The first 0 means read bytes 0-3,
1323+ >>22 means shift that 22 bits to the right. Shifting 24 bits would give
1324+ the first byte, so only 22 bits is four times that plus a few more bits.
1325+ &3C then eliminates the two extra bits on the right and the first four
1326+ bits of the first byte.
1327+ For instance, if IHL=5 then the IP header is 20 (4 x 5) bytes long.
1328+ In this case bytes 0-1 are (in binary) xxxx0101 yyzzzzzz,
1329+ >>22 gives the 10 bit value xxxx0101yy and &3C gives 010100.
1330+ @ means to use this number as a new offset into the packet, and read
1331+ four bytes starting from there. This is the first 4 bytes of the icmp
1332+ payload, of which byte 0 is the icmp type. Therefore we simply shift
1333+ the value 24 to the right to throw out all but the first byte and compare
1334+ the result with 0.
1335+
1336+Example:
1337+ tcp payload bytes 8-12 is any of 1, 2, 5 or 8
1338+ First we test that the packet is a tcp packet (similar to icmp).
1339+ --u32 "6&0xFF=6 && ...
1340+ Next, test that it's not a fragment (same as above).
1341+ ... 0>>22&0x3C@12>>26&0x3C@8=1,2,5,8"
1342+ 0>>22&3C as above computes the number of bytes in the IP header.
1343+ @ makes this the new offset into the packet, which is the start of the
1344+ tcp header. The length of the tcp header (again in 32 bit words) is
1345+ the left half of byte 12 of the tcp header. The 12>>26&3C
1346+ computes this length in bytes (similar to the IP header before).
1347+ @ makes this the new offset, which is the start of the tcp payload.
1348+ Finally 8 reads bytes 8-12 of the payload and = checks whether the
1349+ result is any of 1, 2, 5 or 8
1350+*/
1351+
1352+#include <linux/module.h>
1353+#include <linux/skbuff.h>
1354+
1355+#include <linux/netfilter_ipv4/ipt_u32.h>
1356+#include <linux/netfilter_ipv4/ip_tables.h>
1357+
1358+/* #include <asm-i386/timex.h> for timing */
1359+
1360+MODULE_AUTHOR("Don Cohen <don@isis.cs3-inc.com>");
1361+MODULE_DESCRIPTION("IP tables u32 matching module");
1362+MODULE_LICENSE("GPL");
1363+
1364+static int
1365+match(const struct sk_buff *skb,
1366+ const struct net_device *in,
1367+ const struct net_device *out,
1368+ const void *matchinfo,
1369+ int offset,
1370+ const void *hdr,
1371+ u_int16_t datalen,
1372+ int *hotdrop)
1373+{
1374+ const struct ipt_u32 *data = matchinfo;
1375+ int testind, i;
1376+ unsigned char* origbase = (char*)skb->nh.iph;
1377+ unsigned char* base = origbase;
1378+ unsigned char* head = skb->head;
1379+ unsigned char* end = skb->end;
1380+ int nnums, nvals;
1381+ u_int32_t pos, val;
1382+ /* unsigned long long cycles1, cycles2, cycles3, cycles4;
1383+ cycles1 = get_cycles(); */
1384+
1385+ for (testind=0; testind < data->ntests; testind++) {
1386+ base = origbase; /* reset for each test */
1387+ pos = data->tests[testind].location[0].number;
1388+ if (base+pos+3 > end || base+pos < head)
1389+ return 0;
1390+ val = (base[pos]<<24) + (base[pos+1]<<16) +
1391+ (base[pos+2]<<8) + base[pos+3];
1392+ nnums = data->tests[testind].nnums;
1393+ for (i=1; i < nnums; i++) {
1394+ u_int32_t number = data->tests[testind].location[i].number;
1395+ switch (data->tests[testind].location[i].nextop) {
1396+ case IPT_U32_AND:
1397+ val = val & number;
1398+ break;
1399+ case IPT_U32_LEFTSH:
1400+ val = val << number;
1401+ break;
1402+ case IPT_U32_RIGHTSH:
1403+ val = val >> number;
1404+ break;
1405+ case IPT_U32_AT:
1406+ base = base + val;
1407+ pos = number;
1408+ if (base+pos+3 > end || base+pos < head)
1409+ return 0;
1410+ val = (base[pos]<<24) + (base[pos+1]<<16) +
1411+ (base[pos+2]<<8) + base[pos+3];
1412+ break;
1413+ }
1414+ }
1415+ nvals = data->tests[testind].nvalues;
1416+ for (i=0; i < nvals; i++) {
1417+ if ((data->tests[testind].value[i].min <= val) &&
1418+ (val <= data->tests[testind].value[i].max)) {
1419+ break;
1420+ }
1421+ }
1422+ if (i >= data->tests[testind].nvalues) {
1423+ /* cycles2 = get_cycles();
1424+ printk("failed %d in %d cycles\n", testind,
1425+ cycles2-cycles1); */
1426+ return 0;
1427+ }
1428+ }
1429+ /* cycles2 = get_cycles();
1430+ printk("succeeded in %d cycles\n", cycles2-cycles1); */
1431+ return 1;
1432+}
1433+
1434+static int
1435+checkentry(const char *tablename,
1436+ const struct ipt_ip *ip,
1437+ void *matchinfo,
1438+ unsigned int matchsize,
1439+ unsigned int hook_mask)
1440+{
1441+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_u32)))
1442+ return 0;
1443+ return 1;
1444+}
1445+
1446+static struct ipt_match u32_match
1447+= { { NULL, NULL }, "u32", &match, &checkentry, NULL, THIS_MODULE };
1448+
1449+static int __init init(void)
1450+{
1451+ return ipt_register_match(&u32_match);
1452+}
1453+
1454+static void __exit fini(void)
1455+{
1456+ ipt_unregister_match(&u32_match);
1457+}
1458+
1459+module_init(init);
1460+module_exit(fini);
1461diff -Nur linux-2.6.2-rc2.org/net/ipv6/netfilter/Kconfig linux-2.6.2-rc2/net/ipv6/netfilter/Kconfig
1462--- linux-2.6.2-rc2.org/net/ipv6/netfilter/Kconfig 2004-01-26 03:31:18.000000000 +0100
1463+++ linux-2.6.2-rc2/net/ipv6/netfilter/Kconfig 2004-01-30 12:26:19.000000000 +0100
1464@@ -218,5 +218,53 @@
1465 To compile it as a module, choose M here. If unsure, say N.
1466
1467 #dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
1468+config IP6_NF_TARGET_REJECT
1469+ tristate 'REJECT target support'
1470+ depends on IP6_NF_FILTER
1471+ help
1472+ This CONFIG_IP6_NF_TARGET_REJECT option adds a REJECT target to ip6tables.
1473+ Please keep in mind that the icmp-types are different from the icmpv6 types
1474+ (see ip6tables -j REJECT -h for more info)
1475+
1476+config IP6_NF_MATCH_NTH
1477+ tristate 'Nth match support'
1478+ depends on IP6_NF_IPTABLES
1479+ help
1480+ This option adds an iptables `Nth' match, which allows you to match every Nth
1481+ packet encountered. By default there are 16 different counters that can be
1482+ used.
1483+
1484+ This match functions in one of two ways
1485+ 1) Match ever Nth packet, and only the Nth packet.
1486+ example:
1487+ iptables -t mangle -A PREROUTING -m nth --every 10 -j DROP
1488+ This rule will drop every 10th packet.
1489+ 2) Unique rule for every packet. This is an easy and quick
1490+ method to produce load-balancing for both inbound and outbound.
1491+ example:
1492+ iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
1493+ --every 3 --packet 0 -j SNAT --to-source 10.0.0.5
1494+ iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
1495+ --every 3 --packet 1 -j SNAT --to-source 10.0.0.6
1496+ iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
1497+ --every 3 --packet 2 -j SNAT --to-source 10.0.0.7
1498+ This example evenly splits connections between the three SNAT
1499+ addresses.
1500+
1501+ By using the mangle table and iproute2, you can setup complex
1502+ load-balanced routing. There's lot of other uses. Be creative!
1503+
1504+ Suppported options are:
1505+ --every Nth Match every Nth packet
1506+ [--counter] num Use counter 0-15 (default:0)
1507+ [--start] num Initialize the counter at the number 'num'
1508+ instead of 0. Must be between 0 and Nth-1
1509+ [--packet] num Match on 'num' packet. Must be between 0
1510+ and Nth-1.
1511+ If --packet is used for a counter than
1512+ there must be Nth number of --packet
1513+ rules, covering all values between 0 and
1514+ Nth-1 inclusively.
1515+
1516 endmenu
1517
1518diff -Nur linux-2.6.2-rc2.org/net/ipv6/netfilter/Makefile linux-2.6.2-rc2/net/ipv6/netfilter/Makefile
1519--- linux-2.6.2-rc2.org/net/ipv6/netfilter/Makefile 2004-01-26 03:30:53.000000000 +0100
1520+++ linux-2.6.2-rc2/net/ipv6/netfilter/Makefile 2004-01-30 12:26:19.000000000 +0100
1521@@ -19,6 +19,9 @@
1522 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
1523 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
1524 obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
1525+obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
1526 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
1527 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
1528+
1529+obj-$(CONFIG_IP6_NF_MATCH_NTH) += ip6t_nth.o
1530 obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
1531diff -Nur linux-2.6.2-rc2.org/net/ipv6/netfilter/ip6t_REJECT.c linux-2.6.2-rc2/net/ipv6/netfilter/ip6t_REJECT.c
1532--- linux-2.6.2-rc2.org/net/ipv6/netfilter/ip6t_REJECT.c 1970-01-01 01:00:00.000000000 +0100
1533+++ linux-2.6.2-rc2/net/ipv6/netfilter/ip6t_REJECT.c 2004-01-30 12:26:08.000000000 +0100
1534@@ -0,0 +1,274 @@
1535+/*
1536+ * This is a module which is used for rejecting packets.
1537+ * Added support for customized reject packets (Jozsef Kadlecsik).
1538+ * Sun 12 Nov 2000
1539+ * Port to IPv6 / ip6tables (Harald Welte <laforge@gnumonks.org>)
1540+ */
1541+#include <linux/config.h>
1542+#include <linux/module.h>
1543+#include <linux/skbuff.h>
1544+#include <linux/icmpv6.h>
1545+#include <net/tcp.h>
1546+#include <linux/netfilter_ipv6/ip6_tables.h>
1547+#include <linux/netfilter_ipv6/ip6t_REJECT.h>
1548+
1549+#if 1
1550+#define DEBUGP printk
1551+#else
1552+#define DEBUGP(format, args...)
1553+#endif
1554+
1555+#if 0
1556+/* Send RST reply */
1557+static void send_reset(struct sk_buff *oldskb)
1558+{
1559+ struct sk_buff *nskb;
1560+ struct tcphdr *otcph, *tcph;
1561+ struct rtable *rt;
1562+ unsigned int otcplen;
1563+ int needs_ack;
1564+
1565+ /* IP header checks: fragment, too short. */
1566+ if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)
1567+ || oldskb->len < (oldskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
1568+ return;
1569+
1570+ otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl);
1571+ otcplen = oldskb->len - oldskb->nh.iph->ihl*4;
1572+
1573+ /* No RST for RST. */
1574+ if (otcph->rst)
1575+ return;
1576+
1577+ /* Check checksum. */
1578+ if (tcp_v4_check(otcph, otcplen, oldskb->nh.iph->saddr,
1579+ oldskb->nh.iph->daddr,
1580+ csum_partial((char *)otcph, otcplen, 0)) != 0)
1581+ return;
1582+
1583+ /* Copy skb (even if skb is about to be dropped, we can't just
1584+ clone it because there may be other things, such as tcpdump,
1585+ interested in it) */
1586+ nskb = skb_copy(oldskb, GFP_ATOMIC);
1587+ if (!nskb)
1588+ return;
1589+
1590+ /* This packet will not be the same as the other: clear nf fields */
1591+ nf_conntrack_put(nskb->nfct);
1592+ nskb->nfct = NULL;
1593+ nskb->nfcache = 0;
1594+#ifdef CONFIG_NETFILTER_DEBUG
1595+ nskb->nf_debug = 0;
1596+#endif
1597+
1598+ tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
1599+
1600+ nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
1601+ tcph->source = xchg(&tcph->dest, tcph->source);
1602+
1603+ /* Truncate to length (no data) */
1604+ tcph->doff = sizeof(struct tcphdr)/4;
1605+ skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
1606+ nskb->nh.iph->tot_len = htons(nskb->len);
1607+
1608+ if (tcph->ack) {
1609+ needs_ack = 0;
1610+ tcph->seq = otcph->ack_seq;
1611+ tcph->ack_seq = 0;
1612+ } else {
1613+ needs_ack = 1;
1614+ tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin
1615+ + otcplen - (otcph->doff<<2));
1616+ tcph->seq = 0;
1617+ }
1618+
1619+ /* Reset flags */
1620+ ((u_int8_t *)tcph)[13] = 0;
1621+ tcph->rst = 1;
1622+ tcph->ack = needs_ack;
1623+
1624+ tcph->window = 0;
1625+ tcph->urg_ptr = 0;
1626+
1627+ /* Adjust TCP checksum */
1628+ tcph->check = 0;
1629+ tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
1630+ nskb->nh.iph->saddr,
1631+ nskb->nh.iph->daddr,
1632+ csum_partial((char *)tcph,
1633+ sizeof(struct tcphdr), 0));
1634+
1635+ /* Adjust IP TTL, DF */
1636+ nskb->nh.iph->ttl = MAXTTL;
1637+ /* Set DF, id = 0 */
1638+ nskb->nh.iph->frag_off = htons(IP_DF);
1639+ nskb->nh.iph->id = 0;
1640+
1641+ /* Adjust IP checksum */
1642+ nskb->nh.iph->check = 0;
1643+ nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
1644+ nskb->nh.iph->ihl);
1645+
1646+ /* Routing */
1647+ if (ip_route_output(&rt, nskb->nh.iph->daddr, nskb->nh.iph->saddr,
1648+ RT_TOS(nskb->nh.iph->tos) | RTO_CONN,
1649+ 0) != 0)
1650+ goto free_nskb;
1651+
1652+ dst_release(nskb->dst);
1653+ nskb->dst = &rt->u.dst;
1654+
1655+ /* "Never happens" */
1656+ if (nskb->len > nskb->dst->pmtu)
1657+ goto free_nskb;
1658+
1659+ NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
1660+ ip_finish_output);
1661+ return;
1662+
1663+ free_nskb:
1664+ kfree_skb(nskb);
1665+}
1666+#endif
1667+
1668+static unsigned int reject6_target(struct sk_buff **pskb,
1669+ unsigned int hooknum,
1670+ const struct net_device *in,
1671+ const struct net_device *out,
1672+ const void *targinfo,
1673+ void *userinfo)
1674+{
1675+ const struct ip6t_reject_info *reject = targinfo;
1676+
1677+ /* WARNING: This code causes reentry within ip6tables.
1678+ This means that the ip6tables jump stack is now crap. We
1679+ must return an absolute verdict. --RR */
1680+ DEBUGP("REJECTv6: calling icmpv6_send\n");
1681+ switch (reject->with) {
1682+ case IP6T_ICMP6_NO_ROUTE:
1683+ icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, out);
1684+ break;
1685+ case IP6T_ICMP6_ADM_PROHIBITED:
1686+ icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADM_PROHIBITED, 0, out);
1687+ break;
1688+ case IP6T_ICMP6_NOT_NEIGHBOUR:
1689+ icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOT_NEIGHBOUR, 0, out);
1690+ break;
1691+ case IP6T_ICMP6_ADDR_UNREACH:
1692+ icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, out);
1693+ break;
1694+ case IP6T_ICMP6_PORT_UNREACH:
1695+ icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, out);
1696+ break;
1697+#if 0
1698+ case IPT_ICMP_ECHOREPLY: {
1699+ struct icmp6hdr *icmph = (struct icmphdr *)
1700+ ((u_int32_t *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl);
1701+ unsigned int datalen = (*pskb)->len - (*pskb)->nh.iph->ihl * 4;
1702+
1703+ /* Not non-head frags, or truncated */
1704+ if (((ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET) == 0)
1705+ && datalen >= 4) {
1706+ /* Usually I don't like cut & pasting code,
1707+ but dammit, my party is starting in 45
1708+ mins! --RR */
1709+ struct icmp_bxm icmp_param;
1710+
1711+ icmp_param.icmph=*icmph;
1712+ icmp_param.icmph.type=ICMP_ECHOREPLY;
1713+ icmp_param.data_ptr=(icmph+1);
1714+ icmp_param.data_len=datalen;
1715+ icmp_reply(&icmp_param, *pskb);
1716+ }
1717+ }
1718+ break;
1719+ case IPT_TCP_RESET:
1720+ send_reset(*pskb);
1721+ break;
1722+#endif
1723+ default:
1724+ printk(KERN_WARNING "REJECTv6: case %u not handled yet\n", reject->with);
1725+ break;
1726+ }
1727+
1728+ return NF_DROP;
1729+}
1730+
1731+static inline int find_ping_match(const struct ip6t_entry_match *m)
1732+{
1733+ const struct ip6t_icmp *icmpinfo = (const struct ip6t_icmp *)m->data;
1734+
1735+ if (strcmp(m->u.kernel.match->name, "icmp6") == 0
1736+ && icmpinfo->type == ICMPV6_ECHO_REQUEST
1737+ && !(icmpinfo->invflags & IP6T_ICMP_INV))
1738+ return 1;
1739+
1740+ return 0;
1741+}
1742+
1743+static int check(const char *tablename,
1744+ const struct ip6t_entry *e,
1745+ void *targinfo,
1746+ unsigned int targinfosize,
1747+ unsigned int hook_mask)
1748+{
1749+ const struct ip6t_reject_info *rejinfo = targinfo;
1750+
1751+ if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
1752+ DEBUGP("REJECTv6: targinfosize %u != 0\n", targinfosize);
1753+ return 0;
1754+ }
1755+
1756+ /* Only allow these for packet filtering. */
1757+ if (strcmp(tablename, "filter") != 0) {
1758+ DEBUGP("REJECTv6: bad table `%s'.\n", tablename);
1759+ return 0;
1760+ }
1761+ if ((hook_mask & ~((1 << NF_IP6_LOCAL_IN)
1762+ | (1 << NF_IP6_FORWARD)
1763+ | (1 << NF_IP6_LOCAL_OUT))) != 0) {
1764+ DEBUGP("REJECTv6: bad hook mask %X\n", hook_mask);
1765+ return 0;
1766+ }
1767+
1768+ if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
1769+ /* Must specify that it's an ICMP ping packet. */
1770+ if (e->ipv6.proto != IPPROTO_ICMPV6
1771+ || (e->ipv6.invflags & IP6T_INV_PROTO)) {
1772+ DEBUGP("REJECTv6: ECHOREPLY illegal for non-icmp\n");
1773+ return 0;
1774+ }
1775+ /* Must contain ICMP match. */
1776+ if (IP6T_MATCH_ITERATE(e, find_ping_match) == 0) {
1777+ DEBUGP("REJECTv6: ECHOREPLY illegal for non-ping\n");
1778+ return 0;
1779+ }
1780+ } else if (rejinfo->with == IP6T_TCP_RESET) {
1781+ /* Must specify that it's a TCP packet */
1782+ if (e->ipv6.proto != IPPROTO_TCP
1783+ || (e->ipv6.invflags & IP6T_INV_PROTO)) {
1784+ DEBUGP("REJECTv6: TCP_RESET illegal for non-tcp\n");
1785+ return 0;
1786+ }
1787+ }
1788+
1789+ return 1;
1790+}
1791+
1792+static struct ip6t_target ip6t_reject_reg
1793+= { { NULL, NULL }, "REJECT", reject6_target, check, NULL, THIS_MODULE };
1794+
1795+static int __init init(void)
1796+{
1797+ if (ip6t_register_target(&ip6t_reject_reg))
1798+ return -EINVAL;
1799+ return 0;
1800+}
1801+
1802+static void __exit fini(void)
1803+{
1804+ ip6t_unregister_target(&ip6t_reject_reg);
1805+}
1806+
1807+module_init(init);
1808+module_exit(fini);
1809diff -Nur linux-2.6.2-rc2.org/net/ipv6/netfilter/ip6t_nth.c linux-2.6.2-rc2/net/ipv6/netfilter/ip6t_nth.c
1810--- linux-2.6.2-rc2.org/net/ipv6/netfilter/ip6t_nth.c 1970-01-01 01:00:00.000000000 +0100
1811+++ linux-2.6.2-rc2/net/ipv6/netfilter/ip6t_nth.c 2004-01-30 12:26:19.000000000 +0100
1812@@ -0,0 +1,173 @@
1813+/*
1814+ This is a module which is used for match support for every Nth packet
1815+ This file is distributed under the terms of the GNU General Public
1816+ License (GPL). Copies of the GPL can be obtained from:
1817+ ftp://prep.ai.mit.edu/pub/gnu/GPL
1818+
1819+ 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
1820+ 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
1821+ * added support for multiple counters
1822+ * added support for matching on individual packets
1823+ in the counter cycle
1824+ 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
1825+
1826+*/
1827+
1828+#include <linux/module.h>
1829+#include <linux/skbuff.h>
1830+#include <linux/ip.h>
1831+#include <net/tcp.h>
1832+#include <linux/spinlock.h>
1833+#include <linux/netfilter_ipv6/ip6_tables.h>
1834+#include <linux/netfilter_ipv6/ip6t_nth.h>
1835+
1836+MODULE_LICENSE("GPL");
1837+
1838+/*
1839+ * State information.
1840+ */
1841+struct state {
1842+ spinlock_t lock;
1843+ u_int16_t number;
1844+};
1845+
1846+static struct state states[IP6T_NTH_NUM_COUNTERS];
1847+
1848+static int
1849+ip6t_nth_match(const struct sk_buff *pskb,
1850+ const struct net_device *in,
1851+ const struct net_device *out,
1852+ const void *matchinfo,
1853+ int offset,
1854+ const void *hdr,
1855+ u_int16_t datalen,
1856+ int *hotdrop)
1857+{
1858+ /* Parameters from userspace */
1859+ const struct ip6t_nth_info *info = matchinfo;
1860+ unsigned counter = info->counter;
1861+ if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
1862+ {
1863+ printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
1864+ return 0;
1865+ };
1866+
1867+ spin_lock(&states[counter].lock);
1868+
1869+ /* Are we matching every nth packet?*/
1870+ if (info->packet == 0xFF)
1871+ {
1872+ /* We're matching every nth packet and only every nth packet*/
1873+ /* Do we match or invert match? */
1874+ if (info->not == 0)
1875+ {
1876+ if (states[counter].number == 0)
1877+ {
1878+ ++states[counter].number;
1879+ goto match;
1880+ }
1881+ if (states[counter].number >= info->every)
1882+ states[counter].number = 0; /* reset the counter */
1883+ else
1884+ ++states[counter].number;
1885+ goto dontmatch;
1886+ }
1887+ else
1888+ {
1889+ if (states[counter].number == 0)
1890+ {
1891+ ++states[counter].number;
1892+ goto dontmatch;
1893+ }
1894+ if (states[counter].number >= info->every)
1895+ states[counter].number = 0;
1896+ else
1897+ ++states[counter].number;
1898+ goto match;
1899+ }
1900+ }
1901+ else
1902+ {
1903+ /* We're using the --packet, so there must be a rule for every value */
1904+ if (states[counter].number == info->packet)
1905+ {
1906+ /* only increment the counter when a match happens */
1907+ if (states[counter].number >= info->every)
1908+ states[counter].number = 0; /* reset the counter */
1909+ else
1910+ ++states[counter].number;
1911+ goto match;
1912+ }
1913+ else
1914+ goto dontmatch;
1915+ }
1916+
1917+ dontmatch:
1918+ /* don't match */
1919+ spin_unlock(&states[counter].lock);
1920+ return 0;
1921+
1922+ match:
1923+ spin_unlock(&states[counter].lock);
1924+ return 1;
1925+}
1926+
1927+static int
1928+ip6t_nth_checkentry(const char *tablename,
1929+ const struct ip6t_ip6 *e,
1930+ void *matchinfo,
1931+ unsigned int matchsize,
1932+ unsigned int hook_mask)
1933+{
1934+ /* Parameters from userspace */
1935+ const struct ip6t_nth_info *info = matchinfo;
1936+ unsigned counter = info->counter;
1937+ if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
1938+ {
1939+ printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
1940+ return 0;
1941+ };
1942+
1943+ if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_nth_info))) {
1944+ printk("nth: matchsize %u != %u\n", matchsize,
1945+ IP6T_ALIGN(sizeof(struct ip6t_nth_info)));
1946+ return 0;
1947+ }
1948+
1949+ states[counter].number = info->startat;
1950+
1951+ return 1;
1952+}
1953+
1954+static struct ip6t_match ip6t_nth_reg = {
1955+ {NULL, NULL},
1956+ "nth",
1957+ ip6t_nth_match,
1958+ ip6t_nth_checkentry,
1959+ NULL,
1960+ THIS_MODULE };
1961+
1962+static int __init init(void)
1963+{
1964+ unsigned counter;
1965+ memset(&states, 0, sizeof(states));
1966+ if (ip6t_register_match(&ip6t_nth_reg))
1967+ return -EINVAL;
1968+
1969+ for(counter = 0; counter < IP6T_NTH_NUM_COUNTERS; counter++)
1970+ {
1971+ spin_lock_init(&(states[counter].lock));
1972+ };
1973+
1974+ printk("ip6t_nth match loaded\n");
1975+ return 0;
1976+}
1977+
1978+static void __exit fini(void)
1979+{
1980+ ip6t_unregister_match(&ip6t_nth_reg);
1981+ printk("ip6t_nth match unloaded\n");
1982+}
1983+
1984+module_init(init);
1985+module_exit(fini);
This page took 0.264301 seconds and 4 git commands to generate.