1 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.7/include/linux/netfilter_ipv4/ip_conntrack.h
2 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ip_conntrack.h 2004-06-29 12:24:13.240828712 +0200
3 +++ linux-2.6.7/include/linux/netfilter_ipv4/ip_conntrack.h 2004-06-29 12:35:41.913134608 +0200
6 #include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
7 #include <linux/netfilter_ipv4/ip_conntrack_icmp.h>
8 +#include <linux/netfilter_ipv4/ip_conntrack_sctp.h>
10 /* per conntrack: protocol private data */
11 union ip_conntrack_proto {
12 /* insert conntrack proto private data here */
13 + struct ip_ct_sctp sctp;
15 struct ip_ct_icmp icmp;
19 #endif /* CONFIG_IP_NF_NAT_NEEDED */
21 +#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
27 /* get master conntrack via master expectation */
28 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ip_conntrack_sctp.h linux-2.6.7/include/linux/netfilter_ipv4/ip_conntrack_sctp.h
29 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ip_conntrack_sctp.h 1970-01-01 01:00:00.000000000 +0100
30 +++ linux-2.6.7/include/linux/netfilter_ipv4/ip_conntrack_sctp.h 2004-06-29 12:35:41.896137192 +0200
32 +#ifndef _IP_CONNTRACK_SCTP_H
33 +#define _IP_CONNTRACK_SCTP_H
36 +enum sctp_conntrack {
37 + SCTP_CONNTRACK_NONE,
38 + SCTP_CONNTRACK_CLOSED,
39 + SCTP_CONNTRACK_COOKIE_WAIT,
40 + SCTP_CONNTRACK_COOKIE_ECHOED,
41 + SCTP_CONNTRACK_ESTABLISHED,
42 + SCTP_CONNTRACK_SHUTDOWN_SENT,
43 + SCTP_CONNTRACK_SHUTDOWN_RECD,
44 + SCTP_CONNTRACK_SHUTDOWN_ACK_SENT,
50 + enum sctp_conntrack state;
52 + u_int32_t vtag[IP_CT_DIR_MAX];
53 + u_int32_t ttag[IP_CT_DIR_MAX];
56 +#endif /* _IP_CONNTRACK_SCTP_H */
57 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ip_conntrack_tuple.h linux-2.6.7/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
58 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ip_conntrack_tuple.h 2004-06-16 07:19:43.000000000 +0200
59 +++ linux-2.6.7/include/linux/netfilter_ipv4/ip_conntrack_tuple.h 2004-06-29 12:35:41.952128680 +0200
69 /* The manipulable part of the tuple. */
80 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ip_queue.h linux-2.6.7/include/linux/netfilter_ipv4/ip_queue.h
81 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ip_queue.h 2004-06-16 07:20:03.000000000 +0200
82 +++ linux-2.6.7/include/linux/netfilter_ipv4/ip_queue.h 2004-06-29 12:35:08.141268712 +0200
84 unsigned char payload[0]; /* Optional replacement packet */
87 +typedef struct ipq_vwmark_msg {
88 + unsigned int value; /* Verdict to hand to netfilter */
89 + unsigned long id; /* Packet ID for this verdict */
90 + size_t data_len; /* Length of replacement data */
91 + unsigned char payload[0]; /* Optional replacement packet */
92 + unsigned long nfmark; /* Mark for the Packet */
96 typedef struct ipq_peer_msg {
98 ipq_verdict_msg_t verdict;
100 + ipq_vwmark_msg_t vwmark;
105 #define IPQM_MODE (IPQM_BASE + 1) /* Mode request from peer */
106 #define IPQM_VERDICT (IPQM_BASE + 2) /* Verdict from peer */
107 #define IPQM_PACKET (IPQM_BASE + 3) /* Packet from kernel */
108 -#define IPQM_MAX (IPQM_BASE + 4)
109 +#define IPQM_VWMARK (IPQM_BASE + 4) /* Verdict and mark from peer */
110 +#define IPQM_MAX (IPQM_BASE + 5)
112 #endif /*_IP_QUEUE_H*/
113 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_CONNMARK.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_CONNMARK.h
114 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_CONNMARK.h 1970-01-01 01:00:00.000000000 +0100
115 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_CONNMARK.h 2004-06-29 12:34:21.508357992 +0200
117 +#ifndef _IPT_CONNMARK_H_target
118 +#define _IPT_CONNMARK_H_target
120 +/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
121 + * by Henrik Nordstrom <hno@marasystems.com>
123 + * This program is free software; you can redistribute it and/or modify
124 + * it under the terms of the GNU General Public License as published by
125 + * the Free Software Foundation; either version 2 of the License, or
126 + * (at your option) any later version.
130 + IPT_CONNMARK_SET = 0,
132 + IPT_CONNMARK_RESTORE
135 +struct ipt_connmark_target_info {
136 + unsigned long mark;
137 + unsigned long mask;
141 +#endif /*_IPT_CONNMARK_H_target*/
142 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_IPMARK.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_IPMARK.h
143 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_IPMARK.h 1970-01-01 01:00:00.000000000 +0100
144 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_IPMARK.h 2004-06-29 12:34:27.607430792 +0200
146 +#ifndef _IPT_IPMARK_H_target
147 +#define _IPT_IPMARK_H_target
149 +struct ipt_ipmark_target_info {
150 + unsigned long andmask;
151 + unsigned long ormask;
155 +#define IPT_IPMARK_SRC 0
156 +#define IPT_IPMARK_DST 1
158 +#endif /*_IPT_IPMARK_H_target*/
159 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_ROUTE.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_ROUTE.h
160 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_ROUTE.h 1970-01-01 01:00:00.000000000 +0100
161 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_ROUTE.h 2004-06-29 12:34:33.507533840 +0200
163 +/* Header file for iptables ipt_ROUTE target
165 + * (C) 2002 by Cédric de Launois <delaunois@info.ucl.ac.be>
167 + * This software is distributed under GNU GPL v2, 1991
169 +#ifndef _IPT_ROUTE_H_target
170 +#define _IPT_ROUTE_H_target
172 +#define IPT_ROUTE_IFNAMSIZ 16
174 +struct ipt_route_target_info {
175 + char oif[IPT_ROUTE_IFNAMSIZ]; /* Output Interface Name */
176 + char iif[IPT_ROUTE_IFNAMSIZ]; /* Input Interface Name */
177 + u_int32_t gw; /* IP address of gateway */
181 +/* Values for "flags" field */
182 +#define IPT_ROUTE_CONTINUE 0x01
184 +#endif /*_IPT_ROUTE_H_target*/
185 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_TTL.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_TTL.h
186 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_TTL.h 1970-01-01 01:00:00.000000000 +0100
187 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_TTL.h 2004-06-29 12:32:03.616320768 +0200
189 +/* TTL modification module for IP tables
190 + * (C) 2000 by Harald Welte <laforge@gnumonks.org> */
201 +#define IPT_TTL_MAXMODE IPT_TTL_DEC
203 +struct ipt_TTL_info {
210 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_XOR.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_XOR.h
211 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_XOR.h 1970-01-01 01:00:00.000000000 +0100
212 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_XOR.h 2004-06-29 12:34:46.048627304 +0200
217 +struct ipt_XOR_info {
219 + u_int8_t block_size;
222 +#endif /* _IPT_XOR_H */
223 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_connlimit.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_connlimit.h
224 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_connlimit.h 1970-01-01 01:00:00.000000000 +0100
225 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_connlimit.h 2004-06-29 12:32:05.986960376 +0200
227 +#ifndef _IPT_CONNLIMIT_H
228 +#define _IPT_CONNLIMIT_H
230 +struct ipt_connlimit_data;
232 +struct ipt_connlimit_info {
236 + struct ipt_connlimit_data *data;
238 +#endif /* _IPT_CONNLIMIT_H */
239 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_connmark.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_connmark.h
240 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_connmark.h 1970-01-01 01:00:00.000000000 +0100
241 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_connmark.h 2004-06-29 12:34:21.510357688 +0200
243 +#ifndef _IPT_CONNMARK_H
244 +#define _IPT_CONNMARK_H
246 +/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
247 + * by Henrik Nordstrom <hno@marasystems.com>
249 + * This program is free software; you can redistribute it and/or modify
250 + * it under the terms of the GNU General Public License as published by
251 + * the Free Software Foundation; either version 2 of the License, or
252 + * (at your option) any later version.
255 +struct ipt_connmark_info {
256 + unsigned long mark, mask;
260 +#endif /*_IPT_CONNMARK_H*/
261 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_dstlimit.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_dstlimit.h
262 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_dstlimit.h 1970-01-01 01:00:00.000000000 +0100
263 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_dstlimit.h 2004-06-29 12:32:07.241769616 +0200
265 +#ifndef _IPT_DSTLIMIT_H
266 +#define _IPT_DSTLIMIT_H
268 +/* timings are in milliseconds. */
269 +#define IPT_DSTLIMIT_SCALE 10000
270 +/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490
271 + seconds, or one every 59 hours. */
273 +/* details of this structure hidden by the implementation */
274 +struct ipt_dstlimit_htable;
276 +#define IPT_DSTLIMIT_HASH_DIP 0x0001
277 +#define IPT_DSTLIMIT_HASH_DPT 0x0002
278 +#define IPT_DSTLIMIT_HASH_SIP 0x0004
280 +struct dstlimit_cfg {
281 + u_int32_t mode; /* bitmask of IPT_DSTLIMIT_HASH_* */
282 + u_int32_t avg; /* Average secs between packets * scale */
283 + u_int32_t burst; /* Period multiplier for upper limit. */
285 + /* user specified */
286 + u_int32_t size; /* how many buckets */
287 + u_int32_t max; /* max number of entries */
288 + u_int32_t gc_interval; /* gc interval */
289 + u_int32_t expire; /* when do entries expire? */
292 +struct ipt_dstlimit_info {
293 + char name [IFNAMSIZ]; /* name */
294 + struct dstlimit_cfg cfg;
295 + struct ipt_dstlimit_htable *hinfo;
297 + /* Used internally by the kernel */
300 + struct ipt_dstlimit_info *master;
303 +#endif /*_IPT_DSTLIMIT_H*/
304 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_fuzzy.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_fuzzy.h
305 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_fuzzy.h 1970-01-01 01:00:00.000000000 +0100
306 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_fuzzy.h 2004-06-29 12:32:08.818529912 +0200
308 +#ifndef _IPT_FUZZY_H
309 +#define _IPT_FUZZY_H
311 +#include <linux/param.h>
312 +#include <linux/types.h>
314 +#define MAXFUZZYRATE 10000000
315 +#define MINFUZZYRATE 3
317 +struct ipt_fuzzy_info {
318 + u_int32_t minimum_rate;
319 + u_int32_t maximum_rate;
320 + u_int32_t packets_total;
321 + u_int32_t bytes_total;
322 + u_int32_t previous_time;
323 + u_int32_t present_time;
324 + u_int32_t mean_rate;
325 + u_int8_t acceptance_rate;
328 +#endif /*_IPT_FUZZY_H*/
329 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_ipv4options.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_ipv4options.h
330 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_ipv4options.h 1970-01-01 01:00:00.000000000 +0100
331 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_ipv4options.h 2004-06-29 12:32:14.110725376 +0200
333 +#ifndef __ipt_ipv4options_h_included__
334 +#define __ipt_ipv4options_h_included__
336 +#define IPT_IPV4OPTION_MATCH_SSRR 0x01 /* For strict source routing */
337 +#define IPT_IPV4OPTION_MATCH_LSRR 0x02 /* For loose source routing */
338 +#define IPT_IPV4OPTION_DONT_MATCH_SRR 0x04 /* any source routing */
339 +#define IPT_IPV4OPTION_MATCH_RR 0x08 /* For Record route */
340 +#define IPT_IPV4OPTION_DONT_MATCH_RR 0x10
341 +#define IPT_IPV4OPTION_MATCH_TIMESTAMP 0x20 /* For timestamp request */
342 +#define IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP 0x40
343 +#define IPT_IPV4OPTION_MATCH_ROUTER_ALERT 0x80 /* For router-alert */
344 +#define IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT 0x100
345 +#define IPT_IPV4OPTION_MATCH_ANY_OPT 0x200 /* match packet with any option */
346 +#define IPT_IPV4OPTION_DONT_MATCH_ANY_OPT 0x400 /* match packet with no option */
348 +struct ipt_ipv4options_info {
353 +#endif /* __ipt_ipv4options_h_included__ */
354 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_mport.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_mport.h
355 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_mport.h 1970-01-01 01:00:00.000000000 +0100
356 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_mport.h 2004-06-29 12:32:15.539508168 +0200
358 +#ifndef _IPT_MPORT_H
359 +#define _IPT_MPORT_H
360 +#include <linux/netfilter_ipv4/ip_tables.h>
362 +#define IPT_MPORT_SOURCE (1<<0)
363 +#define IPT_MPORT_DESTINATION (1<<1)
364 +#define IPT_MPORT_EITHER (IPT_MPORT_SOURCE|IPT_MPORT_DESTINATION)
366 +#define IPT_MULTI_PORTS 15
368 +/* Must fit inside union ipt_matchinfo: 32 bytes */
369 +/* every entry in ports[] except for the last one has one bit in pflags
370 + * associated with it. If this bit is set, the port is the first port of
371 + * a portrange, with the next entry being the last.
372 + * End of list is marked with pflags bit set and port=65535.
373 + * If 14 ports are used (last one does not have a pflag), the last port
374 + * is repeated to fill the last entry in ports[] */
377 + u_int8_t flags:2; /* Type of comparison */
378 + u_int16_t pflags:14; /* Port flags */
379 + u_int16_t ports[IPT_MULTI_PORTS]; /* Ports */
381 +#endif /*_IPT_MPORT_H*/
382 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_nth.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_nth.h
383 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_nth.h 1970-01-01 01:00:00.000000000 +0100
384 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_nth.h 2004-06-29 12:32:16.697332152 +0200
389 +#include <linux/param.h>
390 +#include <linux/types.h>
392 +#ifndef IPT_NTH_NUM_COUNTERS
393 +#define IPT_NTH_NUM_COUNTERS 16
396 +struct ipt_nth_info {
404 +#endif /*_IPT_NTH_H*/
405 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_policy.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_policy.h
406 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_policy.h 1970-01-01 01:00:00.000000000 +0100
407 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_policy.h 2004-06-29 12:35:40.044418696 +0200
409 +#ifndef _IPT_POLICY_H
410 +#define _IPT_POLICY_H
412 +#define POLICY_MAX_ELEM 4
414 +enum ipt_policy_flags
416 + POLICY_MATCH_IN = 0x1,
417 + POLICY_MATCH_OUT = 0x2,
418 + POLICY_MATCH_NONE = 0x4,
419 + POLICY_MATCH_STRICT = 0x8,
422 +enum ipt_policy_modes
424 + POLICY_MODE_TRANSPORT,
428 +struct ipt_policy_spec
438 +struct ipt_policy_elem
449 + struct ipt_policy_spec match;
450 + struct ipt_policy_spec invert;
453 +struct ipt_policy_info
455 + struct ipt_policy_elem pol[POLICY_MAX_ELEM];
460 +#endif /* _IPT_POLICY_H */
461 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_psd.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_psd.h
462 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_psd.h 1970-01-01 01:00:00.000000000 +0100
463 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_psd.h 2004-06-29 12:32:18.293089560 +0200
468 +#include <linux/param.h>
469 +#include <linux/types.h>
472 + * High port numbers have a lower weight to reduce the frequency of false
473 + * positives, such as from passive mode FTP transfers.
475 +#define PORT_WEIGHT_PRIV 3
476 +#define PORT_WEIGHT_HIGH 1
479 + * Port scan detection thresholds: at least COUNT ports need to be scanned
480 + * from the same source, with no longer than DELAY ticks between ports.
482 +#define SCAN_MIN_COUNT 7
483 +#define SCAN_MAX_COUNT (SCAN_MIN_COUNT * PORT_WEIGHT_PRIV)
484 +#define SCAN_WEIGHT_THRESHOLD SCAN_MAX_COUNT
485 +#define SCAN_DELAY_THRESHOLD (300) /* old usage of HZ here was erroneously and broke under uml */
488 + * Keep track of up to LIST_SIZE source addresses, using a hash table of
489 + * HASH_SIZE entries for faster lookups, but limiting hash collisions to
490 + * HASH_MAX source addresses per the same hash value.
492 +#define LIST_SIZE 0x100
494 +#define HASH_SIZE (1 << HASH_LOG)
495 +#define HASH_MAX 0x10
497 +struct ipt_psd_info {
498 + unsigned int weight_threshold;
499 + unsigned int delay_threshold;
500 + unsigned short lo_ports_weight;
501 + unsigned short hi_ports_weight;
504 +#endif /*_IPT_PSD_H*/
505 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_quota.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_quota.h
506 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_quota.h 1970-01-01 01:00:00.000000000 +0100
507 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_quota.h 2004-06-29 12:32:19.477909440 +0200
509 +#ifndef _IPT_QUOTA_H
510 +#define _IPT_QUOTA_H
512 +/* print debug info in both kernel/netfilter module & iptable library */
513 +//#define DEBUG_IPT_QUOTA
515 +struct ipt_quota_info {
519 +#endif /*_IPT_QUOTA_H*/
520 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_sctp.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_sctp.h
521 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_sctp.h 1970-01-01 01:00:00.000000000 +0100
522 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_sctp.h 2004-06-29 12:32:35.029545232 +0200
524 +#ifndef _IPT_SCTP_H_
525 +#define _IPT_SCTP_H_
527 +#define IPT_SCTP_SRC_PORTS 0x01
528 +#define IPT_SCTP_DEST_PORTS 0x02
529 +#define IPT_SCTP_CHUNK_TYPES 0x04
531 +#define IPT_SCTP_VALID_FLAGS 0x07
533 +#define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0]))
536 +struct ipt_sctp_flag_info {
537 + u_int8_t chunktype;
539 + u_int8_t flag_mask;
542 +#define IPT_NUM_SCTP_FLAGS 4
544 +struct ipt_sctp_info {
545 + u_int16_t dpts[2]; /* Min, Max */
546 + u_int16_t spts[2]; /* Min, Max */
548 + u_int32_t chunkmap[256 / sizeof (u_int32_t)]; /* Bit mask of chunks to be matched according to RFC 2960 */
550 +#define SCTP_CHUNK_MATCH_ANY 0x01 /* Match if any of the chunk types are present */
551 +#define SCTP_CHUNK_MATCH_ALL 0x02 /* Match if all of the chunk types are present */
552 +#define SCTP_CHUNK_MATCH_ONLY 0x04 /* Match if these are the only chunk types present */
554 + u_int32_t chunk_match_type;
555 + struct ipt_sctp_flag_info flag_info[IPT_NUM_SCTP_FLAGS];
559 + u_int32_t invflags;
562 +#define bytes(type) (sizeof(type) * 8)
564 +#define SCTP_CHUNKMAP_SET(chunkmap, type) \
566 + chunkmap[type / bytes(u_int32_t)] |= \
567 + 1 << (type % bytes(u_int32_t)); \
570 +#define SCTP_CHUNKMAP_CLEAR(chunkmap, type) \
572 + chunkmap[type / bytes(u_int32_t)] &= \
573 + ~(1 << (type % bytes(u_int32_t))); \
576 +#define SCTP_CHUNKMAP_IS_SET(chunkmap, type) \
578 + (chunkmap[type / bytes (u_int32_t)] & \
579 + (1 << (type % bytes (u_int32_t)))) ? 1: 0; \
582 +#define SCTP_CHUNKMAP_RESET(chunkmap) \
585 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
589 +#define SCTP_CHUNKMAP_SET_ALL(chunkmap) \
592 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
593 + chunkmap[i] = ~0; \
596 +#define SCTP_CHUNKMAP_COPY(destmap, srcmap) \
599 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
600 + destmap[i] = srcmap[i]; \
603 +#define SCTP_CHUNKMAP_IS_CLEAR(chunkmap) \
607 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \
608 + if (chunkmap[i]) { \
616 +#define SCTP_CHUNKMAP_IS_ALL_SET(chunkmap) \
620 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \
621 + if (chunkmap[i] != ~0) { \
629 +#endif /* _IPT_SCTP_H_ */
631 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_string.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_string.h
632 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_string.h 1970-01-01 01:00:00.000000000 +0100
633 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_string.h 2004-06-29 12:36:14.589167096 +0200
635 +#ifndef _IPT_STRING_H
636 +#define _IPT_STRING_H
638 +/* *** PERFORMANCE TWEAK ***
639 + * Packet size and search string threshold,
640 + * above which sublinear searches is used. */
641 +#define IPT_STRING_HAYSTACK_THRESH 100
642 +#define IPT_STRING_NEEDLE_THRESH 20
644 +#define BM_MAX_NLEN 256
645 +#define BM_MAX_HLEN 1024
647 +typedef char *(*proc_ipt_search) (char *, char *, int, int);
649 +struct ipt_string_info {
650 + char string[BM_MAX_NLEN];
655 +#endif /* _IPT_STRING_H */
656 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_time.h linux-2.6.7/include/linux/netfilter_ipv4/ipt_time.h
657 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_time.h 1970-01-01 01:00:00.000000000 +0100
658 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_time.h 2004-06-29 12:32:41.025633688 +0200
660 +#ifndef __ipt_time_h_included__
661 +#define __ipt_time_h_included__
664 +struct ipt_time_info {
665 + u_int8_t days_match; /* 1 bit per day. -SMTWTFS */
666 + u_int16_t time_start; /* 0 < time_start < 23*60+59 = 1439 */
667 + u_int16_t time_stop; /* 0:0 < time_stat < 23:59 */
668 + u_int8_t kerneltime; /* ignore skb time (and use kerneltime) or not. */
674 +#endif /* __ipt_time_h_included__ */
675 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_HL.h linux-2.6.7/include/linux/netfilter_ipv6/ip6t_HL.h
676 --- linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_HL.h 1970-01-01 01:00:00.000000000 +0100
677 +++ linux-2.6.7/include/linux/netfilter_ipv6/ip6t_HL.h 2004-06-29 12:31:59.776904448 +0200
679 +/* Hop Limit modification module for ip6tables
680 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
681 + * Based on HW's TTL module */
692 +#define IP6T_HL_MAXMODE IP6T_HL_DEC
694 +struct ip6t_HL_info {
696 + u_int8_t hop_limit;
701 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_REJECT.h linux-2.6.7/include/linux/netfilter_ipv6/ip6t_REJECT.h
702 --- linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-06-16 07:18:38.000000000 +0200
703 +++ linux-2.6.7/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-06-29 12:32:02.745453160 +0200
705 #define _IP6T_REJECT_H
707 enum ip6t_reject_with {
708 - IP6T_ICMP_NET_UNREACHABLE,
709 - IP6T_ICMP_HOST_UNREACHABLE,
710 - IP6T_ICMP_PROT_UNREACHABLE,
711 - IP6T_ICMP_PORT_UNREACHABLE,
712 - IP6T_ICMP_ECHOREPLY
713 + IP6T_ICMP6_NO_ROUTE,
714 + IP6T_ICMP6_ADM_PROHIBITED,
715 + IP6T_ICMP6_NOT_NEIGHBOUR,
716 + IP6T_ICMP6_ADDR_UNREACH,
717 + IP6T_ICMP6_PORT_UNREACH,
718 + IP6T_ICMP6_ECHOREPLY,
722 struct ip6t_reject_info {
723 enum ip6t_reject_with with; /* reject type */
726 -#endif /*_IPT_REJECT_H*/
727 +#endif /*_IP6T_REJECT_H*/
728 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_ROUTE.h linux-2.6.7/include/linux/netfilter_ipv6/ip6t_ROUTE.h
729 --- linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_ROUTE.h 1970-01-01 01:00:00.000000000 +0100
730 +++ linux-2.6.7/include/linux/netfilter_ipv6/ip6t_ROUTE.h 2004-06-29 12:34:33.509533536 +0200
732 +/* Header file for iptables ip6t_ROUTE target
734 + * (C) 2003 by Cédric de Launois <delaunois@info.ucl.ac.be>
736 + * This software is distributed under GNU GPL v2, 1991
738 +#ifndef _IPT_ROUTE_H_target
739 +#define _IPT_ROUTE_H_target
741 +#define IP6T_ROUTE_IFNAMSIZ 16
743 +struct ip6t_route_target_info {
744 + char oif[IP6T_ROUTE_IFNAMSIZ]; /* Output Interface Name */
745 + char iif[IP6T_ROUTE_IFNAMSIZ]; /* Input Interface Name */
746 + u_int32_t gw[4]; /* IPv6 address of gateway */
750 +/* Values for "flags" field */
751 +#define IP6T_ROUTE_CONTINUE 0x01
753 +#endif /*_IP6T_ROUTE_H_target*/
754 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h linux-2.6.7/include/linux/netfilter_ipv6/ip6t_fuzzy.h
755 --- linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h 1970-01-01 01:00:00.000000000 +0100
756 +++ linux-2.6.7/include/linux/netfilter_ipv6/ip6t_fuzzy.h 2004-06-29 12:32:08.820529608 +0200
758 +#ifndef _IP6T_FUZZY_H
759 +#define _IP6T_FUZZY_H
761 +#include <linux/param.h>
762 +#include <linux/types.h>
764 +#define MAXFUZZYRATE 10000000
765 +#define MINFUZZYRATE 3
767 +struct ip6t_fuzzy_info {
768 + u_int32_t minimum_rate;
769 + u_int32_t maximum_rate;
770 + u_int32_t packets_total;
771 + u_int32_t bytes_total;
772 + u_int32_t previous_time;
773 + u_int32_t present_time;
774 + u_int32_t mean_rate;
775 + u_int8_t acceptance_rate;
778 +#endif /*_IP6T_FUZZY_H*/
779 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_nth.h linux-2.6.7/include/linux/netfilter_ipv6/ip6t_nth.h
780 --- linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_nth.h 1970-01-01 01:00:00.000000000 +0100
781 +++ linux-2.6.7/include/linux/netfilter_ipv6/ip6t_nth.h 2004-06-29 12:32:16.699331848 +0200
786 +#include <linux/param.h>
787 +#include <linux/types.h>
789 +#ifndef IP6T_NTH_NUM_COUNTERS
790 +#define IP6T_NTH_NUM_COUNTERS 16
793 +struct ip6t_nth_info {
801 +#endif /*_IP6T_NTH_H*/
802 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_owner.h linux-2.6.7/include/linux/netfilter_ipv6/ip6t_owner.h
803 --- linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_owner.h 2004-06-16 07:19:37.000000000 +0200
804 +++ linux-2.6.7/include/linux/netfilter_ipv6/ip6t_owner.h 2004-06-29 12:35:37.769764496 +0200
806 #define IP6T_OWNER_GID 0x02
807 #define IP6T_OWNER_PID 0x04
808 #define IP6T_OWNER_SID 0x08
809 +#define IP6T_OWNER_COMM 0x10
811 struct ip6t_owner_info {
817 u_int8_t match, invert; /* flags */
820 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_policy.h linux-2.6.7/include/linux/netfilter_ipv6/ip6t_policy.h
821 --- linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_policy.h 1970-01-01 01:00:00.000000000 +0100
822 +++ linux-2.6.7/include/linux/netfilter_ipv6/ip6t_policy.h 2004-06-29 12:35:40.046418392 +0200
824 +#ifndef _IP6T_POLICY_H
825 +#define _IP6T_POLICY_H
827 +#define POLICY_MAX_ELEM 4
829 +enum ip6t_policy_flags
831 + POLICY_MATCH_IN = 0x1,
832 + POLICY_MATCH_OUT = 0x2,
833 + POLICY_MATCH_NONE = 0x4,
834 + POLICY_MATCH_STRICT = 0x8,
837 +enum ip6t_policy_modes
839 + POLICY_MODE_TRANSPORT,
843 +struct ip6t_policy_spec
853 +struct ip6t_policy_elem
855 + struct in6_addr saddr;
856 + struct in6_addr smask;
857 + struct in6_addr daddr;
858 + struct in6_addr dmask;
864 + struct ip6t_policy_spec match;
865 + struct ip6t_policy_spec invert;
868 +struct ip6t_policy_info
870 + struct ip6t_policy_elem pol[POLICY_MAX_ELEM];
875 +#endif /* _IP6T_POLICY_H */
876 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/sysctl.h linux-2.6.7/include/linux/sysctl.h
877 --- linux-2.6.7.org/include/linux/sysctl.h 2004-06-29 12:24:13.353811536 +0200
878 +++ linux-2.6.7/include/linux/sysctl.h 2004-06-29 12:32:11.293153712 +0200
880 NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT=12,
881 NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT=13,
882 NET_IPV4_NF_CONNTRACK_BUCKETS=14,
883 + NET_IPV4_NF_CONNTRACK_COUNT=15,
886 /* /proc/sys/net/ipv6 */
887 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/net/tcp.h linux-2.6.7/include/net/tcp.h
888 --- linux-2.6.7.org/include/net/tcp.h 2004-06-29 12:24:13.429799984 +0200
889 +++ linux-2.6.7/include/net/tcp.h 2004-06-29 12:35:34.488263360 +0200
891 extern void tcp_bucket_unlock(struct sock *sk);
892 extern int tcp_port_rover;
893 extern struct sock *tcp_v4_lookup_listener(u32 addr, unsigned short hnum, int dif);
894 +extern struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 hnum, int dif);
896 /* These are AF independent. */
897 static __inline__ int tcp_bhashfn(__u16 lport)
898 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/net/udp.h linux-2.6.7/include/net/udp.h
899 --- linux-2.6.7.org/include/net/udp.h 2004-06-16 07:19:51.000000000 +0200
900 +++ linux-2.6.7/include/net/udp.h 2004-06-29 12:35:34.490263056 +0200
902 extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
903 extern int udp_disconnect(struct sock *sk, int flags);
905 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
907 DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
908 #define UDP_INC_STATS(field) SNMP_INC_STATS(udp_statistics, field)
909 #define UDP_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_statistics, field)
910 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/Kconfig linux-2.6.7/net/ipv4/netfilter/Kconfig
911 --- linux-2.6.7.org/net/ipv4/netfilter/Kconfig 2004-06-29 12:24:13.000000000 +0200
912 +++ linux-2.6.7/net/ipv4/netfilter/Kconfig 2004-06-29 12:36:14.610163904 +0200
915 To compile it as a module, choose M here. If unsure, say N.
917 +config IP_NF_MATCH_UNCLEAN
918 + tristate 'unclean match support (EXPERIMENTAL)'
919 + depends on EXPERIMENTAL && IP_NF_IPTABLES
922 config IP_NF_MATCH_TTL
923 tristate "TTL match support"
924 depends on IP_NF_IPTABLES
925 @@ -627,5 +632,246 @@
926 If you want to compile it as a module, say M here and read
927 Documentation/modules.txt. If unsure, say `N'.
929 +config IP_NF_TARGET_IPV4OPTSSTRIP
930 + tristate 'IPV4OPTSSTRIP target support'
931 + depends on IP_NF_MANGLE
933 + This option adds an IPV4OPTSSTRIP target.
934 + This target allows you to strip all IP options in a packet.
936 + If you want to compile it as a module, say M here and read
937 + Documentation/modules.txt. If unsure, say `N'.
939 +config IP_NF_TARGET_TTL
940 + tristate 'TTL target support'
941 + depends on IP_NF_MANGLE
943 + This option adds a `TTL' target, which enables the user to set
944 + the TTL value or increment / decrement the TTL value by a given
947 + If you want to compile it as a module, say M here and read
948 + Documentation/modules.txt. If unsure, say `N'.
950 +config IP_NF_MATCH_CONNLIMIT
951 + tristate 'Connections/IP limit match support'
952 + depends on IP_NF_IPTABLES
954 + This match allows you to restrict the number of parallel TCP
955 + connections to a server per client IP address (or address block).
957 + If you want to compile it as a module, say M here and read
958 + Documentation/modules.txt. If unsure, say `N'.
960 +config IP_NF_MATCH_DSTLIMIT
961 + tristate 'dstlimit match support'
962 + depends on IP_NF_IPTABLES
964 +config IP_NF_MATCH_FUZZY
965 + tristate 'fuzzy match support'
966 + depends on IP_NF_IPTABLES
968 + This option adds a `fuzzy' match, which allows you to match
969 + packets according to a fuzzy logic based law.
971 + If you want to compile it as a module, say M here and read
972 + Documentation/modules.txt. If unsure, say `N'.
974 +config IP_NF_MATCH_IPV4OPTIONS
975 + tristate 'IPV4OPTIONS match support'
976 + depends on IP_NF_IPTABLES
978 + This option adds a IPV4OPTIONS match.
979 + It allows you to filter options like source routing,
980 + record route, timestamp and router-altert.
982 + If you say Y here, try iptables -m ipv4options --help for more information.
984 + If you want to compile it as a module, say M here and read
985 + Documentation/modules.txt. If unsure, say `N'.
987 +config IP_NF_MATCH_MPORT
988 + tristate 'Multiple port with ranges match support'
989 + depends on IP_NF_IPTABLES
991 + This is an enhanced multiport match which supports port
992 + ranges as well as single ports.
994 + If you want to compile it as a module, say M here and read
995 + Documentation/modules.txt. If unsure, say `N'.
997 +config IP_NF_MATCH_NTH
998 + tristate 'Nth match support'
999 + depends on IP_NF_IPTABLES
1001 + This option adds a `Nth' match, which allow you to make
1002 + rules that match every Nth packet. By default there are
1003 + 16 different counters.
1006 + --every Nth Match every Nth packet
1007 + [--counter] num Use counter 0-15 (default:0)
1008 + [--start] num Initialize the counter at the number 'num'
1009 + instead of 0. Must be between 0 and Nth-1
1010 + [--packet] num Match on 'num' packet. Must be between 0
1013 + If --packet is used for a counter than
1014 + there must be Nth number of --packet
1015 + rules, covering all values between 0 and
1016 + Nth-1 inclusively.
1018 + If you want to compile it as a module, say M here and read
1019 + Documentation/modules.txt. If unsure, say `N'.
1021 +config IP_NF_MATCH_PSD
1022 + tristate 'psd match support'
1023 + depends on IP_NF_IPTABLES
1025 + This option adds a `psd' match, which allows you to create rules in
1026 + any iptables table wich will detect TCP and UDP port scans.
1028 + If you want to compile it as a module, say M here and read
1029 + Documentation/modules.txt. If unsure, say `N'.
1031 +config IP_NF_MATCH_QUOTA
1032 + tristate 'quota match support'
1033 + depends on IP_NF_IPTABLES
1035 + This match implements network quotas.
1037 + If you want to compile it as a module, say M here and read
1038 + Documentation/modules.txt. If unsure, say `N'.
1041 +config IP_NF_MATCH_SCTP
1042 + tristate 'SCTP protocol match support'
1043 + depends on IP_NF_IPTABLES
1045 +config IP_NF_MATCH_TIME
1046 + tristate 'TIME match support'
1047 + depends on IP_NF_IPTABLES
1049 + This option adds a `time' match, which allows you
1050 + to match based on the packet arrival time/date
1051 + (arrival time/date at the machine which netfilter is running on) or
1052 + departure time/date (for locally generated packets).
1054 + If you say Y here, try iptables -m time --help for more information.
1056 + If you want to compile it as a module, say M here and read
1057 + Documentation/modules.txt. If unsure, say `N'.
1059 +config IP_NF_CONNTRACK_MARK
1060 + bool 'Connection mark tracking support'
1062 + This option enables support for connection marks, used by the
1063 + `CONNMARK' target and `connmark' match. Similar to the mark value
1064 + of packets, but this mark value is kept in the conntrack session
1065 + instead of the individual packets.
1067 +config IP_NF_TARGET_CONNMARK
1068 + tristate 'CONNMARK target support'
1069 + depends on IP_NF_CONNTRACK_MARK && IP_NF_MANGLE
1071 + This option adds a `CONNMARK' target, which allows one to manipulate
1072 + the connection mark value. Similar to the MARK target, but
1073 + affects the connection mark value rather than the packet mark value.
1075 + If you want to compile it as a module, say M here and read
1076 + Documentation/modules.txt. The module will be called
1077 + ipt_CONNMARK.o. If unsure, say `N'.
1079 +config IP_NF_MATCH_CONNMARK
1080 + tristate ' Connection mark match support'
1081 + depends on IP_NF_CONNTRACK_MARK && IP_NF_IPTABLES
1083 + This option adds a `connmark' match, which allows you to match the
1084 + connection mark value previously set for the session by `CONNMARK'.
1086 + If you want to compile it as a module, say M here and read
1087 + Documentation/modules.txt. The module will be called
1088 + ipt_connmark.o. If unsure, say `N'.
1090 +config IP_NF_TARGET_IPMARK
1091 + tristate 'IPMARK target support'
1092 + depends on IP_NF_MANGLE
1094 + This option adds a `IPMARK' target, which allows you to create rules
1095 + in the `mangle' table which alter the netfilter mark (nfmark) field
1096 + basing on the source or destination ip address of the packet.
1097 + This is very useful for very fast massive mangling and marking.
1099 + If you want to compile it as a module, say M here and read
1100 + <file:Documentation/modules.txt>. If unsure, say `N'.
1102 +config IP_NF_TARGET_ROUTE
1103 + tristate 'ROUTE target support'
1104 + depends on IP_NF_MANGLE
1106 + This option adds a `ROUTE' target, which enables you to setup unusual
1107 + routes. For example, the ROUTE lets you route a received packet through
1108 + an interface or towards a host, even if the regular destination of the
1109 + packet is the router itself. The ROUTE target is also able to change the
1110 + incoming interface of a packet.
1112 + The target can be or not a final target. It has to be used inside the
1115 + If you want to compile it as a module, say M here and read
1116 + Documentation/modules.txt. The module will be called ipt_ROUTE.o.
1117 + If unsure, say `N'.
1119 +config IP_NF_TARGET_TARPIT
1120 + tristate 'TARPIT target support'
1121 + depends on IP_NF_FILTER
1123 + Adds a TARPIT target to iptables, which captures and holds
1124 + incoming TCP connections using no local per-connection resources.
1125 + Connections are accepted, but immediately switched to the persist
1126 + state (0 byte window), in which the remote side stops sending data
1127 + and asks to continue every 60-240 seconds. Attempts to close the
1128 + connection are ignored, forcing the remote side to time out the
1129 + connection in 12-24 minutes.
1131 + This offers similar functionality to LaBrea
1132 + <http://www.hackbusters.net/LaBrea/> but doesn't require dedicated
1133 + hardware or IPs. Any TCP port that you would normally DROP or REJECT
1134 + can instead become a tarpit.
1136 +config IP_NF_TARGET_XOR
1137 + tristate 'XOR target support'
1138 + depends on IP_NF_MANGLE
1140 + This option adds a `XOR' target, which can encrypt TCP and
1141 + UDP traffic using a simple XOR encryption.
1143 + If you want to compile it as a module, say M here and read
1144 + Documentation/modules.txt. If unsure, say `N'.
1146 +config IP_NF_MATCH_POLICY
1147 + tristate "IPsec policy match support"
1148 + depends on IP_NF_IPTABLES && XFRM
1150 + Policy matching allows you to match packets based on the
1151 + IPsec policy that was used during decapsulation/will
1152 + be used during encapsulation.
1154 + To compile it as a module, choose M here. If unsure, say N.
1156 +config IP_NF_CT_PROTO_SCTP
1157 + tristate 'SCTP protocol connection tracking support'
1158 + depends on IP_NF_CONNTRACK
1160 +config IP_NF_MATCH_STRING
1161 + tristate 'String match support'
1162 + depends on IP_NF_IPTABLES
1164 + String matching alows you to match packets which contain a
1165 + specified string of characters.
1167 + If you want to compile it as a module, say M here and read
1168 + Documentation/modules.txt. If unsure, say `N'.
1172 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/Makefile linux-2.6.7/net/ipv4/netfilter/Makefile
1173 --- linux-2.6.7.org/net/ipv4/netfilter/Makefile 2004-06-29 12:24:13.000000000 +0200
1174 +++ linux-2.6.7/net/ipv4/netfilter/Makefile 2004-06-29 12:36:14.615163144 +0200
1176 # connection tracking
1177 obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
1179 +# SCTP protocol connection tracking
1180 +obj-$(CONFIG_IP_NF_CT_PROTO_SCTP) += ip_conntrack_proto_sctp.o
1182 # connection tracking helpers
1183 obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o
1184 obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o
1187 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
1188 obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
1189 +obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o
1190 +obj-$(CONFIG_IP_NF_MATCH_QUOTA) += ipt_quota.o
1191 +obj-$(CONFIG_IP_NF_MATCH_DSTLIMIT) += ipt_dstlimit.o
1192 obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
1193 obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
1194 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
1196 obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
1197 obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
1199 +obj-$(CONFIG_IP_NF_MATCH_MPORT) += ipt_mport.o
1201 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
1202 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
1204 +obj-$(CONFIG_IP_NF_MATCH_TIME) += ipt_time.o
1207 +obj-$(CONFIG_IP_NF_MATCH_PSD) += ipt_psd.o
1209 +obj-$(CONFIG_IP_NF_MATCH_NTH) += ipt_nth.o
1211 +obj-$(CONFIG_IP_NF_MATCH_IPV4OPTIONS) += ipt_ipv4options.o
1214 +obj-$(CONFIG_IP_NF_MATCH_FUZZY) += ipt_fuzzy.o
1216 obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
1218 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
1221 obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o
1223 +obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o
1224 +obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o
1225 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
1226 obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
1227 +obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o
1228 +obj-$(CONFIG_IP_NF_MATCH_CONNLIMIT) += ipt_connlimit.o
1229 obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
1230 obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
1231 obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
1232 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
1234 obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
1235 +obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o
1238 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
1239 +obj-$(CONFIG_IP_NF_TARGET_TARPIT) += ipt_TARPIT.o
1240 obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
1241 obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
1242 obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o
1243 obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o
1244 +obj-$(CONFIG_IP_NF_TARGET_IPMARK) += ipt_IPMARK.o
1245 obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
1246 obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
1247 +obj-$(CONFIG_IP_NF_TARGET_ROUTE) += ipt_ROUTE.o
1248 obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
1249 obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o
1250 obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
1251 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
1252 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
1253 +obj-$(CONFIG_IP_NF_TARGET_XOR) += ipt_XOR.o
1254 +obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o
1255 +obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
1256 +obj-$(CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP) += ipt_IPV4OPTSSTRIP.o
1257 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
1258 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
1259 obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o
1260 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ip_conntrack_core.c linux-2.6.7/net/ipv4/netfilter/ip_conntrack_core.c
1261 --- linux-2.6.7.org/net/ipv4/netfilter/ip_conntrack_core.c 2004-06-29 12:24:13.000000000 +0200
1262 +++ linux-2.6.7/net/ipv4/netfilter/ip_conntrack_core.c 2004-06-29 12:34:21.572348264 +0200
1264 static LIST_HEAD(helpers);
1265 unsigned int ip_conntrack_htable_size = 0;
1266 int ip_conntrack_max;
1267 -static atomic_t ip_conntrack_count = ATOMIC_INIT(0);
1268 +atomic_t ip_conntrack_count = ATOMIC_INIT(0);
1269 struct list_head *ip_conntrack_hash;
1270 static kmem_cache_t *ip_conntrack_cachep;
1271 +static kmem_cache_t *ip_conntrack_expect_cachep;
1272 struct ip_conntrack ip_conntrack_untracked;
1274 extern struct ip_conntrack_protocol ip_conntrack_generic_protocol;
1276 IP_NF_ASSERT(atomic_read(&exp->use) == 0);
1277 IP_NF_ASSERT(!timer_pending(&exp->timeout));
1280 + kmem_cache_free(ip_conntrack_expect_cachep, exp);
1283 inline void ip_conntrack_expect_put(struct ip_conntrack_expect *exp)
1285 list_del(&ct->master->expected_list);
1286 master = ct->master->expectant;
1288 - kfree(ct->master);
1289 + kmem_cache_free(ip_conntrack_expect_cachep, ct->master);
1291 WRITE_UNLOCK(&ip_conntrack_lock);
1294 __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
1295 conntrack->master = expected;
1296 expected->sibling = conntrack;
1297 +#if CONFIG_IP_NF_CONNTRACK_MARK
1298 + conntrack->mark = expected->expectant->mark;
1300 LIST_DELETE(&ip_conntrack_expect_list, expected);
1301 expected->expectant->expecting--;
1302 nf_conntrack_get(&master_ct(conntrack)->infos[0]);
1304 ip_conntrack_expect_alloc(void)
1306 struct ip_conntrack_expect *new;
1308 - new = (struct ip_conntrack_expect *)
1309 - kmalloc(sizeof(struct ip_conntrack_expect), GFP_ATOMIC);
1311 + new = kmem_cache_alloc(ip_conntrack_expect_cachep, GFP_ATOMIC);
1313 DEBUGP("expect_related: OOM allocating expect\n");
1317 /* tuple_cmp compares whole union, we have to initialized cleanly */
1318 memset(new, 0, sizeof(struct ip_conntrack_expect));
1319 + atomic_set(&new->use, 1);
1324 DEBUGP("new expectation %p of conntrack %p\n", new, related_to);
1325 new->expectant = related_to;
1326 new->sibling = NULL;
1327 - atomic_set(&new->use, 1);
1329 /* add to expected list for this connection */
1330 list_add_tail(&new->expected_list, &related_to->sibling_list);
1331 @@ -997,7 +1000,8 @@
1334 WRITE_UNLOCK(&ip_conntrack_lock);
1336 + /* This expectation is not inserted so no need to lock */
1337 + kmem_cache_free(ip_conntrack_expect_cachep, expect);
1340 } else if (related_to->helper->max_expected &&
1341 @@ -1015,7 +1019,7 @@
1342 related_to->helper->name,
1343 NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip),
1344 NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip));
1346 + kmem_cache_free(ip_conntrack_expect_cachep, expect);
1349 DEBUGP("ip_conntrack: max number of expected "
1350 @@ -1049,7 +1053,7 @@
1351 WRITE_UNLOCK(&ip_conntrack_lock);
1352 DEBUGP("expect_related: busy!\n");
1355 + kmem_cache_free(ip_conntrack_expect_cachep, expect);
1359 @@ -1368,6 +1372,7 @@
1362 kmem_cache_destroy(ip_conntrack_cachep);
1363 + kmem_cache_destroy(ip_conntrack_expect_cachep);
1364 vfree(ip_conntrack_hash);
1365 nf_unregister_sockopt(&so_getorigdst);
1367 @@ -1420,6 +1425,15 @@
1368 printk(KERN_ERR "Unable to create ip_conntrack slab cache\n");
1372 + ip_conntrack_expect_cachep = kmem_cache_create("ip_conntrack_expect",
1373 + sizeof(struct ip_conntrack_expect),
1374 + 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
1375 + if (!ip_conntrack_expect_cachep) {
1376 + printk(KERN_ERR "Unable to create ip_expect slab cache\n");
1377 + goto err_free_conntrack_slab;
1380 /* Don't NEED lock here, but good form anyway. */
1381 WRITE_LOCK(&ip_conntrack_lock);
1382 /* Sew in builtin protocols. */
1383 @@ -1447,6 +1461,8 @@
1387 +err_free_conntrack_slab:
1388 + kmem_cache_destroy(ip_conntrack_cachep);
1390 vfree(ip_conntrack_hash);
1392 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ip_conntrack_proto_sctp.c linux-2.6.7/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
1393 --- linux-2.6.7.org/net/ipv4/netfilter/ip_conntrack_proto_sctp.c 1970-01-01 01:00:00.000000000 +0100
1394 +++ linux-2.6.7/net/ipv4/netfilter/ip_conntrack_proto_sctp.c 2004-06-29 12:35:41.898136888 +0200
1397 + * Connection tracking protocol helper module for SCTP.
1399 + * SCTP is defined in RFC 2960. References to various sections in this code
1400 + * are to this RFC.
1402 + * This program is free software; you can redistribute it and/or modify
1403 + * it under the terms of the GNU General Public License version 2 as
1404 + * published by the Free Software Foundation.
1407 +#include <linux/types.h>
1408 +#include <linux/sched.h>
1409 +#include <linux/timer.h>
1410 +#include <linux/netfilter.h>
1411 +#include <linux/module.h>
1412 +#include <linux/in.h>
1413 +#include <linux/ip.h>
1414 +#include <linux/sctp.h>
1415 +#include <linux/string.h>
1417 +#include <linux/netfilter_ipv4/ip_conntrack.h>
1418 +#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
1419 +#include <linux/netfilter_ipv4/lockhelp.h>
1422 +#define DEBUGP(format, ...) printk(format, ## __VA_ARGS__)
1424 +#define DEBUGP(format, args...)
1427 +/* Protects conntrack->proto.sctp */
1428 +static DECLARE_RWLOCK(sctp_lock);
1430 +/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
1431 + closely. They're more complex. --RR
1433 + And so for me for SCTP :D -Kiran */
1435 +static const char *sctp_conntrack_names[] = {
1443 + "SHUTDOWN_ACK_SENT",
1447 +#define MINS * 60 SECS
1448 +#define HOURS * 60 MINS
1449 +#define DAYS * 24 HOURS
1451 +unsigned long ip_ct_sctp_timeout_closed = 10 SECS;
1452 +unsigned long ip_ct_sctp_timeout_cookie_wait = 3 SECS;
1453 +unsigned long ip_ct_sctp_timeout_cookie_echoed = 3 SECS;
1454 +unsigned long ip_ct_sctp_timeout_established = 5 DAYS;
1455 +unsigned long ip_ct_sctp_timeout_shutdown_sent = 300 SECS / 1000;
1456 +unsigned long ip_ct_sctp_timeout_shutdown_recd = 300 SECS / 1000;
1457 +unsigned long ip_ct_sctp_timeout_shutdown_ack_sent = 3 SECS;
1459 +static unsigned long * sctp_timeouts[]
1460 += { 0, /* SCTP_CONNTRACK_NONE */
1461 + &ip_ct_sctp_timeout_closed, /* SCTP_CONNTRACK_CLOSED */
1462 + &ip_ct_sctp_timeout_cookie_wait, /* SCTP_CONNTRACK_COOKIE_WAIT */
1463 + &ip_ct_sctp_timeout_cookie_echoed, /* SCTP_CONNTRACK_COOKIE_ECHOED */
1464 + &ip_ct_sctp_timeout_established, /* SCTP_CONNTRACK_ESTABLISHED */
1465 + &ip_ct_sctp_timeout_shutdown_sent, /* SCTP_CONNTRACK_SHUTDOWN_SENT */
1466 + &ip_ct_sctp_timeout_shutdown_recd, /* SCTP_CONNTRACK_SHUTDOWN_RECD */
1467 + &ip_ct_sctp_timeout_shutdown_ack_sent /* SCTP_CONNTRACK_SHUTDOWN_ACK_SENT */
1470 +#define sNO SCTP_CONNTRACK_NONE
1471 +#define sCL SCTP_CONNTRACK_CLOSED
1472 +#define sCW SCTP_CONNTRACK_COOKIE_WAIT
1473 +#define sCE SCTP_CONNTRACK_COOKIE_ECHOED
1474 +#define sES SCTP_CONNTRACK_ESTABLISHED
1475 +#define sSS SCTP_CONNTRACK_SHUTDOWN_SENT
1476 +#define sSR SCTP_CONNTRACK_SHUTDOWN_RECD
1477 +#define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
1478 +#define sIV SCTP_CONNTRACK_MAX
1481 + These are the descriptions of the states:
1483 +NOTE: These state names are tantalizingly similar to the states of an
1484 +SCTP endpoint. But the interpretation of the states is a little different,
1485 +considering that these are the states of the connection and not of an end
1486 +point. Please note the subtleties. -Kiran
1488 +NONE - Nothing so far.
1489 +COOKIE WAIT - We have seen an INIT chunk in the original direction, or also
1490 + an INIT_ACK chunk in the reply direction.
1491 +COOKIE ECHOED - We have seen a COOKIE_ECHO chunk in the original direction.
1492 +ESTABLISHED - We have seen a COOKIE_ACK in the reply direction.
1493 +SHUTDOWN_SENT - We have seen a SHUTDOWN chunk in the original direction.
1494 +SHUTDOWN_RECD - We have seen a SHUTDOWN chunk in the reply directoin.
1495 +SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opposite
1496 + to that of the SHUTDOWN chunk.
1497 +CLOSED - We have seen a SHUTDOWN_COMPLETE chunk in the direction of
1498 + the SHUTDOWN chunk. Connection is closed.
1502 + - I have assumed that the first INIT is in the original direction.
1503 + This messes things when an INIT comes in the reply direction in CLOSED
1505 + - Check the error type in the reply dir before transitioning from
1506 +cookie echoed to closed.
1507 + - Sec 5.2.4 of RFC 2960
1508 + - Multi Homing support.
1511 +/* SCTP conntrack state transitions */
1512 +static enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
1515 +/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
1516 +/* init */ {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA},
1517 +/* init_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},
1518 +/* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
1519 +/* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA},
1520 +/* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA},
1521 +/* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant have Stale cookie*/
1522 +/* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},/* 5.2.4 - Big TODO */
1523 +/* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come in orig dir */
1524 +/* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL}
1528 +/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
1529 +/* init */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* INIT in sCL Big TODO */
1530 +/* init_ack */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},
1531 +/* abort */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
1532 +/* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA},
1533 +/* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA},
1534 +/* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA},
1535 +/* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come in reply dir */
1536 +/* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA},
1537 +/* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL}
1541 +static int sctp_pkt_to_tuple(const struct sk_buff *skb,
1542 + unsigned int dataoff,
1543 + struct ip_conntrack_tuple *tuple)
1545 + sctp_sctphdr_t hdr;
1547 + DEBUGP(__FUNCTION__);
1550 + /* Actually only need first 8 bytes. */
1551 + if (skb_copy_bits(skb, dataoff, &hdr, 8) != 0)
1554 + tuple->src.u.sctp.port = hdr.source;
1555 + tuple->dst.u.sctp.port = hdr.dest;
1560 +static int sctp_invert_tuple(struct ip_conntrack_tuple *tuple,
1561 + const struct ip_conntrack_tuple *orig)
1563 + DEBUGP(__FUNCTION__);
1566 + tuple->src.u.sctp.port = orig->dst.u.sctp.port;
1567 + tuple->dst.u.sctp.port = orig->src.u.sctp.port;
1571 +/* Print out the per-protocol part of the tuple. */
1572 +static unsigned int sctp_print_tuple(char *buffer,
1573 + const struct ip_conntrack_tuple *tuple)
1575 + DEBUGP(__FUNCTION__);
1578 + return sprintf(buffer, "sport=%hu dport=%hu ",
1579 + ntohs(tuple->src.u.sctp.port),
1580 + ntohs(tuple->dst.u.sctp.port));
1583 +/* Print out the private part of the conntrack. */
1584 +static unsigned int sctp_print_conntrack(char *buffer,
1585 + const struct ip_conntrack *conntrack)
1587 + enum sctp_conntrack state;
1589 + DEBUGP(__FUNCTION__);
1592 + READ_LOCK(&sctp_lock);
1593 + state = conntrack->proto.sctp.state;
1594 + READ_UNLOCK(&sctp_lock);
1596 + return sprintf(buffer, "%s ", sctp_conntrack_names[state]);
1599 +#define for_each_sctp_chunk(skb, sch, offset, count) \
1600 +for (offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t), count = 0; \
1601 + offset < skb->len && !skb_copy_bits(skb, offset, &sch, sizeof(sch)); \
1602 + offset += (htons(sch.length) + 3) & ~3, count++)
1604 +/* Some validity checks to make sure the chunks are fine */
1605 +static int do_basic_checks(struct ip_conntrack *conntrack,
1606 + const struct sk_buff *skb,
1609 + u_int32_t offset, count;
1610 + sctp_chunkhdr_t sch;
1613 + DEBUGP(__FUNCTION__);
1618 + for_each_sctp_chunk (skb, sch, offset, count) {
1619 + DEBUGP("Chunk Num: %d Type: %d\n", count, sch.type);
1621 + if (sch.type == SCTP_CID_INIT
1622 + || sch.type == SCTP_CID_INIT_ACK
1623 + || sch.type == SCTP_CID_SHUTDOWN_COMPLETE) {
1627 + /* Cookie Ack/Echo chunks not the first OR
1628 + Init / Init Ack / Shutdown compl chunks not the only chunks */
1629 + if ((sch.type == SCTP_CID_COOKIE_ACK
1630 + || sch.type == SCTP_CID_COOKIE_ECHO
1633 + DEBUGP("Basic checks failed\n");
1638 + set_bit (sch.type, (void *)map);
1642 + DEBUGP("Basic checks passed\n");
1646 +static int new_state(enum ip_conntrack_dir dir,
1647 + enum sctp_conntrack cur_state,
1652 + DEBUGP(__FUNCTION__);
1655 + DEBUGP("Chunk type: %d\n", chunk_type);
1657 + switch (chunk_type) {
1658 + case SCTP_CID_INIT:
1659 + DEBUGP("SCTP_CID_INIT\n");
1661 + case SCTP_CID_INIT_ACK:
1662 + DEBUGP("SCTP_CID_INIT_ACK\n");
1664 + case SCTP_CID_ABORT:
1665 + DEBUGP("SCTP_CID_ABORT\n");
1667 + case SCTP_CID_SHUTDOWN:
1668 + DEBUGP("SCTP_CID_SHUTDOWN\n");
1670 + case SCTP_CID_SHUTDOWN_ACK:
1671 + DEBUGP("SCTP_CID_SHUTDOWN_ACK\n");
1673 + case SCTP_CID_ERROR:
1674 + DEBUGP("SCTP_CID_ERROR\n");
1676 + case SCTP_CID_COOKIE_ECHO:
1677 + DEBUGP("SCTP_CID_COOKIE_ECHO\n");
1679 + case SCTP_CID_COOKIE_ACK:
1680 + DEBUGP("SCTP_CID_COOKIE_ACK\n");
1682 + case SCTP_CID_SHUTDOWN_COMPLETE:
1683 + DEBUGP("SCTP_CID_SHUTDOWN_COMPLETE\n");
1686 + /* Other chunks like DATA, SACK, HEARTBEAT and
1687 + its ACK do not cause a change in state */
1688 + DEBUGP("Unknown chunk type, Will stay in %s\n",
1689 + sctp_conntrack_names[cur_state]);
1693 + DEBUGP("dir: %d cur_state: %s chunk_type: %d new_state: %s\n",
1694 + dir, sctp_conntrack_names[cur_state], chunk_type,
1695 + sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
1697 + return sctp_conntracks[dir][i][cur_state];
1700 +/* Returns verdict for packet, or -1 for invalid. */
1701 +static int sctp_packet(struct ip_conntrack *conntrack,
1702 + const struct sk_buff *skb,
1703 + enum ip_conntrack_info ctinfo)
1705 + enum sctp_conntrack newconntrack, oldsctpstate;
1706 + sctp_sctphdr_t sctph;
1707 + sctp_chunkhdr_t sch;
1708 + u_int32_t offset, count;
1709 + char map[256 / sizeof (char)] = {0};
1711 + DEBUGP(__FUNCTION__);
1714 + if (skb_copy_bits(skb, skb->nh.iph->ihl * 4, &sctph, sizeof(sctph)) != 0)
1717 + if (do_basic_checks(conntrack, skb, map) != 0)
1720 + /* Check the verification tag (Sec 8.5) */
1721 + if (!test_bit(SCTP_CID_INIT, (void *)map)
1722 + && !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, (void *)map)
1723 + && !test_bit(SCTP_CID_COOKIE_ECHO, (void *)map)
1724 + && !test_bit(SCTP_CID_ABORT, (void *)map)
1725 + && !test_bit(SCTP_CID_SHUTDOWN_ACK, (void *)map)
1726 + && (sctph.vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
1727 + DEBUGP("Verification tag check failed\n");
1731 + oldsctpstate = newconntrack = SCTP_CONNTRACK_MAX;
1732 + for_each_sctp_chunk (skb, sch, offset, count) {
1733 + WRITE_LOCK(&sctp_lock);
1735 + /* Special cases of Verification tag check (Sec 8.5.1) */
1736 + if (sch.type == SCTP_CID_INIT) {
1737 + /* Sec 8.5.1 (A) */
1738 + if (sctph.vtag != 0) {
1739 + WRITE_UNLOCK(&sctp_lock);
1742 + } else if (sch.type == SCTP_CID_ABORT) {
1743 + /* Sec 8.5.1 (B) */
1744 + if (!(sctph.vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
1745 + && !(sctph.vtag == conntrack->proto.sctp.vtag
1746 + [1 - CTINFO2DIR(ctinfo)])) {
1747 + WRITE_UNLOCK(&sctp_lock);
1750 + } else if (sch.type == SCTP_CID_SHUTDOWN_COMPLETE) {
1751 + /* Sec 8.5.1 (C) */
1752 + if (!(sctph.vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
1753 + && !(sctph.vtag == conntrack->proto.sctp.vtag
1754 + [1 - CTINFO2DIR(ctinfo)]
1755 + && (sch.flags & 1))) {
1756 + WRITE_UNLOCK(&sctp_lock);
1759 + } else if (sch.type == SCTP_CID_COOKIE_ECHO) {
1760 + /* Sec 8.5.1 (D) */
1761 + if (!(sctph.vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
1762 + WRITE_UNLOCK(&sctp_lock);
1767 + oldsctpstate = conntrack->proto.sctp.state;
1768 + newconntrack = new_state(CTINFO2DIR(ctinfo), oldsctpstate, sch.type);
1771 + if (newconntrack == SCTP_CONNTRACK_MAX) {
1772 + DEBUGP("ip_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u\n",
1773 + CTINFO2DIR(ctinfo), sch.type, oldsctpstate);
1774 + WRITE_UNLOCK(&sctp_lock);
1778 + /* If it is an INIT or an INIT ACK note down the vtag */
1779 + if (sch.type == SCTP_CID_INIT
1780 + || sch.type == SCTP_CID_INIT_ACK) {
1781 + sctp_inithdr_t inithdr;
1783 + if (skb_copy_bits(skb, offset + sizeof (sctp_chunkhdr_t),
1784 + &inithdr, sizeof(inithdr)) != 0) {
1785 + WRITE_UNLOCK(&sctp_lock);
1788 + DEBUGP("Setting vtag %x for dir %d\n",
1789 + inithdr.init_tag, CTINFO2DIR(ctinfo));
1790 + conntrack->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] = inithdr.init_tag;
1793 + conntrack->proto.sctp.state = newconntrack;
1794 + WRITE_UNLOCK(&sctp_lock);
1797 + ip_ct_refresh(conntrack, *sctp_timeouts[newconntrack]);
1799 + if (oldsctpstate == SCTP_CONNTRACK_COOKIE_ECHOED
1800 + && CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY
1801 + && newconntrack == SCTP_CONNTRACK_ESTABLISHED) {
1802 + DEBUGP("Setting assured bit\n");
1803 + set_bit(IPS_ASSURED_BIT, &conntrack->status);
1809 +/* Called when a new connection for this protocol found. */
1810 +static int sctp_new(struct ip_conntrack *conntrack,
1811 + const struct sk_buff *skb)
1813 + enum sctp_conntrack newconntrack;
1814 + sctp_sctphdr_t sctph;
1815 + sctp_chunkhdr_t sch;
1816 + u_int32_t offset, count;
1817 + char map[256 / sizeof (char)] = {0};
1819 + DEBUGP(__FUNCTION__);
1822 + if (skb_copy_bits(skb, skb->nh.iph->ihl * 4, &sctph, sizeof(sctph)) != 0)
1825 + if (do_basic_checks(conntrack, skb, map) != 0)
1828 + /* If an OOTB packet has any of these chunks discard (Sec 8.4) */
1829 + if ((test_bit (SCTP_CID_ABORT, (void *)map))
1830 + || (test_bit (SCTP_CID_SHUTDOWN_COMPLETE, (void *)map))
1831 + || (test_bit (SCTP_CID_COOKIE_ACK, (void *)map))) {
1835 + newconntrack = SCTP_CONNTRACK_MAX;
1836 + for_each_sctp_chunk (skb, sch, offset, count) {
1837 + /* Don't need lock here: this conntrack not in circulation yet */
1838 + newconntrack = new_state (IP_CT_DIR_ORIGINAL,
1839 + SCTP_CONNTRACK_NONE, sch.type);
1841 + /* Invalid: delete conntrack */
1842 + if (newconntrack == SCTP_CONNTRACK_MAX) {
1843 + DEBUGP("ip_conntrack_sctp: invalid new deleting.\n");
1847 + /* Copy the vtag into the state info */
1848 + if (sch.type == SCTP_CID_INIT) {
1849 + if (sctph.vtag == 0) {
1850 + sctp_inithdr_t inithdr;
1852 + if (skb_copy_bits(skb, offset + sizeof (sctp_chunkhdr_t),
1853 + &inithdr, sizeof(inithdr)) != 0) {
1857 + DEBUGP("Setting vtag %x for new conn\n",
1858 + inithdr.init_tag);
1860 + conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] =
1863 + /* Sec 8.5.1 (A) */
1867 + /* If it is a shutdown ack OOTB packet, we expect a return
1868 + shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
1870 + DEBUGP("Setting vtag %x for new conn OOTB\n",
1872 + conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = sctph.vtag;
1875 + conntrack->proto.sctp.state = newconntrack;
1881 +static int sctp_exp_matches_pkt(struct ip_conntrack_expect *exp,
1882 + const struct sk_buff *skb)
1884 + /* To be implemented */
1888 +struct ip_conntrack_protocol ip_conntrack_protocol_sctp = {
1889 + .list = { NULL, NULL },
1890 + .proto = IPPROTO_SCTP,
1892 + .pkt_to_tuple = sctp_pkt_to_tuple,
1893 + .invert_tuple = sctp_invert_tuple,
1894 + .print_tuple = sctp_print_tuple,
1895 + .print_conntrack = sctp_print_conntrack,
1896 + .packet = sctp_packet,
1899 + .exp_matches_pkt = sctp_exp_matches_pkt,
1903 +int __init init(void)
1907 + ret = ip_conntrack_protocol_register(&ip_conntrack_protocol_sctp);
1908 + DEBUGP("SCTP conntrack module loading %s\n",
1909 + ret ? "failed": "succeeded");
1913 +void __exit fini(void)
1915 + ip_conntrack_protocol_unregister(&ip_conntrack_protocol_sctp);
1916 + DEBUGP("SCTP conntrack module unloaded\n");
1922 +MODULE_LICENSE("GPL");
1923 +MODULE_AUTHOR("Kiran Kumar Immidi");
1924 +MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");
1925 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.7/net/ipv4/netfilter/ip_conntrack_standalone.c
1926 --- linux-2.6.7.org/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-06-29 12:24:13.000000000 +0200
1927 +++ linux-2.6.7/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-06-29 12:34:21.566349176 +0200
1929 len += sprintf(buffer + len, "[ASSURED] ");
1930 len += sprintf(buffer + len, "use=%u ",
1931 atomic_read(&conntrack->ct_general.use));
1932 +#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
1933 + len += sprintf(buffer + len, "mark=%ld ", conntrack->mark);
1935 len += sprintf(buffer + len, "\n");
1940 /* From ip_conntrack_core.c */
1941 extern int ip_conntrack_max;
1942 +extern atomic_t ip_conntrack_count;
1943 extern unsigned int ip_conntrack_htable_size;
1945 /* From ip_conntrack_proto_tcp.c */
1946 @@ -346,6 +350,14 @@
1947 .proc_handler = &proc_dointvec,
1950 + .ctl_name = NET_IPV4_NF_CONNTRACK_COUNT,
1951 + .procname = "ip_conntrack_count",
1952 + .data = &ip_conntrack_count,
1953 + .maxlen = sizeof(int),
1955 + .proc_handler = &proc_dointvec,
1958 .ctl_name = NET_IPV4_NF_CONNTRACK_BUCKETS,
1959 .procname = "ip_conntrack_buckets",
1960 .data = &ip_conntrack_htable_size,
1961 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ip_queue.c linux-2.6.7/net/ipv4/netfilter/ip_queue.c
1962 --- linux-2.6.7.org/net/ipv4/netfilter/ip_queue.c 2004-06-16 07:20:26.000000000 +0200
1963 +++ linux-2.6.7/net/ipv4/netfilter/ip_queue.c 2004-06-29 12:35:08.146267952 +0200
1964 @@ -421,6 +421,33 @@
1968 +ipq_set_vwmark(struct ipq_vwmark_msg *vmsg, unsigned int len)
1970 + struct ipq_queue_entry *entry;
1972 + if (vmsg->value > NF_MAX_VERDICT)
1975 + entry = ipq_find_dequeue_entry(id_cmp, vmsg->id);
1976 + if (entry == NULL)
1979 + int verdict = vmsg->value;
1981 + if (vmsg->data_len && vmsg->data_len == len)
1982 + if (ipq_mangle_ipv4((ipq_verdict_msg_t *)vmsg, entry) < 0)
1983 + verdict = NF_DROP;
1985 + /* set mark of associated skb */
1986 + entry->skb->nfmark = vmsg->nfmark;
1988 + ipq_issue_verdict(entry, verdict);
1995 ipq_receive_peer(struct ipq_peer_msg *pmsg,
1996 unsigned char type, unsigned int len)
1998 @@ -442,6 +469,14 @@
1999 status = ipq_set_verdict(&pmsg->msg.verdict,
2000 len - sizeof(*pmsg));
2003 + if (pmsg->msg.verdict.value > NF_MAX_VERDICT)
2006 + status = ipq_set_vwmark(&pmsg->msg.vwmark,
2007 + len - sizeof(*pmsg));
2013 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ip_tables.c linux-2.6.7/net/ipv4/netfilter/ip_tables.c
2014 --- linux-2.6.7.org/net/ipv4/netfilter/ip_tables.c 2004-06-29 12:24:13.000000000 +0200
2015 +++ linux-2.6.7/net/ipv4/netfilter/ip_tables.c 2004-06-29 12:35:27.076390136 +0200
2017 * it under the terms of the GNU General Public License version 2 as
2018 * published by the Free Software Foundation.
2020 + * 6 Mar 2002 Robert Olsson <robban@robtex.com>
2021 + * 17 Apr 2003 Chris Wilson <chris@netservers.co.uk>
2022 + * - mark_source_chains speedup for complex chains
2024 * 19 Jan 2002 Harald Welte <laforge@gnumonks.org>
2025 * - increase module usage count as soon as we have rules inside
2031 + /* keep track of where we have been: */
2032 + unsigned char *been = vmalloc(newinfo->size);
2034 /* No recursion; use packet counter to save back ptrs (reset
2035 to 0 as we leave), and comefrom to save source hook bitmask */
2036 for (hook = 0; hook < NF_IP_NUMHOOKS; hook++) {
2039 /* Set initial back pointer. */
2040 e->counters.pcnt = pos;
2041 + memset(been, 0, newinfo->size);
2044 struct ipt_standard_target *t
2046 if (e->comefrom & (1 << NF_IP_NUMHOOKS)) {
2047 printk("iptables: loop hook %u pos %u %08X.\n",
2048 hook, pos, e->comefrom);
2053 @@ -562,10 +571,14 @@
2055 int newpos = t->verdict;
2057 - if (strcmp(t->target.u.user.name,
2058 + if ( (pos < 0 || pos >= newinfo->size
2060 + && strcmp(t->target.u.user.name,
2061 IPT_STANDARD_TARGET) == 0
2063 /* This a jump; chase it. */
2064 + if (pos >= 0 && pos < newinfo->size)
2066 duprintf("Jump rule %u -> %u\n",
2071 duprintf("Finished chain %u\n", hook);
2077 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_CONNMARK.c linux-2.6.7/net/ipv4/netfilter/ipt_CONNMARK.c
2078 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_CONNMARK.c 1970-01-01 01:00:00.000000000 +0100
2079 +++ linux-2.6.7/net/ipv4/netfilter/ipt_CONNMARK.c 2004-06-29 12:34:21.512357384 +0200
2081 +/* This kernel module is used to modify the connection mark values, or
2082 + * to optionally restore the skb nfmark from the connection mark
2084 + * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
2085 + * by Henrik Nordstrom <hno@marasystems.com>
2087 + * This program is free software; you can redistribute it and/or modify
2088 + * it under the terms of the GNU General Public License as published by
2089 + * the Free Software Foundation; either version 2 of the License, or
2090 + * (at your option) any later version.
2092 + * This program is distributed in the hope that it will be useful,
2093 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2094 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2095 + * GNU General Public License for more details.
2097 + * You should have received a copy of the GNU General Public License
2098 + * along with this program; if not, write to the Free Software
2099 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2101 +#include <linux/module.h>
2102 +#include <linux/skbuff.h>
2103 +#include <linux/ip.h>
2104 +#include <net/checksum.h>
2106 +MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
2107 +MODULE_DESCRIPTION("IP tables CONNMARK matching module");
2108 +MODULE_LICENSE("GPL");
2110 +#include <linux/netfilter_ipv4/ip_tables.h>
2111 +#include <linux/netfilter_ipv4/ipt_CONNMARK.h>
2112 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2114 +static unsigned int
2115 +target(struct sk_buff **pskb,
2116 + const struct net_device *in,
2117 + const struct net_device *out,
2118 + unsigned int hooknum,
2119 + const void *targinfo,
2122 + const struct ipt_connmark_target_info *markinfo = targinfo;
2123 + unsigned long diff;
2124 + unsigned long nfmark;
2125 + unsigned long newmark;
2127 + enum ip_conntrack_info ctinfo;
2128 + struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo);
2130 + switch(markinfo->mode) {
2131 + case IPT_CONNMARK_SET:
2132 + newmark = (ct->mark & ~markinfo->mask) | markinfo->mark;
2133 + if (newmark != ct->mark)
2134 + ct->mark = newmark;
2136 + case IPT_CONNMARK_SAVE:
2137 + newmark = (ct->mark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask);
2138 + if (ct->mark != newmark)
2139 + ct->mark = newmark;
2141 + case IPT_CONNMARK_RESTORE:
2142 + nfmark = (*pskb)->nfmark;
2143 + diff = (ct->mark ^ nfmark & markinfo->mask);
2145 + (*pskb)->nfmark = nfmark ^ diff;
2146 + (*pskb)->nfcache |= NFC_ALTERED;
2152 + return IPT_CONTINUE;
2156 +checkentry(const char *tablename,
2157 + const struct ipt_entry *e,
2159 + unsigned int targinfosize,
2160 + unsigned int hook_mask)
2162 + struct ipt_connmark_target_info *matchinfo = targinfo;
2163 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) {
2164 + printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n",
2166 + IPT_ALIGN(sizeof(struct ipt_connmark_target_info)));
2170 + if (matchinfo->mode == IPT_CONNMARK_RESTORE) {
2171 + if (strcmp(tablename, "mangle") != 0) {
2172 + printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename);
2180 +static struct ipt_target ipt_connmark_reg = {
2181 + .name = "CONNMARK",
2182 + .target = &target,
2183 + .checkentry = &checkentry,
2187 +static int __init init(void)
2189 + return ipt_register_target(&ipt_connmark_reg);
2192 +static void __exit fini(void)
2194 + ipt_unregister_target(&ipt_connmark_reg);
2199 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_IPMARK.c linux-2.6.7/net/ipv4/netfilter/ipt_IPMARK.c
2200 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_IPMARK.c 1970-01-01 01:00:00.000000000 +0100
2201 +++ linux-2.6.7/net/ipv4/netfilter/ipt_IPMARK.c 2004-06-29 12:34:27.609430488 +0200
2203 +/* This is a module which is used for setting the NFMARK field of an skb. */
2204 +#include <linux/module.h>
2205 +#include <linux/skbuff.h>
2206 +#include <linux/ip.h>
2207 +#include <net/checksum.h>
2209 +#include <linux/netfilter_ipv4/ip_tables.h>
2210 +#include <linux/netfilter_ipv4/ipt_IPMARK.h>
2212 +MODULE_AUTHOR("Grzegorz Janoszka <Grzegorz.Janoszka@pro.onet.pl>");
2213 +MODULE_DESCRIPTION("IP tables IPMARK: mark based on ip address");
2214 +MODULE_LICENSE("GPL");
2216 +static unsigned int
2217 +target(struct sk_buff **pskb,
2218 + const struct net_device *in,
2219 + const struct net_device *out,
2220 + unsigned int hooknum,
2221 + const void *targinfo,
2224 + const struct ipt_ipmark_target_info *ipmarkinfo = targinfo;
2225 + struct iphdr *iph = (*pskb)->nh.iph;
2226 + unsigned long mark;
2228 + if (ipmarkinfo->addr == IPT_IPMARK_SRC)
2229 + mark = (unsigned long) ntohl(iph->saddr);
2231 + mark = (unsigned long) ntohl(iph->daddr);
2233 + mark &= ipmarkinfo->andmask;
2234 + mark |= ipmarkinfo->ormask;
2236 + if ((*pskb)->nfmark != mark) {
2237 + (*pskb)->nfmark = mark;
2238 + (*pskb)->nfcache |= NFC_ALTERED;
2240 + return IPT_CONTINUE;
2244 +checkentry(const char *tablename,
2245 + const struct ipt_entry *e,
2247 + unsigned int targinfosize,
2248 + unsigned int hook_mask)
2250 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ipmark_target_info))) {
2251 + printk(KERN_WARNING "IPMARK: targinfosize %u != %Zu\n",
2253 + IPT_ALIGN(sizeof(struct ipt_ipmark_target_info)));
2257 + if (strcmp(tablename, "mangle") != 0) {
2258 + printk(KERN_WARNING "IPMARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
2265 +static struct ipt_target ipt_ipmark_reg = {
2268 + .checkentry = checkentry,
2272 +static int __init init(void)
2274 + return ipt_register_target(&ipt_ipmark_reg);
2277 +static void __exit fini(void)
2279 + ipt_unregister_target(&ipt_ipmark_reg);
2284 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c linux-2.6.7/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c
2285 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 1970-01-01 01:00:00.000000000 +0100
2286 +++ linux-2.6.7/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 2004-06-29 12:32:01.665617320 +0200
2289 + * Strip all IP options in the IP packet header.
2291 + * (C) 2001 by Fabrice MARIE <fabrice@netfilter.org>
2292 + * This software is distributed under GNU GPL v2, 1991
2295 +#include <linux/module.h>
2296 +#include <linux/skbuff.h>
2297 +#include <net/ip.h>
2298 +#include <net/checksum.h>
2300 +#include <linux/netfilter_ipv4/ip_tables.h>
2302 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
2303 +MODULE_DESCRIPTION("Strip all options in IPv4 packets");
2304 +MODULE_LICENSE("GPL");
2306 +static unsigned int
2307 +target(struct sk_buff **pskb,
2308 + const struct net_device *in,
2309 + const struct net_device *out,
2310 + unsigned int hooknum,
2311 + const void *targinfo,
2314 + struct iphdr *iph;
2315 + struct sk_buff *skb;
2316 + struct ip_options *opt;
2317 + unsigned char *optiph;
2320 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
2324 + iph = (*pskb)->nh.iph;
2325 + optiph = skb->nh.raw;
2326 + l = ((struct ip_options *)(&(IPCB(skb)->opt)))->optlen;
2328 + /* if no options in packet then nothing to clear. */
2329 + if (iph->ihl * 4 == sizeof(struct iphdr))
2330 + return IPT_CONTINUE;
2332 + /* else clear all options */
2333 + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
2334 + memset(optiph+sizeof(struct iphdr), IPOPT_NOOP, l);
2335 + opt = &(IPCB(skb)->opt);
2339 + skb->nfcache |= NFC_ALTERED;
2341 + return IPT_CONTINUE;
2345 +checkentry(const char *tablename,
2346 + const struct ipt_entry *e,
2348 + unsigned int targinfosize,
2349 + unsigned int hook_mask)
2351 + if (strcmp(tablename, "mangle")) {
2352 + printk(KERN_WARNING "IPV4OPTSSTRIP: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
2355 + /* nothing else to check because no parameters */
2359 +static struct ipt_target ipt_ipv4optsstrip_reg = {
2360 + .name = "IPV4OPTSSTRIP",
2362 + .checkentry = checkentry,
2363 + .me = THIS_MODULE };
2365 +static int __init init(void)
2367 + return ipt_register_target(&ipt_ipv4optsstrip_reg);
2370 +static void __exit fini(void)
2372 + ipt_unregister_target(&ipt_ipv4optsstrip_reg);
2377 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_ROUTE.c linux-2.6.7/net/ipv4/netfilter/ipt_ROUTE.c
2378 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_ROUTE.c 1970-01-01 01:00:00.000000000 +0100
2379 +++ linux-2.6.7/net/ipv4/netfilter/ipt_ROUTE.c 2004-06-29 12:34:33.511533232 +0200
2382 + * This implements the ROUTE target, which enables you to setup unusual
2383 + * routes not supported by the standard kernel routing table.
2385 + * Copyright (C) 2002 Cedric de Launois <delaunois@info.ucl.ac.be>
2387 + * v 1.9 2004/05/14
2389 + * This software is distributed under GNU GPL v2, 1991
2392 +#include <linux/module.h>
2393 +#include <linux/skbuff.h>
2394 +#include <linux/ip.h>
2395 +#include <linux/netfilter_ipv4/ip_tables.h>
2396 +#include <linux/netfilter_ipv4/ipt_ROUTE.h>
2397 +#include <linux/netdevice.h>
2398 +#include <linux/route.h>
2399 +#include <net/ip.h>
2400 +#include <net/route.h>
2401 +#include <net/icmp.h>
2402 +#include <net/checksum.h>
2405 +#define DEBUGP printk
2407 +#define DEBUGP(format, args...)
2410 +MODULE_LICENSE("GPL");
2411 +MODULE_AUTHOR("Cedric de Launois <delaunois@info.ucl.ac.be>");
2412 +MODULE_DESCRIPTION("iptables ROUTE target module");
2414 +/* Try to route the packet according to the routing keys specified in
2415 + * route_info. Keys are :
2417 + * 0 if no oif preferred,
2418 + * otherwise set to the index of the desired oif
2419 + * - route_info->gw :
2420 + * 0 if no gateway specified,
2421 + * otherwise set to the next host to which the pkt must be routed
2422 + * If success, skb->dev is the output device to which the packet must
2423 + * be sent and skb->dst is not NULL
2425 + * RETURN: -1 if an error occured
2426 + * 1 if the packet was succesfully routed to the
2427 + * destination desired
2428 + * 0 if the kernel routing table could not route the packet
2429 + * according to the keys specified
2431 +static int route(struct sk_buff *skb,
2432 + unsigned int ifindex,
2433 + const struct ipt_route_target_info *route_info)
2436 + struct rtable *rt;
2437 + struct iphdr *iph = skb->nh.iph;
2438 + struct flowi fl = {
2442 + .daddr = iph->daddr,
2444 + .tos = RT_TOS(iph->tos),
2445 + .scope = RT_SCOPE_UNIVERSE,
2450 + /* The destination address may be overloaded by the target */
2451 + if (route_info->gw)
2452 + fl.fld_dst = route_info->gw;
2454 + /* Trying to route the packet using the standard routing table. */
2455 + if ((err = ip_route_output_key(&rt, &fl))) {
2456 + if (net_ratelimit())
2457 + DEBUGP("ipt_ROUTE: couldn't route pkt (err: %i)",err);
2461 + /* Drop old route. */
2462 + dst_release(skb->dst);
2465 + /* Success if no oif specified or if the oif correspond to the
2467 + if (!ifindex || rt->u.dst.dev->ifindex == ifindex) {
2468 + skb->dst = &rt->u.dst;
2469 + skb->dev = skb->dst->dev;
2473 + /* The interface selected by the routing table is not the one
2474 + * specified by the user. This may happen because the dst address
2475 + * is one of our own addresses.
2477 + if (net_ratelimit())
2478 + DEBUGP("ipt_ROUTE: failed to route as desired gw=%u.%u.%u.%u oif=%i (got oif=%i)\n",
2479 + NIPQUAD(route_info->gw), ifindex, rt->u.dst.dev->ifindex);
2485 +/* Stolen from ip_finish_output2
2486 + * PRE : skb->dev is set to the device we are leaving by
2487 + * skb->dst is not NULL
2488 + * POST: the packet is sent with the link layer header pushed
2489 + * the packet is destroyed
2491 +static void ip_direct_send(struct sk_buff *skb)
2493 + struct dst_entry *dst = skb->dst;
2494 + struct hh_cache *hh = dst->hh;
2497 + read_lock_bh(&hh->hh_lock);
2498 + memcpy(skb->data - 16, hh->hh_data, 16);
2499 + read_unlock_bh(&hh->hh_lock);
2500 + skb_push(skb, hh->hh_len);
2501 + hh->hh_output(skb);
2502 + } else if (dst->neighbour)
2503 + dst->neighbour->output(skb);
2505 + if (net_ratelimit())
2506 + DEBUGP(KERN_DEBUG "ipt_ROUTE: no hdr & no neighbour cache!\n");
2512 +/* PRE : skb->dev is set to the device we are leaving by
2513 + * POST: - the packet is directly sent to the skb->dev device, without
2514 + * pushing the link layer header.
2515 + * - the packet is destroyed
2517 +static inline int dev_direct_send(struct sk_buff *skb)
2519 + return dev_queue_xmit(skb);
2523 +static unsigned int route_oif(const struct ipt_route_target_info *route_info,
2524 + struct sk_buff *skb)
2526 + unsigned int ifindex = 0;
2527 + struct net_device *dev_out = NULL;
2529 + /* The user set the interface name to use.
2530 + * Getting the current interface index.
2532 + if ((dev_out = dev_get_by_name(route_info->oif))) {
2533 + ifindex = dev_out->ifindex;
2535 + /* Unknown interface name : packet dropped */
2536 + if (net_ratelimit())
2537 + DEBUGP("ipt_ROUTE: oif interface %s not found\n", route_info->oif);
2541 + /* Trying the standard way of routing packets */
2542 + switch (route(skb, ifindex, route_info)) {
2545 + if (route_info->flags & IPT_ROUTE_CONTINUE)
2546 + return IPT_CONTINUE;
2548 + ip_direct_send(skb);
2552 + /* Failed to send to oif. Trying the hard way */
2553 + if (route_info->flags & IPT_ROUTE_CONTINUE)
2556 + if (net_ratelimit())
2557 + DEBUGP("ipt_ROUTE: forcing the use of %i\n",
2560 + /* We have to force the use of an interface.
2561 + * This interface must be a tunnel interface since
2562 + * otherwise we can't guess the hw address for
2563 + * the packet. For a tunnel interface, no hw address
2566 + if ((dev_out->type != ARPHRD_TUNNEL)
2567 + && (dev_out->type != ARPHRD_IPGRE)) {
2568 + if (net_ratelimit())
2569 + DEBUGP("ipt_ROUTE: can't guess the hw addr !\n");
2574 + /* Send the packet. This will also free skb
2575 + * Do not go through the POST_ROUTING hook because
2576 + * skb->dst is not set and because it will probably
2577 + * get confused by the destination IP address.
2579 + skb->dev = dev_out;
2580 + dev_direct_send(skb);
2585 + /* Unexpected error */
2592 +static unsigned int route_iif(const struct ipt_route_target_info *route_info,
2593 + struct sk_buff *skb)
2595 + struct net_device *dev_in = NULL;
2597 + /* Getting the current interface index. */
2598 + if (!(dev_in = dev_get_by_name(route_info->iif))) {
2599 + if (net_ratelimit())
2600 + DEBUGP("ipt_ROUTE: iif interface %s not found\n", route_info->iif);
2604 + skb->dev = dev_in;
2605 + dst_release(skb->dst);
2614 +static unsigned int route_gw(const struct ipt_route_target_info *route_info,
2615 + struct sk_buff *skb)
2617 + if (route(skb, 0, route_info)!=1)
2620 + if (route_info->flags & IPT_ROUTE_CONTINUE)
2621 + return IPT_CONTINUE;
2623 + ip_direct_send(skb);
2628 +static unsigned int ipt_route_target(struct sk_buff **pskb,
2629 + const struct net_device *in,
2630 + const struct net_device *out,
2631 + unsigned int hooknum,
2632 + const void *targinfo,
2635 + const struct ipt_route_target_info *route_info = targinfo;
2636 + struct sk_buff *skb = *pskb;
2638 + /* If we are at PREROUTING or INPUT hook
2639 + * the TTL isn't decreased by the IP stack
2641 + if (hooknum == NF_IP_PRE_ROUTING ||
2642 + hooknum == NF_IP_LOCAL_IN) {
2644 + struct iphdr *iph = skb->nh.iph;
2646 + if (iph->ttl <= 1) {
2647 + struct rtable *rt;
2648 + struct flowi fl = {
2652 + .daddr = iph->daddr,
2653 + .saddr = iph->saddr,
2654 + .tos = RT_TOS(iph->tos),
2655 + .scope = ((iph->tos & RTO_ONLINK) ?
2657 + RT_SCOPE_UNIVERSE)
2662 + if (ip_route_output_key(&rt, &fl)) {
2666 + if (skb->dev == rt->u.dst.dev) {
2667 + /* Drop old route. */
2668 + dst_release(skb->dst);
2669 + skb->dst = &rt->u.dst;
2671 + /* this will traverse normal stack, and
2672 + * thus call conntrack on the icmp packet */
2673 + icmp_send(skb, ICMP_TIME_EXCEEDED,
2681 + * If we are at INPUT the checksum must be recalculated since
2682 + * the length could change as the result of a defragmentation.
2684 + if(hooknum == NF_IP_LOCAL_IN) {
2685 + iph->ttl = iph->ttl - 1;
2687 + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
2689 + ip_decrease_ttl(iph);
2693 + /* Tell conntrack to forget this packet since it may get confused
2694 + * when a packet is leaving with dst address == our address.
2695 + * Good idea ? Dunno. Need advice.
2697 + if (!(route_info->flags & IPT_ROUTE_CONTINUE)) {
2698 + nf_conntrack_put(skb->nfct);
2701 +#ifdef CONFIG_NETFILTER_DEBUG
2702 + skb->nf_debug = 0;
2706 + if (route_info->oif[0] != '\0')
2707 + return route_oif(route_info, *pskb);
2709 + if (route_info->iif[0] != '\0')
2710 + return route_iif(route_info, *pskb);
2712 + if (route_info->gw)
2713 + return route_gw(route_info, *pskb);
2715 + if (net_ratelimit())
2716 + DEBUGP(KERN_DEBUG "ipt_ROUTE: no parameter !\n");
2718 + return IPT_CONTINUE;
2722 +static int ipt_route_checkentry(const char *tablename,
2723 + const struct ipt_entry *e,
2725 + unsigned int targinfosize,
2726 + unsigned int hook_mask)
2728 + if (strcmp(tablename, "mangle") != 0) {
2729 + printk("ipt_ROUTE: bad table `%s', use the `mangle' table.\n",
2734 + if (hook_mask & ~( (1 << NF_IP_PRE_ROUTING)
2735 + | (1 << NF_IP_LOCAL_IN)
2736 + | (1 << NF_IP_FORWARD)
2737 + | (1 << NF_IP_LOCAL_OUT)
2738 + | (1 << NF_IP_POST_ROUTING))) {
2739 + printk("ipt_ROUTE: bad hook\n");
2743 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_route_target_info))) {
2744 + printk(KERN_WARNING "ipt_ROUTE: targinfosize %u != %Zu\n",
2746 + IPT_ALIGN(sizeof(struct ipt_route_target_info)));
2754 +static struct ipt_target ipt_route_reg = {
2756 + .target = ipt_route_target,
2757 + .checkentry = ipt_route_checkentry,
2758 + .me = THIS_MODULE,
2761 +static int __init init(void)
2763 + return ipt_register_target(&ipt_route_reg);
2767 +static void __exit fini(void)
2769 + ipt_unregister_target(&ipt_route_reg);
2774 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_TARPIT.c linux-2.6.7/net/ipv4/netfilter/ipt_TARPIT.c
2775 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_TARPIT.c 1970-01-01 01:00:00.000000000 +0100
2776 +++ linux-2.6.7/net/ipv4/netfilter/ipt_TARPIT.c 2004-06-29 12:34:39.109682184 +0200
2779 + * Kernel module to capture and hold incoming TCP connections using
2780 + * no local per-connection resources.
2782 + * Based on ipt_REJECT.c and offering functionality similar to
2783 + * LaBrea <http://www.hackbusters.net/LaBrea/>.
2785 + * Copyright (c) 2002 Aaron Hopkins <tools@die.net>
2787 + * This program is free software; you can redistribute it and/or modify
2788 + * it under the terms of the GNU General Public License as published by
2789 + * the Free Software Foundation; either version 2 of the License, or
2790 + * (at your option) any later version.
2792 + * This program is distributed in the hope that it will be useful,
2793 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2794 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2795 + * GNU General Public License for more details.
2797 + * You should have received a copy of the GNU General Public License
2798 + * along with this program; if not, write to the Free Software
2799 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2802 + * - Allow incoming TCP connections to be established.
2803 + * - Passing data should result in the connection being switched to the
2804 + * persist state (0 byte window), in which the remote side stops sending
2805 + * data and asks to continue every 60 seconds.
2806 + * - Attempts to shut down the connection should be ignored completely, so
2807 + * the remote side ends up having to time it out.
2810 + * - Reply to TCP SYN,!ACK,!RST,!FIN with SYN-ACK, window 5 bytes
2811 + * - Reply to TCP SYN,ACK,!RST,!FIN with RST to prevent spoofing
2812 + * - Reply to TCP !SYN,!RST,!FIN with ACK, window 0 bytes, rate-limited
2815 +#include <linux/config.h>
2816 +#include <linux/module.h>
2817 +#include <linux/skbuff.h>
2818 +#include <linux/ip.h>
2819 +#include <net/ip.h>
2820 +#include <net/tcp.h>
2821 +#include <net/icmp.h>
2823 +#include <net/route.h>
2824 +#include <linux/random.h>
2825 +#include <linux/netfilter_ipv4/ip_tables.h>
2828 +#define DEBUGP printk
2830 +#define DEBUGP(format, args...)
2833 +MODULE_LICENSE("GPL");
2834 +MODULE_AUTHOR("Aaron Hopkins <tools@die.net>");
2836 +/* Stolen from ip_finish_output2 */
2837 +static int ip_direct_send(struct sk_buff *skb)
2839 + struct dst_entry *dst = skb->dst;
2840 + struct hh_cache *hh = dst->hh;
2843 + read_lock_bh(&hh->hh_lock);
2844 + memcpy(skb->data - 16, hh->hh_data, 16);
2845 + read_unlock_bh(&hh->hh_lock);
2846 + skb_push(skb, hh->hh_len);
2847 + return hh->hh_output(skb);
2848 + } else if (dst->neighbour)
2849 + return dst->neighbour->output(skb);
2851 + if (net_ratelimit())
2852 + printk(KERN_DEBUG "TARPIT ip_direct_send: no header cache and no neighbor!\n");
2859 +static void tarpit_tcp(struct sk_buff *oskb,struct rtable *ort,int local)
2861 + struct sk_buff *nskb;
2862 + struct rtable *nrt;
2863 + struct tcphdr *otcph, *ntcph;
2864 + struct flowi fl = {};
2865 + unsigned int otcplen;
2868 + /* A truncated TCP header isn't going to be useful */
2869 + if (oskb->len < (oskb->nh.iph->ihl*4) + sizeof(struct tcphdr))
2872 + otcph = (struct tcphdr *)((u_int32_t*)oskb->nh.iph
2873 + + oskb->nh.iph->ihl);
2874 + otcplen = oskb->len - oskb->nh.iph->ihl*4;
2876 + /* No replies for RST or FIN */
2877 + if (otcph->rst || otcph->fin)
2880 + /* No reply to !SYN,!ACK. Rate-limit replies to !SYN,ACKs */
2881 + if (!otcph->syn && (!otcph->ack || !xrlim_allow(&ort->u.dst, 1*HZ)))
2884 + /* Check checksum. */
2885 + if (tcp_v4_check(otcph, otcplen, oskb->nh.iph->saddr,
2886 + oskb->nh.iph->daddr,
2887 + csum_partial((char *)otcph, otcplen, 0)) != 0)
2890 + /* Copy skb (even if skb is about to be dropped, we can't just
2891 + clone it because there may be other things, such as tcpdump,
2892 + interested in it) */
2893 + nskb = skb_copy(oskb, GFP_ATOMIC);
2897 + /* This packet will not be the same as the other: clear nf fields */
2898 + nf_conntrack_put(nskb->nfct);
2899 + nskb->nfct = NULL;
2900 + nskb->nfcache = 0;
2901 +#ifdef CONFIG_NETFILTER_DEBUG
2902 + nskb->nf_debug = 0;
2905 + ntcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
2907 + /* Truncate to length (no data) */
2908 + ntcph->doff = sizeof(struct tcphdr)/4;
2909 + skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
2910 + nskb->nh.iph->tot_len = htons(nskb->len);
2912 + /* Swap source and dest */
2913 + nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
2914 + tmp = ntcph->source;
2915 + ntcph->source = ntcph->dest;
2916 + ntcph->dest = tmp;
2918 + /* Use supplied sequence number or make a new one */
2919 + ntcph->seq = otcph->ack ? otcph->ack_seq
2920 + : htonl(secure_tcp_sequence_number(nskb->nh.iph->saddr,
2921 + nskb->nh.iph->daddr,
2925 + /* Our SYN-ACKs must have a >0 window */
2926 + ntcph->window = (otcph->syn && !otcph->ack) ? htons(5) : 0;
2928 + ntcph->urg_ptr = 0;
2931 + ((u_int8_t *)ntcph)[13] = 0;
2933 + if (otcph->syn && otcph->ack) {
2935 + ntcph->ack_seq = 0;
2937 + ntcph->syn = otcph->syn;
2939 + ntcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn);
2942 + /* Adjust TCP checksum */
2944 + ntcph->check = tcp_v4_check(ntcph, sizeof(struct tcphdr),
2945 + nskb->nh.iph->saddr,
2946 + nskb->nh.iph->daddr,
2947 + csum_partial((char *)ntcph,
2948 + sizeof(struct tcphdr), 0));
2950 + /* Adjust IP TTL */
2951 + nskb->nh.iph->ttl = sysctl_ip_default_ttl;
2953 + /* Set DF, id = 0 */
2954 + nskb->nh.iph->frag_off = htons(IP_DF);
2955 + nskb->nh.iph->id = 0;
2957 + /* Adjust IP checksum */
2958 + nskb->nh.iph->check = 0;
2959 + nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
2960 + nskb->nh.iph->ihl);
2962 + fl.nl_u.ip4_u.daddr = nskb->nh.iph->daddr;
2963 + fl.nl_u.ip4_u.saddr = local ? nskb->nh.iph->saddr : 0;
2964 + fl.nl_u.ip4_u.tos = RT_TOS(nskb->nh.iph->tos) | RTO_CONN;
2967 + if (ip_route_output_key(&nrt, &fl))
2970 + dst_release(nskb->dst);
2971 + nskb->dst = &nrt->u.dst;
2973 + /* "Never happens" */
2974 + if (nskb->len > dst_pmtu(nskb->dst))
2977 + ip_direct_send (nskb);
2986 +static unsigned int tarpit(struct sk_buff **pskb,
2987 + const struct net_device *in,
2988 + const struct net_device *out,
2989 + unsigned int hooknum,
2990 + const void *targinfo,
2993 + struct sk_buff *skb = *pskb;
2994 + struct rtable *rt = (struct rtable*)skb->dst;
2996 + /* Do we have an input route cache entry? */
3000 + /* No replies to physical multicast/broadcast */
3001 + if (skb->pkt_type != PACKET_HOST && skb->pkt_type != PACKET_OTHERHOST)
3004 + /* Now check at the protocol level */
3005 + if (rt->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST))
3008 + /* Our naive response construction doesn't deal with IP
3009 + options, and probably shouldn't try. */
3010 + if (skb->nh.iph->ihl*4 != sizeof(struct iphdr))
3013 + /* We aren't interested in fragments */
3014 + if (skb->nh.iph->frag_off & htons(IP_OFFSET))
3017 + tarpit_tcp(skb,rt,hooknum == NF_IP_LOCAL_IN);
3023 +static int check(const char *tablename,
3024 + const struct ipt_entry *e,
3026 + unsigned int targinfosize,
3027 + unsigned int hook_mask)
3029 + /* Only allow these for input/forward packet filtering. */
3030 + if (strcmp(tablename, "filter") != 0) {
3031 + DEBUGP("TARPIT: bad table %s'.\n", tablename);
3034 + if ((hook_mask & ~((1 << NF_IP_LOCAL_IN)
3035 + | (1 << NF_IP_FORWARD))) != 0) {
3036 + DEBUGP("TARPIT: bad hook mask %X\n", hook_mask);
3040 + /* Must specify that it's a TCP packet */
3041 + if (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & IPT_INV_PROTO)) {
3042 + DEBUGP("TARPIT: not valid for non-tcp\n");
3049 +static struct ipt_target ipt_tarpit_reg = {
3052 + .checkentry = check,
3056 +static int __init init(void)
3058 + return ipt_register_target(&ipt_tarpit_reg);
3061 +static void __exit fini(void)
3063 + ipt_unregister_target(&ipt_tarpit_reg);
3068 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_TTL.c linux-2.6.7/net/ipv4/netfilter/ipt_TTL.c
3069 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_TTL.c 1970-01-01 01:00:00.000000000 +0100
3070 +++ linux-2.6.7/net/ipv4/netfilter/ipt_TTL.c 2004-06-29 12:32:03.618320464 +0200
3072 +/* TTL modification target for IP tables
3073 + * (C) 2000 by Harald Welte <laforge@gnumonks.org>
3075 + * Version: $Revision$
3077 + * This software is distributed under the terms of GNU GPL
3080 +#include <linux/module.h>
3081 +#include <linux/skbuff.h>
3082 +#include <linux/ip.h>
3083 +#include <net/checksum.h>
3085 +#include <linux/netfilter_ipv4/ip_tables.h>
3086 +#include <linux/netfilter_ipv4/ipt_TTL.h>
3088 +MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
3089 +MODULE_DESCRIPTION("IP tables TTL modification module");
3090 +MODULE_LICENSE("GPL");
3092 +static unsigned int
3093 +ipt_ttl_target(struct sk_buff **pskb, const struct net_device *in,
3094 + const struct net_device *out, unsigned int hooknum,
3095 + const void *targinfo, void *userinfo)
3097 + struct iphdr *iph;
3098 + const struct ipt_TTL_info *info = targinfo;
3099 + u_int16_t diffs[2];
3102 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
3105 + iph = (*pskb)->nh.iph;
3107 + switch (info->mode) {
3109 + new_ttl = info->ttl;
3112 + new_ttl = iph->ttl + info->ttl;
3113 + if (new_ttl > 255)
3117 + new_ttl = iph->ttl + info->ttl;
3122 + new_ttl = iph->ttl;
3126 + if (new_ttl != iph->ttl) {
3127 + diffs[0] = htons(((unsigned)iph->ttl) << 8) ^ 0xFFFF;
3128 + iph->ttl = new_ttl;
3129 + diffs[1] = htons(((unsigned)iph->ttl) << 8);
3130 + iph->check = csum_fold(csum_partial((char *)diffs,
3132 + iph->check^0xFFFF));
3133 + (*pskb)->nfcache |= NFC_ALTERED;
3136 + return IPT_CONTINUE;
3139 +static int ipt_ttl_checkentry(const char *tablename,
3140 + const struct ipt_entry *e,
3142 + unsigned int targinfosize,
3143 + unsigned int hook_mask)
3145 + struct ipt_TTL_info *info = targinfo;
3147 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_TTL_info))) {
3148 + printk(KERN_WARNING "TTL: targinfosize %u != %Zu\n",
3150 + IPT_ALIGN(sizeof(struct ipt_TTL_info)));
3154 + if (strcmp(tablename, "mangle")) {
3155 + printk(KERN_WARNING "TTL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
3159 + if (info->mode > IPT_TTL_MAXMODE) {
3160 + printk(KERN_WARNING "TTL: invalid or unknown Mode %u\n",
3165 + if ((info->mode != IPT_TTL_SET) && (info->ttl == 0)) {
3166 + printk(KERN_WARNING "TTL: increment/decrement doesn't make sense with value 0\n");
3173 +static struct ipt_target ipt_TTL = {
3175 + .target = ipt_ttl_target,
3176 + .checkentry = ipt_ttl_checkentry,
3180 +static int __init init(void)
3182 + return ipt_register_target(&ipt_TTL);
3185 +static void __exit fini(void)
3187 + ipt_unregister_target(&ipt_TTL);
3192 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_XOR.c linux-2.6.7/net/ipv4/netfilter/ipt_XOR.c
3193 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_XOR.c 1970-01-01 01:00:00.000000000 +0100
3194 +++ linux-2.6.7/net/ipv4/netfilter/ipt_XOR.c 2004-06-29 12:34:46.050627000 +0200
3196 +/* XOR target for IP tables
3197 + * (C) 2000 by Tim Vandermeersch <Tim.Vandermeersch@pandora.be>
3198 + * Based on ipt_TTL.c
3202 + * This software is distributed under the terms of GNU GPL
3205 +#include <linux/module.h>
3206 +#include <linux/skbuff.h>
3207 +#include <linux/ip.h>
3208 +#include <linux/tcp.h>
3209 +#include <linux/udp.h>
3211 +#include <linux/netfilter_ipv4/ip_tables.h>
3212 +#include <linux/netfilter_ipv4/ipt_XOR.h>
3214 +MODULE_AUTHOR("Tim Vandermeersch <Tim.Vandermeersch@pandora.be>");
3215 +MODULE_DESCRIPTION("IP tables XOR module");
3216 +MODULE_LICENSE("GPL");
3218 +static unsigned int
3219 +ipt_xor_target(struct sk_buff **pskb,
3220 + const struct net_device *in, const struct net_device *out,
3221 + unsigned int hooknum, const void *targinfo, void *userinfo)
3223 + struct ipt_XOR_info *info = (void *) targinfo;
3224 + struct iphdr *iph;
3225 + struct tcphdr *tcph;
3226 + struct udphdr *udph;
3229 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
3232 + iph = (*pskb)->nh.iph;
3234 + if (iph->protocol == IPPROTO_TCP) {
3235 + tcph = (struct tcphdr *) ((*pskb)->data + iph->ihl*4);
3236 + for (i=0, j=0; i<(ntohs(iph->tot_len) - iph->ihl*4 - tcph->doff*4); ) {
3237 + for (k=0; k<=info->block_size; k++) {
3238 + (char) (*pskb)->data[ iph->ihl*4 + tcph->doff*4 + i ] ^=
3243 + if (info->key[j] == 0x00)
3246 + } else if (iph->protocol == IPPROTO_UDP) {
3247 + udph = (struct udphdr *) ((*pskb)->data + iph->ihl*4);
3248 + for (i=0, j=0; i<(ntohs(udph->len)-8); ) {
3249 + for (k=0; k<=info->block_size; k++) {
3250 + (char) (*pskb)->data[ iph->ihl*4 + sizeof(struct udphdr) + i ] ^=
3255 + if (info->key[j] == 0x00)
3260 + return IPT_CONTINUE;
3263 +static int ipt_xor_checkentry(const char *tablename, const struct ipt_entry *e,
3264 + void *targinfo, unsigned int targinfosize,
3265 + unsigned int hook_mask)
3267 + struct ipt_XOR_info *info = targinfo;
3269 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_XOR_info))) {
3270 + printk(KERN_WARNING "XOR: targinfosize %u != %Zu\n",
3271 + targinfosize, IPT_ALIGN(sizeof(struct ipt_XOR_info)));
3275 + if (strcmp(tablename, "mangle")) {
3276 + printk(KERN_WARNING "XOR: can only be called from"
3277 + "\"mangle\" table, not \"%s\"\n", tablename);
3281 + if (!strcmp(info->key, "")) {
3282 + printk(KERN_WARNING "XOR: You must specify a key");
3286 + if (info->block_size == 0) {
3287 + printk(KERN_WARNING "XOR: You must specify a block-size");
3294 +static struct ipt_target ipt_XOR = {
3296 + .target = ipt_xor_target,
3297 + .checkentry = ipt_xor_checkentry,
3298 + .me = THIS_MODULE,
3301 +static int __init init(void)
3303 + return ipt_register_target(&ipt_XOR);
3306 +static void __exit fini(void)
3308 + ipt_unregister_target(&ipt_XOR);
3313 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_connlimit.c linux-2.6.7/net/ipv4/netfilter/ipt_connlimit.c
3314 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_connlimit.c 1970-01-01 01:00:00.000000000 +0100
3315 +++ linux-2.6.7/net/ipv4/netfilter/ipt_connlimit.c 2004-06-29 12:32:05.988960072 +0200
3318 + * netfilter module to limit the number of parallel tcp
3319 + * connections per IP address.
3320 + * (c) 2000 Gerd Knorr <kraxel@bytesex.org>
3321 + * Nov 2002: Martin Bene <martin.bene@icomedias.com>:
3322 + * only ignore TIME_WAIT or gone connections
3326 + * Kernel module to match connection tracking information.
3327 + * GPL (C) 1999 Rusty Russell (rusty@rustcorp.com.au).
3329 +#include <linux/module.h>
3330 +#include <linux/skbuff.h>
3331 +#include <linux/list.h>
3332 +#include <linux/netfilter_ipv4/ip_conntrack.h>
3333 +#include <linux/netfilter_ipv4/ip_conntrack_core.h>
3334 +#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
3335 +#include <linux/netfilter_ipv4/ip_tables.h>
3336 +#include <linux/netfilter_ipv4/ipt_connlimit.h>
3340 +MODULE_LICENSE("GPL");
3342 +/* we'll save the tuples of all connections we care about */
3343 +struct ipt_connlimit_conn
3345 + struct list_head list;
3346 + struct ip_conntrack_tuple tuple;
3349 +struct ipt_connlimit_data {
3351 + struct list_head iphash[256];
3354 +static int ipt_iphash(u_int32_t addr)
3358 + hash = addr & 0xff;
3359 + hash ^= (addr >> 8) & 0xff;
3360 + hash ^= (addr >> 16) & 0xff;
3361 + hash ^= (addr >> 24) & 0xff;
3365 +static int count_them(struct ipt_connlimit_data *data,
3366 + u_int32_t addr, u_int32_t mask,
3367 + struct ip_conntrack *ct)
3370 + const static char *tcp[] = { "none", "established", "syn_sent", "syn_recv",
3371 + "fin_wait", "time_wait", "close", "close_wait",
3372 + "last_ack", "listen" };
3374 + int addit = 1, matches = 0;
3375 + struct ip_conntrack_tuple tuple;
3376 + struct ip_conntrack_tuple_hash *found;
3377 + struct ipt_connlimit_conn *conn;
3378 + struct list_head *hash,*lh;
3380 + spin_lock(&data->lock);
3381 + tuple = ct->tuplehash[0].tuple;
3382 + hash = &data->iphash[ipt_iphash(addr & mask)];
3384 + /* check the saved connections */
3385 + for (lh = hash->next; lh != hash; lh = lh->next) {
3386 + conn = list_entry(lh,struct ipt_connlimit_conn,list);
3387 + found = ip_conntrack_find_get(&conn->tuple,ct);
3388 + if (0 == memcmp(&conn->tuple,&tuple,sizeof(tuple)) &&
3390 + found->ctrack->proto.tcp.state != TCP_CONNTRACK_TIME_WAIT) {
3391 + /* Just to be sure we have it only once in the list.
3392 + We should'nt see tuples twice unless someone hooks this
3393 + into a table without "-p tcp --syn" */
3397 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d %s\n",
3398 + ipt_iphash(addr & mask),
3399 + NIPQUAD(conn->tuple.src.ip), ntohs(conn->tuple.src.u.tcp.port),
3400 + NIPQUAD(conn->tuple.dst.ip), ntohs(conn->tuple.dst.u.tcp.port),
3401 + (NULL != found) ? tcp[found->ctrack->proto.tcp.state] : "gone");
3403 + if (NULL == found) {
3404 + /* this one is gone */
3406 + list_del(lh->next);
3410 + if (found->ctrack->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT) {
3411 + /* we don't care about connections which are
3412 + closed already -> ditch it */
3414 + list_del(lh->next);
3416 + nf_conntrack_put(&found->ctrack->infos[0]);
3419 + if ((addr & mask) == (conn->tuple.src.ip & mask)) {
3420 + /* same source IP address -> be counted! */
3423 + nf_conntrack_put(&found->ctrack->infos[0]);
3426 + /* save the new connection in our list */
3428 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d new\n",
3429 + ipt_iphash(addr & mask),
3430 + NIPQUAD(tuple.src.ip), ntohs(tuple.src.u.tcp.port),
3431 + NIPQUAD(tuple.dst.ip), ntohs(tuple.dst.u.tcp.port));
3433 + conn = kmalloc(sizeof(*conn),GFP_ATOMIC);
3436 + memset(conn,0,sizeof(*conn));
3437 + INIT_LIST_HEAD(&conn->list);
3438 + conn->tuple = tuple;
3439 + list_add(&conn->list,hash);
3442 + spin_unlock(&data->lock);
3447 +match(const struct sk_buff *skb,
3448 + const struct net_device *in,
3449 + const struct net_device *out,
3450 + const void *matchinfo,
3454 + const struct ipt_connlimit_info *info = matchinfo;
3455 + int connections, match;
3456 + struct ip_conntrack *ct;
3457 + enum ip_conntrack_info ctinfo;
3459 + ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
3461 + printk("ipt_connlimit: Oops: invalid ct state ?\n");
3465 + connections = count_them(info->data,skb->nh.iph->saddr,info->mask,ct);
3466 + if (-1 == connections) {
3467 + printk("ipt_connlimit: Hmm, kmalloc failed :-(\n");
3468 + *hotdrop = 1; /* let's free some memory :-) */
3471 + match = (info->inverse) ? (connections <= info->limit) : (connections > info->limit);
3473 + printk("ipt_connlimit: src=%u.%u.%u.%u mask=%u.%u.%u.%u "
3474 + "connections=%d limit=%d match=%s\n",
3475 + NIPQUAD(skb->nh.iph->saddr), NIPQUAD(info->mask),
3476 + connections, info->limit, match ? "yes" : "no");
3482 +static int check(const char *tablename,
3483 + const struct ipt_ip *ip,
3485 + unsigned int matchsize,
3486 + unsigned int hook_mask)
3488 + struct ipt_connlimit_info *info = matchinfo;
3492 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connlimit_info)))
3495 + /* refuse anything but tcp */
3496 + if (ip->proto != IPPROTO_TCP)
3499 + /* init private data */
3500 + info->data = kmalloc(sizeof(struct ipt_connlimit_data),GFP_KERNEL);
3501 + spin_lock_init(&(info->data->lock));
3502 + for (i = 0; i < 256; i++)
3503 + INIT_LIST_HEAD(&(info->data->iphash[i]));
3508 +static void destroy(void *matchinfo, unsigned int matchinfosize)
3510 + struct ipt_connlimit_info *info = matchinfo;
3511 + struct ipt_connlimit_conn *conn;
3512 + struct list_head *hash;
3516 + for (i = 0; i < 256; i++) {
3517 + hash = &(info->data->iphash[i]);
3518 + while (hash != hash->next) {
3519 + conn = list_entry(hash->next,struct ipt_connlimit_conn,list);
3520 + list_del(hash->next);
3524 + kfree(info->data);
3527 +static struct ipt_match connlimit_match = {
3528 + .name = "connlimit",
3530 + .checkentry = &check,
3531 + .destroy = &destroy,
3535 +static int __init init(void)
3537 + return ipt_register_match(&connlimit_match);
3540 +static void __exit fini(void)
3542 + ipt_unregister_match(&connlimit_match);
3547 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_connmark.c linux-2.6.7/net/ipv4/netfilter/ipt_connmark.c
3548 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_connmark.c 1970-01-01 01:00:00.000000000 +0100
3549 +++ linux-2.6.7/net/ipv4/netfilter/ipt_connmark.c 2004-06-29 12:34:21.514357080 +0200
3551 +/* This kernel module matches connection mark values set by the
3554 + * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
3555 + * by Henrik Nordstrom <hno@marasystems.com>
3557 + * This program is free software; you can redistribute it and/or modify
3558 + * it under the terms of the GNU General Public License as published by
3559 + * the Free Software Foundation; either version 2 of the License, or
3560 + * (at your option) any later version.
3562 + * This program is distributed in the hope that it will be useful,
3563 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3564 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3565 + * GNU General Public License for more details.
3567 + * You should have received a copy of the GNU General Public License
3568 + * along with this program; if not, write to the Free Software
3569 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3572 +#include <linux/module.h>
3573 +#include <linux/skbuff.h>
3575 +MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
3576 +MODULE_DESCRIPTION("IP tables connmark match module");
3577 +MODULE_LICENSE("GPL");
3579 +#include <linux/netfilter_ipv4/ip_tables.h>
3580 +#include <linux/netfilter_ipv4/ipt_connmark.h>
3581 +#include <linux/netfilter_ipv4/ip_conntrack.h>
3584 +match(const struct sk_buff *skb,
3585 + const struct net_device *in,
3586 + const struct net_device *out,
3587 + const void *matchinfo,
3591 + const struct ipt_connmark_info *info = matchinfo;
3592 + enum ip_conntrack_info ctinfo;
3593 + struct ip_conntrack *ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
3597 + return ((ct->mark & info->mask) == info->mark) ^ info->invert;
3601 +checkentry(const char *tablename,
3602 + const struct ipt_ip *ip,
3604 + unsigned int matchsize,
3605 + unsigned int hook_mask)
3607 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info)))
3613 +static struct ipt_match connmark_match = {
3614 + .name = "connmark",
3616 + .checkentry = &checkentry,
3620 +static int __init init(void)
3622 + return ipt_register_match(&connmark_match);
3625 +static void __exit fini(void)
3627 + ipt_unregister_match(&connmark_match);
3632 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_dstlimit.c linux-2.6.7/net/ipv4/netfilter/ipt_dstlimit.c
3633 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_dstlimit.c 1970-01-01 01:00:00.000000000 +0100
3634 +++ linux-2.6.7/net/ipv4/netfilter/ipt_dstlimit.c 2004-06-29 12:32:07.243769312 +0200
3636 +/* iptables match extension to limit the number of packets per second
3637 + * seperately for each destination.
3639 + * (C) 2003 by Harald Welte <laforge@netfilter.org>
3643 + * Development of this code was funded by Astaro AG, http://www.astaro.com/
3645 + * based on ipt_limit.c by:
3646 + * Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
3647 + * Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
3648 + * Rusty Russell <rusty@rustcorp.com.au>
3650 + * The general idea is to create a hash table for every dstip and have a
3651 + * seperate limit counter per tuple. This way you can do something like 'limit
3652 + * the number of syn packets for each of my internal addresses.
3654 + * Ideally this would just be implemented as a general 'hash' match, which would
3655 + * allow us to attach any iptables target to it's hash buckets. But this is
3656 + * not possible in the current iptables architecture. As always, pkttables for
3657 + * 2.7.x will help ;)
3659 +#include <linux/module.h>
3660 +#include <linux/skbuff.h>
3661 +#include <linux/spinlock.h>
3662 +#include <linux/random.h>
3663 +#include <linux/jhash.h>
3664 +#include <linux/slab.h>
3665 +#include <linux/vmalloc.h>
3666 +#include <linux/tcp.h>
3667 +#include <linux/udp.h>
3668 +#include <linux/proc_fs.h>
3669 +#include <linux/seq_file.h>
3671 +#define ASSERT_READ_LOCK(x)
3672 +#define ASSERT_WRITE_LOCK(x)
3673 +#include <linux/netfilter_ipv4/lockhelp.h>
3674 +#include <linux/netfilter_ipv4/listhelp.h>
3676 +#include <linux/netfilter_ipv4/ip_tables.h>
3677 +#include <linux/netfilter_ipv4/ipt_dstlimit.h>
3679 +/* FIXME: this is just for IP_NF_ASSERRT */
3680 +#include <linux/netfilter_ipv4/ip_conntrack.h>
3682 +#define MS2JIFFIES(x) ((x*HZ)/1000)
3684 +MODULE_LICENSE("GPL");
3685 +MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
3686 +MODULE_DESCRIPTION("iptables match for limiting per destination");
3688 +/* need to declare this at the top */
3689 +static struct proc_dir_entry *dstlimit_procdir;
3690 +static struct file_operations dl_file_ops;
3692 +/* hash table crap */
3694 +struct dsthash_dst {
3700 +struct dsthash_ent {
3701 + /* static / read-only parts in the beginning */
3702 + struct list_head list;
3703 + struct dsthash_dst dst;
3705 + /* modified structure members in the end */
3706 + unsigned long expires; /* precalculated expiry time */
3708 + unsigned long prev; /* last modification */
3710 + u_int32_t credit_cap, cost;
3714 +struct ipt_dstlimit_htable {
3715 + struct list_head list; /* global list of all htables */
3718 + struct dstlimit_cfg cfg; /* config */
3720 + /* used internally */
3721 + spinlock_t lock; /* lock for list_head */
3722 + u_int32_t rnd; /* random seed for hash */
3723 + struct timer_list timer; /* timer for gc */
3724 + atomic_t count; /* number entries in table */
3726 + /* seq_file stuff */
3727 + struct proc_dir_entry *pde;
3729 + struct list_head hash[0]; /* hashtable itself */
3732 +DECLARE_RWLOCK(dstlimit_lock); /* protects htables list */
3733 +static LIST_HEAD(dstlimit_htables);
3734 +static kmem_cache_t *dstlimit_cachep;
3736 +static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b)
3738 + return (ent->dst.dst_ip == b->dst_ip
3739 + && ent->dst.port == b->port
3740 + && ent->dst.src_ip == b->src_ip);
3743 +static inline u_int32_t
3744 +hash_dst(const struct ipt_dstlimit_htable *ht, const struct dsthash_dst *dst)
3746 + return (jhash_3words(dst->dst_ip, dst->port,
3747 + dst->src_ip, ht->rnd) % ht->cfg.size);
3750 +static inline struct dsthash_ent *
3751 +__dsthash_find(const struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
3753 + struct dsthash_ent *ent;
3754 + u_int32_t hash = hash_dst(ht, dst);
3755 + MUST_BE_LOCKED(&ht->lock);
3756 + ent = LIST_FIND(&ht->hash[hash], dst_cmp, struct dsthash_ent *, dst);
3760 +/* allocate dsthash_ent, initialize dst, put in htable and lock it */
3761 +static struct dsthash_ent *
3762 +__dsthash_alloc_init(struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
3764 + struct dsthash_ent *ent;
3766 + /* initialize hash with random val at the time we allocate
3767 + * the first hashtable entry */
3769 + get_random_bytes(&ht->rnd, 4);
3771 + if (ht->cfg.max &&
3772 + atomic_read(&ht->count) >= ht->cfg.max) {
3773 + /* FIXME: do something. question is what.. */
3774 + if (net_ratelimit())
3775 + printk(KERN_WARNING
3776 + "ipt_dstlimit: max count of %u reached\n",
3781 + ent = kmem_cache_alloc(dstlimit_cachep, GFP_ATOMIC);
3783 + if (net_ratelimit())
3785 + "ipt_dstlimit: can't allocate dsthash_ent\n");
3789 + atomic_inc(&ht->count);
3791 + ent->dst.dst_ip = dst->dst_ip;
3792 + ent->dst.port = dst->port;
3793 + ent->dst.src_ip = dst->src_ip;
3795 + list_add(&ent->list, &ht->hash[hash_dst(ht, dst)]);
3801 +__dsthash_free(struct ipt_dstlimit_htable *ht, struct dsthash_ent *ent)
3803 + MUST_BE_LOCKED(&ht->lock);
3805 + list_del(&ent->list);
3806 + kmem_cache_free(dstlimit_cachep, ent);
3807 + atomic_dec(&ht->count);
3809 +static void htable_gc(unsigned long htlong);
3811 +static int htable_create(struct ipt_dstlimit_info *minfo)
3814 + unsigned int size;
3815 + struct ipt_dstlimit_htable *hinfo;
3817 + if (minfo->cfg.size)
3818 + size = minfo->cfg.size;
3820 + size = (((num_physpages << PAGE_SHIFT) / 16384)
3821 + / sizeof(struct list_head));
3822 + if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
3827 + /* FIXME: don't use vmalloc() here or anywhere else -HW */
3828 + hinfo = vmalloc(sizeof(struct ipt_dstlimit_htable)
3829 + + (sizeof(struct list_head) * size));
3831 + printk(KERN_ERR "ipt_dstlimit: Unable to create hashtable\n");
3834 + minfo->hinfo = hinfo;
3836 + /* copy match config into hashtable config */
3837 + memcpy(&hinfo->cfg, &minfo->cfg, sizeof(hinfo->cfg));
3838 + hinfo->cfg.size = size;
3839 + if (!hinfo->cfg.max)
3840 + hinfo->cfg.max = 8 * hinfo->cfg.size;
3841 + else if (hinfo->cfg.max < hinfo->cfg.size)
3842 + hinfo->cfg.max = hinfo->cfg.size;
3844 + for (i = 0; i < hinfo->cfg.size; i++)
3845 + INIT_LIST_HEAD(&hinfo->hash[i]);
3847 + atomic_set(&hinfo->count, 0);
3848 + atomic_set(&hinfo->use, 1);
3850 + hinfo->lock = SPIN_LOCK_UNLOCKED;
3851 + hinfo->pde = create_proc_entry(minfo->name, 0, dstlimit_procdir);
3852 + if (!hinfo->pde) {
3856 + hinfo->pde->proc_fops = &dl_file_ops;
3857 + hinfo->pde->data = hinfo;
3859 + init_timer(&hinfo->timer);
3860 + hinfo->timer.expires = jiffies + MS2JIFFIES(hinfo->cfg.gc_interval);
3861 + hinfo->timer.data = (unsigned long )hinfo;
3862 + hinfo->timer.function = htable_gc;
3863 + add_timer(&hinfo->timer);
3865 + WRITE_LOCK(&dstlimit_lock);
3866 + list_add(&hinfo->list, &dstlimit_htables);
3867 + WRITE_UNLOCK(&dstlimit_lock);
3872 +static int select_all(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
3877 +static int select_gc(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
3879 + return (jiffies >= he->expires);
3882 +static void htable_selective_cleanup(struct ipt_dstlimit_htable *ht,
3883 + int (*select)(struct ipt_dstlimit_htable *ht,
3884 + struct dsthash_ent *he))
3888 + IP_NF_ASSERT(ht->cfg.size && ht->cfg.max);
3890 + /* lock hash table and iterate over it */
3891 + LOCK_BH(&ht->lock);
3892 + for (i = 0; i < ht->cfg.size; i++) {
3893 + struct dsthash_ent *dh, *n;
3894 + list_for_each_entry_safe(dh, n, &ht->hash[i], list) {
3895 + if ((*select)(ht, dh))
3896 + __dsthash_free(ht, dh);
3899 + UNLOCK_BH(&ht->lock);
3902 +/* hash table garbage collector, run by timer */
3903 +static void htable_gc(unsigned long htlong)
3905 + struct ipt_dstlimit_htable *ht = (struct ipt_dstlimit_htable *)htlong;
3907 + htable_selective_cleanup(ht, select_gc);
3909 + /* re-add the timer accordingly */
3910 + ht->timer.expires = jiffies + MS2JIFFIES(ht->cfg.gc_interval);
3911 + add_timer(&ht->timer);
3914 +static void htable_destroy(struct ipt_dstlimit_htable *hinfo)
3916 + /* remove timer, if it is pending */
3917 + if (timer_pending(&hinfo->timer))
3918 + del_timer(&hinfo->timer);
3920 + /* remove proc entry */
3921 + remove_proc_entry(hinfo->pde->name, dstlimit_procdir);
3923 + htable_selective_cleanup(hinfo, select_all);
3927 +static struct ipt_dstlimit_htable *htable_find_get(char *name)
3929 + struct ipt_dstlimit_htable *hinfo;
3931 + READ_LOCK(&dstlimit_lock);
3932 + list_for_each_entry(hinfo, &dstlimit_htables, list) {
3933 + if (!strcmp(name, hinfo->pde->name)) {
3934 + atomic_inc(&hinfo->use);
3935 + READ_UNLOCK(&dstlimit_lock);
3939 + READ_UNLOCK(&dstlimit_lock);
3944 +static void htable_put(struct ipt_dstlimit_htable *hinfo)
3946 + if (atomic_dec_and_test(&hinfo->use)) {
3947 + WRITE_LOCK(&dstlimit_lock);
3948 + list_del(&hinfo->list);
3949 + WRITE_UNLOCK(&dstlimit_lock);
3950 + htable_destroy(hinfo);
3955 +/* The algorithm used is the Simple Token Bucket Filter (TBF)
3956 + * see net/sched/sch_tbf.c in the linux source tree
3959 +/* Rusty: This is my (non-mathematically-inclined) understanding of
3960 + this algorithm. The `average rate' in jiffies becomes your initial
3961 + amount of credit `credit' and the most credit you can ever have
3962 + `credit_cap'. The `peak rate' becomes the cost of passing the
3965 + `prev' tracks the last packet hit: you gain one credit per jiffy.
3966 + If you get credit balance more than this, the extra credit is
3967 + discarded. Every time the match passes, you lose `cost' credits;
3968 + if you don't have that many, the test fails.
3970 + See Alexey's formal explanation in net/sched/sch_tbf.c.
3972 + To get the maximum range, we multiply by this factor (ie. you get N
3973 + credits per jiffy). We want to allow a rate as low as 1 per day
3974 + (slowest userspace tool allows), which means
3975 + CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32 ie.
3977 +#define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24))
3979 +/* Repeated shift and or gives us all 1s, final shift and add 1 gives
3980 + * us the power of 2 below the theoretical max, so GCC simply does a
3982 +#define _POW2_BELOW2(x) ((x)|((x)>>1))
3983 +#define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2))
3984 +#define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4))
3985 +#define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8))
3986 +#define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16))
3987 +#define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1)
3989 +#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
3991 +/* Precision saver. */
3992 +static inline u_int32_t
3993 +user2credits(u_int32_t user)
3995 + /* If multiplying would overflow... */
3996 + if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY))
3997 + /* Divide first. */
3998 + return (user / IPT_DSTLIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;
4000 + return (user * HZ * CREDITS_PER_JIFFY) / IPT_DSTLIMIT_SCALE;
4003 +static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
4005 + dh->rateinfo.credit += (now - xchg(&dh->rateinfo.prev, now))
4006 + * CREDITS_PER_JIFFY;
4007 + if (dh->rateinfo.credit > dh->rateinfo.credit_cap)
4008 + dh->rateinfo.credit = dh->rateinfo.credit_cap;
4012 +dstlimit_match(const struct sk_buff *skb,
4013 + const struct net_device *in,
4014 + const struct net_device *out,
4015 + const void *matchinfo,
4019 + struct ipt_dstlimit_info *r =
4020 + ((struct ipt_dstlimit_info *)matchinfo)->u.master;
4021 + struct ipt_dstlimit_htable *hinfo = r->hinfo;
4022 + unsigned long now = jiffies;
4023 + struct dsthash_ent *dh;
4024 + struct dsthash_dst dst;
4026 + memset(&dst, 0, sizeof(dst));
4028 + /* dest ip is always in hash */
4029 + dst.dst_ip = skb->nh.iph->daddr;
4031 + /* source ip only if respective hashmode, otherwise set to
4033 + if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_SIP)
4034 + dst.src_ip = skb->nh.iph->saddr;
4036 + /* dest port only if respective mode */
4037 + if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_DPT) {
4040 + /* Must not be a fragment. */
4044 + /* Must be big enough to read ports (both UDP and TCP have
4045 + them at the start). */
4046 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
4047 + /* We've been asked to examine this packet, and we
4048 + can't. Hence, no choice but to drop. */
4053 + switch (skb->nh.iph->protocol) {
4054 + struct tcphdr *th;
4055 + struct udphdr *uh;
4057 + th = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
4058 + dst.port = th->dest;
4061 + uh = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
4062 + dst.port = uh->dest;
4069 + LOCK_BH(&hinfo->lock);
4070 + dh = __dsthash_find(hinfo, &dst);
4072 + dh = __dsthash_alloc_init(hinfo, &dst);
4075 + /* enomem... don't match == DROP */
4076 + if (net_ratelimit())
4077 + printk(KERN_ERR "%s: ENOMEM\n", __FUNCTION__);
4078 + UNLOCK_BH(&hinfo->lock);
4082 + dh->expires = jiffies + MS2JIFFIES(hinfo->cfg.expire);
4084 + dh->rateinfo.prev = jiffies;
4085 + dh->rateinfo.credit = user2credits(hinfo->cfg.avg *
4086 + hinfo->cfg.burst);
4087 + dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg *
4088 + hinfo->cfg.burst);
4089 + dh->rateinfo.cost = user2credits(hinfo->cfg.avg);
4091 + UNLOCK_BH(&hinfo->lock);
4095 + /* update expiration timeout */
4096 + dh->expires = now + MS2JIFFIES(hinfo->cfg.expire);
4098 + rateinfo_recalc(dh, now);
4099 + if (dh->rateinfo.credit >= dh->rateinfo.cost) {
4100 + /* We're underlimit. */
4101 + dh->rateinfo.credit -= dh->rateinfo.cost;
4102 + UNLOCK_BH(&hinfo->lock);
4106 + UNLOCK_BH(&hinfo->lock);
4108 + /* default case: we're overlimit, thus don't match */
4113 +dstlimit_checkentry(const char *tablename,
4114 + const struct ipt_ip *ip,
4116 + unsigned int matchsize,
4117 + unsigned int hook_mask)
4119 + struct ipt_dstlimit_info *r = matchinfo;
4121 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_dstlimit_info)))
4124 + /* Check for overflow. */
4125 + if (r->cfg.burst == 0
4126 + || user2credits(r->cfg.avg * r->cfg.burst) <
4127 + user2credits(r->cfg.avg)) {
4128 + printk(KERN_ERR "ipt_dstlimit: Overflow, try lower: %u/%u\n",
4129 + r->cfg.avg, r->cfg.burst);
4133 + if (r->cfg.mode == 0
4134 + || r->cfg.mode > (IPT_DSTLIMIT_HASH_DPT
4135 + |IPT_DSTLIMIT_HASH_DIP
4136 + |IPT_DSTLIMIT_HASH_SIP))
4139 + if (!r->cfg.gc_interval)
4142 + if (!r->cfg.expire)
4145 + r->hinfo = htable_find_get(r->name);
4146 + if (!r->hinfo && (htable_create(r) != 0)) {
4150 + /* Ugly hack: For SMP, we only want to use one set */
4157 +dstlimit_destroy(void *matchinfo, unsigned int matchsize)
4159 + struct ipt_dstlimit_info *r = (struct ipt_dstlimit_info *) matchinfo;
4161 + htable_put(r->hinfo);
4164 +static struct ipt_match ipt_dstlimit = {
4165 + .list = { .prev = NULL, .next = NULL },
4166 + .name = "dstlimit",
4167 + .match = dstlimit_match,
4168 + .checkentry = dstlimit_checkentry,
4169 + .destroy = dstlimit_destroy,
4175 +static void *dl_seq_start(struct seq_file *s, loff_t *pos)
4177 + struct proc_dir_entry *pde = s->private;
4178 + struct ipt_dstlimit_htable *htable = pde->data;
4179 + unsigned int *bucket;
4181 + LOCK_BH(&htable->lock);
4182 + if (*pos >= htable->cfg.size)
4185 + bucket = kmalloc(sizeof(unsigned int), GFP_KERNEL);
4187 + return ERR_PTR(-ENOMEM);
4193 +static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
4195 + struct proc_dir_entry *pde = s->private;
4196 + struct ipt_dstlimit_htable *htable = pde->data;
4197 + unsigned int *bucket = (unsigned int *)v;
4199 + *pos = ++(*bucket);
4200 + if (*pos >= htable->cfg.size) {
4207 +static void dl_seq_stop(struct seq_file *s, void *v)
4209 + struct proc_dir_entry *pde = s->private;
4210 + struct ipt_dstlimit_htable *htable = pde->data;
4211 + unsigned int *bucket = (unsigned int *)v;
4215 + UNLOCK_BH(&htable->lock);
4218 +static inline int dl_seq_real_show(struct dsthash_ent *ent, struct seq_file *s)
4220 + /* recalculate to show accurate numbers */
4221 + rateinfo_recalc(ent, jiffies);
4223 + return seq_printf(s, "%ld %u.%u.%u.%u->%u.%u.%u.%u:%u %u %u %u\n",
4224 + (ent->expires - jiffies)/HZ,
4225 + NIPQUAD(ent->dst.src_ip),
4226 + NIPQUAD(ent->dst.dst_ip), ntohs(ent->dst.port),
4227 + ent->rateinfo.credit, ent->rateinfo.credit_cap,
4228 + ent->rateinfo.cost);
4231 +static int dl_seq_show(struct seq_file *s, void *v)
4233 + struct proc_dir_entry *pde = s->private;
4234 + struct ipt_dstlimit_htable *htable = pde->data;
4235 + unsigned int *bucket = (unsigned int *)v;
4237 + if (LIST_FIND_W(&htable->hash[*bucket], dl_seq_real_show,
4238 + struct dsthash_ent *, s)) {
4239 + /* buffer was filled and unable to print that tuple */
4245 +static struct seq_operations dl_seq_ops = {
4246 + .start = dl_seq_start,
4247 + .next = dl_seq_next,
4248 + .stop = dl_seq_stop,
4249 + .show = dl_seq_show
4252 +static int dl_proc_open(struct inode *inode, struct file *file)
4254 + int ret = seq_open(file, &dl_seq_ops);
4257 + struct seq_file *sf = file->private_data;
4258 + sf->private = PDE(inode);
4263 +static struct file_operations dl_file_ops = {
4264 + .owner = THIS_MODULE,
4265 + .open = dl_proc_open,
4267 + .llseek = seq_lseek,
4268 + .release = seq_release
4271 +static int init_or_fini(int fini)
4278 + if (ipt_register_match(&ipt_dstlimit)) {
4280 + goto cleanup_nothing;
4283 + /* FIXME: do we really want HWCACHE_ALIGN since our objects are
4284 + * quite small ? */
4285 + dstlimit_cachep = kmem_cache_create("ipt_dstlimit",
4286 + sizeof(struct dsthash_ent), 0,
4287 + SLAB_HWCACHE_ALIGN, NULL, NULL);
4288 + if (!dstlimit_cachep) {
4289 + printk(KERN_ERR "Unable to create ipt_dstlimit slab cache\n");
4291 + goto cleanup_unreg_match;
4294 + dstlimit_procdir = proc_mkdir("ipt_dstlimit", proc_net);
4295 + if (!dstlimit_procdir) {
4296 + printk(KERN_ERR "Unable to create proc dir entry\n");
4298 + goto cleanup_free_slab;
4304 + remove_proc_entry("ipt_dstlimit", proc_net);
4306 + kmem_cache_destroy(dstlimit_cachep);
4307 +cleanup_unreg_match:
4308 + ipt_unregister_match(&ipt_dstlimit);
4314 +static int __init init(void)
4316 + return init_or_fini(0);
4319 +static void __exit fini(void)
4326 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_fuzzy.c linux-2.6.7/net/ipv4/netfilter/ipt_fuzzy.c
4327 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_fuzzy.c 1970-01-01 01:00:00.000000000 +0100
4328 +++ linux-2.6.7/net/ipv4/netfilter/ipt_fuzzy.c 2004-06-29 12:32:08.822529304 +0200
4331 + * This module implements a simple TSK FLC
4332 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
4333 + * to limit , in an adaptive and flexible way , the packet rate crossing
4334 + * a given stream . It serves as an initial and very simple (but effective)
4335 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
4336 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
4337 + * into our code in a precise , adaptive and efficient manner.
4338 + * The goal is very similar to that of "limit" match , but using techniques of
4339 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
4340 + * avoiding over and undershoots - and stuff like that .
4343 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
4344 + * 2002-08-17 : Changed to eliminate floating point operations .
4345 + * 2002-08-23 : Coding style changes .
4348 +#include <linux/module.h>
4349 +#include <linux/skbuff.h>
4350 +#include <linux/ip.h>
4351 +#include <linux/random.h>
4352 +#include <net/tcp.h>
4353 +#include <linux/spinlock.h>
4354 +#include <linux/netfilter_ipv4/ip_tables.h>
4355 +#include <linux/netfilter_ipv4/ipt_fuzzy.h>
4358 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
4359 + Expressed in percentage
4362 +#define PAR_LOW 1/100
4365 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED ;
4367 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
4368 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
4369 +MODULE_LICENSE("GPL");
4371 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
4379 + return ( (100*(tx-mini)) / (maxi-mini) );
4382 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
4390 + return ( (100*( maxi - tx )) / ( maxi - mini ) );
4394 +ipt_fuzzy_match(const struct sk_buff *pskb,
4395 + const struct net_device *in,
4396 + const struct net_device *out,
4397 + const void *matchinfo,
4401 + /* From userspace */
4403 + struct ipt_fuzzy_info *info = (struct ipt_fuzzy_info *) matchinfo;
4405 + u_int8_t random_number;
4406 + unsigned long amount;
4407 + u_int8_t howhigh, howlow;
4410 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
4412 + info->bytes_total += pskb->len;
4413 + info->packets_total++;
4415 + info->present_time = jiffies;
4417 + if (info->present_time >= info->previous_time)
4418 + amount = info->present_time - info->previous_time;
4420 + /* There was a transition : I choose to re-sample
4421 + and keep the old acceptance rate...
4425 + info->previous_time = info->present_time;
4426 + info->bytes_total = info->packets_total = 0;
4429 + if (amount > HZ/10) /* More than 100 ms elapsed ... */
4432 + info->mean_rate = (u_int32_t) ((HZ*info->packets_total) \
4435 + info->previous_time = info->present_time;
4436 + info->bytes_total = info->packets_total = 0;
4438 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
4439 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
4441 + info->acceptance_rate = (u_int8_t) \
4442 + (howhigh*PAR_LOW + PAR_HIGH*howlow);
4444 + /* In fact , the above defuzzification would require a denominator
4445 + proportional to (howhigh+howlow) but , in this particular case ,
4446 + that expression is constant .
4447 + An imediate consequence is that it isn't necessary to call
4448 + both mf_high and mf_low - but to keep things understandable ,
4453 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
4456 + if ( info->acceptance_rate < 100 )
4458 + get_random_bytes((void *)(&random_number), 1);
4460 + /* If within the acceptance , it can pass => don't match */
4461 + if (random_number <= (255 * info->acceptance_rate) / 100)
4464 + return 1; /* It can't pass ( It matches ) */
4467 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
4472 +ipt_fuzzy_checkentry(const char *tablename,
4473 + const struct ipt_ip *e,
4475 + unsigned int matchsize,
4476 + unsigned int hook_mask)
4479 + const struct ipt_fuzzy_info *info = matchinfo;
4481 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_fuzzy_info))) {
4482 + printk("ipt_fuzzy: matchsize %u != %u\n", matchsize,
4483 + IPT_ALIGN(sizeof(struct ipt_fuzzy_info)));
4487 + if ((info->minimum_rate < MINFUZZYRATE ) || (info->maximum_rate > MAXFUZZYRATE)
4488 + || (info->minimum_rate >= info->maximum_rate )) {
4489 + printk("ipt_fuzzy: BAD limits , please verify !!!\n");
4496 +static struct ipt_match ipt_fuzzy_reg = {
4498 + .match = ipt_fuzzy_match,
4499 + .checkentry = ipt_fuzzy_checkentry,
4503 +static int __init init(void)
4505 + return ipt_register_match(&ipt_fuzzy_reg);
4508 +static void __exit fini(void)
4510 + ipt_unregister_match(&ipt_fuzzy_reg);
4515 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_ipv4options.c linux-2.6.7/net/ipv4/netfilter/ipt_ipv4options.c
4516 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_ipv4options.c 1970-01-01 01:00:00.000000000 +0100
4517 +++ linux-2.6.7/net/ipv4/netfilter/ipt_ipv4options.c 2004-06-29 12:32:14.112725072 +0200
4520 + This is a module which is used to match ipv4 options.
4521 + This file is distributed under the terms of the GNU General Public
4522 + License (GPL). Copies of the GPL can be obtained from:
4523 + ftp://prep.ai.mit.edu/pub/gnu/GPL
4525 + 11-mars-2001 Fabrice MARIE <fabrice@netfilter.org> : initial development.
4526 + 12-july-2001 Fabrice MARIE <fabrice@netfilter.org> : added router-alert otions matching. Fixed a bug with no-srr
4527 + 12-august-2001 Imran Patel <ipatel@crosswinds.net> : optimization of the match.
4528 + 18-november-2001 Fabrice MARIE <fabrice@netfilter.org> : added [!] 'any' option match.
4529 + 19-february-2004 Harald Welte <laforge@netfilter.org> : merge with 2.6.x
4532 +#include <linux/module.h>
4533 +#include <linux/skbuff.h>
4534 +#include <net/ip.h>
4536 +#include <linux/netfilter_ipv4/ip_tables.h>
4537 +#include <linux/netfilter_ipv4/ipt_ipv4options.h>
4539 +MODULE_LICENSE("GPL");
4540 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
4543 +match(const struct sk_buff *skb,
4544 + const struct net_device *in,
4545 + const struct net_device *out,
4546 + const void *matchinfo,
4550 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
4551 + const struct iphdr *iph = skb->nh.iph;
4552 + const struct ip_options *opt;
4554 + if (iph->ihl * 4 == sizeof(struct iphdr)) {
4555 + /* No options, so we match only the "DONTs" and the "IGNOREs" */
4557 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) ||
4558 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
4559 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
4560 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
4561 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
4562 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
4567 + if ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)
4568 + /* there are options, and we don't need to care which one */
4571 + if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
4572 + /* there are options but we don't want any ! */
4577 + opt = &(IPCB(skb)->opt);
4579 + /* source routing */
4580 + if ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) {
4581 + if (!((opt->srr) & (opt->is_strictroute)))
4584 + else if ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) {
4585 + if (!((opt->srr) & (!opt->is_strictroute)))
4588 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) {
4592 + /* record route */
4593 + if ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) {
4597 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) {
4602 + if ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) {
4606 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) {
4610 + /* router-alert option */
4611 + if ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) {
4612 + if (!opt->router_alert)
4615 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) {
4616 + if (opt->router_alert)
4625 +checkentry(const char *tablename,
4626 + const struct ipt_ip *ip,
4628 + unsigned int matchsize,
4629 + unsigned int hook_mask)
4631 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
4632 + /* Check the size */
4633 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_ipv4options_info)))
4635 + /* Now check the coherence of the data ... */
4636 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) &&
4637 + (((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) ||
4638 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) ||
4639 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) ||
4640 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) ||
4641 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)))
4642 + return 0; /* opposites */
4643 + if (((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) &&
4644 + (((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
4645 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
4646 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
4647 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
4648 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) ||
4649 + ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)))
4650 + return 0; /* opposites */
4651 + if (((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) &&
4652 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR))
4653 + return 0; /* cannot match in the same time loose and strict source routing */
4654 + if ((((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
4655 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR)) &&
4656 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR))
4657 + return 0; /* opposites */
4658 + if (((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) &&
4659 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR))
4660 + return 0; /* opposites */
4661 + if (((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) &&
4662 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
4663 + return 0; /* opposites */
4664 + if (((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) &&
4665 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
4666 + return 0; /* opposites */
4668 + /* everything looks ok. */
4672 +static struct ipt_match ipv4options_match = {
4673 + .name = "ipv4options",
4675 + .checkentry = checkentry,
4679 +static int __init init(void)
4681 + return ipt_register_match(&ipv4options_match);
4684 +static void __exit fini(void)
4686 + ipt_unregister_match(&ipv4options_match);
4691 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_mport.c linux-2.6.7/net/ipv4/netfilter/ipt_mport.c
4692 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_mport.c 1970-01-01 01:00:00.000000000 +0100
4693 +++ linux-2.6.7/net/ipv4/netfilter/ipt_mport.c 2004-06-29 12:32:15.541507864 +0200
4695 +/* Kernel module to match one of a list of TCP/UDP ports: ports are in
4696 + the same place so we can treat them as equal. */
4697 +#include <linux/module.h>
4698 +#include <linux/types.h>
4699 +#include <linux/udp.h>
4700 +#include <linux/skbuff.h>
4702 +#include <linux/netfilter_ipv4/ipt_mport.h>
4703 +#include <linux/netfilter_ipv4/ip_tables.h>
4705 +MODULE_LICENSE("GPL");
4708 +#define duprintf(format, args...) printk(format , ## args)
4710 +#define duprintf(format, args...)
4713 +/* Returns 1 if the port is matched by the test, 0 otherwise. */
4715 +ports_match(const struct ipt_mport *minfo, u_int16_t src, u_int16_t dst)
4719 + u_int16_t pflags = minfo->pflags;
4720 + for (i=0, m=1; i<IPT_MULTI_PORTS; i++, m<<=1) {
4724 + && minfo->ports[i] == 65535)
4727 + s = minfo->ports[i];
4730 + e = minfo->ports[++i];
4735 + if (minfo->flags & IPT_MPORT_SOURCE
4736 + && src >= s && src <= e)
4739 + if (minfo->flags & IPT_MPORT_DESTINATION
4740 + && dst >= s && dst <= e)
4748 +match(const struct sk_buff *skb,
4749 + const struct net_device *in,
4750 + const struct net_device *out,
4751 + const void *matchinfo,
4756 + const struct ipt_mport *minfo = matchinfo;
4761 + /* Must be big enough to read ports (both UDP and TCP have
4762 + them at the start). */
4763 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
4764 + /* We've been asked to examine this packet, and we
4765 + can't. Hence, no choice but to drop. */
4766 + duprintf("ipt_multiport:"
4767 + " Dropping evil offset=0 tinygram.\n");
4772 + return ports_match(minfo, ntohs(ports[0]), ntohs(ports[1]));
4775 +/* Called when user tries to insert an entry of this type. */
4777 +checkentry(const char *tablename,
4778 + const struct ipt_ip *ip,
4780 + unsigned int matchsize,
4781 + unsigned int hook_mask)
4783 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_mport)))
4786 + /* Must specify proto == TCP/UDP, no unknown flags or bad count */
4787 + return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
4788 + && !(ip->invflags & IPT_INV_PROTO)
4789 + && matchsize == IPT_ALIGN(sizeof(struct ipt_mport));
4792 +static struct ipt_match mport_match = {
4795 + .checkentry = &checkentry,
4799 +static int __init init(void)
4801 + return ipt_register_match(&mport_match);
4804 +static void __exit fini(void)
4806 + ipt_unregister_match(&mport_match);
4811 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_nth.c linux-2.6.7/net/ipv4/netfilter/ipt_nth.c
4812 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_nth.c 1970-01-01 01:00:00.000000000 +0100
4813 +++ linux-2.6.7/net/ipv4/netfilter/ipt_nth.c 2004-06-29 12:32:16.701331544 +0200
4816 + This is a module which is used for match support for every Nth packet
4817 + This file is distributed under the terms of the GNU General Public
4818 + License (GPL). Copies of the GPL can be obtained from:
4819 + ftp://prep.ai.mit.edu/pub/gnu/GPL
4821 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
4822 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
4823 + * added support for multiple counters
4824 + * added support for matching on individual packets
4825 + in the counter cycle
4826 + 2004-02-19 Harald Welte <laforge@netfilter.org>
4831 +#include <linux/module.h>
4832 +#include <linux/skbuff.h>
4833 +#include <linux/ip.h>
4834 +#include <net/tcp.h>
4835 +#include <linux/spinlock.h>
4836 +#include <linux/netfilter_ipv4/ip_tables.h>
4837 +#include <linux/netfilter_ipv4/ipt_nth.h>
4839 +MODULE_LICENSE("GPL");
4840 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
4843 + * State information.
4850 +static struct state states[IPT_NTH_NUM_COUNTERS];
4853 +ipt_nth_match(const struct sk_buff *pskb,
4854 + const struct net_device *in,
4855 + const struct net_device *out,
4856 + const void *matchinfo,
4860 + /* Parameters from userspace */
4861 + const struct ipt_nth_info *info = matchinfo;
4862 + unsigned counter = info->counter;
4863 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
4865 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
4869 + spin_lock(&states[counter].lock);
4871 + /* Are we matching every nth packet?*/
4872 + if (info->packet == 0xFF)
4874 + /* We're matching every nth packet and only every nth packet*/
4875 + /* Do we match or invert match? */
4876 + if (info->not == 0)
4878 + if (states[counter].number == 0)
4880 + ++states[counter].number;
4883 + if (states[counter].number >= info->every)
4884 + states[counter].number = 0; /* reset the counter */
4886 + ++states[counter].number;
4891 + if (states[counter].number == 0)
4893 + ++states[counter].number;
4896 + if (states[counter].number >= info->every)
4897 + states[counter].number = 0;
4899 + ++states[counter].number;
4905 + /* We're using the --packet, so there must be a rule for every value */
4906 + if (states[counter].number == info->packet)
4908 + /* only increment the counter when a match happens */
4909 + if (states[counter].number >= info->every)
4910 + states[counter].number = 0; /* reset the counter */
4912 + ++states[counter].number;
4921 + spin_unlock(&states[counter].lock);
4925 + spin_unlock(&states[counter].lock);
4930 +ipt_nth_checkentry(const char *tablename,
4931 + const struct ipt_ip *e,
4933 + unsigned int matchsize,
4934 + unsigned int hook_mask)
4936 + /* Parameters from userspace */
4937 + const struct ipt_nth_info *info = matchinfo;
4938 + unsigned counter = info->counter;
4939 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
4941 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
4945 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_nth_info))) {
4946 + printk("nth: matchsize %u != %u\n", matchsize,
4947 + IPT_ALIGN(sizeof(struct ipt_nth_info)));
4951 + states[counter].number = info->startat;
4956 +static struct ipt_match ipt_nth_reg = {
4958 + .match = ipt_nth_match,
4959 + .checkentry = ipt_nth_checkentry,
4963 +static int __init init(void)
4967 + memset(&states, 0, sizeof(states));
4968 + for (counter = 0; counter < IPT_NTH_NUM_COUNTERS; counter++)
4969 + spin_lock_init(&(states[counter].lock));
4971 + return ipt_register_match(&ipt_nth_reg);
4974 +static void __exit fini(void)
4976 + ipt_unregister_match(&ipt_nth_reg);
4981 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_owner.c linux-2.6.7/net/ipv4/netfilter/ipt_owner.c
4982 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_owner.c 2004-06-29 12:24:13.000000000 +0200
4983 +++ linux-2.6.7/net/ipv4/netfilter/ipt_owner.c 2004-06-29 12:35:34.494262448 +0200
4985 * This program is free software; you can redistribute it and/or modify
4986 * it under the terms of the GNU General Public License version 2 as
4987 * published by the Free Software Foundation.
4989 + * 03/26/2003 Patrick McHardy <kaber@trash.net> : LOCAL_IN support
4992 #include <linux/module.h>
4993 #include <linux/skbuff.h>
4994 #include <linux/file.h>
4995 +#include <linux/ip.h>
4996 +#include <linux/tcp.h>
4997 +#include <linux/udp.h>
4998 #include <net/sock.h>
4999 +#include <net/tcp.h>
5000 +#include <net/udp.h>
5002 #include <linux/netfilter_ipv4/ipt_owner.h>
5003 #include <linux/netfilter_ipv4/ip_tables.h>
5005 MODULE_DESCRIPTION("iptables owner match");
5008 -match_comm(const struct sk_buff *skb, const char *comm)
5009 +match_comm(const struct sock *sk, const char *comm)
5011 struct task_struct *g, *p;
5012 struct files_struct *files;
5014 spin_lock(&files->file_lock);
5015 for (i=0; i < files->max_fds; i++) {
5016 if (fcheck_files(files, i) ==
5017 - skb->sk->sk_socket->file) {
5018 + sk->sk_socket->file) {
5019 spin_unlock(&files->file_lock);
5021 read_unlock(&tasklist_lock);
5026 -match_pid(const struct sk_buff *skb, pid_t pid)
5027 +match_pid(const struct sock *sk, pid_t pid)
5029 struct task_struct *p;
5030 struct files_struct *files;
5032 spin_lock(&files->file_lock);
5033 for (i=0; i < files->max_fds; i++) {
5034 if (fcheck_files(files, i) ==
5035 - skb->sk->sk_socket->file) {
5036 + sk->sk_socket->file) {
5037 spin_unlock(&files->file_lock);
5039 read_unlock(&tasklist_lock);
5044 -match_sid(const struct sk_buff *skb, pid_t sid)
5045 +match_sid(const struct sock *sk, pid_t sid)
5047 struct task_struct *g, *p;
5048 - struct file *file = skb->sk->sk_socket->file;
5049 + struct file *file = sk->sk_socket->file;
5052 read_lock(&tasklist_lock);
5053 @@ -129,41 +136,71 @@
5056 const struct ipt_owner_info *info = matchinfo;
5057 + struct iphdr *iph = skb->nh.iph;
5058 + struct sock *sk = NULL;
5064 + if (iph->protocol == IPPROTO_TCP) {
5065 + struct tcphdr *tcph =
5066 + (struct tcphdr *)((u_int32_t *)iph + iph->ihl);
5067 + sk = tcp_v4_lookup(iph->saddr, tcph->source,
5068 + iph->daddr, tcph->dest,
5069 + skb->dev->ifindex);
5070 + if (sk && sk->sk_state == TCP_TIME_WAIT) {
5071 + tcp_tw_put((struct tcp_tw_bucket *)sk);
5074 + } else if (iph->protocol == IPPROTO_UDP) {
5075 + struct udphdr *udph =
5076 + (struct udphdr *)((u_int32_t *)iph + iph->ihl);
5077 + sk = udp_v4_lookup(iph->saddr, udph->source, iph->daddr,
5078 + udph->dest, skb->dev->ifindex);
5082 - if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
5084 + if (!sk || !sk->sk_socket || !sk->sk_socket->file)
5087 if(info->match & IPT_OWNER_UID) {
5088 - if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
5089 + if ((sk->sk_socket->file->f_uid != info->uid) ^
5090 !!(info->invert & IPT_OWNER_UID))
5095 if(info->match & IPT_OWNER_GID) {
5096 - if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
5097 + if ((sk->sk_socket->file->f_gid != info->gid) ^
5098 !!(info->invert & IPT_OWNER_GID))
5103 if(info->match & IPT_OWNER_PID) {
5104 - if (!match_pid(skb, info->pid) ^
5105 + if (!match_pid(sk, info->pid) ^
5106 !!(info->invert & IPT_OWNER_PID))
5111 if(info->match & IPT_OWNER_SID) {
5112 - if (!match_sid(skb, info->sid) ^
5113 + if (!match_sid(sk, info->sid) ^
5114 !!(info->invert & IPT_OWNER_SID))
5119 if(info->match & IPT_OWNER_COMM) {
5120 - if (!match_comm(skb, info->comm) ^
5121 + if (!match_comm(sk, info->comm) ^
5122 !!(info->invert & IPT_OWNER_COMM))
5138 @@ -173,11 +210,19 @@
5139 unsigned int matchsize,
5140 unsigned int hook_mask)
5143 - & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) {
5144 - printk("ipt_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
5148 + & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING) |
5149 + (1 << NF_IP_LOCAL_IN))) {
5150 + printk("ipt_owner: only valid for LOCAL_IN, LOCAL_OUT "
5151 + "or POST_ROUTING.\n");
5155 + if ((hook_mask & (1 << NF_IP_LOCAL_IN))
5156 + && ip->proto != IPPROTO_TCP && ip->proto != IPPROTO_UDP) {
5157 + printk("ipt_owner: only TCP or UDP can be used in LOCAL_IN\n");
5161 if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info))) {
5162 printk("Matchsize %u != %Zu\n", matchsize,
5163 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_policy.c linux-2.6.7/net/ipv4/netfilter/ipt_policy.c
5164 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_policy.c 1970-01-01 01:00:00.000000000 +0100
5165 +++ linux-2.6.7/net/ipv4/netfilter/ipt_policy.c 2004-06-29 12:35:40.048418088 +0200
5167 +/* IP tables module for matching IPsec policy
5169 + * Copyright (c) 2004 Patrick McHardy, <kaber@trash.net>
5171 + * This program is free software; you can redistribute it and/or modify
5172 + * it under the terms of the GNU General Public License version 2 as
5173 + * published by the Free Software Foundation.
5176 +#include <linux/kernel.h>
5177 +#include <linux/config.h>
5178 +#include <linux/module.h>
5179 +#include <linux/skbuff.h>
5180 +#include <linux/init.h>
5181 +#include <net/xfrm.h>
5183 +#include <linux/netfilter_ipv4.h>
5184 +#include <linux/netfilter_ipv4/ipt_policy.h>
5185 +#include <linux/netfilter_ipv4/ip_tables.h>
5187 +MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
5188 +MODULE_DESCRIPTION("IPtables IPsec policy matching module");
5189 +MODULE_LICENSE("GPL");
5193 +match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e)
5195 +#define MISMATCH(x,y) (e->match.x && ((e->x != (y)) ^ e->invert.x))
5197 + if (MISMATCH(saddr, x->props.saddr.a4 & e->smask) ||
5198 + MISMATCH(daddr, x->id.daddr.a4 & e->dmask) ||
5199 + MISMATCH(proto, x->id.proto) ||
5200 + MISMATCH(mode, x->props.mode) ||
5201 + MISMATCH(spi, x->id.spi) ||
5202 + MISMATCH(reqid, x->props.reqid))
5208 +match_policy_in(const struct sk_buff *skb, const struct ipt_policy_info *info)
5210 + const struct ipt_policy_elem *e;
5211 + struct sec_path *sp = skb->sp;
5212 + int strict = info->flags & POLICY_MATCH_STRICT;
5217 + if (strict && info->len != sp->len)
5220 + for (i = sp->len - 1; i >= 0; i--) {
5221 + pos = strict ? i - sp->len + 1 : 0;
5222 + if (pos >= info->len)
5224 + e = &info->pol[pos];
5226 + if (match_xfrm_state(sp->x[i].xvec, e)) {
5229 + } else if (strict)
5233 + return strict ? 1 : 0;
5237 +match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info)
5239 + const struct ipt_policy_elem *e;
5240 + struct dst_entry *dst = skb->dst;
5241 + int strict = info->flags & POLICY_MATCH_STRICT;
5244 + if (dst->xfrm == NULL)
5247 + for (i = 0; dst && dst->xfrm; dst = dst->child, i++) {
5248 + pos = strict ? i : 0;
5249 + if (pos >= info->len)
5251 + e = &info->pol[pos];
5253 + if (match_xfrm_state(dst->xfrm, e)) {
5256 + } else if (strict)
5260 + return strict ? 1 : 0;
5263 +static int match(const struct sk_buff *skb,
5264 + const struct net_device *in,
5265 + const struct net_device *out,
5266 + const void *matchinfo, int offset, int *hotdrop)
5268 + const struct ipt_policy_info *info = matchinfo;
5271 + if (info->flags & POLICY_MATCH_IN)
5272 + ret = match_policy_in(skb, info);
5274 + ret = match_policy_out(skb, info);
5277 + if (info->flags & POLICY_MATCH_NONE)
5281 + } else if (info->flags & POLICY_MATCH_NONE)
5287 +static int checkentry(const char *tablename, const struct ipt_ip *ip,
5288 + void *matchinfo, unsigned int matchsize,
5289 + unsigned int hook_mask)
5291 + struct ipt_policy_info *info = matchinfo;
5293 + if (matchsize != IPT_ALIGN(sizeof(*info))) {
5294 + printk(KERN_ERR "ipt_policy: matchsize %u != %u\n",
5295 + matchsize, IPT_ALIGN(sizeof(*info)));
5298 + if (!(info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT))) {
5299 + printk(KERN_ERR "ipt_policy: neither incoming nor "
5300 + "outgoing policy selected\n");
5303 + if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
5304 + && info->flags & POLICY_MATCH_OUT) {
5305 + printk(KERN_ERR "ipt_policy: output policy not valid in "
5306 + "PRE_ROUTING and INPUT\n");
5309 + if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
5310 + && info->flags & POLICY_MATCH_IN) {
5311 + printk(KERN_ERR "ipt_policy: input policy not valid in "
5312 + "POST_ROUTING and OUTPUT\n");
5315 + if (info->len > POLICY_MAX_ELEM) {
5316 + printk(KERN_ERR "ipt_policy: too many policy elements\n");
5323 +static struct ipt_match policy_match =
5327 + .checkentry = checkentry,
5328 + .me = THIS_MODULE,
5331 +static int __init init(void)
5333 + return ipt_register_match(&policy_match);
5336 +static void __exit fini(void)
5338 + ipt_unregister_match(&policy_match);
5343 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_psd.c linux-2.6.7/net/ipv4/netfilter/ipt_psd.c
5344 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_psd.c 1970-01-01 01:00:00.000000000 +0100
5345 +++ linux-2.6.7/net/ipv4/netfilter/ipt_psd.c 2004-06-29 12:32:18.295089256 +0200
5348 + This is a module which is used for PSD (portscan detection)
5349 + Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
5350 + and LOG target module.
5352 + Copyright (C) 2000,2001 astaro AG
5354 + This file is distributed under the terms of the GNU General Public
5355 + License (GPL). Copies of the GPL can be obtained from:
5356 + ftp://prep.ai.mit.edu/pub/gnu/GPL
5358 + 2000-05-04 Markus Hennig <hennig@astaro.de> : initial
5359 + 2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
5360 + 2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
5361 + 2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
5362 + 2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
5363 + 2004-05-05 Martijn Lievaart <m@rtij.nl> : ported to 2.6
5366 +#include <linux/module.h>
5367 +#include <linux/skbuff.h>
5368 +#include <linux/ip.h>
5369 +#include <net/tcp.h>
5370 +#include <linux/spinlock.h>
5371 +#include <linux/netfilter_ipv4/ip_tables.h>
5372 +#include <linux/netfilter_ipv4/ipt_psd.h>
5375 +#define DEBUGP printk
5377 +#define DEBUGP(format, args...)
5380 +MODULE_LICENSE("GPL");
5381 +MODULE_AUTHOR("Dennis Koslowski <koslowski@astaro.com>");
5383 +#define HF_DADDR_CHANGING 0x01
5384 +#define HF_SPORT_CHANGING 0x02
5385 +#define HF_TOS_CHANGING 0x04
5386 +#define HF_TTL_CHANGING 0x08
5389 + * Information we keep per each target port
5392 + u_int16_t number; /* port number */
5393 + u_int8_t proto; /* protocol number */
5394 + u_int8_t and_flags; /* tcp ANDed flags */
5395 + u_int8_t or_flags; /* tcp ORed flags */
5399 + * Information we keep per each source address.
5402 + struct host *next; /* Next entry with the same hash */
5403 + clock_t timestamp; /* Last update time */
5404 + struct in_addr src_addr; /* Source address */
5405 + struct in_addr dest_addr; /* Destination address */
5406 + unsigned short src_port; /* Source port */
5407 + int count; /* Number of ports in the list */
5408 + int weight; /* Total weight of ports in the list */
5409 + struct port ports[SCAN_MAX_COUNT - 1]; /* List of ports */
5410 + unsigned char tos; /* TOS */
5411 + unsigned char ttl; /* TTL */
5412 + unsigned char flags; /* HF_ flags bitmask */
5416 + * State information.
5420 + struct host list[LIST_SIZE]; /* List of source addresses */
5421 + struct host *hash[HASH_SIZE]; /* Hash: pointers into the list */
5422 + int index; /* Oldest entry to be replaced */
5426 + * Convert an IP address into a hash table index.
5428 +static inline int hashfunc(struct in_addr addr)
5430 + unsigned int value;
5433 + value = addr.s_addr;
5437 + } while ((value >>= HASH_LOG));
5439 + return hash & (HASH_SIZE - 1);
5443 +ipt_psd_match(const struct sk_buff *pskb,
5444 + const struct net_device *in,
5445 + const struct net_device *out,
5446 + const void *matchinfo,
5450 + struct iphdr *ip_hdr;
5451 + struct tcphdr *tcp_hdr;
5452 + struct in_addr addr;
5453 + u_int16_t src_port,dest_port;
5454 + u_int8_t tcp_flags, proto;
5456 + struct host *curr, *last, **head;
5457 + int hash, index, count;
5459 + /* Parameters from userspace */
5460 + const struct ipt_psd_info *psdinfo = matchinfo;
5463 + ip_hdr = pskb->nh.iph;
5465 + /* Sanity check */
5466 + if (ntohs(ip_hdr->frag_off) & IP_OFFSET) {
5467 + DEBUGP("PSD: sanity check failed\n");
5471 + /* TCP or UDP ? */
5472 + proto = ip_hdr->protocol;
5474 + if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
5475 + DEBUGP("PSD: protocol not supported\n");
5479 + /* Get the source address, source & destination ports, and TCP flags */
5481 + addr.s_addr = ip_hdr->saddr;
5483 + tcp_hdr = (struct tcphdr*)((u_int32_t *)ip_hdr + ip_hdr->ihl);
5485 + /* Yep, it´s dirty */
5486 + src_port = tcp_hdr->source;
5487 + dest_port = tcp_hdr->dest;
5489 + if (proto == IPPROTO_TCP) {
5490 + tcp_flags = *((u_int8_t*)tcp_hdr + 13);
5496 + /* We're using IP address 0.0.0.0 for a special purpose here, so don't let
5497 + * them spoof us. [DHCP needs this feature - HW] */
5498 + if (!addr.s_addr) {
5499 + DEBUGP("PSD: spoofed source address (0.0.0.0)\n");
5503 + /* Use jiffies here not to depend on someone setting the time while we're
5504 + * running; we need to be careful with possible return value overflows. */
5507 + spin_lock(&state.lock);
5509 + /* Do we know this source address already? */
5512 + if ((curr = *(head = &state.hash[hash = hashfunc(addr)])))
5514 + if (curr->src_addr.s_addr == addr.s_addr) break;
5516 + if (curr->next) last = curr;
5517 + } while ((curr = curr->next));
5521 + /* We know this address, and the entry isn't too old. Update it. */
5522 + if (now - curr->timestamp <= (psdinfo->delay_threshold*HZ)/100 &&
5523 + time_after_eq(now, curr->timestamp)) {
5525 + /* Just update the appropriate list entry if we've seen this port already */
5526 + for (index = 0; index < curr->count; index++) {
5527 + if (curr->ports[index].number == dest_port) {
5528 + curr->ports[index].proto = proto;
5529 + curr->ports[index].and_flags &= tcp_flags;
5530 + curr->ports[index].or_flags |= tcp_flags;
5531 + goto out_no_match;
5535 + /* TCP/ACK and/or TCP/RST to a new port? This could be an outgoing connection. */
5536 + if (proto == IPPROTO_TCP && (tcp_hdr->ack || tcp_hdr->rst))
5537 + goto out_no_match;
5539 + /* Packet to a new port, and not TCP/ACK: update the timestamp */
5540 + curr->timestamp = now;
5542 + /* Logged this scan already? Then drop the packet. */
5543 + if (curr->weight >= psdinfo->weight_threshold)
5546 + /* Specify if destination address, source port, TOS or TTL are not fixed */
5547 + if (curr->dest_addr.s_addr != ip_hdr->daddr)
5548 + curr->flags |= HF_DADDR_CHANGING;
5549 + if (curr->src_port != src_port)
5550 + curr->flags |= HF_SPORT_CHANGING;
5551 + if (curr->tos != ip_hdr->tos)
5552 + curr->flags |= HF_TOS_CHANGING;
5553 + if (curr->ttl != ip_hdr->ttl)
5554 + curr->flags |= HF_TTL_CHANGING;
5556 + /* Update the total weight */
5557 + curr->weight += (ntohs(dest_port) < 1024) ?
5558 + psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
5560 + /* Got enough destination ports to decide that this is a scan? */
5561 + /* Then log it and drop the packet. */
5562 + if (curr->weight >= psdinfo->weight_threshold)
5565 + /* Remember the new port */
5566 + if (curr->count < SCAN_MAX_COUNT) {
5567 + curr->ports[curr->count].number = dest_port;
5568 + curr->ports[curr->count].proto = proto;
5569 + curr->ports[curr->count].and_flags = tcp_flags;
5570 + curr->ports[curr->count].or_flags = tcp_flags;
5574 + goto out_no_match;
5577 + /* We know this address, but the entry is outdated. Mark it unused, and
5578 + * remove from the hash table. We'll allocate a new entry instead since
5579 + * this one might get re-used too soon. */
5580 + curr->src_addr.s_addr = 0;
5582 + last->next = last->next->next;
5584 + *head = (*head)->next;
5588 + /* We don't need an ACK from a new source address */
5589 + if (proto == IPPROTO_TCP && tcp_hdr->ack)
5590 + goto out_no_match;
5592 + /* Got too many source addresses with the same hash value? Then remove the
5593 + * oldest one from the hash table, so that they can't take too much of our
5594 + * CPU time even with carefully chosen spoofed IP addresses. */
5595 + if (count >= HASH_MAX && last) last->next = NULL;
5597 + /* We're going to re-use the oldest list entry, so remove it from the hash
5598 + * table first (if it is really already in use, and isn't removed from the
5599 + * hash table already because of the HASH_MAX check above). */
5601 + /* First, find it */
5602 + if (state.list[state.index].src_addr.s_addr)
5603 + head = &state.hash[hashfunc(state.list[state.index].src_addr)];
5607 + if ((curr = *head))
5609 + if (curr == &state.list[state.index]) break;
5611 + } while ((curr = curr->next));
5613 + /* Then, remove it */
5616 + last->next = last->next->next;
5618 + *head = (*head)->next;
5621 + /* Get our list entry */
5622 + curr = &state.list[state.index++];
5623 + if (state.index >= LIST_SIZE) state.index = 0;
5625 + /* Link it into the hash table */
5626 + head = &state.hash[hash];
5627 + curr->next = *head;
5630 + /* And fill in the fields */
5631 + curr->timestamp = now;
5632 + curr->src_addr = addr;
5633 + curr->dest_addr.s_addr = ip_hdr->daddr;
5634 + curr->src_port = src_port;
5636 + curr->weight = (ntohs(dest_port) < 1024) ?
5637 + psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
5638 + curr->ports[0].number = dest_port;
5639 + curr->ports[0].proto = proto;
5640 + curr->ports[0].and_flags = tcp_flags;
5641 + curr->ports[0].or_flags = tcp_flags;
5642 + curr->tos = ip_hdr->tos;
5643 + curr->ttl = ip_hdr->ttl;
5646 + spin_unlock(&state.lock);
5650 + spin_unlock(&state.lock);
5654 +static int ipt_psd_checkentry(const char *tablename,
5655 + const struct ipt_ip *e,
5657 + unsigned int matchsize,
5658 + unsigned int hook_mask)
5660 +/* const struct ipt_psd_info *psdinfo = targinfo;*/
5662 + /* we accept TCP only */
5663 +/* if (e->ip.proto != IPPROTO_TCP) { */
5664 +/* DEBUGP("PSD: specified protocol may be TCP only\n"); */
5668 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_psd_info))) {
5669 + DEBUGP("PSD: matchsize %u != %u\n",
5671 + IPT_ALIGN(sizeof(struct ipt_psd_info)));
5678 +static struct ipt_match ipt_psd_reg = {
5680 + .match = ipt_psd_match,
5681 + .checkentry = ipt_psd_checkentry,
5682 + .me = THIS_MODULE };
5684 +static int __init init(void)
5686 + if (ipt_register_match(&ipt_psd_reg))
5689 + memset(&state, 0, sizeof(state));
5691 + spin_lock_init(&(state.lock));
5693 + printk("netfilter PSD loaded - (c) astaro AG\n");
5697 +static void __exit fini(void)
5699 + ipt_unregister_match(&ipt_psd_reg);
5700 + printk("netfilter PSD unloaded - (c) astaro AG\n");
5705 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_quota.c linux-2.6.7/net/ipv4/netfilter/ipt_quota.c
5706 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_quota.c 1970-01-01 01:00:00.000000000 +0100
5707 +++ linux-2.6.7/net/ipv4/netfilter/ipt_quota.c 2004-06-29 12:32:19.479909136 +0200
5710 + * netfilter module to enforce network quotas
5712 + * Sam Johnston <samj@samj.net>
5714 +#include <linux/module.h>
5715 +#include <linux/skbuff.h>
5716 +#include <linux/spinlock.h>
5717 +#include <linux/interrupt.h>
5719 +#include <linux/netfilter_ipv4/ip_tables.h>
5720 +#include <linux/netfilter_ipv4/ipt_quota.h>
5722 +MODULE_LICENSE("GPL");
5723 +MODULE_AUTHOR("Sam Johnston <samj@samj.net>");
5725 +static spinlock_t quota_lock = SPIN_LOCK_UNLOCKED;
5728 +match(const struct sk_buff *skb,
5729 + const struct net_device *in,
5730 + const struct net_device *out,
5731 + const void *matchinfo,
5732 + int offset, int *hotdrop)
5734 + struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
5735 + unsigned int datalen;
5737 + if (skb->len < sizeof(struct iphdr))
5740 + datalen = skb->len - skb->nh.iph->ihl*4;
5742 + spin_lock_bh("a_lock);
5744 + if (q->quota >= datalen) {
5745 + /* we can afford this one */
5746 + q->quota -= datalen;
5747 + spin_unlock_bh("a_lock);
5749 +#ifdef DEBUG_IPT_QUOTA
5750 + printk("IPT Quota OK: %llu datlen %d \n", q->quota, datalen);
5755 + /* so we do not allow even small packets from now on */
5758 +#ifdef DEBUG_IPT_QUOTA
5759 + printk("IPT Quota Failed: %llu datlen %d \n", q->quota, datalen);
5762 + spin_unlock_bh("a_lock);
5767 +checkentry(const char *tablename,
5768 + const struct ipt_ip *ip,
5769 + void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
5771 + /* TODO: spinlocks? sanity checks? */
5772 + if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info)))
5778 +static struct ipt_match quota_match = {
5781 + .checkentry = checkentry,
5788 + return ipt_register_match("a_match);
5794 + ipt_unregister_match("a_match);
5800 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_sctp.c linux-2.6.7/net/ipv4/netfilter/ipt_sctp.c
5801 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_sctp.c 1970-01-01 01:00:00.000000000 +0100
5802 +++ linux-2.6.7/net/ipv4/netfilter/ipt_sctp.c 2004-06-29 12:32:35.031544928 +0200
5804 +#include <linux/module.h>
5805 +#include <linux/skbuff.h>
5806 +#include <net/ip.h>
5807 +#include <linux/sctp.h>
5809 +#include <linux/netfilter_ipv4/ip_tables.h>
5810 +#include <linux/netfilter_ipv4/ipt_sctp.h>
5813 +#define duprintf(format, args...) printk(format , ## args)
5815 +#define duprintf(format, args...)
5818 +#define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \
5819 + || (!!((invflag) & (option)) ^ (cond)))
5822 +match_flags(const struct ipt_sctp_flag_info *flag_info,
5823 + const int flag_count,
5824 + u_int8_t chunktype,
5825 + u_int8_t chunkflags)
5829 + for (i = 0; i < flag_count; i++) {
5830 + if (flag_info[i].chunktype == chunktype) {
5831 + return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag;
5839 +match_packet(const struct sk_buff *skb,
5840 + const u_int32_t *chunkmap,
5841 + int chunk_match_type,
5842 + const struct ipt_sctp_flag_info *flag_info,
5843 + const int flag_count,
5847 + u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
5848 + sctp_chunkhdr_t sch;
5852 + if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) {
5853 + SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap);
5856 + offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t);
5858 + if (skb_copy_bits(skb, offset, &sch, sizeof(sch)) < 0) {
5859 + duprintf("Dropping invalid SCTP packet.\n");
5864 + duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n",
5865 + ++i, offset, sch.type, htons(sch.length), sch.flags);
5867 + offset += (htons(sch.length) + 3) & ~3;
5869 + duprintf("skb->len: %d\toffset: %d\n", skb->len, offset);
5871 + if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch.type)) {
5872 + switch (chunk_match_type) {
5873 + case SCTP_CHUNK_MATCH_ANY:
5874 + if (match_flags(flag_info, flag_count,
5875 + sch.type, sch.flags)) {
5880 + case SCTP_CHUNK_MATCH_ALL:
5881 + if (match_flags(flag_info, flag_count,
5882 + sch.type, sch.flags)) {
5883 + SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch.type);
5887 + case SCTP_CHUNK_MATCH_ONLY:
5888 + if (!match_flags(flag_info, flag_count,
5889 + sch.type, sch.flags)) {
5895 + switch (chunk_match_type) {
5896 + case SCTP_CHUNK_MATCH_ONLY:
5900 + } while (offset < skb->len);
5902 + switch (chunk_match_type) {
5903 + case SCTP_CHUNK_MATCH_ALL:
5904 + return SCTP_CHUNKMAP_IS_CLEAR(chunkmap);
5905 + case SCTP_CHUNK_MATCH_ANY:
5907 + case SCTP_CHUNK_MATCH_ONLY:
5911 + /* This will never be reached, but required to stop compiler whine */
5916 +match(const struct sk_buff *skb,
5917 + const struct net_device *in,
5918 + const struct net_device *out,
5919 + const void *matchinfo,
5923 + const struct ipt_sctp_info *info;
5924 + sctp_sctphdr_t sh;
5926 + info = (const struct ipt_sctp_info *)matchinfo;
5929 + duprintf("Dropping non-first fragment.. FIXME\n");
5933 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &sh, sizeof(sh)) < 0) {
5934 + duprintf("Dropping evil TCP offset=0 tinygram.\n");
5938 + duprintf("spt: %d\tdpt: %d\n", ntohs(sh.source), ntohs(sh.dest));
5940 + return SCCHECK(((ntohs(sh.source) >= info->spts[0])
5941 + && (ntohs(sh.source) <= info->spts[1])),
5942 + IPT_SCTP_SRC_PORTS, info->flags, info->invflags)
5943 + && SCCHECK(((ntohs(sh.dest) >= info->dpts[0])
5944 + && (ntohs(sh.dest) <= info->dpts[1])),
5945 + IPT_SCTP_DEST_PORTS, info->flags, info->invflags)
5946 + && SCCHECK(match_packet(skb, info->chunkmap, info->chunk_match_type,
5947 + info->flag_info, info->flag_count,
5949 + IPT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
5953 +checkentry(const char *tablename,
5954 + const struct ipt_ip *ip,
5956 + unsigned int matchsize,
5957 + unsigned int hook_mask)
5959 + const struct ipt_sctp_info *info;
5961 + info = (const struct ipt_sctp_info *)matchinfo;
5963 + return ip->proto == IPPROTO_SCTP
5964 + && !(ip->invflags & IPT_INV_PROTO)
5965 + && matchsize == IPT_ALIGN(sizeof(struct ipt_sctp_info))
5966 + && !(info->flags & ~IPT_SCTP_VALID_FLAGS)
5967 + && !(info->invflags & ~IPT_SCTP_VALID_FLAGS)
5968 + && !(info->invflags & ~info->flags)
5969 + && ((!(info->flags & IPT_SCTP_CHUNK_TYPES)) ||
5970 + (info->chunk_match_type &
5971 + (SCTP_CHUNK_MATCH_ALL
5972 + | SCTP_CHUNK_MATCH_ANY
5973 + | SCTP_CHUNK_MATCH_ONLY)));
5976 +static struct ipt_match sctp_match =
5978 + .list = { NULL, NULL},
5981 + .checkentry = &checkentry,
5986 +static int __init init(void)
5988 + return ipt_register_match(&sctp_match);
5991 +static void __exit fini(void)
5993 + ipt_unregister_match(&sctp_match);
5999 +MODULE_LICENSE("GPL");
6000 +MODULE_AUTHOR("Kiran Kumar Immidi");
6001 +MODULE_DESCRIPTION("Match for SCTP protocol packets");
6003 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_string.c linux-2.6.7/net/ipv4/netfilter/ipt_string.c
6004 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_string.c 1970-01-01 01:00:00.000000000 +0100
6005 +++ linux-2.6.7/net/ipv4/netfilter/ipt_string.c 2004-06-29 12:36:14.591166792 +0200
6007 +/* Kernel module to match a string into a packet.
6009 + * Copyright (C) 2000 Emmanuel Roger <winfield@freegates.be>
6012 + * 24.03.2004: Eric Lauriault <elauri@lacitec.on.ca>
6013 + * Initial 2.6 port
6014 + * 19.02.2002: Gianni Tedesco <gianni@ecsc.co.uk>
6015 + * Fixed SMP re-entrancy problem using per-cpu data areas
6016 + * for the skip/shift tables.
6017 + * 02.05.2001: Gianni Tedesco <gianni@ecsc.co.uk>
6018 + * Fixed kernel panic, due to overrunning boyer moore string
6019 + * tables. Also slightly tweaked heuristic for deciding what
6020 + * search algo to use.
6021 + * 27.01.2001: Gianni Tedesco <gianni@ecsc.co.uk>
6022 + * Implemented Boyer Moore Sublinear search algorithm
6023 + * alongside the existing linear search based on memcmp().
6024 + * Also a quick check to decide which method to use on a per
6028 +#include <linux/smp.h>
6029 +#include <linux/percpu.h>
6030 +#include <linux/module.h>
6031 +#include <linux/skbuff.h>
6032 +#include <linux/file.h>
6033 +#include <net/sock.h>
6035 +#include <linux/netfilter_ipv4/ip_tables.h>
6036 +#include <linux/netfilter_ipv4/ipt_string.h>
6038 +MODULE_LICENSE("GPL");
6040 +struct string_per_cpu {
6041 + int skip[BM_MAX_HLEN];
6042 + int shift[BM_MAX_HLEN];
6043 + int len[BM_MAX_HLEN];
6046 +static DEFINE_PER_CPU(struct string_per_cpu, bm_string_data);
6049 +/* Boyer Moore Sublinear string search - VERY FAST */
6050 +char *search_sublinear (char *needle, char *haystack, int needle_len, int haystack_len)
6052 + int M1, right_end, sk, sh;
6055 + int *skip, *shift, *len;
6057 + /* use data suitable for this CPU */
6058 + shift=__get_cpu_var(bm_string_data).shift;
6059 + skip=__get_cpu_var(bm_string_data).skip;
6060 + len=__get_cpu_var(bm_string_data).len;
6062 + /* Setup skip/shift tables */
6063 + M1 = right_end = needle_len-1;
6064 + for (i = 0; i < BM_MAX_HLEN; i++) skip[i] = needle_len;
6065 + for (i = 0; needle[i]; i++) skip[(int)needle[i]] = M1 - i;
6067 + for (i = 1; i < needle_len; i++) {
6068 + for (j = 0; j < needle_len && needle[M1 - j] == needle[M1 - i - j]; j++);
6073 + for (i = 1; i < needle_len; i++) shift[i] = needle_len;
6074 + for (i = M1; i > 0; i--) shift[len[i]] = i;
6077 + for (i = 0; i < needle_len; i++) {
6078 + if (len[i] == M1 - i) ended = i;
6079 + if (ended) shift[i] = ended;
6082 + /* Do the search*/
6083 + while (right_end < haystack_len)
6085 + for (i = 0; i < needle_len && haystack[right_end - i] == needle[M1 - i]; i++);
6086 + if (i == needle_len) {
6087 + return haystack+(right_end - M1);
6090 + sk = skip[(int)haystack[right_end - i]];
6092 + right_end = max(right_end - i + sk, right_end + sh);
6098 +/* Linear string search based on memcmp() */
6099 +char *search_linear (char *needle, char *haystack, int needle_len, int haystack_len)
6101 + char *k = haystack + (haystack_len-needle_len);
6102 + char *t = haystack;
6104 + while ( t <= k ) {
6105 + if (memcmp(t, needle, needle_len) == 0)
6114 +match(const struct sk_buff *skb,
6115 + const struct net_device *in,
6116 + const struct net_device *out,
6117 + const void *matchinfo,
6121 + const struct ipt_string_info *info = matchinfo;
6122 + struct iphdr *ip = skb->nh.iph;
6124 + char *needle, *haystack;
6125 + proc_ipt_search search=search_linear;
6127 + if ( !ip ) return 0;
6129 + /* get lenghts, and validate them */
6131 + hlen=ntohs(ip->tot_len)-(ip->ihl*4);
6132 + if ( nlen > hlen ) return 0;
6134 + needle=(char *)&info->string;
6135 + haystack=(char *)ip+(ip->ihl*4);
6137 + /* The sublinear search comes in to its own
6138 + * on the larger packets */
6139 + if ( (hlen>IPT_STRING_HAYSTACK_THRESH) &&
6140 + (nlen>IPT_STRING_NEEDLE_THRESH) ) {
6141 + if ( hlen < BM_MAX_HLEN ) {
6142 + search=search_sublinear;
6144 + if (net_ratelimit())
6145 + printk(KERN_INFO "ipt_string: Packet too big "
6146 + "to attempt sublinear string search "
6147 + "(%d bytes)\n", hlen );
6151 + return ((search(needle, haystack, nlen, hlen)!=NULL) ^ info->invert);
6155 +checkentry(const char *tablename,
6156 + const struct ipt_ip *ip,
6158 + unsigned int matchsize,
6159 + unsigned int hook_mask)
6162 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_string_info)))
6168 +static struct ipt_match string_match = {
6171 + .checkentry = &checkentry,
6176 +static int __init init(void)
6178 + return ipt_register_match(&string_match);
6181 +static void __exit fini(void)
6183 + ipt_unregister_match(&string_match);
6190 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_time.c linux-2.6.7/net/ipv4/netfilter/ipt_time.c
6191 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_time.c 1970-01-01 01:00:00.000000000 +0100
6192 +++ linux-2.6.7/net/ipv4/netfilter/ipt_time.c 2004-06-29 12:32:41.027633384 +0200
6195 + This is a module which is used for time matching
6196 + It is using some modified code from dietlibc (localtime() function)
6197 + that you can find at http://www.fefe.de/dietlibc/
6198 + This file is distributed under the terms of the GNU General Public
6199 + License (GPL). Copies of the GPL can be obtained from: ftp://prep.ai.mit.edu/pub/gnu/GPL
6200 + 2001-05-04 Fabrice MARIE <fabrice@netfilter.org> : initial development.
6201 + 2001-21-05 Fabrice MARIE <fabrice@netfilter.org> : bug fix in the match code,
6202 + thanks to "Zeng Yu" <zengy@capitel.com.cn> for bug report.
6203 + 2001-26-09 Fabrice MARIE <fabrice@netfilter.org> : force the match to be in LOCAL_IN or PRE_ROUTING only.
6204 + 2001-30-11 Fabrice : added the possibility to use the match in FORWARD/OUTPUT with a little hack,
6205 + added Nguyen Dang Phuoc Dong <dongnd@tlnet.com.vn> patch to support timezones.
6206 + 2004-05-02 Fabrice : added support for date matching, from an idea of Fabien COELHO.
6209 +#include <linux/module.h>
6210 +#include <linux/skbuff.h>
6211 +#include <linux/netfilter_ipv4/ip_tables.h>
6212 +#include <linux/netfilter_ipv4/ipt_time.h>
6213 +#include <linux/time.h>
6215 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
6216 +MODULE_DESCRIPTION("Match arrival timestamp/date");
6217 +MODULE_LICENSE("GPL");
6221 + int tm_sec; /* Seconds. [0-60] (1 leap second) */
6222 + int tm_min; /* Minutes. [0-59] */
6223 + int tm_hour; /* Hours. [0-23] */
6224 + int tm_mday; /* Day. [1-31] */
6225 + int tm_mon; /* Month. [0-11] */
6226 + int tm_year; /* Year - 1900. */
6227 + int tm_wday; /* Day of week. [0-6] */
6228 + int tm_yday; /* Days in year.[0-365] */
6229 + int tm_isdst; /* DST. [-1/0/1]*/
6231 + long int tm_gmtoff; /* we don't care, we count from GMT */
6232 + const char *tm_zone; /* we don't care, we count from GMT */
6236 +localtime(const time_t *timepr, struct tm *r);
6239 +match(const struct sk_buff *skb,
6240 + const struct net_device *in,
6241 + const struct net_device *out,
6242 + const void *matchinfo,
6245 + u_int16_t datalen,
6248 + const struct ipt_time_info *info = matchinfo; /* match info for rule */
6249 + struct tm currenttime; /* time human readable */
6250 + u_int8_t days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
6251 + u_int16_t packet_time;
6252 + struct timeval kerneltimeval;
6253 + time_t packet_local_time;
6255 + /* if kerneltime=1, we don't read the skb->timestamp but kernel time instead */
6256 + if (info->kerneltime)
6258 + do_gettimeofday(&kerneltimeval);
6259 + packet_local_time = kerneltimeval.tv_sec;
6262 + packet_local_time = skb->stamp.tv_sec;
6264 + /* First we make sure we are in the date start-stop boundaries */
6265 + if ((packet_local_time < info->date_start) || (packet_local_time > info->date_stop))
6266 + return 0; /* We are outside the date boundaries */
6268 + /* Transform the timestamp of the packet, in a human readable form */
6269 + localtime(&packet_local_time, ¤ttime);
6271 + /* check if we match this timestamp, we start by the days... */
6272 + if ((days_of_week[currenttime.tm_wday] & info->days_match) != days_of_week[currenttime.tm_wday])
6273 + return 0; /* the day doesn't match */
6275 + /* ... check the time now */
6276 + packet_time = (currenttime.tm_hour * 60) + currenttime.tm_min;
6277 + if ((packet_time < info->time_start) || (packet_time > info->time_stop))
6280 + /* here we match ! */
6285 +checkentry(const char *tablename,
6286 + const struct ipt_ip *ip,
6288 + unsigned int matchsize,
6289 + unsigned int hook_mask)
6291 + struct ipt_time_info *info = matchinfo; /* match info for rule */
6293 + /* First, check that we are in the correct hooks */
6295 + & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
6297 + printk("ipt_time: error, only valid for PRE_ROUTING, LOCAL_IN, FORWARD and OUTPUT)\n");
6300 + /* we use the kerneltime if we are in forward or output */
6301 + info->kerneltime = 1;
6302 + if (hook_mask & ~((1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
6303 + /* we use the skb time */
6304 + info->kerneltime = 0;
6306 + /* Check the size */
6307 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_time_info)))
6309 + /* Now check the coherence of the data ... */
6310 + if ((info->time_start > 1439) || /* 23*60+59 = 1439*/
6311 + (info->time_stop > 1439))
6313 + printk(KERN_WARNING "ipt_time: invalid argument\n");
6320 +static struct ipt_match time_match
6321 += { { NULL, NULL }, "time", &match, &checkentry, NULL, THIS_MODULE };
6323 +static int __init init(void)
6325 + printk("ipt_time loading\n");
6326 + return ipt_register_match(&time_match);
6329 +static void __exit fini(void)
6331 + ipt_unregister_match(&time_match);
6332 + printk("ipt_time unloaded\n");
6339 +/* The part below is borowed and modified from dietlibc */
6341 +/* seconds per day */
6342 +#define SPD 24*60*60
6345 +localtime(const time_t *timepr, struct tm *r) {
6348 + extern struct timezone sys_tz;
6349 + const unsigned int __spm[12] =
6356 + (31+28+31+30+31+30),
6357 + (31+28+31+30+31+30+31),
6358 + (31+28+31+30+31+30+31+31),
6359 + (31+28+31+30+31+30+31+31+30),
6360 + (31+28+31+30+31+30+31+31+30+31),
6361 + (31+28+31+30+31+30+31+31+30+31+30),
6363 + register time_t work;
6365 + timep = (*timepr) - (sys_tz.tz_minuteswest * 60);
6367 + r->tm_sec=work%60; work/=60;
6368 + r->tm_min=work%60; r->tm_hour=work/60;
6370 + r->tm_wday=(4+work)%7;
6371 + for (i=1970; ; ++i) {
6372 + register time_t k= (!(i%4) && ((i%100) || !(i%400)))?366:365;
6378 + r->tm_year=i-1900;
6379 + for (i=11; i && __spm[i]>work; --i) ;
6381 + r->tm_mday=work-__spm[i]+1;
6383 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/ipt_unclean.c linux-2.6.7/net/ipv4/netfilter/ipt_unclean.c
6384 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_unclean.c 1970-01-01 01:00:00.000000000 +0100
6385 +++ linux-2.6.7/net/ipv4/netfilter/ipt_unclean.c 2004-06-29 12:36:11.004712016 +0200
6387 +/* Kernel module to match suspect packets. */
6388 +#include <linux/module.h>
6389 +#include <linux/skbuff.h>
6390 +#include <net/ip.h>
6391 +#include <linux/udp.h>
6392 +#include <linux/tcp.h>
6393 +#include <linux/icmp.h>
6394 +#include <net/checksum.h>
6396 +#include <linux/netfilter_ipv4/ip_tables.h>
6398 +#define limpk(format, args...) \
6400 + if (net_ratelimit()) \
6401 + printk("ipt_unclean: %s" format, \
6402 + embedded ? "(embedded packet) " : "" , ## args); \
6405 +enum icmp_error_status
6407 + ICMP_MAY_BE_ERROR,
6414 + size_t min_len, max_len;
6415 + enum icmp_error_status err;
6416 + u_int8_t min_code, max_code;
6420 +check_ip(struct iphdr *iph, size_t length, int embedded);
6422 +/* ICMP-specific checks. */
6424 +check_icmp(const struct icmphdr *icmph,
6425 + u_int16_t datalen,
6426 + unsigned int offset,
6430 + static struct icmp_info info[]
6431 + = { [ICMP_ECHOREPLY]
6432 + = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
6433 + [ICMP_DEST_UNREACH]
6434 + = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 15 },
6435 + [ICMP_SOURCE_QUENCH]
6436 + = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 0 },
6438 + = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 3 },
6440 + = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
6441 + /* Router advertisement. */
6443 + = { 8, 8 + 255 * 8, ICMP_NOT_ERROR, 0, 0 },
6444 + /* Router solicitation. */
6446 + = { 8, 8, ICMP_NOT_ERROR, 0, 0 },
6447 + [ICMP_TIME_EXCEEDED]
6448 + = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 1 },
6449 + [ICMP_PARAMETERPROB]
6450 + = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 1 },
6452 + = { 20, 20, ICMP_NOT_ERROR, 0, 0 },
6453 + [ICMP_TIMESTAMPREPLY]
6454 + = { 20, 20, ICMP_NOT_ERROR, 0, 0 },
6455 + [ICMP_INFO_REQUEST]
6456 + = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
6458 + = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
6460 + = { 12, 12, ICMP_NOT_ERROR, 0, 0 },
6461 + [ICMP_ADDRESSREPLY]
6462 + = { 12, 12, ICMP_NOT_ERROR, 0, 0 } };
6464 + /* Can't do anything if it's a fragment. */
6468 + /* Must cover type and code. */
6469 + if (datalen < 2) {
6470 + limpk("ICMP len=%u too short\n", datalen);
6474 + /* If not embedded. */
6476 + /* Bad checksum? Don't print, just ignore. */
6478 + && ip_compute_csum((unsigned char *) icmph, datalen) != 0)
6481 + /* CHECK: Truncated ICMP (even if first fragment). */
6482 + if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
6483 + && info[icmph->type].min_len != 0
6484 + && datalen < info[icmph->type].min_len) {
6485 + limpk("ICMP type %u len %u too short\n",
6486 + icmph->type, datalen);
6490 + /* CHECK: Check within known error ICMPs. */
6491 + if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
6492 + && info[icmph->type].err == ICMP_IS_ERROR) {
6493 + /* CHECK: Embedded packet must be at least
6494 + length of iph + 8 bytes. */
6495 + struct iphdr *inner = (void *)icmph + 8;
6497 + /* datalen > 8 since all ICMP_IS_ERROR types
6498 + have min length > 8 */
6499 + if (datalen - 8 < sizeof(struct iphdr)) {
6500 + limpk("ICMP error internal way too short\n");
6503 + if (datalen - 8 < inner->ihl*4 + 8) {
6504 + limpk("ICMP error internal too short\n");
6507 + if (!check_ip(inner, datalen - 8, 1))
6511 + /* CHECK: Can't embed ICMP unless known non-error. */
6512 + if (icmph->type >= sizeof(info)/sizeof(struct icmp_info)
6513 + || info[icmph->type].err != ICMP_NOT_ERROR) {
6514 + limpk("ICMP type %u not embeddable\n",
6520 + /* CHECK: Invalid ICMP codes. */
6521 + if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
6522 + && (icmph->code < info[icmph->type].min_code
6523 + || icmph->code > info[icmph->type].max_code)) {
6524 + limpk("ICMP type=%u code=%u\n",
6525 + icmph->type, icmph->code);
6529 + /* CHECK: Above maximum length. */
6530 + if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
6531 + && info[icmph->type].max_len != 0
6532 + && datalen > info[icmph->type].max_len) {
6533 + limpk("ICMP type=%u too long: %u bytes\n",
6534 + icmph->type, datalen);
6538 + switch (icmph->type) {
6539 + case ICMP_PARAMETERPROB: {
6540 + /* CHECK: Problem param must be within error packet's
6542 + struct iphdr *iph = (void *)icmph + 8;
6543 + u_int32_t arg = ntohl(icmph->un.gateway);
6545 + if (icmph->code == 0) {
6546 + /* Code 0 means that upper 8 bits is pointer
6548 + if ((arg >> 24) >= iph->ihl*4) {
6549 + limpk("ICMP PARAMETERPROB ptr = %u\n",
6550 + ntohl(icmph->un.gateway) >> 24);
6553 + arg &= 0x00FFFFFF;
6556 + /* CHECK: Rest must be zero. */
6558 + limpk("ICMP PARAMETERPROB nonzero arg = %u\n",
6565 + case ICMP_TIME_EXCEEDED:
6566 + case ICMP_SOURCE_QUENCH:
6567 + /* CHECK: Unused must be zero. */
6568 + if (icmph->un.gateway != 0) {
6569 + limpk("ICMP type=%u unused = %u\n",
6570 + icmph->type, ntohl(icmph->un.gateway));
6579 +/* UDP-specific checks. */
6581 +check_udp(const struct iphdr *iph,
6582 + const struct udphdr *udph,
6583 + u_int16_t datalen,
6584 + unsigned int offset,
6588 + /* Can't do anything if it's a fragment. */
6592 + /* CHECK: Must cover UDP header. */
6593 + if (datalen < sizeof(struct udphdr)) {
6594 + limpk("UDP len=%u too short\n", datalen);
6598 + /* Bad checksum? Don't print, just say it's unclean. */
6599 + /* FIXME: SRC ROUTE packets won't match checksum --RR */
6600 + if (!more_frags && !embedded && udph->check
6601 + && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_UDP,
6602 + csum_partial((char *)udph, datalen, 0)) != 0)
6605 + /* CHECK: Destination port can't be zero. */
6606 + if (!udph->dest) {
6607 + limpk("UDP zero destination port\n");
6611 + if (!more_frags) {
6613 + /* CHECK: UDP length must match. */
6614 + if (ntohs(udph->len) != datalen) {
6615 + limpk("UDP len too short %u vs %u\n",
6616 + ntohs(udph->len), datalen);
6620 + /* CHECK: UDP length be >= this truncated pkt. */
6621 + if (ntohs(udph->len) < datalen) {
6622 + limpk("UDP len too long %u vs %u\n",
6623 + ntohs(udph->len), datalen);
6628 + /* CHECK: UDP length must be > this frag's length. */
6629 + if (ntohs(udph->len) <= datalen) {
6630 + limpk("UDP fragment len too short %u vs %u\n",
6631 + ntohs(udph->len), datalen);
6639 +#define TH_FIN 0x01
6640 +#define TH_SYN 0x02
6641 +#define TH_RST 0x04
6642 +#define TH_PUSH 0x08
6643 +#define TH_ACK 0x10
6644 +#define TH_URG 0x20
6645 +#define TH_ECE 0x40
6646 +#define TH_CWR 0x80
6648 +/* table of valid flag combinations - ECE and CWR are always valid */
6649 +static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
6652 + [TH_SYN|TH_ACK] = 1,
6654 + [TH_RST|TH_ACK] = 1,
6655 + [TH_RST|TH_ACK|TH_PUSH] = 1,
6656 + [TH_FIN|TH_ACK] = 1,
6658 + [TH_ACK|TH_PUSH] = 1,
6659 + [TH_ACK|TH_URG] = 1,
6660 + [TH_ACK|TH_URG|TH_PUSH] = 1,
6661 + [TH_FIN|TH_ACK|TH_PUSH] = 1,
6662 + [TH_FIN|TH_ACK|TH_URG] = 1,
6663 + [TH_FIN|TH_ACK|TH_URG|TH_PUSH] = 1
6666 +/* TCP-specific checks. */
6668 +check_tcp(const struct iphdr *iph,
6669 + const struct tcphdr *tcph,
6670 + u_int16_t datalen,
6671 + unsigned int offset,
6675 + u_int8_t *opt = (u_int8_t *)tcph;
6676 + u_int8_t *endhdr = (u_int8_t *)tcph + tcph->doff * 4;
6677 + u_int8_t tcpflags;
6678 + int end_of_options = 0;
6681 + /* CHECK: Can't have offset=1: used to override TCP syn-checks. */
6682 + /* In fact, this is caught below (offset < 516). */
6684 + /* Can't do anything if it's a fragment. */
6688 + /* CHECK: Smaller than minimal TCP hdr. */
6689 + if (datalen < sizeof(struct tcphdr)) {
6691 + limpk("Packet length %u < TCP header.\n", datalen);
6694 + /* Must have ports available (datalen >= 8), from
6695 + check_icmp which set embedded = 1 */
6696 + /* CHECK: TCP ports inside ICMP error */
6697 + if (!tcph->source || !tcph->dest) {
6698 + limpk("Zero TCP ports %u/%u.\n",
6699 + htons(tcph->source), htons(tcph->dest));
6705 + /* CHECK: Smaller than actual TCP hdr. */
6706 + if (datalen < tcph->doff * 4) {
6708 + limpk("Packet length %u < actual TCP header.\n",
6715 + /* Bad checksum? Don't print, just say it's unclean. */
6716 + /* FIXME: SRC ROUTE packets won't match checksum --RR */
6717 + if (!more_frags && !embedded
6718 + && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_TCP,
6719 + csum_partial((char *)tcph, datalen, 0)) != 0)
6722 + /* CHECK: TCP ports non-zero */
6723 + if (!tcph->source || !tcph->dest) {
6724 + limpk("Zero TCP ports %u/%u.\n",
6725 + htons(tcph->source), htons(tcph->dest));
6729 + /* CHECK: TCP reserved bits zero. */
6730 + if(tcp_flag_word(tcph) & TCP_RESERVED_BITS) {
6731 + limpk("TCP reserved bits not zero\n");
6735 + /* CHECK: TCP flags. */
6736 + tcpflags = (((u_int8_t *)tcph)[13] & ~(TH_ECE|TH_CWR));
6737 + if (!tcp_valid_flags[tcpflags]) {
6738 + limpk("TCP flags bad: %u\n", tcpflags);
6742 + for (i = sizeof(struct tcphdr); i < tcph->doff * 4; ) {
6745 + end_of_options = 1;
6752 + /* CHECK: options after EOO. */
6753 + if (end_of_options) {
6754 + limpk("TCP option %u after end\n",
6758 + /* CHECK: options at tail. */
6759 + else if (i+1 >= tcph->doff * 4) {
6760 + limpk("TCP option %u at tail\n",
6764 + /* CHECK: zero-length options. */
6765 + else if (opt[i+1] == 0) {
6766 + limpk("TCP option %u 0 len\n",
6770 + /* CHECK: oversize options. */
6771 + else if (&opt[i] + opt[i+1] > endhdr) {
6772 + limpk("TCP option %u at %Zu too long\n",
6773 + (unsigned int) opt[i], i);
6776 + /* Move to next option */
6784 +/* Returns 1 if ok */
6785 +/* Standard IP checks. */
6787 +check_ip(struct iphdr *iph, size_t length, int embedded)
6789 + u_int8_t *opt = (u_int8_t *)iph;
6790 + u_int8_t *endhdr = (u_int8_t *)iph + iph->ihl * 4;
6791 + int end_of_options = 0;
6795 + unsigned int offset;
6797 + /* Should only happen for local outgoing raw-socket packets. */
6798 + /* CHECK: length >= ip header. */
6799 + if (length < sizeof(struct iphdr) || length < iph->ihl * 4) {
6800 + limpk("Packet length %Zu < IP header.\n", length);
6804 + offset = ntohs(iph->frag_off) & IP_OFFSET;
6805 + protoh = (void *)iph + iph->ihl * 4;
6806 + datalen = length - iph->ihl * 4;
6808 + /* CHECK: Embedded fragment. */
6809 + if (embedded && offset) {
6810 + limpk("Embedded fragment.\n");
6814 + for (i = sizeof(struct iphdr); i < iph->ihl * 4; ) {
6817 + end_of_options = 1;
6824 + /* CHECK: options after EOO. */
6825 + if (end_of_options) {
6826 + limpk("IP option %u after end\n",
6830 + /* CHECK: options at tail. */
6831 + else if (i+1 >= iph->ihl * 4) {
6832 + limpk("IP option %u at tail\n",
6836 + /* CHECK: zero-length or one-length options. */
6837 + else if (opt[i+1] < 2) {
6838 + limpk("IP option %u %u len\n",
6839 + opt[i], opt[i+1]);
6842 + /* CHECK: oversize options. */
6843 + else if (&opt[i] + opt[i+1] > endhdr) {
6844 + limpk("IP option %u at %u too long\n",
6848 + /* Move to next option */
6853 + /* Fragment checks. */
6855 + /* CHECK: More fragments, but doesn't fill 8-byte boundary. */
6856 + if ((ntohs(iph->frag_off) & IP_MF)
6857 + && (ntohs(iph->tot_len) % 8) != 0) {
6858 + limpk("Truncated fragment %u long.\n", ntohs(iph->tot_len));
6862 + /* CHECK: Oversize fragment a-la Ping of Death. */
6863 + if (offset * 8 + datalen > 65535) {
6864 + limpk("Oversize fragment to %u.\n", offset * 8);
6868 + /* CHECK: DF set and offset or MF set. */
6869 + if ((ntohs(iph->frag_off) & IP_DF)
6870 + && (offset || (ntohs(iph->frag_off) & IP_MF))) {
6871 + limpk("DF set and offset=%u, MF=%u.\n",
6872 + offset, ntohs(iph->frag_off) & IP_MF);
6876 + /* CHECK: Zero-sized fragments. */
6877 + if ((offset || (ntohs(iph->frag_off) & IP_MF))
6878 + && datalen == 0) {
6879 + limpk("Zero size fragment offset=%u\n", offset);
6883 + /* Note: we can have even middle fragments smaller than this:
6884 + consider a large packet passing through a 600MTU then
6885 + 576MTU link: this gives a fragment of 24 data bytes. But
6886 + everyone packs fragments largest first, hence a fragment
6887 + can't START before 576 - MAX_IP_HEADER_LEN. */
6889 + /* Used to be min-size 576: I recall Alan Cox saying ax25 goes
6890 + down to 128 (576 taken from RFC 791: All hosts must be
6891 + prepared to accept datagrams of up to 576 octets). Use 128
6893 +#define MIN_LIKELY_MTU 128
6894 + /* CHECK: Min size of first frag = 128. */
6895 + if ((ntohs(iph->frag_off) & IP_MF)
6897 + && ntohs(iph->tot_len) < MIN_LIKELY_MTU) {
6898 + limpk("First fragment size %u < %u\n", ntohs(iph->tot_len),
6903 + /* CHECK: Min offset of frag = 128 - IP hdr len. */
6904 + if (offset && offset * 8 < MIN_LIKELY_MTU - iph->ihl * 4) {
6905 + limpk("Fragment starts at %u < %u\n", offset * 8,
6906 + MIN_LIKELY_MTU - iph->ihl * 4);
6910 + /* CHECK: Protocol specification non-zero. */
6911 + if (iph->protocol == 0) {
6912 + limpk("Zero protocol\n");
6916 + /* CHECK: Do not use what is unused.
6917 + * First bit of fragmentation flags should be unused.
6918 + * May be used by OS fingerprinting tools.
6919 + * 04 Jun 2002, Maciej Soltysiak, solt@dns.toxicfilms.tv
6921 + if (ntohs(iph->frag_off)>>15) {
6922 + limpk("IP unused bit set\n");
6926 + /* Per-protocol checks. */
6927 + switch (iph->protocol) {
6928 + case IPPROTO_ICMP:
6929 + return check_icmp(protoh, datalen, offset,
6930 + (ntohs(iph->frag_off) & IP_MF),
6934 + return check_udp(iph, protoh, datalen, offset,
6935 + (ntohs(iph->frag_off) & IP_MF),
6939 + return check_tcp(iph, protoh, datalen, offset,
6940 + (ntohs(iph->frag_off) & IP_MF),
6943 + /* Ignorance is bliss. */
6949 +match(const struct sk_buff *skb,
6950 + const struct net_device *in,
6951 + const struct net_device *out,
6952 + const void *matchinfo,
6955 + u_int16_t datalen,
6958 + return !check_ip(skb->nh.iph, skb->len, 0);
6961 +/* Called when user tries to insert an entry of this type. */
6963 +checkentry(const char *tablename,
6964 + const struct ipt_ip *ip,
6966 + unsigned int matchsize,
6967 + unsigned int hook_mask)
6969 + if (matchsize != IPT_ALIGN(0))
6975 +static struct ipt_match unclean_match
6976 += { { NULL, NULL }, "unclean", &match, &checkentry, NULL, THIS_MODULE };
6978 +static int __init init(void)
6980 + return ipt_register_match(&unclean_match);
6983 +static void __exit fini(void)
6985 + ipt_unregister_match(&unclean_match);
6990 +MODULE_LICENSE("GPL");
6991 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/tcp_ipv4.c linux-2.6.7/net/ipv4/tcp_ipv4.c
6992 --- linux-2.6.7.org/net/ipv4/tcp_ipv4.c 2004-06-29 12:24:14.000000000 +0200
6993 +++ linux-2.6.7/net/ipv4/tcp_ipv4.c 2004-06-29 12:35:34.503261080 +0200
6994 @@ -2642,6 +2642,7 @@
6995 EXPORT_SYMBOL(tcp_v4_connect);
6996 EXPORT_SYMBOL(tcp_v4_do_rcv);
6997 EXPORT_SYMBOL(tcp_v4_lookup_listener);
6998 +EXPORT_SYMBOL(tcp_v4_lookup);
6999 EXPORT_SYMBOL(tcp_v4_rebuild_header);
7000 EXPORT_SYMBOL(tcp_v4_remember_stamp);
7001 EXPORT_SYMBOL(tcp_v4_send_check);
7002 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/udp.c linux-2.6.7/net/ipv4/udp.c
7003 --- linux-2.6.7.org/net/ipv4/udp.c 2004-06-29 12:24:14.000000000 +0200
7004 +++ linux-2.6.7/net/ipv4/udp.c 2004-06-29 12:35:34.509260168 +0200
7005 @@ -1560,6 +1560,7 @@
7006 EXPORT_SYMBOL(udp_port_rover);
7007 EXPORT_SYMBOL(udp_prot);
7008 EXPORT_SYMBOL(udp_sendmsg);
7009 +EXPORT_SYMBOL(udp_v4_lookup);
7011 #ifdef CONFIG_PROC_FS
7012 EXPORT_SYMBOL(udp_proc_register);
7013 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv6/netfilter/Kconfig linux-2.6.7/net/ipv6/netfilter/Kconfig
7014 --- linux-2.6.7.org/net/ipv6/netfilter/Kconfig 2004-06-16 07:19:52.000000000 +0200
7015 +++ linux-2.6.7/net/ipv6/netfilter/Kconfig 2004-06-29 12:35:40.081413072 +0200
7016 @@ -230,5 +230,83 @@
7017 <file:Documentation/modules.txt>. If unsure, say `N'.
7020 +config IP6_NF_TARGET_HL
7021 + tristate 'HL target support'
7022 + depends on IP6_NF_MANGLE
7024 + This option adds a `HL' target, which allows you to modify the value of
7025 + IPv6 Hop Limit field.
7027 + If you want to compile it as a module, say M here and read
7028 + <file:Documentation/modules.txt>. If unsure, say `N'.
7030 +config IP6_NF_TARGET_REJECT
7031 + tristate 'REJECT target support'
7032 + depends on IP6_NF_FILTER
7034 + The REJECT target allows a filtering rule to specify that an ICMPv6
7035 + error should be issued in response to an incoming packet, rather
7036 + than silently being dropped.
7038 + If you want to compile it as a module, say M here and read
7039 + Documentation/modules.txt. If unsure, say `N'.
7041 +config IP6_NF_MATCH_FUZZY
7042 + tristate 'Fuzzy match support'
7043 + depends on IP6_NF_FILTER
7045 + This option adds a `fuzzy' match, which allows you to match
7046 + packets according to a fuzzy logic based law.
7048 + If you want to compile it as a module, say M here and read
7049 + Documentation/modules.txt. If unsure, say `N'.
7051 +config IP6_NF_MATCH_NTH
7052 + tristate 'Nth match support'
7053 + depends on IP6_NF_IPTABLES
7055 + This option adds a `Nth' match, which allow you to make
7056 + rules that match every Nth packet. By default there are
7057 + 16 different counters.
7060 + --every Nth Match every Nth packet
7061 + [--counter] num Use counter 0-15 (default:0)
7062 + [--start] num Initialize the counter at the number 'num'
7063 + instead of 0. Must be between 0 and Nth-1
7064 + [--packet] num Match on 'num' packet. Must be between 0
7067 + If --packet is used for a counter than
7068 + there must be Nth number of --packet
7069 + rules, covering all values between 0 and
7070 + Nth-1 inclusively.
7072 + If you want to compile it as a module, say M here and read
7073 + Documentation/modules.txt. If unsure, say `N'.
7075 +config IP6_NF_TARGET_ROUTE
7076 + tristate ' ROUTE target support'
7077 + depends on IP6_NF_MANGLE
7079 + This option adds a `ROUTE' target, which enables you to setup unusual
7080 + routes. The ROUTE target is also able to change the incoming interface
7083 + The target can be or not a final target. It has to be used inside the
7086 + Not working as a module.
7088 +config IP6_NF_MATCH_POLICY
7089 + tristate "IPsec policy match support"
7090 + depends on IP6_NF_IPTABLES && XFRM
7092 + Policy matching allows you to match packets based on the
7093 + IPsec policy that was used during decapsulation/will
7094 + be used during encapsulation.
7096 + To compile it as a module, choose M here. If unsure, say N.
7100 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv6/netfilter/Makefile linux-2.6.7/net/ipv6/netfilter/Makefile
7101 --- linux-2.6.7.org/net/ipv6/netfilter/Makefile 2004-06-16 07:19:36.000000000 +0200
7102 +++ linux-2.6.7/net/ipv6/netfilter/Makefile 2004-06-29 12:35:40.083412768 +0200
7104 obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
7105 obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
7106 obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
7107 +obj-$(CONFIG_IP6_NF_MATCH_FUZZY) += ip6t_fuzzy.o
7108 obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
7109 obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
7110 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
7111 obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o
7112 obj-$(CONFIG_IP6_NF_MATCH_AHESP) += ip6t_esp.o ip6t_ah.o
7113 +obj-$(CONFIG_IP6_NF_MATCH_POLICY) += ip6t_policy.o
7114 obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o
7115 obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o
7116 obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
7117 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
7118 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
7119 obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
7120 +obj-$(CONFIG_IP6_NF_TARGET_ROUTE) += ip6t_ROUTE.o
7121 +obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
7122 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
7123 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
7125 +obj-$(CONFIG_IP6_NF_MATCH_NTH) += ip6t_nth.o
7126 +obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
7127 obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
7128 obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
7129 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv6/netfilter/ip6t_HL.c linux-2.6.7/net/ipv6/netfilter/ip6t_HL.c
7130 --- linux-2.6.7.org/net/ipv6/netfilter/ip6t_HL.c 1970-01-01 01:00:00.000000000 +0100
7131 +++ linux-2.6.7/net/ipv6/netfilter/ip6t_HL.c 2004-06-29 12:31:59.778904144 +0200
7134 + * Hop Limit modification target for ip6tables
7135 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
7136 + * Based on HW's TTL module
7138 + * This software is distributed under the terms of GNU GPL
7141 +#include <linux/module.h>
7142 +#include <linux/skbuff.h>
7143 +#include <linux/ip.h>
7145 +#include <linux/netfilter_ipv6/ip6_tables.h>
7146 +#include <linux/netfilter_ipv6/ip6t_HL.h>
7148 +MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
7149 +MODULE_DESCRIPTION("IP tables Hop Limit modification module");
7150 +MODULE_LICENSE("GPL");
7152 +static unsigned int ip6t_hl_target(struct sk_buff **pskb, unsigned int hooknum,
7153 + const struct net_device *in, const struct net_device *out,
7154 + const void *targinfo, void *userinfo)
7156 + struct ipv6hdr *ip6h = (*pskb)->nh.ipv6h;
7157 + const struct ip6t_HL_info *info = targinfo;
7158 + u_int16_t diffs[2];
7161 + switch (info->mode) {
7163 + new_hl = info->hop_limit;
7166 + new_hl = ip6h->hop_limit + info->hop_limit;
7171 + new_hl = ip6h->hop_limit + info->hop_limit;
7176 + new_hl = ip6h->hop_limit;
7180 + if (new_hl != ip6h->hop_limit) {
7181 + diffs[0] = htons(((unsigned)ip6h->hop_limit) << 8) ^ 0xFFFF;
7182 + ip6h->hop_limit = new_hl;
7183 + diffs[1] = htons(((unsigned)ip6h->hop_limit) << 8);
7186 + return IP6T_CONTINUE;
7189 +static int ip6t_hl_checkentry(const char *tablename,
7190 + const struct ip6t_entry *e,
7192 + unsigned int targinfosize,
7193 + unsigned int hook_mask)
7195 + struct ip6t_HL_info *info = targinfo;
7197 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_HL_info))) {
7198 + printk(KERN_WARNING "HL: targinfosize %u != %Zu\n",
7200 + IP6T_ALIGN(sizeof(struct ip6t_HL_info)));
7204 + if (strcmp(tablename, "mangle")) {
7205 + printk(KERN_WARNING "HL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
7209 + if (info->mode > IP6T_HL_MAXMODE) {
7210 + printk(KERN_WARNING "HL: invalid or unknown Mode %u\n",
7215 + if ((info->mode != IP6T_HL_SET) && (info->hop_limit == 0)) {
7216 + printk(KERN_WARNING "HL: increment/decrement doesn't make sense with value 0\n");
7223 +static struct ip6t_target ip6t_HL = { { NULL, NULL }, "HL",
7224 + ip6t_hl_target, ip6t_hl_checkentry, NULL, THIS_MODULE };
7226 +static int __init init(void)
7228 + return ip6t_register_target(&ip6t_HL);
7231 +static void __exit fini(void)
7233 + ip6t_unregister_target(&ip6t_HL);
7238 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv6/netfilter/ip6t_REJECT.c linux-2.6.7/net/ipv6/netfilter/ip6t_REJECT.c
7239 --- linux-2.6.7.org/net/ipv6/netfilter/ip6t_REJECT.c 1970-01-01 01:00:00.000000000 +0100
7240 +++ linux-2.6.7/net/ipv6/netfilter/ip6t_REJECT.c 2004-06-29 12:32:02.720456960 +0200
7243 + * IP6 tables REJECT target module
7244 + * Linux INET6 implementation
7246 + * Copyright (C)2003 USAGI/WIDE Project
7249 + * Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
7251 + * Based on net/ipv4/netfilter/ipt_REJECT.c
7253 + * This program is free software; you can redistribute it and/or
7254 + * modify it under the terms of the GNU General Public License
7255 + * as published by the Free Software Foundation; either version
7256 + * 2 of the License, or (at your option) any later version.
7259 +#include <linux/config.h>
7260 +#include <linux/module.h>
7261 +#include <linux/skbuff.h>
7262 +#include <linux/icmpv6.h>
7263 +#include <net/ipv6.h>
7264 +#include <net/tcp.h>
7265 +#include <net/icmp.h>
7266 +#include <net/ip6_fib.h>
7267 +#include <net/ip6_route.h>
7268 +#include <net/flow.h>
7269 +#include <linux/netfilter_ipv6/ip6_tables.h>
7270 +#include <linux/netfilter_ipv6/ip6t_REJECT.h>
7272 +MODULE_AUTHOR("Yasuyuki KOZAKAI <yasuyuki.kozakai@toshiba.co.jp>");
7273 +MODULE_DESCRIPTION("IP6 tables REJECT target module");
7274 +MODULE_LICENSE("GPL");
7277 +#define DEBUGP printk
7279 +#define DEBUGP(format, args...)
7283 +static void connection_attach(struct sk_buff *new_skb, struct nf_ct_info *nfct)
7285 + void (*attach)(struct sk_buff *, struct nf_ct_info *);
7286 + if (nfct && (attach = ip6_ct_attach) != NULL) {
7288 + attach(new_skb, nfct);
7293 +static int maybe_reroute(struct sk_buff *skb)
7295 + if (skb->nfcache & NFC_ALTERED){
7296 + if (ip6_route_me_harder(skb) != 0){
7302 + return dst_output(skb);
7305 +/* Send RST reply */
7306 +static void send_reset(struct sk_buff *oldskb)
7308 + struct sk_buff *nskb;
7309 + struct tcphdr otcph, *tcph;
7310 + unsigned int otcplen, tcphoff, hh_len;
7312 + struct ipv6hdr *oip6h = oldskb->nh.ipv6h, *ip6h;
7313 + struct dst_entry *dst = NULL;
7316 + proto = oip6h->nexthdr;
7319 + if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) ||
7320 + (!(ipv6_addr_type(&oip6h->daddr) & IPV6_ADDR_UNICAST))) {
7321 + DEBUGP("ip6t_REJECT: addr is not unicast.\n");
7325 + tcphoff = ipv6_skip_exthdr(oldskb, ((u8*)(oip6h+1) - oldskb->data),
7326 + &proto, oldskb->len - ((u8*)(oip6h+1)
7329 + if ((tcphoff < 0) || (tcphoff > oldskb->len)) {
7330 + DEBUGP("ip6t_REJECT: Can't get TCP header.\n");
7334 + otcplen = oldskb->len - tcphoff;
7336 + /* IP header checks: fragment, too short. */
7337 + if ((proto != IPPROTO_TCP) || (otcplen < sizeof(struct tcphdr))) {
7338 + DEBUGP("ip6t_REJECT: proto(%d) != IPPROTO_TCP, or too short. otcplen = %d\n",
7343 + if (skb_copy_bits(oldskb, tcphoff, &otcph, sizeof(struct tcphdr))) {
7344 + if (net_ratelimit())
7345 + printk("ip6t_REJECT: Can't copy tcp header\n");
7349 + /* No RST for RST. */
7351 + DEBUGP("ip6t_REJECT: RST is set\n");
7355 + /* Check checksum. */
7356 + if (csum_ipv6_magic(&oip6h->saddr, &oip6h->daddr, otcplen, IPPROTO_TCP,
7357 + skb_checksum(oldskb, tcphoff, otcplen, 0))) {
7358 + DEBUGP("ip6t_REJECT: TCP checksum is invalid\n");
7362 + memset(&fl, 0, sizeof(fl));
7363 + fl.proto = IPPROTO_TCP;
7364 + ipv6_addr_copy(&fl.fl6_src, &oip6h->daddr);
7365 + ipv6_addr_copy(&fl.fl6_dst, &oip6h->saddr);
7366 + fl.fl_ip_sport = otcph.dest;
7367 + fl.fl_ip_dport = otcph.source;
7368 + err = ip6_dst_lookup(NULL, &dst, &fl);
7370 + if (net_ratelimit())
7371 + printk("ip6t_REJECT: can't find dst. err = %d\n", err);
7375 + hh_len = (dst->dev->hard_header_len + 15)&~15;
7376 + nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr)
7377 + + sizeof(struct tcphdr) + dst->trailer_len,
7381 + if (net_ratelimit())
7382 + printk("ip6t_REJECT: Can't alloc skb\n");
7390 + skb_reserve(nskb, hh_len + dst->header_len);
7392 + ip6h = nskb->nh.ipv6h = (struct ipv6hdr *)
7393 + skb_put(nskb, sizeof(struct ipv6hdr));
7394 + ip6h->version = 6;
7395 + ip6h->hop_limit = dst_metric(dst, RTAX_HOPLIMIT);
7396 + ip6h->nexthdr = IPPROTO_TCP;
7397 + ip6h->payload_len = htons(sizeof(struct tcphdr));
7398 + ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr);
7399 + ipv6_addr_copy(&ip6h->daddr, &oip6h->saddr);
7401 + tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
7402 + /* Truncate to length (no data) */
7403 + tcph->doff = sizeof(struct tcphdr)/4;
7404 + tcph->source = otcph.dest;
7405 + tcph->dest = otcph.source;
7409 + tcph->seq = otcph.ack_seq;
7410 + tcph->ack_seq = 0;
7413 + tcph->ack_seq = htonl(ntohl(otcph.seq) + otcph.syn + otcph.fin
7414 + + otcplen - (otcph.doff<<2));
7419 + ((u_int8_t *)tcph)[13] = 0;
7421 + tcph->ack = needs_ack;
7423 + tcph->urg_ptr = 0;
7426 + /* Adjust TCP checksum */
7427 + tcph->check = csum_ipv6_magic(&nskb->nh.ipv6h->saddr,
7428 + &nskb->nh.ipv6h->daddr,
7429 + sizeof(struct tcphdr), IPPROTO_TCP,
7430 + csum_partial((char *)tcph,
7431 + sizeof(struct tcphdr), 0));
7434 + connection_attach(nskb, oldskb->nfct);
7437 + NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
7443 +static void send_unreach(struct sk_buff *skb_in, unsigned char code)
7445 + struct ipv6hdr *ip6h, *hdr = skb_in->nh.ipv6h;
7446 + struct icmp6hdr *icmp6h;
7447 + struct dst_entry *dst = NULL;
7448 + struct rt6_info *rt;
7451 + unsigned int len, datalen, hh_len;
7452 + int saddr_type, daddr_type;
7453 + unsigned int ptr, ip6off;
7456 + struct sk_buff *nskb;
7459 + saddr_type = ipv6_addr_type(&hdr->saddr);
7460 + daddr_type = ipv6_addr_type(&hdr->daddr);
7462 + if ((!(saddr_type & IPV6_ADDR_UNICAST)) ||
7463 + (!(daddr_type & IPV6_ADDR_UNICAST))) {
7464 + DEBUGP("ip6t_REJECT: addr is not unicast.\n");
7468 + ip6off = skb_in->nh.raw - skb_in->data;
7469 + proto = hdr->nexthdr;
7470 + ptr = ipv6_skip_exthdr(skb_in, ip6off + sizeof(struct ipv6hdr), &proto,
7471 + skb_in->len - ip6off);
7473 + if ((ptr < 0) || (ptr > skb_in->len)) {
7474 + ptr = ip6off + sizeof(struct ipv6hdr);
7475 + proto = hdr->nexthdr;
7476 + } else if (proto == IPPROTO_ICMPV6) {
7479 + if (skb_copy_bits(skb_in, ptr + offsetof(struct icmp6hdr,
7480 + icmp6_type), &type, 1)) {
7481 + DEBUGP("ip6t_REJECT: Can't get ICMPv6 type\n");
7485 + if (!(type & ICMPV6_INFOMSG_MASK)) {
7486 + DEBUGP("ip6t_REJECT: no reply to icmp error\n");
7489 + } else if (proto == IPPROTO_UDP) {
7490 + int plen = skb_in->len - (ptr - ip6off);
7493 + if (plen < sizeof(struct udphdr)) {
7494 + DEBUGP("ip6t_REJECT: too short\n");
7498 + if (skb_copy_bits(skb_in, ptr + offsetof(struct udphdr, check),
7500 + if (net_ratelimit())
7501 + printk("ip6t_REJECT: can't get copy from skb");
7506 + csum_ipv6_magic(&hdr->saddr, &hdr->daddr, plen,
7508 + skb_checksum(skb_in, ptr, plen, 0))) {
7509 + DEBUGP("ip6t_REJECT: UDP checksum is invalid.\n");
7514 + memset(&fl, 0, sizeof(fl));
7515 + fl.proto = IPPROTO_ICMPV6;
7516 + ipv6_addr_copy(&fl.fl6_src, &hdr->daddr);
7517 + ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr);
7518 + fl.fl_icmp_type = ICMPV6_DEST_UNREACH;
7519 + fl.fl_icmp_code = code;
7521 + if (ip6_dst_lookup(NULL, &dst, &fl)) {
7525 + rt = (struct rt6_info *)dst;
7528 + if (rt->rt6i_dst.plen < 128)
7529 + tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
7531 + if (!xrlim_allow(dst, tmo)) {
7532 + if (net_ratelimit())
7533 + printk("ip6t_REJECT: rate limitted\n");
7534 + goto dst_release_out;
7537 + len = skb_in->len + sizeof(struct ipv6hdr) + sizeof(struct icmp6hdr);
7539 + if (len > dst_pmtu(dst))
7540 + len = dst_pmtu(dst);
7541 + if (len > IPV6_MIN_MTU)
7542 + len = IPV6_MIN_MTU;
7544 + datalen = len - sizeof(struct ipv6hdr) - sizeof(struct icmp6hdr);
7545 + hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
7547 + nskb = alloc_skb(hh_len + 15 + dst->header_len + dst->trailer_len + len,
7551 + if (net_ratelimit())
7552 + printk("ip6t_REJECT: can't alloc skb\n");
7553 + goto dst_release_out;
7556 + nskb->priority = 0;
7560 + skb_reserve(nskb, hh_len + dst->header_len);
7562 + ip6h = nskb->nh.ipv6h = (struct ipv6hdr *)
7563 + skb_put(nskb, sizeof(struct ipv6hdr));
7564 + ip6h->version = 6;
7565 + ip6h->hop_limit = dst_metric(dst, RTAX_HOPLIMIT);
7566 + ip6h->nexthdr = IPPROTO_ICMPV6;
7567 + ip6h->payload_len = htons(datalen + sizeof(struct icmp6hdr));
7568 + ipv6_addr_copy(&ip6h->saddr, &hdr->daddr);
7569 + ipv6_addr_copy(&ip6h->daddr, &hdr->saddr);
7571 + icmp6h = (struct icmp6hdr *) skb_put(nskb, sizeof(struct icmp6hdr));
7572 + icmp6h->icmp6_type = ICMPV6_DEST_UNREACH;
7573 + icmp6h->icmp6_code = code;
7574 + icmp6h->icmp6_cksum = 0;
7576 + data = skb_put(nskb, datalen);
7578 + csum = csum_partial((unsigned char *)icmp6h, sizeof(struct icmp6hdr), 0);
7579 + csum = skb_copy_and_csum_bits(skb_in, ip6off, data, datalen, csum);
7580 + icmp6h->icmp6_cksum = csum_ipv6_magic(&hdr->saddr, &hdr->daddr,
7581 + datalen + sizeof(struct icmp6hdr),
7582 + IPPROTO_ICMPV6, csum);
7585 + connection_attach(nskb, skb_in->nfct);
7587 + NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
7594 +static unsigned int reject6_target(struct sk_buff **pskb,
7595 + unsigned int hooknum,
7596 + const struct net_device *in,
7597 + const struct net_device *out,
7598 + const void *targinfo,
7601 + const struct ip6t_reject_info *reject = targinfo;
7603 + DEBUGP(KERN_DEBUG "%s: medium point\n", __FUNCTION__);
7604 + /* WARNING: This code causes reentry within ip6tables.
7605 + This means that the ip6tables jump stack is now crap. We
7606 + must return an absolute verdict. --RR */
7607 + switch (reject->with) {
7608 + case IP6T_ICMP6_NO_ROUTE:
7609 + send_unreach(*pskb, ICMPV6_NOROUTE);
7611 + case IP6T_ICMP6_ADM_PROHIBITED:
7612 + send_unreach(*pskb, ICMPV6_ADM_PROHIBITED);
7614 + case IP6T_ICMP6_NOT_NEIGHBOUR:
7615 + send_unreach(*pskb, ICMPV6_NOT_NEIGHBOUR);
7617 + case IP6T_ICMP6_ADDR_UNREACH:
7618 + send_unreach(*pskb, ICMPV6_ADDR_UNREACH);
7620 + case IP6T_ICMP6_PORT_UNREACH:
7621 + send_unreach(*pskb, ICMPV6_PORT_UNREACH);
7623 + case IP6T_ICMP6_ECHOREPLY:
7626 + case IP6T_TCP_RESET:
7627 + send_reset(*pskb);
7630 + if (net_ratelimit())
7631 + printk(KERN_WARNING "ip6t_REJECT: case %u not handled yet\n", reject->with);
7638 +static int check(const char *tablename,
7639 + const struct ip6t_entry *e,
7641 + unsigned int targinfosize,
7642 + unsigned int hook_mask)
7644 + const struct ip6t_reject_info *rejinfo = targinfo;
7646 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
7647 + DEBUGP("ip6t_REJECT: targinfosize %u != 0\n", targinfosize);
7651 + /* Only allow these for packet filtering. */
7652 + if (strcmp(tablename, "filter") != 0) {
7653 + DEBUGP("ip6t_REJECT: bad table `%s'.\n", tablename);
7657 + if ((hook_mask & ~((1 << NF_IP6_LOCAL_IN)
7658 + | (1 << NF_IP6_FORWARD)
7659 + | (1 << NF_IP6_LOCAL_OUT))) != 0) {
7660 + DEBUGP("ip6t_REJECT: bad hook mask %X\n", hook_mask);
7664 + if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
7665 + printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
7667 + } else if (rejinfo->with == IP6T_TCP_RESET) {
7668 + /* Must specify that it's a TCP packet */
7669 + if (e->ipv6.proto != IPPROTO_TCP
7670 + || (e->ipv6.invflags & IP6T_INV_PROTO)) {
7671 + DEBUGP("ip6t_REJECT: TCP_RESET illegal for non-tcp\n");
7679 +static struct ip6t_target ip6t_reject_reg = {
7681 + .target = reject6_target,
7682 + .checkentry = check,
7686 +static int __init init(void)
7688 + if (ip6t_register_target(&ip6t_reject_reg))
7693 +static void __exit fini(void)
7695 + ip6t_unregister_target(&ip6t_reject_reg);
7700 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv6/netfilter/ip6t_ROUTE.c linux-2.6.7/net/ipv6/netfilter/ip6t_ROUTE.c
7701 --- linux-2.6.7.org/net/ipv6/netfilter/ip6t_ROUTE.c 1970-01-01 01:00:00.000000000 +0100
7702 +++ linux-2.6.7/net/ipv6/netfilter/ip6t_ROUTE.c 2004-06-29 12:34:33.513532928 +0200
7705 + * This implements the ROUTE v6 target, which enables you to setup unusual
7706 + * routes not supported by the standard kernel routing table.
7708 + * Copyright (C) 2003 Cedric de Launois <delaunois@info.ucl.ac.be>
7710 + * v 1.0 2003/08/05
7712 + * This software is distributed under GNU GPL v2, 1991
7715 +#include <linux/module.h>
7716 +#include <linux/skbuff.h>
7717 +#include <linux/ipv6.h>
7718 +#include <linux/netfilter_ipv6/ip6_tables.h>
7719 +#include <linux/netfilter_ipv6/ip6t_ROUTE.h>
7720 +#include <linux/netdevice.h>
7721 +#include <net/ipv6.h>
7722 +#include <net/ndisc.h>
7723 +#include <net/ip6_route.h>
7724 +#include <linux/icmpv6.h>
7727 +#define DEBUGP printk
7729 +#define DEBUGP(format, args...)
7732 +#define NIP6(addr) \
7733 + ntohs((addr).s6_addr16[0]), \
7734 + ntohs((addr).s6_addr16[1]), \
7735 + ntohs((addr).s6_addr16[2]), \
7736 + ntohs((addr).s6_addr16[3]), \
7737 + ntohs((addr).s6_addr16[4]), \
7738 + ntohs((addr).s6_addr16[5]), \
7739 + ntohs((addr).s6_addr16[6]), \
7740 + ntohs((addr).s6_addr16[7])
7742 +/* Route the packet according to the routing keys specified in
7743 + * route_info. Keys are :
7745 + * 0 if no oif preferred,
7746 + * otherwise set to the index of the desired oif
7747 + * - route_info->gw :
7748 + * 0 if no gateway specified,
7749 + * otherwise set to the next host to which the pkt must be routed
7750 + * If success, skb->dev is the output device to which the packet must
7751 + * be sent and skb->dst is not NULL
7753 + * RETURN: 1 if the packet was succesfully routed to the
7754 + * destination desired
7755 + * 0 if the kernel routing table could not route the packet
7756 + * according to the keys specified
7759 +route6(struct sk_buff *skb,
7760 + unsigned int ifindex,
7761 + const struct ip6t_route_target_info *route_info)
7763 + struct rt6_info *rt = NULL;
7764 + struct ipv6hdr *ipv6h = skb->nh.ipv6h;
7765 + struct in6_addr *gw = (struct in6_addr*)&route_info->gw;
7767 + DEBUGP("ip6t_ROUTE: called with: ");
7768 + DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(ipv6h->daddr));
7769 + DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(*gw));
7770 + DEBUGP("OUT=%s\n", route_info->oif);
7772 + if (ipv6_addr_any(gw))
7773 + rt = rt6_lookup(&ipv6h->daddr, &ipv6h->saddr, ifindex, 1);
7775 + rt = rt6_lookup(gw, &ipv6h->saddr, ifindex, 1);
7780 + DEBUGP("ip6t_ROUTE: routing gives: ");
7781 + DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_dst.addr));
7782 + DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_gateway));
7783 + DEBUGP("OUT=%s\n", rt->rt6i_dev->name);
7785 + if (ifindex && rt->rt6i_dev->ifindex!=ifindex)
7788 + if (!rt->rt6i_nexthop) {
7789 + DEBUGP("ip6t_ROUTE: discovering neighbour\n");
7790 + rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_dst.addr);
7793 + /* Drop old route. */
7794 + dst_release(skb->dst);
7795 + skb->dst = &rt->u.dst;
7796 + skb->dev = rt->rt6i_dev;
7800 + dst_release(&rt->u.dst);
7802 + if (!net_ratelimit())
7805 + printk("ip6t_ROUTE: no explicit route found ");
7807 + printk("via interface %s ", route_info->oif);
7808 + if (!ipv6_addr_any(gw))
7809 + printk("via gateway %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", NIP6(*gw));
7815 +/* Stolen from ip6_output_finish
7816 + * PRE : skb->dev is set to the device we are leaving by
7817 + * skb->dst is not NULL
7818 + * POST: the packet is sent with the link layer header pushed
7819 + * the packet is destroyed
7821 +static void ip_direct_send(struct sk_buff *skb)
7823 + struct dst_entry *dst = skb->dst;
7824 + struct hh_cache *hh = dst->hh;
7827 + read_lock_bh(&hh->hh_lock);
7828 + memcpy(skb->data - 16, hh->hh_data, 16);
7829 + read_unlock_bh(&hh->hh_lock);
7830 + skb_push(skb, hh->hh_len);
7831 + hh->hh_output(skb);
7832 + } else if (dst->neighbour)
7833 + dst->neighbour->output(skb);
7835 + if (net_ratelimit())
7836 + DEBUGP(KERN_DEBUG "ip6t_ROUTE: no hdr & no neighbour cache!\n");
7842 +static unsigned int
7843 +route6_oif(const struct ip6t_route_target_info *route_info,
7844 + struct sk_buff *skb)
7846 + unsigned int ifindex = 0;
7847 + struct net_device *dev_out = NULL;
7849 + /* The user set the interface name to use.
7850 + * Getting the current interface index.
7852 + if ((dev_out = dev_get_by_name(route_info->oif))) {
7853 + ifindex = dev_out->ifindex;
7855 + /* Unknown interface name : packet dropped */
7856 + if (net_ratelimit())
7857 + DEBUGP("ip6t_ROUTE: oif interface %s not found\n", route_info->oif);
7859 + if (route_info->flags & IP6T_ROUTE_CONTINUE)
7860 + return IP6T_CONTINUE;
7865 + /* Trying the standard way of routing packets */
7866 + if (route6(skb, ifindex, route_info)) {
7868 + if (route_info->flags & IP6T_ROUTE_CONTINUE)
7869 + return IP6T_CONTINUE;
7871 + ip_direct_send(skb);
7878 +static unsigned int
7879 +route6_gw(const struct ip6t_route_target_info *route_info,
7880 + struct sk_buff *skb)
7882 + if (route6(skb, 0, route_info)) {
7883 + if (route_info->flags & IP6T_ROUTE_CONTINUE)
7884 + return IP6T_CONTINUE;
7886 + ip_direct_send(skb);
7893 +static unsigned int
7894 +ip6t_route_target(struct sk_buff **pskb,
7895 + unsigned int hooknum,
7896 + const struct net_device *in,
7897 + const struct net_device *out,
7898 + const void *targinfo,
7901 + const struct ip6t_route_target_info *route_info = targinfo;
7902 + struct sk_buff *skb = *pskb;
7903 + struct in6_addr *gw = (struct in6_addr*)&route_info->gw;
7905 + if (route_info->flags & IP6T_ROUTE_CONTINUE)
7908 + /* If we are at PREROUTING or INPUT hook
7909 + * the TTL isn't decreased by the IP stack
7911 + if (hooknum == NF_IP6_PRE_ROUTING ||
7912 + hooknum == NF_IP6_LOCAL_IN) {
7914 + struct ipv6hdr *ipv6h = skb->nh.ipv6h;
7916 + if (ipv6h->hop_limit <= 1) {
7917 + /* Force OUTPUT device used as source address */
7918 + skb->dev = skb->dst->dev;
7920 + icmpv6_send(skb, ICMPV6_TIME_EXCEED,
7921 + ICMPV6_EXC_HOPLIMIT, 0, skb->dev);
7926 + ipv6h->hop_limit--;
7931 + if (route_info->oif[0])
7932 + return route6_oif(route_info, *pskb);
7934 + if (!ipv6_addr_any(gw))
7935 + return route6_gw(route_info, *pskb);
7937 + if (net_ratelimit())
7938 + DEBUGP(KERN_DEBUG "ip6t_ROUTE: no parameter !\n");
7940 + return IP6T_CONTINUE;
7945 +ip6t_route_checkentry(const char *tablename,
7946 + const struct ip6t_entry *e,
7948 + unsigned int targinfosize,
7949 + unsigned int hook_mask)
7951 + if (strcmp(tablename, "mangle") != 0) {
7952 + printk("ip6t_ROUTE: can only be called from \"mangle\" table.\n");
7956 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_route_target_info))) {
7957 + printk(KERN_WARNING "ip6t_ROUTE: targinfosize %u != %Zu\n",
7959 + IP6T_ALIGN(sizeof(struct ip6t_route_target_info)));
7967 +static struct ip6t_target ip6t_route_reg = {
7969 + .target = ip6t_route_target,
7970 + .checkentry = ip6t_route_checkentry,
7975 +static int __init init(void)
7977 + printk(KERN_DEBUG "registering ipv6 ROUTE target\n");
7978 + if (ip6t_register_target(&ip6t_route_reg))
7985 +static void __exit fini(void)
7987 + ip6t_unregister_target(&ip6t_route_reg);
7992 +MODULE_LICENSE("GPL");
7993 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv6/netfilter/ip6t_fuzzy.c linux-2.6.7/net/ipv6/netfilter/ip6t_fuzzy.c
7994 --- linux-2.6.7.org/net/ipv6/netfilter/ip6t_fuzzy.c 1970-01-01 01:00:00.000000000 +0100
7995 +++ linux-2.6.7/net/ipv6/netfilter/ip6t_fuzzy.c 2004-06-29 12:32:08.824529000 +0200
7998 + * This module implements a simple TSK FLC
7999 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
8000 + * to limit , in an adaptive and flexible way , the packet rate crossing
8001 + * a given stream . It serves as an initial and very simple (but effective)
8002 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
8003 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
8004 + * into our code in a precise , adaptive and efficient manner.
8005 + * The goal is very similar to that of "limit" match , but using techniques of
8006 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
8007 + * avoiding over and undershoots - and stuff like that .
8010 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
8011 + * 2002-08-17 : Changed to eliminate floating point operations .
8012 + * 2002-08-23 : Coding style changes .
8013 + * 2003-04-08 Maciej Soltysiak <solt@dns.toxicilms.tv> : IPv6 Port
8016 +#include <linux/module.h>
8017 +#include <linux/skbuff.h>
8018 +#include <linux/ipv6.h>
8019 +#include <linux/random.h>
8020 +#include <net/tcp.h>
8021 +#include <linux/spinlock.h>
8022 +#include <linux/netfilter_ipv6/ip6_tables.h>
8023 +#include <linux/netfilter_ipv6/ip6t_fuzzy.h>
8026 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
8027 + Expressed in percentage
8030 +#define PAR_LOW 1/100
8033 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED;
8035 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
8036 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
8037 +MODULE_LICENSE("GPL");
8039 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
8041 + if (tx >= maxi) return 100;
8043 + if (tx <= mini) return 0;
8045 + return ((100 * (tx-mini)) / (maxi-mini));
8048 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
8050 + if (tx <= mini) return 100;
8052 + if (tx >= maxi) return 0;
8054 + return ((100 * (maxi - tx)) / (maxi - mini));
8059 +ip6t_fuzzy_match(const struct sk_buff *pskb,
8060 + const struct net_device *in,
8061 + const struct net_device *out,
8062 + const void *matchinfo,
8065 + u_int16_t datalen,
8068 + /* From userspace */
8070 + struct ip6t_fuzzy_info *info = (struct ip6t_fuzzy_info *) matchinfo;
8072 + u_int8_t random_number;
8073 + unsigned long amount;
8074 + u_int8_t howhigh, howlow;
8077 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
8079 + info->bytes_total += pskb->len;
8080 + info->packets_total++;
8082 + info->present_time = jiffies;
8084 + if (info->present_time >= info->previous_time)
8085 + amount = info->present_time - info->previous_time;
8087 + /* There was a transition : I choose to re-sample
8088 + and keep the old acceptance rate...
8092 + info->previous_time = info->present_time;
8093 + info->bytes_total = info->packets_total = 0;
8096 + if ( amount > HZ/10) {/* More than 100 ms elapsed ... */
8098 + info->mean_rate = (u_int32_t) ((HZ * info->packets_total) \
8101 + info->previous_time = info->present_time;
8102 + info->bytes_total = info->packets_total = 0;
8104 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
8105 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
8107 + info->acceptance_rate = (u_int8_t) \
8108 + (howhigh * PAR_LOW + PAR_HIGH * howlow);
8110 + /* In fact, the above defuzzification would require a denominator
8111 + * proportional to (howhigh+howlow) but, in this particular case,
8112 + * that expression is constant.
8113 + * An imediate consequence is that it is not necessary to call
8114 + * both mf_high and mf_low - but to keep things understandable,
8120 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
8123 + if (info->acceptance_rate < 100)
8125 + get_random_bytes((void *)(&random_number), 1);
8127 + /* If within the acceptance , it can pass => don't match */
8128 + if (random_number <= (255 * info->acceptance_rate) / 100)
8131 + return 1; /* It can't pass (It matches) */
8134 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
8139 +ip6t_fuzzy_checkentry(const char *tablename,
8140 + const struct ip6t_ip6 *ip,
8142 + unsigned int matchsize,
8143 + unsigned int hook_mask)
8146 + const struct ip6t_fuzzy_info *info = matchinfo;
8148 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info))) {
8149 + printk("ip6t_fuzzy: matchsize %u != %u\n", matchsize,
8150 + IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info)));
8154 + if ((info->minimum_rate < MINFUZZYRATE) || (info->maximum_rate > MAXFUZZYRATE)
8155 + || (info->minimum_rate >= info->maximum_rate)) {
8156 + printk("ip6t_fuzzy: BAD limits , please verify !!!\n");
8163 +static struct ip6t_match ip6t_fuzzy_reg = {
8167 + ip6t_fuzzy_checkentry,
8171 +static int __init init(void)
8173 + if (ip6t_register_match(&ip6t_fuzzy_reg))
8179 +static void __exit fini(void)
8181 + ip6t_unregister_match(&ip6t_fuzzy_reg);
8186 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv6/netfilter/ip6t_nth.c linux-2.6.7/net/ipv6/netfilter/ip6t_nth.c
8187 --- linux-2.6.7.org/net/ipv6/netfilter/ip6t_nth.c 1970-01-01 01:00:00.000000000 +0100
8188 +++ linux-2.6.7/net/ipv6/netfilter/ip6t_nth.c 2004-06-29 12:32:16.703331240 +0200
8191 + This is a module which is used for match support for every Nth packet
8192 + This file is distributed under the terms of the GNU General Public
8193 + License (GPL). Copies of the GPL can be obtained from:
8194 + ftp://prep.ai.mit.edu/pub/gnu/GPL
8196 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
8197 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
8198 + * added support for multiple counters
8199 + * added support for matching on individual packets
8200 + in the counter cycle
8201 + 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
8205 +#include <linux/module.h>
8206 +#include <linux/skbuff.h>
8207 +#include <linux/ip.h>
8208 +#include <net/tcp.h>
8209 +#include <linux/spinlock.h>
8210 +#include <linux/netfilter_ipv6/ip6_tables.h>
8211 +#include <linux/netfilter_ipv6/ip6t_nth.h>
8213 +MODULE_LICENSE("GPL");
8216 + * State information.
8223 +static struct state states[IP6T_NTH_NUM_COUNTERS];
8226 +ip6t_nth_match(const struct sk_buff *pskb,
8227 + const struct net_device *in,
8228 + const struct net_device *out,
8229 + const void *matchinfo,
8232 + u_int16_t datalen,
8235 + /* Parameters from userspace */
8236 + const struct ip6t_nth_info *info = matchinfo;
8237 + unsigned counter = info->counter;
8238 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
8240 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
8244 + spin_lock(&states[counter].lock);
8246 + /* Are we matching every nth packet?*/
8247 + if (info->packet == 0xFF)
8249 + /* We're matching every nth packet and only every nth packet*/
8250 + /* Do we match or invert match? */
8251 + if (info->not == 0)
8253 + if (states[counter].number == 0)
8255 + ++states[counter].number;
8258 + if (states[counter].number >= info->every)
8259 + states[counter].number = 0; /* reset the counter */
8261 + ++states[counter].number;
8266 + if (states[counter].number == 0)
8268 + ++states[counter].number;
8271 + if (states[counter].number >= info->every)
8272 + states[counter].number = 0;
8274 + ++states[counter].number;
8280 + /* We're using the --packet, so there must be a rule for every value */
8281 + if (states[counter].number == info->packet)
8283 + /* only increment the counter when a match happens */
8284 + if (states[counter].number >= info->every)
8285 + states[counter].number = 0; /* reset the counter */
8287 + ++states[counter].number;
8296 + spin_unlock(&states[counter].lock);
8300 + spin_unlock(&states[counter].lock);
8305 +ip6t_nth_checkentry(const char *tablename,
8306 + const struct ip6t_ip6 *e,
8308 + unsigned int matchsize,
8309 + unsigned int hook_mask)
8311 + /* Parameters from userspace */
8312 + const struct ip6t_nth_info *info = matchinfo;
8313 + unsigned counter = info->counter;
8314 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
8316 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
8320 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_nth_info))) {
8321 + printk("nth: matchsize %u != %u\n", matchsize,
8322 + IP6T_ALIGN(sizeof(struct ip6t_nth_info)));
8326 + states[counter].number = info->startat;
8331 +static struct ip6t_match ip6t_nth_reg = {
8335 + ip6t_nth_checkentry,
8339 +static int __init init(void)
8342 + memset(&states, 0, sizeof(states));
8343 + if (ip6t_register_match(&ip6t_nth_reg))
8346 + for(counter = 0; counter < IP6T_NTH_NUM_COUNTERS; counter++)
8348 + spin_lock_init(&(states[counter].lock));
8351 + printk("ip6t_nth match loaded\n");
8355 +static void __exit fini(void)
8357 + ip6t_unregister_match(&ip6t_nth_reg);
8358 + printk("ip6t_nth match unloaded\n");
8363 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv6/netfilter/ip6t_owner.c linux-2.6.7/net/ipv6/netfilter/ip6t_owner.c
8364 --- linux-2.6.7.org/net/ipv6/netfilter/ip6t_owner.c 2004-06-29 12:24:14.000000000 +0200
8365 +++ linux-2.6.7/net/ipv6/netfilter/ip6t_owner.c 2004-06-29 12:35:37.772764040 +0200
8367 MODULE_LICENSE("GPL");
8370 +match_comm(const struct sk_buff *skb, const char *comm)
8372 + struct task_struct *p, *g;
8373 + struct files_struct *files;
8376 + read_lock(&tasklist_lock);
8377 + do_each_thread(g, p) {
8378 + if(strncmp(p->comm, comm, sizeof(p->comm)))
8384 + read_lock(&files->file_lock);
8385 + for (i=0; i < files->max_fds; i++) {
8386 + if (fcheck_files(files, i) ==
8387 + skb->sk->sk_socket->file) {
8388 + read_unlock(&files->file_lock);
8390 + read_unlock(&tasklist_lock);
8394 + read_unlock(&files->file_lock);
8397 + } while_each_thread(g, p);
8398 + read_unlock(&tasklist_lock);
8403 match_pid(const struct sk_buff *skb, pid_t pid)
8405 struct task_struct *p;
8406 @@ -125,6 +158,12 @@
8410 + if(info->match & IP6T_OWNER_COMM) {
8411 + if (!match_comm(skb, info->comm) ^
8412 + !!(info->invert & IP6T_OWNER_COMM))
8419 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv6/netfilter/ip6t_policy.c linux-2.6.7/net/ipv6/netfilter/ip6t_policy.c
8420 --- linux-2.6.7.org/net/ipv6/netfilter/ip6t_policy.c 1970-01-01 01:00:00.000000000 +0100
8421 +++ linux-2.6.7/net/ipv6/netfilter/ip6t_policy.c 2004-06-29 12:35:40.050417784 +0200
8423 +/* IP tables module for matching IPsec policy
8425 + * Copyright (c) 2004 Patrick McHardy, <kaber@trash.net>
8427 + * This program is free software; you can redistribute it and/or modify
8428 + * it under the terms of the GNU General Public License version 2 as
8429 + * published by the Free Software Foundation.
8432 +#include <linux/kernel.h>
8433 +#include <linux/config.h>
8434 +#include <linux/module.h>
8435 +#include <linux/skbuff.h>
8436 +#include <linux/init.h>
8437 +#include <net/xfrm.h>
8439 +#include <linux/netfilter_ipv6.h>
8440 +#include <linux/netfilter_ipv6/ip6t_policy.h>
8441 +#include <linux/netfilter_ipv6/ip6_tables.h>
8443 +MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
8444 +MODULE_DESCRIPTION("IPtables IPsec policy matching module");
8445 +MODULE_LICENSE("GPL");
8448 +static inline int ip6_masked_addrcmp(struct in6_addr addr1,
8449 + struct in6_addr mask,
8450 + struct in6_addr addr2)
8454 + for (i = 0; i < 16; i++) {
8455 + if ((addr1.s6_addr[i] & mask.s6_addr[i]) !=
8456 + (addr2.s6_addr[i] & mask.s6_addr[i]))
8464 +match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e)
8466 +#define MISMATCH(x,y) (e->match.x && ((e->x != (y)) ^ e->invert.x))
8468 + struct in6_addr xfrm_saddr, xfrm_daddr;
8470 + if ((e->match.saddr
8471 + && (ip6_masked_addrcmp(xfrm_saddr, e->saddr, e->smask))
8472 + ^ e->invert.saddr ) ||
8474 + && (ip6_masked_addrcmp(xfrm_daddr, e->daddr, e->dmask))
8475 + ^ e->invert.daddr ) ||
8476 + MISMATCH(proto, x->id.proto) ||
8477 + MISMATCH(mode, x->props.mode) ||
8478 + MISMATCH(spi, x->id.spi) ||
8479 + MISMATCH(reqid, x->props.reqid))
8485 +match_policy_in(const struct sk_buff *skb, const struct ip6t_policy_info *info)
8487 + const struct ip6t_policy_elem *e;
8488 + struct sec_path *sp = skb->sp;
8489 + int strict = info->flags & POLICY_MATCH_STRICT;
8494 + if (strict && info->len != sp->len)
8497 + for (i = sp->len - 1; i >= 0; i--) {
8498 + pos = strict ? i - sp->len + 1 : 0;
8499 + if (pos >= info->len)
8501 + e = &info->pol[pos];
8503 + if (match_xfrm_state(sp->x[i].xvec, e)) {
8506 + } else if (strict)
8510 + return strict ? 1 : 0;
8514 +match_policy_out(const struct sk_buff *skb, const struct ip6t_policy_info *info)
8516 + const struct ip6t_policy_elem *e;
8517 + struct dst_entry *dst = skb->dst;
8518 + int strict = info->flags & POLICY_MATCH_STRICT;
8521 + if (dst->xfrm == NULL)
8524 + for (i = 0; dst && dst->xfrm; dst = dst->child, i++) {
8525 + pos = strict ? i : 0;
8526 + if (pos >= info->len)
8528 + e = &info->pol[pos];
8530 + if (match_xfrm_state(dst->xfrm, e)) {
8533 + } else if (strict)
8537 + return strict ? 1 : 0;
8540 +static int match(const struct sk_buff *skb,
8541 + const struct net_device *in,
8542 + const struct net_device *out,
8543 + const void *matchinfo,
8546 + u_int16_t datalen,
8549 + const struct ip6t_policy_info *info = matchinfo;
8552 + if (info->flags & POLICY_MATCH_IN)
8553 + ret = match_policy_in(skb, info);
8555 + ret = match_policy_out(skb, info);
8558 + if (info->flags & POLICY_MATCH_NONE)
8562 + } else if (info->flags & POLICY_MATCH_NONE)
8568 +static int checkentry(const char *tablename, const struct ip6t_ip6 *ip,
8569 + void *matchinfo, unsigned int matchsize,
8570 + unsigned int hook_mask)
8572 + struct ip6t_policy_info *info = matchinfo;
8574 + if (matchsize != IP6T_ALIGN(sizeof(*info))) {
8575 + printk(KERN_ERR "ip6t_policy: matchsize %u != %u\n",
8576 + matchsize, IP6T_ALIGN(sizeof(*info)));
8579 + if (!(info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT))) {
8580 + printk(KERN_ERR "ip6t_policy: neither incoming nor "
8581 + "outgoing policy selected\n");
8584 + if (hook_mask & (1 << NF_IP6_PRE_ROUTING | 1 << NF_IP6_LOCAL_IN)
8585 + && info->flags & POLICY_MATCH_OUT) {
8586 + printk(KERN_ERR "ip6t_policy: output policy not valid in "
8587 + "PRE_ROUTING and INPUT\n");
8590 + if (hook_mask & (1 << NF_IP6_POST_ROUTING | 1 << NF_IP6_LOCAL_OUT)
8591 + && info->flags & POLICY_MATCH_IN) {
8592 + printk(KERN_ERR "ip6t_policy: input policy not valid in "
8593 + "POST_ROUTING and OUTPUT\n");
8596 + if (info->len > POLICY_MAX_ELEM) {
8597 + printk(KERN_ERR "ip6t_policy: too many policy elements\n");
8604 +static struct ip6t_match policy_match =
8608 + .checkentry = checkentry,
8609 + .me = THIS_MODULE,
8612 +static int __init init(void)
8614 + return ip6t_register_match(&policy_match);
8617 +static void __exit fini(void)
8619 + ip6t_unregister_match(&policy_match);