]> git.pld-linux.org Git - packages/kernel.git/blob - 2.6-p-o-m-ng-20040130.patch
Netfilter Modules:
[packages/kernel.git] / 2.6-p-o-m-ng-20040130.patch
1 diff -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 */
14 diff -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*/
33 diff -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
58 diff -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 */
74 diff -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*/
87 diff -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*/
115 diff -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*/
138 diff -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*/
182 diff -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*/
209 diff -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*/
232 diff -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  
376 diff -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  
416 diff -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]);
429 diff -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;
442 diff -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);
537 diff -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);
655 diff -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);
891 diff -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);
954 diff -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);
1070 diff -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);
1246 diff -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);
1461 diff -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  
1518 diff -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
1531 diff -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);
1809 diff -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.166216 seconds and 4 git commands to generate.