1 --- linux-2.6.9-rc1/include/linux/netfilter_ipv4/ip_conntrack.h.orig 2004-08-29 16:44:31.000000000 +0200
2 +++ linux-2.6.9-rc1/include/linux/netfilter_ipv4/ip_conntrack.h 2004-08-29 19:58:04.869439888 +0200
5 #endif /* CONFIG_IP_NF_NAT_NEEDED */
7 +#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
13 /* get master conntrack via master expectation */
14 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
15 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ip_queue.h 2004-06-16 07:20:03.000000000 +0200
16 +++ linux-2.6.7/include/linux/netfilter_ipv4/ip_queue.h 2004-06-29 12:35:08.141268712 +0200
18 unsigned char payload[0]; /* Optional replacement packet */
21 +typedef struct ipq_vwmark_msg {
22 + unsigned int value; /* Verdict to hand to netfilter */
23 + unsigned long id; /* Packet ID for this verdict */
24 + size_t data_len; /* Length of replacement data */
25 + unsigned char payload[0]; /* Optional replacement packet */
26 + unsigned long nfmark; /* Mark for the Packet */
30 typedef struct ipq_peer_msg {
32 ipq_verdict_msg_t verdict;
34 + ipq_vwmark_msg_t vwmark;
39 #define IPQM_MODE (IPQM_BASE + 1) /* Mode request from peer */
40 #define IPQM_VERDICT (IPQM_BASE + 2) /* Verdict from peer */
41 #define IPQM_PACKET (IPQM_BASE + 3) /* Packet from kernel */
42 -#define IPQM_MAX (IPQM_BASE + 4)
43 +#define IPQM_VWMARK (IPQM_BASE + 4) /* Verdict and mark from peer */
44 +#define IPQM_MAX (IPQM_BASE + 5)
46 #endif /*_IP_QUEUE_H*/
47 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
48 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_CONNMARK.h 1970-01-01 01:00:00.000000000 +0100
49 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_CONNMARK.h 2004-06-29 12:34:21.508357992 +0200
51 +#ifndef _IPT_CONNMARK_H_target
52 +#define _IPT_CONNMARK_H_target
54 +/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
55 + * by Henrik Nordstrom <hno@marasystems.com>
57 + * This program is free software; you can redistribute it and/or modify
58 + * it under the terms of the GNU General Public License as published by
59 + * the Free Software Foundation; either version 2 of the License, or
60 + * (at your option) any later version.
64 + IPT_CONNMARK_SET = 0,
66 + IPT_CONNMARK_RESTORE
69 +struct ipt_connmark_target_info {
75 +#endif /*_IPT_CONNMARK_H_target*/
76 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
77 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_IPMARK.h 1970-01-01 01:00:00.000000000 +0100
78 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_IPMARK.h 2004-06-29 12:34:27.607430792 +0200
80 +#ifndef _IPT_IPMARK_H_target
81 +#define _IPT_IPMARK_H_target
83 +struct ipt_ipmark_target_info {
84 + unsigned long andmask;
85 + unsigned long ormask;
89 +#define IPT_IPMARK_SRC 0
90 +#define IPT_IPMARK_DST 1
92 +#endif /*_IPT_IPMARK_H_target*/
93 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
94 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_ROUTE.h 1970-01-01 01:00:00.000000000 +0100
95 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_ROUTE.h 2004-06-29 12:34:33.507533840 +0200
97 +/* Header file for iptables ipt_ROUTE target
99 + * (C) 2002 by Cédric de Launois <delaunois@info.ucl.ac.be>
101 + * This software is distributed under GNU GPL v2, 1991
103 +#ifndef _IPT_ROUTE_H_target
104 +#define _IPT_ROUTE_H_target
106 +#define IPT_ROUTE_IFNAMSIZ 16
108 +struct ipt_route_target_info {
109 + char oif[IPT_ROUTE_IFNAMSIZ]; /* Output Interface Name */
110 + char iif[IPT_ROUTE_IFNAMSIZ]; /* Input Interface Name */
111 + u_int32_t gw; /* IP address of gateway */
115 +/* Values for "flags" field */
116 +#define IPT_ROUTE_CONTINUE 0x01
118 +#endif /*_IPT_ROUTE_H_target*/
119 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
120 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_TTL.h 1970-01-01 01:00:00.000000000 +0100
121 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_TTL.h 2004-06-29 12:32:03.616320768 +0200
123 +/* TTL modification module for IP tables
124 + * (C) 2000 by Harald Welte <laforge@gnumonks.org> */
135 +#define IPT_TTL_MAXMODE IPT_TTL_DEC
137 +struct ipt_TTL_info {
144 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
145 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_XOR.h 1970-01-01 01:00:00.000000000 +0100
146 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_XOR.h 2004-06-29 12:34:46.048627304 +0200
151 +struct ipt_XOR_info {
153 + u_int8_t block_size;
156 +#endif /* _IPT_XOR_H */
157 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
158 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_connlimit.h 1970-01-01 01:00:00.000000000 +0100
159 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_connlimit.h 2004-06-29 12:32:05.986960376 +0200
161 +#ifndef _IPT_CONNLIMIT_H
162 +#define _IPT_CONNLIMIT_H
164 +struct ipt_connlimit_data;
166 +struct ipt_connlimit_info {
170 + struct ipt_connlimit_data *data;
172 +#endif /* _IPT_CONNLIMIT_H */
173 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
174 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_connmark.h 1970-01-01 01:00:00.000000000 +0100
175 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_connmark.h 2004-06-29 12:34:21.510357688 +0200
177 +#ifndef _IPT_CONNMARK_H
178 +#define _IPT_CONNMARK_H
180 +/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
181 + * by Henrik Nordstrom <hno@marasystems.com>
183 + * This program is free software; you can redistribute it and/or modify
184 + * it under the terms of the GNU General Public License as published by
185 + * the Free Software Foundation; either version 2 of the License, or
186 + * (at your option) any later version.
189 +struct ipt_connmark_info {
190 + unsigned long mark, mask;
194 +#endif /*_IPT_CONNMARK_H*/
195 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
196 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_dstlimit.h 1970-01-01 01:00:00.000000000 +0100
197 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_dstlimit.h 2004-06-29 12:32:07.241769616 +0200
199 +#ifndef _IPT_DSTLIMIT_H
200 +#define _IPT_DSTLIMIT_H
202 +/* timings are in milliseconds. */
203 +#define IPT_DSTLIMIT_SCALE 10000
204 +/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490
205 + seconds, or one every 59 hours. */
207 +/* details of this structure hidden by the implementation */
208 +struct ipt_dstlimit_htable;
210 +#define IPT_DSTLIMIT_HASH_DIP 0x0001
211 +#define IPT_DSTLIMIT_HASH_DPT 0x0002
212 +#define IPT_DSTLIMIT_HASH_SIP 0x0004
214 +struct dstlimit_cfg {
215 + u_int32_t mode; /* bitmask of IPT_DSTLIMIT_HASH_* */
216 + u_int32_t avg; /* Average secs between packets * scale */
217 + u_int32_t burst; /* Period multiplier for upper limit. */
219 + /* user specified */
220 + u_int32_t size; /* how many buckets */
221 + u_int32_t max; /* max number of entries */
222 + u_int32_t gc_interval; /* gc interval */
223 + u_int32_t expire; /* when do entries expire? */
226 +struct ipt_dstlimit_info {
227 + char name [IFNAMSIZ]; /* name */
228 + struct dstlimit_cfg cfg;
229 + struct ipt_dstlimit_htable *hinfo;
231 + /* Used internally by the kernel */
234 + struct ipt_dstlimit_info *master;
237 +#endif /*_IPT_DSTLIMIT_H*/
238 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
239 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_fuzzy.h 1970-01-01 01:00:00.000000000 +0100
240 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_fuzzy.h 2004-06-29 12:32:08.818529912 +0200
242 +#ifndef _IPT_FUZZY_H
243 +#define _IPT_FUZZY_H
245 +#include <linux/param.h>
246 +#include <linux/types.h>
248 +#define MAXFUZZYRATE 10000000
249 +#define MINFUZZYRATE 3
251 +struct ipt_fuzzy_info {
252 + u_int32_t minimum_rate;
253 + u_int32_t maximum_rate;
254 + u_int32_t packets_total;
255 + u_int32_t bytes_total;
256 + u_int32_t previous_time;
257 + u_int32_t present_time;
258 + u_int32_t mean_rate;
259 + u_int8_t acceptance_rate;
262 +#endif /*_IPT_FUZZY_H*/
263 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
264 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_ipv4options.h 1970-01-01 01:00:00.000000000 +0100
265 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_ipv4options.h 2004-06-29 12:32:14.110725376 +0200
267 +#ifndef __ipt_ipv4options_h_included__
268 +#define __ipt_ipv4options_h_included__
270 +#define IPT_IPV4OPTION_MATCH_SSRR 0x01 /* For strict source routing */
271 +#define IPT_IPV4OPTION_MATCH_LSRR 0x02 /* For loose source routing */
272 +#define IPT_IPV4OPTION_DONT_MATCH_SRR 0x04 /* any source routing */
273 +#define IPT_IPV4OPTION_MATCH_RR 0x08 /* For Record route */
274 +#define IPT_IPV4OPTION_DONT_MATCH_RR 0x10
275 +#define IPT_IPV4OPTION_MATCH_TIMESTAMP 0x20 /* For timestamp request */
276 +#define IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP 0x40
277 +#define IPT_IPV4OPTION_MATCH_ROUTER_ALERT 0x80 /* For router-alert */
278 +#define IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT 0x100
279 +#define IPT_IPV4OPTION_MATCH_ANY_OPT 0x200 /* match packet with any option */
280 +#define IPT_IPV4OPTION_DONT_MATCH_ANY_OPT 0x400 /* match packet with no option */
282 +struct ipt_ipv4options_info {
287 +#endif /* __ipt_ipv4options_h_included__ */
288 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
289 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_mport.h 1970-01-01 01:00:00.000000000 +0100
290 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_mport.h 2004-06-29 12:32:15.539508168 +0200
292 +#ifndef _IPT_MPORT_H
293 +#define _IPT_MPORT_H
294 +#include <linux/netfilter_ipv4/ip_tables.h>
296 +#define IPT_MPORT_SOURCE (1<<0)
297 +#define IPT_MPORT_DESTINATION (1<<1)
298 +#define IPT_MPORT_EITHER (IPT_MPORT_SOURCE|IPT_MPORT_DESTINATION)
300 +#define IPT_MULTI_PORTS 15
302 +/* Must fit inside union ipt_matchinfo: 32 bytes */
303 +/* every entry in ports[] except for the last one has one bit in pflags
304 + * associated with it. If this bit is set, the port is the first port of
305 + * a portrange, with the next entry being the last.
306 + * End of list is marked with pflags bit set and port=65535.
307 + * If 14 ports are used (last one does not have a pflag), the last port
308 + * is repeated to fill the last entry in ports[] */
311 + u_int8_t flags:2; /* Type of comparison */
312 + u_int16_t pflags:14; /* Port flags */
313 + u_int16_t ports[IPT_MULTI_PORTS]; /* Ports */
315 +#endif /*_IPT_MPORT_H*/
316 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
317 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_nth.h 1970-01-01 01:00:00.000000000 +0100
318 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_nth.h 2004-06-29 12:32:16.697332152 +0200
323 +#include <linux/param.h>
324 +#include <linux/types.h>
326 +#ifndef IPT_NTH_NUM_COUNTERS
327 +#define IPT_NTH_NUM_COUNTERS 16
330 +struct ipt_nth_info {
338 +#endif /*_IPT_NTH_H*/
339 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
340 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_policy.h 1970-01-01 01:00:00.000000000 +0100
341 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_policy.h 2004-06-29 12:35:40.044418696 +0200
343 +#ifndef _IPT_POLICY_H
344 +#define _IPT_POLICY_H
346 +#define POLICY_MAX_ELEM 4
348 +enum ipt_policy_flags
350 + POLICY_MATCH_IN = 0x1,
351 + POLICY_MATCH_OUT = 0x2,
352 + POLICY_MATCH_NONE = 0x4,
353 + POLICY_MATCH_STRICT = 0x8,
356 +enum ipt_policy_modes
358 + POLICY_MODE_TRANSPORT,
362 +struct ipt_policy_spec
372 +struct ipt_policy_elem
383 + struct ipt_policy_spec match;
384 + struct ipt_policy_spec invert;
387 +struct ipt_policy_info
389 + struct ipt_policy_elem pol[POLICY_MAX_ELEM];
394 +#endif /* _IPT_POLICY_H */
395 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
396 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_psd.h 1970-01-01 01:00:00.000000000 +0100
397 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_psd.h 2004-06-29 12:32:18.293089560 +0200
402 +#include <linux/param.h>
403 +#include <linux/types.h>
406 + * High port numbers have a lower weight to reduce the frequency of false
407 + * positives, such as from passive mode FTP transfers.
409 +#define PORT_WEIGHT_PRIV 3
410 +#define PORT_WEIGHT_HIGH 1
413 + * Port scan detection thresholds: at least COUNT ports need to be scanned
414 + * from the same source, with no longer than DELAY ticks between ports.
416 +#define SCAN_MIN_COUNT 7
417 +#define SCAN_MAX_COUNT (SCAN_MIN_COUNT * PORT_WEIGHT_PRIV)
418 +#define SCAN_WEIGHT_THRESHOLD SCAN_MAX_COUNT
419 +#define SCAN_DELAY_THRESHOLD (300) /* old usage of HZ here was erroneously and broke under uml */
422 + * Keep track of up to LIST_SIZE source addresses, using a hash table of
423 + * HASH_SIZE entries for faster lookups, but limiting hash collisions to
424 + * HASH_MAX source addresses per the same hash value.
426 +#define LIST_SIZE 0x100
428 +#define HASH_SIZE (1 << HASH_LOG)
429 +#define HASH_MAX 0x10
431 +struct ipt_psd_info {
432 + unsigned int weight_threshold;
433 + unsigned int delay_threshold;
434 + unsigned short lo_ports_weight;
435 + unsigned short hi_ports_weight;
438 +#endif /*_IPT_PSD_H*/
439 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
440 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_quota.h 1970-01-01 01:00:00.000000000 +0100
441 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_quota.h 2004-06-29 12:32:19.477909440 +0200
443 +#ifndef _IPT_QUOTA_H
444 +#define _IPT_QUOTA_H
446 +/* print debug info in both kernel/netfilter module & iptable library */
447 +//#define DEBUG_IPT_QUOTA
449 +struct ipt_quota_info {
453 +#endif /*_IPT_QUOTA_H*/
454 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
455 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_string.h 1970-01-01 01:00:00.000000000 +0100
456 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_string.h 2004-06-29 12:36:14.589167096 +0200
458 +#ifndef _IPT_STRING_H
459 +#define _IPT_STRING_H
461 +/* *** PERFORMANCE TWEAK ***
462 + * Packet size and search string threshold,
463 + * above which sublinear searches is used. */
464 +#define IPT_STRING_HAYSTACK_THRESH 100
465 +#define IPT_STRING_NEEDLE_THRESH 20
467 +#define BM_MAX_NLEN 256
468 +#define BM_MAX_HLEN 1024
470 +typedef char *(*proc_ipt_search) (char *, char *, int, int);
472 +struct ipt_string_info {
473 + char string[BM_MAX_NLEN];
478 +#endif /* _IPT_STRING_H */
479 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
480 --- linux-2.6.7.org/include/linux/netfilter_ipv4/ipt_time.h 1970-01-01 01:00:00.000000000 +0100
481 +++ linux-2.6.7/include/linux/netfilter_ipv4/ipt_time.h 2004-06-29 12:32:41.025633688 +0200
483 +#ifndef __ipt_time_h_included__
484 +#define __ipt_time_h_included__
487 +struct ipt_time_info {
488 + u_int8_t days_match; /* 1 bit per day. -SMTWTFS */
489 + u_int16_t time_start; /* 0 < time_start < 23*60+59 = 1439 */
490 + u_int16_t time_stop; /* 0:0 < time_stat < 23:59 */
491 + u_int8_t kerneltime; /* ignore skb time (and use kerneltime) or not. */
497 +#endif /* __ipt_time_h_included__ */
498 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
499 --- linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_HL.h 1970-01-01 01:00:00.000000000 +0100
500 +++ linux-2.6.7/include/linux/netfilter_ipv6/ip6t_HL.h 2004-06-29 12:31:59.776904448 +0200
502 +/* Hop Limit modification module for ip6tables
503 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
504 + * Based on HW's TTL module */
515 +#define IP6T_HL_MAXMODE IP6T_HL_DEC
517 +struct ip6t_HL_info {
519 + u_int8_t hop_limit;
524 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
525 --- linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_ROUTE.h 1970-01-01 01:00:00.000000000 +0100
526 +++ linux-2.6.7/include/linux/netfilter_ipv6/ip6t_ROUTE.h 2004-06-29 12:34:33.509533536 +0200
528 +/* Header file for iptables ip6t_ROUTE target
530 + * (C) 2003 by Cédric de Launois <delaunois@info.ucl.ac.be>
532 + * This software is distributed under GNU GPL v2, 1991
534 +#ifndef _IPT_ROUTE_H_target
535 +#define _IPT_ROUTE_H_target
537 +#define IP6T_ROUTE_IFNAMSIZ 16
539 +struct ip6t_route_target_info {
540 + char oif[IP6T_ROUTE_IFNAMSIZ]; /* Output Interface Name */
541 + char iif[IP6T_ROUTE_IFNAMSIZ]; /* Input Interface Name */
542 + u_int32_t gw[4]; /* IPv6 address of gateway */
546 +/* Values for "flags" field */
547 +#define IP6T_ROUTE_CONTINUE 0x01
549 +#endif /*_IP6T_ROUTE_H_target*/
550 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
551 --- linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h 1970-01-01 01:00:00.000000000 +0100
552 +++ linux-2.6.7/include/linux/netfilter_ipv6/ip6t_fuzzy.h 2004-06-29 12:32:08.820529608 +0200
554 +#ifndef _IP6T_FUZZY_H
555 +#define _IP6T_FUZZY_H
557 +#include <linux/param.h>
558 +#include <linux/types.h>
560 +#define MAXFUZZYRATE 10000000
561 +#define MINFUZZYRATE 3
563 +struct ip6t_fuzzy_info {
564 + u_int32_t minimum_rate;
565 + u_int32_t maximum_rate;
566 + u_int32_t packets_total;
567 + u_int32_t bytes_total;
568 + u_int32_t previous_time;
569 + u_int32_t present_time;
570 + u_int32_t mean_rate;
571 + u_int8_t acceptance_rate;
574 +#endif /*_IP6T_FUZZY_H*/
575 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
576 --- linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_nth.h 1970-01-01 01:00:00.000000000 +0100
577 +++ linux-2.6.7/include/linux/netfilter_ipv6/ip6t_nth.h 2004-06-29 12:32:16.699331848 +0200
582 +#include <linux/param.h>
583 +#include <linux/types.h>
585 +#ifndef IP6T_NTH_NUM_COUNTERS
586 +#define IP6T_NTH_NUM_COUNTERS 16
589 +struct ip6t_nth_info {
597 +#endif /*_IP6T_NTH_H*/
598 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
599 --- linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_owner.h 2004-06-16 07:19:37.000000000 +0200
600 +++ linux-2.6.7/include/linux/netfilter_ipv6/ip6t_owner.h 2004-06-29 12:35:37.769764496 +0200
602 #define IP6T_OWNER_GID 0x02
603 #define IP6T_OWNER_PID 0x04
604 #define IP6T_OWNER_SID 0x08
605 +#define IP6T_OWNER_COMM 0x10
607 struct ip6t_owner_info {
613 u_int8_t match, invert; /* flags */
616 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
617 --- linux-2.6.7.org/include/linux/netfilter_ipv6/ip6t_policy.h 1970-01-01 01:00:00.000000000 +0100
618 +++ linux-2.6.7/include/linux/netfilter_ipv6/ip6t_policy.h 2004-06-29 12:35:40.046418392 +0200
620 +#ifndef _IP6T_POLICY_H
621 +#define _IP6T_POLICY_H
623 +#define POLICY_MAX_ELEM 4
625 +enum ip6t_policy_flags
627 + POLICY_MATCH_IN = 0x1,
628 + POLICY_MATCH_OUT = 0x2,
629 + POLICY_MATCH_NONE = 0x4,
630 + POLICY_MATCH_STRICT = 0x8,
633 +enum ip6t_policy_modes
635 + POLICY_MODE_TRANSPORT,
639 +struct ip6t_policy_spec
649 +struct ip6t_policy_elem
651 + struct in6_addr saddr;
652 + struct in6_addr smask;
653 + struct in6_addr daddr;
654 + struct in6_addr dmask;
660 + struct ip6t_policy_spec match;
661 + struct ip6t_policy_spec invert;
664 +struct ip6t_policy_info
666 + struct ip6t_policy_elem pol[POLICY_MAX_ELEM];
671 +#endif /* _IP6T_POLICY_H */
672 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/sysctl.h linux-2.6.7/include/linux/sysctl.h
673 --- linux-2.6.7.org/include/linux/sysctl.h 2004-06-29 12:24:13.353811536 +0200
674 +++ linux-2.6.7/include/linux/sysctl.h 2004-06-29 12:32:11.293153712 +0200
676 NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24,
677 NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25,
678 NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26,
679 + NET_IPV4_NF_CONNTRACK_COUNT=27,
682 /* /proc/sys/net/ipv6 */
683 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/net/tcp.h linux-2.6.7/include/net/tcp.h
684 --- linux-2.6.7.org/include/net/tcp.h 2004-06-29 12:24:13.429799984 +0200
685 +++ linux-2.6.7/include/net/tcp.h 2004-06-29 12:35:34.488263360 +0200
687 extern void tcp_bucket_unlock(struct sock *sk);
688 extern int tcp_port_rover;
689 extern struct sock *tcp_v4_lookup_listener(u32 addr, unsigned short hnum, int dif);
690 +extern struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 hnum, int dif);
692 /* These are AF independent. */
693 static __inline__ int tcp_bhashfn(__u16 lport)
694 diff -Nur --exclude '*.orig' linux-2.6.7.org/include/net/udp.h linux-2.6.7/include/net/udp.h
695 --- linux-2.6.7.org/include/net/udp.h 2004-06-16 07:19:51.000000000 +0200
696 +++ linux-2.6.7/include/net/udp.h 2004-06-29 12:35:34.490263056 +0200
698 extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
699 extern int udp_disconnect(struct sock *sk, int flags);
701 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
703 DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
704 #define UDP_INC_STATS(field) SNMP_INC_STATS(udp_statistics, field)
705 #define UDP_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_statistics, field)
706 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/Kconfig linux-2.6.7/net/ipv4/netfilter/Kconfig
707 --- linux-2.6.7.org/net/ipv4/netfilter/Kconfig 2004-06-29 12:24:13.000000000 +0200
708 +++ linux-2.6.7/net/ipv4/netfilter/Kconfig 2004-06-29 12:36:14.610163904 +0200
711 To compile it as a module, choose M here. If unsure, say N.
713 +config IP_NF_MATCH_UNCLEAN
714 + tristate 'unclean match support (EXPERIMENTAL)'
715 + depends on EXPERIMENTAL && IP_NF_IPTABLES
718 config IP_NF_MATCH_TTL
719 tristate "TTL match support"
720 depends on IP_NF_IPTABLES
721 @@ -627,5 +632,246 @@
722 If you want to compile it as a module, say M here and read
723 Documentation/modules.txt. If unsure, say `N'.
725 +config IP_NF_TARGET_IPV4OPTSSTRIP
726 + tristate 'IPV4OPTSSTRIP target support'
727 + depends on IP_NF_MANGLE
729 + This option adds an IPV4OPTSSTRIP target.
730 + This target allows you to strip all IP options in a packet.
732 + If you want to compile it as a module, say M here and read
733 + Documentation/modules.txt. If unsure, say `N'.
735 +config IP_NF_TARGET_TTL
736 + tristate 'TTL target support'
737 + depends on IP_NF_MANGLE
739 + This option adds a `TTL' target, which enables the user to set
740 + the TTL value or increment / decrement the TTL value by a given
743 + If you want to compile it as a module, say M here and read
744 + Documentation/modules.txt. If unsure, say `N'.
746 +config IP_NF_MATCH_CONNLIMIT
747 + tristate 'Connections/IP limit match support'
748 + depends on IP_NF_IPTABLES
750 + This match allows you to restrict the number of parallel TCP
751 + connections to a server per client IP address (or address block).
753 + If you want to compile it as a module, say M here and read
754 + Documentation/modules.txt. If unsure, say `N'.
756 +config IP_NF_MATCH_DSTLIMIT
757 + tristate 'dstlimit match support'
758 + depends on IP_NF_IPTABLES
760 +config IP_NF_MATCH_FUZZY
761 + tristate 'fuzzy match support'
762 + depends on IP_NF_IPTABLES
764 + This option adds a `fuzzy' match, which allows you to match
765 + packets according to a fuzzy logic based law.
767 + If you want to compile it as a module, say M here and read
768 + Documentation/modules.txt. If unsure, say `N'.
770 +config IP_NF_MATCH_IPV4OPTIONS
771 + tristate 'IPV4OPTIONS match support'
772 + depends on IP_NF_IPTABLES
774 + This option adds a IPV4OPTIONS match.
775 + It allows you to filter options like source routing,
776 + record route, timestamp and router-altert.
778 + If you say Y here, try iptables -m ipv4options --help for more information.
780 + If you want to compile it as a module, say M here and read
781 + Documentation/modules.txt. If unsure, say `N'.
783 +config IP_NF_MATCH_MPORT
784 + tristate 'Multiple port with ranges match support'
785 + depends on IP_NF_IPTABLES
787 + This is an enhanced multiport match which supports port
788 + ranges as well as single ports.
790 + If you want to compile it as a module, say M here and read
791 + Documentation/modules.txt. If unsure, say `N'.
793 +config IP_NF_MATCH_NTH
794 + tristate 'Nth match support'
795 + depends on IP_NF_IPTABLES
797 + This option adds a `Nth' match, which allow you to make
798 + rules that match every Nth packet. By default there are
799 + 16 different counters.
802 + --every Nth Match every Nth packet
803 + [--counter] num Use counter 0-15 (default:0)
804 + [--start] num Initialize the counter at the number 'num'
805 + instead of 0. Must be between 0 and Nth-1
806 + [--packet] num Match on 'num' packet. Must be between 0
809 + If --packet is used for a counter than
810 + there must be Nth number of --packet
811 + rules, covering all values between 0 and
814 + If you want to compile it as a module, say M here and read
815 + Documentation/modules.txt. If unsure, say `N'.
817 +config IP_NF_MATCH_PSD
818 + tristate 'psd match support'
819 + depends on IP_NF_IPTABLES
821 + This option adds a `psd' match, which allows you to create rules in
822 + any iptables table wich will detect TCP and UDP port scans.
824 + If you want to compile it as a module, say M here and read
825 + Documentation/modules.txt. If unsure, say `N'.
827 +config IP_NF_MATCH_QUOTA
828 + tristate 'quota match support'
829 + depends on IP_NF_IPTABLES
831 + This match implements network quotas.
833 + If you want to compile it as a module, say M here and read
834 + Documentation/modules.txt. If unsure, say `N'.
837 +config IP_NF_MATCH_SCTP
838 + tristate 'SCTP protocol match support'
839 + depends on IP_NF_IPTABLES
841 +config IP_NF_MATCH_TIME
842 + tristate 'TIME match support'
843 + depends on IP_NF_IPTABLES
845 + This option adds a `time' match, which allows you
846 + to match based on the packet arrival time/date
847 + (arrival time/date at the machine which netfilter is running on) or
848 + departure time/date (for locally generated packets).
850 + If you say Y here, try iptables -m time --help for more information.
852 + If you want to compile it as a module, say M here and read
853 + Documentation/modules.txt. If unsure, say `N'.
855 +config IP_NF_CONNTRACK_MARK
856 + bool 'Connection mark tracking support'
858 + This option enables support for connection marks, used by the
859 + `CONNMARK' target and `connmark' match. Similar to the mark value
860 + of packets, but this mark value is kept in the conntrack session
861 + instead of the individual packets.
863 +config IP_NF_TARGET_CONNMARK
864 + tristate 'CONNMARK target support'
865 + depends on IP_NF_CONNTRACK_MARK && IP_NF_MANGLE
867 + This option adds a `CONNMARK' target, which allows one to manipulate
868 + the connection mark value. Similar to the MARK target, but
869 + affects the connection mark value rather than the packet mark value.
871 + If you want to compile it as a module, say M here and read
872 + Documentation/modules.txt. The module will be called
873 + ipt_CONNMARK.o. If unsure, say `N'.
875 +config IP_NF_MATCH_CONNMARK
876 + tristate ' Connection mark match support'
877 + depends on IP_NF_CONNTRACK_MARK && IP_NF_IPTABLES
879 + This option adds a `connmark' match, which allows you to match the
880 + connection mark value previously set for the session by `CONNMARK'.
882 + If you want to compile it as a module, say M here and read
883 + Documentation/modules.txt. The module will be called
884 + ipt_connmark.o. If unsure, say `N'.
886 +config IP_NF_TARGET_IPMARK
887 + tristate 'IPMARK target support'
888 + depends on IP_NF_MANGLE
890 + This option adds a `IPMARK' target, which allows you to create rules
891 + in the `mangle' table which alter the netfilter mark (nfmark) field
892 + basing on the source or destination ip address of the packet.
893 + This is very useful for very fast massive mangling and marking.
895 + If you want to compile it as a module, say M here and read
896 + <file:Documentation/modules.txt>. If unsure, say `N'.
898 +config IP_NF_TARGET_ROUTE
899 + tristate 'ROUTE target support'
900 + depends on IP_NF_MANGLE
902 + This option adds a `ROUTE' target, which enables you to setup unusual
903 + routes. For example, the ROUTE lets you route a received packet through
904 + an interface or towards a host, even if the regular destination of the
905 + packet is the router itself. The ROUTE target is also able to change the
906 + incoming interface of a packet.
908 + The target can be or not a final target. It has to be used inside the
911 + If you want to compile it as a module, say M here and read
912 + Documentation/modules.txt. The module will be called ipt_ROUTE.o.
913 + If unsure, say `N'.
915 +config IP_NF_TARGET_TARPIT
916 + tristate 'TARPIT target support'
917 + depends on IP_NF_FILTER
919 + Adds a TARPIT target to iptables, which captures and holds
920 + incoming TCP connections using no local per-connection resources.
921 + Connections are accepted, but immediately switched to the persist
922 + state (0 byte window), in which the remote side stops sending data
923 + and asks to continue every 60-240 seconds. Attempts to close the
924 + connection are ignored, forcing the remote side to time out the
925 + connection in 12-24 minutes.
927 + This offers similar functionality to LaBrea
928 + <http://www.hackbusters.net/LaBrea/> but doesn't require dedicated
929 + hardware or IPs. Any TCP port that you would normally DROP or REJECT
930 + can instead become a tarpit.
932 +config IP_NF_TARGET_XOR
933 + tristate 'XOR target support'
934 + depends on IP_NF_MANGLE
936 + This option adds a `XOR' target, which can encrypt TCP and
937 + UDP traffic using a simple XOR encryption.
939 + If you want to compile it as a module, say M here and read
940 + Documentation/modules.txt. If unsure, say `N'.
942 +config IP_NF_MATCH_POLICY
943 + tristate "IPsec policy match support"
944 + depends on IP_NF_IPTABLES && XFRM
946 + Policy matching allows you to match packets based on the
947 + IPsec policy that was used during decapsulation/will
948 + be used during encapsulation.
950 + To compile it as a module, choose M here. If unsure, say N.
952 +config IP_NF_CT_PROTO_SCTP
953 + tristate 'SCTP protocol connection tracking support'
954 + depends on IP_NF_CONNTRACK
956 +config IP_NF_MATCH_STRING
957 + tristate 'String match support'
958 + depends on IP_NF_IPTABLES
960 + String matching alows you to match packets which contain a
961 + specified string of characters.
963 + If you want to compile it as a module, say M here and read
964 + Documentation/modules.txt. If unsure, say `N'.
968 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/netfilter/Makefile linux-2.6.7/net/ipv4/netfilter/Makefile
969 --- linux-2.6.7.org/net/ipv4/netfilter/Makefile 2004-06-29 12:24:13.000000000 +0200
970 +++ linux-2.6.7/net/ipv4/netfilter/Makefile 2004-06-29 12:36:14.615163144 +0200
972 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
973 obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
974 obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o
975 +obj-$(CONFIG_IP_NF_MATCH_QUOTA) += ipt_quota.o
976 +obj-$(CONFIG_IP_NF_MATCH_DSTLIMIT) += ipt_dstlimit.o
977 obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
978 obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
979 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
981 obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
982 obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
983 +obj-$(CONFIG_IP_NF_MATCH_MPORT) += ipt_mport.o
984 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
985 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
986 +obj-$(CONFIG_IP_NF_MATCH_TIME) += ipt_time.o
987 +obj-$(CONFIG_IP_NF_MATCH_PSD) += ipt_psd.o
988 +obj-$(CONFIG_IP_NF_MATCH_NTH) += ipt_nth.o
989 +obj-$(CONFIG_IP_NF_MATCH_IPV4OPTIONS) += ipt_ipv4options.o
990 +obj-$(CONFIG_IP_NF_MATCH_FUZZY) += ipt_fuzzy.o
992 obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
996 obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o
998 +obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o
999 +obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o
1000 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
1001 obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
1002 +obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o
1003 +obj-$(CONFIG_IP_NF_MATCH_CONNLIMIT) += ipt_connlimit.o
1004 obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
1005 obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
1006 obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
1007 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
1009 obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
1010 +obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o
1013 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
1014 +obj-$(CONFIG_IP_NF_TARGET_TARPIT) += ipt_TARPIT.o
1015 obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
1016 obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
1017 obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o
1018 obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o
1019 +obj-$(CONFIG_IP_NF_TARGET_IPMARK) += ipt_IPMARK.o
1020 obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
1021 obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
1022 +obj-$(CONFIG_IP_NF_TARGET_ROUTE) += ipt_ROUTE.o
1023 obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
1024 obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o
1025 obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
1026 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
1027 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
1028 +obj-$(CONFIG_IP_NF_TARGET_XOR) += ipt_XOR.o
1029 +obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o
1030 +obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
1031 +obj-$(CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP) += ipt_IPV4OPTSSTRIP.o
1032 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
1033 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
1034 obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o
1035 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
1036 --- linux-2.6.7.org/net/ipv4/netfilter/ip_conntrack_core.c 2004-06-29 12:24:13.000000000 +0200
1037 +++ linux-2.6.7/net/ipv4/netfilter/ip_conntrack_core.c 2004-06-29 12:34:21.572348264 +0200
1039 __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
1040 conntrack->master = expected;
1041 expected->sibling = conntrack;
1042 +#if CONFIG_IP_NF_CONNTRACK_MARK
1043 + conntrack->mark = expected->expectant->mark;
1045 LIST_DELETE(&ip_conntrack_expect_list, expected);
1046 expected->expectant->expecting--;
1047 nf_conntrack_get(&master_ct(conntrack)->infos[0]);
1048 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
1049 --- linux-2.6.7.org/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-06-29 12:24:13.000000000 +0200
1050 +++ linux-2.6.7/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-06-29 12:34:21.566349176 +0200
1051 @@ -169,7 +169,15 @@
1052 if (seq_printf(s, "[ASSURED] "))
1055 - if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use)))
1056 + if (seq_printf(s, "use=%u ", atomic_read(&conntrack->ct_general.use)))
1059 +#ifdef CONFIG_IP_NF_CONNTRACK_MARK
1060 + if (seq_printf(s, "mark=%ld ", conntrack->mark))
1064 + if (seq_printf(s, "\n"))
1070 /* From ip_conntrack_core.c */
1071 extern int ip_conntrack_max;
1072 +extern atomic_t ip_conntrack_count;
1073 extern unsigned int ip_conntrack_htable_size;
1075 /* From ip_conntrack_proto_tcp.c */
1076 @@ -537,6 +546,14 @@
1077 .proc_handler = &proc_dointvec,
1080 + .ctl_name = NET_IPV4_NF_CONNTRACK_COUNT,
1081 + .procname = "ip_conntrack_count",
1082 + .data = &ip_conntrack_count,
1083 + .maxlen = sizeof(int),
1085 + .proc_handler = &proc_dointvec,
1088 .ctl_name = NET_IPV4_NF_CONNTRACK_BUCKETS,
1089 .procname = "ip_conntrack_buckets",
1090 .data = &ip_conntrack_htable_size,
1091 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
1092 --- linux-2.6.7.org/net/ipv4/netfilter/ip_queue.c 2004-06-16 07:20:26.000000000 +0200
1093 +++ linux-2.6.7/net/ipv4/netfilter/ip_queue.c 2004-06-29 12:35:08.146267952 +0200
1094 @@ -421,6 +421,33 @@
1098 +ipq_set_vwmark(struct ipq_vwmark_msg *vmsg, unsigned int len)
1100 + struct ipq_queue_entry *entry;
1102 + if (vmsg->value > NF_MAX_VERDICT)
1105 + entry = ipq_find_dequeue_entry(id_cmp, vmsg->id);
1106 + if (entry == NULL)
1109 + int verdict = vmsg->value;
1111 + if (vmsg->data_len && vmsg->data_len == len)
1112 + if (ipq_mangle_ipv4((ipq_verdict_msg_t *)vmsg, entry) < 0)
1113 + verdict = NF_DROP;
1115 + /* set mark of associated skb */
1116 + entry->skb->nfmark = vmsg->nfmark;
1118 + ipq_issue_verdict(entry, verdict);
1125 ipq_receive_peer(struct ipq_peer_msg *pmsg,
1126 unsigned char type, unsigned int len)
1128 @@ -442,6 +469,14 @@
1129 status = ipq_set_verdict(&pmsg->msg.verdict,
1130 len - sizeof(*pmsg));
1133 + if (pmsg->msg.verdict.value > NF_MAX_VERDICT)
1136 + status = ipq_set_vwmark(&pmsg->msg.vwmark,
1137 + len - sizeof(*pmsg));
1143 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
1144 --- linux-2.6.7.org/net/ipv4/netfilter/ip_tables.c 2004-06-29 12:24:13.000000000 +0200
1145 +++ linux-2.6.7/net/ipv4/netfilter/ip_tables.c 2004-06-29 12:35:27.076390136 +0200
1147 * it under the terms of the GNU General Public License version 2 as
1148 * published by the Free Software Foundation.
1150 + * 6 Mar 2002 Robert Olsson <robban@robtex.com>
1151 + * 17 Apr 2003 Chris Wilson <chris@netservers.co.uk>
1152 + * - mark_source_chains speedup for complex chains
1154 * 19 Jan 2002 Harald Welte <laforge@gnumonks.org>
1155 * - increase module usage count as soon as we have rules inside
1161 + /* keep track of where we have been: */
1162 + unsigned char *been = vmalloc(newinfo->size);
1164 /* No recursion; use packet counter to save back ptrs (reset
1165 to 0 as we leave), and comefrom to save source hook bitmask */
1166 for (hook = 0; hook < NF_IP_NUMHOOKS; hook++) {
1169 /* Set initial back pointer. */
1170 e->counters.pcnt = pos;
1171 + memset(been, 0, newinfo->size);
1174 struct ipt_standard_target *t
1176 if (e->comefrom & (1 << NF_IP_NUMHOOKS)) {
1177 printk("iptables: loop hook %u pos %u %08X.\n",
1178 hook, pos, e->comefrom);
1183 @@ -562,10 +571,14 @@
1185 int newpos = t->verdict;
1187 - if (strcmp(t->target.u.user.name,
1188 + if ( (pos < 0 || pos >= newinfo->size
1190 + && strcmp(t->target.u.user.name,
1191 IPT_STANDARD_TARGET) == 0
1193 /* This a jump; chase it. */
1194 + if (pos >= 0 && pos < newinfo->size)
1196 duprintf("Jump rule %u -> %u\n",
1201 duprintf("Finished chain %u\n", hook);
1207 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
1208 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_CONNMARK.c 1970-01-01 01:00:00.000000000 +0100
1209 +++ linux-2.6.7/net/ipv4/netfilter/ipt_CONNMARK.c 2004-06-29 12:34:21.512357384 +0200
1211 +/* This kernel module is used to modify the connection mark values, or
1212 + * to optionally restore the skb nfmark from the connection mark
1214 + * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
1215 + * by Henrik Nordstrom <hno@marasystems.com>
1217 + * This program is free software; you can redistribute it and/or modify
1218 + * it under the terms of the GNU General Public License as published by
1219 + * the Free Software Foundation; either version 2 of the License, or
1220 + * (at your option) any later version.
1222 + * This program is distributed in the hope that it will be useful,
1223 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1224 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1225 + * GNU General Public License for more details.
1227 + * You should have received a copy of the GNU General Public License
1228 + * along with this program; if not, write to the Free Software
1229 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1231 +#include <linux/module.h>
1232 +#include <linux/skbuff.h>
1233 +#include <linux/ip.h>
1234 +#include <net/checksum.h>
1236 +MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
1237 +MODULE_DESCRIPTION("IP tables CONNMARK matching module");
1238 +MODULE_LICENSE("GPL");
1240 +#include <linux/netfilter_ipv4/ip_tables.h>
1241 +#include <linux/netfilter_ipv4/ipt_CONNMARK.h>
1242 +#include <linux/netfilter_ipv4/ip_conntrack.h>
1244 +static unsigned int
1245 +target(struct sk_buff **pskb,
1246 + const struct net_device *in,
1247 + const struct net_device *out,
1248 + unsigned int hooknum,
1249 + const void *targinfo,
1252 + const struct ipt_connmark_target_info *markinfo = targinfo;
1253 + unsigned long diff;
1254 + unsigned long nfmark;
1255 + unsigned long newmark;
1257 + enum ip_conntrack_info ctinfo;
1258 + struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo);
1260 + switch(markinfo->mode) {
1261 + case IPT_CONNMARK_SET:
1262 + newmark = (ct->mark & ~markinfo->mask) | markinfo->mark;
1263 + if (newmark != ct->mark)
1264 + ct->mark = newmark;
1266 + case IPT_CONNMARK_SAVE:
1267 + newmark = (ct->mark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask);
1268 + if (ct->mark != newmark)
1269 + ct->mark = newmark;
1271 + case IPT_CONNMARK_RESTORE:
1272 + nfmark = (*pskb)->nfmark;
1273 + diff = (ct->mark ^ nfmark & markinfo->mask);
1275 + (*pskb)->nfmark = nfmark ^ diff;
1276 + (*pskb)->nfcache |= NFC_ALTERED;
1282 + return IPT_CONTINUE;
1286 +checkentry(const char *tablename,
1287 + const struct ipt_entry *e,
1289 + unsigned int targinfosize,
1290 + unsigned int hook_mask)
1292 + struct ipt_connmark_target_info *matchinfo = targinfo;
1293 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) {
1294 + printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n",
1296 + IPT_ALIGN(sizeof(struct ipt_connmark_target_info)));
1300 + if (matchinfo->mode == IPT_CONNMARK_RESTORE) {
1301 + if (strcmp(tablename, "mangle") != 0) {
1302 + printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1310 +static struct ipt_target ipt_connmark_reg = {
1311 + .name = "CONNMARK",
1312 + .target = &target,
1313 + .checkentry = &checkentry,
1317 +static int __init init(void)
1319 + return ipt_register_target(&ipt_connmark_reg);
1322 +static void __exit fini(void)
1324 + ipt_unregister_target(&ipt_connmark_reg);
1329 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
1330 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_IPMARK.c 1970-01-01 01:00:00.000000000 +0100
1331 +++ linux-2.6.7/net/ipv4/netfilter/ipt_IPMARK.c 2004-06-29 12:34:27.609430488 +0200
1333 +/* This is a module which is used for setting the NFMARK field of an skb. */
1334 +#include <linux/module.h>
1335 +#include <linux/skbuff.h>
1336 +#include <linux/ip.h>
1337 +#include <net/checksum.h>
1339 +#include <linux/netfilter_ipv4/ip_tables.h>
1340 +#include <linux/netfilter_ipv4/ipt_IPMARK.h>
1342 +MODULE_AUTHOR("Grzegorz Janoszka <Grzegorz.Janoszka@pro.onet.pl>");
1343 +MODULE_DESCRIPTION("IP tables IPMARK: mark based on ip address");
1344 +MODULE_LICENSE("GPL");
1346 +static unsigned int
1347 +target(struct sk_buff **pskb,
1348 + const struct net_device *in,
1349 + const struct net_device *out,
1350 + unsigned int hooknum,
1351 + const void *targinfo,
1354 + const struct ipt_ipmark_target_info *ipmarkinfo = targinfo;
1355 + struct iphdr *iph = (*pskb)->nh.iph;
1356 + unsigned long mark;
1358 + if (ipmarkinfo->addr == IPT_IPMARK_SRC)
1359 + mark = (unsigned long) ntohl(iph->saddr);
1361 + mark = (unsigned long) ntohl(iph->daddr);
1363 + mark &= ipmarkinfo->andmask;
1364 + mark |= ipmarkinfo->ormask;
1366 + if ((*pskb)->nfmark != mark) {
1367 + (*pskb)->nfmark = mark;
1368 + (*pskb)->nfcache |= NFC_ALTERED;
1370 + return IPT_CONTINUE;
1374 +checkentry(const char *tablename,
1375 + const struct ipt_entry *e,
1377 + unsigned int targinfosize,
1378 + unsigned int hook_mask)
1380 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ipmark_target_info))) {
1381 + printk(KERN_WARNING "IPMARK: targinfosize %u != %Zu\n",
1383 + IPT_ALIGN(sizeof(struct ipt_ipmark_target_info)));
1387 + if (strcmp(tablename, "mangle") != 0) {
1388 + printk(KERN_WARNING "IPMARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1395 +static struct ipt_target ipt_ipmark_reg = {
1398 + .checkentry = checkentry,
1402 +static int __init init(void)
1404 + return ipt_register_target(&ipt_ipmark_reg);
1407 +static void __exit fini(void)
1409 + ipt_unregister_target(&ipt_ipmark_reg);
1414 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
1415 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 1970-01-01 01:00:00.000000000 +0100
1416 +++ linux-2.6.7/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 2004-06-29 12:32:01.665617320 +0200
1419 + * Strip all IP options in the IP packet header.
1421 + * (C) 2001 by Fabrice MARIE <fabrice@netfilter.org>
1422 + * This software is distributed under GNU GPL v2, 1991
1425 +#include <linux/module.h>
1426 +#include <linux/skbuff.h>
1427 +#include <net/ip.h>
1428 +#include <net/checksum.h>
1430 +#include <linux/netfilter_ipv4/ip_tables.h>
1432 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
1433 +MODULE_DESCRIPTION("Strip all options in IPv4 packets");
1434 +MODULE_LICENSE("GPL");
1436 +static unsigned int
1437 +target(struct sk_buff **pskb,
1438 + const struct net_device *in,
1439 + const struct net_device *out,
1440 + unsigned int hooknum,
1441 + const void *targinfo,
1444 + struct iphdr *iph;
1445 + struct sk_buff *skb;
1446 + struct ip_options *opt;
1447 + unsigned char *optiph;
1450 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
1454 + iph = (*pskb)->nh.iph;
1455 + optiph = skb->nh.raw;
1456 + l = ((struct ip_options *)(&(IPCB(skb)->opt)))->optlen;
1458 + /* if no options in packet then nothing to clear. */
1459 + if (iph->ihl * 4 == sizeof(struct iphdr))
1460 + return IPT_CONTINUE;
1462 + /* else clear all options */
1463 + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
1464 + memset(optiph+sizeof(struct iphdr), IPOPT_NOOP, l);
1465 + opt = &(IPCB(skb)->opt);
1469 + skb->nfcache |= NFC_ALTERED;
1471 + return IPT_CONTINUE;
1475 +checkentry(const char *tablename,
1476 + const struct ipt_entry *e,
1478 + unsigned int targinfosize,
1479 + unsigned int hook_mask)
1481 + if (strcmp(tablename, "mangle")) {
1482 + printk(KERN_WARNING "IPV4OPTSSTRIP: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1485 + /* nothing else to check because no parameters */
1489 +static struct ipt_target ipt_ipv4optsstrip_reg = {
1490 + .name = "IPV4OPTSSTRIP",
1492 + .checkentry = checkentry,
1493 + .me = THIS_MODULE };
1495 +static int __init init(void)
1497 + return ipt_register_target(&ipt_ipv4optsstrip_reg);
1500 +static void __exit fini(void)
1502 + ipt_unregister_target(&ipt_ipv4optsstrip_reg);
1507 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
1508 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_ROUTE.c 1970-01-01 01:00:00.000000000 +0100
1509 +++ linux-2.6.7/net/ipv4/netfilter/ipt_ROUTE.c 2004-06-29 12:34:33.511533232 +0200
1512 + * This implements the ROUTE target, which enables you to setup unusual
1513 + * routes not supported by the standard kernel routing table.
1515 + * Copyright (C) 2002 Cedric de Launois <delaunois@info.ucl.ac.be>
1517 + * v 1.9 2004/05/14
1519 + * This software is distributed under GNU GPL v2, 1991
1522 +#include <linux/module.h>
1523 +#include <linux/skbuff.h>
1524 +#include <linux/ip.h>
1525 +#include <linux/netfilter_ipv4/ip_tables.h>
1526 +#include <linux/netfilter_ipv4/ipt_ROUTE.h>
1527 +#include <linux/netdevice.h>
1528 +#include <linux/route.h>
1529 +#include <net/ip.h>
1530 +#include <net/route.h>
1531 +#include <net/icmp.h>
1532 +#include <net/checksum.h>
1535 +#define DEBUGP printk
1537 +#define DEBUGP(format, args...)
1540 +MODULE_LICENSE("GPL");
1541 +MODULE_AUTHOR("Cedric de Launois <delaunois@info.ucl.ac.be>");
1542 +MODULE_DESCRIPTION("iptables ROUTE target module");
1544 +/* Try to route the packet according to the routing keys specified in
1545 + * route_info. Keys are :
1547 + * 0 if no oif preferred,
1548 + * otherwise set to the index of the desired oif
1549 + * - route_info->gw :
1550 + * 0 if no gateway specified,
1551 + * otherwise set to the next host to which the pkt must be routed
1552 + * If success, skb->dev is the output device to which the packet must
1553 + * be sent and skb->dst is not NULL
1555 + * RETURN: -1 if an error occured
1556 + * 1 if the packet was succesfully routed to the
1557 + * destination desired
1558 + * 0 if the kernel routing table could not route the packet
1559 + * according to the keys specified
1561 +static int route(struct sk_buff *skb,
1562 + unsigned int ifindex,
1563 + const struct ipt_route_target_info *route_info)
1566 + struct rtable *rt;
1567 + struct iphdr *iph = skb->nh.iph;
1568 + struct flowi fl = {
1572 + .daddr = iph->daddr,
1574 + .tos = RT_TOS(iph->tos),
1575 + .scope = RT_SCOPE_UNIVERSE,
1580 + /* The destination address may be overloaded by the target */
1581 + if (route_info->gw)
1582 + fl.fld_dst = route_info->gw;
1584 + /* Trying to route the packet using the standard routing table. */
1585 + if ((err = ip_route_output_key(&rt, &fl))) {
1586 + if (net_ratelimit())
1587 + DEBUGP("ipt_ROUTE: couldn't route pkt (err: %i)",err);
1591 + /* Drop old route. */
1592 + dst_release(skb->dst);
1595 + /* Success if no oif specified or if the oif correspond to the
1597 + if (!ifindex || rt->u.dst.dev->ifindex == ifindex) {
1598 + skb->dst = &rt->u.dst;
1599 + skb->dev = skb->dst->dev;
1603 + /* The interface selected by the routing table is not the one
1604 + * specified by the user. This may happen because the dst address
1605 + * is one of our own addresses.
1607 + if (net_ratelimit())
1608 + DEBUGP("ipt_ROUTE: failed to route as desired gw=%u.%u.%u.%u oif=%i (got oif=%i)\n",
1609 + NIPQUAD(route_info->gw), ifindex, rt->u.dst.dev->ifindex);
1615 +/* Stolen from ip_finish_output2
1616 + * PRE : skb->dev is set to the device we are leaving by
1617 + * skb->dst is not NULL
1618 + * POST: the packet is sent with the link layer header pushed
1619 + * the packet is destroyed
1621 +static void ip_direct_send(struct sk_buff *skb)
1623 + struct dst_entry *dst = skb->dst;
1624 + struct hh_cache *hh = dst->hh;
1627 + read_lock_bh(&hh->hh_lock);
1628 + memcpy(skb->data - 16, hh->hh_data, 16);
1629 + read_unlock_bh(&hh->hh_lock);
1630 + skb_push(skb, hh->hh_len);
1631 + hh->hh_output(skb);
1632 + } else if (dst->neighbour)
1633 + dst->neighbour->output(skb);
1635 + if (net_ratelimit())
1636 + DEBUGP(KERN_DEBUG "ipt_ROUTE: no hdr & no neighbour cache!\n");
1642 +/* PRE : skb->dev is set to the device we are leaving by
1643 + * POST: - the packet is directly sent to the skb->dev device, without
1644 + * pushing the link layer header.
1645 + * - the packet is destroyed
1647 +static inline int dev_direct_send(struct sk_buff *skb)
1649 + return dev_queue_xmit(skb);
1653 +static unsigned int route_oif(const struct ipt_route_target_info *route_info,
1654 + struct sk_buff *skb)
1656 + unsigned int ifindex = 0;
1657 + struct net_device *dev_out = NULL;
1659 + /* The user set the interface name to use.
1660 + * Getting the current interface index.
1662 + if ((dev_out = dev_get_by_name(route_info->oif))) {
1663 + ifindex = dev_out->ifindex;
1665 + /* Unknown interface name : packet dropped */
1666 + if (net_ratelimit())
1667 + DEBUGP("ipt_ROUTE: oif interface %s not found\n", route_info->oif);
1671 + /* Trying the standard way of routing packets */
1672 + switch (route(skb, ifindex, route_info)) {
1675 + if (route_info->flags & IPT_ROUTE_CONTINUE)
1676 + return IPT_CONTINUE;
1678 + ip_direct_send(skb);
1682 + /* Failed to send to oif. Trying the hard way */
1683 + if (route_info->flags & IPT_ROUTE_CONTINUE)
1686 + if (net_ratelimit())
1687 + DEBUGP("ipt_ROUTE: forcing the use of %i\n",
1690 + /* We have to force the use of an interface.
1691 + * This interface must be a tunnel interface since
1692 + * otherwise we can't guess the hw address for
1693 + * the packet. For a tunnel interface, no hw address
1696 + if ((dev_out->type != ARPHRD_TUNNEL)
1697 + && (dev_out->type != ARPHRD_IPGRE)) {
1698 + if (net_ratelimit())
1699 + DEBUGP("ipt_ROUTE: can't guess the hw addr !\n");
1704 + /* Send the packet. This will also free skb
1705 + * Do not go through the POST_ROUTING hook because
1706 + * skb->dst is not set and because it will probably
1707 + * get confused by the destination IP address.
1709 + skb->dev = dev_out;
1710 + dev_direct_send(skb);
1715 + /* Unexpected error */
1722 +static unsigned int route_iif(const struct ipt_route_target_info *route_info,
1723 + struct sk_buff *skb)
1725 + struct net_device *dev_in = NULL;
1727 + /* Getting the current interface index. */
1728 + if (!(dev_in = dev_get_by_name(route_info->iif))) {
1729 + if (net_ratelimit())
1730 + DEBUGP("ipt_ROUTE: iif interface %s not found\n", route_info->iif);
1734 + skb->dev = dev_in;
1735 + dst_release(skb->dst);
1744 +static unsigned int route_gw(const struct ipt_route_target_info *route_info,
1745 + struct sk_buff *skb)
1747 + if (route(skb, 0, route_info)!=1)
1750 + if (route_info->flags & IPT_ROUTE_CONTINUE)
1751 + return IPT_CONTINUE;
1753 + ip_direct_send(skb);
1758 +static unsigned int ipt_route_target(struct sk_buff **pskb,
1759 + const struct net_device *in,
1760 + const struct net_device *out,
1761 + unsigned int hooknum,
1762 + const void *targinfo,
1765 + const struct ipt_route_target_info *route_info = targinfo;
1766 + struct sk_buff *skb = *pskb;
1768 + /* If we are at PREROUTING or INPUT hook
1769 + * the TTL isn't decreased by the IP stack
1771 + if (hooknum == NF_IP_PRE_ROUTING ||
1772 + hooknum == NF_IP_LOCAL_IN) {
1774 + struct iphdr *iph = skb->nh.iph;
1776 + if (iph->ttl <= 1) {
1777 + struct rtable *rt;
1778 + struct flowi fl = {
1782 + .daddr = iph->daddr,
1783 + .saddr = iph->saddr,
1784 + .tos = RT_TOS(iph->tos),
1785 + .scope = ((iph->tos & RTO_ONLINK) ?
1787 + RT_SCOPE_UNIVERSE)
1792 + if (ip_route_output_key(&rt, &fl)) {
1796 + if (skb->dev == rt->u.dst.dev) {
1797 + /* Drop old route. */
1798 + dst_release(skb->dst);
1799 + skb->dst = &rt->u.dst;
1801 + /* this will traverse normal stack, and
1802 + * thus call conntrack on the icmp packet */
1803 + icmp_send(skb, ICMP_TIME_EXCEEDED,
1811 + * If we are at INPUT the checksum must be recalculated since
1812 + * the length could change as the result of a defragmentation.
1814 + if(hooknum == NF_IP_LOCAL_IN) {
1815 + iph->ttl = iph->ttl - 1;
1817 + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
1819 + ip_decrease_ttl(iph);
1823 + /* Tell conntrack to forget this packet since it may get confused
1824 + * when a packet is leaving with dst address == our address.
1825 + * Good idea ? Dunno. Need advice.
1827 + if (!(route_info->flags & IPT_ROUTE_CONTINUE)) {
1828 + nf_conntrack_put(skb->nfct);
1831 +#ifdef CONFIG_NETFILTER_DEBUG
1832 + skb->nf_debug = 0;
1836 + if (route_info->oif[0] != '\0')
1837 + return route_oif(route_info, *pskb);
1839 + if (route_info->iif[0] != '\0')
1840 + return route_iif(route_info, *pskb);
1842 + if (route_info->gw)
1843 + return route_gw(route_info, *pskb);
1845 + if (net_ratelimit())
1846 + DEBUGP(KERN_DEBUG "ipt_ROUTE: no parameter !\n");
1848 + return IPT_CONTINUE;
1852 +static int ipt_route_checkentry(const char *tablename,
1853 + const struct ipt_entry *e,
1855 + unsigned int targinfosize,
1856 + unsigned int hook_mask)
1858 + if (strcmp(tablename, "mangle") != 0) {
1859 + printk("ipt_ROUTE: bad table `%s', use the `mangle' table.\n",
1864 + if (hook_mask & ~( (1 << NF_IP_PRE_ROUTING)
1865 + | (1 << NF_IP_LOCAL_IN)
1866 + | (1 << NF_IP_FORWARD)
1867 + | (1 << NF_IP_LOCAL_OUT)
1868 + | (1 << NF_IP_POST_ROUTING))) {
1869 + printk("ipt_ROUTE: bad hook\n");
1873 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_route_target_info))) {
1874 + printk(KERN_WARNING "ipt_ROUTE: targinfosize %u != %Zu\n",
1876 + IPT_ALIGN(sizeof(struct ipt_route_target_info)));
1884 +static struct ipt_target ipt_route_reg = {
1886 + .target = ipt_route_target,
1887 + .checkentry = ipt_route_checkentry,
1888 + .me = THIS_MODULE,
1891 +static int __init init(void)
1893 + return ipt_register_target(&ipt_route_reg);
1897 +static void __exit fini(void)
1899 + ipt_unregister_target(&ipt_route_reg);
1904 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
1905 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_TARPIT.c 1970-01-01 01:00:00.000000000 +0100
1906 +++ linux-2.6.7/net/ipv4/netfilter/ipt_TARPIT.c 2004-06-29 12:34:39.109682184 +0200
1909 + * Kernel module to capture and hold incoming TCP connections using
1910 + * no local per-connection resources.
1912 + * Based on ipt_REJECT.c and offering functionality similar to
1913 + * LaBrea <http://www.hackbusters.net/LaBrea/>.
1915 + * Copyright (c) 2002 Aaron Hopkins <tools@die.net>
1917 + * This program is free software; you can redistribute it and/or modify
1918 + * it under the terms of the GNU General Public License as published by
1919 + * the Free Software Foundation; either version 2 of the License, or
1920 + * (at your option) any later version.
1922 + * This program is distributed in the hope that it will be useful,
1923 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1924 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1925 + * GNU General Public License for more details.
1927 + * You should have received a copy of the GNU General Public License
1928 + * along with this program; if not, write to the Free Software
1929 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1932 + * - Allow incoming TCP connections to be established.
1933 + * - Passing data should result in the connection being switched to the
1934 + * persist state (0 byte window), in which the remote side stops sending
1935 + * data and asks to continue every 60 seconds.
1936 + * - Attempts to shut down the connection should be ignored completely, so
1937 + * the remote side ends up having to time it out.
1940 + * - Reply to TCP SYN,!ACK,!RST,!FIN with SYN-ACK, window 5 bytes
1941 + * - Reply to TCP SYN,ACK,!RST,!FIN with RST to prevent spoofing
1942 + * - Reply to TCP !SYN,!RST,!FIN with ACK, window 0 bytes, rate-limited
1945 +#include <linux/config.h>
1946 +#include <linux/module.h>
1947 +#include <linux/skbuff.h>
1948 +#include <linux/ip.h>
1949 +#include <net/ip.h>
1950 +#include <net/tcp.h>
1951 +#include <net/icmp.h>
1953 +#include <net/route.h>
1954 +#include <linux/random.h>
1955 +#include <linux/netfilter_ipv4/ip_tables.h>
1958 +#define DEBUGP printk
1960 +#define DEBUGP(format, args...)
1963 +MODULE_LICENSE("GPL");
1964 +MODULE_AUTHOR("Aaron Hopkins <tools@die.net>");
1966 +/* Stolen from ip_finish_output2 */
1967 +static int ip_direct_send(struct sk_buff *skb)
1969 + struct dst_entry *dst = skb->dst;
1970 + struct hh_cache *hh = dst->hh;
1973 + read_lock_bh(&hh->hh_lock);
1974 + memcpy(skb->data - 16, hh->hh_data, 16);
1975 + read_unlock_bh(&hh->hh_lock);
1976 + skb_push(skb, hh->hh_len);
1977 + return hh->hh_output(skb);
1978 + } else if (dst->neighbour)
1979 + return dst->neighbour->output(skb);
1981 + if (net_ratelimit())
1982 + printk(KERN_DEBUG "TARPIT ip_direct_send: no header cache and no neighbor!\n");
1989 +static void tarpit_tcp(struct sk_buff *oskb,struct rtable *ort,int local)
1991 + struct sk_buff *nskb;
1992 + struct rtable *nrt;
1993 + struct tcphdr *otcph, *ntcph;
1994 + struct flowi fl = {};
1995 + unsigned int otcplen;
1998 + /* A truncated TCP header isn't going to be useful */
1999 + if (oskb->len < (oskb->nh.iph->ihl*4) + sizeof(struct tcphdr))
2002 + otcph = (struct tcphdr *)((u_int32_t*)oskb->nh.iph
2003 + + oskb->nh.iph->ihl);
2004 + otcplen = oskb->len - oskb->nh.iph->ihl*4;
2006 + /* No replies for RST or FIN */
2007 + if (otcph->rst || otcph->fin)
2010 + /* No reply to !SYN,!ACK. Rate-limit replies to !SYN,ACKs */
2011 + if (!otcph->syn && (!otcph->ack || !xrlim_allow(&ort->u.dst, 1*HZ)))
2014 + /* Check checksum. */
2015 + if (tcp_v4_check(otcph, otcplen, oskb->nh.iph->saddr,
2016 + oskb->nh.iph->daddr,
2017 + csum_partial((char *)otcph, otcplen, 0)) != 0)
2020 + /* Copy skb (even if skb is about to be dropped, we can't just
2021 + clone it because there may be other things, such as tcpdump,
2022 + interested in it) */
2023 + nskb = skb_copy(oskb, GFP_ATOMIC);
2027 + /* This packet will not be the same as the other: clear nf fields */
2028 + nf_conntrack_put(nskb->nfct);
2029 + nskb->nfct = NULL;
2030 + nskb->nfcache = 0;
2031 +#ifdef CONFIG_NETFILTER_DEBUG
2032 + nskb->nf_debug = 0;
2035 + ntcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
2037 + /* Truncate to length (no data) */
2038 + ntcph->doff = sizeof(struct tcphdr)/4;
2039 + skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
2040 + nskb->nh.iph->tot_len = htons(nskb->len);
2042 + /* Swap source and dest */
2043 + nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
2044 + tmp = ntcph->source;
2045 + ntcph->source = ntcph->dest;
2046 + ntcph->dest = tmp;
2048 + /* Use supplied sequence number or make a new one */
2049 + ntcph->seq = otcph->ack ? otcph->ack_seq
2050 + : htonl(secure_tcp_sequence_number(nskb->nh.iph->saddr,
2051 + nskb->nh.iph->daddr,
2055 + /* Our SYN-ACKs must have a >0 window */
2056 + ntcph->window = (otcph->syn && !otcph->ack) ? htons(5) : 0;
2058 + ntcph->urg_ptr = 0;
2061 + ((u_int8_t *)ntcph)[13] = 0;
2063 + if (otcph->syn && otcph->ack) {
2065 + ntcph->ack_seq = 0;
2067 + ntcph->syn = otcph->syn;
2069 + ntcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn);
2072 + /* Adjust TCP checksum */
2074 + ntcph->check = tcp_v4_check(ntcph, sizeof(struct tcphdr),
2075 + nskb->nh.iph->saddr,
2076 + nskb->nh.iph->daddr,
2077 + csum_partial((char *)ntcph,
2078 + sizeof(struct tcphdr), 0));
2080 + /* Adjust IP TTL */
2081 + nskb->nh.iph->ttl = sysctl_ip_default_ttl;
2083 + /* Set DF, id = 0 */
2084 + nskb->nh.iph->frag_off = htons(IP_DF);
2085 + nskb->nh.iph->id = 0;
2087 + /* Adjust IP checksum */
2088 + nskb->nh.iph->check = 0;
2089 + nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
2090 + nskb->nh.iph->ihl);
2092 + fl.nl_u.ip4_u.daddr = nskb->nh.iph->daddr;
2093 + fl.nl_u.ip4_u.saddr = local ? nskb->nh.iph->saddr : 0;
2094 + fl.nl_u.ip4_u.tos = RT_TOS(nskb->nh.iph->tos) | RTO_CONN;
2097 + if (ip_route_output_key(&nrt, &fl))
2100 + dst_release(nskb->dst);
2101 + nskb->dst = &nrt->u.dst;
2103 + /* "Never happens" */
2104 + if (nskb->len > dst_pmtu(nskb->dst))
2107 + ip_direct_send (nskb);
2116 +static unsigned int tarpit(struct sk_buff **pskb,
2117 + const struct net_device *in,
2118 + const struct net_device *out,
2119 + unsigned int hooknum,
2120 + const void *targinfo,
2123 + struct sk_buff *skb = *pskb;
2124 + struct rtable *rt = (struct rtable*)skb->dst;
2126 + /* Do we have an input route cache entry? */
2130 + /* No replies to physical multicast/broadcast */
2131 + if (skb->pkt_type != PACKET_HOST && skb->pkt_type != PACKET_OTHERHOST)
2134 + /* Now check at the protocol level */
2135 + if (rt->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST))
2138 + /* Our naive response construction doesn't deal with IP
2139 + options, and probably shouldn't try. */
2140 + if (skb->nh.iph->ihl*4 != sizeof(struct iphdr))
2143 + /* We aren't interested in fragments */
2144 + if (skb->nh.iph->frag_off & htons(IP_OFFSET))
2147 + tarpit_tcp(skb,rt,hooknum == NF_IP_LOCAL_IN);
2153 +static int check(const char *tablename,
2154 + const struct ipt_entry *e,
2156 + unsigned int targinfosize,
2157 + unsigned int hook_mask)
2159 + /* Only allow these for input/forward packet filtering. */
2160 + if (strcmp(tablename, "filter") != 0) {
2161 + DEBUGP("TARPIT: bad table %s'.\n", tablename);
2164 + if ((hook_mask & ~((1 << NF_IP_LOCAL_IN)
2165 + | (1 << NF_IP_FORWARD))) != 0) {
2166 + DEBUGP("TARPIT: bad hook mask %X\n", hook_mask);
2170 + /* Must specify that it's a TCP packet */
2171 + if (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & IPT_INV_PROTO)) {
2172 + DEBUGP("TARPIT: not valid for non-tcp\n");
2179 +static struct ipt_target ipt_tarpit_reg = {
2182 + .checkentry = check,
2186 +static int __init init(void)
2188 + return ipt_register_target(&ipt_tarpit_reg);
2191 +static void __exit fini(void)
2193 + ipt_unregister_target(&ipt_tarpit_reg);
2198 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
2199 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_TTL.c 1970-01-01 01:00:00.000000000 +0100
2200 +++ linux-2.6.7/net/ipv4/netfilter/ipt_TTL.c 2004-06-29 12:32:03.618320464 +0200
2202 +/* TTL modification target for IP tables
2203 + * (C) 2000 by Harald Welte <laforge@gnumonks.org>
2205 + * Version: $Revision$
2207 + * This software is distributed under the terms of GNU GPL
2210 +#include <linux/module.h>
2211 +#include <linux/skbuff.h>
2212 +#include <linux/ip.h>
2213 +#include <net/checksum.h>
2215 +#include <linux/netfilter_ipv4/ip_tables.h>
2216 +#include <linux/netfilter_ipv4/ipt_TTL.h>
2218 +MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
2219 +MODULE_DESCRIPTION("IP tables TTL modification module");
2220 +MODULE_LICENSE("GPL");
2222 +static unsigned int
2223 +ipt_ttl_target(struct sk_buff **pskb, const struct net_device *in,
2224 + const struct net_device *out, unsigned int hooknum,
2225 + const void *targinfo, void *userinfo)
2227 + struct iphdr *iph;
2228 + const struct ipt_TTL_info *info = targinfo;
2229 + u_int16_t diffs[2];
2232 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
2235 + iph = (*pskb)->nh.iph;
2237 + switch (info->mode) {
2239 + new_ttl = info->ttl;
2242 + new_ttl = iph->ttl + info->ttl;
2243 + if (new_ttl > 255)
2247 + new_ttl = iph->ttl + info->ttl;
2252 + new_ttl = iph->ttl;
2256 + if (new_ttl != iph->ttl) {
2257 + diffs[0] = htons(((unsigned)iph->ttl) << 8) ^ 0xFFFF;
2258 + iph->ttl = new_ttl;
2259 + diffs[1] = htons(((unsigned)iph->ttl) << 8);
2260 + iph->check = csum_fold(csum_partial((char *)diffs,
2262 + iph->check^0xFFFF));
2263 + (*pskb)->nfcache |= NFC_ALTERED;
2266 + return IPT_CONTINUE;
2269 +static int ipt_ttl_checkentry(const char *tablename,
2270 + const struct ipt_entry *e,
2272 + unsigned int targinfosize,
2273 + unsigned int hook_mask)
2275 + struct ipt_TTL_info *info = targinfo;
2277 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_TTL_info))) {
2278 + printk(KERN_WARNING "TTL: targinfosize %u != %Zu\n",
2280 + IPT_ALIGN(sizeof(struct ipt_TTL_info)));
2284 + if (strcmp(tablename, "mangle")) {
2285 + printk(KERN_WARNING "TTL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
2289 + if (info->mode > IPT_TTL_MAXMODE) {
2290 + printk(KERN_WARNING "TTL: invalid or unknown Mode %u\n",
2295 + if ((info->mode != IPT_TTL_SET) && (info->ttl == 0)) {
2296 + printk(KERN_WARNING "TTL: increment/decrement doesn't make sense with value 0\n");
2303 +static struct ipt_target ipt_TTL = {
2305 + .target = ipt_ttl_target,
2306 + .checkentry = ipt_ttl_checkentry,
2310 +static int __init init(void)
2312 + return ipt_register_target(&ipt_TTL);
2315 +static void __exit fini(void)
2317 + ipt_unregister_target(&ipt_TTL);
2322 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
2323 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_XOR.c 1970-01-01 01:00:00.000000000 +0100
2324 +++ linux-2.6.7/net/ipv4/netfilter/ipt_XOR.c 2004-06-29 12:34:46.050627000 +0200
2326 +/* XOR target for IP tables
2327 + * (C) 2000 by Tim Vandermeersch <Tim.Vandermeersch@pandora.be>
2328 + * Based on ipt_TTL.c
2332 + * This software is distributed under the terms of GNU GPL
2335 +#include <linux/module.h>
2336 +#include <linux/skbuff.h>
2337 +#include <linux/ip.h>
2338 +#include <linux/tcp.h>
2339 +#include <linux/udp.h>
2341 +#include <linux/netfilter_ipv4/ip_tables.h>
2342 +#include <linux/netfilter_ipv4/ipt_XOR.h>
2344 +MODULE_AUTHOR("Tim Vandermeersch <Tim.Vandermeersch@pandora.be>");
2345 +MODULE_DESCRIPTION("IP tables XOR module");
2346 +MODULE_LICENSE("GPL");
2348 +static unsigned int
2349 +ipt_xor_target(struct sk_buff **pskb,
2350 + const struct net_device *in, const struct net_device *out,
2351 + unsigned int hooknum, const void *targinfo, void *userinfo)
2353 + struct ipt_XOR_info *info = (void *) targinfo;
2354 + struct iphdr *iph;
2355 + struct tcphdr *tcph;
2356 + struct udphdr *udph;
2359 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
2362 + iph = (*pskb)->nh.iph;
2364 + if (iph->protocol == IPPROTO_TCP) {
2365 + tcph = (struct tcphdr *) ((*pskb)->data + iph->ihl*4);
2366 + for (i=0, j=0; i<(ntohs(iph->tot_len) - iph->ihl*4 - tcph->doff*4); ) {
2367 + for (k=0; k<=info->block_size; k++) {
2368 + (char) (*pskb)->data[ iph->ihl*4 + tcph->doff*4 + i ] ^=
2373 + if (info->key[j] == 0x00)
2376 + } else if (iph->protocol == IPPROTO_UDP) {
2377 + udph = (struct udphdr *) ((*pskb)->data + iph->ihl*4);
2378 + for (i=0, j=0; i<(ntohs(udph->len)-8); ) {
2379 + for (k=0; k<=info->block_size; k++) {
2380 + (char) (*pskb)->data[ iph->ihl*4 + sizeof(struct udphdr) + i ] ^=
2385 + if (info->key[j] == 0x00)
2390 + return IPT_CONTINUE;
2393 +static int ipt_xor_checkentry(const char *tablename, const struct ipt_entry *e,
2394 + void *targinfo, unsigned int targinfosize,
2395 + unsigned int hook_mask)
2397 + struct ipt_XOR_info *info = targinfo;
2399 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_XOR_info))) {
2400 + printk(KERN_WARNING "XOR: targinfosize %u != %Zu\n",
2401 + targinfosize, IPT_ALIGN(sizeof(struct ipt_XOR_info)));
2405 + if (strcmp(tablename, "mangle")) {
2406 + printk(KERN_WARNING "XOR: can only be called from"
2407 + "\"mangle\" table, not \"%s\"\n", tablename);
2411 + if (!strcmp(info->key, "")) {
2412 + printk(KERN_WARNING "XOR: You must specify a key");
2416 + if (info->block_size == 0) {
2417 + printk(KERN_WARNING "XOR: You must specify a block-size");
2424 +static struct ipt_target ipt_XOR = {
2426 + .target = ipt_xor_target,
2427 + .checkentry = ipt_xor_checkentry,
2428 + .me = THIS_MODULE,
2431 +static int __init init(void)
2433 + return ipt_register_target(&ipt_XOR);
2436 +static void __exit fini(void)
2438 + ipt_unregister_target(&ipt_XOR);
2443 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
2444 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_connlimit.c 1970-01-01 01:00:00.000000000 +0100
2445 +++ linux-2.6.7/net/ipv4/netfilter/ipt_connlimit.c 2004-06-29 12:32:05.988960072 +0200
2448 + * netfilter module to limit the number of parallel tcp
2449 + * connections per IP address.
2450 + * (c) 2000 Gerd Knorr <kraxel@bytesex.org>
2451 + * Nov 2002: Martin Bene <martin.bene@icomedias.com>:
2452 + * only ignore TIME_WAIT or gone connections
2456 + * Kernel module to match connection tracking information.
2457 + * GPL (C) 1999 Rusty Russell (rusty@rustcorp.com.au).
2459 +#include <linux/module.h>
2460 +#include <linux/skbuff.h>
2461 +#include <linux/list.h>
2462 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2463 +#include <linux/netfilter_ipv4/ip_conntrack_core.h>
2464 +#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
2465 +#include <linux/netfilter_ipv4/ip_tables.h>
2466 +#include <linux/netfilter_ipv4/ipt_connlimit.h>
2470 +MODULE_LICENSE("GPL");
2472 +/* we'll save the tuples of all connections we care about */
2473 +struct ipt_connlimit_conn
2475 + struct list_head list;
2476 + struct ip_conntrack_tuple tuple;
2479 +struct ipt_connlimit_data {
2481 + struct list_head iphash[256];
2484 +static int ipt_iphash(u_int32_t addr)
2488 + hash = addr & 0xff;
2489 + hash ^= (addr >> 8) & 0xff;
2490 + hash ^= (addr >> 16) & 0xff;
2491 + hash ^= (addr >> 24) & 0xff;
2495 +static int count_them(struct ipt_connlimit_data *data,
2496 + u_int32_t addr, u_int32_t mask,
2497 + struct ip_conntrack *ct)
2500 + const static char *tcp[] = { "none", "established", "syn_sent", "syn_recv",
2501 + "fin_wait", "time_wait", "close", "close_wait",
2502 + "last_ack", "listen" };
2504 + int addit = 1, matches = 0;
2505 + struct ip_conntrack_tuple tuple;
2506 + struct ip_conntrack_tuple_hash *found;
2507 + struct ipt_connlimit_conn *conn;
2508 + struct list_head *hash,*lh;
2510 + spin_lock(&data->lock);
2511 + tuple = ct->tuplehash[0].tuple;
2512 + hash = &data->iphash[ipt_iphash(addr & mask)];
2514 + /* check the saved connections */
2515 + for (lh = hash->next; lh != hash; lh = lh->next) {
2516 + conn = list_entry(lh,struct ipt_connlimit_conn,list);
2517 + found = ip_conntrack_find_get(&conn->tuple,ct);
2518 + if (0 == memcmp(&conn->tuple,&tuple,sizeof(tuple)) &&
2520 + found->ctrack->proto.tcp.state != TCP_CONNTRACK_TIME_WAIT) {
2521 + /* Just to be sure we have it only once in the list.
2522 + We should'nt see tuples twice unless someone hooks this
2523 + into a table without "-p tcp --syn" */
2527 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d %s\n",
2528 + ipt_iphash(addr & mask),
2529 + NIPQUAD(conn->tuple.src.ip), ntohs(conn->tuple.src.u.tcp.port),
2530 + NIPQUAD(conn->tuple.dst.ip), ntohs(conn->tuple.dst.u.tcp.port),
2531 + (NULL != found) ? tcp[found->ctrack->proto.tcp.state] : "gone");
2533 + if (NULL == found) {
2534 + /* this one is gone */
2536 + list_del(lh->next);
2540 + if (found->ctrack->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT) {
2541 + /* we don't care about connections which are
2542 + closed already -> ditch it */
2544 + list_del(lh->next);
2546 + nf_conntrack_put(&found->ctrack->infos[0]);
2549 + if ((addr & mask) == (conn->tuple.src.ip & mask)) {
2550 + /* same source IP address -> be counted! */
2553 + nf_conntrack_put(&found->ctrack->infos[0]);
2556 + /* save the new connection in our list */
2558 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d new\n",
2559 + ipt_iphash(addr & mask),
2560 + NIPQUAD(tuple.src.ip), ntohs(tuple.src.u.tcp.port),
2561 + NIPQUAD(tuple.dst.ip), ntohs(tuple.dst.u.tcp.port));
2563 + conn = kmalloc(sizeof(*conn),GFP_ATOMIC);
2566 + memset(conn,0,sizeof(*conn));
2567 + INIT_LIST_HEAD(&conn->list);
2568 + conn->tuple = tuple;
2569 + list_add(&conn->list,hash);
2572 + spin_unlock(&data->lock);
2577 +match(const struct sk_buff *skb,
2578 + const struct net_device *in,
2579 + const struct net_device *out,
2580 + const void *matchinfo,
2584 + const struct ipt_connlimit_info *info = matchinfo;
2585 + int connections, match;
2586 + struct ip_conntrack *ct;
2587 + enum ip_conntrack_info ctinfo;
2589 + ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
2591 + printk("ipt_connlimit: Oops: invalid ct state ?\n");
2595 + connections = count_them(info->data,skb->nh.iph->saddr,info->mask,ct);
2596 + if (-1 == connections) {
2597 + printk("ipt_connlimit: Hmm, kmalloc failed :-(\n");
2598 + *hotdrop = 1; /* let's free some memory :-) */
2601 + match = (info->inverse) ? (connections <= info->limit) : (connections > info->limit);
2603 + printk("ipt_connlimit: src=%u.%u.%u.%u mask=%u.%u.%u.%u "
2604 + "connections=%d limit=%d match=%s\n",
2605 + NIPQUAD(skb->nh.iph->saddr), NIPQUAD(info->mask),
2606 + connections, info->limit, match ? "yes" : "no");
2612 +static int check(const char *tablename,
2613 + const struct ipt_ip *ip,
2615 + unsigned int matchsize,
2616 + unsigned int hook_mask)
2618 + struct ipt_connlimit_info *info = matchinfo;
2622 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connlimit_info)))
2625 + /* refuse anything but tcp */
2626 + if (ip->proto != IPPROTO_TCP)
2629 + /* init private data */
2630 + info->data = kmalloc(sizeof(struct ipt_connlimit_data),GFP_KERNEL);
2631 + spin_lock_init(&(info->data->lock));
2632 + for (i = 0; i < 256; i++)
2633 + INIT_LIST_HEAD(&(info->data->iphash[i]));
2638 +static void destroy(void *matchinfo, unsigned int matchinfosize)
2640 + struct ipt_connlimit_info *info = matchinfo;
2641 + struct ipt_connlimit_conn *conn;
2642 + struct list_head *hash;
2646 + for (i = 0; i < 256; i++) {
2647 + hash = &(info->data->iphash[i]);
2648 + while (hash != hash->next) {
2649 + conn = list_entry(hash->next,struct ipt_connlimit_conn,list);
2650 + list_del(hash->next);
2654 + kfree(info->data);
2657 +static struct ipt_match connlimit_match = {
2658 + .name = "connlimit",
2660 + .checkentry = &check,
2661 + .destroy = &destroy,
2665 +static int __init init(void)
2667 + return ipt_register_match(&connlimit_match);
2670 +static void __exit fini(void)
2672 + ipt_unregister_match(&connlimit_match);
2677 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
2678 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_connmark.c 1970-01-01 01:00:00.000000000 +0100
2679 +++ linux-2.6.7/net/ipv4/netfilter/ipt_connmark.c 2004-06-29 12:34:21.514357080 +0200
2681 +/* This kernel module matches connection mark values set by the
2684 + * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
2685 + * by Henrik Nordstrom <hno@marasystems.com>
2687 + * This program is free software; you can redistribute it and/or modify
2688 + * it under the terms of the GNU General Public License as published by
2689 + * the Free Software Foundation; either version 2 of the License, or
2690 + * (at your option) any later version.
2692 + * This program is distributed in the hope that it will be useful,
2693 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2694 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2695 + * GNU General Public License for more details.
2697 + * You should have received a copy of the GNU General Public License
2698 + * along with this program; if not, write to the Free Software
2699 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2702 +#include <linux/module.h>
2703 +#include <linux/skbuff.h>
2705 +MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
2706 +MODULE_DESCRIPTION("IP tables connmark match module");
2707 +MODULE_LICENSE("GPL");
2709 +#include <linux/netfilter_ipv4/ip_tables.h>
2710 +#include <linux/netfilter_ipv4/ipt_connmark.h>
2711 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2714 +match(const struct sk_buff *skb,
2715 + const struct net_device *in,
2716 + const struct net_device *out,
2717 + const void *matchinfo,
2721 + const struct ipt_connmark_info *info = matchinfo;
2722 + enum ip_conntrack_info ctinfo;
2723 + struct ip_conntrack *ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
2727 + return ((ct->mark & info->mask) == info->mark) ^ info->invert;
2731 +checkentry(const char *tablename,
2732 + const struct ipt_ip *ip,
2734 + unsigned int matchsize,
2735 + unsigned int hook_mask)
2737 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info)))
2743 +static struct ipt_match connmark_match = {
2744 + .name = "connmark",
2746 + .checkentry = &checkentry,
2750 +static int __init init(void)
2752 + return ipt_register_match(&connmark_match);
2755 +static void __exit fini(void)
2757 + ipt_unregister_match(&connmark_match);
2762 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
2763 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_dstlimit.c 1970-01-01 01:00:00.000000000 +0100
2764 +++ linux-2.6.7/net/ipv4/netfilter/ipt_dstlimit.c 2004-06-29 12:32:07.243769312 +0200
2766 +/* iptables match extension to limit the number of packets per second
2767 + * seperately for each destination.
2769 + * (C) 2003 by Harald Welte <laforge@netfilter.org>
2773 + * Development of this code was funded by Astaro AG, http://www.astaro.com/
2775 + * based on ipt_limit.c by:
2776 + * Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
2777 + * Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
2778 + * Rusty Russell <rusty@rustcorp.com.au>
2780 + * The general idea is to create a hash table for every dstip and have a
2781 + * seperate limit counter per tuple. This way you can do something like 'limit
2782 + * the number of syn packets for each of my internal addresses.
2784 + * Ideally this would just be implemented as a general 'hash' match, which would
2785 + * allow us to attach any iptables target to it's hash buckets. But this is
2786 + * not possible in the current iptables architecture. As always, pkttables for
2787 + * 2.7.x will help ;)
2789 +#include <linux/module.h>
2790 +#include <linux/skbuff.h>
2791 +#include <linux/spinlock.h>
2792 +#include <linux/random.h>
2793 +#include <linux/jhash.h>
2794 +#include <linux/slab.h>
2795 +#include <linux/vmalloc.h>
2796 +#include <linux/tcp.h>
2797 +#include <linux/udp.h>
2798 +#include <linux/proc_fs.h>
2799 +#include <linux/seq_file.h>
2801 +#define ASSERT_READ_LOCK(x)
2802 +#define ASSERT_WRITE_LOCK(x)
2803 +#include <linux/netfilter_ipv4/lockhelp.h>
2804 +#include <linux/netfilter_ipv4/listhelp.h>
2806 +#include <linux/netfilter_ipv4/ip_tables.h>
2807 +#include <linux/netfilter_ipv4/ipt_dstlimit.h>
2809 +/* FIXME: this is just for IP_NF_ASSERRT */
2810 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2812 +#define MS2JIFFIES(x) ((x*HZ)/1000)
2814 +MODULE_LICENSE("GPL");
2815 +MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
2816 +MODULE_DESCRIPTION("iptables match for limiting per destination");
2818 +/* need to declare this at the top */
2819 +static struct proc_dir_entry *dstlimit_procdir;
2820 +static struct file_operations dl_file_ops;
2822 +/* hash table crap */
2824 +struct dsthash_dst {
2830 +struct dsthash_ent {
2831 + /* static / read-only parts in the beginning */
2832 + struct list_head list;
2833 + struct dsthash_dst dst;
2835 + /* modified structure members in the end */
2836 + unsigned long expires; /* precalculated expiry time */
2838 + unsigned long prev; /* last modification */
2840 + u_int32_t credit_cap, cost;
2844 +struct ipt_dstlimit_htable {
2845 + struct list_head list; /* global list of all htables */
2848 + struct dstlimit_cfg cfg; /* config */
2850 + /* used internally */
2851 + spinlock_t lock; /* lock for list_head */
2852 + u_int32_t rnd; /* random seed for hash */
2853 + struct timer_list timer; /* timer for gc */
2854 + atomic_t count; /* number entries in table */
2856 + /* seq_file stuff */
2857 + struct proc_dir_entry *pde;
2859 + struct list_head hash[0]; /* hashtable itself */
2862 +DECLARE_RWLOCK(dstlimit_lock); /* protects htables list */
2863 +static LIST_HEAD(dstlimit_htables);
2864 +static kmem_cache_t *dstlimit_cachep;
2866 +static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b)
2868 + return (ent->dst.dst_ip == b->dst_ip
2869 + && ent->dst.port == b->port
2870 + && ent->dst.src_ip == b->src_ip);
2873 +static inline u_int32_t
2874 +hash_dst(const struct ipt_dstlimit_htable *ht, const struct dsthash_dst *dst)
2876 + return (jhash_3words(dst->dst_ip, dst->port,
2877 + dst->src_ip, ht->rnd) % ht->cfg.size);
2880 +static inline struct dsthash_ent *
2881 +__dsthash_find(const struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
2883 + struct dsthash_ent *ent;
2884 + u_int32_t hash = hash_dst(ht, dst);
2885 + MUST_BE_LOCKED(&ht->lock);
2886 + ent = LIST_FIND(&ht->hash[hash], dst_cmp, struct dsthash_ent *, dst);
2890 +/* allocate dsthash_ent, initialize dst, put in htable and lock it */
2891 +static struct dsthash_ent *
2892 +__dsthash_alloc_init(struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
2894 + struct dsthash_ent *ent;
2896 + /* initialize hash with random val at the time we allocate
2897 + * the first hashtable entry */
2899 + get_random_bytes(&ht->rnd, 4);
2901 + if (ht->cfg.max &&
2902 + atomic_read(&ht->count) >= ht->cfg.max) {
2903 + /* FIXME: do something. question is what.. */
2904 + if (net_ratelimit())
2905 + printk(KERN_WARNING
2906 + "ipt_dstlimit: max count of %u reached\n",
2911 + ent = kmem_cache_alloc(dstlimit_cachep, GFP_ATOMIC);
2913 + if (net_ratelimit())
2915 + "ipt_dstlimit: can't allocate dsthash_ent\n");
2919 + atomic_inc(&ht->count);
2921 + ent->dst.dst_ip = dst->dst_ip;
2922 + ent->dst.port = dst->port;
2923 + ent->dst.src_ip = dst->src_ip;
2925 + list_add(&ent->list, &ht->hash[hash_dst(ht, dst)]);
2931 +__dsthash_free(struct ipt_dstlimit_htable *ht, struct dsthash_ent *ent)
2933 + MUST_BE_LOCKED(&ht->lock);
2935 + list_del(&ent->list);
2936 + kmem_cache_free(dstlimit_cachep, ent);
2937 + atomic_dec(&ht->count);
2939 +static void htable_gc(unsigned long htlong);
2941 +static int htable_create(struct ipt_dstlimit_info *minfo)
2944 + unsigned int size;
2945 + struct ipt_dstlimit_htable *hinfo;
2947 + if (minfo->cfg.size)
2948 + size = minfo->cfg.size;
2950 + size = (((num_physpages << PAGE_SHIFT) / 16384)
2951 + / sizeof(struct list_head));
2952 + if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
2957 + /* FIXME: don't use vmalloc() here or anywhere else -HW */
2958 + hinfo = vmalloc(sizeof(struct ipt_dstlimit_htable)
2959 + + (sizeof(struct list_head) * size));
2961 + printk(KERN_ERR "ipt_dstlimit: Unable to create hashtable\n");
2964 + minfo->hinfo = hinfo;
2966 + /* copy match config into hashtable config */
2967 + memcpy(&hinfo->cfg, &minfo->cfg, sizeof(hinfo->cfg));
2968 + hinfo->cfg.size = size;
2969 + if (!hinfo->cfg.max)
2970 + hinfo->cfg.max = 8 * hinfo->cfg.size;
2971 + else if (hinfo->cfg.max < hinfo->cfg.size)
2972 + hinfo->cfg.max = hinfo->cfg.size;
2974 + for (i = 0; i < hinfo->cfg.size; i++)
2975 + INIT_LIST_HEAD(&hinfo->hash[i]);
2977 + atomic_set(&hinfo->count, 0);
2978 + atomic_set(&hinfo->use, 1);
2980 + hinfo->lock = SPIN_LOCK_UNLOCKED;
2981 + hinfo->pde = create_proc_entry(minfo->name, 0, dstlimit_procdir);
2982 + if (!hinfo->pde) {
2986 + hinfo->pde->proc_fops = &dl_file_ops;
2987 + hinfo->pde->data = hinfo;
2989 + init_timer(&hinfo->timer);
2990 + hinfo->timer.expires = jiffies + MS2JIFFIES(hinfo->cfg.gc_interval);
2991 + hinfo->timer.data = (unsigned long )hinfo;
2992 + hinfo->timer.function = htable_gc;
2993 + add_timer(&hinfo->timer);
2995 + WRITE_LOCK(&dstlimit_lock);
2996 + list_add(&hinfo->list, &dstlimit_htables);
2997 + WRITE_UNLOCK(&dstlimit_lock);
3002 +static int select_all(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
3007 +static int select_gc(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
3009 + return (jiffies >= he->expires);
3012 +static void htable_selective_cleanup(struct ipt_dstlimit_htable *ht,
3013 + int (*select)(struct ipt_dstlimit_htable *ht,
3014 + struct dsthash_ent *he))
3018 + IP_NF_ASSERT(ht->cfg.size && ht->cfg.max);
3020 + /* lock hash table and iterate over it */
3021 + LOCK_BH(&ht->lock);
3022 + for (i = 0; i < ht->cfg.size; i++) {
3023 + struct dsthash_ent *dh, *n;
3024 + list_for_each_entry_safe(dh, n, &ht->hash[i], list) {
3025 + if ((*select)(ht, dh))
3026 + __dsthash_free(ht, dh);
3029 + UNLOCK_BH(&ht->lock);
3032 +/* hash table garbage collector, run by timer */
3033 +static void htable_gc(unsigned long htlong)
3035 + struct ipt_dstlimit_htable *ht = (struct ipt_dstlimit_htable *)htlong;
3037 + htable_selective_cleanup(ht, select_gc);
3039 + /* re-add the timer accordingly */
3040 + ht->timer.expires = jiffies + MS2JIFFIES(ht->cfg.gc_interval);
3041 + add_timer(&ht->timer);
3044 +static void htable_destroy(struct ipt_dstlimit_htable *hinfo)
3046 + /* remove timer, if it is pending */
3047 + if (timer_pending(&hinfo->timer))
3048 + del_timer(&hinfo->timer);
3050 + /* remove proc entry */
3051 + remove_proc_entry(hinfo->pde->name, dstlimit_procdir);
3053 + htable_selective_cleanup(hinfo, select_all);
3057 +static struct ipt_dstlimit_htable *htable_find_get(char *name)
3059 + struct ipt_dstlimit_htable *hinfo;
3061 + READ_LOCK(&dstlimit_lock);
3062 + list_for_each_entry(hinfo, &dstlimit_htables, list) {
3063 + if (!strcmp(name, hinfo->pde->name)) {
3064 + atomic_inc(&hinfo->use);
3065 + READ_UNLOCK(&dstlimit_lock);
3069 + READ_UNLOCK(&dstlimit_lock);
3074 +static void htable_put(struct ipt_dstlimit_htable *hinfo)
3076 + if (atomic_dec_and_test(&hinfo->use)) {
3077 + WRITE_LOCK(&dstlimit_lock);
3078 + list_del(&hinfo->list);
3079 + WRITE_UNLOCK(&dstlimit_lock);
3080 + htable_destroy(hinfo);
3085 +/* The algorithm used is the Simple Token Bucket Filter (TBF)
3086 + * see net/sched/sch_tbf.c in the linux source tree
3089 +/* Rusty: This is my (non-mathematically-inclined) understanding of
3090 + this algorithm. The `average rate' in jiffies becomes your initial
3091 + amount of credit `credit' and the most credit you can ever have
3092 + `credit_cap'. The `peak rate' becomes the cost of passing the
3095 + `prev' tracks the last packet hit: you gain one credit per jiffy.
3096 + If you get credit balance more than this, the extra credit is
3097 + discarded. Every time the match passes, you lose `cost' credits;
3098 + if you don't have that many, the test fails.
3100 + See Alexey's formal explanation in net/sched/sch_tbf.c.
3102 + To get the maximum range, we multiply by this factor (ie. you get N
3103 + credits per jiffy). We want to allow a rate as low as 1 per day
3104 + (slowest userspace tool allows), which means
3105 + CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32 ie.
3107 +#define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24))
3109 +/* Repeated shift and or gives us all 1s, final shift and add 1 gives
3110 + * us the power of 2 below the theoretical max, so GCC simply does a
3112 +#define _POW2_BELOW2(x) ((x)|((x)>>1))
3113 +#define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2))
3114 +#define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4))
3115 +#define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8))
3116 +#define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16))
3117 +#define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1)
3119 +#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
3121 +/* Precision saver. */
3122 +static inline u_int32_t
3123 +user2credits(u_int32_t user)
3125 + /* If multiplying would overflow... */
3126 + if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY))
3127 + /* Divide first. */
3128 + return (user / IPT_DSTLIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;
3130 + return (user * HZ * CREDITS_PER_JIFFY) / IPT_DSTLIMIT_SCALE;
3133 +static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
3135 + dh->rateinfo.credit += (now - xchg(&dh->rateinfo.prev, now))
3136 + * CREDITS_PER_JIFFY;
3137 + if (dh->rateinfo.credit > dh->rateinfo.credit_cap)
3138 + dh->rateinfo.credit = dh->rateinfo.credit_cap;
3142 +dstlimit_match(const struct sk_buff *skb,
3143 + const struct net_device *in,
3144 + const struct net_device *out,
3145 + const void *matchinfo,
3149 + struct ipt_dstlimit_info *r =
3150 + ((struct ipt_dstlimit_info *)matchinfo)->u.master;
3151 + struct ipt_dstlimit_htable *hinfo = r->hinfo;
3152 + unsigned long now = jiffies;
3153 + struct dsthash_ent *dh;
3154 + struct dsthash_dst dst;
3156 + memset(&dst, 0, sizeof(dst));
3158 + /* dest ip is always in hash */
3159 + dst.dst_ip = skb->nh.iph->daddr;
3161 + /* source ip only if respective hashmode, otherwise set to
3163 + if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_SIP)
3164 + dst.src_ip = skb->nh.iph->saddr;
3166 + /* dest port only if respective mode */
3167 + if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_DPT) {
3170 + /* Must not be a fragment. */
3174 + /* Must be big enough to read ports (both UDP and TCP have
3175 + them at the start). */
3176 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
3177 + /* We've been asked to examine this packet, and we
3178 + can't. Hence, no choice but to drop. */
3183 + switch (skb->nh.iph->protocol) {
3184 + struct tcphdr *th;
3185 + struct udphdr *uh;
3187 + th = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
3188 + dst.port = th->dest;
3191 + uh = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
3192 + dst.port = uh->dest;
3199 + LOCK_BH(&hinfo->lock);
3200 + dh = __dsthash_find(hinfo, &dst);
3202 + dh = __dsthash_alloc_init(hinfo, &dst);
3205 + /* enomem... don't match == DROP */
3206 + if (net_ratelimit())
3207 + printk(KERN_ERR "%s: ENOMEM\n", __FUNCTION__);
3208 + UNLOCK_BH(&hinfo->lock);
3212 + dh->expires = jiffies + MS2JIFFIES(hinfo->cfg.expire);
3214 + dh->rateinfo.prev = jiffies;
3215 + dh->rateinfo.credit = user2credits(hinfo->cfg.avg *
3216 + hinfo->cfg.burst);
3217 + dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg *
3218 + hinfo->cfg.burst);
3219 + dh->rateinfo.cost = user2credits(hinfo->cfg.avg);
3221 + UNLOCK_BH(&hinfo->lock);
3225 + /* update expiration timeout */
3226 + dh->expires = now + MS2JIFFIES(hinfo->cfg.expire);
3228 + rateinfo_recalc(dh, now);
3229 + if (dh->rateinfo.credit >= dh->rateinfo.cost) {
3230 + /* We're underlimit. */
3231 + dh->rateinfo.credit -= dh->rateinfo.cost;
3232 + UNLOCK_BH(&hinfo->lock);
3236 + UNLOCK_BH(&hinfo->lock);
3238 + /* default case: we're overlimit, thus don't match */
3243 +dstlimit_checkentry(const char *tablename,
3244 + const struct ipt_ip *ip,
3246 + unsigned int matchsize,
3247 + unsigned int hook_mask)
3249 + struct ipt_dstlimit_info *r = matchinfo;
3251 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_dstlimit_info)))
3254 + /* Check for overflow. */
3255 + if (r->cfg.burst == 0
3256 + || user2credits(r->cfg.avg * r->cfg.burst) <
3257 + user2credits(r->cfg.avg)) {
3258 + printk(KERN_ERR "ipt_dstlimit: Overflow, try lower: %u/%u\n",
3259 + r->cfg.avg, r->cfg.burst);
3263 + if (r->cfg.mode == 0
3264 + || r->cfg.mode > (IPT_DSTLIMIT_HASH_DPT
3265 + |IPT_DSTLIMIT_HASH_DIP
3266 + |IPT_DSTLIMIT_HASH_SIP))
3269 + if (!r->cfg.gc_interval)
3272 + if (!r->cfg.expire)
3275 + r->hinfo = htable_find_get(r->name);
3276 + if (!r->hinfo && (htable_create(r) != 0)) {
3280 + /* Ugly hack: For SMP, we only want to use one set */
3287 +dstlimit_destroy(void *matchinfo, unsigned int matchsize)
3289 + struct ipt_dstlimit_info *r = (struct ipt_dstlimit_info *) matchinfo;
3291 + htable_put(r->hinfo);
3294 +static struct ipt_match ipt_dstlimit = {
3295 + .list = { .prev = NULL, .next = NULL },
3296 + .name = "dstlimit",
3297 + .match = dstlimit_match,
3298 + .checkentry = dstlimit_checkentry,
3299 + .destroy = dstlimit_destroy,
3305 +static void *dl_seq_start(struct seq_file *s, loff_t *pos)
3307 + struct proc_dir_entry *pde = s->private;
3308 + struct ipt_dstlimit_htable *htable = pde->data;
3309 + unsigned int *bucket;
3311 + LOCK_BH(&htable->lock);
3312 + if (*pos >= htable->cfg.size)
3315 + bucket = kmalloc(sizeof(unsigned int), GFP_KERNEL);
3317 + return ERR_PTR(-ENOMEM);
3323 +static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
3325 + struct proc_dir_entry *pde = s->private;
3326 + struct ipt_dstlimit_htable *htable = pde->data;
3327 + unsigned int *bucket = (unsigned int *)v;
3329 + *pos = ++(*bucket);
3330 + if (*pos >= htable->cfg.size) {
3337 +static void dl_seq_stop(struct seq_file *s, void *v)
3339 + struct proc_dir_entry *pde = s->private;
3340 + struct ipt_dstlimit_htable *htable = pde->data;
3341 + unsigned int *bucket = (unsigned int *)v;
3345 + UNLOCK_BH(&htable->lock);
3348 +static inline int dl_seq_real_show(struct dsthash_ent *ent, struct seq_file *s)
3350 + /* recalculate to show accurate numbers */
3351 + rateinfo_recalc(ent, jiffies);
3353 + return seq_printf(s, "%ld %u.%u.%u.%u->%u.%u.%u.%u:%u %u %u %u\n",
3354 + (ent->expires - jiffies)/HZ,
3355 + NIPQUAD(ent->dst.src_ip),
3356 + NIPQUAD(ent->dst.dst_ip), ntohs(ent->dst.port),
3357 + ent->rateinfo.credit, ent->rateinfo.credit_cap,
3358 + ent->rateinfo.cost);
3361 +static int dl_seq_show(struct seq_file *s, void *v)
3363 + struct proc_dir_entry *pde = s->private;
3364 + struct ipt_dstlimit_htable *htable = pde->data;
3365 + unsigned int *bucket = (unsigned int *)v;
3367 + if (LIST_FIND_W(&htable->hash[*bucket], dl_seq_real_show,
3368 + struct dsthash_ent *, s)) {
3369 + /* buffer was filled and unable to print that tuple */
3375 +static struct seq_operations dl_seq_ops = {
3376 + .start = dl_seq_start,
3377 + .next = dl_seq_next,
3378 + .stop = dl_seq_stop,
3379 + .show = dl_seq_show
3382 +static int dl_proc_open(struct inode *inode, struct file *file)
3384 + int ret = seq_open(file, &dl_seq_ops);
3387 + struct seq_file *sf = file->private_data;
3388 + sf->private = PDE(inode);
3393 +static struct file_operations dl_file_ops = {
3394 + .owner = THIS_MODULE,
3395 + .open = dl_proc_open,
3397 + .llseek = seq_lseek,
3398 + .release = seq_release
3401 +static int init_or_fini(int fini)
3408 + if (ipt_register_match(&ipt_dstlimit)) {
3410 + goto cleanup_nothing;
3413 + /* FIXME: do we really want HWCACHE_ALIGN since our objects are
3414 + * quite small ? */
3415 + dstlimit_cachep = kmem_cache_create("ipt_dstlimit",
3416 + sizeof(struct dsthash_ent), 0,
3417 + SLAB_HWCACHE_ALIGN, NULL, NULL);
3418 + if (!dstlimit_cachep) {
3419 + printk(KERN_ERR "Unable to create ipt_dstlimit slab cache\n");
3421 + goto cleanup_unreg_match;
3424 + dstlimit_procdir = proc_mkdir("ipt_dstlimit", proc_net);
3425 + if (!dstlimit_procdir) {
3426 + printk(KERN_ERR "Unable to create proc dir entry\n");
3428 + goto cleanup_free_slab;
3434 + remove_proc_entry("ipt_dstlimit", proc_net);
3436 + kmem_cache_destroy(dstlimit_cachep);
3437 +cleanup_unreg_match:
3438 + ipt_unregister_match(&ipt_dstlimit);
3444 +static int __init init(void)
3446 + return init_or_fini(0);
3449 +static void __exit fini(void)
3456 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
3457 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_fuzzy.c 1970-01-01 01:00:00.000000000 +0100
3458 +++ linux-2.6.7/net/ipv4/netfilter/ipt_fuzzy.c 2004-06-29 12:32:08.822529304 +0200
3461 + * This module implements a simple TSK FLC
3462 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
3463 + * to limit , in an adaptive and flexible way , the packet rate crossing
3464 + * a given stream . It serves as an initial and very simple (but effective)
3465 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
3466 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
3467 + * into our code in a precise , adaptive and efficient manner.
3468 + * The goal is very similar to that of "limit" match , but using techniques of
3469 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
3470 + * avoiding over and undershoots - and stuff like that .
3473 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
3474 + * 2002-08-17 : Changed to eliminate floating point operations .
3475 + * 2002-08-23 : Coding style changes .
3478 +#include <linux/module.h>
3479 +#include <linux/skbuff.h>
3480 +#include <linux/ip.h>
3481 +#include <linux/random.h>
3482 +#include <net/tcp.h>
3483 +#include <linux/spinlock.h>
3484 +#include <linux/netfilter_ipv4/ip_tables.h>
3485 +#include <linux/netfilter_ipv4/ipt_fuzzy.h>
3488 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
3489 + Expressed in percentage
3492 +#define PAR_LOW 1/100
3495 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED ;
3497 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
3498 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
3499 +MODULE_LICENSE("GPL");
3501 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
3509 + return ( (100*(tx-mini)) / (maxi-mini) );
3512 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
3520 + return ( (100*( maxi - tx )) / ( maxi - mini ) );
3524 +ipt_fuzzy_match(const struct sk_buff *pskb,
3525 + const struct net_device *in,
3526 + const struct net_device *out,
3527 + const void *matchinfo,
3531 + /* From userspace */
3533 + struct ipt_fuzzy_info *info = (struct ipt_fuzzy_info *) matchinfo;
3535 + u_int8_t random_number;
3536 + unsigned long amount;
3537 + u_int8_t howhigh, howlow;
3540 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
3542 + info->bytes_total += pskb->len;
3543 + info->packets_total++;
3545 + info->present_time = jiffies;
3547 + if (info->present_time >= info->previous_time)
3548 + amount = info->present_time - info->previous_time;
3550 + /* There was a transition : I choose to re-sample
3551 + and keep the old acceptance rate...
3555 + info->previous_time = info->present_time;
3556 + info->bytes_total = info->packets_total = 0;
3559 + if (amount > HZ/10) /* More than 100 ms elapsed ... */
3562 + info->mean_rate = (u_int32_t) ((HZ*info->packets_total) \
3565 + info->previous_time = info->present_time;
3566 + info->bytes_total = info->packets_total = 0;
3568 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
3569 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
3571 + info->acceptance_rate = (u_int8_t) \
3572 + (howhigh*PAR_LOW + PAR_HIGH*howlow);
3574 + /* In fact , the above defuzzification would require a denominator
3575 + proportional to (howhigh+howlow) but , in this particular case ,
3576 + that expression is constant .
3577 + An imediate consequence is that it isn't necessary to call
3578 + both mf_high and mf_low - but to keep things understandable ,
3583 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
3586 + if ( info->acceptance_rate < 100 )
3588 + get_random_bytes((void *)(&random_number), 1);
3590 + /* If within the acceptance , it can pass => don't match */
3591 + if (random_number <= (255 * info->acceptance_rate) / 100)
3594 + return 1; /* It can't pass ( It matches ) */
3597 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
3602 +ipt_fuzzy_checkentry(const char *tablename,
3603 + const struct ipt_ip *e,
3605 + unsigned int matchsize,
3606 + unsigned int hook_mask)
3609 + const struct ipt_fuzzy_info *info = matchinfo;
3611 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_fuzzy_info))) {
3612 + printk("ipt_fuzzy: matchsize %u != %u\n", matchsize,
3613 + IPT_ALIGN(sizeof(struct ipt_fuzzy_info)));
3617 + if ((info->minimum_rate < MINFUZZYRATE ) || (info->maximum_rate > MAXFUZZYRATE)
3618 + || (info->minimum_rate >= info->maximum_rate )) {
3619 + printk("ipt_fuzzy: BAD limits , please verify !!!\n");
3626 +static struct ipt_match ipt_fuzzy_reg = {
3628 + .match = ipt_fuzzy_match,
3629 + .checkentry = ipt_fuzzy_checkentry,
3633 +static int __init init(void)
3635 + return ipt_register_match(&ipt_fuzzy_reg);
3638 +static void __exit fini(void)
3640 + ipt_unregister_match(&ipt_fuzzy_reg);
3645 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
3646 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_ipv4options.c 1970-01-01 01:00:00.000000000 +0100
3647 +++ linux-2.6.7/net/ipv4/netfilter/ipt_ipv4options.c 2004-06-29 12:32:14.112725072 +0200
3650 + This is a module which is used to match ipv4 options.
3651 + This file is distributed under the terms of the GNU General Public
3652 + License (GPL). Copies of the GPL can be obtained from:
3653 + ftp://prep.ai.mit.edu/pub/gnu/GPL
3655 + 11-mars-2001 Fabrice MARIE <fabrice@netfilter.org> : initial development.
3656 + 12-july-2001 Fabrice MARIE <fabrice@netfilter.org> : added router-alert otions matching. Fixed a bug with no-srr
3657 + 12-august-2001 Imran Patel <ipatel@crosswinds.net> : optimization of the match.
3658 + 18-november-2001 Fabrice MARIE <fabrice@netfilter.org> : added [!] 'any' option match.
3659 + 19-february-2004 Harald Welte <laforge@netfilter.org> : merge with 2.6.x
3662 +#include <linux/module.h>
3663 +#include <linux/skbuff.h>
3664 +#include <net/ip.h>
3666 +#include <linux/netfilter_ipv4/ip_tables.h>
3667 +#include <linux/netfilter_ipv4/ipt_ipv4options.h>
3669 +MODULE_LICENSE("GPL");
3670 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
3673 +match(const struct sk_buff *skb,
3674 + const struct net_device *in,
3675 + const struct net_device *out,
3676 + const void *matchinfo,
3680 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
3681 + const struct iphdr *iph = skb->nh.iph;
3682 + const struct ip_options *opt;
3684 + if (iph->ihl * 4 == sizeof(struct iphdr)) {
3685 + /* No options, so we match only the "DONTs" and the "IGNOREs" */
3687 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) ||
3688 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3689 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
3690 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
3691 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
3692 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
3697 + if ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)
3698 + /* there are options, and we don't need to care which one */
3701 + if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
3702 + /* there are options but we don't want any ! */
3707 + opt = &(IPCB(skb)->opt);
3709 + /* source routing */
3710 + if ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) {
3711 + if (!((opt->srr) & (opt->is_strictroute)))
3714 + else if ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) {
3715 + if (!((opt->srr) & (!opt->is_strictroute)))
3718 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) {
3722 + /* record route */
3723 + if ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) {
3727 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) {
3732 + if ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) {
3736 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) {
3740 + /* router-alert option */
3741 + if ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) {
3742 + if (!opt->router_alert)
3745 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) {
3746 + if (opt->router_alert)
3755 +checkentry(const char *tablename,
3756 + const struct ipt_ip *ip,
3758 + unsigned int matchsize,
3759 + unsigned int hook_mask)
3761 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
3762 + /* Check the size */
3763 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_ipv4options_info)))
3765 + /* Now check the coherence of the data ... */
3766 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) &&
3767 + (((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) ||
3768 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) ||
3769 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) ||
3770 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) ||
3771 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)))
3772 + return 0; /* opposites */
3773 + if (((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) &&
3774 + (((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
3775 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3776 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
3777 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
3778 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) ||
3779 + ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)))
3780 + return 0; /* opposites */
3781 + if (((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) &&
3782 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR))
3783 + return 0; /* cannot match in the same time loose and strict source routing */
3784 + if ((((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3785 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR)) &&
3786 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR))
3787 + return 0; /* opposites */
3788 + if (((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) &&
3789 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR))
3790 + return 0; /* opposites */
3791 + if (((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) &&
3792 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
3793 + return 0; /* opposites */
3794 + if (((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) &&
3795 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
3796 + return 0; /* opposites */
3798 + /* everything looks ok. */
3802 +static struct ipt_match ipv4options_match = {
3803 + .name = "ipv4options",
3805 + .checkentry = checkentry,
3809 +static int __init init(void)
3811 + return ipt_register_match(&ipv4options_match);
3814 +static void __exit fini(void)
3816 + ipt_unregister_match(&ipv4options_match);
3821 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
3822 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_mport.c 1970-01-01 01:00:00.000000000 +0100
3823 +++ linux-2.6.7/net/ipv4/netfilter/ipt_mport.c 2004-06-29 12:32:15.541507864 +0200
3825 +/* Kernel module to match one of a list of TCP/UDP ports: ports are in
3826 + the same place so we can treat them as equal. */
3827 +#include <linux/module.h>
3828 +#include <linux/types.h>
3829 +#include <linux/udp.h>
3830 +#include <linux/skbuff.h>
3832 +#include <linux/netfilter_ipv4/ipt_mport.h>
3833 +#include <linux/netfilter_ipv4/ip_tables.h>
3835 +MODULE_LICENSE("GPL");
3838 +#define duprintf(format, args...) printk(format , ## args)
3840 +#define duprintf(format, args...)
3843 +/* Returns 1 if the port is matched by the test, 0 otherwise. */
3845 +ports_match(const struct ipt_mport *minfo, u_int16_t src, u_int16_t dst)
3849 + u_int16_t pflags = minfo->pflags;
3850 + for (i=0, m=1; i<IPT_MULTI_PORTS; i++, m<<=1) {
3854 + && minfo->ports[i] == 65535)
3857 + s = minfo->ports[i];
3860 + e = minfo->ports[++i];
3865 + if (minfo->flags & IPT_MPORT_SOURCE
3866 + && src >= s && src <= e)
3869 + if (minfo->flags & IPT_MPORT_DESTINATION
3870 + && dst >= s && dst <= e)
3878 +match(const struct sk_buff *skb,
3879 + const struct net_device *in,
3880 + const struct net_device *out,
3881 + const void *matchinfo,
3886 + const struct ipt_mport *minfo = matchinfo;
3891 + /* Must be big enough to read ports (both UDP and TCP have
3892 + them at the start). */
3893 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
3894 + /* We've been asked to examine this packet, and we
3895 + can't. Hence, no choice but to drop. */
3896 + duprintf("ipt_multiport:"
3897 + " Dropping evil offset=0 tinygram.\n");
3902 + return ports_match(minfo, ntohs(ports[0]), ntohs(ports[1]));
3905 +/* Called when user tries to insert an entry of this type. */
3907 +checkentry(const char *tablename,
3908 + const struct ipt_ip *ip,
3910 + unsigned int matchsize,
3911 + unsigned int hook_mask)
3913 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_mport)))
3916 + /* Must specify proto == TCP/UDP, no unknown flags or bad count */
3917 + return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
3918 + && !(ip->invflags & IPT_INV_PROTO)
3919 + && matchsize == IPT_ALIGN(sizeof(struct ipt_mport));
3922 +static struct ipt_match mport_match = {
3925 + .checkentry = &checkentry,
3929 +static int __init init(void)
3931 + return ipt_register_match(&mport_match);
3934 +static void __exit fini(void)
3936 + ipt_unregister_match(&mport_match);
3941 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
3942 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_nth.c 1970-01-01 01:00:00.000000000 +0100
3943 +++ linux-2.6.7/net/ipv4/netfilter/ipt_nth.c 2004-06-29 12:32:16.701331544 +0200
3946 + This is a module which is used for match support for every Nth packet
3947 + This file is distributed under the terms of the GNU General Public
3948 + License (GPL). Copies of the GPL can be obtained from:
3949 + ftp://prep.ai.mit.edu/pub/gnu/GPL
3951 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
3952 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
3953 + * added support for multiple counters
3954 + * added support for matching on individual packets
3955 + in the counter cycle
3956 + 2004-02-19 Harald Welte <laforge@netfilter.org>
3961 +#include <linux/module.h>
3962 +#include <linux/skbuff.h>
3963 +#include <linux/ip.h>
3964 +#include <net/tcp.h>
3965 +#include <linux/spinlock.h>
3966 +#include <linux/netfilter_ipv4/ip_tables.h>
3967 +#include <linux/netfilter_ipv4/ipt_nth.h>
3969 +MODULE_LICENSE("GPL");
3970 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
3973 + * State information.
3980 +static struct state states[IPT_NTH_NUM_COUNTERS];
3983 +ipt_nth_match(const struct sk_buff *pskb,
3984 + const struct net_device *in,
3985 + const struct net_device *out,
3986 + const void *matchinfo,
3990 + /* Parameters from userspace */
3991 + const struct ipt_nth_info *info = matchinfo;
3992 + unsigned counter = info->counter;
3993 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
3995 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
3999 + spin_lock(&states[counter].lock);
4001 + /* Are we matching every nth packet?*/
4002 + if (info->packet == 0xFF)
4004 + /* We're matching every nth packet and only every nth packet*/
4005 + /* Do we match or invert match? */
4006 + if (info->not == 0)
4008 + if (states[counter].number == 0)
4010 + ++states[counter].number;
4013 + if (states[counter].number >= info->every)
4014 + states[counter].number = 0; /* reset the counter */
4016 + ++states[counter].number;
4021 + if (states[counter].number == 0)
4023 + ++states[counter].number;
4026 + if (states[counter].number >= info->every)
4027 + states[counter].number = 0;
4029 + ++states[counter].number;
4035 + /* We're using the --packet, so there must be a rule for every value */
4036 + if (states[counter].number == info->packet)
4038 + /* only increment the counter when a match happens */
4039 + if (states[counter].number >= info->every)
4040 + states[counter].number = 0; /* reset the counter */
4042 + ++states[counter].number;
4051 + spin_unlock(&states[counter].lock);
4055 + spin_unlock(&states[counter].lock);
4060 +ipt_nth_checkentry(const char *tablename,
4061 + const struct ipt_ip *e,
4063 + unsigned int matchsize,
4064 + unsigned int hook_mask)
4066 + /* Parameters from userspace */
4067 + const struct ipt_nth_info *info = matchinfo;
4068 + unsigned counter = info->counter;
4069 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
4071 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
4075 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_nth_info))) {
4076 + printk("nth: matchsize %u != %u\n", matchsize,
4077 + IPT_ALIGN(sizeof(struct ipt_nth_info)));
4081 + states[counter].number = info->startat;
4086 +static struct ipt_match ipt_nth_reg = {
4088 + .match = ipt_nth_match,
4089 + .checkentry = ipt_nth_checkentry,
4093 +static int __init init(void)
4097 + memset(&states, 0, sizeof(states));
4098 + for (counter = 0; counter < IPT_NTH_NUM_COUNTERS; counter++)
4099 + spin_lock_init(&(states[counter].lock));
4101 + return ipt_register_match(&ipt_nth_reg);
4104 +static void __exit fini(void)
4106 + ipt_unregister_match(&ipt_nth_reg);
4111 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
4112 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_owner.c 2004-06-29 12:24:13.000000000 +0200
4113 +++ linux-2.6.7/net/ipv4/netfilter/ipt_owner.c 2004-06-29 12:35:34.494262448 +0200
4115 * This program is free software; you can redistribute it and/or modify
4116 * it under the terms of the GNU General Public License version 2 as
4117 * published by the Free Software Foundation.
4119 + * 03/26/2003 Patrick McHardy <kaber@trash.net> : LOCAL_IN support
4122 #include <linux/module.h>
4123 #include <linux/skbuff.h>
4124 #include <linux/file.h>
4125 +#include <linux/ip.h>
4126 +#include <linux/tcp.h>
4127 +#include <linux/udp.h>
4128 #include <net/sock.h>
4129 +#include <net/tcp.h>
4130 +#include <net/udp.h>
4132 #include <linux/netfilter_ipv4/ipt_owner.h>
4133 #include <linux/netfilter_ipv4/ip_tables.h>
4135 MODULE_DESCRIPTION("iptables owner match");
4138 -match_comm(const struct sk_buff *skb, const char *comm)
4139 +match_comm(const struct sock *sk, const char *comm)
4141 struct task_struct *g, *p;
4142 struct files_struct *files;
4144 spin_lock(&files->file_lock);
4145 for (i=0; i < files->max_fds; i++) {
4146 if (fcheck_files(files, i) ==
4147 - skb->sk->sk_socket->file) {
4148 + sk->sk_socket->file) {
4149 spin_unlock(&files->file_lock);
4151 read_unlock(&tasklist_lock);
4156 -match_pid(const struct sk_buff *skb, pid_t pid)
4157 +match_pid(const struct sock *sk, pid_t pid)
4159 struct task_struct *p;
4160 struct files_struct *files;
4162 spin_lock(&files->file_lock);
4163 for (i=0; i < files->max_fds; i++) {
4164 if (fcheck_files(files, i) ==
4165 - skb->sk->sk_socket->file) {
4166 + sk->sk_socket->file) {
4167 spin_unlock(&files->file_lock);
4169 read_unlock(&tasklist_lock);
4174 -match_sid(const struct sk_buff *skb, pid_t sid)
4175 +match_sid(const struct sock *sk, pid_t sid)
4177 struct task_struct *g, *p;
4178 - struct file *file = skb->sk->sk_socket->file;
4179 + struct file *file = sk->sk_socket->file;
4182 read_lock(&tasklist_lock);
4183 @@ -129,41 +136,71 @@
4186 const struct ipt_owner_info *info = matchinfo;
4187 + struct iphdr *iph = skb->nh.iph;
4188 + struct sock *sk = NULL;
4194 + if (iph->protocol == IPPROTO_TCP) {
4195 + struct tcphdr *tcph =
4196 + (struct tcphdr *)((u_int32_t *)iph + iph->ihl);
4197 + sk = tcp_v4_lookup(iph->saddr, tcph->source,
4198 + iph->daddr, tcph->dest,
4199 + skb->dev->ifindex);
4200 + if (sk && sk->sk_state == TCP_TIME_WAIT) {
4201 + tcp_tw_put((struct tcp_tw_bucket *)sk);
4204 + } else if (iph->protocol == IPPROTO_UDP) {
4205 + struct udphdr *udph =
4206 + (struct udphdr *)((u_int32_t *)iph + iph->ihl);
4207 + sk = udp_v4_lookup(iph->saddr, udph->source, iph->daddr,
4208 + udph->dest, skb->dev->ifindex);
4212 - if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
4214 + if (!sk || !sk->sk_socket || !sk->sk_socket->file)
4217 if(info->match & IPT_OWNER_UID) {
4218 - if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
4219 + if ((sk->sk_socket->file->f_uid != info->uid) ^
4220 !!(info->invert & IPT_OWNER_UID))
4225 if(info->match & IPT_OWNER_GID) {
4226 - if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
4227 + if ((sk->sk_socket->file->f_gid != info->gid) ^
4228 !!(info->invert & IPT_OWNER_GID))
4233 if(info->match & IPT_OWNER_PID) {
4234 - if (!match_pid(skb, info->pid) ^
4235 + if (!match_pid(sk, info->pid) ^
4236 !!(info->invert & IPT_OWNER_PID))
4241 if(info->match & IPT_OWNER_SID) {
4242 - if (!match_sid(skb, info->sid) ^
4243 + if (!match_sid(sk, info->sid) ^
4244 !!(info->invert & IPT_OWNER_SID))
4249 if(info->match & IPT_OWNER_COMM) {
4250 - if (!match_comm(skb, info->comm) ^
4251 + if (!match_comm(sk, info->comm) ^
4252 !!(info->invert & IPT_OWNER_COMM))
4268 @@ -173,11 +210,19 @@
4269 unsigned int matchsize,
4270 unsigned int hook_mask)
4273 - & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) {
4274 - printk("ipt_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
4278 + & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING) |
4279 + (1 << NF_IP_LOCAL_IN))) {
4280 + printk("ipt_owner: only valid for LOCAL_IN, LOCAL_OUT "
4281 + "or POST_ROUTING.\n");
4285 + if ((hook_mask & (1 << NF_IP_LOCAL_IN))
4286 + && ip->proto != IPPROTO_TCP && ip->proto != IPPROTO_UDP) {
4287 + printk("ipt_owner: only TCP or UDP can be used in LOCAL_IN\n");
4291 if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info))) {
4292 printk("Matchsize %u != %Zu\n", matchsize,
4293 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
4294 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_policy.c 1970-01-01 01:00:00.000000000 +0100
4295 +++ linux-2.6.7/net/ipv4/netfilter/ipt_policy.c 2004-06-29 12:35:40.048418088 +0200
4297 +/* IP tables module for matching IPsec policy
4299 + * Copyright (c) 2004 Patrick McHardy, <kaber@trash.net>
4301 + * This program is free software; you can redistribute it and/or modify
4302 + * it under the terms of the GNU General Public License version 2 as
4303 + * published by the Free Software Foundation.
4306 +#include <linux/kernel.h>
4307 +#include <linux/config.h>
4308 +#include <linux/module.h>
4309 +#include <linux/skbuff.h>
4310 +#include <linux/init.h>
4311 +#include <net/xfrm.h>
4313 +#include <linux/netfilter_ipv4.h>
4314 +#include <linux/netfilter_ipv4/ipt_policy.h>
4315 +#include <linux/netfilter_ipv4/ip_tables.h>
4317 +MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
4318 +MODULE_DESCRIPTION("IPtables IPsec policy matching module");
4319 +MODULE_LICENSE("GPL");
4323 +match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e)
4325 +#define MISMATCH(x,y) (e->match.x && ((e->x != (y)) ^ e->invert.x))
4327 + if (MISMATCH(saddr, x->props.saddr.a4 & e->smask) ||
4328 + MISMATCH(daddr, x->id.daddr.a4 & e->dmask) ||
4329 + MISMATCH(proto, x->id.proto) ||
4330 + MISMATCH(mode, x->props.mode) ||
4331 + MISMATCH(spi, x->id.spi) ||
4332 + MISMATCH(reqid, x->props.reqid))
4338 +match_policy_in(const struct sk_buff *skb, const struct ipt_policy_info *info)
4340 + const struct ipt_policy_elem *e;
4341 + struct sec_path *sp = skb->sp;
4342 + int strict = info->flags & POLICY_MATCH_STRICT;
4347 + if (strict && info->len != sp->len)
4350 + for (i = sp->len - 1; i >= 0; i--) {
4351 + pos = strict ? i - sp->len + 1 : 0;
4352 + if (pos >= info->len)
4354 + e = &info->pol[pos];
4356 + if (match_xfrm_state(sp->x[i].xvec, e)) {
4359 + } else if (strict)
4363 + return strict ? 1 : 0;
4367 +match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info)
4369 + const struct ipt_policy_elem *e;
4370 + struct dst_entry *dst = skb->dst;
4371 + int strict = info->flags & POLICY_MATCH_STRICT;
4374 + if (dst->xfrm == NULL)
4377 + for (i = 0; dst && dst->xfrm; dst = dst->child, i++) {
4378 + pos = strict ? i : 0;
4379 + if (pos >= info->len)
4381 + e = &info->pol[pos];
4383 + if (match_xfrm_state(dst->xfrm, e)) {
4386 + } else if (strict)
4390 + return strict ? 1 : 0;
4393 +static int match(const struct sk_buff *skb,
4394 + const struct net_device *in,
4395 + const struct net_device *out,
4396 + const void *matchinfo, int offset, int *hotdrop)
4398 + const struct ipt_policy_info *info = matchinfo;
4401 + if (info->flags & POLICY_MATCH_IN)
4402 + ret = match_policy_in(skb, info);
4404 + ret = match_policy_out(skb, info);
4407 + if (info->flags & POLICY_MATCH_NONE)
4411 + } else if (info->flags & POLICY_MATCH_NONE)
4417 +static int checkentry(const char *tablename, const struct ipt_ip *ip,
4418 + void *matchinfo, unsigned int matchsize,
4419 + unsigned int hook_mask)
4421 + struct ipt_policy_info *info = matchinfo;
4423 + if (matchsize != IPT_ALIGN(sizeof(*info))) {
4424 + printk(KERN_ERR "ipt_policy: matchsize %u != %u\n",
4425 + matchsize, IPT_ALIGN(sizeof(*info)));
4428 + if (!(info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT))) {
4429 + printk(KERN_ERR "ipt_policy: neither incoming nor "
4430 + "outgoing policy selected\n");
4433 + if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
4434 + && info->flags & POLICY_MATCH_OUT) {
4435 + printk(KERN_ERR "ipt_policy: output policy not valid in "
4436 + "PRE_ROUTING and INPUT\n");
4439 + if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
4440 + && info->flags & POLICY_MATCH_IN) {
4441 + printk(KERN_ERR "ipt_policy: input policy not valid in "
4442 + "POST_ROUTING and OUTPUT\n");
4445 + if (info->len > POLICY_MAX_ELEM) {
4446 + printk(KERN_ERR "ipt_policy: too many policy elements\n");
4453 +static struct ipt_match policy_match =
4457 + .checkentry = checkentry,
4458 + .me = THIS_MODULE,
4461 +static int __init init(void)
4463 + return ipt_register_match(&policy_match);
4466 +static void __exit fini(void)
4468 + ipt_unregister_match(&policy_match);
4473 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
4474 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_psd.c 1970-01-01 01:00:00.000000000 +0100
4475 +++ linux-2.6.7/net/ipv4/netfilter/ipt_psd.c 2004-06-29 12:32:18.295089256 +0200
4478 + This is a module which is used for PSD (portscan detection)
4479 + Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
4480 + and LOG target module.
4482 + Copyright (C) 2000,2001 astaro AG
4484 + This file is distributed under the terms of the GNU General Public
4485 + License (GPL). Copies of the GPL can be obtained from:
4486 + ftp://prep.ai.mit.edu/pub/gnu/GPL
4488 + 2000-05-04 Markus Hennig <hennig@astaro.de> : initial
4489 + 2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
4490 + 2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
4491 + 2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
4492 + 2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
4493 + 2004-05-05 Martijn Lievaart <m@rtij.nl> : ported to 2.6
4496 +#include <linux/module.h>
4497 +#include <linux/skbuff.h>
4498 +#include <linux/ip.h>
4499 +#include <net/tcp.h>
4500 +#include <linux/spinlock.h>
4501 +#include <linux/netfilter_ipv4/ip_tables.h>
4502 +#include <linux/netfilter_ipv4/ipt_psd.h>
4505 +#define DEBUGP printk
4507 +#define DEBUGP(format, args...)
4510 +MODULE_LICENSE("GPL");
4511 +MODULE_AUTHOR("Dennis Koslowski <koslowski@astaro.com>");
4513 +#define HF_DADDR_CHANGING 0x01
4514 +#define HF_SPORT_CHANGING 0x02
4515 +#define HF_TOS_CHANGING 0x04
4516 +#define HF_TTL_CHANGING 0x08
4519 + * Information we keep per each target port
4522 + u_int16_t number; /* port number */
4523 + u_int8_t proto; /* protocol number */
4524 + u_int8_t and_flags; /* tcp ANDed flags */
4525 + u_int8_t or_flags; /* tcp ORed flags */
4529 + * Information we keep per each source address.
4532 + struct host *next; /* Next entry with the same hash */
4533 + clock_t timestamp; /* Last update time */
4534 + struct in_addr src_addr; /* Source address */
4535 + struct in_addr dest_addr; /* Destination address */
4536 + unsigned short src_port; /* Source port */
4537 + int count; /* Number of ports in the list */
4538 + int weight; /* Total weight of ports in the list */
4539 + struct port ports[SCAN_MAX_COUNT - 1]; /* List of ports */
4540 + unsigned char tos; /* TOS */
4541 + unsigned char ttl; /* TTL */
4542 + unsigned char flags; /* HF_ flags bitmask */
4546 + * State information.
4550 + struct host list[LIST_SIZE]; /* List of source addresses */
4551 + struct host *hash[HASH_SIZE]; /* Hash: pointers into the list */
4552 + int index; /* Oldest entry to be replaced */
4556 + * Convert an IP address into a hash table index.
4558 +static inline int hashfunc(struct in_addr addr)
4560 + unsigned int value;
4563 + value = addr.s_addr;
4567 + } while ((value >>= HASH_LOG));
4569 + return hash & (HASH_SIZE - 1);
4573 +ipt_psd_match(const struct sk_buff *pskb,
4574 + const struct net_device *in,
4575 + const struct net_device *out,
4576 + const void *matchinfo,
4580 + struct iphdr *ip_hdr;
4581 + struct tcphdr *tcp_hdr;
4582 + struct in_addr addr;
4583 + u_int16_t src_port,dest_port;
4584 + u_int8_t tcp_flags, proto;
4586 + struct host *curr, *last, **head;
4587 + int hash, index, count;
4589 + /* Parameters from userspace */
4590 + const struct ipt_psd_info *psdinfo = matchinfo;
4593 + ip_hdr = pskb->nh.iph;
4595 + /* Sanity check */
4596 + if (ntohs(ip_hdr->frag_off) & IP_OFFSET) {
4597 + DEBUGP("PSD: sanity check failed\n");
4601 + /* TCP or UDP ? */
4602 + proto = ip_hdr->protocol;
4604 + if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
4605 + DEBUGP("PSD: protocol not supported\n");
4609 + /* Get the source address, source & destination ports, and TCP flags */
4611 + addr.s_addr = ip_hdr->saddr;
4613 + tcp_hdr = (struct tcphdr*)((u_int32_t *)ip_hdr + ip_hdr->ihl);
4615 + /* Yep, it´s dirty */
4616 + src_port = tcp_hdr->source;
4617 + dest_port = tcp_hdr->dest;
4619 + if (proto == IPPROTO_TCP) {
4620 + tcp_flags = *((u_int8_t*)tcp_hdr + 13);
4626 + /* We're using IP address 0.0.0.0 for a special purpose here, so don't let
4627 + * them spoof us. [DHCP needs this feature - HW] */
4628 + if (!addr.s_addr) {
4629 + DEBUGP("PSD: spoofed source address (0.0.0.0)\n");
4633 + /* Use jiffies here not to depend on someone setting the time while we're
4634 + * running; we need to be careful with possible return value overflows. */
4637 + spin_lock(&state.lock);
4639 + /* Do we know this source address already? */
4642 + if ((curr = *(head = &state.hash[hash = hashfunc(addr)])))
4644 + if (curr->src_addr.s_addr == addr.s_addr) break;
4646 + if (curr->next) last = curr;
4647 + } while ((curr = curr->next));
4651 + /* We know this address, and the entry isn't too old. Update it. */
4652 + if (now - curr->timestamp <= (psdinfo->delay_threshold*HZ)/100 &&
4653 + time_after_eq(now, curr->timestamp)) {
4655 + /* Just update the appropriate list entry if we've seen this port already */
4656 + for (index = 0; index < curr->count; index++) {
4657 + if (curr->ports[index].number == dest_port) {
4658 + curr->ports[index].proto = proto;
4659 + curr->ports[index].and_flags &= tcp_flags;
4660 + curr->ports[index].or_flags |= tcp_flags;
4661 + goto out_no_match;
4665 + /* TCP/ACK and/or TCP/RST to a new port? This could be an outgoing connection. */
4666 + if (proto == IPPROTO_TCP && (tcp_hdr->ack || tcp_hdr->rst))
4667 + goto out_no_match;
4669 + /* Packet to a new port, and not TCP/ACK: update the timestamp */
4670 + curr->timestamp = now;
4672 + /* Logged this scan already? Then drop the packet. */
4673 + if (curr->weight >= psdinfo->weight_threshold)
4676 + /* Specify if destination address, source port, TOS or TTL are not fixed */
4677 + if (curr->dest_addr.s_addr != ip_hdr->daddr)
4678 + curr->flags |= HF_DADDR_CHANGING;
4679 + if (curr->src_port != src_port)
4680 + curr->flags |= HF_SPORT_CHANGING;
4681 + if (curr->tos != ip_hdr->tos)
4682 + curr->flags |= HF_TOS_CHANGING;
4683 + if (curr->ttl != ip_hdr->ttl)
4684 + curr->flags |= HF_TTL_CHANGING;
4686 + /* Update the total weight */
4687 + curr->weight += (ntohs(dest_port) < 1024) ?
4688 + psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
4690 + /* Got enough destination ports to decide that this is a scan? */
4691 + /* Then log it and drop the packet. */
4692 + if (curr->weight >= psdinfo->weight_threshold)
4695 + /* Remember the new port */
4696 + if (curr->count < SCAN_MAX_COUNT) {
4697 + curr->ports[curr->count].number = dest_port;
4698 + curr->ports[curr->count].proto = proto;
4699 + curr->ports[curr->count].and_flags = tcp_flags;
4700 + curr->ports[curr->count].or_flags = tcp_flags;
4704 + goto out_no_match;
4707 + /* We know this address, but the entry is outdated. Mark it unused, and
4708 + * remove from the hash table. We'll allocate a new entry instead since
4709 + * this one might get re-used too soon. */
4710 + curr->src_addr.s_addr = 0;
4712 + last->next = last->next->next;
4714 + *head = (*head)->next;
4718 + /* We don't need an ACK from a new source address */
4719 + if (proto == IPPROTO_TCP && tcp_hdr->ack)
4720 + goto out_no_match;
4722 + /* Got too many source addresses with the same hash value? Then remove the
4723 + * oldest one from the hash table, so that they can't take too much of our
4724 + * CPU time even with carefully chosen spoofed IP addresses. */
4725 + if (count >= HASH_MAX && last) last->next = NULL;
4727 + /* We're going to re-use the oldest list entry, so remove it from the hash
4728 + * table first (if it is really already in use, and isn't removed from the
4729 + * hash table already because of the HASH_MAX check above). */
4731 + /* First, find it */
4732 + if (state.list[state.index].src_addr.s_addr)
4733 + head = &state.hash[hashfunc(state.list[state.index].src_addr)];
4737 + if ((curr = *head))
4739 + if (curr == &state.list[state.index]) break;
4741 + } while ((curr = curr->next));
4743 + /* Then, remove it */
4746 + last->next = last->next->next;
4748 + *head = (*head)->next;
4751 + /* Get our list entry */
4752 + curr = &state.list[state.index++];
4753 + if (state.index >= LIST_SIZE) state.index = 0;
4755 + /* Link it into the hash table */
4756 + head = &state.hash[hash];
4757 + curr->next = *head;
4760 + /* And fill in the fields */
4761 + curr->timestamp = now;
4762 + curr->src_addr = addr;
4763 + curr->dest_addr.s_addr = ip_hdr->daddr;
4764 + curr->src_port = src_port;
4766 + curr->weight = (ntohs(dest_port) < 1024) ?
4767 + psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
4768 + curr->ports[0].number = dest_port;
4769 + curr->ports[0].proto = proto;
4770 + curr->ports[0].and_flags = tcp_flags;
4771 + curr->ports[0].or_flags = tcp_flags;
4772 + curr->tos = ip_hdr->tos;
4773 + curr->ttl = ip_hdr->ttl;
4776 + spin_unlock(&state.lock);
4780 + spin_unlock(&state.lock);
4784 +static int ipt_psd_checkentry(const char *tablename,
4785 + const struct ipt_ip *e,
4787 + unsigned int matchsize,
4788 + unsigned int hook_mask)
4790 +/* const struct ipt_psd_info *psdinfo = targinfo;*/
4792 + /* we accept TCP only */
4793 +/* if (e->ip.proto != IPPROTO_TCP) { */
4794 +/* DEBUGP("PSD: specified protocol may be TCP only\n"); */
4798 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_psd_info))) {
4799 + DEBUGP("PSD: matchsize %u != %u\n",
4801 + IPT_ALIGN(sizeof(struct ipt_psd_info)));
4808 +static struct ipt_match ipt_psd_reg = {
4810 + .match = ipt_psd_match,
4811 + .checkentry = ipt_psd_checkentry,
4812 + .me = THIS_MODULE };
4814 +static int __init init(void)
4816 + if (ipt_register_match(&ipt_psd_reg))
4819 + memset(&state, 0, sizeof(state));
4821 + spin_lock_init(&(state.lock));
4823 + printk("netfilter PSD loaded - (c) astaro AG\n");
4827 +static void __exit fini(void)
4829 + ipt_unregister_match(&ipt_psd_reg);
4830 + printk("netfilter PSD unloaded - (c) astaro AG\n");
4835 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
4836 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_quota.c 1970-01-01 01:00:00.000000000 +0100
4837 +++ linux-2.6.7/net/ipv4/netfilter/ipt_quota.c 2004-06-29 12:32:19.479909136 +0200
4840 + * netfilter module to enforce network quotas
4842 + * Sam Johnston <samj@samj.net>
4844 +#include <linux/module.h>
4845 +#include <linux/skbuff.h>
4846 +#include <linux/spinlock.h>
4847 +#include <linux/interrupt.h>
4849 +#include <linux/netfilter_ipv4/ip_tables.h>
4850 +#include <linux/netfilter_ipv4/ipt_quota.h>
4852 +MODULE_LICENSE("GPL");
4853 +MODULE_AUTHOR("Sam Johnston <samj@samj.net>");
4855 +static spinlock_t quota_lock = SPIN_LOCK_UNLOCKED;
4858 +match(const struct sk_buff *skb,
4859 + const struct net_device *in,
4860 + const struct net_device *out,
4861 + const void *matchinfo,
4862 + int offset, int *hotdrop)
4864 + struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
4865 + unsigned int datalen;
4867 + if (skb->len < sizeof(struct iphdr))
4870 + datalen = skb->len - skb->nh.iph->ihl*4;
4872 + spin_lock_bh("a_lock);
4874 + if (q->quota >= datalen) {
4875 + /* we can afford this one */
4876 + q->quota -= datalen;
4877 + spin_unlock_bh("a_lock);
4879 +#ifdef DEBUG_IPT_QUOTA
4880 + printk("IPT Quota OK: %llu datlen %d \n", q->quota, datalen);
4885 + /* so we do not allow even small packets from now on */
4888 +#ifdef DEBUG_IPT_QUOTA
4889 + printk("IPT Quota Failed: %llu datlen %d \n", q->quota, datalen);
4892 + spin_unlock_bh("a_lock);
4897 +checkentry(const char *tablename,
4898 + const struct ipt_ip *ip,
4899 + void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
4901 + /* TODO: spinlocks? sanity checks? */
4902 + if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info)))
4908 +static struct ipt_match quota_match = {
4911 + .checkentry = checkentry,
4918 + return ipt_register_match("a_match);
4924 + ipt_unregister_match("a_match);
4930 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
4931 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_string.c 1970-01-01 01:00:00.000000000 +0100
4932 +++ linux-2.6.7/net/ipv4/netfilter/ipt_string.c 2004-06-29 12:36:14.591166792 +0200
4934 +/* Kernel module to match a string into a packet.
4936 + * Copyright (C) 2000 Emmanuel Roger <winfield@freegates.be>
4939 + * 24.03.2004: Eric Lauriault <elauri@lacitec.on.ca>
4940 + * Initial 2.6 port
4941 + * 19.02.2002: Gianni Tedesco <gianni@ecsc.co.uk>
4942 + * Fixed SMP re-entrancy problem using per-cpu data areas
4943 + * for the skip/shift tables.
4944 + * 02.05.2001: Gianni Tedesco <gianni@ecsc.co.uk>
4945 + * Fixed kernel panic, due to overrunning boyer moore string
4946 + * tables. Also slightly tweaked heuristic for deciding what
4947 + * search algo to use.
4948 + * 27.01.2001: Gianni Tedesco <gianni@ecsc.co.uk>
4949 + * Implemented Boyer Moore Sublinear search algorithm
4950 + * alongside the existing linear search based on memcmp().
4951 + * Also a quick check to decide which method to use on a per
4955 +#include <linux/smp.h>
4956 +#include <linux/percpu.h>
4957 +#include <linux/module.h>
4958 +#include <linux/skbuff.h>
4959 +#include <linux/file.h>
4960 +#include <net/sock.h>
4962 +#include <linux/netfilter_ipv4/ip_tables.h>
4963 +#include <linux/netfilter_ipv4/ipt_string.h>
4965 +MODULE_LICENSE("GPL");
4967 +struct string_per_cpu {
4968 + int skip[BM_MAX_HLEN];
4969 + int shift[BM_MAX_HLEN];
4970 + int len[BM_MAX_HLEN];
4973 +static DEFINE_PER_CPU(struct string_per_cpu, bm_string_data);
4976 +/* Boyer Moore Sublinear string search - VERY FAST */
4977 +char *search_sublinear (char *needle, char *haystack, int needle_len, int haystack_len)
4979 + int M1, right_end, sk, sh;
4982 + int *skip, *shift, *len;
4984 + /* use data suitable for this CPU */
4985 + shift=__get_cpu_var(bm_string_data).shift;
4986 + skip=__get_cpu_var(bm_string_data).skip;
4987 + len=__get_cpu_var(bm_string_data).len;
4989 + /* Setup skip/shift tables */
4990 + M1 = right_end = needle_len-1;
4991 + for (i = 0; i < BM_MAX_HLEN; i++) skip[i] = needle_len;
4992 + for (i = 0; needle[i]; i++) skip[(int)needle[i]] = M1 - i;
4994 + for (i = 1; i < needle_len; i++) {
4995 + for (j = 0; j < needle_len && needle[M1 - j] == needle[M1 - i - j]; j++);
5000 + for (i = 1; i < needle_len; i++) shift[i] = needle_len;
5001 + for (i = M1; i > 0; i--) shift[len[i]] = i;
5004 + for (i = 0; i < needle_len; i++) {
5005 + if (len[i] == M1 - i) ended = i;
5006 + if (ended) shift[i] = ended;
5009 + /* Do the search*/
5010 + while (right_end < haystack_len)
5012 + for (i = 0; i < needle_len && haystack[right_end - i] == needle[M1 - i]; i++);
5013 + if (i == needle_len) {
5014 + return haystack+(right_end - M1);
5017 + sk = skip[(int)haystack[right_end - i]];
5019 + right_end = max(right_end - i + sk, right_end + sh);
5025 +/* Linear string search based on memcmp() */
5026 +char *search_linear (char *needle, char *haystack, int needle_len, int haystack_len)
5028 + char *k = haystack + (haystack_len-needle_len);
5029 + char *t = haystack;
5031 + while ( t <= k ) {
5032 + if (memcmp(t, needle, needle_len) == 0)
5041 +match(const struct sk_buff *skb,
5042 + const struct net_device *in,
5043 + const struct net_device *out,
5044 + const void *matchinfo,
5048 + const struct ipt_string_info *info = matchinfo;
5049 + struct iphdr *ip = skb->nh.iph;
5051 + char *needle, *haystack;
5052 + proc_ipt_search search=search_linear;
5054 + if ( !ip ) return 0;
5056 + /* get lenghts, and validate them */
5058 + hlen=ntohs(ip->tot_len)-(ip->ihl*4);
5059 + if ( nlen > hlen ) return 0;
5061 + needle=(char *)&info->string;
5062 + haystack=(char *)ip+(ip->ihl*4);
5064 + /* The sublinear search comes in to its own
5065 + * on the larger packets */
5066 + if ( (hlen>IPT_STRING_HAYSTACK_THRESH) &&
5067 + (nlen>IPT_STRING_NEEDLE_THRESH) ) {
5068 + if ( hlen < BM_MAX_HLEN ) {
5069 + search=search_sublinear;
5071 + if (net_ratelimit())
5072 + printk(KERN_INFO "ipt_string: Packet too big "
5073 + "to attempt sublinear string search "
5074 + "(%d bytes)\n", hlen );
5078 + return ((search(needle, haystack, nlen, hlen)!=NULL) ^ info->invert);
5082 +checkentry(const char *tablename,
5083 + const struct ipt_ip *ip,
5085 + unsigned int matchsize,
5086 + unsigned int hook_mask)
5089 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_string_info)))
5095 +static struct ipt_match string_match = {
5098 + .checkentry = &checkentry,
5103 +static int __init init(void)
5105 + return ipt_register_match(&string_match);
5108 +static void __exit fini(void)
5110 + ipt_unregister_match(&string_match);
5117 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
5118 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_time.c 1970-01-01 01:00:00.000000000 +0100
5119 +++ linux-2.6.7/net/ipv4/netfilter/ipt_time.c 2004-06-29 12:32:41.027633384 +0200
5122 + This is a module which is used for time matching
5123 + It is using some modified code from dietlibc (localtime() function)
5124 + that you can find at http://www.fefe.de/dietlibc/
5125 + This file is distributed under the terms of the GNU General Public
5126 + License (GPL). Copies of the GPL can be obtained from: ftp://prep.ai.mit.edu/pub/gnu/GPL
5127 + 2001-05-04 Fabrice MARIE <fabrice@netfilter.org> : initial development.
5128 + 2001-21-05 Fabrice MARIE <fabrice@netfilter.org> : bug fix in the match code,
5129 + thanks to "Zeng Yu" <zengy@capitel.com.cn> for bug report.
5130 + 2001-26-09 Fabrice MARIE <fabrice@netfilter.org> : force the match to be in LOCAL_IN or PRE_ROUTING only.
5131 + 2001-30-11 Fabrice : added the possibility to use the match in FORWARD/OUTPUT with a little hack,
5132 + added Nguyen Dang Phuoc Dong <dongnd@tlnet.com.vn> patch to support timezones.
5133 + 2004-05-02 Fabrice : added support for date matching, from an idea of Fabien COELHO.
5136 +#include <linux/module.h>
5137 +#include <linux/skbuff.h>
5138 +#include <linux/netfilter_ipv4/ip_tables.h>
5139 +#include <linux/netfilter_ipv4/ipt_time.h>
5140 +#include <linux/time.h>
5142 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
5143 +MODULE_DESCRIPTION("Match arrival timestamp/date");
5144 +MODULE_LICENSE("GPL");
5148 + int tm_sec; /* Seconds. [0-60] (1 leap second) */
5149 + int tm_min; /* Minutes. [0-59] */
5150 + int tm_hour; /* Hours. [0-23] */
5151 + int tm_mday; /* Day. [1-31] */
5152 + int tm_mon; /* Month. [0-11] */
5153 + int tm_year; /* Year - 1900. */
5154 + int tm_wday; /* Day of week. [0-6] */
5155 + int tm_yday; /* Days in year.[0-365] */
5156 + int tm_isdst; /* DST. [-1/0/1]*/
5158 + long int tm_gmtoff; /* we don't care, we count from GMT */
5159 + const char *tm_zone; /* we don't care, we count from GMT */
5163 +localtime(const time_t *timepr, struct tm *r);
5166 +match(const struct sk_buff *skb,
5167 + const struct net_device *in,
5168 + const struct net_device *out,
5169 + const void *matchinfo,
5172 + u_int16_t datalen,
5175 + const struct ipt_time_info *info = matchinfo; /* match info for rule */
5176 + struct tm currenttime; /* time human readable */
5177 + u_int8_t days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
5178 + u_int16_t packet_time;
5179 + struct timeval kerneltimeval;
5180 + time_t packet_local_time;
5182 + /* if kerneltime=1, we don't read the skb->timestamp but kernel time instead */
5183 + if (info->kerneltime)
5185 + do_gettimeofday(&kerneltimeval);
5186 + packet_local_time = kerneltimeval.tv_sec;
5189 + packet_local_time = skb->stamp.tv_sec;
5191 + /* First we make sure we are in the date start-stop boundaries */
5192 + if ((packet_local_time < info->date_start) || (packet_local_time > info->date_stop))
5193 + return 0; /* We are outside the date boundaries */
5195 + /* Transform the timestamp of the packet, in a human readable form */
5196 + localtime(&packet_local_time, ¤ttime);
5198 + /* check if we match this timestamp, we start by the days... */
5199 + if ((days_of_week[currenttime.tm_wday] & info->days_match) != days_of_week[currenttime.tm_wday])
5200 + return 0; /* the day doesn't match */
5202 + /* ... check the time now */
5203 + packet_time = (currenttime.tm_hour * 60) + currenttime.tm_min;
5204 + if ((packet_time < info->time_start) || (packet_time > info->time_stop))
5207 + /* here we match ! */
5212 +checkentry(const char *tablename,
5213 + const struct ipt_ip *ip,
5215 + unsigned int matchsize,
5216 + unsigned int hook_mask)
5218 + struct ipt_time_info *info = matchinfo; /* match info for rule */
5220 + /* First, check that we are in the correct hooks */
5222 + & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
5224 + printk("ipt_time: error, only valid for PRE_ROUTING, LOCAL_IN, FORWARD and OUTPUT)\n");
5227 + /* we use the kerneltime if we are in forward or output */
5228 + info->kerneltime = 1;
5229 + if (hook_mask & ~((1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
5230 + /* we use the skb time */
5231 + info->kerneltime = 0;
5233 + /* Check the size */
5234 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_time_info)))
5236 + /* Now check the coherence of the data ... */
5237 + if ((info->time_start > 1439) || /* 23*60+59 = 1439*/
5238 + (info->time_stop > 1439))
5240 + printk(KERN_WARNING "ipt_time: invalid argument\n");
5247 +static struct ipt_match time_match
5248 += { { NULL, NULL }, "time", &match, &checkentry, NULL, THIS_MODULE };
5250 +static int __init init(void)
5252 + printk("ipt_time loading\n");
5253 + return ipt_register_match(&time_match);
5256 +static void __exit fini(void)
5258 + ipt_unregister_match(&time_match);
5259 + printk("ipt_time unloaded\n");
5266 +/* The part below is borowed and modified from dietlibc */
5268 +/* seconds per day */
5269 +#define SPD 24*60*60
5272 +localtime(const time_t *timepr, struct tm *r) {
5275 + extern struct timezone sys_tz;
5276 + const unsigned int __spm[12] =
5283 + (31+28+31+30+31+30),
5284 + (31+28+31+30+31+30+31),
5285 + (31+28+31+30+31+30+31+31),
5286 + (31+28+31+30+31+30+31+31+30),
5287 + (31+28+31+30+31+30+31+31+30+31),
5288 + (31+28+31+30+31+30+31+31+30+31+30),
5290 + register time_t work;
5292 + timep = (*timepr) - (sys_tz.tz_minuteswest * 60);
5294 + r->tm_sec=work%60; work/=60;
5295 + r->tm_min=work%60; r->tm_hour=work/60;
5297 + r->tm_wday=(4+work)%7;
5298 + for (i=1970; ; ++i) {
5299 + register time_t k= (!(i%4) && ((i%100) || !(i%400)))?366:365;
5305 + r->tm_year=i-1900;
5306 + for (i=11; i && __spm[i]>work; --i) ;
5308 + r->tm_mday=work-__spm[i]+1;
5310 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
5311 --- linux-2.6.7.org/net/ipv4/netfilter/ipt_unclean.c 1970-01-01 01:00:00.000000000 +0100
5312 +++ linux-2.6.7/net/ipv4/netfilter/ipt_unclean.c 2004-06-29 12:36:11.004712016 +0200
5314 +/* Kernel module to match suspect packets. */
5315 +#include <linux/module.h>
5316 +#include <linux/skbuff.h>
5317 +#include <net/ip.h>
5318 +#include <linux/udp.h>
5319 +#include <linux/tcp.h>
5320 +#include <linux/icmp.h>
5321 +#include <net/checksum.h>
5323 +#include <linux/netfilter_ipv4/ip_tables.h>
5325 +#define limpk(format, args...) \
5327 + if (net_ratelimit()) \
5328 + printk("ipt_unclean: %s" format, \
5329 + embedded ? "(embedded packet) " : "" , ## args); \
5332 +enum icmp_error_status
5334 + ICMP_MAY_BE_ERROR,
5341 + size_t min_len, max_len;
5342 + enum icmp_error_status err;
5343 + u_int8_t min_code, max_code;
5347 +check_ip(struct iphdr *iph, size_t length, int embedded);
5349 +/* ICMP-specific checks. */
5351 +check_icmp(const struct icmphdr *icmph,
5352 + u_int16_t datalen,
5353 + unsigned int offset,
5357 + static struct icmp_info info[]
5358 + = { [ICMP_ECHOREPLY]
5359 + = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
5360 + [ICMP_DEST_UNREACH]
5361 + = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 15 },
5362 + [ICMP_SOURCE_QUENCH]
5363 + = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 0 },
5365 + = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 3 },
5367 + = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
5368 + /* Router advertisement. */
5370 + = { 8, 8 + 255 * 8, ICMP_NOT_ERROR, 0, 0 },
5371 + /* Router solicitation. */
5373 + = { 8, 8, ICMP_NOT_ERROR, 0, 0 },
5374 + [ICMP_TIME_EXCEEDED]
5375 + = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 1 },
5376 + [ICMP_PARAMETERPROB]
5377 + = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 1 },
5379 + = { 20, 20, ICMP_NOT_ERROR, 0, 0 },
5380 + [ICMP_TIMESTAMPREPLY]
5381 + = { 20, 20, ICMP_NOT_ERROR, 0, 0 },
5382 + [ICMP_INFO_REQUEST]
5383 + = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
5385 + = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
5387 + = { 12, 12, ICMP_NOT_ERROR, 0, 0 },
5388 + [ICMP_ADDRESSREPLY]
5389 + = { 12, 12, ICMP_NOT_ERROR, 0, 0 } };
5391 + /* Can't do anything if it's a fragment. */
5395 + /* Must cover type and code. */
5396 + if (datalen < 2) {
5397 + limpk("ICMP len=%u too short\n", datalen);
5401 + /* If not embedded. */
5403 + /* Bad checksum? Don't print, just ignore. */
5405 + && ip_compute_csum((unsigned char *) icmph, datalen) != 0)
5408 + /* CHECK: Truncated ICMP (even if first fragment). */
5409 + if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
5410 + && info[icmph->type].min_len != 0
5411 + && datalen < info[icmph->type].min_len) {
5412 + limpk("ICMP type %u len %u too short\n",
5413 + icmph->type, datalen);
5417 + /* CHECK: Check within known error ICMPs. */
5418 + if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
5419 + && info[icmph->type].err == ICMP_IS_ERROR) {
5420 + /* CHECK: Embedded packet must be at least
5421 + length of iph + 8 bytes. */
5422 + struct iphdr *inner = (void *)icmph + 8;
5424 + /* datalen > 8 since all ICMP_IS_ERROR types
5425 + have min length > 8 */
5426 + if (datalen - 8 < sizeof(struct iphdr)) {
5427 + limpk("ICMP error internal way too short\n");
5430 + if (datalen - 8 < inner->ihl*4 + 8) {
5431 + limpk("ICMP error internal too short\n");
5434 + if (!check_ip(inner, datalen - 8, 1))
5438 + /* CHECK: Can't embed ICMP unless known non-error. */
5439 + if (icmph->type >= sizeof(info)/sizeof(struct icmp_info)
5440 + || info[icmph->type].err != ICMP_NOT_ERROR) {
5441 + limpk("ICMP type %u not embeddable\n",
5447 + /* CHECK: Invalid ICMP codes. */
5448 + if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
5449 + && (icmph->code < info[icmph->type].min_code
5450 + || icmph->code > info[icmph->type].max_code)) {
5451 + limpk("ICMP type=%u code=%u\n",
5452 + icmph->type, icmph->code);
5456 + /* CHECK: Above maximum length. */
5457 + if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
5458 + && info[icmph->type].max_len != 0
5459 + && datalen > info[icmph->type].max_len) {
5460 + limpk("ICMP type=%u too long: %u bytes\n",
5461 + icmph->type, datalen);
5465 + switch (icmph->type) {
5466 + case ICMP_PARAMETERPROB: {
5467 + /* CHECK: Problem param must be within error packet's
5469 + struct iphdr *iph = (void *)icmph + 8;
5470 + u_int32_t arg = ntohl(icmph->un.gateway);
5472 + if (icmph->code == 0) {
5473 + /* Code 0 means that upper 8 bits is pointer
5475 + if ((arg >> 24) >= iph->ihl*4) {
5476 + limpk("ICMP PARAMETERPROB ptr = %u\n",
5477 + ntohl(icmph->un.gateway) >> 24);
5480 + arg &= 0x00FFFFFF;
5483 + /* CHECK: Rest must be zero. */
5485 + limpk("ICMP PARAMETERPROB nonzero arg = %u\n",
5492 + case ICMP_TIME_EXCEEDED:
5493 + case ICMP_SOURCE_QUENCH:
5494 + /* CHECK: Unused must be zero. */
5495 + if (icmph->un.gateway != 0) {
5496 + limpk("ICMP type=%u unused = %u\n",
5497 + icmph->type, ntohl(icmph->un.gateway));
5506 +/* UDP-specific checks. */
5508 +check_udp(const struct iphdr *iph,
5509 + const struct udphdr *udph,
5510 + u_int16_t datalen,
5511 + unsigned int offset,
5515 + /* Can't do anything if it's a fragment. */
5519 + /* CHECK: Must cover UDP header. */
5520 + if (datalen < sizeof(struct udphdr)) {
5521 + limpk("UDP len=%u too short\n", datalen);
5525 + /* Bad checksum? Don't print, just say it's unclean. */
5526 + /* FIXME: SRC ROUTE packets won't match checksum --RR */
5527 + if (!more_frags && !embedded && udph->check
5528 + && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_UDP,
5529 + csum_partial((char *)udph, datalen, 0)) != 0)
5532 + /* CHECK: Destination port can't be zero. */
5533 + if (!udph->dest) {
5534 + limpk("UDP zero destination port\n");
5538 + if (!more_frags) {
5540 + /* CHECK: UDP length must match. */
5541 + if (ntohs(udph->len) != datalen) {
5542 + limpk("UDP len too short %u vs %u\n",
5543 + ntohs(udph->len), datalen);
5547 + /* CHECK: UDP length be >= this truncated pkt. */
5548 + if (ntohs(udph->len) < datalen) {
5549 + limpk("UDP len too long %u vs %u\n",
5550 + ntohs(udph->len), datalen);
5555 + /* CHECK: UDP length must be > this frag's length. */
5556 + if (ntohs(udph->len) <= datalen) {
5557 + limpk("UDP fragment len too short %u vs %u\n",
5558 + ntohs(udph->len), datalen);
5566 +#define TH_FIN 0x01
5567 +#define TH_SYN 0x02
5568 +#define TH_RST 0x04
5569 +#define TH_PUSH 0x08
5570 +#define TH_ACK 0x10
5571 +#define TH_URG 0x20
5572 +#define TH_ECE 0x40
5573 +#define TH_CWR 0x80
5575 +/* table of valid flag combinations - ECE and CWR are always valid */
5576 +static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
5579 + [TH_SYN|TH_ACK] = 1,
5581 + [TH_RST|TH_ACK] = 1,
5582 + [TH_RST|TH_ACK|TH_PUSH] = 1,
5583 + [TH_FIN|TH_ACK] = 1,
5585 + [TH_ACK|TH_PUSH] = 1,
5586 + [TH_ACK|TH_URG] = 1,
5587 + [TH_ACK|TH_URG|TH_PUSH] = 1,
5588 + [TH_FIN|TH_ACK|TH_PUSH] = 1,
5589 + [TH_FIN|TH_ACK|TH_URG] = 1,
5590 + [TH_FIN|TH_ACK|TH_URG|TH_PUSH] = 1
5593 +/* TCP-specific checks. */
5595 +check_tcp(const struct iphdr *iph,
5596 + const struct tcphdr *tcph,
5597 + u_int16_t datalen,
5598 + unsigned int offset,
5602 + u_int8_t *opt = (u_int8_t *)tcph;
5603 + u_int8_t *endhdr = (u_int8_t *)tcph + tcph->doff * 4;
5604 + u_int8_t tcpflags;
5605 + int end_of_options = 0;
5608 + /* CHECK: Can't have offset=1: used to override TCP syn-checks. */
5609 + /* In fact, this is caught below (offset < 516). */
5611 + /* Can't do anything if it's a fragment. */
5615 + /* CHECK: Smaller than minimal TCP hdr. */
5616 + if (datalen < sizeof(struct tcphdr)) {
5618 + limpk("Packet length %u < TCP header.\n", datalen);
5621 + /* Must have ports available (datalen >= 8), from
5622 + check_icmp which set embedded = 1 */
5623 + /* CHECK: TCP ports inside ICMP error */
5624 + if (!tcph->source || !tcph->dest) {
5625 + limpk("Zero TCP ports %u/%u.\n",
5626 + htons(tcph->source), htons(tcph->dest));
5632 + /* CHECK: Smaller than actual TCP hdr. */
5633 + if (datalen < tcph->doff * 4) {
5635 + limpk("Packet length %u < actual TCP header.\n",
5642 + /* Bad checksum? Don't print, just say it's unclean. */
5643 + /* FIXME: SRC ROUTE packets won't match checksum --RR */
5644 + if (!more_frags && !embedded
5645 + && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_TCP,
5646 + csum_partial((char *)tcph, datalen, 0)) != 0)
5649 + /* CHECK: TCP ports non-zero */
5650 + if (!tcph->source || !tcph->dest) {
5651 + limpk("Zero TCP ports %u/%u.\n",
5652 + htons(tcph->source), htons(tcph->dest));
5656 + /* CHECK: TCP reserved bits zero. */
5657 + if(tcp_flag_word(tcph) & TCP_RESERVED_BITS) {
5658 + limpk("TCP reserved bits not zero\n");
5662 + /* CHECK: TCP flags. */
5663 + tcpflags = (((u_int8_t *)tcph)[13] & ~(TH_ECE|TH_CWR));
5664 + if (!tcp_valid_flags[tcpflags]) {
5665 + limpk("TCP flags bad: %u\n", tcpflags);
5669 + for (i = sizeof(struct tcphdr); i < tcph->doff * 4; ) {
5672 + end_of_options = 1;
5679 + /* CHECK: options after EOO. */
5680 + if (end_of_options) {
5681 + limpk("TCP option %u after end\n",
5685 + /* CHECK: options at tail. */
5686 + else if (i+1 >= tcph->doff * 4) {
5687 + limpk("TCP option %u at tail\n",
5691 + /* CHECK: zero-length options. */
5692 + else if (opt[i+1] == 0) {
5693 + limpk("TCP option %u 0 len\n",
5697 + /* CHECK: oversize options. */
5698 + else if (&opt[i] + opt[i+1] > endhdr) {
5699 + limpk("TCP option %u at %Zu too long\n",
5700 + (unsigned int) opt[i], i);
5703 + /* Move to next option */
5711 +/* Returns 1 if ok */
5712 +/* Standard IP checks. */
5714 +check_ip(struct iphdr *iph, size_t length, int embedded)
5716 + u_int8_t *opt = (u_int8_t *)iph;
5717 + u_int8_t *endhdr = (u_int8_t *)iph + iph->ihl * 4;
5718 + int end_of_options = 0;
5722 + unsigned int offset;
5724 + /* Should only happen for local outgoing raw-socket packets. */
5725 + /* CHECK: length >= ip header. */
5726 + if (length < sizeof(struct iphdr) || length < iph->ihl * 4) {
5727 + limpk("Packet length %Zu < IP header.\n", length);
5731 + offset = ntohs(iph->frag_off) & IP_OFFSET;
5732 + protoh = (void *)iph + iph->ihl * 4;
5733 + datalen = length - iph->ihl * 4;
5735 + /* CHECK: Embedded fragment. */
5736 + if (embedded && offset) {
5737 + limpk("Embedded fragment.\n");
5741 + for (i = sizeof(struct iphdr); i < iph->ihl * 4; ) {
5744 + end_of_options = 1;
5751 + /* CHECK: options after EOO. */
5752 + if (end_of_options) {
5753 + limpk("IP option %u after end\n",
5757 + /* CHECK: options at tail. */
5758 + else if (i+1 >= iph->ihl * 4) {
5759 + limpk("IP option %u at tail\n",
5763 + /* CHECK: zero-length or one-length options. */
5764 + else if (opt[i+1] < 2) {
5765 + limpk("IP option %u %u len\n",
5766 + opt[i], opt[i+1]);
5769 + /* CHECK: oversize options. */
5770 + else if (&opt[i] + opt[i+1] > endhdr) {
5771 + limpk("IP option %u at %u too long\n",
5775 + /* Move to next option */
5780 + /* Fragment checks. */
5782 + /* CHECK: More fragments, but doesn't fill 8-byte boundary. */
5783 + if ((ntohs(iph->frag_off) & IP_MF)
5784 + && (ntohs(iph->tot_len) % 8) != 0) {
5785 + limpk("Truncated fragment %u long.\n", ntohs(iph->tot_len));
5789 + /* CHECK: Oversize fragment a-la Ping of Death. */
5790 + if (offset * 8 + datalen > 65535) {
5791 + limpk("Oversize fragment to %u.\n", offset * 8);
5795 + /* CHECK: DF set and offset or MF set. */
5796 + if ((ntohs(iph->frag_off) & IP_DF)
5797 + && (offset || (ntohs(iph->frag_off) & IP_MF))) {
5798 + limpk("DF set and offset=%u, MF=%u.\n",
5799 + offset, ntohs(iph->frag_off) & IP_MF);
5803 + /* CHECK: Zero-sized fragments. */
5804 + if ((offset || (ntohs(iph->frag_off) & IP_MF))
5805 + && datalen == 0) {
5806 + limpk("Zero size fragment offset=%u\n", offset);
5810 + /* Note: we can have even middle fragments smaller than this:
5811 + consider a large packet passing through a 600MTU then
5812 + 576MTU link: this gives a fragment of 24 data bytes. But
5813 + everyone packs fragments largest first, hence a fragment
5814 + can't START before 576 - MAX_IP_HEADER_LEN. */
5816 + /* Used to be min-size 576: I recall Alan Cox saying ax25 goes
5817 + down to 128 (576 taken from RFC 791: All hosts must be
5818 + prepared to accept datagrams of up to 576 octets). Use 128
5820 +#define MIN_LIKELY_MTU 128
5821 + /* CHECK: Min size of first frag = 128. */
5822 + if ((ntohs(iph->frag_off) & IP_MF)
5824 + && ntohs(iph->tot_len) < MIN_LIKELY_MTU) {
5825 + limpk("First fragment size %u < %u\n", ntohs(iph->tot_len),
5830 + /* CHECK: Min offset of frag = 128 - IP hdr len. */
5831 + if (offset && offset * 8 < MIN_LIKELY_MTU - iph->ihl * 4) {
5832 + limpk("Fragment starts at %u < %u\n", offset * 8,
5833 + MIN_LIKELY_MTU - iph->ihl * 4);
5837 + /* CHECK: Protocol specification non-zero. */
5838 + if (iph->protocol == 0) {
5839 + limpk("Zero protocol\n");
5843 + /* CHECK: Do not use what is unused.
5844 + * First bit of fragmentation flags should be unused.
5845 + * May be used by OS fingerprinting tools.
5846 + * 04 Jun 2002, Maciej Soltysiak, solt@dns.toxicfilms.tv
5848 + if (ntohs(iph->frag_off)>>15) {
5849 + limpk("IP unused bit set\n");
5853 + /* Per-protocol checks. */
5854 + switch (iph->protocol) {
5855 + case IPPROTO_ICMP:
5856 + return check_icmp(protoh, datalen, offset,
5857 + (ntohs(iph->frag_off) & IP_MF),
5861 + return check_udp(iph, protoh, datalen, offset,
5862 + (ntohs(iph->frag_off) & IP_MF),
5866 + return check_tcp(iph, protoh, datalen, offset,
5867 + (ntohs(iph->frag_off) & IP_MF),
5870 + /* Ignorance is bliss. */
5876 +match(const struct sk_buff *skb,
5877 + const struct net_device *in,
5878 + const struct net_device *out,
5879 + const void *matchinfo,
5882 + u_int16_t datalen,
5885 + return !check_ip(skb->nh.iph, skb->len, 0);
5888 +/* Called when user tries to insert an entry of this type. */
5890 +checkentry(const char *tablename,
5891 + const struct ipt_ip *ip,
5893 + unsigned int matchsize,
5894 + unsigned int hook_mask)
5896 + if (matchsize != IPT_ALIGN(0))
5902 +static struct ipt_match unclean_match
5903 += { { NULL, NULL }, "unclean", &match, &checkentry, NULL, THIS_MODULE };
5905 +static int __init init(void)
5907 + return ipt_register_match(&unclean_match);
5910 +static void __exit fini(void)
5912 + ipt_unregister_match(&unclean_match);
5917 +MODULE_LICENSE("GPL");
5918 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/tcp_ipv4.c linux-2.6.7/net/ipv4/tcp_ipv4.c
5919 --- linux-2.6.7.org/net/ipv4/tcp_ipv4.c 2004-06-29 12:24:14.000000000 +0200
5920 +++ linux-2.6.7/net/ipv4/tcp_ipv4.c 2004-06-29 12:35:34.503261080 +0200
5921 @@ -2642,6 +2642,7 @@
5922 EXPORT_SYMBOL(tcp_v4_connect);
5923 EXPORT_SYMBOL(tcp_v4_do_rcv);
5924 EXPORT_SYMBOL(tcp_v4_lookup_listener);
5925 +EXPORT_SYMBOL(tcp_v4_lookup);
5926 EXPORT_SYMBOL(tcp_v4_rebuild_header);
5927 EXPORT_SYMBOL(tcp_v4_remember_stamp);
5928 EXPORT_SYMBOL(tcp_v4_send_check);
5929 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv4/udp.c linux-2.6.7/net/ipv4/udp.c
5930 --- linux-2.6.7.org/net/ipv4/udp.c 2004-06-29 12:24:14.000000000 +0200
5931 +++ linux-2.6.7/net/ipv4/udp.c 2004-06-29 12:35:34.509260168 +0200
5932 @@ -1560,6 +1560,7 @@
5933 EXPORT_SYMBOL(udp_port_rover);
5934 EXPORT_SYMBOL(udp_prot);
5935 EXPORT_SYMBOL(udp_sendmsg);
5936 +EXPORT_SYMBOL(udp_v4_lookup);
5938 #ifdef CONFIG_PROC_FS
5939 EXPORT_SYMBOL(udp_proc_register);
5940 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv6/netfilter/Kconfig linux-2.6.7/net/ipv6/netfilter/Kconfig
5941 --- linux-2.6.7.org/net/ipv6/netfilter/Kconfig 2004-06-16 07:19:52.000000000 +0200
5942 +++ linux-2.6.7/net/ipv6/netfilter/Kconfig 2004-06-29 12:35:40.081413072 +0200
5943 @@ -230,5 +230,83 @@
5944 <file:Documentation/modules.txt>. If unsure, say `N'.
5947 +config IP6_NF_TARGET_HL
5948 + tristate 'HL target support'
5949 + depends on IP6_NF_MANGLE
5951 + This option adds a `HL' target, which allows you to modify the value of
5952 + IPv6 Hop Limit field.
5954 + If you want to compile it as a module, say M here and read
5955 + <file:Documentation/modules.txt>. If unsure, say `N'.
5957 +config IP6_NF_TARGET_REJECT
5958 + tristate 'REJECT target support'
5959 + depends on IP6_NF_FILTER
5961 + The REJECT target allows a filtering rule to specify that an ICMPv6
5962 + error should be issued in response to an incoming packet, rather
5963 + than silently being dropped.
5965 + If you want to compile it as a module, say M here and read
5966 + Documentation/modules.txt. If unsure, say `N'.
5968 +config IP6_NF_MATCH_FUZZY
5969 + tristate 'Fuzzy match support'
5970 + depends on IP6_NF_FILTER
5972 + This option adds a `fuzzy' match, which allows you to match
5973 + packets according to a fuzzy logic based law.
5975 + If you want to compile it as a module, say M here and read
5976 + Documentation/modules.txt. If unsure, say `N'.
5978 +config IP6_NF_MATCH_NTH
5979 + tristate 'Nth match support'
5980 + depends on IP6_NF_IPTABLES
5982 + This option adds a `Nth' match, which allow you to make
5983 + rules that match every Nth packet. By default there are
5984 + 16 different counters.
5987 + --every Nth Match every Nth packet
5988 + [--counter] num Use counter 0-15 (default:0)
5989 + [--start] num Initialize the counter at the number 'num'
5990 + instead of 0. Must be between 0 and Nth-1
5991 + [--packet] num Match on 'num' packet. Must be between 0
5994 + If --packet is used for a counter than
5995 + there must be Nth number of --packet
5996 + rules, covering all values between 0 and
5997 + Nth-1 inclusively.
5999 + If you want to compile it as a module, say M here and read
6000 + Documentation/modules.txt. If unsure, say `N'.
6002 +config IP6_NF_TARGET_ROUTE
6003 + tristate ' ROUTE target support'
6004 + depends on IP6_NF_MANGLE
6006 + This option adds a `ROUTE' target, which enables you to setup unusual
6007 + routes. The ROUTE target is also able to change the incoming interface
6010 + The target can be or not a final target. It has to be used inside the
6013 + Not working as a module.
6015 +config IP6_NF_MATCH_POLICY
6016 + tristate "IPsec policy match support"
6017 + depends on IP6_NF_IPTABLES && XFRM
6019 + Policy matching allows you to match packets based on the
6020 + IPsec policy that was used during decapsulation/will
6021 + be used during encapsulation.
6023 + To compile it as a module, choose M here. If unsure, say N.
6027 diff -Nur --exclude '*.orig' linux-2.6.7.org/net/ipv6/netfilter/Makefile linux-2.6.7/net/ipv6/netfilter/Makefile
6028 --- linux-2.6.7.org/net/ipv6/netfilter/Makefile 2004-06-16 07:19:36.000000000 +0200
6029 +++ linux-2.6.7/net/ipv6/netfilter/Makefile 2004-06-29 12:35:40.083412768 +0200
6031 obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
6032 obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
6033 obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
6034 +obj-$(CONFIG_IP6_NF_MATCH_FUZZY) += ip6t_fuzzy.o
6035 obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
6036 obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
6037 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
6038 obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o
6039 obj-$(CONFIG_IP6_NF_MATCH_AHESP) += ip6t_esp.o ip6t_ah.o
6040 +obj-$(CONFIG_IP6_NF_MATCH_POLICY) += ip6t_policy.o
6041 obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o
6042 obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o
6043 obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
6044 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
6045 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
6046 obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
6047 +obj-$(CONFIG_IP6_NF_TARGET_ROUTE) += ip6t_ROUTE.o
6048 +obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
6049 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
6050 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
6052 +obj-$(CONFIG_IP6_NF_MATCH_NTH) += ip6t_nth.o
6053 +obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
6054 obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
6055 obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
6056 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
6057 --- linux-2.6.7.org/net/ipv6/netfilter/ip6t_HL.c 1970-01-01 01:00:00.000000000 +0100
6058 +++ linux-2.6.7/net/ipv6/netfilter/ip6t_HL.c 2004-06-29 12:31:59.778904144 +0200
6061 + * Hop Limit modification target for ip6tables
6062 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
6063 + * Based on HW's TTL module
6065 + * This software is distributed under the terms of GNU GPL
6068 +#include <linux/module.h>
6069 +#include <linux/skbuff.h>
6070 +#include <linux/ip.h>
6072 +#include <linux/netfilter_ipv6/ip6_tables.h>
6073 +#include <linux/netfilter_ipv6/ip6t_HL.h>
6075 +MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
6076 +MODULE_DESCRIPTION("IP tables Hop Limit modification module");
6077 +MODULE_LICENSE("GPL");
6079 +static unsigned int ip6t_hl_target(struct sk_buff **pskb, unsigned int hooknum,
6080 + const struct net_device *in, const struct net_device *out,
6081 + const void *targinfo, void *userinfo)
6083 + struct ipv6hdr *ip6h = (*pskb)->nh.ipv6h;
6084 + const struct ip6t_HL_info *info = targinfo;
6085 + u_int16_t diffs[2];
6088 + switch (info->mode) {
6090 + new_hl = info->hop_limit;
6093 + new_hl = ip6h->hop_limit + info->hop_limit;
6098 + new_hl = ip6h->hop_limit + info->hop_limit;
6103 + new_hl = ip6h->hop_limit;
6107 + if (new_hl != ip6h->hop_limit) {
6108 + diffs[0] = htons(((unsigned)ip6h->hop_limit) << 8) ^ 0xFFFF;
6109 + ip6h->hop_limit = new_hl;
6110 + diffs[1] = htons(((unsigned)ip6h->hop_limit) << 8);
6113 + return IP6T_CONTINUE;
6116 +static int ip6t_hl_checkentry(const char *tablename,
6117 + const struct ip6t_entry *e,
6119 + unsigned int targinfosize,
6120 + unsigned int hook_mask)
6122 + struct ip6t_HL_info *info = targinfo;
6124 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_HL_info))) {
6125 + printk(KERN_WARNING "HL: targinfosize %u != %Zu\n",
6127 + IP6T_ALIGN(sizeof(struct ip6t_HL_info)));
6131 + if (strcmp(tablename, "mangle")) {
6132 + printk(KERN_WARNING "HL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
6136 + if (info->mode > IP6T_HL_MAXMODE) {
6137 + printk(KERN_WARNING "HL: invalid or unknown Mode %u\n",
6142 + if ((info->mode != IP6T_HL_SET) && (info->hop_limit == 0)) {
6143 + printk(KERN_WARNING "HL: increment/decrement doesn't make sense with value 0\n");
6150 +static struct ip6t_target ip6t_HL = { { NULL, NULL }, "HL",
6151 + ip6t_hl_target, ip6t_hl_checkentry, NULL, THIS_MODULE };
6153 +static int __init init(void)
6155 + return ip6t_register_target(&ip6t_HL);
6158 +static void __exit fini(void)
6160 + ip6t_unregister_target(&ip6t_HL);
6165 diff -uNr linux-2.6.9-rc1.orig/include/linux/netfilter_ipv6/ip6t_REJECT.h linux-2.6.9-rc1/include/linux/netfilter_ipv6/ip6t_REJECT.h
6166 --- linux-2.6.9-rc1.orig/include/linux/netfilter_ipv6/ip6t_REJECT.h 1970-01-01 01:00:00.000000000 +0100
6167 +++ linux-2.6.9-rc1/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-08-29 11:44:11.277430632 +0200
6169 +#ifndef _IP6T_REJECT_H
6170 +#define _IP6T_REJECT_H
6172 +enum ip6t_reject_with {
6173 + IP6T_ICMP6_NO_ROUTE,
6174 + IP6T_ICMP6_ADM_PROHIBITED,
6175 + IP6T_ICMP6_NOT_NEIGHBOUR,
6176 + IP6T_ICMP6_ADDR_UNREACH,
6177 + IP6T_ICMP6_PORT_UNREACH,
6178 + IP6T_ICMP6_ECHOREPLY,
6182 +struct ip6t_reject_info {
6183 + enum ip6t_reject_with with; /* reject type */
6186 +#endif /*_IP6T_REJECT_H*/
6187 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
6188 --- linux-2.6.7.org/net/ipv6/netfilter/ip6t_REJECT.c 1970-01-01 01:00:00.000000000 +0100
6189 +++ linux-2.6.7/net/ipv6/netfilter/ip6t_REJECT.c 2004-06-29 12:32:02.720456960 +0200
6192 + * IP6 tables REJECT target module
6193 + * Linux INET6 implementation
6195 + * Copyright (C)2003 USAGI/WIDE Project
6198 + * Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
6200 + * Based on net/ipv4/netfilter/ipt_REJECT.c
6202 + * This program is free software; you can redistribute it and/or
6203 + * modify it under the terms of the GNU General Public License
6204 + * as published by the Free Software Foundation; either version
6205 + * 2 of the License, or (at your option) any later version.
6208 +#include <linux/config.h>
6209 +#include <linux/module.h>
6210 +#include <linux/skbuff.h>
6211 +#include <linux/icmpv6.h>
6212 +#include <net/ipv6.h>
6213 +#include <net/tcp.h>
6214 +#include <net/icmp.h>
6215 +#include <net/ip6_fib.h>
6216 +#include <net/ip6_route.h>
6217 +#include <net/flow.h>
6218 +#include <linux/netfilter_ipv6/ip6_tables.h>
6219 +#include <linux/netfilter_ipv6/ip6t_REJECT.h>
6221 +MODULE_AUTHOR("Yasuyuki KOZAKAI <yasuyuki.kozakai@toshiba.co.jp>");
6222 +MODULE_DESCRIPTION("IP6 tables REJECT target module");
6223 +MODULE_LICENSE("GPL");
6226 +#define DEBUGP printk
6228 +#define DEBUGP(format, args...)
6232 +static void connection_attach(struct sk_buff *new_skb, struct nf_ct_info *nfct)
6234 + void (*attach)(struct sk_buff *, struct nf_ct_info *);
6235 + if (nfct && (attach = ip6_ct_attach) != NULL) {
6237 + attach(new_skb, nfct);
6242 +static int maybe_reroute(struct sk_buff *skb)
6244 + if (skb->nfcache & NFC_ALTERED){
6245 + if (ip6_route_me_harder(skb) != 0){
6251 + return dst_output(skb);
6254 +/* Send RST reply */
6255 +static void send_reset(struct sk_buff *oldskb)
6257 + struct sk_buff *nskb;
6258 + struct tcphdr otcph, *tcph;
6259 + unsigned int otcplen, tcphoff, hh_len;
6261 + struct ipv6hdr *oip6h = oldskb->nh.ipv6h, *ip6h;
6262 + struct dst_entry *dst = NULL;
6265 + proto = oip6h->nexthdr;
6268 + if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) ||
6269 + (!(ipv6_addr_type(&oip6h->daddr) & IPV6_ADDR_UNICAST))) {
6270 + DEBUGP("ip6t_REJECT: addr is not unicast.\n");
6274 + tcphoff = ipv6_skip_exthdr(oldskb, ((u8*)(oip6h+1) - oldskb->data),
6275 + &proto, oldskb->len - ((u8*)(oip6h+1)
6278 + if ((tcphoff < 0) || (tcphoff > oldskb->len)) {
6279 + DEBUGP("ip6t_REJECT: Can't get TCP header.\n");
6283 + otcplen = oldskb->len - tcphoff;
6285 + /* IP header checks: fragment, too short. */
6286 + if ((proto != IPPROTO_TCP) || (otcplen < sizeof(struct tcphdr))) {
6287 + DEBUGP("ip6t_REJECT: proto(%d) != IPPROTO_TCP, or too short. otcplen = %d\n",
6292 + if (skb_copy_bits(oldskb, tcphoff, &otcph, sizeof(struct tcphdr))) {
6293 + if (net_ratelimit())
6294 + printk("ip6t_REJECT: Can't copy tcp header\n");
6298 + /* No RST for RST. */
6300 + DEBUGP("ip6t_REJECT: RST is set\n");
6304 + /* Check checksum. */
6305 + if (csum_ipv6_magic(&oip6h->saddr, &oip6h->daddr, otcplen, IPPROTO_TCP,
6306 + skb_checksum(oldskb, tcphoff, otcplen, 0))) {
6307 + DEBUGP("ip6t_REJECT: TCP checksum is invalid\n");
6311 + memset(&fl, 0, sizeof(fl));
6312 + fl.proto = IPPROTO_TCP;
6313 + ipv6_addr_copy(&fl.fl6_src, &oip6h->daddr);
6314 + ipv6_addr_copy(&fl.fl6_dst, &oip6h->saddr);
6315 + fl.fl_ip_sport = otcph.dest;
6316 + fl.fl_ip_dport = otcph.source;
6317 + err = ip6_dst_lookup(NULL, &dst, &fl);
6319 + if (net_ratelimit())
6320 + printk("ip6t_REJECT: can't find dst. err = %d\n", err);
6324 + hh_len = (dst->dev->hard_header_len + 15)&~15;
6325 + nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr)
6326 + + sizeof(struct tcphdr) + dst->trailer_len,
6330 + if (net_ratelimit())
6331 + printk("ip6t_REJECT: Can't alloc skb\n");
6339 + skb_reserve(nskb, hh_len + dst->header_len);
6341 + ip6h = nskb->nh.ipv6h = (struct ipv6hdr *)
6342 + skb_put(nskb, sizeof(struct ipv6hdr));
6343 + ip6h->version = 6;
6344 + ip6h->hop_limit = dst_metric(dst, RTAX_HOPLIMIT);
6345 + ip6h->nexthdr = IPPROTO_TCP;
6346 + ip6h->payload_len = htons(sizeof(struct tcphdr));
6347 + ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr);
6348 + ipv6_addr_copy(&ip6h->daddr, &oip6h->saddr);
6350 + tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
6351 + /* Truncate to length (no data) */
6352 + tcph->doff = sizeof(struct tcphdr)/4;
6353 + tcph->source = otcph.dest;
6354 + tcph->dest = otcph.source;
6358 + tcph->seq = otcph.ack_seq;
6359 + tcph->ack_seq = 0;
6362 + tcph->ack_seq = htonl(ntohl(otcph.seq) + otcph.syn + otcph.fin
6363 + + otcplen - (otcph.doff<<2));
6368 + ((u_int8_t *)tcph)[13] = 0;
6370 + tcph->ack = needs_ack;
6372 + tcph->urg_ptr = 0;
6375 + /* Adjust TCP checksum */
6376 + tcph->check = csum_ipv6_magic(&nskb->nh.ipv6h->saddr,
6377 + &nskb->nh.ipv6h->daddr,
6378 + sizeof(struct tcphdr), IPPROTO_TCP,
6379 + csum_partial((char *)tcph,
6380 + sizeof(struct tcphdr), 0));
6383 + connection_attach(nskb, oldskb->nfct);
6386 + NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
6392 +static void send_unreach(struct sk_buff *skb_in, unsigned char code)
6394 + struct ipv6hdr *ip6h, *hdr = skb_in->nh.ipv6h;
6395 + struct icmp6hdr *icmp6h;
6396 + struct dst_entry *dst = NULL;
6397 + struct rt6_info *rt;
6400 + unsigned int len, datalen, hh_len;
6401 + int saddr_type, daddr_type;
6402 + unsigned int ptr, ip6off;
6405 + struct sk_buff *nskb;
6408 + saddr_type = ipv6_addr_type(&hdr->saddr);
6409 + daddr_type = ipv6_addr_type(&hdr->daddr);
6411 + if ((!(saddr_type & IPV6_ADDR_UNICAST)) ||
6412 + (!(daddr_type & IPV6_ADDR_UNICAST))) {
6413 + DEBUGP("ip6t_REJECT: addr is not unicast.\n");
6417 + ip6off = skb_in->nh.raw - skb_in->data;
6418 + proto = hdr->nexthdr;
6419 + ptr = ipv6_skip_exthdr(skb_in, ip6off + sizeof(struct ipv6hdr), &proto,
6420 + skb_in->len - ip6off);
6422 + if ((ptr < 0) || (ptr > skb_in->len)) {
6423 + ptr = ip6off + sizeof(struct ipv6hdr);
6424 + proto = hdr->nexthdr;
6425 + } else if (proto == IPPROTO_ICMPV6) {
6428 + if (skb_copy_bits(skb_in, ptr + offsetof(struct icmp6hdr,
6429 + icmp6_type), &type, 1)) {
6430 + DEBUGP("ip6t_REJECT: Can't get ICMPv6 type\n");
6434 + if (!(type & ICMPV6_INFOMSG_MASK)) {
6435 + DEBUGP("ip6t_REJECT: no reply to icmp error\n");
6438 + } else if (proto == IPPROTO_UDP) {
6439 + int plen = skb_in->len - (ptr - ip6off);
6442 + if (plen < sizeof(struct udphdr)) {
6443 + DEBUGP("ip6t_REJECT: too short\n");
6447 + if (skb_copy_bits(skb_in, ptr + offsetof(struct udphdr, check),
6449 + if (net_ratelimit())
6450 + printk("ip6t_REJECT: can't get copy from skb");
6455 + csum_ipv6_magic(&hdr->saddr, &hdr->daddr, plen,
6457 + skb_checksum(skb_in, ptr, plen, 0))) {
6458 + DEBUGP("ip6t_REJECT: UDP checksum is invalid.\n");
6463 + memset(&fl, 0, sizeof(fl));
6464 + fl.proto = IPPROTO_ICMPV6;
6465 + ipv6_addr_copy(&fl.fl6_src, &hdr->daddr);
6466 + ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr);
6467 + fl.fl_icmp_type = ICMPV6_DEST_UNREACH;
6468 + fl.fl_icmp_code = code;
6470 + if (ip6_dst_lookup(NULL, &dst, &fl)) {
6474 + rt = (struct rt6_info *)dst;
6477 + if (rt->rt6i_dst.plen < 128)
6478 + tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
6480 + if (!xrlim_allow(dst, tmo)) {
6481 + if (net_ratelimit())
6482 + printk("ip6t_REJECT: rate limitted\n");
6483 + goto dst_release_out;
6486 + len = skb_in->len + sizeof(struct ipv6hdr) + sizeof(struct icmp6hdr);
6488 + if (len > dst_pmtu(dst))
6489 + len = dst_pmtu(dst);
6490 + if (len > IPV6_MIN_MTU)
6491 + len = IPV6_MIN_MTU;
6493 + datalen = len - sizeof(struct ipv6hdr) - sizeof(struct icmp6hdr);
6494 + hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
6496 + nskb = alloc_skb(hh_len + 15 + dst->header_len + dst->trailer_len + len,
6500 + if (net_ratelimit())
6501 + printk("ip6t_REJECT: can't alloc skb\n");
6502 + goto dst_release_out;
6505 + nskb->priority = 0;
6509 + skb_reserve(nskb, hh_len + dst->header_len);
6511 + ip6h = nskb->nh.ipv6h = (struct ipv6hdr *)
6512 + skb_put(nskb, sizeof(struct ipv6hdr));
6513 + ip6h->version = 6;
6514 + ip6h->hop_limit = dst_metric(dst, RTAX_HOPLIMIT);
6515 + ip6h->nexthdr = IPPROTO_ICMPV6;
6516 + ip6h->payload_len = htons(datalen + sizeof(struct icmp6hdr));
6517 + ipv6_addr_copy(&ip6h->saddr, &hdr->daddr);
6518 + ipv6_addr_copy(&ip6h->daddr, &hdr->saddr);
6520 + icmp6h = (struct icmp6hdr *) skb_put(nskb, sizeof(struct icmp6hdr));
6521 + icmp6h->icmp6_type = ICMPV6_DEST_UNREACH;
6522 + icmp6h->icmp6_code = code;
6523 + icmp6h->icmp6_cksum = 0;
6525 + data = skb_put(nskb, datalen);
6527 + csum = csum_partial((unsigned char *)icmp6h, sizeof(struct icmp6hdr), 0);
6528 + csum = skb_copy_and_csum_bits(skb_in, ip6off, data, datalen, csum);
6529 + icmp6h->icmp6_cksum = csum_ipv6_magic(&hdr->saddr, &hdr->daddr,
6530 + datalen + sizeof(struct icmp6hdr),
6531 + IPPROTO_ICMPV6, csum);
6534 + connection_attach(nskb, skb_in->nfct);
6536 + NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
6543 +static unsigned int reject6_target(struct sk_buff **pskb,
6544 + unsigned int hooknum,
6545 + const struct net_device *in,
6546 + const struct net_device *out,
6547 + const void *targinfo,
6550 + const struct ip6t_reject_info *reject = targinfo;
6552 + DEBUGP(KERN_DEBUG "%s: medium point\n", __FUNCTION__);
6553 + /* WARNING: This code causes reentry within ip6tables.
6554 + This means that the ip6tables jump stack is now crap. We
6555 + must return an absolute verdict. --RR */
6556 + switch (reject->with) {
6557 + case IP6T_ICMP6_NO_ROUTE:
6558 + send_unreach(*pskb, ICMPV6_NOROUTE);
6560 + case IP6T_ICMP6_ADM_PROHIBITED:
6561 + send_unreach(*pskb, ICMPV6_ADM_PROHIBITED);
6563 + case IP6T_ICMP6_NOT_NEIGHBOUR:
6564 + send_unreach(*pskb, ICMPV6_NOT_NEIGHBOUR);
6566 + case IP6T_ICMP6_ADDR_UNREACH:
6567 + send_unreach(*pskb, ICMPV6_ADDR_UNREACH);
6569 + case IP6T_ICMP6_PORT_UNREACH:
6570 + send_unreach(*pskb, ICMPV6_PORT_UNREACH);
6572 + case IP6T_ICMP6_ECHOREPLY:
6575 + case IP6T_TCP_RESET:
6576 + send_reset(*pskb);
6579 + if (net_ratelimit())
6580 + printk(KERN_WARNING "ip6t_REJECT: case %u not handled yet\n", reject->with);
6587 +static int check(const char *tablename,
6588 + const struct ip6t_entry *e,
6590 + unsigned int targinfosize,
6591 + unsigned int hook_mask)
6593 + const struct ip6t_reject_info *rejinfo = targinfo;
6595 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
6596 + DEBUGP("ip6t_REJECT: targinfosize %u != 0\n", targinfosize);
6600 + /* Only allow these for packet filtering. */
6601 + if (strcmp(tablename, "filter") != 0) {
6602 + DEBUGP("ip6t_REJECT: bad table `%s'.\n", tablename);
6606 + if ((hook_mask & ~((1 << NF_IP6_LOCAL_IN)
6607 + | (1 << NF_IP6_FORWARD)
6608 + | (1 << NF_IP6_LOCAL_OUT))) != 0) {
6609 + DEBUGP("ip6t_REJECT: bad hook mask %X\n", hook_mask);
6613 + if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
6614 + printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
6616 + } else if (rejinfo->with == IP6T_TCP_RESET) {
6617 + /* Must specify that it's a TCP packet */
6618 + if (e->ipv6.proto != IPPROTO_TCP
6619 + || (e->ipv6.invflags & IP6T_INV_PROTO)) {
6620 + DEBUGP("ip6t_REJECT: TCP_RESET illegal for non-tcp\n");
6628 +static struct ip6t_target ip6t_reject_reg = {
6630 + .target = reject6_target,
6631 + .checkentry = check,
6635 +static int __init init(void)
6637 + if (ip6t_register_target(&ip6t_reject_reg))
6642 +static void __exit fini(void)
6644 + ip6t_unregister_target(&ip6t_reject_reg);
6649 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
6650 --- linux-2.6.7.org/net/ipv6/netfilter/ip6t_ROUTE.c 1970-01-01 01:00:00.000000000 +0100
6651 +++ linux-2.6.7/net/ipv6/netfilter/ip6t_ROUTE.c 2004-06-29 12:34:33.513532928 +0200
6654 + * This implements the ROUTE v6 target, which enables you to setup unusual
6655 + * routes not supported by the standard kernel routing table.
6657 + * Copyright (C) 2003 Cedric de Launois <delaunois@info.ucl.ac.be>
6659 + * v 1.0 2003/08/05
6661 + * This software is distributed under GNU GPL v2, 1991
6664 +#include <linux/module.h>
6665 +#include <linux/skbuff.h>
6666 +#include <linux/ipv6.h>
6667 +#include <linux/netfilter_ipv6/ip6_tables.h>
6668 +#include <linux/netfilter_ipv6/ip6t_ROUTE.h>
6669 +#include <linux/netdevice.h>
6670 +#include <net/ipv6.h>
6671 +#include <net/ndisc.h>
6672 +#include <net/ip6_route.h>
6673 +#include <linux/icmpv6.h>
6676 +#define DEBUGP printk
6678 +#define DEBUGP(format, args...)
6681 +#define NIP6(addr) \
6682 + ntohs((addr).s6_addr16[0]), \
6683 + ntohs((addr).s6_addr16[1]), \
6684 + ntohs((addr).s6_addr16[2]), \
6685 + ntohs((addr).s6_addr16[3]), \
6686 + ntohs((addr).s6_addr16[4]), \
6687 + ntohs((addr).s6_addr16[5]), \
6688 + ntohs((addr).s6_addr16[6]), \
6689 + ntohs((addr).s6_addr16[7])
6691 +/* Route the packet according to the routing keys specified in
6692 + * route_info. Keys are :
6694 + * 0 if no oif preferred,
6695 + * otherwise set to the index of the desired oif
6696 + * - route_info->gw :
6697 + * 0 if no gateway specified,
6698 + * otherwise set to the next host to which the pkt must be routed
6699 + * If success, skb->dev is the output device to which the packet must
6700 + * be sent and skb->dst is not NULL
6702 + * RETURN: 1 if the packet was succesfully routed to the
6703 + * destination desired
6704 + * 0 if the kernel routing table could not route the packet
6705 + * according to the keys specified
6708 +route6(struct sk_buff *skb,
6709 + unsigned int ifindex,
6710 + const struct ip6t_route_target_info *route_info)
6712 + struct rt6_info *rt = NULL;
6713 + struct ipv6hdr *ipv6h = skb->nh.ipv6h;
6714 + struct in6_addr *gw = (struct in6_addr*)&route_info->gw;
6716 + DEBUGP("ip6t_ROUTE: called with: ");
6717 + DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(ipv6h->daddr));
6718 + DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(*gw));
6719 + DEBUGP("OUT=%s\n", route_info->oif);
6721 + if (ipv6_addr_any(gw))
6722 + rt = rt6_lookup(&ipv6h->daddr, &ipv6h->saddr, ifindex, 1);
6724 + rt = rt6_lookup(gw, &ipv6h->saddr, ifindex, 1);
6729 + DEBUGP("ip6t_ROUTE: routing gives: ");
6730 + DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_dst.addr));
6731 + DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_gateway));
6732 + DEBUGP("OUT=%s\n", rt->rt6i_dev->name);
6734 + if (ifindex && rt->rt6i_dev->ifindex!=ifindex)
6737 + if (!rt->rt6i_nexthop) {
6738 + DEBUGP("ip6t_ROUTE: discovering neighbour\n");
6739 + rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_dst.addr);
6742 + /* Drop old route. */
6743 + dst_release(skb->dst);
6744 + skb->dst = &rt->u.dst;
6745 + skb->dev = rt->rt6i_dev;
6749 + dst_release(&rt->u.dst);
6751 + if (!net_ratelimit())
6754 + printk("ip6t_ROUTE: no explicit route found ");
6756 + printk("via interface %s ", route_info->oif);
6757 + if (!ipv6_addr_any(gw))
6758 + printk("via gateway %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", NIP6(*gw));
6764 +/* Stolen from ip6_output_finish
6765 + * PRE : skb->dev is set to the device we are leaving by
6766 + * skb->dst is not NULL
6767 + * POST: the packet is sent with the link layer header pushed
6768 + * the packet is destroyed
6770 +static void ip_direct_send(struct sk_buff *skb)
6772 + struct dst_entry *dst = skb->dst;
6773 + struct hh_cache *hh = dst->hh;
6776 + read_lock_bh(&hh->hh_lock);
6777 + memcpy(skb->data - 16, hh->hh_data, 16);
6778 + read_unlock_bh(&hh->hh_lock);
6779 + skb_push(skb, hh->hh_len);
6780 + hh->hh_output(skb);
6781 + } else if (dst->neighbour)
6782 + dst->neighbour->output(skb);
6784 + if (net_ratelimit())
6785 + DEBUGP(KERN_DEBUG "ip6t_ROUTE: no hdr & no neighbour cache!\n");
6791 +static unsigned int
6792 +route6_oif(const struct ip6t_route_target_info *route_info,
6793 + struct sk_buff *skb)
6795 + unsigned int ifindex = 0;
6796 + struct net_device *dev_out = NULL;
6798 + /* The user set the interface name to use.
6799 + * Getting the current interface index.
6801 + if ((dev_out = dev_get_by_name(route_info->oif))) {
6802 + ifindex = dev_out->ifindex;
6804 + /* Unknown interface name : packet dropped */
6805 + if (net_ratelimit())
6806 + DEBUGP("ip6t_ROUTE: oif interface %s not found\n", route_info->oif);
6808 + if (route_info->flags & IP6T_ROUTE_CONTINUE)
6809 + return IP6T_CONTINUE;
6814 + /* Trying the standard way of routing packets */
6815 + if (route6(skb, ifindex, route_info)) {
6817 + if (route_info->flags & IP6T_ROUTE_CONTINUE)
6818 + return IP6T_CONTINUE;
6820 + ip_direct_send(skb);
6827 +static unsigned int
6828 +route6_gw(const struct ip6t_route_target_info *route_info,
6829 + struct sk_buff *skb)
6831 + if (route6(skb, 0, route_info)) {
6832 + if (route_info->flags & IP6T_ROUTE_CONTINUE)
6833 + return IP6T_CONTINUE;
6835 + ip_direct_send(skb);
6842 +static unsigned int
6843 +ip6t_route_target(struct sk_buff **pskb,
6844 + unsigned int hooknum,
6845 + const struct net_device *in,
6846 + const struct net_device *out,
6847 + const void *targinfo,
6850 + const struct ip6t_route_target_info *route_info = targinfo;
6851 + struct sk_buff *skb = *pskb;
6852 + struct in6_addr *gw = (struct in6_addr*)&route_info->gw;
6854 + if (route_info->flags & IP6T_ROUTE_CONTINUE)
6857 + /* If we are at PREROUTING or INPUT hook
6858 + * the TTL isn't decreased by the IP stack
6860 + if (hooknum == NF_IP6_PRE_ROUTING ||
6861 + hooknum == NF_IP6_LOCAL_IN) {
6863 + struct ipv6hdr *ipv6h = skb->nh.ipv6h;
6865 + if (ipv6h->hop_limit <= 1) {
6866 + /* Force OUTPUT device used as source address */
6867 + skb->dev = skb->dst->dev;
6869 + icmpv6_send(skb, ICMPV6_TIME_EXCEED,
6870 + ICMPV6_EXC_HOPLIMIT, 0, skb->dev);
6875 + ipv6h->hop_limit--;
6880 + if (route_info->oif[0])
6881 + return route6_oif(route_info, *pskb);
6883 + if (!ipv6_addr_any(gw))
6884 + return route6_gw(route_info, *pskb);
6886 + if (net_ratelimit())
6887 + DEBUGP(KERN_DEBUG "ip6t_ROUTE: no parameter !\n");
6889 + return IP6T_CONTINUE;
6894 +ip6t_route_checkentry(const char *tablename,
6895 + const struct ip6t_entry *e,
6897 + unsigned int targinfosize,
6898 + unsigned int hook_mask)
6900 + if (strcmp(tablename, "mangle") != 0) {
6901 + printk("ip6t_ROUTE: can only be called from \"mangle\" table.\n");
6905 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_route_target_info))) {
6906 + printk(KERN_WARNING "ip6t_ROUTE: targinfosize %u != %Zu\n",
6908 + IP6T_ALIGN(sizeof(struct ip6t_route_target_info)));
6916 +static struct ip6t_target ip6t_route_reg = {
6918 + .target = ip6t_route_target,
6919 + .checkentry = ip6t_route_checkentry,
6924 +static int __init init(void)
6926 + printk(KERN_DEBUG "registering ipv6 ROUTE target\n");
6927 + if (ip6t_register_target(&ip6t_route_reg))
6934 +static void __exit fini(void)
6936 + ip6t_unregister_target(&ip6t_route_reg);
6941 +MODULE_LICENSE("GPL");
6942 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
6943 --- linux-2.6.7.org/net/ipv6/netfilter/ip6t_fuzzy.c 1970-01-01 01:00:00.000000000 +0100
6944 +++ linux-2.6.7/net/ipv6/netfilter/ip6t_fuzzy.c 2004-06-29 12:32:08.824529000 +0200
6947 + * This module implements a simple TSK FLC
6948 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
6949 + * to limit , in an adaptive and flexible way , the packet rate crossing
6950 + * a given stream . It serves as an initial and very simple (but effective)
6951 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
6952 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
6953 + * into our code in a precise , adaptive and efficient manner.
6954 + * The goal is very similar to that of "limit" match , but using techniques of
6955 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
6956 + * avoiding over and undershoots - and stuff like that .
6959 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
6960 + * 2002-08-17 : Changed to eliminate floating point operations .
6961 + * 2002-08-23 : Coding style changes .
6962 + * 2003-04-08 Maciej Soltysiak <solt@dns.toxicilms.tv> : IPv6 Port
6965 +#include <linux/module.h>
6966 +#include <linux/skbuff.h>
6967 +#include <linux/ipv6.h>
6968 +#include <linux/random.h>
6969 +#include <net/tcp.h>
6970 +#include <linux/spinlock.h>
6971 +#include <linux/netfilter_ipv6/ip6_tables.h>
6972 +#include <linux/netfilter_ipv6/ip6t_fuzzy.h>
6975 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
6976 + Expressed in percentage
6979 +#define PAR_LOW 1/100
6982 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED;
6984 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
6985 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
6986 +MODULE_LICENSE("GPL");
6988 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
6990 + if (tx >= maxi) return 100;
6992 + if (tx <= mini) return 0;
6994 + return ((100 * (tx-mini)) / (maxi-mini));
6997 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
6999 + if (tx <= mini) return 100;
7001 + if (tx >= maxi) return 0;
7003 + return ((100 * (maxi - tx)) / (maxi - mini));
7008 +ip6t_fuzzy_match(const struct sk_buff *pskb,
7009 + const struct net_device *in,
7010 + const struct net_device *out,
7011 + const void *matchinfo,
7014 + u_int16_t datalen,
7017 + /* From userspace */
7019 + struct ip6t_fuzzy_info *info = (struct ip6t_fuzzy_info *) matchinfo;
7021 + u_int8_t random_number;
7022 + unsigned long amount;
7023 + u_int8_t howhigh, howlow;
7026 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
7028 + info->bytes_total += pskb->len;
7029 + info->packets_total++;
7031 + info->present_time = jiffies;
7033 + if (info->present_time >= info->previous_time)
7034 + amount = info->present_time - info->previous_time;
7036 + /* There was a transition : I choose to re-sample
7037 + and keep the old acceptance rate...
7041 + info->previous_time = info->present_time;
7042 + info->bytes_total = info->packets_total = 0;
7045 + if ( amount > HZ/10) {/* More than 100 ms elapsed ... */
7047 + info->mean_rate = (u_int32_t) ((HZ * info->packets_total) \
7050 + info->previous_time = info->present_time;
7051 + info->bytes_total = info->packets_total = 0;
7053 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
7054 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
7056 + info->acceptance_rate = (u_int8_t) \
7057 + (howhigh * PAR_LOW + PAR_HIGH * howlow);
7059 + /* In fact, the above defuzzification would require a denominator
7060 + * proportional to (howhigh+howlow) but, in this particular case,
7061 + * that expression is constant.
7062 + * An imediate consequence is that it is not necessary to call
7063 + * both mf_high and mf_low - but to keep things understandable,
7069 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
7072 + if (info->acceptance_rate < 100)
7074 + get_random_bytes((void *)(&random_number), 1);
7076 + /* If within the acceptance , it can pass => don't match */
7077 + if (random_number <= (255 * info->acceptance_rate) / 100)
7080 + return 1; /* It can't pass (It matches) */
7083 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
7088 +ip6t_fuzzy_checkentry(const char *tablename,
7089 + const struct ip6t_ip6 *ip,
7091 + unsigned int matchsize,
7092 + unsigned int hook_mask)
7095 + const struct ip6t_fuzzy_info *info = matchinfo;
7097 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info))) {
7098 + printk("ip6t_fuzzy: matchsize %u != %u\n", matchsize,
7099 + IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info)));
7103 + if ((info->minimum_rate < MINFUZZYRATE) || (info->maximum_rate > MAXFUZZYRATE)
7104 + || (info->minimum_rate >= info->maximum_rate)) {
7105 + printk("ip6t_fuzzy: BAD limits , please verify !!!\n");
7112 +static struct ip6t_match ip6t_fuzzy_reg = {
7116 + ip6t_fuzzy_checkentry,
7120 +static int __init init(void)
7122 + if (ip6t_register_match(&ip6t_fuzzy_reg))
7128 +static void __exit fini(void)
7130 + ip6t_unregister_match(&ip6t_fuzzy_reg);
7135 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
7136 --- linux-2.6.7.org/net/ipv6/netfilter/ip6t_nth.c 1970-01-01 01:00:00.000000000 +0100
7137 +++ linux-2.6.7/net/ipv6/netfilter/ip6t_nth.c 2004-06-29 12:32:16.703331240 +0200
7140 + This is a module which is used for match support for every Nth packet
7141 + This file is distributed under the terms of the GNU General Public
7142 + License (GPL). Copies of the GPL can be obtained from:
7143 + ftp://prep.ai.mit.edu/pub/gnu/GPL
7145 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
7146 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
7147 + * added support for multiple counters
7148 + * added support for matching on individual packets
7149 + in the counter cycle
7150 + 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
7154 +#include <linux/module.h>
7155 +#include <linux/skbuff.h>
7156 +#include <linux/ip.h>
7157 +#include <net/tcp.h>
7158 +#include <linux/spinlock.h>
7159 +#include <linux/netfilter_ipv6/ip6_tables.h>
7160 +#include <linux/netfilter_ipv6/ip6t_nth.h>
7162 +MODULE_LICENSE("GPL");
7165 + * State information.
7172 +static struct state states[IP6T_NTH_NUM_COUNTERS];
7175 +ip6t_nth_match(const struct sk_buff *pskb,
7176 + const struct net_device *in,
7177 + const struct net_device *out,
7178 + const void *matchinfo,
7181 + u_int16_t datalen,
7184 + /* Parameters from userspace */
7185 + const struct ip6t_nth_info *info = matchinfo;
7186 + unsigned counter = info->counter;
7187 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
7189 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
7193 + spin_lock(&states[counter].lock);
7195 + /* Are we matching every nth packet?*/
7196 + if (info->packet == 0xFF)
7198 + /* We're matching every nth packet and only every nth packet*/
7199 + /* Do we match or invert match? */
7200 + if (info->not == 0)
7202 + if (states[counter].number == 0)
7204 + ++states[counter].number;
7207 + if (states[counter].number >= info->every)
7208 + states[counter].number = 0; /* reset the counter */
7210 + ++states[counter].number;
7215 + if (states[counter].number == 0)
7217 + ++states[counter].number;
7220 + if (states[counter].number >= info->every)
7221 + states[counter].number = 0;
7223 + ++states[counter].number;
7229 + /* We're using the --packet, so there must be a rule for every value */
7230 + if (states[counter].number == info->packet)
7232 + /* only increment the counter when a match happens */
7233 + if (states[counter].number >= info->every)
7234 + states[counter].number = 0; /* reset the counter */
7236 + ++states[counter].number;
7245 + spin_unlock(&states[counter].lock);
7249 + spin_unlock(&states[counter].lock);
7254 +ip6t_nth_checkentry(const char *tablename,
7255 + const struct ip6t_ip6 *e,
7257 + unsigned int matchsize,
7258 + unsigned int hook_mask)
7260 + /* Parameters from userspace */
7261 + const struct ip6t_nth_info *info = matchinfo;
7262 + unsigned counter = info->counter;
7263 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
7265 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
7269 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_nth_info))) {
7270 + printk("nth: matchsize %u != %u\n", matchsize,
7271 + IP6T_ALIGN(sizeof(struct ip6t_nth_info)));
7275 + states[counter].number = info->startat;
7280 +static struct ip6t_match ip6t_nth_reg = {
7284 + ip6t_nth_checkentry,
7288 +static int __init init(void)
7291 + memset(&states, 0, sizeof(states));
7292 + if (ip6t_register_match(&ip6t_nth_reg))
7295 + for(counter = 0; counter < IP6T_NTH_NUM_COUNTERS; counter++)
7297 + spin_lock_init(&(states[counter].lock));
7300 + printk("ip6t_nth match loaded\n");
7304 +static void __exit fini(void)
7306 + ip6t_unregister_match(&ip6t_nth_reg);
7307 + printk("ip6t_nth match unloaded\n");
7312 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
7313 --- linux-2.6.7.org/net/ipv6/netfilter/ip6t_owner.c 2004-06-29 12:24:14.000000000 +0200
7314 +++ linux-2.6.7/net/ipv6/netfilter/ip6t_owner.c 2004-06-29 12:35:37.772764040 +0200
7316 MODULE_LICENSE("GPL");
7319 +match_comm(const struct sk_buff *skb, const char *comm)
7321 + struct task_struct *p, *g;
7322 + struct files_struct *files;
7325 + read_lock(&tasklist_lock);
7326 + do_each_thread(g, p) {
7327 + if(strncmp(p->comm, comm, sizeof(p->comm)))
7333 + read_lock(&files->file_lock);
7334 + for (i=0; i < files->max_fds; i++) {
7335 + if (fcheck_files(files, i) ==
7336 + skb->sk->sk_socket->file) {
7337 + read_unlock(&files->file_lock);
7339 + read_unlock(&tasklist_lock);
7343 + read_unlock(&files->file_lock);
7346 + } while_each_thread(g, p);
7347 + read_unlock(&tasklist_lock);
7352 match_pid(const struct sk_buff *skb, pid_t pid)
7354 struct task_struct *p;
7355 @@ -125,6 +158,12 @@
7359 + if(info->match & IP6T_OWNER_COMM) {
7360 + if (!match_comm(skb, info->comm) ^
7361 + !!(info->invert & IP6T_OWNER_COMM))
7368 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
7369 --- linux-2.6.7.org/net/ipv6/netfilter/ip6t_policy.c 1970-01-01 01:00:00.000000000 +0100
7370 +++ linux-2.6.7/net/ipv6/netfilter/ip6t_policy.c 2004-06-29 12:35:40.050417784 +0200
7372 +/* IP tables module for matching IPsec policy
7374 + * Copyright (c) 2004 Patrick McHardy, <kaber@trash.net>
7376 + * This program is free software; you can redistribute it and/or modify
7377 + * it under the terms of the GNU General Public License version 2 as
7378 + * published by the Free Software Foundation.
7381 +#include <linux/kernel.h>
7382 +#include <linux/config.h>
7383 +#include <linux/module.h>
7384 +#include <linux/skbuff.h>
7385 +#include <linux/init.h>
7386 +#include <net/xfrm.h>
7388 +#include <linux/netfilter_ipv6.h>
7389 +#include <linux/netfilter_ipv6/ip6t_policy.h>
7390 +#include <linux/netfilter_ipv6/ip6_tables.h>
7392 +MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
7393 +MODULE_DESCRIPTION("IPtables IPsec policy matching module");
7394 +MODULE_LICENSE("GPL");
7397 +static inline int ip6_masked_addrcmp(struct in6_addr addr1,
7398 + struct in6_addr mask,
7399 + struct in6_addr addr2)
7403 + for (i = 0; i < 16; i++) {
7404 + if ((addr1.s6_addr[i] & mask.s6_addr[i]) !=
7405 + (addr2.s6_addr[i] & mask.s6_addr[i]))
7413 +match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e)
7415 +#define MISMATCH(x,y) (e->match.x && ((e->x != (y)) ^ e->invert.x))
7417 + struct in6_addr xfrm_saddr, xfrm_daddr;
7419 + if ((e->match.saddr
7420 + && (ip6_masked_addrcmp(xfrm_saddr, e->saddr, e->smask))
7421 + ^ e->invert.saddr ) ||
7423 + && (ip6_masked_addrcmp(xfrm_daddr, e->daddr, e->dmask))
7424 + ^ e->invert.daddr ) ||
7425 + MISMATCH(proto, x->id.proto) ||
7426 + MISMATCH(mode, x->props.mode) ||
7427 + MISMATCH(spi, x->id.spi) ||
7428 + MISMATCH(reqid, x->props.reqid))
7434 +match_policy_in(const struct sk_buff *skb, const struct ip6t_policy_info *info)
7436 + const struct ip6t_policy_elem *e;
7437 + struct sec_path *sp = skb->sp;
7438 + int strict = info->flags & POLICY_MATCH_STRICT;
7443 + if (strict && info->len != sp->len)
7446 + for (i = sp->len - 1; i >= 0; i--) {
7447 + pos = strict ? i - sp->len + 1 : 0;
7448 + if (pos >= info->len)
7450 + e = &info->pol[pos];
7452 + if (match_xfrm_state(sp->x[i].xvec, e)) {
7455 + } else if (strict)
7459 + return strict ? 1 : 0;
7463 +match_policy_out(const struct sk_buff *skb, const struct ip6t_policy_info *info)
7465 + const struct ip6t_policy_elem *e;
7466 + struct dst_entry *dst = skb->dst;
7467 + int strict = info->flags & POLICY_MATCH_STRICT;
7470 + if (dst->xfrm == NULL)
7473 + for (i = 0; dst && dst->xfrm; dst = dst->child, i++) {
7474 + pos = strict ? i : 0;
7475 + if (pos >= info->len)
7477 + e = &info->pol[pos];
7479 + if (match_xfrm_state(dst->xfrm, e)) {
7482 + } else if (strict)
7486 + return strict ? 1 : 0;
7489 +static int match(const struct sk_buff *skb,
7490 + const struct net_device *in,
7491 + const struct net_device *out,
7492 + const void *matchinfo,
7495 + u_int16_t datalen,
7498 + const struct ip6t_policy_info *info = matchinfo;
7501 + if (info->flags & POLICY_MATCH_IN)
7502 + ret = match_policy_in(skb, info);
7504 + ret = match_policy_out(skb, info);
7507 + if (info->flags & POLICY_MATCH_NONE)
7511 + } else if (info->flags & POLICY_MATCH_NONE)
7517 +static int checkentry(const char *tablename, const struct ip6t_ip6 *ip,
7518 + void *matchinfo, unsigned int matchsize,
7519 + unsigned int hook_mask)
7521 + struct ip6t_policy_info *info = matchinfo;
7523 + if (matchsize != IP6T_ALIGN(sizeof(*info))) {
7524 + printk(KERN_ERR "ip6t_policy: matchsize %u != %u\n",
7525 + matchsize, IP6T_ALIGN(sizeof(*info)));
7528 + if (!(info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT))) {
7529 + printk(KERN_ERR "ip6t_policy: neither incoming nor "
7530 + "outgoing policy selected\n");
7533 + if (hook_mask & (1 << NF_IP6_PRE_ROUTING | 1 << NF_IP6_LOCAL_IN)
7534 + && info->flags & POLICY_MATCH_OUT) {
7535 + printk(KERN_ERR "ip6t_policy: output policy not valid in "
7536 + "PRE_ROUTING and INPUT\n");
7539 + if (hook_mask & (1 << NF_IP6_POST_ROUTING | 1 << NF_IP6_LOCAL_OUT)
7540 + && info->flags & POLICY_MATCH_IN) {
7541 + printk(KERN_ERR "ip6t_policy: input policy not valid in "
7542 + "POST_ROUTING and OUTPUT\n");
7545 + if (info->len > POLICY_MAX_ELEM) {
7546 + printk(KERN_ERR "ip6t_policy: too many policy elements\n");
7553 +static struct ip6t_match policy_match =
7557 + .checkentry = checkentry,
7558 + .me = THIS_MODULE,
7561 +static int __init init(void)
7563 + return ip6t_register_match(&policy_match);
7566 +static void __exit fini(void)
7568 + ip6t_unregister_match(&policy_match);