]> git.pld-linux.org Git - packages/kernel.git/blob - 2.6-p-o-m-ng-20040130.patch
- moving config-* fixed.
[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,227 @@
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 +       return ipt_register_match(&connlimit_match);
877 +}
878 +
879 +static void __exit fini(void)
880 +{
881 +       ipt_unregister_match(&connlimit_match);
882 +}
883 +
884 +module_init(init);
885 +module_exit(fini);
886 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
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);
949 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
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);
1065 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
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);
1241 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
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);
1456 diff -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  
1513 diff -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
1526 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
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);
1804 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
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 0.164632 seconds and 3 git commands to generate.