]> git.pld-linux.org Git - packages/kernel.git/blame - 2.6-p-o-m-ng-20040130.patch
- CSZ scheduler removed from kernel tree.
[packages/kernel.git] / 2.6-p-o-m-ng-20040130.patch
CommitLineData
7179a358 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
9794b8dc 658@@ -0,0 +1,227 @@
7179a358 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+{
7179a358 876+ return ipt_register_match(&connlimit_match);
877+}
878+
879+static void __exit fini(void)
880+{
881+ ipt_unregister_match(&connlimit_match);
7179a358 882+}
883+
884+module_init(init);
885+module_exit(fini);
886diff -Nur linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_connmark.c linux-2.6.2-rc2/net/ipv4/netfilter/ipt_connmark.c
887--- linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_connmark.c 1970-01-01 01:00:00.000000000 +0100
888+++ linux-2.6.2-rc2/net/ipv4/netfilter/ipt_connmark.c 2004-01-30 12:25:22.000000000 +0100
889@@ -0,0 +1,59 @@
890+/* Kernel module to match connection mark values. */
891+#include <linux/module.h>
892+#include <linux/skbuff.h>
893+
894+#include <linux/netfilter_ipv4/ip_tables.h>
895+#include <linux/netfilter_ipv4/ipt_connmark.h>
896+#include <linux/netfilter_ipv4/ip_conntrack.h>
897+
898+static int
899+match(const struct sk_buff *skb,
900+ const struct net_device *in,
901+ const struct net_device *out,
902+ const void *matchinfo,
903+ int offset,
904+ const void *hdr,
905+ u_int16_t datalen,
906+ int *hotdrop)
907+{
908+ const struct ipt_connmark_info *info = matchinfo;
909+ enum ip_conntrack_info ctinfo;
910+ struct ip_conntrack *ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
911+ if (!ct)
912+ return 0;
913+
914+ return ((ct->mark & info->mask) == info->mark) ^ info->invert;
915+}
916+
917+static int
918+checkentry(const char *tablename,
919+ const struct ipt_ip *ip,
920+ void *matchinfo,
921+ unsigned int matchsize,
922+ unsigned int hook_mask)
923+{
924+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info)))
925+ return 0;
926+
927+ return 1;
928+}
929+
930+static struct ipt_match connmark_match = {
931+ .name = "connmark",
932+ .match = &match,
933+ .checkentry = &checkentry,
934+ .me = THIS_MODULE
935+};
936+
937+static int __init init(void)
938+{
939+ return ipt_register_match(&connmark_match);
940+}
941+
942+static void __exit fini(void)
943+{
944+ ipt_unregister_match(&connmark_match);
945+}
946+
947+module_init(init);
948+module_exit(fini);
949diff -Nur linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_mport.c linux-2.6.2-rc2/net/ipv4/netfilter/ipt_mport.c
950--- linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_mport.c 1970-01-01 01:00:00.000000000 +0100
951+++ linux-2.6.2-rc2/net/ipv4/netfilter/ipt_mport.c 2004-01-30 12:25:56.000000000 +0100
952@@ -0,0 +1,112 @@
953+/* Kernel module to match one of a list of TCP/UDP ports: ports are in
954+ the same place so we can treat them as equal. */
955+#include <linux/module.h>
956+#include <linux/types.h>
957+#include <linux/udp.h>
958+#include <linux/skbuff.h>
959+
960+#include <linux/netfilter_ipv4/ipt_mport.h>
961+#include <linux/netfilter_ipv4/ip_tables.h>
962+
963+MODULE_LICENSE("GPL");
964+
965+#if 0
966+#define duprintf(format, args...) printk(format , ## args)
967+#else
968+#define duprintf(format, args...)
969+#endif
970+
971+/* Returns 1 if the port is matched by the test, 0 otherwise. */
972+static inline int
973+ports_match(const struct ipt_mport *minfo, u_int16_t src, u_int16_t dst)
974+{
975+ unsigned int i;
976+ unsigned int m;
977+ u_int16_t pflags = minfo->pflags;
978+ for (i=0, m=1; i<IPT_MULTI_PORTS; i++, m<<=1) {
979+ u_int16_t s, e;
980+
981+ if (pflags & m
982+ && minfo->ports[i] == 65535)
983+ return 0;
984+
985+ s = minfo->ports[i];
986+
987+ if (pflags & m) {
988+ e = minfo->ports[++i];
989+ m <<= 1;
990+ } else
991+ e = s;
992+
993+ if (minfo->flags & IPT_MPORT_SOURCE
994+ && src >= s && src <= e)
995+ return 1;
996+
997+ if (minfo->flags & IPT_MPORT_DESTINATION
998+ && dst >= s && dst <= e)
999+ return 1;
1000+ }
1001+
1002+ return 0;
1003+}
1004+
1005+static int
1006+match(const struct sk_buff *skb,
1007+ const struct net_device *in,
1008+ const struct net_device *out,
1009+ const void *matchinfo,
1010+ int offset,
1011+ const void *hdr,
1012+ u_int16_t datalen,
1013+ int *hotdrop)
1014+{
1015+ const struct udphdr *udp = hdr;
1016+ const struct ipt_mport *minfo = matchinfo;
1017+
1018+ /* Must be big enough to read ports. */
1019+ if (offset == 0 && datalen < sizeof(struct udphdr)) {
1020+ /* We've been asked to examine this packet, and we
1021+ can't. Hence, no choice but to drop. */
1022+ duprintf("ipt_mport:"
1023+ " Dropping evil offset=0 tinygram.\n");
1024+ *hotdrop = 1;
1025+ return 0;
1026+ }
1027+
1028+ /* Must not be a fragment. */
1029+ return !offset
1030+ && ports_match(minfo, ntohs(udp->source), ntohs(udp->dest));
1031+}
1032+
1033+/* Called when user tries to insert an entry of this type. */
1034+static int
1035+checkentry(const char *tablename,
1036+ const struct ipt_ip *ip,
1037+ void *matchinfo,
1038+ unsigned int matchsize,
1039+ unsigned int hook_mask)
1040+{
1041+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_mport)))
1042+ return 0;
1043+
1044+ /* Must specify proto == TCP/UDP, no unknown flags or bad count */
1045+ return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
1046+ && !(ip->invflags & IPT_INV_PROTO)
1047+ && matchsize == IPT_ALIGN(sizeof(struct ipt_mport));
1048+}
1049+
1050+static struct ipt_match mport_match
1051+= { { NULL, NULL }, "mport", &match, &checkentry, NULL, THIS_MODULE };
1052+
1053+static int __init init(void)
1054+{
1055+ return ipt_register_match(&mport_match);
1056+}
1057+
1058+static void __exit fini(void)
1059+{
1060+ ipt_unregister_match(&mport_match);
1061+}
1062+
1063+module_init(init);
1064+module_exit(fini);
1065diff -Nur linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_nth.c linux-2.6.2-rc2/net/ipv4/netfilter/ipt_nth.c
1066--- linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_nth.c 1970-01-01 01:00:00.000000000 +0100
1067+++ linux-2.6.2-rc2/net/ipv4/netfilter/ipt_nth.c 2004-01-30 12:26:19.000000000 +0100
1068@@ -0,0 +1,172 @@
1069+/*
1070+ This is a module which is used for match support for every Nth packet
1071+ This file is distributed under the terms of the GNU General Public
1072+ License (GPL). Copies of the GPL can be obtained from:
1073+ ftp://prep.ai.mit.edu/pub/gnu/GPL
1074+
1075+ 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
1076+ 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
1077+ * added support for multiple counters
1078+ * added support for matching on individual packets
1079+ in the counter cycle
1080+
1081+*/
1082+
1083+#include <linux/module.h>
1084+#include <linux/skbuff.h>
1085+#include <linux/ip.h>
1086+#include <net/tcp.h>
1087+#include <linux/spinlock.h>
1088+#include <linux/netfilter_ipv4/ip_tables.h>
1089+#include <linux/netfilter_ipv4/ipt_nth.h>
1090+
1091+MODULE_LICENSE("GPL");
1092+
1093+/*
1094+ * State information.
1095+ */
1096+struct state {
1097+ spinlock_t lock;
1098+ u_int16_t number;
1099+};
1100+
1101+static struct state states[IPT_NTH_NUM_COUNTERS];
1102+
1103+static int
1104+ipt_nth_match(const struct sk_buff *pskb,
1105+ const struct net_device *in,
1106+ const struct net_device *out,
1107+ const void *matchinfo,
1108+ int offset,
1109+ const void *hdr,
1110+ u_int16_t datalen,
1111+ int *hotdrop)
1112+{
1113+ /* Parameters from userspace */
1114+ const struct ipt_nth_info *info = matchinfo;
1115+ unsigned counter = info->counter;
1116+ if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
1117+ {
1118+ printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
1119+ return 0;
1120+ };
1121+
1122+ spin_lock(&states[counter].lock);
1123+
1124+ /* Are we matching every nth packet?*/
1125+ if (info->packet == 0xFF)
1126+ {
1127+ /* We're matching every nth packet and only every nth packet*/
1128+ /* Do we match or invert match? */
1129+ if (info->not == 0)
1130+ {
1131+ if (states[counter].number == 0)
1132+ {
1133+ ++states[counter].number;
1134+ goto match;
1135+ }
1136+ if (states[counter].number >= info->every)
1137+ states[counter].number = 0; /* reset the counter */
1138+ else
1139+ ++states[counter].number;
1140+ goto dontmatch;
1141+ }
1142+ else
1143+ {
1144+ if (states[counter].number == 0)
1145+ {
1146+ ++states[counter].number;
1147+ goto dontmatch;
1148+ }
1149+ if (states[counter].number >= info->every)
1150+ states[counter].number = 0;
1151+ else
1152+ ++states[counter].number;
1153+ goto match;
1154+ }
1155+ }
1156+ else
1157+ {
1158+ /* We're using the --packet, so there must be a rule for every value */
1159+ if (states[counter].number == info->packet)
1160+ {
1161+ /* only increment the counter when a match happens */
1162+ if (states[counter].number >= info->every)
1163+ states[counter].number = 0; /* reset the counter */
1164+ else
1165+ ++states[counter].number;
1166+ goto match;
1167+ }
1168+ else
1169+ goto dontmatch;
1170+ }
1171+
1172+ dontmatch:
1173+ /* don't match */
1174+ spin_unlock(&states[counter].lock);
1175+ return 0;
1176+
1177+ match:
1178+ spin_unlock(&states[counter].lock);
1179+ return 1;
1180+}
1181+
1182+static int
1183+ipt_nth_checkentry(const char *tablename,
1184+ const struct ipt_ip *e,
1185+ void *matchinfo,
1186+ unsigned int matchsize,
1187+ unsigned int hook_mask)
1188+{
1189+ /* Parameters from userspace */
1190+ const struct ipt_nth_info *info = matchinfo;
1191+ unsigned counter = info->counter;
1192+ if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
1193+ {
1194+ printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
1195+ return 0;
1196+ };
1197+
1198+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_nth_info))) {
1199+ printk("nth: matchsize %u != %u\n", matchsize,
1200+ IPT_ALIGN(sizeof(struct ipt_nth_info)));
1201+ return 0;
1202+ }
1203+
1204+ states[counter].number = info->startat;
1205+
1206+ return 1;
1207+}
1208+
1209+static struct ipt_match ipt_nth_reg = {
1210+ {NULL, NULL},
1211+ "nth",
1212+ ipt_nth_match,
1213+ ipt_nth_checkentry,
1214+ NULL,
1215+ THIS_MODULE };
1216+
1217+static int __init init(void)
1218+{
1219+ unsigned counter;
1220+ memset(&states, 0, sizeof(states));
1221+ if (ipt_register_match(&ipt_nth_reg))
1222+ return -EINVAL;
1223+
1224+ for(counter = 0; counter < IPT_NTH_NUM_COUNTERS; counter++)
1225+ {
1226+ spin_lock_init(&(states[counter].lock));
1227+ };
1228+
1229+ printk("ipt_nth match loaded\n");
1230+ return 0;
1231+}
1232+
1233+static void __exit fini(void)
1234+{
1235+ ipt_unregister_match(&ipt_nth_reg);
1236+ printk("ipt_nth match unloaded\n");
1237+}
1238+
1239+module_init(init);
1240+module_exit(fini);
1241diff -Nur linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_u32.c linux-2.6.2-rc2/net/ipv4/netfilter/ipt_u32.c
1242--- linux-2.6.2-rc2.org/net/ipv4/netfilter/ipt_u32.c 1970-01-01 01:00:00.000000000 +0100
1243+++ linux-2.6.2-rc2/net/ipv4/netfilter/ipt_u32.c 2004-01-30 12:25:44.000000000 +0100
1244@@ -0,0 +1,211 @@
1245+/* Kernel module to match u32 packet content. */
1246+
1247+/*
1248+U32 tests whether quantities of up to 4 bytes extracted from a packet
1249+have specified values. The specification of what to extract is general
1250+enough to find data at given offsets from tcp headers or payloads.
1251+
1252+ --u32 tests
1253+ The argument amounts to a program in a small language described below.
1254+ tests := location = value | tests && location = value
1255+ value := range | value , range
1256+ range := number | number : number
1257+ a single number, n, is interpreted the same as n:n
1258+ n:m is interpreted as the range of numbers >=n and <=m
1259+ location := number | location operator number
1260+ operator := & | << | >> | @
1261+
1262+ The operators &, <<, >>, && mean the same as in c. The = is really a set
1263+ membership operator and the value syntax describes a set. The @ operator
1264+ is what allows moving to the next header and is described further below.
1265+
1266+ *** Until I can find out how to avoid it, there are some artificial limits
1267+ on the size of the tests:
1268+ - no more than 10 ='s (and 9 &&'s) in the u32 argument
1269+ - no more than 10 ranges (and 9 commas) per value
1270+ - no more than 10 numbers (and 9 operators) per location
1271+
1272+ To describe the meaning of location, imagine the following machine that
1273+ interprets it. There are three registers:
1274+ A is of type char*, initially the address of the IP header
1275+ B and C are unsigned 32 bit integers, initially zero
1276+
1277+ The instructions are:
1278+ number B = number;
1279+ C = (*(A+B)<<24)+(*(A+B+1)<<16)+(*(A+B+2)<<8)+*(A+B+3)
1280+ &number C = C&number
1281+ <<number C = C<<number
1282+ >>number C = C>>number
1283+ @number A = A+C; then do the instruction number
1284+ Any access of memory outside [skb->head,skb->end] causes the match to fail.
1285+ Otherwise the result of the computation is the final value of C.
1286+
1287+ Whitespace is allowed but not required in the tests.
1288+ However the characters that do occur there are likely to require
1289+ shell quoting, so it's a good idea to enclose the arguments in quotes.
1290+
1291+Example:
1292+ match IP packets with total length >= 256
1293+ The IP header contains a total length field in bytes 2-3.
1294+ --u32 "0&0xFFFF=0x100:0xFFFF"
1295+ read bytes 0-3
1296+ AND that with FFFF (giving bytes 2-3),
1297+ and test whether that's in the range [0x100:0xFFFF]
1298+
1299+Example: (more realistic, hence more complicated)
1300+ match icmp packets with icmp type 0
1301+ First test that it's an icmp packet, true iff byte 9 (protocol) = 1
1302+ --u32 "6&0xFF=1 && ...
1303+ read bytes 6-9, use & to throw away bytes 6-8 and compare the result to 1
1304+ Next test that it's not a fragment.
1305+ (If so it might be part of such a packet but we can't always tell.)
1306+ n.b. This test is generally needed if you want to match anything
1307+ beyond the IP header.
1308+ The last 6 bits of byte 6 and all of byte 7 are 0 iff this is a complete
1309+ packet (not a fragment). Alternatively, you can allow first fragments
1310+ by only testing the last 5 bits of byte 6.
1311+ ... 4&0x3FFF=0 && ...
1312+ Last test: the first byte past the IP header (the type) is 0
1313+ This is where we have to use the @syntax. The length of the IP header
1314+ (IHL) in 32 bit words is stored in the right half of byte 0 of the
1315+ IP header itself.
1316+ ... 0>>22&0x3C@0>>24=0"
1317+ The first 0 means read bytes 0-3,
1318+ >>22 means shift that 22 bits to the right. Shifting 24 bits would give
1319+ the first byte, so only 22 bits is four times that plus a few more bits.
1320+ &3C then eliminates the two extra bits on the right and the first four
1321+ bits of the first byte.
1322+ For instance, if IHL=5 then the IP header is 20 (4 x 5) bytes long.
1323+ In this case bytes 0-1 are (in binary) xxxx0101 yyzzzzzz,
1324+ >>22 gives the 10 bit value xxxx0101yy and &3C gives 010100.
1325+ @ means to use this number as a new offset into the packet, and read
1326+ four bytes starting from there. This is the first 4 bytes of the icmp
1327+ payload, of which byte 0 is the icmp type. Therefore we simply shift
1328+ the value 24 to the right to throw out all but the first byte and compare
1329+ the result with 0.
1330+
1331+Example:
1332+ tcp payload bytes 8-12 is any of 1, 2, 5 or 8
1333+ First we test that the packet is a tcp packet (similar to icmp).
1334+ --u32 "6&0xFF=6 && ...
1335+ Next, test that it's not a fragment (same as above).
1336+ ... 0>>22&0x3C@12>>26&0x3C@8=1,2,5,8"
1337+ 0>>22&3C as above computes the number of bytes in the IP header.
1338+ @ makes this the new offset into the packet, which is the start of the
1339+ tcp header. The length of the tcp header (again in 32 bit words) is
1340+ the left half of byte 12 of the tcp header. The 12>>26&3C
1341+ computes this length in bytes (similar to the IP header before).
1342+ @ makes this the new offset, which is the start of the tcp payload.
1343+ Finally 8 reads bytes 8-12 of the payload and = checks whether the
1344+ result is any of 1, 2, 5 or 8
1345+*/
1346+
1347+#include <linux/module.h>
1348+#include <linux/skbuff.h>
1349+
1350+#include <linux/netfilter_ipv4/ipt_u32.h>
1351+#include <linux/netfilter_ipv4/ip_tables.h>
1352+
1353+/* #include <asm-i386/timex.h> for timing */
1354+
1355+MODULE_AUTHOR("Don Cohen <don@isis.cs3-inc.com>");
1356+MODULE_DESCRIPTION("IP tables u32 matching module");
1357+MODULE_LICENSE("GPL");
1358+
1359+static int
1360+match(const struct sk_buff *skb,
1361+ const struct net_device *in,
1362+ const struct net_device *out,
1363+ const void *matchinfo,
1364+ int offset,
1365+ const void *hdr,
1366+ u_int16_t datalen,
1367+ int *hotdrop)
1368+{
1369+ const struct ipt_u32 *data = matchinfo;
1370+ int testind, i;
1371+ unsigned char* origbase = (char*)skb->nh.iph;
1372+ unsigned char* base = origbase;
1373+ unsigned char* head = skb->head;
1374+ unsigned char* end = skb->end;
1375+ int nnums, nvals;
1376+ u_int32_t pos, val;
1377+ /* unsigned long long cycles1, cycles2, cycles3, cycles4;
1378+ cycles1 = get_cycles(); */
1379+
1380+ for (testind=0; testind < data->ntests; testind++) {
1381+ base = origbase; /* reset for each test */
1382+ pos = data->tests[testind].location[0].number;
1383+ if (base+pos+3 > end || base+pos < head)
1384+ return 0;
1385+ val = (base[pos]<<24) + (base[pos+1]<<16) +
1386+ (base[pos+2]<<8) + base[pos+3];
1387+ nnums = data->tests[testind].nnums;
1388+ for (i=1; i < nnums; i++) {
1389+ u_int32_t number = data->tests[testind].location[i].number;
1390+ switch (data->tests[testind].location[i].nextop) {
1391+ case IPT_U32_AND:
1392+ val = val & number;
1393+ break;
1394+ case IPT_U32_LEFTSH:
1395+ val = val << number;
1396+ break;
1397+ case IPT_U32_RIGHTSH:
1398+ val = val >> number;
1399+ break;
1400+ case IPT_U32_AT:
1401+ base = base + val;
1402+ pos = number;
1403+ if (base+pos+3 > end || base+pos < head)
1404+ return 0;
1405+ val = (base[pos]<<24) + (base[pos+1]<<16) +
1406+ (base[pos+2]<<8) + base[pos+3];
1407+ break;
1408+ }
1409+ }
1410+ nvals = data->tests[testind].nvalues;
1411+ for (i=0; i < nvals; i++) {
1412+ if ((data->tests[testind].value[i].min <= val) &&
1413+ (val <= data->tests[testind].value[i].max)) {
1414+ break;
1415+ }
1416+ }
1417+ if (i >= data->tests[testind].nvalues) {
1418+ /* cycles2 = get_cycles();
1419+ printk("failed %d in %d cycles\n", testind,
1420+ cycles2-cycles1); */
1421+ return 0;
1422+ }
1423+ }
1424+ /* cycles2 = get_cycles();
1425+ printk("succeeded in %d cycles\n", cycles2-cycles1); */
1426+ return 1;
1427+}
1428+
1429+static int
1430+checkentry(const char *tablename,
1431+ const struct ipt_ip *ip,
1432+ void *matchinfo,
1433+ unsigned int matchsize,
1434+ unsigned int hook_mask)
1435+{
1436+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_u32)))
1437+ return 0;
1438+ return 1;
1439+}
1440+
1441+static struct ipt_match u32_match
1442+= { { NULL, NULL }, "u32", &match, &checkentry, NULL, THIS_MODULE };
1443+
1444+static int __init init(void)
1445+{
1446+ return ipt_register_match(&u32_match);
1447+}
1448+
1449+static void __exit fini(void)
1450+{
1451+ ipt_unregister_match(&u32_match);
1452+}
1453+
1454+module_init(init);
1455+module_exit(fini);
1456diff -Nur linux-2.6.2-rc2.org/net/ipv6/netfilter/Kconfig linux-2.6.2-rc2/net/ipv6/netfilter/Kconfig
1457--- linux-2.6.2-rc2.org/net/ipv6/netfilter/Kconfig 2004-01-26 03:31:18.000000000 +0100
1458+++ linux-2.6.2-rc2/net/ipv6/netfilter/Kconfig 2004-01-30 12:26:19.000000000 +0100
1459@@ -218,5 +218,53 @@
1460 To compile it as a module, choose M here. If unsure, say N.
1461
1462 #dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
1463+config IP6_NF_TARGET_REJECT
1464+ tristate 'REJECT target support'
1465+ depends on IP6_NF_FILTER
1466+ help
1467+ This CONFIG_IP6_NF_TARGET_REJECT option adds a REJECT target to ip6tables.
1468+ Please keep in mind that the icmp-types are different from the icmpv6 types
1469+ (see ip6tables -j REJECT -h for more info)
1470+
1471+config IP6_NF_MATCH_NTH
1472+ tristate 'Nth match support'
1473+ depends on IP6_NF_IPTABLES
1474+ help
1475+ This option adds an iptables `Nth' match, which allows you to match every Nth
1476+ packet encountered. By default there are 16 different counters that can be
1477+ used.
1478+
1479+ This match functions in one of two ways
1480+ 1) Match ever Nth packet, and only the Nth packet.
1481+ example:
1482+ iptables -t mangle -A PREROUTING -m nth --every 10 -j DROP
1483+ This rule will drop every 10th packet.
1484+ 2) Unique rule for every packet. This is an easy and quick
1485+ method to produce load-balancing for both inbound and outbound.
1486+ example:
1487+ iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
1488+ --every 3 --packet 0 -j SNAT --to-source 10.0.0.5
1489+ iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
1490+ --every 3 --packet 1 -j SNAT --to-source 10.0.0.6
1491+ iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
1492+ --every 3 --packet 2 -j SNAT --to-source 10.0.0.7
1493+ This example evenly splits connections between the three SNAT
1494+ addresses.
1495+
1496+ By using the mangle table and iproute2, you can setup complex
1497+ load-balanced routing. There's lot of other uses. Be creative!
1498+
1499+ Suppported options are:
1500+ --every Nth Match every Nth packet
1501+ [--counter] num Use counter 0-15 (default:0)
1502+ [--start] num Initialize the counter at the number 'num'
1503+ instead of 0. Must be between 0 and Nth-1
1504+ [--packet] num Match on 'num' packet. Must be between 0
1505+ and Nth-1.
1506+ If --packet is used for a counter than
1507+ there must be Nth number of --packet
1508+ rules, covering all values between 0 and
1509+ Nth-1 inclusively.
1510+
1511 endmenu
1512
1513diff -Nur linux-2.6.2-rc2.org/net/ipv6/netfilter/Makefile linux-2.6.2-rc2/net/ipv6/netfilter/Makefile
1514--- linux-2.6.2-rc2.org/net/ipv6/netfilter/Makefile 2004-01-26 03:30:53.000000000 +0100
1515+++ linux-2.6.2-rc2/net/ipv6/netfilter/Makefile 2004-01-30 12:26:19.000000000 +0100
1516@@ -19,6 +19,9 @@
1517 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
1518 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
1519 obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
1520+obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
1521 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
1522 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
1523+
1524+obj-$(CONFIG_IP6_NF_MATCH_NTH) += ip6t_nth.o
1525 obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
1526diff -Nur linux-2.6.2-rc2.org/net/ipv6/netfilter/ip6t_REJECT.c linux-2.6.2-rc2/net/ipv6/netfilter/ip6t_REJECT.c
1527--- linux-2.6.2-rc2.org/net/ipv6/netfilter/ip6t_REJECT.c 1970-01-01 01:00:00.000000000 +0100
1528+++ linux-2.6.2-rc2/net/ipv6/netfilter/ip6t_REJECT.c 2004-01-30 12:26:08.000000000 +0100
1529@@ -0,0 +1,274 @@
1530+/*
1531+ * This is a module which is used for rejecting packets.
1532+ * Added support for customized reject packets (Jozsef Kadlecsik).
1533+ * Sun 12 Nov 2000
1534+ * Port to IPv6 / ip6tables (Harald Welte <laforge@gnumonks.org>)
1535+ */
1536+#include <linux/config.h>
1537+#include <linux/module.h>
1538+#include <linux/skbuff.h>
1539+#include <linux/icmpv6.h>
1540+#include <net/tcp.h>
1541+#include <linux/netfilter_ipv6/ip6_tables.h>
1542+#include <linux/netfilter_ipv6/ip6t_REJECT.h>
1543+
1544+#if 1
1545+#define DEBUGP printk
1546+#else
1547+#define DEBUGP(format, args...)
1548+#endif
1549+
1550+#if 0
1551+/* Send RST reply */
1552+static void send_reset(struct sk_buff *oldskb)
1553+{
1554+ struct sk_buff *nskb;
1555+ struct tcphdr *otcph, *tcph;
1556+ struct rtable *rt;
1557+ unsigned int otcplen;
1558+ int needs_ack;
1559+
1560+ /* IP header checks: fragment, too short. */
1561+ if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)
1562+ || oldskb->len < (oldskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
1563+ return;
1564+
1565+ otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl);
1566+ otcplen = oldskb->len - oldskb->nh.iph->ihl*4;
1567+
1568+ /* No RST for RST. */
1569+ if (otcph->rst)
1570+ return;
1571+
1572+ /* Check checksum. */
1573+ if (tcp_v4_check(otcph, otcplen, oldskb->nh.iph->saddr,
1574+ oldskb->nh.iph->daddr,
1575+ csum_partial((char *)otcph, otcplen, 0)) != 0)
1576+ return;
1577+
1578+ /* Copy skb (even if skb is about to be dropped, we can't just
1579+ clone it because there may be other things, such as tcpdump,
1580+ interested in it) */
1581+ nskb = skb_copy(oldskb, GFP_ATOMIC);
1582+ if (!nskb)
1583+ return;
1584+
1585+ /* This packet will not be the same as the other: clear nf fields */
1586+ nf_conntrack_put(nskb->nfct);
1587+ nskb->nfct = NULL;
1588+ nskb->nfcache = 0;
1589+#ifdef CONFIG_NETFILTER_DEBUG
1590+ nskb->nf_debug = 0;
1591+#endif
1592+
1593+ tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
1594+
1595+ nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
1596+ tcph->source = xchg(&tcph->dest, tcph->source);
1597+
1598+ /* Truncate to length (no data) */
1599+ tcph->doff = sizeof(struct tcphdr)/4;
1600+ skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
1601+ nskb->nh.iph->tot_len = htons(nskb->len);
1602+
1603+ if (tcph->ack) {
1604+ needs_ack = 0;
1605+ tcph->seq = otcph->ack_seq;
1606+ tcph->ack_seq = 0;
1607+ } else {
1608+ needs_ack = 1;
1609+ tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin
1610+ + otcplen - (otcph->doff<<2));
1611+ tcph->seq = 0;
1612+ }
1613+
1614+ /* Reset flags */
1615+ ((u_int8_t *)tcph)[13] = 0;
1616+ tcph->rst = 1;
1617+ tcph->ack = needs_ack;
1618+
1619+ tcph->window = 0;
1620+ tcph->urg_ptr = 0;
1621+
1622+ /* Adjust TCP checksum */
1623+ tcph->check = 0;
1624+ tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
1625+ nskb->nh.iph->saddr,
1626+ nskb->nh.iph->daddr,
1627+ csum_partial((char *)tcph,
1628+ sizeof(struct tcphdr), 0));
1629+
1630+ /* Adjust IP TTL, DF */
1631+ nskb->nh.iph->ttl = MAXTTL;
1632+ /* Set DF, id = 0 */
1633+ nskb->nh.iph->frag_off = htons(IP_DF);
1634+ nskb->nh.iph->id = 0;
1635+
1636+ /* Adjust IP checksum */
1637+ nskb->nh.iph->check = 0;
1638+ nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
1639+ nskb->nh.iph->ihl);
1640+
1641+ /* Routing */
1642+ if (ip_route_output(&rt, nskb->nh.iph->daddr, nskb->nh.iph->saddr,
1643+ RT_TOS(nskb->nh.iph->tos) | RTO_CONN,
1644+ 0) != 0)
1645+ goto free_nskb;
1646+
1647+ dst_release(nskb->dst);
1648+ nskb->dst = &rt->u.dst;
1649+
1650+ /* "Never happens" */
1651+ if (nskb->len > nskb->dst->pmtu)
1652+ goto free_nskb;
1653+
1654+ NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
1655+ ip_finish_output);
1656+ return;
1657+
1658+ free_nskb:
1659+ kfree_skb(nskb);
1660+}
1661+#endif
1662+
1663+static unsigned int reject6_target(struct sk_buff **pskb,
1664+ unsigned int hooknum,
1665+ const struct net_device *in,
1666+ const struct net_device *out,
1667+ const void *targinfo,
1668+ void *userinfo)
1669+{
1670+ const struct ip6t_reject_info *reject = targinfo;
1671+
1672+ /* WARNING: This code causes reentry within ip6tables.
1673+ This means that the ip6tables jump stack is now crap. We
1674+ must return an absolute verdict. --RR */
1675+ DEBUGP("REJECTv6: calling icmpv6_send\n");
1676+ switch (reject->with) {
1677+ case IP6T_ICMP6_NO_ROUTE:
1678+ icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, out);
1679+ break;
1680+ case IP6T_ICMP6_ADM_PROHIBITED:
1681+ icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADM_PROHIBITED, 0, out);
1682+ break;
1683+ case IP6T_ICMP6_NOT_NEIGHBOUR:
1684+ icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOT_NEIGHBOUR, 0, out);
1685+ break;
1686+ case IP6T_ICMP6_ADDR_UNREACH:
1687+ icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, out);
1688+ break;
1689+ case IP6T_ICMP6_PORT_UNREACH:
1690+ icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, out);
1691+ break;
1692+#if 0
1693+ case IPT_ICMP_ECHOREPLY: {
1694+ struct icmp6hdr *icmph = (struct icmphdr *)
1695+ ((u_int32_t *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl);
1696+ unsigned int datalen = (*pskb)->len - (*pskb)->nh.iph->ihl * 4;
1697+
1698+ /* Not non-head frags, or truncated */
1699+ if (((ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET) == 0)
1700+ && datalen >= 4) {
1701+ /* Usually I don't like cut & pasting code,
1702+ but dammit, my party is starting in 45
1703+ mins! --RR */
1704+ struct icmp_bxm icmp_param;
1705+
1706+ icmp_param.icmph=*icmph;
1707+ icmp_param.icmph.type=ICMP_ECHOREPLY;
1708+ icmp_param.data_ptr=(icmph+1);
1709+ icmp_param.data_len=datalen;
1710+ icmp_reply(&icmp_param, *pskb);
1711+ }
1712+ }
1713+ break;
1714+ case IPT_TCP_RESET:
1715+ send_reset(*pskb);
1716+ break;
1717+#endif
1718+ default:
1719+ printk(KERN_WARNING "REJECTv6: case %u not handled yet\n", reject->with);
1720+ break;
1721+ }
1722+
1723+ return NF_DROP;
1724+}
1725+
1726+static inline int find_ping_match(const struct ip6t_entry_match *m)
1727+{
1728+ const struct ip6t_icmp *icmpinfo = (const struct ip6t_icmp *)m->data;
1729+
1730+ if (strcmp(m->u.kernel.match->name, "icmp6") == 0
1731+ && icmpinfo->type == ICMPV6_ECHO_REQUEST
1732+ && !(icmpinfo->invflags & IP6T_ICMP_INV))
1733+ return 1;
1734+
1735+ return 0;
1736+}
1737+
1738+static int check(const char *tablename,
1739+ const struct ip6t_entry *e,
1740+ void *targinfo,
1741+ unsigned int targinfosize,
1742+ unsigned int hook_mask)
1743+{
1744+ const struct ip6t_reject_info *rejinfo = targinfo;
1745+
1746+ if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
1747+ DEBUGP("REJECTv6: targinfosize %u != 0\n", targinfosize);
1748+ return 0;
1749+ }
1750+
1751+ /* Only allow these for packet filtering. */
1752+ if (strcmp(tablename, "filter") != 0) {
1753+ DEBUGP("REJECTv6: bad table `%s'.\n", tablename);
1754+ return 0;
1755+ }
1756+ if ((hook_mask & ~((1 << NF_IP6_LOCAL_IN)
1757+ | (1 << NF_IP6_FORWARD)
1758+ | (1 << NF_IP6_LOCAL_OUT))) != 0) {
1759+ DEBUGP("REJECTv6: bad hook mask %X\n", hook_mask);
1760+ return 0;
1761+ }
1762+
1763+ if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
1764+ /* Must specify that it's an ICMP ping packet. */
1765+ if (e->ipv6.proto != IPPROTO_ICMPV6
1766+ || (e->ipv6.invflags & IP6T_INV_PROTO)) {
1767+ DEBUGP("REJECTv6: ECHOREPLY illegal for non-icmp\n");
1768+ return 0;
1769+ }
1770+ /* Must contain ICMP match. */
1771+ if (IP6T_MATCH_ITERATE(e, find_ping_match) == 0) {
1772+ DEBUGP("REJECTv6: ECHOREPLY illegal for non-ping\n");
1773+ return 0;
1774+ }
1775+ } else if (rejinfo->with == IP6T_TCP_RESET) {
1776+ /* Must specify that it's a TCP packet */
1777+ if (e->ipv6.proto != IPPROTO_TCP
1778+ || (e->ipv6.invflags & IP6T_INV_PROTO)) {
1779+ DEBUGP("REJECTv6: TCP_RESET illegal for non-tcp\n");
1780+ return 0;
1781+ }
1782+ }
1783+
1784+ return 1;
1785+}
1786+
1787+static struct ip6t_target ip6t_reject_reg
1788+= { { NULL, NULL }, "REJECT", reject6_target, check, NULL, THIS_MODULE };
1789+
1790+static int __init init(void)
1791+{
1792+ if (ip6t_register_target(&ip6t_reject_reg))
1793+ return -EINVAL;
1794+ return 0;
1795+}
1796+
1797+static void __exit fini(void)
1798+{
1799+ ip6t_unregister_target(&ip6t_reject_reg);
1800+}
1801+
1802+module_init(init);
1803+module_exit(fini);
1804diff -Nur linux-2.6.2-rc2.org/net/ipv6/netfilter/ip6t_nth.c linux-2.6.2-rc2/net/ipv6/netfilter/ip6t_nth.c
1805--- linux-2.6.2-rc2.org/net/ipv6/netfilter/ip6t_nth.c 1970-01-01 01:00:00.000000000 +0100
1806+++ linux-2.6.2-rc2/net/ipv6/netfilter/ip6t_nth.c 2004-01-30 12:26:19.000000000 +0100
1807@@ -0,0 +1,173 @@
1808+/*
1809+ This is a module which is used for match support for every Nth packet
1810+ This file is distributed under the terms of the GNU General Public
1811+ License (GPL). Copies of the GPL can be obtained from:
1812+ ftp://prep.ai.mit.edu/pub/gnu/GPL
1813+
1814+ 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
1815+ 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
1816+ * added support for multiple counters
1817+ * added support for matching on individual packets
1818+ in the counter cycle
1819+ 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
1820+
1821+*/
1822+
1823+#include <linux/module.h>
1824+#include <linux/skbuff.h>
1825+#include <linux/ip.h>
1826+#include <net/tcp.h>
1827+#include <linux/spinlock.h>
1828+#include <linux/netfilter_ipv6/ip6_tables.h>
1829+#include <linux/netfilter_ipv6/ip6t_nth.h>
1830+
1831+MODULE_LICENSE("GPL");
1832+
1833+/*
1834+ * State information.
1835+ */
1836+struct state {
1837+ spinlock_t lock;
1838+ u_int16_t number;
1839+};
1840+
1841+static struct state states[IP6T_NTH_NUM_COUNTERS];
1842+
1843+static int
1844+ip6t_nth_match(const struct sk_buff *pskb,
1845+ const struct net_device *in,
1846+ const struct net_device *out,
1847+ const void *matchinfo,
1848+ int offset,
1849+ const void *hdr,
1850+ u_int16_t datalen,
1851+ int *hotdrop)
1852+{
1853+ /* Parameters from userspace */
1854+ const struct ip6t_nth_info *info = matchinfo;
1855+ unsigned counter = info->counter;
1856+ if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
1857+ {
1858+ printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
1859+ return 0;
1860+ };
1861+
1862+ spin_lock(&states[counter].lock);
1863+
1864+ /* Are we matching every nth packet?*/
1865+ if (info->packet == 0xFF)
1866+ {
1867+ /* We're matching every nth packet and only every nth packet*/
1868+ /* Do we match or invert match? */
1869+ if (info->not == 0)
1870+ {
1871+ if (states[counter].number == 0)
1872+ {
1873+ ++states[counter].number;
1874+ goto match;
1875+ }
1876+ if (states[counter].number >= info->every)
1877+ states[counter].number = 0; /* reset the counter */
1878+ else
1879+ ++states[counter].number;
1880+ goto dontmatch;
1881+ }
1882+ else
1883+ {
1884+ if (states[counter].number == 0)
1885+ {
1886+ ++states[counter].number;
1887+ goto dontmatch;
1888+ }
1889+ if (states[counter].number >= info->every)
1890+ states[counter].number = 0;
1891+ else
1892+ ++states[counter].number;
1893+ goto match;
1894+ }
1895+ }
1896+ else
1897+ {
1898+ /* We're using the --packet, so there must be a rule for every value */
1899+ if (states[counter].number == info->packet)
1900+ {
1901+ /* only increment the counter when a match happens */
1902+ if (states[counter].number >= info->every)
1903+ states[counter].number = 0; /* reset the counter */
1904+ else
1905+ ++states[counter].number;
1906+ goto match;
1907+ }
1908+ else
1909+ goto dontmatch;
1910+ }
1911+
1912+ dontmatch:
1913+ /* don't match */
1914+ spin_unlock(&states[counter].lock);
1915+ return 0;
1916+
1917+ match:
1918+ spin_unlock(&states[counter].lock);
1919+ return 1;
1920+}
1921+
1922+static int
1923+ip6t_nth_checkentry(const char *tablename,
1924+ const struct ip6t_ip6 *e,
1925+ void *matchinfo,
1926+ unsigned int matchsize,
1927+ unsigned int hook_mask)
1928+{
1929+ /* Parameters from userspace */
1930+ const struct ip6t_nth_info *info = matchinfo;
1931+ unsigned counter = info->counter;
1932+ if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
1933+ {
1934+ printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
1935+ return 0;
1936+ };
1937+
1938+ if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_nth_info))) {
1939+ printk("nth: matchsize %u != %u\n", matchsize,
1940+ IP6T_ALIGN(sizeof(struct ip6t_nth_info)));
1941+ return 0;
1942+ }
1943+
1944+ states[counter].number = info->startat;
1945+
1946+ return 1;
1947+}
1948+
1949+static struct ip6t_match ip6t_nth_reg = {
1950+ {NULL, NULL},
1951+ "nth",
1952+ ip6t_nth_match,
1953+ ip6t_nth_checkentry,
1954+ NULL,
1955+ THIS_MODULE };
1956+
1957+static int __init init(void)
1958+{
1959+ unsigned counter;
1960+ memset(&states, 0, sizeof(states));
1961+ if (ip6t_register_match(&ip6t_nth_reg))
1962+ return -EINVAL;
1963+
1964+ for(counter = 0; counter < IP6T_NTH_NUM_COUNTERS; counter++)
1965+ {
1966+ spin_lock_init(&(states[counter].lock));
1967+ };
1968+
1969+ printk("ip6t_nth match loaded\n");
1970+ return 0;
1971+}
1972+
1973+static void __exit fini(void)
1974+{
1975+ ip6t_unregister_match(&ip6t_nth_reg);
1976+ printk("ip6t_nth match unloaded\n");
1977+}
1978+
1979+module_init(init);
1980+module_exit(fini);
This page took 1.033701 seconds and 4 git commands to generate.