1 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter.h linux-2.6.5-rc2/include/linux/netfilter.h
2 --- linux-2.6.5-rc2.org/include/linux/netfilter.h 2004-03-20 00:11:18.000000000 +0000
3 +++ linux-2.6.5-rc2/include/linux/netfilter.h 2004-03-22 08:27:15.000000000 +0000
6 extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
8 +typedef void nf_logfn(unsigned int hooknum,
9 + const struct sk_buff *skb,
10 + const struct net_device *in,
11 + const struct net_device *out,
12 + const char *prefix);
14 +/* Function to register/unregister log function. */
15 +int nf_log_register(int pf, nf_logfn *logfn);
16 +void nf_log_unregister(int pf, nf_logfn *logfn);
18 +/* Calls the registered backend logging function */
19 +void nf_log_packet(int pf,
20 + unsigned int hooknum,
21 + const struct sk_buff *skb,
22 + const struct net_device *in,
23 + const struct net_device *out,
24 + const char *fmt, ...);
26 /* Activate hook; either okfn or kfree_skb called, unless a hook
27 returns NF_STOLEN (in which case, it's up to the hook to deal with
29 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ip_conntrack.h
30 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-20 00:11:50.000000000 +0000
31 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-22 08:29:50.000000000 +0000
33 /* Call me when a conntrack is destroyed. */
34 extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack);
36 +/* Fake conntrack entry for untracked connections */
37 +extern struct ip_conntrack ip_conntrack_untracked;
39 /* Returns new sk_buff, or NULL */
41 ip_ct_gather_frags(struct sk_buff *skb);
42 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ip_pool.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ip_pool.h
43 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ip_pool.h 1970-01-01 00:00:00.000000000 +0000
44 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ip_pool.h 2004-03-22 08:29:18.000000000 +0000
49 +/***************************************************************************/
50 +/* This program is free software; you can redistribute it and/or modify */
51 +/* it under the terms of the GNU General Public License as published by */
52 +/* the Free Software Foundation; either version 2 of the License, or */
53 +/* (at your option) any later version. */
55 +/* This program is distributed in the hope that it will be useful, */
56 +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
57 +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
58 +/* GNU General Public License for more details. */
60 +/* You should have received a copy of the GNU General Public License */
61 +/* along with this program; if not, write to the Free Software */
62 +/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/
63 +/***************************************************************************/
65 +/* A sockopt of such quality has hardly ever been seen before on the open
66 + * market! This little beauty, hardly ever used: above 64, so it's
67 + * traditionally used for firewalling, not touched (even once!) by the
68 + * 2.0, 2.2 and 2.4 kernels!
70 + * Comes with its own certificate of authenticity, valid anywhere in the
75 +#define SO_IP_POOL 81
77 +typedef int ip_pool_t; /* pool index */
78 +#define IP_POOL_NONE ((ip_pool_t)-1)
80 +struct ip_pool_request {
87 +/* NOTE: I deliberately break the first cut ippool utility. Nobody uses it. */
89 +#define IP_POOL_BAD001 0x00000010
91 +#define IP_POOL_FLUSH 0x00000011 /* req.index, no arguments */
92 +#define IP_POOL_INIT 0x00000012 /* from addr to addr2 incl. */
93 +#define IP_POOL_DESTROY 0x00000013 /* req.index, no arguments */
94 +#define IP_POOL_ADD_ADDR 0x00000014 /* add addr to pool */
95 +#define IP_POOL_DEL_ADDR 0x00000015 /* del addr from pool */
96 +#define IP_POOL_HIGH_NR 0x00000016 /* result in req.index */
97 +#define IP_POOL_LOOKUP 0x00000017 /* result in addr and addr2 */
98 +#define IP_POOL_USAGE 0x00000018 /* result in addr */
99 +#define IP_POOL_TEST_ADDR 0x00000019 /* result (0/1) returned */
103 +/* NOTE: ip_pool_match() and ip_pool_mod() expect ADDR to be host byte order */
104 +extern int ip_pool_match(ip_pool_t pool, u_int32_t addr);
105 +extern int ip_pool_mod(ip_pool_t pool, u_int32_t addr, int isdel);
109 +#endif /*_IP_POOL_H*/
110 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_TTL.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_TTL.h
111 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_TTL.h 1970-01-01 00:00:00.000000000 +0000
112 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_TTL.h 2004-03-22 08:28:11.000000000 +0000
114 +/* TTL modification module for IP tables
115 + * (C) 2000 by Harald Welte <laforge@gnumonks.org> */
126 +#define IPT_TTL_MAXMODE IPT_TTL_DEC
128 +struct ipt_TTL_info {
135 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_ULOG.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_ULOG.h
136 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_ULOG.h 2004-03-20 00:11:05.000000000 +0000
137 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_ULOG.h 2004-03-22 08:27:15.000000000 +0000
139 #define NETLINK_NFLOG 5
142 +#define ULOG_DEFAULT_NLGROUP 1
143 +#define ULOG_DEFAULT_QTHRESHOLD 1
145 #define ULOG_MAC_LEN 80
146 #define ULOG_PREFIX_LEN 32
148 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_connlimit.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_connlimit.h
149 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_connlimit.h 1970-01-01 00:00:00.000000000 +0000
150 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_connlimit.h 2004-03-22 08:28:18.000000000 +0000
152 +#ifndef _IPT_CONNLIMIT_H
153 +#define _IPT_CONNLIMIT_H
155 +struct ipt_connlimit_data;
157 +struct ipt_connlimit_info {
161 + struct ipt_connlimit_data *data;
163 +#endif /* _IPT_CONNLIMIT_H */
164 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_conntrack.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_conntrack.h
165 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_conntrack.h 2004-03-20 00:11:34.000000000 +0000
166 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_conntrack.h 2004-03-22 08:29:50.000000000 +0000
169 #define IPT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1))
170 #define IPT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2))
171 +#define IPT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3))
173 /* flags, invflags: */
174 #define IPT_CONNTRACK_STATE 0x01
175 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_dstlimit.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_dstlimit.h
176 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_dstlimit.h 1970-01-01 00:00:00.000000000 +0000
177 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_dstlimit.h 2004-03-22 08:28:26.000000000 +0000
179 +#ifndef _IPT_DSTLIMIT_H
180 +#define _IPT_DSTLIMIT_H
182 +/* timings are in milliseconds. */
183 +#define IPT_DSTLIMIT_SCALE 10000
184 +/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490
185 + seconds, or one every 59 hours. */
187 +/* details of this structure hidden by the implementation */
188 +struct ipt_dstlimit_htable;
190 +#define IPT_DSTLIMIT_HASH_DIP 0x0001
191 +#define IPT_DSTLIMIT_HASH_DPT 0x0002
192 +#define IPT_DSTLIMIT_HASH_SIP 0x0004
194 +struct dstlimit_cfg {
195 + u_int32_t mode; /* bitmask of IPT_DSTLIMIT_HASH_* */
196 + u_int32_t avg; /* Average secs between packets * scale */
197 + u_int32_t burst; /* Period multiplier for upper limit. */
199 + /* user specified */
200 + u_int32_t size; /* how many buckets */
201 + u_int32_t max; /* max number of entries */
202 + u_int32_t gc_interval; /* gc interval */
203 + u_int32_t expire; /* when do entries expire? */
206 +struct ipt_dstlimit_info {
207 + char name [IFNAMSIZ]; /* name */
208 + struct dstlimit_cfg cfg;
209 + struct ipt_dstlimit_htable *hinfo;
211 + /* Used internally by the kernel */
214 + struct ipt_dstlimit_info *master;
217 +#endif /*_IPT_DSTLIMIT_H*/
218 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_fuzzy.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_fuzzy.h
219 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_fuzzy.h 1970-01-01 00:00:00.000000000 +0000
220 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_fuzzy.h 2004-03-22 08:28:32.000000000 +0000
222 +#ifndef _IPT_FUZZY_H
223 +#define _IPT_FUZZY_H
225 +#include <linux/param.h>
226 +#include <linux/types.h>
228 +#define MAXFUZZYRATE 10000000
229 +#define MINFUZZYRATE 3
231 +struct ipt_fuzzy_info {
232 + u_int32_t minimum_rate;
233 + u_int32_t maximum_rate;
234 + u_int32_t packets_total;
235 + u_int32_t bytes_total;
236 + u_int32_t previous_time;
237 + u_int32_t present_time;
238 + u_int32_t mean_rate;
239 + u_int8_t acceptance_rate;
242 +#endif /*_IPT_FUZZY_H*/
243 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_ipv4options.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_ipv4options.h
244 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_ipv4options.h 1970-01-01 00:00:00.000000000 +0000
245 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_ipv4options.h 2004-03-22 08:28:47.000000000 +0000
247 +#ifndef __ipt_ipv4options_h_included__
248 +#define __ipt_ipv4options_h_included__
250 +#define IPT_IPV4OPTION_MATCH_SSRR 0x01 /* For strict source routing */
251 +#define IPT_IPV4OPTION_MATCH_LSRR 0x02 /* For loose source routing */
252 +#define IPT_IPV4OPTION_DONT_MATCH_SRR 0x04 /* any source routing */
253 +#define IPT_IPV4OPTION_MATCH_RR 0x08 /* For Record route */
254 +#define IPT_IPV4OPTION_DONT_MATCH_RR 0x10
255 +#define IPT_IPV4OPTION_MATCH_TIMESTAMP 0x20 /* For timestamp request */
256 +#define IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP 0x40
257 +#define IPT_IPV4OPTION_MATCH_ROUTER_ALERT 0x80 /* For router-alert */
258 +#define IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT 0x100
259 +#define IPT_IPV4OPTION_MATCH_ANY_OPT 0x200 /* match packet with any option */
260 +#define IPT_IPV4OPTION_DONT_MATCH_ANY_OPT 0x400 /* match packet with no option */
262 +struct ipt_ipv4options_info {
267 +#endif /* __ipt_ipv4options_h_included__ */
268 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_mport.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_mport.h
269 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_mport.h 1970-01-01 00:00:00.000000000 +0000
270 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_mport.h 2004-03-22 08:28:51.000000000 +0000
272 +#ifndef _IPT_MPORT_H
273 +#define _IPT_MPORT_H
274 +#include <linux/netfilter_ipv4/ip_tables.h>
276 +#define IPT_MPORT_SOURCE (1<<0)
277 +#define IPT_MPORT_DESTINATION (1<<1)
278 +#define IPT_MPORT_EITHER (IPT_MPORT_SOURCE|IPT_MPORT_DESTINATION)
280 +#define IPT_MULTI_PORTS 15
282 +/* Must fit inside union ipt_matchinfo: 32 bytes */
283 +/* every entry in ports[] except for the last one has one bit in pflags
284 + * associated with it. If this bit is set, the port is the first port of
285 + * a portrange, with the next entry being the last.
286 + * End of list is marked with pflags bit set and port=65535.
287 + * If 14 ports are used (last one does not have a pflag), the last port
288 + * is repeated to fill the last entry in ports[] */
291 + u_int8_t flags:2; /* Type of comparison */
292 + u_int16_t pflags:14; /* Port flags */
293 + u_int16_t ports[IPT_MULTI_PORTS]; /* Ports */
295 +#endif /*_IPT_MPORT_H*/
296 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_nth.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_nth.h
297 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_nth.h 1970-01-01 00:00:00.000000000 +0000
298 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_nth.h 2004-03-22 08:29:02.000000000 +0000
303 +#include <linux/param.h>
304 +#include <linux/types.h>
306 +#ifndef IPT_NTH_NUM_COUNTERS
307 +#define IPT_NTH_NUM_COUNTERS 16
310 +struct ipt_nth_info {
318 +#endif /*_IPT_NTH_H*/
319 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_osf.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_osf.h
320 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_osf.h 1970-01-01 00:00:00.000000000 +0000
321 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_osf.h 2004-03-22 08:29:11.000000000 +0000
326 + * Copyright (c) 2003 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
329 + * This program is free software; you can redistribute it and/or modify
330 + * it under the terms of the GNU General Public License as published by
331 + * the Free Software Foundation; either version 2 of the License, or
332 + * (at your option) any later version.
334 + * This program is distributed in the hope that it will be useful,
335 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
336 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
337 + * GNU General Public License for more details.
339 + * You should have received a copy of the GNU General Public License
340 + * along with this program; if not, write to the Free Software
341 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
347 +#define MAXGENRELEN 32
348 +#define MAXDETLEN 64
350 +#define IPT_OSF_GENRE 1
351 +#define IPT_OSF_SMART 2
352 +#define IPT_OSF_LOG 4
353 +#define IPT_OSF_NETLINK 8
355 +#define IPT_OSF_LOGLEVEL_ALL 0
356 +#define IPT_OSF_LOGLEVEL_FIRST 1
358 +#include <linux/list.h>
361 +#include <netinet/ip.h>
362 +#include <netinet/tcp.h>
366 + struct list_head *prev, *next;
372 + char genre[MAXGENRELEN];
374 + unsigned long flags;
376 + int invert; /* UNSUPPORTED */
385 +/* This struct represents IANA options
386 + * http://www.iana.org/assignments/tcp-parameters
390 + unsigned char kind;
391 + unsigned char length;
397 + struct list_head flist;
402 + unsigned char genre[MAXGENRELEN];
403 + unsigned char version[MAXGENRELEN], subtype[MAXGENRELEN];
405 + /* Not needed, but for consistency with original table from Michal Zalewski */
406 + unsigned char details[MAXDETLEN];
409 + struct osf_opt opt[MAX_IPOPTLEN]; /* In case it is all NOP or EOL */
413 +struct ipt_osf_nlmsg
415 + struct osf_finger f;
422 +/* Defines for IANA option kinds */
424 +#define OSFOPT_EOL 0 /* End of options */
425 +#define OSFOPT_NOP 1 /* NOP */
426 +#define OSFOPT_MSS 2 /* Maximum segment size */
427 +#define OSFOPT_WSO 3 /* Window scale option */
428 +#define OSFOPT_SACKP 4 /* SACK permitted */
429 +#define OSFOPT_SACK 5 /* SACK */
430 +#define OSFOPT_ECHO 6
431 +#define OSFOPT_ECHOREPLY 7
432 +#define OSFOPT_TS 8 /* Timestamp option */
433 +#define OSFOPT_POCP 9 /* Partial Order Connection Permitted */
434 +#define OSFOPT_POSP 10 /* Partial Order Service Profile */
435 +/* Others are not used in current OSF */
437 +static struct osf_opt IANA_opts[] =
444 + {5, 1 ,}, /* SACK length is not defined */
450 + {11, 1,}, /* CC: Suppose 1 */
451 + {12, 1,}, /* the same */
452 + {13, 1,}, /* and here too */
454 + {15, 1,}, /* TCP Alternate Checksum Data. Length is not defined */
468 +#endif /* __KERNEL__ */
470 +#endif /* _IPT_OSF_H */
471 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_pool.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_pool.h
472 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_pool.h 1970-01-01 00:00:00.000000000 +0000
473 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_pool.h 2004-03-22 08:29:18.000000000 +0000
478 +#include <linux/netfilter_ipv4/ip_pool.h>
480 +#define IPT_POOL_INV_SRC 0x00000001
481 +#define IPT_POOL_INV_DST 0x00000002
482 +#define IPT_POOL_DEL_SRC 0x00000004
483 +#define IPT_POOL_DEL_DST 0x00000008
484 +#define IPT_POOL_INV_MOD_SRC 0x00000010
485 +#define IPT_POOL_INV_MOD_DST 0x00000020
486 +#define IPT_POOL_MOD_SRC_ACCEPT 0x00000040
487 +#define IPT_POOL_MOD_DST_ACCEPT 0x00000080
488 +#define IPT_POOL_MOD_SRC_DROP 0x00000100
489 +#define IPT_POOL_MOD_DST_DROP 0x00000200
492 +struct ipt_pool_info
499 +#endif /*_IPT_POOL_H*/
500 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_psd.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_psd.h
501 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_psd.h 1970-01-01 00:00:00.000000000 +0000
502 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_psd.h 2004-03-22 08:29:30.000000000 +0000
507 +#include <linux/param.h>
508 +#include <linux/types.h>
511 + * High port numbers have a lower weight to reduce the frequency of false
512 + * positives, such as from passive mode FTP transfers.
514 +#define PORT_WEIGHT_PRIV 3
515 +#define PORT_WEIGHT_HIGH 1
518 + * Port scan detection thresholds: at least COUNT ports need to be scanned
519 + * from the same source, with no longer than DELAY ticks between ports.
521 +#define SCAN_MIN_COUNT 7
522 +#define SCAN_MAX_COUNT (SCAN_MIN_COUNT * PORT_WEIGHT_PRIV)
523 +#define SCAN_WEIGHT_THRESHOLD SCAN_MAX_COUNT
524 +#define SCAN_DELAY_THRESHOLD (HZ * 3)
527 + * Keep track of up to LIST_SIZE source addresses, using a hash table of
528 + * HASH_SIZE entries for faster lookups, but limiting hash collisions to
529 + * HASH_MAX source addresses per the same hash value.
531 +#define LIST_SIZE 0x100
533 +#define HASH_SIZE (1 << HASH_LOG)
534 +#define HASH_MAX 0x10
536 +struct ipt_psd_info {
537 + unsigned int weight_threshold;
538 + unsigned int delay_threshold;
539 + unsigned short lo_ports_weight;
540 + unsigned short hi_ports_weight;
543 +#endif /*_IPT_PSD_H*/
544 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_quota.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_quota.h
545 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_quota.h 1970-01-01 00:00:00.000000000 +0000
546 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_quota.h 2004-03-22 08:29:35.000000000 +0000
548 +#ifndef _IPT_QUOTA_H
549 +#define _IPT_QUOTA_H
551 +/* print debug info in both kernel/netfilter module & iptable library */
552 +//#define DEBUG_IPT_QUOTA
554 +struct ipt_quota_info {
558 +#endif /*_IPT_QUOTA_H*/
559 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_random.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_random.h
560 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_random.h 1970-01-01 00:00:00.000000000 +0000
561 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_random.h 2004-03-22 08:29:43.000000000 +0000
566 +#include <linux/param.h>
567 +#include <linux/types.h>
569 +struct ipt_rand_info {
573 +#endif /*_IPT_RAND_H*/
574 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_realm.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_realm.h
575 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_realm.h 1970-01-01 00:00:00.000000000 +0000
576 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_realm.h 2004-03-22 08:29:57.000000000 +0000
578 +#ifndef _IPT_REALM_H
579 +#define _IPT_REALM_H
581 +struct ipt_realm_info {
586 +#endif /*_IPT_REALM_H*/
587 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_sctp.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_sctp.h
588 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_sctp.h 1970-01-01 00:00:00.000000000 +0000
589 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_sctp.h 2004-03-22 08:30:03.000000000 +0000
591 +#ifndef _IPT_SCTP_H_
592 +#define _IPT_SCTP_H_
594 +#define IPT_SCTP_SRC_PORTS 0x01
595 +#define IPT_SCTP_DEST_PORTS 0x02
596 +#define IPT_SCTP_CHUNK_TYPES 0x04
598 +#define IPT_SCTP_VALID_FLAGS 0x07
600 +#define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0]))
603 +struct ipt_sctp_flag_info {
604 + u_int8_t chunktype;
606 + u_int8_t flag_mask;
609 +#define IPT_NUM_SCTP_FLAGS 4
611 +struct ipt_sctp_info {
612 + u_int16_t dpts[2]; /* Min, Max */
613 + u_int16_t spts[2]; /* Min, Max */
615 + u_int32_t chunkmap[256 / sizeof (u_int32_t)]; /* Bit mask of chunks to be matched according to RFC 2960 */
617 +#define SCTP_CHUNK_MATCH_ANY 0x01 /* Match if any of the chunk types are present */
618 +#define SCTP_CHUNK_MATCH_ALL 0x02 /* Match if all of the chunk types are present */
619 +#define SCTP_CHUNK_MATCH_ONLY 0x04 /* Match if these are the only chunk types present */
621 + u_int32_t chunk_match_type;
622 + struct ipt_sctp_flag_info flag_info[IPT_NUM_SCTP_FLAGS];
626 + u_int32_t invflags;
629 +#define bytes(type) (sizeof(type) * 8)
631 +#define SCTP_CHUNKMAP_SET(chunkmap, type) \
633 + chunkmap[type / bytes(u_int32_t)] |= \
634 + 1 << (type % bytes(u_int32_t)); \
637 +#define SCTP_CHUNKMAP_CLEAR(chunkmap, type) \
639 + chunkmap[type / bytes(u_int32_t)] &= \
640 + ~(1 << (type % bytes(u_int32_t))); \
643 +#define SCTP_CHUNKMAP_IS_SET(chunkmap, type) \
645 + (chunkmap[type / bytes (u_int32_t)] & \
646 + (1 << (type % bytes (u_int32_t)))) ? 1: 0; \
649 +#define SCTP_CHUNKMAP_RESET(chunkmap) \
652 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
656 +#define SCTP_CHUNKMAP_SET_ALL(chunkmap) \
659 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
660 + chunkmap[i] = ~0; \
663 +#define SCTP_CHUNKMAP_COPY(destmap, srcmap) \
666 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
667 + destmap[i] = srcmap[i]; \
670 +#define SCTP_CHUNKMAP_IS_CLEAR(chunkmap) \
674 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \
675 + if (chunkmap[i]) { \
683 +#define SCTP_CHUNKMAP_IS_ALL_SET(chunkmap) \
687 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \
688 + if (chunkmap[i] != ~0) { \
696 +#endif /* _IPT_SCTP_H_ */
698 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_state.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_state.h
699 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_state.h 2004-03-20 00:11:41.000000000 +0000
700 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_state.h 2004-03-22 08:29:50.000000000 +0000
702 #define IPT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
703 #define IPT_STATE_INVALID (1 << 0)
705 +#define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1))
707 struct ipt_state_info
709 unsigned int statemask;
710 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_time.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_time.h
711 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_time.h 1970-01-01 00:00:00.000000000 +0000
712 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_time.h 2004-03-22 08:30:10.000000000 +0000
714 +#ifndef __ipt_time_h_included__
715 +#define __ipt_time_h_included__
718 +struct ipt_time_info {
719 + u_int8_t days_match; /* 1 bit per day. -SMTWTFS */
720 + u_int16_t time_start; /* 0 < time_start < 23*60+59 = 1439 */
721 + u_int16_t time_stop; /* 0:0 < time_stat < 23:59 */
722 + u_int8_t kerneltime; /* ignore skb time (and use kerneltime) or not. */
726 +#endif /* __ipt_time_h_included__ */
727 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_u32.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_u32.h
728 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_u32.h 1970-01-01 00:00:00.000000000 +0000
729 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_u32.h 2004-03-22 08:30:19.000000000 +0000
733 +#include <linux/netfilter_ipv4/ip_tables.h>
743 +struct ipt_u32_location_element
748 +struct ipt_u32_value_element
753 +/* *** any way to allow for an arbitrary number of elements?
754 + for now I settle for a limit of 10 of each */
755 +#define U32MAXSIZE 10
759 + struct ipt_u32_location_element location[U32MAXSIZE+1];
761 + struct ipt_u32_value_element value[U32MAXSIZE+1];
767 + struct ipt_u32_test tests[U32MAXSIZE+1];
770 +#endif /*_IPT_U32_H*/
771 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4.h linux-2.6.5-rc2/include/linux/netfilter_ipv4.h
772 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4.h 2004-03-20 00:11:41.000000000 +0000
773 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4.h 2004-03-22 08:29:50.000000000 +0000
776 enum nf_ip_hook_priorities {
777 NF_IP_PRI_FIRST = INT_MIN,
778 + NF_IP_PRI_CONNTRACK_DEFRAG = -400,
779 + NF_IP_PRI_RAW = -300,
780 NF_IP_PRI_SELINUX_FIRST = -225,
781 NF_IP_PRI_CONNTRACK = -200,
782 NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
783 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_HL.h linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_HL.h
784 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_HL.h 1970-01-01 00:00:00.000000000 +0000
785 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_HL.h 2004-03-22 08:27:23.000000000 +0000
787 +/* Hop Limit modification module for ip6tables
788 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
789 + * Based on HW's TTL module */
800 +#define IP6T_HL_MAXMODE IP6T_HL_DEC
802 +struct ip6t_HL_info {
804 + u_int8_t hop_limit;
809 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_REJECT.h linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_REJECT.h
810 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-03-20 00:11:00.000000000 +0000
811 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-03-22 08:28:02.000000000 +0000
813 #define _IP6T_REJECT_H
815 enum ip6t_reject_with {
816 - IP6T_ICMP_NET_UNREACHABLE,
817 - IP6T_ICMP_HOST_UNREACHABLE,
818 - IP6T_ICMP_PROT_UNREACHABLE,
819 - IP6T_ICMP_PORT_UNREACHABLE,
820 - IP6T_ICMP_ECHOREPLY
821 + IP6T_ICMP6_NO_ROUTE,
822 + IP6T_ICMP6_ADM_PROHIBITED,
823 + IP6T_ICMP6_NOT_NEIGHBOUR,
824 + IP6T_ICMP6_ADDR_UNREACH,
825 + IP6T_ICMP6_PORT_UNREACH,
826 + IP6T_ICMP6_ECHOREPLY,
830 struct ip6t_reject_info {
831 enum ip6t_reject_with with; /* reject type */
834 -#endif /*_IPT_REJECT_H*/
835 +#endif /*_IP6T_REJECT_H*/
836 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_fuzzy.h
837 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h 1970-01-01 00:00:00.000000000 +0000
838 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_fuzzy.h 2004-03-22 08:28:32.000000000 +0000
840 +#ifndef _IP6T_FUZZY_H
841 +#define _IP6T_FUZZY_H
843 +#include <linux/param.h>
844 +#include <linux/types.h>
846 +#define MAXFUZZYRATE 10000000
847 +#define MINFUZZYRATE 3
849 +struct ip6t_fuzzy_info {
850 + u_int32_t minimum_rate;
851 + u_int32_t maximum_rate;
852 + u_int32_t packets_total;
853 + u_int32_t bytes_total;
854 + u_int32_t previous_time;
855 + u_int32_t present_time;
856 + u_int32_t mean_rate;
857 + u_int8_t acceptance_rate;
860 +#endif /*_IP6T_FUZZY_H*/
861 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_nth.h linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_nth.h
862 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_nth.h 1970-01-01 00:00:00.000000000 +0000
863 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_nth.h 2004-03-22 08:29:02.000000000 +0000
868 +#include <linux/param.h>
869 +#include <linux/types.h>
871 +#ifndef IP6T_NTH_NUM_COUNTERS
872 +#define IP6T_NTH_NUM_COUNTERS 16
875 +struct ip6t_nth_info {
883 +#endif /*_IP6T_NTH_H*/
884 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_random.h linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_random.h
885 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_random.h 1970-01-01 00:00:00.000000000 +0000
886 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_random.h 2004-03-22 08:29:43.000000000 +0000
888 +#ifndef _IP6T_RAND_H
889 +#define _IP6T_RAND_H
891 +#include <linux/param.h>
892 +#include <linux/types.h>
894 +struct ip6t_rand_info {
898 +#endif /*_IP6T_RAND_H*/
899 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/core/netfilter.c linux-2.6.5-rc2/net/core/netfilter.c
900 --- linux-2.6.5-rc2.org/net/core/netfilter.c 2004-03-20 00:11:08.000000000 +0000
901 +++ linux-2.6.5-rc2/net/core/netfilter.c 2004-03-22 08:27:15.000000000 +0000
904 * February 2000: Modified by James Morris to have 1 queue per protocol.
905 * 15-Mar-2000: Added NF_REPEAT --RR.
906 + * 08-May-2003: Internal logging interface added by Jozsef Kadlecsik.
908 #include <linux/config.h>
909 +#include <linux/kernel.h>
910 #include <linux/netfilter.h>
911 #include <net/protocol.h>
912 #include <linux/init.h>
914 EXPORT_SYMBOL(skb_ip_make_writable);
915 #endif /*CONFIG_INET*/
917 +/* Internal logging interface, which relies on the real
918 + LOG target modules */
920 +#define NF_LOG_PREFIXLEN 128
922 +static nf_logfn *nf_logging[NPROTO]; /* = NULL */
923 +static int reported = 0;
924 +static spinlock_t nf_log_lock = SPIN_LOCK_UNLOCKED;
926 +int nf_log_register(int pf, nf_logfn *logfn)
930 + /* Any setup of logging members must be done before
931 + * substituting pointer. */
933 + spin_lock(&nf_log_lock);
934 + if (!nf_logging[pf]) {
935 + nf_logging[pf] = logfn;
938 + spin_unlock(&nf_log_lock);
942 +void nf_log_unregister(int pf, nf_logfn *logfn)
944 + spin_lock(&nf_log_lock);
945 + if (nf_logging[pf] == logfn)
946 + nf_logging[pf] = NULL;
947 + spin_unlock(&nf_log_lock);
949 + /* Give time to concurrent readers. */
953 +void nf_log_packet(int pf,
954 + unsigned int hooknum,
955 + const struct sk_buff *skb,
956 + const struct net_device *in,
957 + const struct net_device *out,
958 + const char *fmt, ...)
961 + char prefix[NF_LOG_PREFIXLEN];
965 + logfn = nf_logging[pf];
967 + va_start(args, fmt);
968 + vsnprintf(prefix, sizeof(prefix), fmt, args);
970 + /* We must read logging before nf_logfn[pf] */
971 + smp_read_barrier_depends();
972 + logfn(hooknum, skb, in, out, prefix);
973 + } else if (!reported) {
974 + printk(KERN_WARNING "nf_log_packet: can\'t log yet, "
975 + "no backend logging module loaded in!\n");
980 +EXPORT_SYMBOL(nf_log_register);
981 +EXPORT_SYMBOL(nf_log_unregister);
982 +EXPORT_SYMBOL(nf_log_packet);
984 /* This does not belong here, but ipt_REJECT needs it if connection
985 tracking in use: without this, connection may not be in hash table,
986 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/Kconfig linux-2.6.5-rc2/net/ipv4/netfilter/Kconfig
987 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/Kconfig 2004-03-20 00:11:41.000000000 +0000
988 +++ linux-2.6.5-rc2/net/ipv4/netfilter/Kconfig 2004-03-22 08:30:19.000000000 +0000
989 @@ -579,5 +579,118 @@
991 To compile it as a module, choose M here. If unsure, say N.
993 +config IP_NF_TARGET_IPV4OPTSSTRIP
994 + tristate 'IPV4OPTSSTRIP target support'
995 + depends on IP_NF_MANGLE
998 +config IP_NF_TARGET_TTL
999 + tristate 'TTL target support'
1000 + depends on IP_NF_MANGLE
1003 +config IP_NF_MATCH_CONNLIMIT
1004 + tristate 'Connections/IP limit match support'
1005 + depends on IP_NF_IPTABLES
1008 +config IP_NF_MATCH_DSTLIMIT
1009 + tristate 'dstlimit match support'
1010 + depends on IP_NF_IPTABLES
1013 +config IP_NF_MATCH_FUZZY
1014 + tristate 'fuzzy match support'
1015 + depends on IP_NF_IPTABLES
1018 +config IP_NF_MATCH_IPV4OPTIONS
1019 + tristate 'IPV4OPTIONS match support'
1020 + depends on IP_NF_IPTABLES
1023 +config IP_NF_MATCH_MPORT
1024 + tristate 'Multiple port with ranges match support'
1025 + depends on IP_NF_IPTABLES
1028 +config IP_NF_MATCH_NTH
1029 + tristate 'Nth match support'
1030 + depends on IP_NF_IPTABLES
1033 +config IP_NF_MATCH_OSF
1034 + tristate 'OSF match support'
1035 + depends on IP_NF_IPTABLES
1038 +config IP_POOL_STATISTICS
1039 + bool 'enable statistics on pool usage'
1040 + depends on IP_NF_POOL!=n
1043 + tristate 'IP address pool support'
1044 + depends on IP_NF_IPTABLES
1047 +config IP_NF_MATCH_PSD
1048 + tristate 'psd match support'
1049 + depends on IP_NF_IPTABLES
1052 +config IP_NF_MATCH_QUOTA
1053 + tristate 'quota match support'
1054 + depends on IP_NF_IPTABLES
1057 +config IP_NF_MATCH_RANDOM
1058 + tristate 'random match support'
1059 + depends on IP_NF_IPTABLES
1062 +config IP_NF_TARGET_NOTRACK
1063 + tristate 'NOTRACK target support'
1064 + depends on IP_NF_RAW
1066 + The NOTRACK target allows a select rule to specify
1067 + which packets *not* to enter the conntrack/NAT
1068 + subsystem with all the consequences (no ICMP error tracking,
1069 + no protocol helpers for the selected packets).
1071 + If you want to compile it as a module, say M here and read
1072 + <file:Documentation/modules.txt>. If unsure, say `N'.
1075 + tristate 'raw table support (required for NOTRACK/TRACE)'
1076 + depends on IP_NF_IPTABLES
1078 + This option adds a `raw' table to iptables. This table is the very
1079 + first in the netfilter framework and hooks in at the PREROUTING
1080 + and OUTPUT chains.
1082 + If you want to compile it as a module, say M here and read
1083 + <file:Documentation/modules.txt>. If unsure, say `N'.
1086 +config IP_NF_MATCH_REALM
1087 + tristate 'realm match support'
1088 + depends on IP_NF_IPTABLES && NET_CLS_ROUTE
1091 +config IP_NF_MATCH_SCTP
1092 + tristate 'SCTP protocol match support'
1093 + depends on IP_NF_IPTABLES
1096 +config IP_NF_MATCH_TIME
1097 + tristate 'TIME match support'
1098 + depends on IP_NF_IPTABLES
1101 +config IP_NF_MATCH_U32
1102 + tristate 'U32 match support'
1103 + depends on IP_NF_IPTABLES
1108 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/Makefile linux-2.6.5-rc2/net/ipv4/netfilter/Makefile
1109 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/Makefile 2004-03-20 00:11:03.000000000 +0000
1110 +++ linux-2.6.5-rc2/net/ipv4/netfilter/Makefile 2004-03-22 08:30:19.000000000 +0000
1112 obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
1113 obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
1114 obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
1115 +obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
1118 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
1119 obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
1120 +obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o
1121 +obj-$(CONFIG_IP_NF_MATCH_QUOTA) += ipt_quota.o
1122 +obj-$(CONFIG_IP_NF_MATCH_DSTLIMIT) += ipt_dstlimit.o
1123 obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
1124 +obj-$(CONFIG_IP_NF_POOL) += ipt_pool.o ipt_POOL.o ip_pool.o
1125 obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
1126 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
1128 obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
1129 obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
1131 +obj-$(CONFIG_IP_NF_MATCH_MPORT) += ipt_mport.o
1133 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
1134 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
1136 +obj-$(CONFIG_IP_NF_MATCH_TIME) += ipt_time.o
1139 +obj-$(CONFIG_IP_NF_MATCH_RANDOM) += ipt_random.o
1141 +obj-$(CONFIG_IP_NF_MATCH_PSD) += ipt_psd.o
1143 +obj-$(CONFIG_IP_NF_MATCH_OSF) += ipt_osf.o
1146 +obj-$(CONFIG_IP_NF_MATCH_NTH) += ipt_nth.o
1148 +obj-$(CONFIG_IP_NF_MATCH_IPV4OPTIONS) += ipt_ipv4options.o
1151 +obj-$(CONFIG_IP_NF_MATCH_FUZZY) += ipt_fuzzy.o
1153 obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
1155 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
1158 obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o
1160 +obj-$(CONFIG_IP_NF_MATCH_U32) += ipt_u32.o
1163 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
1164 obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
1165 +obj-$(CONFIG_IP_NF_MATCH_CONNLIMIT) += ipt_connlimit.o
1166 obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
1167 obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
1168 +obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
1170 obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
1173 obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
1174 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
1175 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
1176 +obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
1177 +obj-$(CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP) += ipt_IPV4OPTSSTRIP.o
1178 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
1179 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
1180 +obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o
1182 # generic ARP tables
1183 obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
1184 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_conntrack_core.c linux-2.6.5-rc2/net/ipv4/netfilter/ip_conntrack_core.c
1185 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_conntrack_core.c 2004-03-20 00:11:00.000000000 +0000
1186 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ip_conntrack_core.c 2004-03-22 08:29:50.000000000 +0000
1188 static atomic_t ip_conntrack_count = ATOMIC_INIT(0);
1189 struct list_head *ip_conntrack_hash;
1190 static kmem_cache_t *ip_conntrack_cachep;
1191 +struct ip_conntrack ip_conntrack_untracked;
1193 extern struct ip_conntrack_protocol ip_conntrack_generic_protocol;
1195 @@ -691,42 +692,50 @@
1196 struct ip_conntrack_expect *, tuple);
1197 READ_UNLOCK(&ip_conntrack_expect_tuple_lock);
1199 - /* If master is not in hash table yet (ie. packet hasn't left
1200 - this machine yet), how can other end know about expected?
1201 - Hence these are not the droids you are looking for (if
1202 - master ct never got confirmed, we'd hold a reference to it
1203 - and weird things would happen to future packets). */
1204 - if (expected && !is_confirmed(expected->expectant))
1207 - /* Look up the conntrack helper for master connections only */
1209 - conntrack->helper = ip_ct_find_helper(&repl_tuple);
1211 - /* If the expectation is dying, then this is a loser. */
1213 - && expected->expectant->helper->timeout
1214 - && ! del_timer(&expected->timeout))
1218 - DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
1219 - conntrack, expected);
1220 - /* Welcome, Mr. Bond. We've been expecting you... */
1221 - IP_NF_ASSERT(master_ct(conntrack));
1222 - __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
1223 - conntrack->master = expected;
1224 - expected->sibling = conntrack;
1225 - LIST_DELETE(&ip_conntrack_expect_list, expected);
1226 - expected->expectant->expecting--;
1227 - nf_conntrack_get(&master_ct(conntrack)->infos[0]);
1229 - atomic_inc(&ip_conntrack_count);
1230 + /* If master is not in hash table yet (ie. packet hasn't left
1231 + this machine yet), how can other end know about expected?
1232 + Hence these are not the droids you are looking for (if
1233 + master ct never got confirmed, we'd hold a reference to it
1234 + and weird things would happen to future packets). */
1235 + if (!is_confirmed(expected->expectant)) {
1237 + conntrack->helper = ip_ct_find_helper(&repl_tuple);
1241 + /* Expectation is dying... */
1242 + if (expected->expectant->helper->timeout
1243 + && ! del_timer(&expected->timeout)) {
1247 + DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
1248 + conntrack, expected);
1249 + /* Welcome, Mr. Bond. We've been expecting you... */
1250 + IP_NF_ASSERT(master_ct(conntrack));
1251 + __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
1252 + conntrack->master = expected;
1253 + expected->sibling = conntrack;
1254 + LIST_DELETE(&ip_conntrack_expect_list, expected);
1255 + expected->expectant->expecting--;
1256 + nf_conntrack_get(&master_ct(conntrack)->infos[0]);
1258 + /* this is a braindead... --pablo */
1259 + atomic_inc(&ip_conntrack_count);
1260 + WRITE_UNLOCK(&ip_conntrack_lock);
1262 + if (expected->expectfn)
1263 + expected->expectfn(conntrack);
1267 + conntrack->helper = ip_ct_find_helper(&repl_tuple);
1269 +end: atomic_inc(&ip_conntrack_count);
1270 WRITE_UNLOCK(&ip_conntrack_lock);
1272 - if (expected && expected->expectfn)
1273 - expected->expectfn(conntrack);
1274 - return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
1275 +ret: return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
1278 /* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
1279 @@ -794,6 +803,15 @@
1283 + /* Never happen */
1284 + if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) {
1285 + if (net_ratelimit()) {
1286 + printk(KERN_ERR "ip_conntrack_in: Frag of proto %u (hook=%u)\n",
1287 + (*pskb)->nh.iph->protocol, hooknum);
1292 /* FIXME: Do this right please. --RR */
1293 (*pskb)->nfcache |= NFC_UNKNOWN;
1295 @@ -812,18 +830,10 @@
1299 - /* Previously seen (loopback)? Ignore. Do this before
1300 - fragment check. */
1301 + /* Previously seen (loopback or untracked)? Ignore. */
1305 - /* Gather fragments. */
1306 - if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
1307 - *pskb = ip_ct_gather_frags(*pskb);
1312 proto = ip_ct_find_proto((*pskb)->nh.iph->protocol);
1314 /* It may be an icmp error... */
1315 @@ -1422,6 +1432,18 @@
1317 /* For use by ipt_REJECT */
1318 ip_ct_attach = ip_conntrack_attach;
1320 + /* Set up fake conntrack:
1321 + - to never be deleted, not in any hashes */
1322 + atomic_set(&ip_conntrack_untracked.ct_general.use, 1);
1323 + /* - and look it like as a confirmed connection */
1324 + set_bit(IPS_CONFIRMED_BIT, &ip_conntrack_untracked.status);
1325 + /* - and prepare the ctinfo field for REJECT & NAT. */
1326 + ip_conntrack_untracked.infos[IP_CT_NEW].master =
1327 + ip_conntrack_untracked.infos[IP_CT_RELATED].master =
1328 + ip_conntrack_untracked.infos[IP_CT_RELATED + IP_CT_IS_REPLY].master =
1329 + &ip_conntrack_untracked.ct_general;
1334 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.5-rc2/net/ipv4/netfilter/ip_conntrack_standalone.c
1335 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-20 00:11:06.000000000 +0000
1336 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-22 08:29:50.000000000 +0000
1337 @@ -194,6 +194,26 @@
1338 return ip_conntrack_confirm(*pskb);
1341 +static unsigned int ip_conntrack_defrag(unsigned int hooknum,
1342 + struct sk_buff **pskb,
1343 + const struct net_device *in,
1344 + const struct net_device *out,
1345 + int (*okfn)(struct sk_buff *))
1347 + /* Previously seen (loopback)? Ignore. Do this before
1348 + fragment check. */
1349 + if ((*pskb)->nfct)
1352 + /* Gather fragments. */
1353 + if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
1354 + *pskb = ip_ct_gather_frags(*pskb);
1361 static unsigned int ip_refrag(unsigned int hooknum,
1362 struct sk_buff **pskb,
1363 const struct net_device *in,
1364 @@ -236,6 +256,14 @@
1366 /* Connection tracking may drop packets, but never alters them, so
1367 make it the first hook. */
1368 +static struct nf_hook_ops ip_conntrack_defrag_ops = {
1369 + .hook = ip_conntrack_defrag,
1370 + .owner = THIS_MODULE,
1372 + .hooknum = NF_IP_PRE_ROUTING,
1373 + .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
1376 static struct nf_hook_ops ip_conntrack_in_ops = {
1377 .hook = ip_conntrack_in,
1378 .owner = THIS_MODULE,
1379 @@ -244,6 +272,14 @@
1380 .priority = NF_IP_PRI_CONNTRACK,
1383 +static struct nf_hook_ops ip_conntrack_defrag_local_out_ops = {
1384 + .hook = ip_conntrack_defrag,
1385 + .owner = THIS_MODULE,
1387 + .hooknum = NF_IP_LOCAL_OUT,
1388 + .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
1391 static struct nf_hook_ops ip_conntrack_local_out_ops = {
1392 .hook = ip_conntrack_local,
1393 .owner = THIS_MODULE,
1394 @@ -470,10 +506,20 @@
1395 if (!proc) goto cleanup_init;
1396 proc->owner = THIS_MODULE;
1398 + ret = nf_register_hook(&ip_conntrack_defrag_ops);
1400 + printk("ip_conntrack: can't register pre-routing defrag hook.\n");
1401 + goto cleanup_proc;
1403 + ret = nf_register_hook(&ip_conntrack_defrag_local_out_ops);
1405 + printk("ip_conntrack: can't register local_out defrag hook.\n");
1406 + goto cleanup_defragops;
1408 ret = nf_register_hook(&ip_conntrack_in_ops);
1410 printk("ip_conntrack: can't register pre-routing hook.\n");
1411 - goto cleanup_proc;
1412 + goto cleanup_defraglocalops;
1414 ret = nf_register_hook(&ip_conntrack_local_out_ops);
1416 @@ -511,6 +557,10 @@
1417 nf_unregister_hook(&ip_conntrack_local_out_ops);
1419 nf_unregister_hook(&ip_conntrack_in_ops);
1420 + cleanup_defraglocalops:
1421 + nf_unregister_hook(&ip_conntrack_defrag_local_out_ops);
1422 + cleanup_defragops:
1423 + nf_unregister_hook(&ip_conntrack_defrag_ops);
1425 proc_net_remove("ip_conntrack");
1428 EXPORT_SYMBOL(ip_conntrack_expect_list);
1429 EXPORT_SYMBOL(ip_conntrack_lock);
1430 EXPORT_SYMBOL(ip_conntrack_hash);
1431 +EXPORT_SYMBOL(ip_conntrack_untracked);
1432 EXPORT_SYMBOL_GPL(ip_conntrack_find_get);
1433 EXPORT_SYMBOL_GPL(ip_conntrack_put);
1434 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_nat_core.c linux-2.6.5-rc2/net/ipv4/netfilter/ip_nat_core.c
1435 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_nat_core.c 2004-03-20 00:11:02.000000000 +0000
1436 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ip_nat_core.c 2004-03-22 08:29:50.000000000 +0000
1437 @@ -1016,6 +1016,10 @@
1438 /* FIXME: Man, this is a hack. <SIGH> */
1439 IP_NF_ASSERT(ip_conntrack_destroyed == NULL);
1440 ip_conntrack_destroyed = &ip_nat_cleanup_conntrack;
1442 + /* Initialize fake conntrack so that NAT will skip it */
1443 + ip_conntrack_untracked.nat.info.initialized |=
1444 + (1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST);
1448 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_pool.c linux-2.6.5-rc2/net/ipv4/netfilter/ip_pool.c
1449 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_pool.c 1970-01-01 00:00:00.000000000 +0000
1450 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ip_pool.c 2004-03-22 08:29:18.000000000 +0000
1452 +/* Kernel module for IP pool management */
1454 +#include <linux/module.h>
1455 +#include <linux/ip.h>
1456 +#include <linux/skbuff.h>
1457 +#include <linux/netfilter_ipv4/ip_tables.h>
1458 +#include <linux/netfilter_ipv4/ip_pool.h>
1459 +#include <linux/errno.h>
1460 +#include <asm/uaccess.h>
1461 +#include <asm/bitops.h>
1462 +#include <linux/interrupt.h>
1463 +#include <linux/spinlock.h>
1468 +#define DP(format, args...)
1471 +MODULE_LICENSE("GPL");
1474 +static int nr_pool = NR_POOL;/* overwrite this when loading module */
1477 + u_int32_t first_ip; /* host byte order, included in range */
1478 + u_int32_t last_ip; /* host byte order, included in range */
1479 + void *members; /* the bitmap proper */
1480 + int nr_use; /* total nr. of tests through this */
1481 + int nr_match; /* total nr. of matches through this */
1485 +static struct ip_pool *POOL;
1487 +static inline struct ip_pool *lookup(ip_pool_t index)
1489 + if (index < 0 || index >= nr_pool) {
1490 + DP("ip_pool:lookup: bad index %d\n", index);
1493 + return POOL+index;
1496 +int ip_pool_match(ip_pool_t index, u_int32_t addr)
1498 + struct ip_pool *pool = lookup(index);
1501 + if (!pool || !pool->members)
1503 + read_lock_bh(&pool->lock);
1504 + if (pool->members) {
1505 + if (addr >= pool->first_ip && addr <= pool->last_ip) {
1506 + addr -= pool->first_ip;
1507 + if (test_bit(addr, pool->members)) {
1509 +#ifdef CONFIG_IP_POOL_STATISTICS
1514 +#ifdef CONFIG_IP_POOL_STATISTICS
1518 + read_unlock_bh(&pool->lock);
1521 +EXPORT_SYMBOL(ip_pool_match);
1523 +static int pool_change(ip_pool_t index, u_int32_t addr, int isdel)
1525 + struct ip_pool *pool;
1528 + pool = lookup(index);
1529 + if ( !pool || !pool->members
1530 + || addr < pool->first_ip || addr > pool->last_ip)
1532 + read_lock_bh(&pool->lock);
1533 + if (pool->members && addr >= pool->first_ip && addr <= pool->last_ip) {
1534 + addr -= pool->first_ip;
1536 + ? (0 != test_and_clear_bit(addr, pool->members))
1537 + : (0 != test_and_set_bit(addr, pool->members));
1539 + read_unlock_bh(&pool->lock);
1543 +int ip_pool_mod(ip_pool_t index, u_int32_t addr, int isdel)
1545 + int res = pool_change(index,addr,isdel);
1547 + if (!isdel) res = !res;
1550 +EXPORT_SYMBOL(ip_pool_mod);
1552 +static inline int bitmap_bytes(u_int32_t a, u_int32_t b)
1554 + return 4*((((b-a+8)/8)+3)/4);
1557 +static inline int poolbytes(ip_pool_t index)
1559 + struct ip_pool *pool = lookup(index);
1561 + return pool ? bitmap_bytes(pool->first_ip, pool->last_ip) : 0;
1564 +static int setpool(
1570 + struct ip_pool_request req;
1572 + DP("ip_pool:setpool: optval=%d, user=%p, len=%d\n", optval, user, len);
1573 + if (!capable(CAP_NET_ADMIN))
1575 + if (optval != SO_IP_POOL)
1577 + if (len != sizeof(req))
1579 + if (copy_from_user(&req, user, sizeof(req)) != 0)
1581 + printk("obsolete op - upgrade your ippool(8) utility.\n");
1585 +static int getpool(
1591 + struct ip_pool_request req;
1592 + struct ip_pool *pool;
1598 + DP("ip_pool:getpool: optval=%d, user=%p\n", optval, user);
1599 + if (!capable(CAP_NET_ADMIN))
1601 + if (optval != SO_IP_POOL)
1603 + if (*len != sizeof(req)) {
1606 + if (copy_from_user(&req, user, sizeof(req)) != 0)
1608 + DP("ip_pool:getpool op=%d, index=%d\n", req.op, req.index);
1609 + if (req.op < IP_POOL_BAD001) {
1610 + printk("obsolete op - upgrade your ippool(8) utility.\n");
1614 + case IP_POOL_HIGH_NR:
1615 + DP("ip_pool HIGH_NR\n");
1616 + req.index = IP_POOL_NONE;
1617 + for (i=0; i<nr_pool; i++)
1618 + if (POOL[i].members)
1620 + return copy_to_user(user, &req, sizeof(req));
1621 + case IP_POOL_LOOKUP:
1622 + DP("ip_pool LOOKUP\n");
1623 + pool = lookup(req.index);
1626 + if (!pool->members)
1628 + req.addr = htonl(pool->first_ip);
1629 + req.addr2 = htonl(pool->last_ip);
1630 + return copy_to_user(user, &req, sizeof(req));
1631 + case IP_POOL_USAGE:
1632 + DP("ip_pool USE\n");
1633 + pool = lookup(req.index);
1636 + if (!pool->members)
1638 + req.addr = pool->nr_use;
1639 + req.addr2 = pool->nr_match;
1640 + return copy_to_user(user, &req, sizeof(req));
1641 + case IP_POOL_TEST_ADDR:
1642 + DP("ip_pool TEST 0x%08x\n", req.addr);
1643 + pool = lookup(req.index);
1647 + read_lock_bh(&pool->lock);
1648 + if (!pool->members) {
1649 + DP("ip_pool TEST_ADDR no members in pool\n");
1651 + goto unlock_and_return_res;
1653 + req.addr = ntohl(req.addr);
1654 + if (req.addr < pool->first_ip) {
1655 + DP("ip_pool TEST_ADDR address < pool bounds\n");
1657 + goto unlock_and_return_res;
1659 + if (req.addr > pool->last_ip) {
1660 + DP("ip_pool TEST_ADDR address > pool bounds\n");
1662 + goto unlock_and_return_res;
1664 + req.addr = (0 != test_bit((req.addr - pool->first_ip),
1666 + read_unlock_bh(&pool->lock);
1667 + return copy_to_user(user, &req, sizeof(req));
1668 + case IP_POOL_FLUSH:
1669 + DP("ip_pool FLUSH not yet implemented.\n");
1671 + case IP_POOL_DESTROY:
1672 + DP("ip_pool DESTROY not yet implemented.\n");
1674 + case IP_POOL_INIT:
1675 + DP("ip_pool INIT 0x%08x-0x%08x\n", req.addr, req.addr2);
1676 + pool = lookup(req.index);
1679 + req.addr = ntohl(req.addr);
1680 + req.addr2 = ntohl(req.addr2);
1681 + if (req.addr > req.addr2) {
1682 + DP("ip_pool INIT bad ip range\n");
1685 + newbytes = bitmap_bytes(req.addr, req.addr2);
1686 + newmembers = kmalloc(newbytes, GFP_KERNEL);
1687 + if (!newmembers) {
1688 + DP("ip_pool INIT out of mem for %d bytes\n", newbytes);
1691 + memset(newmembers, 0, newbytes);
1692 + write_lock_bh(&pool->lock);
1693 + if (pool->members) {
1694 + DP("ip_pool INIT pool %d exists\n", req.index);
1695 + kfree(newmembers);
1697 + goto unlock_and_return_res;
1699 + pool->first_ip = req.addr;
1700 + pool->last_ip = req.addr2;
1702 + pool->nr_match = 0;
1703 + pool->members = newmembers;
1704 + write_unlock_bh(&pool->lock);
1706 + case IP_POOL_ADD_ADDR:
1707 + DP("ip_pool ADD_ADDR 0x%08x\n", req.addr);
1708 + req.addr = pool_change(req.index, ntohl(req.addr), 0);
1709 + return copy_to_user(user, &req, sizeof(req));
1710 + case IP_POOL_DEL_ADDR:
1711 + DP("ip_pool DEL_ADDR 0x%08x\n", req.addr);
1712 + req.addr = pool_change(req.index, ntohl(req.addr), 1);
1713 + return copy_to_user(user, &req, sizeof(req));
1715 + DP("ip_pool:getpool bad op %d\n", req.op);
1720 +unlock_and_return_res:
1722 + read_unlock_bh(&pool->lock);
1726 +static struct nf_sockopt_ops so_pool
1727 += { { NULL, NULL }, PF_INET,
1728 + SO_IP_POOL, SO_IP_POOL+1, &setpool,
1729 + SO_IP_POOL, SO_IP_POOL+1, &getpool,
1732 +MODULE_PARM(nr_pool, "i");
1734 +static int __init init(void)
1739 + if (nr_pool < 1) {
1740 + printk("ip_pool module init: bad nr_pool %d\n", nr_pool);
1743 + POOL = kmalloc(nr_pool * sizeof(*POOL), GFP_KERNEL);
1745 + printk("ip_pool module init: out of memory for nr_pool %d\n",
1749 + for (i=0; i<nr_pool; i++) {
1750 + POOL[i].first_ip = 0;
1751 + POOL[i].last_ip = 0;
1752 + POOL[i].members = 0;
1753 + POOL[i].nr_use = 0;
1754 + POOL[i].nr_match = 0;
1755 + POOL[i].lock = RW_LOCK_UNLOCKED;
1757 + res = nf_register_sockopt(&so_pool);
1758 + DP("ip_pool:init %d pools, result %d\n", nr_pool, res);
1766 +static void __exit fini(void)
1770 + DP("ip_pool:fini BYEBYE\n");
1771 + nf_unregister_sockopt(&so_pool);
1772 + for (i=0; i<nr_pool; i++) {
1773 + if (POOL[i].members) {
1774 + kfree(POOL[i].members);
1775 + POOL[i].members = 0;
1780 + DP("ip_pool:fini these are the famous last words\n");
1786 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c
1787 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 1970-01-01 00:00:00.000000000 +0000
1788 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 2004-03-22 08:27:30.000000000 +0000
1791 + * Strip all IP options in the IP packet header.
1793 + * (C) 2001 by Fabrice MARIE <fabrice@netfilter.org>
1794 + * This software is distributed under GNU GPL v2, 1991
1797 +#include <linux/module.h>
1798 +#include <linux/skbuff.h>
1799 +#include <linux/ip.h>
1800 +#include <net/checksum.h>
1802 +#include <linux/netfilter_ipv4/ip_tables.h>
1804 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
1805 +MODULE_DESCRIPTION("Strip all options in IPv4 packets");
1806 +MODULE_LICENSE("GPL");
1808 +static unsigned int
1809 +target(struct sk_buff **pskb,
1810 + const struct net_device *in,
1811 + const struct net_device *out,
1812 + unsigned int hooknum,
1813 + const void *targinfo,
1816 + struct iphdr *iph;
1817 + struct sk_buff *skb;
1818 + struct ip_options *opt;
1819 + unsigned char *optiph;
1822 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
1826 + iph = (*pskb)->nh.iph;
1827 + optiph = skb->nh.raw;
1828 + l = ((struct ip_options *)(&(IPCB(skb)->opt)))->optlen;
1830 + /* if no options in packet then nothing to clear. */
1831 + if (iph->ihl * 4 == sizeof(struct iphdr))
1832 + return IPT_CONTINUE;
1834 + /* else clear all options */
1835 + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
1836 + memset(optiph+sizeof(struct iphdr), IPOPT_NOOP, l);
1837 + opt = &(IPCB(skb)->opt);
1841 + skb->nfcache |= NFC_ALTERED;
1843 + return IPT_CONTINUE;
1847 +checkentry(const char *tablename,
1848 + const struct ipt_entry *e,
1850 + unsigned int targinfosize,
1851 + unsigned int hook_mask)
1853 + if (strcmp(tablename, "mangle")) {
1854 + printk(KERN_WARNING "IPV4OPTSSTRIP: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1857 + /* nothing else to check because no parameters */
1861 +static struct ipt_target ipt_ipv4optsstrip_reg = {
1862 + .name = "IPV4OPTSSTRIP",
1864 + .checkentry = checkentry,
1865 + .me = THIS_MODULE };
1867 +static int __init init(void)
1869 + return ipt_register_target(&ipt_ipv4optsstrip_reg);
1872 +static void __exit fini(void)
1874 + ipt_unregister_target(&ipt_ipv4optsstrip_reg);
1879 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_LOG.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_LOG.c
1880 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_LOG.c 2004-03-20 00:11:42.000000000 +0000
1881 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_LOG.c 2004-03-22 08:27:15.000000000 +0000
1883 #include <net/tcp.h>
1884 #include <net/route.h>
1886 +#include <linux/netfilter.h>
1887 #include <linux/netfilter_ipv4/ip_tables.h>
1888 #include <linux/netfilter_ipv4/ipt_LOG.h>
1891 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
1892 MODULE_DESCRIPTION("iptables syslog logging module");
1894 +static unsigned int nflog = 1;
1895 +MODULE_PARM(nflog, "i");
1896 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
1899 #define DEBUGP printk
1901 @@ -324,28 +329,25 @@
1902 /* maxlen = 230+ 91 + 230 + 252 = 803 */
1905 -static unsigned int
1906 -ipt_log_target(struct sk_buff **pskb,
1908 +ipt_log_packet(unsigned int hooknum,
1909 + const struct sk_buff *skb,
1910 const struct net_device *in,
1911 const struct net_device *out,
1912 - unsigned int hooknum,
1913 - const void *targinfo,
1915 + const struct ipt_log_info *loginfo,
1916 + const char *level_string,
1917 + const char *prefix)
1919 - const struct ipt_log_info *loginfo = targinfo;
1920 - char level_string[4] = "< >";
1922 - level_string[1] = '0' + (loginfo->level % 8);
1923 spin_lock_bh(&log_lock);
1924 printk(level_string);
1925 printk("%sIN=%s OUT=%s ",
1927 + prefix == NULL ? loginfo->prefix : prefix,
1929 out ? out->name : "");
1930 #ifdef CONFIG_BRIDGE_NETFILTER
1931 - if ((*pskb)->nf_bridge) {
1932 - struct net_device *physindev = (*pskb)->nf_bridge->physindev;
1933 - struct net_device *physoutdev = (*pskb)->nf_bridge->physoutdev;
1934 + if (skb->nf_bridge) {
1935 + struct net_device *physindev = skb->nf_bridge->physindev;
1936 + struct net_device *physoutdev = skb->nf_bridge->physoutdev;
1938 if (physindev && in != physindev)
1939 printk("PHYSIN=%s ", physindev->name);
1940 @@ -357,25 +359,56 @@
1942 /* MAC logging for input chain only. */
1944 - if ((*pskb)->dev && (*pskb)->dev->hard_header_len
1945 - && (*pskb)->mac.raw != (void*)(*pskb)->nh.iph) {
1946 + if (skb->dev && skb->dev->hard_header_len
1947 + && skb->mac.raw != (void*)skb->nh.iph) {
1949 - unsigned char *p = (*pskb)->mac.raw;
1950 - for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++)
1951 + unsigned char *p = skb->mac.raw;
1952 + for (i = 0; i < skb->dev->hard_header_len; i++,p++)
1953 printk("%02x%c", *p,
1954 - i==(*pskb)->dev->hard_header_len - 1
1955 + i==skb->dev->hard_header_len - 1
1961 - dump_packet(loginfo, *pskb, 0);
1962 + dump_packet(loginfo, skb, 0);
1964 spin_unlock_bh(&log_lock);
1967 +static unsigned int
1968 +ipt_log_target(struct sk_buff **pskb,
1969 + const struct net_device *in,
1970 + const struct net_device *out,
1971 + unsigned int hooknum,
1972 + const void *targinfo,
1975 + const struct ipt_log_info *loginfo = targinfo;
1976 + char level_string[4] = "< >";
1978 + level_string[1] = '0' + (loginfo->level % 8);
1979 + ipt_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
1981 return IPT_CONTINUE;
1985 +ipt_logfn(unsigned int hooknum,
1986 + const struct sk_buff *skb,
1987 + const struct net_device *in,
1988 + const struct net_device *out,
1989 + const char *prefix)
1991 + struct ipt_log_info loginfo = {
1993 + .logflags = IPT_LOG_MASK,
1997 + ipt_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
2000 static int ipt_log_checkentry(const char *tablename,
2001 const struct ipt_entry *e,
2003 @@ -413,11 +446,18 @@
2005 static int __init init(void)
2007 - return ipt_register_target(&ipt_log_reg);
2008 + if (ipt_register_target(&ipt_log_reg))
2011 + nf_log_register(PF_INET, &ipt_logfn);
2016 static void __exit fini(void)
2019 + nf_log_unregister(PF_INET, &ipt_logfn);
2020 ipt_unregister_target(&ipt_log_reg);
2023 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_NOTRACK.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_NOTRACK.c
2024 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_NOTRACK.c 1970-01-01 00:00:00.000000000 +0000
2025 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_NOTRACK.c 2004-03-22 08:29:50.000000000 +0000
2027 +/* This is a module which is used for setting up fake conntracks
2028 + * on packets so that they are not seen by the conntrack/NAT code.
2030 +#include <linux/module.h>
2031 +#include <linux/skbuff.h>
2033 +#include <linux/netfilter_ipv4/ip_tables.h>
2034 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2036 +static unsigned int
2037 +target(struct sk_buff **pskb,
2038 + const struct net_device *in,
2039 + const struct net_device *out,
2040 + unsigned int hooknum,
2041 + const void *targinfo,
2044 + /* Previously seen (loopback)? Ignore. */
2045 + if ((*pskb)->nfct != NULL)
2046 + return IPT_CONTINUE;
2048 + /* Attach fake conntrack entry.
2049 + If there is a real ct entry correspondig to this packet,
2050 + it'll hang aroun till timing out. We don't deal with it
2051 + for performance reasons. JK */
2052 + (*pskb)->nfct = &ip_conntrack_untracked.infos[IP_CT_NEW];
2053 + nf_conntrack_get((*pskb)->nfct);
2055 + return IPT_CONTINUE;
2059 +checkentry(const char *tablename,
2060 + const struct ipt_entry *e,
2062 + unsigned int targinfosize,
2063 + unsigned int hook_mask)
2065 + if (targinfosize != 0) {
2066 + printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n",
2071 + if (strcmp(tablename, "raw") != 0) {
2072 + printk(KERN_WARNING "NOTRACK: can only be called from \"raw\" table, not \"%s\"\n", tablename);
2079 +static struct ipt_target ipt_notrack_reg = {
2080 + .name = "NOTRACK",
2082 + .checkentry = checkentry,
2086 +static int __init init(void)
2088 + if (ipt_register_target(&ipt_notrack_reg))
2094 +static void __exit fini(void)
2096 + ipt_unregister_target(&ipt_notrack_reg);
2101 +MODULE_LICENSE("GPL");
2102 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_POOL.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_POOL.c
2103 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_POOL.c 1970-01-01 00:00:00.000000000 +0000
2104 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_POOL.c 2004-03-22 08:29:18.000000000 +0000
2106 +/* ipt_POOL.c - netfilter target to manipulate IP pools
2108 + * This target can be used almost everywhere. It acts on some specified
2109 + * IP pool, adding or deleting some IP address in the pool. The address
2110 + * can be either the source (--addsrc, --delsrc), or destination (--add/deldst)
2111 + * of the packet under inspection.
2113 + * The target normally returns IPT_CONTINUE.
2116 +#include <linux/types.h>
2117 +#include <linux/ip.h>
2118 +#include <linux/timer.h>
2119 +#include <linux/module.h>
2120 +#include <linux/netfilter.h>
2121 +#include <linux/netdevice.h>
2122 +#include <linux/if.h>
2123 +#include <linux/inetdevice.h>
2124 +#include <net/protocol.h>
2125 +#include <net/checksum.h>
2126 +#include <linux/netfilter_ipv4.h>
2127 +#include <linux/netfilter_ipv4/ip_nat_rule.h>
2128 +#include <linux/netfilter_ipv4/ipt_pool.h>
2131 +#define DEBUGP printk
2133 +#define DEBUGP(format, args...)
2136 +/*** NOTE NOTE NOTE NOTE ***
2138 +** By sheer luck, I get away with using the "struct ipt_pool_info", as defined
2139 +** in <linux/netfilter_ipv4/ipt_pool.h>, both as the match and target info.
2140 +** Here, in the target implementation, ipt_pool_info.src, if not IP_POOL_NONE,
2141 +** is modified for the source IP address of the packet under inspection.
2142 +** The same way, the ipt_pool_info.dst pool is modified for the destination.
2144 +** The address is added to the pool normally. However, if IPT_POOL_DEL_dir
2145 +** flag is set in ipt_pool_info.flags, the address is deleted from the pool.
2147 +** If a modification was done to the pool, we possibly return ACCEPT or DROP,
2148 +** if the right IPT_POOL_MOD_dir_ACCEPT or _MOD_dir_DROP flags are set.
2149 +** The IPT_POOL_INV_MOD_dir flag inverts the sense of the check (i.e. the
2150 +** ACCEPT and DROP flags are evaluated when the pool was not modified.)
2154 +do_check(const char *tablename,
2155 + const struct ipt_entry *e,
2157 + unsigned int targinfosize,
2158 + unsigned int hook_mask)
2160 + const struct ipt_pool_info *ipi = targinfo;
2162 + if (targinfosize != IPT_ALIGN(sizeof(*ipi))) {
2163 + DEBUGP("POOL_check: size %u.\n", targinfosize);
2166 + DEBUGP("ipt_POOL:do_check(%d,%d,%d)\n",ipi->src,ipi->dst,ipi->flags);
2170 +static unsigned int
2171 +do_target(struct sk_buff **pskb,
2172 + unsigned int hooknum,
2173 + const struct net_device *in,
2174 + const struct net_device *out,
2175 + const void *targinfo,
2178 + const struct ipt_pool_info *ipi = targinfo;
2180 + unsigned int verdict = IPT_CONTINUE;
2182 + if (ipi->src != IP_POOL_NONE) {
2183 + modified = ip_pool_mod(ipi->src, ntohl((*pskb)->nh.iph->saddr),
2184 + ipi->flags & IPT_POOL_DEL_SRC);
2185 + if (!!modified ^ !!(ipi->flags & IPT_POOL_INV_MOD_SRC)) {
2186 + if (ipi->flags & IPT_POOL_MOD_SRC_ACCEPT)
2187 + verdict = NF_ACCEPT;
2188 + else if (ipi->flags & IPT_POOL_MOD_SRC_DROP)
2189 + verdict = NF_DROP;
2192 + if (verdict == IPT_CONTINUE && ipi->dst != IP_POOL_NONE) {
2193 + modified = ip_pool_mod(ipi->dst, ntohl((*pskb)->nh.iph->daddr),
2194 + ipi->flags & IPT_POOL_DEL_DST);
2195 + if (!!modified ^ !!(ipi->flags & IPT_POOL_INV_MOD_DST)) {
2196 + if (ipi->flags & IPT_POOL_MOD_DST_ACCEPT)
2197 + verdict = NF_ACCEPT;
2198 + else if (ipi->flags & IPT_POOL_MOD_DST_DROP)
2199 + verdict = NF_DROP;
2205 +static struct ipt_target pool_reg
2206 += { { NULL, NULL }, "POOL", do_target, do_check, NULL, THIS_MODULE };
2208 +static int __init init(void)
2210 + DEBUGP("init ipt_POOL\n");
2211 + return ipt_register_target(&pool_reg);
2214 +static void __exit fini(void)
2216 + DEBUGP("fini ipt_POOL\n");
2217 + ipt_unregister_target(&pool_reg);
2222 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_TTL.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_TTL.c
2223 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_TTL.c 1970-01-01 00:00:00.000000000 +0000
2224 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_TTL.c 2004-03-22 08:28:11.000000000 +0000
2226 +/* TTL modification target for IP tables
2227 + * (C) 2000 by Harald Welte <laforge@gnumonks.org>
2229 + * Version: $Revision$
2231 + * This software is distributed under the terms of GNU GPL
2234 +#include <linux/module.h>
2235 +#include <linux/skbuff.h>
2236 +#include <linux/ip.h>
2237 +#include <net/checksum.h>
2239 +#include <linux/netfilter_ipv4/ip_tables.h>
2240 +#include <linux/netfilter_ipv4/ipt_TTL.h>
2242 +MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
2243 +MODULE_DESCRIPTION("IP tables TTL modification module");
2244 +MODULE_LICENSE("GPL");
2246 +static unsigned int
2247 +ipt_ttl_target(struct sk_buff **pskb, const struct net_device *in,
2248 + const struct net_device *out, unsigned int hooknum,
2249 + const void *targinfo, void *userinfo)
2251 + struct iphdr *iph;
2252 + const struct ipt_TTL_info *info = targinfo;
2253 + u_int16_t diffs[2];
2256 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
2259 + iph = (*pskb)->nh.iph;
2261 + switch (info->mode) {
2263 + new_ttl = info->ttl;
2266 + new_ttl = iph->ttl + info->ttl;
2267 + if (new_ttl > 255)
2271 + new_ttl = iph->ttl + info->ttl;
2276 + new_ttl = iph->ttl;
2280 + if (new_ttl != iph->ttl) {
2281 + diffs[0] = htons(((unsigned)iph->ttl) << 8) ^ 0xFFFF;
2282 + iph->ttl = new_ttl;
2283 + diffs[1] = htons(((unsigned)iph->ttl) << 8);
2284 + iph->check = csum_fold(csum_partial((char *)diffs,
2286 + iph->check^0xFFFF));
2287 + (*pskb)->nfcache |= NFC_ALTERED;
2290 + return IPT_CONTINUE;
2293 +static int ipt_ttl_checkentry(const char *tablename,
2294 + const struct ipt_entry *e,
2296 + unsigned int targinfosize,
2297 + unsigned int hook_mask)
2299 + struct ipt_TTL_info *info = targinfo;
2301 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_TTL_info))) {
2302 + printk(KERN_WARNING "TTL: targinfosize %u != %Zu\n",
2304 + IPT_ALIGN(sizeof(struct ipt_TTL_info)));
2308 + if (strcmp(tablename, "mangle")) {
2309 + printk(KERN_WARNING "TTL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
2313 + if (info->mode > IPT_TTL_MAXMODE) {
2314 + printk(KERN_WARNING "TTL: invalid or unknown Mode %u\n",
2319 + if ((info->mode != IPT_TTL_SET) && (info->ttl == 0)) {
2320 + printk(KERN_WARNING "TTL: increment/decrement doesn't make sense with value 0\n");
2327 +static struct ipt_target ipt_TTL = {
2329 + .target = ipt_ttl_target,
2330 + .checkentry = ipt_ttl_checkentry,
2334 +static int __init init(void)
2336 + return ipt_register_target(&ipt_TTL);
2339 +static void __exit fini(void)
2341 + ipt_unregister_target(&ipt_TTL);
2346 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_ULOG.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_ULOG.c
2347 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_ULOG.c 2004-03-20 00:11:05.000000000 +0000
2348 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_ULOG.c 2004-03-22 08:27:15.000000000 +0000
2350 #include <linux/netlink.h>
2351 #include <linux/netdevice.h>
2352 #include <linux/mm.h>
2353 +#include <linux/netfilter.h>
2354 #include <linux/netfilter_ipv4/ip_tables.h>
2355 #include <linux/netfilter_ipv4/ipt_ULOG.h>
2356 #include <linux/netfilter_ipv4/lockhelp.h>
2358 MODULE_PARM(flushtimeout, "i");
2359 MODULE_PARM_DESC(flushtimeout, "buffer flush timeout");
2361 +static unsigned int nflog = 1;
2362 +MODULE_PARM(nflog, "i");
2363 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
2365 /* global data structures */
2368 @@ -157,17 +162,17 @@
2372 -static unsigned int ipt_ulog_target(struct sk_buff **pskb,
2373 - const struct net_device *in,
2374 - const struct net_device *out,
2375 - unsigned int hooknum,
2376 - const void *targinfo, void *userinfo)
2377 +static void ipt_ulog_packet(unsigned int hooknum,
2378 + const struct sk_buff *skb,
2379 + const struct net_device *in,
2380 + const struct net_device *out,
2381 + const struct ipt_ulog_info *loginfo,
2382 + const char *prefix)
2385 ulog_packet_msg_t *pm;
2386 size_t size, copy_len;
2387 struct nlmsghdr *nlh;
2388 - struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
2390 /* ffs == find first bit set, necessary because userspace
2391 * is already shifting groupnumber, but we need unshifted.
2394 /* calculate the size of the skb needed */
2395 if ((loginfo->copy_range == 0) ||
2396 - (loginfo->copy_range > (*pskb)->len)) {
2397 - copy_len = (*pskb)->len;
2398 + (loginfo->copy_range > skb->len)) {
2399 + copy_len = skb->len;
2401 copy_len = loginfo->copy_range;
2403 @@ -214,19 +219,21 @@
2405 /* copy hook, prefix, timestamp, payload, etc. */
2406 pm->data_len = copy_len;
2407 - pm->timestamp_sec = (*pskb)->stamp.tv_sec;
2408 - pm->timestamp_usec = (*pskb)->stamp.tv_usec;
2409 - pm->mark = (*pskb)->nfmark;
2410 + pm->timestamp_sec = skb->stamp.tv_sec;
2411 + pm->timestamp_usec = skb->stamp.tv_usec;
2412 + pm->mark = skb->nfmark;
2414 - if (loginfo->prefix[0] != '\0')
2415 + if (prefix != NULL)
2416 + strncpy(pm->prefix, prefix, sizeof(pm->prefix));
2417 + else if (loginfo->prefix[0] != '\0')
2418 strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix));
2420 *(pm->prefix) = '\0';
2422 if (in && in->hard_header_len > 0
2423 - && (*pskb)->mac.raw != (void *) (*pskb)->nh.iph
2424 + && skb->mac.raw != (void *) skb->nh.iph
2425 && in->hard_header_len <= ULOG_MAC_LEN) {
2426 - memcpy(pm->mac, (*pskb)->mac.raw, in->hard_header_len);
2427 + memcpy(pm->mac, skb->mac.raw, in->hard_header_len);
2428 pm->mac_len = in->hard_header_len;
2433 pm->outdev_name[0] = '\0';
2435 - /* copy_len <= (*pskb)->len, so can't fail. */
2436 - if (skb_copy_bits(*pskb, 0, pm->payload, copy_len) < 0)
2437 + /* copy_len <= skb->len, so can't fail. */
2438 + if (skb_copy_bits(skb, 0, pm->payload, copy_len) < 0)
2441 /* check if we are building multi-part messages */
2444 UNLOCK_BH(&ulog_lock);
2446 - return IPT_CONTINUE;
2451 PRINTR("ipt_ULOG: error during NLMSG_PUT\n");
2452 @@ -276,8 +282,35 @@
2453 PRINTR("ipt_ULOG: Error building netlink message\n");
2455 UNLOCK_BH(&ulog_lock);
2458 +static unsigned int ipt_ulog_target(struct sk_buff **pskb,
2459 + const struct net_device *in,
2460 + const struct net_device *out,
2461 + unsigned int hooknum,
2462 + const void *targinfo, void *userinfo)
2464 + struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
2466 - return IPT_CONTINUE;
2467 + ipt_ulog_packet(hooknum, *pskb, in, out, loginfo, NULL);
2469 + return IPT_CONTINUE;
2472 +static void ipt_logfn(unsigned int hooknum,
2473 + const struct sk_buff *skb,
2474 + const struct net_device *in,
2475 + const struct net_device *out,
2476 + const char *prefix)
2478 + struct ipt_ulog_info loginfo = {
2479 + .nl_group = ULOG_DEFAULT_NLGROUP,
2481 + .qthreshold = ULOG_DEFAULT_QTHRESHOLD,
2485 + ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
2488 static int ipt_ulog_checkentry(const char *tablename,
2490 sock_release(nflognl->sk_socket);
2495 + nf_log_register(PF_INET, &ipt_logfn);
2502 DEBUGP("ipt_ULOG: cleanup_module\n");
2505 + nf_log_unregister(PF_INET, &ipt_logfn);
2506 ipt_unregister_target(&ipt_ulog_reg);
2507 sock_release(nflognl->sk_socket);
2509 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_connlimit.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_connlimit.c
2510 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_connlimit.c 1970-01-01 00:00:00.000000000 +0000
2511 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_connlimit.c 2004-03-22 08:28:18.000000000 +0000
2514 + * netfilter module to limit the number of parallel tcp
2515 + * connections per IP address.
2516 + * (c) 2000 Gerd Knorr <kraxel@bytesex.org>
2517 + * Nov 2002: Martin Bene <martin.bene@icomedias.com>:
2518 + * only ignore TIME_WAIT or gone connections
2522 + * Kernel module to match connection tracking information.
2523 + * GPL (C) 1999 Rusty Russell (rusty@rustcorp.com.au).
2525 +#include <linux/module.h>
2526 +#include <linux/skbuff.h>
2527 +#include <linux/list.h>
2528 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2529 +#include <linux/netfilter_ipv4/ip_conntrack_core.h>
2530 +#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
2531 +#include <linux/netfilter_ipv4/ip_tables.h>
2532 +#include <linux/netfilter_ipv4/ipt_connlimit.h>
2536 +MODULE_LICENSE("GPL");
2538 +/* we'll save the tuples of all connections we care about */
2539 +struct ipt_connlimit_conn
2541 + struct list_head list;
2542 + struct ip_conntrack_tuple tuple;
2545 +struct ipt_connlimit_data {
2547 + struct list_head iphash[256];
2550 +static int ipt_iphash(u_int32_t addr)
2554 + hash = addr & 0xff;
2555 + hash ^= (addr >> 8) & 0xff;
2556 + hash ^= (addr >> 16) & 0xff;
2557 + hash ^= (addr >> 24) & 0xff;
2561 +static int count_them(struct ipt_connlimit_data *data,
2562 + u_int32_t addr, u_int32_t mask,
2563 + struct ip_conntrack *ct)
2566 + const static char *tcp[] = { "none", "established", "syn_sent", "syn_recv",
2567 + "fin_wait", "time_wait", "close", "close_wait",
2568 + "last_ack", "listen" };
2570 + int addit = 1, matches = 0;
2571 + struct ip_conntrack_tuple tuple;
2572 + struct ip_conntrack_tuple_hash *found;
2573 + struct ipt_connlimit_conn *conn;
2574 + struct list_head *hash,*lh;
2576 + spin_lock(&data->lock);
2577 + tuple = ct->tuplehash[0].tuple;
2578 + hash = &data->iphash[ipt_iphash(addr & mask)];
2580 + /* check the saved connections */
2581 + for (lh = hash->next; lh != hash; lh = lh->next) {
2582 + conn = list_entry(lh,struct ipt_connlimit_conn,list);
2583 + found = ip_conntrack_find_get(&conn->tuple,ct);
2584 + if (0 == memcmp(&conn->tuple,&tuple,sizeof(tuple)) &&
2586 + found->ctrack->proto.tcp.state != TCP_CONNTRACK_TIME_WAIT) {
2587 + /* Just to be sure we have it only once in the list.
2588 + We should'nt see tuples twice unless someone hooks this
2589 + into a table without "-p tcp --syn" */
2593 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d %s\n",
2594 + ipt_iphash(addr & mask),
2595 + NIPQUAD(conn->tuple.src.ip), ntohs(conn->tuple.src.u.tcp.port),
2596 + NIPQUAD(conn->tuple.dst.ip), ntohs(conn->tuple.dst.u.tcp.port),
2597 + (NULL != found) ? tcp[found->ctrack->proto.tcp.state] : "gone");
2599 + if (NULL == found) {
2600 + /* this one is gone */
2602 + list_del(lh->next);
2606 + if (found->ctrack->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT) {
2607 + /* we don't care about connections which are
2608 + closed already -> ditch it */
2610 + list_del(lh->next);
2612 + nf_conntrack_put(&found->ctrack->infos[0]);
2615 + if ((addr & mask) == (conn->tuple.src.ip & mask)) {
2616 + /* same source IP address -> be counted! */
2619 + nf_conntrack_put(&found->ctrack->infos[0]);
2622 + /* save the new connection in our list */
2624 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d new\n",
2625 + ipt_iphash(addr & mask),
2626 + NIPQUAD(tuple.src.ip), ntohs(tuple.src.u.tcp.port),
2627 + NIPQUAD(tuple.dst.ip), ntohs(tuple.dst.u.tcp.port));
2629 + conn = kmalloc(sizeof(*conn),GFP_ATOMIC);
2632 + memset(conn,0,sizeof(*conn));
2633 + INIT_LIST_HEAD(&conn->list);
2634 + conn->tuple = tuple;
2635 + list_add(&conn->list,hash);
2638 + spin_unlock(&data->lock);
2643 +match(const struct sk_buff *skb,
2644 + const struct net_device *in,
2645 + const struct net_device *out,
2646 + const void *matchinfo,
2650 + const struct ipt_connlimit_info *info = matchinfo;
2651 + int connections, match;
2652 + struct ip_conntrack *ct;
2653 + enum ip_conntrack_info ctinfo;
2655 + ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
2657 + printk("ipt_connlimit: Oops: invalid ct state ?\n");
2661 + connections = count_them(info->data,skb->nh.iph->saddr,info->mask,ct);
2662 + if (-1 == connections) {
2663 + printk("ipt_connlimit: Hmm, kmalloc failed :-(\n");
2664 + *hotdrop = 1; /* let's free some memory :-) */
2667 + match = (info->inverse) ? (connections <= info->limit) : (connections > info->limit);
2669 + printk("ipt_connlimit: src=%u.%u.%u.%u mask=%u.%u.%u.%u "
2670 + "connections=%d limit=%d match=%s\n",
2671 + NIPQUAD(skb->nh.iph->saddr), NIPQUAD(info->mask),
2672 + connections, info->limit, match ? "yes" : "no");
2678 +static int check(const char *tablename,
2679 + const struct ipt_ip *ip,
2681 + unsigned int matchsize,
2682 + unsigned int hook_mask)
2684 + struct ipt_connlimit_info *info = matchinfo;
2688 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connlimit_info)))
2691 + /* refuse anything but tcp */
2692 + if (ip->proto != IPPROTO_TCP)
2695 + /* init private data */
2696 + info->data = kmalloc(sizeof(struct ipt_connlimit_data),GFP_KERNEL);
2697 + spin_lock_init(&(info->data->lock));
2698 + for (i = 0; i < 256; i++)
2699 + INIT_LIST_HEAD(&(info->data->iphash[i]));
2704 +static void destroy(void *matchinfo, unsigned int matchinfosize)
2706 + struct ipt_connlimit_info *info = matchinfo;
2707 + struct ipt_connlimit_conn *conn;
2708 + struct list_head *hash;
2712 + for (i = 0; i < 256; i++) {
2713 + hash = &(info->data->iphash[i]);
2714 + while (hash != hash->next) {
2715 + conn = list_entry(hash->next,struct ipt_connlimit_conn,list);
2716 + list_del(hash->next);
2720 + kfree(info->data);
2723 +static struct ipt_match connlimit_match = {
2724 + .name = "connlimit",
2726 + .checkentry = &check,
2727 + .destroy = &destroy,
2731 +static int __init init(void)
2733 + return ipt_register_match(&connlimit_match);
2736 +static void __exit fini(void)
2738 + ipt_unregister_match(&connlimit_match);
2743 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_conntrack.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_conntrack.c
2744 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_conntrack.c 2004-03-20 00:11:50.000000000 +0000
2745 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_conntrack.c 2004-03-22 08:29:50.000000000 +0000
2748 #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
2751 - statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
2753 - statebit = IPT_CONNTRACK_STATE_INVALID;
2755 + if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
2756 + statebit = IPT_CONNTRACK_STATE_UNTRACKED;
2758 + statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
2760 + statebit = IPT_CONNTRACK_STATE_INVALID;
2762 if(sinfo->flags & IPT_CONNTRACK_STATE) {
2764 if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip !=
2765 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_dstlimit.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_dstlimit.c
2766 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_dstlimit.c 1970-01-01 00:00:00.000000000 +0000
2767 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_dstlimit.c 2004-03-22 08:28:26.000000000 +0000
2769 +/* iptables match extension to limit the number of packets per second
2770 + * seperately for each destination.
2772 + * (C) 2003 by Harald Welte <laforge@netfilter.org>
2776 + * Development of this code was funded by Astaro AG, http://www.astaro.com/
2778 + * based on ipt_limit.c by:
2779 + * Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
2780 + * Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
2781 + * Rusty Russell <rusty@rustcorp.com.au>
2783 + * The general idea is to create a hash table for every dstip and have a
2784 + * seperate limit counter per tuple. This way you can do something like 'limit
2785 + * the number of syn packets for each of my internal addresses.
2787 + * Ideally this would just be implemented as a general 'hash' match, which would
2788 + * allow us to attach any iptables target to it's hash buckets. But this is
2789 + * not possible in the current iptables architecture. As always, pkttables for
2790 + * 2.7.x will help ;)
2792 +#include <linux/module.h>
2793 +#include <linux/skbuff.h>
2794 +#include <linux/spinlock.h>
2795 +#include <linux/random.h>
2796 +#include <linux/jhash.h>
2797 +#include <linux/slab.h>
2798 +#include <linux/vmalloc.h>
2799 +#include <linux/tcp.h>
2800 +#include <linux/udp.h>
2801 +#include <linux/proc_fs.h>
2802 +#include <linux/seq_file.h>
2804 +#define ASSERT_READ_LOCK(x)
2805 +#define ASSERT_WRITE_LOCK(x)
2806 +#include <linux/netfilter_ipv4/lockhelp.h>
2807 +#include <linux/netfilter_ipv4/listhelp.h>
2809 +#include <linux/netfilter_ipv4/ip_tables.h>
2810 +#include <linux/netfilter_ipv4/ipt_dstlimit.h>
2812 +/* FIXME: this is just for IP_NF_ASSERRT */
2813 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2815 +#define MS2JIFFIES(x) ((x*HZ)/1000)
2817 +MODULE_LICENSE("GPL");
2818 +MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
2819 +MODULE_DESCRIPTION("iptables match for limiting per destination");
2821 +/* need to declare this at the top */
2822 +static struct proc_dir_entry *dstlimit_procdir;
2823 +static struct file_operations dl_file_ops;
2825 +/* hash table crap */
2827 +struct dsthash_dst {
2833 +struct dsthash_ent {
2834 + /* static / read-only parts in the beginning */
2835 + struct list_head list;
2836 + struct dsthash_dst dst;
2838 + /* modified structure members in the end */
2839 + unsigned long expires; /* precalculated expiry time */
2841 + unsigned long prev; /* last modification */
2843 + u_int32_t credit_cap, cost;
2847 +struct ipt_dstlimit_htable {
2848 + struct list_head list; /* global list of all htables */
2851 + struct dstlimit_cfg cfg; /* config */
2853 + /* used internally */
2854 + spinlock_t lock; /* lock for list_head */
2855 + u_int32_t rnd; /* random seed for hash */
2856 + struct timer_list timer; /* timer for gc */
2857 + atomic_t count; /* number entries in table */
2859 + /* seq_file stuff */
2860 + struct proc_dir_entry *pde;
2862 + struct list_head hash[0]; /* hashtable itself */
2865 +DECLARE_RWLOCK(dstlimit_lock); /* protects htables list */
2866 +static LIST_HEAD(dstlimit_htables);
2867 +static kmem_cache_t *dstlimit_cachep;
2869 +static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b)
2871 + return (ent->dst.dst_ip == b->dst_ip
2872 + && ent->dst.port == b->port
2873 + && ent->dst.src_ip == b->src_ip);
2876 +static inline u_int32_t
2877 +hash_dst(const struct ipt_dstlimit_htable *ht, const struct dsthash_dst *dst)
2879 + return (jhash_3words(dst->dst_ip, dst->port,
2880 + dst->src_ip, ht->rnd) % ht->cfg.size);
2883 +static inline struct dsthash_ent *
2884 +__dsthash_find(const struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
2886 + struct dsthash_ent *ent;
2887 + u_int32_t hash = hash_dst(ht, dst);
2888 + MUST_BE_LOCKED(&ht->lock);
2889 + ent = LIST_FIND(&ht->hash[hash], dst_cmp, struct dsthash_ent *, dst);
2893 +/* allocate dsthash_ent, initialize dst, put in htable and lock it */
2894 +static struct dsthash_ent *
2895 +__dsthash_alloc_init(struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
2897 + struct dsthash_ent *ent;
2899 + /* initialize hash with random val at the time we allocate
2900 + * the first hashtable entry */
2902 + get_random_bytes(&ht->rnd, 4);
2904 + if (ht->cfg.max &&
2905 + atomic_read(&ht->count) >= ht->cfg.max) {
2906 + /* FIXME: do something. question is what.. */
2907 + if (net_ratelimit())
2908 + printk(KERN_WARNING
2909 + "ipt_dstlimit: max count of %u reached\n",
2914 + ent = kmem_cache_alloc(dstlimit_cachep, GFP_ATOMIC);
2916 + if (net_ratelimit())
2918 + "ipt_dstlimit: can't allocate dsthash_ent\n");
2922 + atomic_inc(&ht->count);
2924 + ent->dst.dst_ip = dst->dst_ip;
2925 + ent->dst.port = dst->port;
2926 + ent->dst.src_ip = dst->src_ip;
2928 + list_add(&ent->list, &ht->hash[hash_dst(ht, dst)]);
2934 +__dsthash_free(struct ipt_dstlimit_htable *ht, struct dsthash_ent *ent)
2936 + MUST_BE_LOCKED(&ht->lock);
2938 + list_del(&ent->list);
2939 + kmem_cache_free(dstlimit_cachep, ent);
2940 + atomic_dec(&ht->count);
2942 +static void htable_gc(unsigned long htlong);
2944 +static int htable_create(struct ipt_dstlimit_info *minfo)
2947 + unsigned int size;
2948 + struct ipt_dstlimit_htable *hinfo;
2950 + if (minfo->cfg.size)
2951 + size = minfo->cfg.size;
2953 + size = (((num_physpages << PAGE_SHIFT) / 16384)
2954 + / sizeof(struct list_head));
2955 + if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
2960 + /* FIXME: don't use vmalloc() here or anywhere else -HW */
2961 + hinfo = vmalloc(sizeof(struct ipt_dstlimit_htable)
2962 + + (sizeof(struct list_head) * size));
2964 + printk(KERN_ERR "ipt_dstlimit: Unable to create hashtable\n");
2967 + minfo->hinfo = hinfo;
2969 + /* copy match config into hashtable config */
2970 + memcpy(&hinfo->cfg, &minfo->cfg, sizeof(hinfo->cfg));
2971 + hinfo->cfg.size = size;
2972 + if (!hinfo->cfg.max)
2973 + hinfo->cfg.max = 8 * hinfo->cfg.size;
2974 + else if (hinfo->cfg.max < hinfo->cfg.size)
2975 + hinfo->cfg.max = hinfo->cfg.size;
2977 + for (i = 0; i < hinfo->cfg.size; i++)
2978 + INIT_LIST_HEAD(&hinfo->hash[i]);
2980 + atomic_set(&hinfo->count, 0);
2981 + atomic_set(&hinfo->use, 1);
2983 + hinfo->lock = SPIN_LOCK_UNLOCKED;
2984 + hinfo->pde = create_proc_entry(minfo->name, 0, dstlimit_procdir);
2985 + if (!hinfo->pde) {
2989 + hinfo->pde->proc_fops = &dl_file_ops;
2990 + hinfo->pde->data = hinfo;
2992 + init_timer(&hinfo->timer);
2993 + hinfo->timer.expires = jiffies + MS2JIFFIES(hinfo->cfg.gc_interval);
2994 + hinfo->timer.data = (unsigned long )hinfo;
2995 + hinfo->timer.function = htable_gc;
2996 + add_timer(&hinfo->timer);
2998 + WRITE_LOCK(&dstlimit_lock);
2999 + list_add(&hinfo->list, &dstlimit_htables);
3000 + WRITE_UNLOCK(&dstlimit_lock);
3005 +static int select_all(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
3010 +static int select_gc(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
3012 + return (jiffies >= he->expires);
3015 +static void htable_selective_cleanup(struct ipt_dstlimit_htable *ht,
3016 + int (*select)(struct ipt_dstlimit_htable *ht,
3017 + struct dsthash_ent *he))
3021 + IP_NF_ASSERT(ht->cfg.size && ht->cfg.max);
3023 + /* lock hash table and iterate over it */
3024 + LOCK_BH(&ht->lock);
3025 + for (i = 0; i < ht->cfg.size; i++) {
3026 + struct dsthash_ent *dh, *n;
3027 + list_for_each_entry_safe(dh, n, &ht->hash[i], list) {
3028 + if ((*select)(ht, dh))
3029 + __dsthash_free(ht, dh);
3032 + UNLOCK_BH(&ht->lock);
3035 +/* hash table garbage collector, run by timer */
3036 +static void htable_gc(unsigned long htlong)
3038 + struct ipt_dstlimit_htable *ht = (struct ipt_dstlimit_htable *)htlong;
3040 + htable_selective_cleanup(ht, select_gc);
3042 + /* re-add the timer accordingly */
3043 + ht->timer.expires = jiffies + MS2JIFFIES(ht->cfg.gc_interval);
3044 + add_timer(&ht->timer);
3047 +static void htable_destroy(struct ipt_dstlimit_htable *hinfo)
3049 + /* remove timer, if it is pending */
3050 + if (timer_pending(&hinfo->timer))
3051 + del_timer(&hinfo->timer);
3053 + /* remove proc entry */
3054 + remove_proc_entry(hinfo->pde->name, dstlimit_procdir);
3056 + htable_selective_cleanup(hinfo, select_all);
3060 +static struct ipt_dstlimit_htable *htable_find_get(char *name)
3062 + struct ipt_dstlimit_htable *hinfo;
3064 + READ_LOCK(&dstlimit_lock);
3065 + list_for_each_entry(hinfo, &dstlimit_htables, list) {
3066 + if (!strcmp(name, hinfo->pde->name)) {
3067 + atomic_inc(&hinfo->use);
3068 + READ_UNLOCK(&dstlimit_lock);
3072 + READ_UNLOCK(&dstlimit_lock);
3077 +static void htable_put(struct ipt_dstlimit_htable *hinfo)
3079 + if (atomic_dec_and_test(&hinfo->use)) {
3080 + WRITE_LOCK(&dstlimit_lock);
3081 + list_del(&hinfo->list);
3082 + WRITE_UNLOCK(&dstlimit_lock);
3083 + htable_destroy(hinfo);
3088 +/* The algorithm used is the Simple Token Bucket Filter (TBF)
3089 + * see net/sched/sch_tbf.c in the linux source tree
3092 +/* Rusty: This is my (non-mathematically-inclined) understanding of
3093 + this algorithm. The `average rate' in jiffies becomes your initial
3094 + amount of credit `credit' and the most credit you can ever have
3095 + `credit_cap'. The `peak rate' becomes the cost of passing the
3098 + `prev' tracks the last packet hit: you gain one credit per jiffy.
3099 + If you get credit balance more than this, the extra credit is
3100 + discarded. Every time the match passes, you lose `cost' credits;
3101 + if you don't have that many, the test fails.
3103 + See Alexey's formal explanation in net/sched/sch_tbf.c.
3105 + To get the maximum range, we multiply by this factor (ie. you get N
3106 + credits per jiffy). We want to allow a rate as low as 1 per day
3107 + (slowest userspace tool allows), which means
3108 + CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32 ie.
3110 +#define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24))
3112 +/* Repeated shift and or gives us all 1s, final shift and add 1 gives
3113 + * us the power of 2 below the theoretical max, so GCC simply does a
3115 +#define _POW2_BELOW2(x) ((x)|((x)>>1))
3116 +#define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2))
3117 +#define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4))
3118 +#define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8))
3119 +#define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16))
3120 +#define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1)
3122 +#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
3124 +/* Precision saver. */
3125 +static inline u_int32_t
3126 +user2credits(u_int32_t user)
3128 + /* If multiplying would overflow... */
3129 + if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY))
3130 + /* Divide first. */
3131 + return (user / IPT_DSTLIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;
3133 + return (user * HZ * CREDITS_PER_JIFFY) / IPT_DSTLIMIT_SCALE;
3136 +static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
3138 + dh->rateinfo.credit += (now - xchg(&dh->rateinfo.prev, now))
3139 + * CREDITS_PER_JIFFY;
3140 + if (dh->rateinfo.credit > dh->rateinfo.credit_cap)
3141 + dh->rateinfo.credit = dh->rateinfo.credit_cap;
3145 +dstlimit_match(const struct sk_buff *skb,
3146 + const struct net_device *in,
3147 + const struct net_device *out,
3148 + const void *matchinfo,
3152 + struct ipt_dstlimit_info *r =
3153 + ((struct ipt_dstlimit_info *)matchinfo)->u.master;
3154 + struct ipt_dstlimit_htable *hinfo = r->hinfo;
3155 + unsigned long now = jiffies;
3156 + struct dsthash_ent *dh;
3157 + struct dsthash_dst dst;
3159 + memset(&dst, 0, sizeof(dst));
3161 + /* dest ip is always in hash */
3162 + dst.dst_ip = skb->nh.iph->daddr;
3164 + /* source ip only if respective hashmode, otherwise set to
3166 + if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_SIP)
3167 + dst.src_ip = skb->nh.iph->saddr;
3169 + /* dest port only if respective mode */
3170 + if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_DPT) {
3173 + /* Must not be a fragment. */
3177 + /* Must be big enough to read ports (both UDP and TCP have
3178 + them at the start). */
3179 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
3180 + /* We've been asked to examine this packet, and we
3181 + can't. Hence, no choice but to drop. */
3186 + switch (skb->nh.iph->protocol) {
3187 + struct tcphdr *th;
3188 + struct udphdr *uh;
3190 + th = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
3191 + dst.port = th->dest;
3194 + uh = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
3195 + dst.port = uh->dest;
3202 + LOCK_BH(&hinfo->lock);
3203 + dh = __dsthash_find(hinfo, &dst);
3205 + dh = __dsthash_alloc_init(hinfo, &dst);
3208 + /* enomem... don't match == DROP */
3209 + if (net_ratelimit())
3210 + printk(KERN_ERR "%s: ENOMEM\n", __FUNCTION__);
3211 + UNLOCK_BH(&hinfo->lock);
3215 + dh->expires = jiffies + MS2JIFFIES(hinfo->cfg.expire);
3217 + dh->rateinfo.prev = jiffies;
3218 + dh->rateinfo.credit = user2credits(hinfo->cfg.avg *
3219 + hinfo->cfg.burst);
3220 + dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg *
3221 + hinfo->cfg.burst);
3222 + dh->rateinfo.cost = user2credits(hinfo->cfg.avg);
3224 + UNLOCK_BH(&hinfo->lock);
3228 + /* update expiration timeout */
3229 + dh->expires = now + MS2JIFFIES(hinfo->cfg.expire);
3231 + rateinfo_recalc(dh, now);
3232 + if (dh->rateinfo.credit >= dh->rateinfo.cost) {
3233 + /* We're underlimit. */
3234 + dh->rateinfo.credit -= dh->rateinfo.cost;
3235 + UNLOCK_BH(&hinfo->lock);
3239 + UNLOCK_BH(&hinfo->lock);
3241 + /* default case: we're overlimit, thus don't match */
3246 +dstlimit_checkentry(const char *tablename,
3247 + const struct ipt_ip *ip,
3249 + unsigned int matchsize,
3250 + unsigned int hook_mask)
3252 + struct ipt_dstlimit_info *r = matchinfo;
3254 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_dstlimit_info)))
3257 + /* Check for overflow. */
3258 + if (r->cfg.burst == 0
3259 + || user2credits(r->cfg.avg * r->cfg.burst) <
3260 + user2credits(r->cfg.avg)) {
3261 + printk(KERN_ERR "ipt_dstlimit: Overflow, try lower: %u/%u\n",
3262 + r->cfg.avg, r->cfg.burst);
3266 + if (r->cfg.mode == 0
3267 + || r->cfg.mode > (IPT_DSTLIMIT_HASH_DPT
3268 + |IPT_DSTLIMIT_HASH_DIP
3269 + |IPT_DSTLIMIT_HASH_SIP))
3272 + if (!r->cfg.gc_interval)
3275 + if (!r->cfg.expire)
3278 + r->hinfo = htable_find_get(r->name);
3279 + if (!r->hinfo && (htable_create(r) != 0)) {
3283 + /* Ugly hack: For SMP, we only want to use one set */
3290 +dstlimit_destroy(void *matchinfo, unsigned int matchsize)
3292 + struct ipt_dstlimit_info *r = (struct ipt_dstlimit_info *) matchinfo;
3294 + htable_put(r->hinfo);
3297 +static struct ipt_match ipt_dstlimit = {
3298 + .list = { .prev = NULL, .next = NULL },
3299 + .name = "dstlimit",
3300 + .match = dstlimit_match,
3301 + .checkentry = dstlimit_checkentry,
3302 + .destroy = dstlimit_destroy,
3308 +static void *dl_seq_start(struct seq_file *s, loff_t *pos)
3310 + struct proc_dir_entry *pde = s->private;
3311 + struct ipt_dstlimit_htable *htable = pde->data;
3312 + unsigned int *bucket;
3314 + LOCK_BH(&htable->lock);
3315 + if (*pos >= htable->cfg.size)
3318 + bucket = kmalloc(sizeof(unsigned int), GFP_KERNEL);
3320 + return ERR_PTR(-ENOMEM);
3326 +static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
3328 + struct proc_dir_entry *pde = s->private;
3329 + struct ipt_dstlimit_htable *htable = pde->data;
3330 + unsigned int *bucket = (unsigned int *)v;
3332 + *pos = ++(*bucket);
3333 + if (*pos >= htable->cfg.size) {
3340 +static void dl_seq_stop(struct seq_file *s, void *v)
3342 + struct proc_dir_entry *pde = s->private;
3343 + struct ipt_dstlimit_htable *htable = pde->data;
3344 + unsigned int *bucket = (unsigned int *)v;
3348 + UNLOCK_BH(&htable->lock);
3351 +static inline int dl_seq_real_show(struct dsthash_ent *ent, struct seq_file *s)
3353 + /* recalculate to show accurate numbers */
3354 + rateinfo_recalc(ent, jiffies);
3356 + return seq_printf(s, "%ld %u.%u.%u.%u->%u.%u.%u.%u:%u %u %u %u\n",
3357 + (ent->expires - jiffies)/HZ,
3358 + NIPQUAD(ent->dst.src_ip),
3359 + NIPQUAD(ent->dst.dst_ip), ntohs(ent->dst.port),
3360 + ent->rateinfo.credit, ent->rateinfo.credit_cap,
3361 + ent->rateinfo.cost);
3364 +static int dl_seq_show(struct seq_file *s, void *v)
3366 + struct proc_dir_entry *pde = s->private;
3367 + struct ipt_dstlimit_htable *htable = pde->data;
3368 + unsigned int *bucket = (unsigned int *)v;
3370 + if (LIST_FIND_W(&htable->hash[*bucket], dl_seq_real_show,
3371 + struct dsthash_ent *, s)) {
3372 + /* buffer was filled and unable to print that tuple */
3378 +static struct seq_operations dl_seq_ops = {
3379 + .start = dl_seq_start,
3380 + .next = dl_seq_next,
3381 + .stop = dl_seq_stop,
3382 + .show = dl_seq_show
3385 +static int dl_proc_open(struct inode *inode, struct file *file)
3387 + int ret = seq_open(file, &dl_seq_ops);
3390 + struct seq_file *sf = file->private_data;
3391 + sf->private = PDE(inode);
3396 +static struct file_operations dl_file_ops = {
3397 + .owner = THIS_MODULE,
3398 + .open = dl_proc_open,
3400 + .llseek = seq_lseek,
3401 + .release = seq_release
3404 +static int init_or_fini(int fini)
3411 + if (ipt_register_match(&ipt_dstlimit)) {
3413 + goto cleanup_nothing;
3416 + /* FIXME: do we really want HWCACHE_ALIGN since our objects are
3417 + * quite small ? */
3418 + dstlimit_cachep = kmem_cache_create("ipt_dstlimit",
3419 + sizeof(struct dsthash_ent), 0,
3420 + SLAB_HWCACHE_ALIGN, NULL, NULL);
3421 + if (!dstlimit_cachep) {
3422 + printk(KERN_ERR "Unable to create ipt_dstlimit slab cache\n");
3424 + goto cleanup_unreg_match;
3427 + dstlimit_procdir = proc_mkdir("ipt_dstlimit", proc_net);
3428 + if (!dstlimit_procdir) {
3429 + printk(KERN_ERR "Unable to create proc dir entry\n");
3431 + goto cleanup_free_slab;
3437 + remove_proc_entry("ipt_dstlimit", proc_net);
3439 + kmem_cache_destroy(dstlimit_cachep);
3440 +cleanup_unreg_match:
3441 + ipt_unregister_match(&ipt_dstlimit);
3447 +static int __init init(void)
3449 + return init_or_fini(0);
3452 +static void __exit fini(void)
3459 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_fuzzy.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_fuzzy.c
3460 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_fuzzy.c 1970-01-01 00:00:00.000000000 +0000
3461 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_fuzzy.c 2004-03-22 08:28:32.000000000 +0000
3464 + * This module implements a simple TSK FLC
3465 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
3466 + * to limit , in an adaptive and flexible way , the packet rate crossing
3467 + * a given stream . It serves as an initial and very simple (but effective)
3468 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
3469 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
3470 + * into our code in a precise , adaptive and efficient manner.
3471 + * The goal is very similar to that of "limit" match , but using techniques of
3472 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
3473 + * avoiding over and undershoots - and stuff like that .
3476 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
3477 + * 2002-08-17 : Changed to eliminate floating point operations .
3478 + * 2002-08-23 : Coding style changes .
3481 +#include <linux/module.h>
3482 +#include <linux/skbuff.h>
3483 +#include <linux/ip.h>
3484 +#include <linux/random.h>
3485 +#include <net/tcp.h>
3486 +#include <linux/spinlock.h>
3487 +#include <linux/netfilter_ipv4/ip_tables.h>
3488 +#include <linux/netfilter_ipv4/ipt_fuzzy.h>
3491 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
3492 + Expressed in percentage
3495 +#define PAR_LOW 1/100
3498 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED ;
3500 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
3501 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
3502 +MODULE_LICENSE("GPL");
3504 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
3512 + return ( (100*(tx-mini)) / (maxi-mini) );
3515 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
3523 + return ( (100*( maxi - tx )) / ( maxi - mini ) );
3527 +ipt_fuzzy_match(const struct sk_buff *pskb,
3528 + const struct net_device *in,
3529 + const struct net_device *out,
3530 + const void *matchinfo,
3534 + /* From userspace */
3536 + struct ipt_fuzzy_info *info = (struct ipt_fuzzy_info *) matchinfo;
3538 + u_int8_t random_number;
3539 + unsigned long amount;
3540 + u_int8_t howhigh, howlow;
3543 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
3545 + info->bytes_total += pskb->len;
3546 + info->packets_total++;
3548 + info->present_time = jiffies;
3550 + if (info->present_time >= info->previous_time)
3551 + amount = info->present_time - info->previous_time;
3553 + /* There was a transition : I choose to re-sample
3554 + and keep the old acceptance rate...
3558 + info->previous_time = info->present_time;
3559 + info->bytes_total = info->packets_total = 0;
3562 + if (amount > HZ/10) /* More than 100 ms elapsed ... */
3565 + info->mean_rate = (u_int32_t) ((HZ*info->packets_total) \
3568 + info->previous_time = info->present_time;
3569 + info->bytes_total = info->packets_total = 0;
3571 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
3572 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
3574 + info->acceptance_rate = (u_int8_t) \
3575 + (howhigh*PAR_LOW + PAR_HIGH*howlow);
3577 + /* In fact , the above defuzzification would require a denominator
3578 + proportional to (howhigh+howlow) but , in this particular case ,
3579 + that expression is constant .
3580 + An imediate consequence is that it isn't necessary to call
3581 + both mf_high and mf_low - but to keep things understandable ,
3586 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
3589 + if ( info->acceptance_rate < 100 )
3591 + get_random_bytes((void *)(&random_number), 1);
3593 + /* If within the acceptance , it can pass => don't match */
3594 + if (random_number <= (255 * info->acceptance_rate) / 100)
3597 + return 1; /* It can't pass ( It matches ) */
3600 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
3605 +ipt_fuzzy_checkentry(const char *tablename,
3606 + const struct ipt_ip *e,
3608 + unsigned int matchsize,
3609 + unsigned int hook_mask)
3612 + const struct ipt_fuzzy_info *info = matchinfo;
3614 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_fuzzy_info))) {
3615 + printk("ipt_fuzzy: matchsize %u != %u\n", matchsize,
3616 + IPT_ALIGN(sizeof(struct ipt_fuzzy_info)));
3620 + if ((info->minimum_rate < MINFUZZYRATE ) || (info->maximum_rate > MAXFUZZYRATE)
3621 + || (info->minimum_rate >= info->maximum_rate )) {
3622 + printk("ipt_fuzzy: BAD limits , please verify !!!\n");
3629 +static struct ipt_match ipt_fuzzy_reg = {
3631 + .match = ipt_fuzzy_match,
3632 + .checkentry = ipt_fuzzy_checkentry,
3636 +static int __init init(void)
3638 + return ipt_register_match(&ipt_fuzzy_reg);
3641 +static void __exit fini(void)
3643 + ipt_unregister_match(&ipt_fuzzy_reg);
3648 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_helper.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_helper.c
3649 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_helper.c 2004-03-20 00:11:34.000000000 +0000
3650 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_helper.c 2004-03-22 08:27:11.000000000 +0000
3652 struct ip_conntrack_expect *exp;
3653 struct ip_conntrack *ct;
3654 enum ip_conntrack_info ctinfo;
3656 + int ret = info->invert;
3658 ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
3660 DEBUGP("ipt_helper: Eek! invalid conntrack?\n");
3666 DEBUGP("ipt_helper: conntrack %p has no master\n", ct);
3673 DEBUGP("master's name = %s , info->name = %s\n",
3674 exp->expectant->helper->name, info->name);
3676 - ret = !strncmp(exp->expectant->helper->name, info->name,
3677 - strlen(exp->expectant->helper->name)) ^ info->invert;
3678 + ret ^= !strncmp(exp->expectant->helper->name, info->name,
3679 + strlen(exp->expectant->helper->name));
3681 READ_UNLOCK(&ip_conntrack_lock);
3685 static int __init init(void)
3687 - need_ip_conntrack();
3688 return ipt_register_match(&helper_match);
3691 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_ipv4options.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_ipv4options.c
3692 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_ipv4options.c 1970-01-01 00:00:00.000000000 +0000
3693 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_ipv4options.c 2004-03-22 08:28:47.000000000 +0000
3696 + This is a module which is used to match ipv4 options.
3697 + This file is distributed under the terms of the GNU General Public
3698 + License (GPL). Copies of the GPL can be obtained from:
3699 + ftp://prep.ai.mit.edu/pub/gnu/GPL
3701 + 11-mars-2001 Fabrice MARIE <fabrice@netfilter.org> : initial development.
3702 + 12-july-2001 Fabrice MARIE <fabrice@netfilter.org> : added router-alert otions matching. Fixed a bug with no-srr
3703 + 12-august-2001 Imran Patel <ipatel@crosswinds.net> : optimization of the match.
3704 + 18-november-2001 Fabrice MARIE <fabrice@netfilter.org> : added [!] 'any' option match.
3705 + 19-february-2004 Harald Welte <laforge@netfilter.org> : merge with 2.6.x
3708 +#include <linux/module.h>
3709 +#include <linux/skbuff.h>
3710 +#include <net/ip.h>
3712 +#include <linux/netfilter_ipv4/ip_tables.h>
3713 +#include <linux/netfilter_ipv4/ipt_ipv4options.h>
3715 +MODULE_LICENSE("GPL");
3716 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
3719 +match(const struct sk_buff *skb,
3720 + const struct net_device *in,
3721 + const struct net_device *out,
3722 + const void *matchinfo,
3726 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
3727 + const struct iphdr *iph = skb->nh.iph;
3728 + const struct ip_options *opt;
3730 + if (iph->ihl * 4 == sizeof(struct iphdr)) {
3731 + /* No options, so we match only the "DONTs" and the "IGNOREs" */
3733 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) ||
3734 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3735 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
3736 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
3737 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
3738 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
3743 + if ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)
3744 + /* there are options, and we don't need to care which one */
3747 + if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
3748 + /* there are options but we don't want any ! */
3753 + opt = &(IPCB(skb)->opt);
3755 + /* source routing */
3756 + if ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) {
3757 + if (!((opt->srr) & (opt->is_strictroute)))
3760 + else if ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) {
3761 + if (!((opt->srr) & (!opt->is_strictroute)))
3764 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) {
3768 + /* record route */
3769 + if ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) {
3773 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) {
3778 + if ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) {
3782 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) {
3786 + /* router-alert option */
3787 + if ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) {
3788 + if (!opt->router_alert)
3791 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) {
3792 + if (opt->router_alert)
3801 +checkentry(const char *tablename,
3802 + const struct ipt_ip *ip,
3804 + unsigned int matchsize,
3805 + unsigned int hook_mask)
3807 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
3808 + /* Check the size */
3809 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_ipv4options_info)))
3811 + /* Now check the coherence of the data ... */
3812 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) &&
3813 + (((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) ||
3814 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) ||
3815 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) ||
3816 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) ||
3817 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)))
3818 + return 0; /* opposites */
3819 + if (((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) &&
3820 + (((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
3821 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3822 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
3823 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
3824 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) ||
3825 + ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)))
3826 + return 0; /* opposites */
3827 + if (((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) &&
3828 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR))
3829 + return 0; /* cannot match in the same time loose and strict source routing */
3830 + if ((((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3831 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR)) &&
3832 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR))
3833 + return 0; /* opposites */
3834 + if (((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) &&
3835 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR))
3836 + return 0; /* opposites */
3837 + if (((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) &&
3838 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
3839 + return 0; /* opposites */
3840 + if (((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) &&
3841 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
3842 + return 0; /* opposites */
3844 + /* everything looks ok. */
3848 +static struct ipt_match ipv4options_match = {
3849 + .name = "ipv4options",
3851 + .checkentry = checkentry,
3855 +static int __init init(void)
3857 + return ipt_register_match(&ipv4options_match);
3860 +static void __exit fini(void)
3862 + ipt_unregister_match(&ipv4options_match);
3867 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_mport.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_mport.c
3868 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_mport.c 1970-01-01 00:00:00.000000000 +0000
3869 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_mport.c 2004-03-22 08:28:51.000000000 +0000
3871 +/* Kernel module to match one of a list of TCP/UDP ports: ports are in
3872 + the same place so we can treat them as equal. */
3873 +#include <linux/module.h>
3874 +#include <linux/types.h>
3875 +#include <linux/udp.h>
3876 +#include <linux/skbuff.h>
3878 +#include <linux/netfilter_ipv4/ipt_mport.h>
3879 +#include <linux/netfilter_ipv4/ip_tables.h>
3881 +MODULE_LICENSE("GPL");
3884 +#define duprintf(format, args...) printk(format , ## args)
3886 +#define duprintf(format, args...)
3889 +/* Returns 1 if the port is matched by the test, 0 otherwise. */
3891 +ports_match(const struct ipt_mport *minfo, u_int16_t src, u_int16_t dst)
3895 + u_int16_t pflags = minfo->pflags;
3896 + for (i=0, m=1; i<IPT_MULTI_PORTS; i++, m<<=1) {
3900 + && minfo->ports[i] == 65535)
3903 + s = minfo->ports[i];
3906 + e = minfo->ports[++i];
3911 + if (minfo->flags & IPT_MPORT_SOURCE
3912 + && src >= s && src <= e)
3915 + if (minfo->flags & IPT_MPORT_DESTINATION
3916 + && dst >= s && dst <= e)
3924 +match(const struct sk_buff *skb,
3925 + const struct net_device *in,
3926 + const struct net_device *out,
3927 + const void *matchinfo,
3932 + const struct ipt_mport *minfo = matchinfo;
3937 + /* Must be big enough to read ports (both UDP and TCP have
3938 + them at the start). */
3939 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
3940 + /* We've been asked to examine this packet, and we
3941 + can't. Hence, no choice but to drop. */
3942 + duprintf("ipt_multiport:"
3943 + " Dropping evil offset=0 tinygram.\n");
3948 + return ports_match(minfo, ntohs(ports[0]), ntohs(ports[1]));
3951 +/* Called when user tries to insert an entry of this type. */
3953 +checkentry(const char *tablename,
3954 + const struct ipt_ip *ip,
3956 + unsigned int matchsize,
3957 + unsigned int hook_mask)
3959 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_mport)))
3962 + /* Must specify proto == TCP/UDP, no unknown flags or bad count */
3963 + return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
3964 + && !(ip->invflags & IPT_INV_PROTO)
3965 + && matchsize == IPT_ALIGN(sizeof(struct ipt_mport));
3968 +static struct ipt_match mport_match = {
3971 + .checkentry = &checkentry,
3975 +static int __init init(void)
3977 + return ipt_register_match(&mport_match);
3980 +static void __exit fini(void)
3982 + ipt_unregister_match(&mport_match);
3987 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_nth.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_nth.c
3988 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_nth.c 1970-01-01 00:00:00.000000000 +0000
3989 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_nth.c 2004-03-22 08:29:02.000000000 +0000
3992 + This is a module which is used for match support for every Nth packet
3993 + This file is distributed under the terms of the GNU General Public
3994 + License (GPL). Copies of the GPL can be obtained from:
3995 + ftp://prep.ai.mit.edu/pub/gnu/GPL
3997 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
3998 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
3999 + * added support for multiple counters
4000 + * added support for matching on individual packets
4001 + in the counter cycle
4002 + 2004-02-19 Harald Welte <laforge@netfilter.org>
4007 +#include <linux/module.h>
4008 +#include <linux/skbuff.h>
4009 +#include <linux/ip.h>
4010 +#include <net/tcp.h>
4011 +#include <linux/spinlock.h>
4012 +#include <linux/netfilter_ipv4/ip_tables.h>
4013 +#include <linux/netfilter_ipv4/ipt_nth.h>
4015 +MODULE_LICENSE("GPL");
4016 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
4019 + * State information.
4026 +static struct state states[IPT_NTH_NUM_COUNTERS];
4029 +ipt_nth_match(const struct sk_buff *pskb,
4030 + const struct net_device *in,
4031 + const struct net_device *out,
4032 + const void *matchinfo,
4036 + /* Parameters from userspace */
4037 + const struct ipt_nth_info *info = matchinfo;
4038 + unsigned counter = info->counter;
4039 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
4041 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
4045 + spin_lock(&states[counter].lock);
4047 + /* Are we matching every nth packet?*/
4048 + if (info->packet == 0xFF)
4050 + /* We're matching every nth packet and only every nth packet*/
4051 + /* Do we match or invert match? */
4052 + if (info->not == 0)
4054 + if (states[counter].number == 0)
4056 + ++states[counter].number;
4059 + if (states[counter].number >= info->every)
4060 + states[counter].number = 0; /* reset the counter */
4062 + ++states[counter].number;
4067 + if (states[counter].number == 0)
4069 + ++states[counter].number;
4072 + if (states[counter].number >= info->every)
4073 + states[counter].number = 0;
4075 + ++states[counter].number;
4081 + /* We're using the --packet, so there must be a rule for every value */
4082 + if (states[counter].number == info->packet)
4084 + /* only increment the counter when a match happens */
4085 + if (states[counter].number >= info->every)
4086 + states[counter].number = 0; /* reset the counter */
4088 + ++states[counter].number;
4097 + spin_unlock(&states[counter].lock);
4101 + spin_unlock(&states[counter].lock);
4106 +ipt_nth_checkentry(const char *tablename,
4107 + const struct ipt_ip *e,
4109 + unsigned int matchsize,
4110 + unsigned int hook_mask)
4112 + /* Parameters from userspace */
4113 + const struct ipt_nth_info *info = matchinfo;
4114 + unsigned counter = info->counter;
4115 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
4117 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
4121 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_nth_info))) {
4122 + printk("nth: matchsize %u != %u\n", matchsize,
4123 + IPT_ALIGN(sizeof(struct ipt_nth_info)));
4127 + states[counter].number = info->startat;
4132 +static struct ipt_match ipt_nth_reg = {
4134 + .match = ipt_nth_match,
4135 + .checkentry = ipt_nth_checkentry,
4139 +static int __init init(void)
4143 + memset(&states, 0, sizeof(states));
4144 + for (counter = 0; counter < IPT_NTH_NUM_COUNTERS; counter++)
4145 + spin_lock_init(&(states[counter].lock));
4147 + return ipt_register_match(&ipt_nth_reg);
4150 +static void __exit fini(void)
4152 + ipt_unregister_match(&ipt_nth_reg);
4157 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_osf.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_osf.c
4158 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_osf.c 1970-01-01 00:00:00.000000000 +0000
4159 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_osf.c 2004-03-22 08:29:11.000000000 +0000
4164 + * Copyright (c) 2003 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
4167 + * This program is free software; you can redistribute it and/or modify
4168 + * it under the terms of the GNU General Public License as published by
4169 + * the Free Software Foundation; either version 2 of the License, or
4170 + * (at your option) any later version.
4172 + * This program is distributed in the hope that it will be useful,
4173 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4174 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4175 + * GNU General Public License for more details.
4177 + * You should have received a copy of the GNU General Public License
4178 + * along with this program; if not, write to the Free Software
4179 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4183 + * OS fingerprint matching module.
4184 + * It simply compares various parameters from SYN packet with
4185 + * some hardcoded ones.
4187 + * Original table was created by Michal Zalewski <lcamtuf@coredump.cx>
4191 +#include <linux/config.h>
4192 +#include <linux/kernel.h>
4193 +#include <linux/types.h>
4194 +#include <linux/string.h>
4195 +#include <linux/smp.h>
4196 +#include <linux/module.h>
4197 +#include <linux/skbuff.h>
4198 +#include <linux/file.h>
4199 +#include <linux/ip.h>
4200 +#include <linux/proc_fs.h>
4201 +#include <linux/fs.h>
4202 +#include <linux/slab.h>
4203 +#include <linux/spinlock.h>
4204 +#include <linux/ctype.h>
4205 +#include <linux/list.h>
4206 +#include <linux/if.h>
4208 +#include <net/sock.h>
4209 +#include <net/ip.h>
4211 +#include <linux/netfilter_ipv4/ip_tables.h>
4213 +#include <linux/netfilter_ipv4/ipt_osf.h>
4218 +#define log(x...) printk(KERN_INFO "ipt_osf: " x)
4219 +#define loga(x...) printk(x)
4221 +#define log(x...) do {} while(0)
4222 +#define loga(x...) do {} while(0)
4225 +#define FMATCH_WRONG 0
4226 +#define FMATCH_OK 1
4227 +#define FMATCH_OPT_WRONG 2
4230 +#define OSFPDEL ':'
4231 +#define MAXOPTSTRLEN 128
4232 +#define OSFFLUSH "FLUSH"
4234 +static rwlock_t osf_lock = RW_LOCK_UNLOCKED;
4235 +static spinlock_t ipt_osf_netlink_lock = SPIN_LOCK_UNLOCKED;
4236 +static struct list_head finger_list;
4237 +static int match(const struct sk_buff *, const struct net_device *, const struct net_device *,
4238 + const void *, int,
4239 + const void *, u_int16_t,
4241 +static int checkentry(const char *, const struct ipt_ip *, void *,
4242 + unsigned int, unsigned int);
4244 +static unsigned long seq, ipt_osf_groups = 1;
4245 +static struct sock *nts;
4247 +static struct ipt_match osf_match =
4257 +static void ipt_osf_nlsend(struct osf_finger *f, const struct sk_buff *sk)
4259 + unsigned int size;
4260 + struct sk_buff *skb;
4261 + struct ipt_osf_nlmsg *data;
4262 + struct nlmsghdr *nlh;
4264 + size = NLMSG_SPACE(sizeof(struct ipt_osf_nlmsg));
4266 + skb = alloc_skb(size, GFP_ATOMIC);
4269 + log("skb_alloc() failed.\n");
4273 + nlh = NLMSG_PUT(skb, 0, seq++, NLMSG_DONE, size - sizeof(*nlh));
4275 + data = (struct ipt_osf_nlmsg *)NLMSG_DATA(nlh);
4277 + memcpy(&data->f, f, sizeof(struct osf_finger));
4278 + memcpy(&data->ip, sk->nh.iph, sizeof(struct iphdr));
4279 + memcpy(&data->tcp, (struct tcphdr *)((u_int32_t *)sk->nh.iph + sk->nh.iph->ihl), sizeof(struct tcphdr));
4281 + NETLINK_CB(skb).dst_groups = ipt_osf_groups;
4282 + netlink_broadcast(nts, skb, 0, ipt_osf_groups, GFP_ATOMIC);
4288 +static inline int smart_dec(const struct sk_buff *skb, unsigned long flags, unsigned char f_ttl)
4290 + struct iphdr *ip = skb->nh.iph;
4292 + if (flags & IPT_OSF_SMART)
4294 + struct in_device *in_dev = in_dev_get(skb->dev);
4298 + if (inet_ifa_match(ip->saddr, ifa))
4300 + in_dev_put(in_dev);
4301 + return (ip->ttl == f_ttl);
4304 + endfor_ifa(in_dev);
4306 + in_dev_put(in_dev);
4307 + return (ip->ttl <= f_ttl);
4310 + return (ip->ttl == f_ttl);
4314 +match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out,
4315 + const void *matchinfo, int offset,
4316 + const void *hdr, u_int16_t datalen,
4319 + struct ipt_osf_info *info = (struct ipt_osf_info *)matchinfo;
4320 + struct iphdr *ip = skb->nh.iph;
4321 + struct tcphdr *tcp;
4322 + int fmatch = FMATCH_WRONG, fcount = 0;
4323 + unsigned long totlen, optsize = 0, window;
4324 + unsigned char df, *optp = NULL, *_optp = NULL;
4325 + char check_WSS = 0;
4326 + struct list_head *ent;
4327 + struct osf_finger *f;
4332 + tcp = (struct tcphdr *)((u_int32_t *)ip + ip->ihl);
4337 + totlen = ntohs(ip->tot_len);
4338 + df = ((ntohs(ip->frag_off) & IP_DF)?1:0);
4339 + window = ntohs(tcp->window);
4341 + if (tcp->doff*4 > sizeof(struct tcphdr))
4343 + _optp = optp = (char *)(tcp+1);
4344 + optsize = tcp->doff*4 - sizeof(struct tcphdr);
4348 + /* Actually we can create hash/table of all genres and search
4349 + * only in appropriate part, but here is initial variant,
4350 + * so will use slow path.
4352 + read_lock(&osf_lock);
4353 + list_for_each(ent, &finger_list)
4355 + f = list_entry(ent, struct osf_finger, flist);
4357 + if (!(info->flags & IPT_OSF_LOG) && strcmp(info->genre, f->genre))
4361 + fmatch = FMATCH_WRONG;
4363 + if (totlen == f->ss && df == f->df &&
4364 + smart_dec(skb, info->flags, f->ttl))
4366 + unsigned long foptsize;
4368 + unsigned short mss = 0;
4372 + switch (f->wss.wc)
4374 + case 0: check_WSS = 0; break;
4375 + case 'S': check_WSS = 1; break;
4376 + case 'T': check_WSS = 2; break;
4377 + case '%': check_WSS = 3; break;
4378 + default: log("Wrong fingerprint wss.wc=%d, %s - %s\n",
4379 + f->wss.wc, f->genre, f->details);
4383 + if (check_WSS == 4)
4386 + /* Check options */
4389 + for (optnum=0; optnum<f->opt_num; ++optnum)
4390 + foptsize += f->opt[optnum].length;
4393 + if (foptsize > MAX_IPOPTLEN || optsize > MAX_IPOPTLEN || optsize != foptsize)
4398 + fmatch = FMATCH_OK;
4399 + loga("\tYEP : matching without options.\n");
4400 + if ((info->flags & IPT_OSF_LOG) &&
4401 + info->loglevel == IPT_OSF_LOGLEVEL_FIRST)
4408 + for (optnum=0; optnum<f->opt_num; ++optnum)
4410 + if (f->opt[optnum].kind == (*optp))
4412 + unsigned char len = f->opt[optnum].length;
4413 + unsigned char *optend = optp + len;
4414 + int loop_cont = 0;
4416 + fmatch = FMATCH_OK;
4422 + mss = ntohs(*(unsigned short *)(optp+2));
4437 + /* Skip kind and length fields*/
4440 + if (f->opt[optnum].wc.val != 0)
4442 + unsigned long tmp = 0;
4444 + /* Hmmm... It looks a bit ugly. :) */
4445 + memcpy(&tmp, optp,
4446 + (len > sizeof(unsigned long)?
4447 + sizeof(unsigned long):len));
4448 + /* 2 + 2: optlen(2 bytes) +
4449 + * kind(1 byte) + length(1 byte) */
4455 + if (f->opt[optnum].wc.wc == '%')
4457 + if ((tmp % f->opt[optnum].wc.val) != 0)
4458 + fmatch = FMATCH_OPT_WRONG;
4460 + else if (tmp != f->opt[optnum].wc.val)
4461 + fmatch = FMATCH_OPT_WRONG;
4468 + fmatch = FMATCH_OPT_WRONG;
4470 + if (fmatch != FMATCH_OK)
4474 + if (fmatch != FMATCH_OPT_WRONG)
4476 + fmatch = FMATCH_WRONG;
4478 + switch (check_WSS)
4481 + if (f->wss.val == 0 || window == f->wss.val)
4482 + fmatch = FMATCH_OK;
4485 +/* Lurked in OpenBSD */
4486 +#define SMART_MSS 1460
4487 + if (window == f->wss.val*mss ||
4488 + window == f->wss.val*SMART_MSS)
4489 + fmatch = FMATCH_OK;
4492 + if (window == f->wss.val*(mss+40) ||
4493 + window == f->wss.val*(SMART_MSS+40))
4494 + fmatch = FMATCH_OK;
4497 + if ((window % f->wss.val) == 0)
4498 + fmatch = FMATCH_OK;
4504 + if (fmatch == FMATCH_OK)
4507 + log("%s [%s:%s:%s] : %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u hops=%d\n",
4508 + f->genre, f->version,
4509 + f->subtype, f->details,
4510 + NIPQUAD(ip->saddr), ntohs(tcp->source),
4511 + NIPQUAD(ip->daddr), ntohs(tcp->dest),
4512 + f->ttl - ip->ttl);
4513 + if (info->flags & IPT_OSF_NETLINK)
4515 + spin_lock_bh(&ipt_osf_netlink_lock);
4516 + ipt_osf_nlsend(f, skb);
4517 + spin_unlock_bh(&ipt_osf_netlink_lock);
4519 + if ((info->flags & IPT_OSF_LOG) &&
4520 + info->loglevel == IPT_OSF_LOGLEVEL_FIRST)
4525 + if (!fcount && (info->flags & (IPT_OSF_LOG | IPT_OSF_NETLINK)))
4527 + unsigned char opt[4 * 15 - sizeof(struct tcphdr)];
4528 + unsigned int i, optsize;
4529 + struct osf_finger fg;
4531 + memset(&fg, 0, sizeof(fg));
4533 + if ((info->flags & IPT_OSF_LOG))
4534 + log("Unknown: %lu:%d:%d:%lu:", window, ip->ttl, df, totlen);
4537 + optsize = tcp->doff * 4 - sizeof(struct tcphdr);
4538 + if (skb_copy_bits(skb, ip->ihl*4 + sizeof(struct tcphdr),
4539 + opt, optsize) < 0)
4541 + if (info->flags & IPT_OSF_LOG)
4542 + loga("TRUNCATED");
4543 + if (info->flags & IPT_OSF_NETLINK)
4544 + strcpy(fg.details, "TRUNCATED");
4548 + for (i = 0; i < optsize; i++)
4550 + if (info->flags & IPT_OSF_LOG)
4551 + loga("%02X", opt[i]);
4553 + if (info->flags & IPT_OSF_NETLINK)
4554 + memcpy(fg.details, opt, MAXDETLEN);
4557 + if ((info->flags & IPT_OSF_LOG))
4558 + loga(" %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n",
4559 + NIPQUAD(ip->saddr), ntohs(tcp->source),
4560 + NIPQUAD(ip->daddr), ntohs(tcp->dest));
4562 + if (info->flags & IPT_OSF_NETLINK)
4564 + fg.wss.val = window;
4568 + strncpy(fg.genre, "Unknown", MAXGENRELEN);
4570 + spin_lock_bh(&ipt_osf_netlink_lock);
4571 + ipt_osf_nlsend(&fg, skb);
4572 + spin_unlock_bh(&ipt_osf_netlink_lock);
4576 + read_unlock(&osf_lock);
4578 + return (fmatch == FMATCH_OK)?1:0;
4582 +checkentry(const char *tablename,
4583 + const struct ipt_ip *ip,
4585 + unsigned int matchsize,
4586 + unsigned int hook_mask)
4588 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_osf_info)))
4590 + if (ip->proto != IPPROTO_TCP)
4596 +static char * osf_strchr(char *ptr, char c)
4600 + tmp = strchr(ptr, c);
4602 + while (tmp && tmp+1 && isspace(*(tmp+1)))
4608 +static struct osf_finger * finger_alloc(void)
4610 + struct osf_finger *f;
4612 + f = kmalloc(sizeof(struct osf_finger), GFP_KERNEL);
4614 + memset(f, 0, sizeof(struct osf_finger));
4619 +static void finger_free(struct osf_finger *f)
4621 + memset(f, 0, sizeof(struct osf_finger));
4626 +static void osf_parse_opt(struct osf_opt *opt, int *optnum, char *obuf, int olen)
4630 + unsigned long val;
4634 + while (ptr != NULL && i < olen)
4643 + ptr = osf_strchr(&obuf[i], OPTDEL);
4648 + i += (int)(ptr-&obuf[i]);
4655 + op = OSFOPT_SACKP;
4656 + ptr = osf_strchr(&obuf[i], OPTDEL);
4661 + i += (int)(ptr-&obuf[i]);
4669 + ptr = osf_strchr(&obuf[i], OPTDEL);
4674 + i += (int)(ptr-&obuf[i]);
4682 + ptr = osf_strchr(&obuf[i], OPTDEL);
4685 + switch (obuf[i+1])
4687 + case '%': wc = '%'; break;
4688 + case 'S': wc = 'S'; break;
4689 + case 'T': wc = 'T'; break;
4690 + default: wc = 0; break;
4696 + val = simple_strtoul(&obuf[i+2], NULL, 10);
4698 + val = simple_strtoul(&obuf[i+1], NULL, 10);
4699 + i += (int)(ptr-&obuf[i]);
4707 + ptr = osf_strchr(&obuf[i], OPTDEL);
4710 + if (obuf[i+1] == '%')
4715 + val = simple_strtoul(&obuf[i+2], NULL, 10);
4717 + val = simple_strtoul(&obuf[i+1], NULL, 10);
4718 + i += (int)(ptr-&obuf[i]);
4726 + ptr = osf_strchr(&obuf[i], OPTDEL);
4731 + i += (int)(ptr-&obuf[i]);
4738 + ptr = osf_strchr(&obuf[i], OPTDEL);
4742 + i += (int)(ptr-&obuf[i]);
4750 + opt[*optnum].kind = IANA_opts[op].kind;
4751 + opt[*optnum].length = IANA_opts[op].length;
4752 + opt[*optnum].wc.wc = wc;
4753 + opt[*optnum].wc.val = val;
4759 +static int osf_proc_read(char *buf, char **start, off_t off, int count, int *eof, void *data)
4761 + struct list_head *ent;
4762 + struct osf_finger *f = NULL;
4768 + read_lock_bh(&osf_lock);
4769 + list_for_each(ent, &finger_list)
4771 + f = list_entry(ent, struct osf_finger, flist);
4773 + log("%s [%s]", f->genre, f->details);
4775 + count += sprintf(buf+count, "%s - %s[%s] : %s",
4776 + f->genre, f->version,
4777 + f->subtype, f->details);
4782 + //count += sprintf(buf+count, " OPT: ");
4783 + for (i=0; i<f->opt_num; ++i)
4785 + //count += sprintf(buf+count, "%d.%c%lu; ",
4786 + // f->opt[i].kind, (f->opt[i].wc.wc)?f->opt[i].wc.wc:' ', f->opt[i].wc.val);
4787 + loga("%d.%c%lu; ",
4788 + f->opt[i].kind, (f->opt[i].wc.wc)?f->opt[i].wc.wc:' ', f->opt[i].wc.val);
4792 + count += sprintf(buf+count, "\n");
4794 + read_unlock_bh(&osf_lock);
4799 +static int osf_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
4803 + char obuf[MAXOPTSTRLEN];
4804 + struct osf_finger *finger;
4805 + struct list_head *ent, *n;
4807 + char *pbeg, *pend;
4809 + if (count == strlen(OSFFLUSH) && !strncmp(buffer, OSFFLUSH, strlen(OSFFLUSH)))
4812 + write_lock_bh(&osf_lock);
4813 + list_for_each_safe(ent, n, &finger_list)
4816 + finger = list_entry(ent, struct osf_finger, flist);
4817 + list_del(&finger->flist);
4818 + finger_free(finger);
4820 + write_unlock_bh(&osf_lock);
4822 + log("Flushed %d entries.\n", i);
4829 + for (i=0; i<count && buffer[i] != '\0'; ++i)
4830 + if (buffer[i] == ':')
4833 + if (cnt != 8 || i != count)
4835 + log("Wrong input line cnt=%d[8], len=%lu[%lu]\n",
4840 + memset(obuf, 0, sizeof(obuf));
4842 + finger = finger_alloc();
4845 + log("Failed to allocate new fingerprint entry.\n");
4849 + pbeg = (char *)buffer;
4850 + pend = osf_strchr(pbeg, OSFPDEL);
4854 + if (pbeg[0] == 'S')
4856 + finger->wss.wc = 'S';
4857 + if (pbeg[1] == '%')
4858 + finger->wss.val = simple_strtoul(pbeg+2, NULL, 10);
4859 + else if (pbeg[1] == '*')
4860 + finger->wss.val = 0;
4862 + finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
4864 + else if (pbeg[0] == 'T')
4866 + finger->wss.wc = 'T';
4867 + if (pbeg[1] == '%')
4868 + finger->wss.val = simple_strtoul(pbeg+2, NULL, 10);
4869 + else if (pbeg[1] == '*')
4870 + finger->wss.val = 0;
4872 + finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
4874 + else if (pbeg[0] == '%')
4876 + finger->wss.wc = '%';
4877 + finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
4879 + else if (isdigit(pbeg[0]))
4881 + finger->wss.wc = 0;
4882 + finger->wss.val = simple_strtoul(pbeg, NULL, 10);
4887 + pend = osf_strchr(pbeg, OSFPDEL);
4891 + finger->ttl = simple_strtoul(pbeg, NULL, 10);
4894 + pend = osf_strchr(pbeg, OSFPDEL);
4898 + finger->df = simple_strtoul(pbeg, NULL, 10);
4901 + pend = osf_strchr(pbeg, OSFPDEL);
4905 + finger->ss = simple_strtoul(pbeg, NULL, 10);
4909 + pend = osf_strchr(pbeg, OSFPDEL);
4913 + cnt = snprintf(obuf, sizeof(obuf), "%s", pbeg);
4917 + pend = osf_strchr(pbeg, OSFPDEL);
4921 + if (pbeg[0] == '@' || pbeg[0] == '*')
4922 + cnt = snprintf(finger->genre, sizeof(finger->genre), "%s", pbeg+1);
4924 + cnt = snprintf(finger->genre, sizeof(finger->genre), "%s", pbeg);
4928 + pend = osf_strchr(pbeg, OSFPDEL);
4932 + cnt = snprintf(finger->version, sizeof(finger->version), "%s", pbeg);
4936 + pend = osf_strchr(pbeg, OSFPDEL);
4940 + cnt = snprintf(finger->subtype, sizeof(finger->subtype), "%s", pbeg);
4944 + cnt = snprintf(finger->details,
4945 + ((count - (pbeg - buffer)+1) > MAXDETLEN)?MAXDETLEN:(count - (pbeg - buffer)+1),
4948 + log("%s - %s[%s] : %s\n",
4949 + finger->genre, finger->version,
4950 + finger->subtype, finger->details);
4952 + osf_parse_opt(finger->opt, &finger->opt_num, obuf, sizeof(obuf));
4955 + write_lock_bh(&osf_lock);
4956 + list_add_tail(&finger->flist, &finger_list);
4957 + write_unlock_bh(&osf_lock);
4962 +static int __init osf_init(void)
4965 + struct proc_dir_entry *p;
4967 + log("Startng OS fingerprint matching module.\n");
4969 + INIT_LIST_HEAD(&finger_list);
4971 + err = ipt_register_match(&osf_match);
4974 + log("Failed to register OS fingerprint matching module.\n");
4978 + p = create_proc_entry("sys/net/ipv4/osf", S_IFREG | 0644, NULL);
4981 + ipt_unregister_match(&osf_match);
4985 + p->write_proc = osf_proc_write;
4986 + p->read_proc = osf_proc_read;
4988 + nts = netlink_kernel_create(NETLINK_NFLOG, NULL);
4991 + log("netlink_kernel_create() failed\n");
4992 + remove_proc_entry("sys/net/ipv4/osf", NULL);
4993 + ipt_unregister_match(&osf_match);
5000 +static void __exit osf_fini(void)
5002 + struct list_head *ent, *n;
5003 + struct osf_finger *f;
5005 + remove_proc_entry("sys/net/ipv4/osf", NULL);
5006 + ipt_unregister_match(&osf_match);
5007 +// if (nts && nts->socket)
5008 +// sock_release(nts->socket);
5010 + list_for_each_safe(ent, n, &finger_list)
5012 + f = list_entry(ent, struct osf_finger, flist);
5013 + list_del(&f->flist);
5017 + log("OS fingerprint matching module finished.\n");
5020 +module_init(osf_init);
5021 +module_exit(osf_fini);
5023 +MODULE_LICENSE("GPL");
5024 +MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
5025 +MODULE_DESCRIPTION("Passive OS fingerprint matching.");
5026 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_pool.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_pool.c
5027 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_pool.c 1970-01-01 00:00:00.000000000 +0000
5028 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_pool.c 2004-03-22 08:29:18.000000000 +0000
5030 +/* Kernel module to match an IP address pool. */
5032 +#include <linux/module.h>
5033 +#include <linux/ip.h>
5034 +#include <linux/skbuff.h>
5036 +#include <linux/netfilter_ipv4/ip_tables.h>
5037 +#include <linux/netfilter_ipv4/ip_pool.h>
5038 +#include <linux/netfilter_ipv4/ipt_pool.h>
5040 +static inline int match_pool(
5045 + if (ip_pool_match(index, ntohl(addr)))
5051 + const struct sk_buff *skb,
5052 + const struct net_device *in,
5053 + const struct net_device *out,
5054 + const void *matchinfo,
5057 + u_int16_t datalen,
5060 + const struct ipt_pool_info *info = matchinfo;
5061 + const struct iphdr *iph = skb->nh.iph;
5063 + if (info->src != IP_POOL_NONE && !match_pool(info->src, iph->saddr,
5064 + info->flags&IPT_POOL_INV_SRC))
5067 + if (info->dst != IP_POOL_NONE && !match_pool(info->dst, iph->daddr,
5068 + info->flags&IPT_POOL_INV_DST))
5074 +static int checkentry(
5075 + const char *tablename,
5076 + const struct ipt_ip *ip,
5078 + unsigned int matchsize,
5079 + unsigned int hook_mask
5081 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_pool_info)))
5086 +static struct ipt_match pool_match
5087 += { { NULL, NULL }, "pool", &match, &checkentry, NULL, THIS_MODULE };
5089 +static int __init init(void)
5091 + return ipt_register_match(&pool_match);
5094 +static void __exit fini(void)
5096 + ipt_unregister_match(&pool_match);
5101 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_psd.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_psd.c
5102 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_psd.c 1970-01-01 00:00:00.000000000 +0000
5103 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_psd.c 2004-03-22 08:29:30.000000000 +0000
5106 + This is a module which is used for PSD (portscan detection)
5107 + Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
5108 + and LOG target module.
5110 + Copyright (C) 2000,2001 astaro AG
5112 + This file is distributed under the terms of the GNU General Public
5113 + License (GPL). Copies of the GPL can be obtained from:
5114 + ftp://prep.ai.mit.edu/pub/gnu/GPL
5116 + 2000-05-04 Markus Hennig <hennig@astaro.de> : initial
5117 + 2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
5118 + 2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
5119 + 2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
5120 + 2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
5123 +#include <linux/module.h>
5124 +#include <linux/skbuff.h>
5125 +#include <linux/ip.h>
5126 +#include <net/tcp.h>
5127 +#include <linux/spinlock.h>
5128 +#include <linux/netfilter_ipv4/ip_tables.h>
5129 +#include <linux/netfilter_ipv4/ipt_psd.h>
5132 +#define DEBUGP printk
5134 +#define DEBUGP(format, args...)
5137 +MODULE_LICENSE("GPL");
5138 +MODULE_AUTHOR("Dennis Koslowski <koslowski@astaro.com>");
5140 +#define HF_DADDR_CHANGING 0x01
5141 +#define HF_SPORT_CHANGING 0x02
5142 +#define HF_TOS_CHANGING 0x04
5143 +#define HF_TTL_CHANGING 0x08
5146 + * Information we keep per each target port
5149 + u_int16_t number; /* port number */
5150 + u_int8_t proto; /* protocol number */
5151 + u_int8_t and_flags; /* tcp ANDed flags */
5152 + u_int8_t or_flags; /* tcp ORed flags */
5156 + * Information we keep per each source address.
5159 + struct host *next; /* Next entry with the same hash */
5160 + clock_t timestamp; /* Last update time */
5161 + struct in_addr src_addr; /* Source address */
5162 + struct in_addr dest_addr; /* Destination address */
5163 + unsigned short src_port; /* Source port */
5164 + int count; /* Number of ports in the list */
5165 + int weight; /* Total weight of ports in the list */
5166 + struct port ports[SCAN_MAX_COUNT - 1]; /* List of ports */
5167 + unsigned char tos; /* TOS */
5168 + unsigned char ttl; /* TTL */
5169 + unsigned char flags; /* HF_ flags bitmask */
5173 + * State information.
5177 + struct host list[LIST_SIZE]; /* List of source addresses */
5178 + struct host *hash[HASH_SIZE]; /* Hash: pointers into the list */
5179 + int index; /* Oldest entry to be replaced */
5183 + * Convert an IP address into a hash table index.
5185 +static inline int hashfunc(struct in_addr addr)
5187 + unsigned int value;
5190 + value = addr.s_addr;
5194 + } while ((value >>= HASH_LOG));
5196 + return hash & (HASH_SIZE - 1);
5200 +ipt_psd_match(const struct sk_buff *pskb,
5201 + const struct net_device *in,
5202 + const struct net_device *out,
5203 + const void *matchinfo,
5206 + u_int16_t datalen,
5209 + struct iphdr *ip_hdr;
5210 + struct tcphdr *tcp_hdr;
5211 + struct in_addr addr;
5212 + u_int16_t src_port,dest_port;
5213 + u_int8_t tcp_flags, proto;
5215 + struct host *curr, *last, **head;
5216 + int hash, index, count;
5218 + /* Parameters from userspace */
5219 + const struct ipt_psd_info *psdinfo = matchinfo;
5222 + ip_hdr = pskb->nh.iph;
5224 + /* Sanity check */
5225 + if (ntohs(ip_hdr->frag_off) & IP_OFFSET) {
5226 + DEBUGP("PSD: sanity check failed\n");
5230 + /* TCP or UDP ? */
5231 + proto = ip_hdr->protocol;
5233 + if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
5234 + DEBUGP("PSD: protocol not supported\n");
5238 + /* Get the source address, source & destination ports, and TCP flags */
5240 + addr.s_addr = ip_hdr->saddr;
5242 + tcp_hdr = (struct tcphdr*)((u_int32_t *)ip_hdr + ip_hdr->ihl);
5244 + /* Yep, it´s dirty */
5245 + src_port = tcp_hdr->source;
5246 + dest_port = tcp_hdr->dest;
5248 + if (proto == IPPROTO_TCP) {
5249 + tcp_flags = *((u_int8_t*)tcp_hdr + 13);
5255 + /* We're using IP address 0.0.0.0 for a special purpose here, so don't let
5256 + * them spoof us. [DHCP needs this feature - HW] */
5257 + if (!addr.s_addr) {
5258 + DEBUGP("PSD: spoofed source address (0.0.0.0)\n");
5262 + /* Use jiffies here not to depend on someone setting the time while we're
5263 + * running; we need to be careful with possible return value overflows. */
5266 + spin_lock(&state.lock);
5268 + /* Do we know this source address already? */
5271 + if ((curr = *(head = &state.hash[hash = hashfunc(addr)])))
5273 + if (curr->src_addr.s_addr == addr.s_addr) break;
5275 + if (curr->next) last = curr;
5276 + } while ((curr = curr->next));
5280 + /* We know this address, and the entry isn't too old. Update it. */
5281 + if (now - curr->timestamp <= (psdinfo->delay_threshold*HZ)/100 &&
5282 + time_after_eq(now, curr->timestamp)) {
5284 + /* Just update the appropriate list entry if we've seen this port already */
5285 + for (index = 0; index < curr->count; index++) {
5286 + if (curr->ports[index].number == dest_port) {
5287 + curr->ports[index].proto = proto;
5288 + curr->ports[index].and_flags &= tcp_flags;
5289 + curr->ports[index].or_flags |= tcp_flags;
5290 + goto out_no_match;
5294 + /* TCP/ACK and/or TCP/RST to a new port? This could be an outgoing connection. */
5295 + if (proto == IPPROTO_TCP && (tcp_hdr->ack || tcp_hdr->rst))
5296 + goto out_no_match;
5298 + /* Packet to a new port, and not TCP/ACK: update the timestamp */
5299 + curr->timestamp = now;
5301 + /* Logged this scan already? Then drop the packet. */
5302 + if (curr->weight >= psdinfo->weight_threshold)
5305 + /* Specify if destination address, source port, TOS or TTL are not fixed */
5306 + if (curr->dest_addr.s_addr != ip_hdr->daddr)
5307 + curr->flags |= HF_DADDR_CHANGING;
5308 + if (curr->src_port != src_port)
5309 + curr->flags |= HF_SPORT_CHANGING;
5310 + if (curr->tos != ip_hdr->tos)
5311 + curr->flags |= HF_TOS_CHANGING;
5312 + if (curr->ttl != ip_hdr->ttl)
5313 + curr->flags |= HF_TTL_CHANGING;
5315 + /* Update the total weight */
5316 + curr->weight += (ntohs(dest_port) < 1024) ?
5317 + psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
5319 + /* Got enough destination ports to decide that this is a scan? */
5320 + /* Then log it and drop the packet. */
5321 + if (curr->weight >= psdinfo->weight_threshold)
5324 + /* Remember the new port */
5325 + if (curr->count < SCAN_MAX_COUNT) {
5326 + curr->ports[curr->count].number = dest_port;
5327 + curr->ports[curr->count].proto = proto;
5328 + curr->ports[curr->count].and_flags = tcp_flags;
5329 + curr->ports[curr->count].or_flags = tcp_flags;
5333 + goto out_no_match;
5336 + /* We know this address, but the entry is outdated. Mark it unused, and
5337 + * remove from the hash table. We'll allocate a new entry instead since
5338 + * this one might get re-used too soon. */
5339 + curr->src_addr.s_addr = 0;
5341 + last->next = last->next->next;
5343 + *head = (*head)->next;
5347 + /* We don't need an ACK from a new source address */
5348 + if (proto == IPPROTO_TCP && tcp_hdr->ack)
5349 + goto out_no_match;
5351 + /* Got too many source addresses with the same hash value? Then remove the
5352 + * oldest one from the hash table, so that they can't take too much of our
5353 + * CPU time even with carefully chosen spoofed IP addresses. */
5354 + if (count >= HASH_MAX && last) last->next = NULL;
5356 + /* We're going to re-use the oldest list entry, so remove it from the hash
5357 + * table first (if it is really already in use, and isn't removed from the
5358 + * hash table already because of the HASH_MAX check above). */
5360 + /* First, find it */
5361 + if (state.list[state.index].src_addr.s_addr)
5362 + head = &state.hash[hashfunc(state.list[state.index].src_addr)];
5366 + if ((curr = *head))
5368 + if (curr == &state.list[state.index]) break;
5370 + } while ((curr = curr->next));
5372 + /* Then, remove it */
5375 + last->next = last->next->next;
5377 + *head = (*head)->next;
5380 + /* Get our list entry */
5381 + curr = &state.list[state.index++];
5382 + if (state.index >= LIST_SIZE) state.index = 0;
5384 + /* Link it into the hash table */
5385 + head = &state.hash[hash];
5386 + curr->next = *head;
5389 + /* And fill in the fields */
5390 + curr->timestamp = now;
5391 + curr->src_addr = addr;
5392 + curr->dest_addr.s_addr = ip_hdr->daddr;
5393 + curr->src_port = src_port;
5395 + curr->weight = (ntohs(dest_port) < 1024) ?
5396 + psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
5397 + curr->ports[0].number = dest_port;
5398 + curr->ports[0].proto = proto;
5399 + curr->ports[0].and_flags = tcp_flags;
5400 + curr->ports[0].or_flags = tcp_flags;
5401 + curr->tos = ip_hdr->tos;
5402 + curr->ttl = ip_hdr->ttl;
5405 + spin_unlock(&state.lock);
5409 + spin_unlock(&state.lock);
5413 +static int ipt_psd_checkentry(const char *tablename,
5414 + const struct ipt_ip *e,
5416 + unsigned int matchsize,
5417 + unsigned int hook_mask)
5419 +/* const struct ipt_psd_info *psdinfo = targinfo;*/
5421 + /* we accept TCP only */
5422 +/* if (e->ip.proto != IPPROTO_TCP) { */
5423 +/* DEBUGP("PSD: specified protocol may be TCP only\n"); */
5427 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_psd_info))) {
5428 + DEBUGP("PSD: matchsize %u != %u\n",
5430 + IPT_ALIGN(sizeof(struct ipt_psd_info)));
5437 +static struct ipt_match ipt_psd_reg = {
5441 + ipt_psd_checkentry,
5445 +static int __init init(void)
5447 + if (ipt_register_match(&ipt_psd_reg))
5450 + memset(&state, 0, sizeof(state));
5452 + spin_lock_init(&(state.lock));
5454 + printk("netfilter PSD loaded - (c) astaro AG\n");
5458 +static void __exit fini(void)
5460 + ipt_unregister_match(&ipt_psd_reg);
5461 + printk("netfilter PSD unloaded - (c) astaro AG\n");
5466 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_quota.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_quota.c
5467 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_quota.c 1970-01-01 00:00:00.000000000 +0000
5468 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_quota.c 2004-03-22 08:29:35.000000000 +0000
5471 + * netfilter module to enforce network quotas
5473 + * Sam Johnston <samj@samj.net>
5475 +#include <linux/module.h>
5476 +#include <linux/skbuff.h>
5477 +#include <linux/spinlock.h>
5478 +#include <linux/interrupt.h>
5480 +#include <linux/netfilter_ipv4/ip_tables.h>
5481 +#include <linux/netfilter_ipv4/ipt_quota.h>
5483 +MODULE_LICENSE("GPL");
5484 +MODULE_AUTHOR("Sam Johnston <samj@samj.net>");
5486 +static spinlock_t quota_lock = SPIN_LOCK_UNLOCKED;
5489 +match(const struct sk_buff *skb,
5490 + const struct net_device *in,
5491 + const struct net_device *out,
5492 + const void *matchinfo,
5493 + int offset, int *hotdrop)
5495 + struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
5496 + unsigned int datalen;
5498 + if (skb->len < sizeof(struct iphdr))
5501 + datalen = skb->len - skb->nh.iph->ihl*4;
5503 + spin_lock_bh("a_lock);
5505 + if (q->quota >= datalen) {
5506 + /* we can afford this one */
5507 + q->quota -= datalen;
5508 + spin_unlock_bh("a_lock);
5510 +#ifdef DEBUG_IPT_QUOTA
5511 + printk("IPT Quota OK: %llu datlen %d \n", q->quota, datalen);
5516 + /* so we do not allow even small packets from now on */
5519 +#ifdef DEBUG_IPT_QUOTA
5520 + printk("IPT Quota Failed: %llu datlen %d \n", q->quota, datalen);
5523 + spin_unlock_bh("a_lock);
5528 +checkentry(const char *tablename,
5529 + const struct ipt_ip *ip,
5530 + void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
5532 + /* TODO: spinlocks? sanity checks? */
5533 + if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info)))
5539 +static struct ipt_match quota_match = {
5542 + .checkentry = checkentry,
5549 + return ipt_register_match("a_match);
5555 + ipt_unregister_match("a_match);
5561 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_random.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_random.c
5562 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_random.c 1970-01-01 00:00:00.000000000 +0000
5563 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_random.c 2004-03-22 08:29:43.000000000 +0000
5566 + This is a module which is used for a "random" match support.
5567 + This file is distributed under the terms of the GNU General Public
5568 + License (GPL). Copies of the GPL can be obtained from:
5569 + ftp://prep.ai.mit.edu/pub/gnu/GPL
5571 + 2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
5574 +#include <linux/module.h>
5575 +#include <linux/skbuff.h>
5576 +#include <linux/ip.h>
5577 +#include <linux/random.h>
5578 +#include <net/tcp.h>
5579 +#include <linux/spinlock.h>
5580 +#include <linux/netfilter_ipv4/ip_tables.h>
5581 +#include <linux/netfilter_ipv4/ipt_random.h>
5583 +MODULE_LICENSE("GPL");
5586 +ipt_rand_match(const struct sk_buff *pskb,
5587 + const struct net_device *in,
5588 + const struct net_device *out,
5589 + const void *matchinfo,
5592 + u_int16_t datalen,
5595 + /* Parameters from userspace */
5596 + const struct ipt_rand_info *info = matchinfo;
5597 + u_int8_t random_number;
5599 + /* get 1 random number from the kernel random number generation routine */
5600 + get_random_bytes((void *)(&random_number), 1);
5602 + /* Do we match ? */
5603 + if (random_number <= info->average)
5610 +ipt_rand_checkentry(const char *tablename,
5611 + const struct ipt_ip *e,
5613 + unsigned int matchsize,
5614 + unsigned int hook_mask)
5616 + /* Parameters from userspace */
5617 + const struct ipt_rand_info *info = matchinfo;
5619 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_rand_info))) {
5620 + printk("ipt_random: matchsize %u != %u\n", matchsize,
5621 + IPT_ALIGN(sizeof(struct ipt_rand_info)));
5625 + /* must be 1 <= average % <= 99 */
5626 + /* 1 x 2.55 = 2 */
5627 + /* 99 x 2.55 = 252 */
5628 + if ((info->average < 2) || (info->average > 252)) {
5629 + printk("ipt_random: invalid average %u\n", info->average);
5636 +static struct ipt_match ipt_rand_reg = {
5640 + ipt_rand_checkentry,
5644 +static int __init init(void)
5646 + if (ipt_register_match(&ipt_rand_reg))
5649 + printk("ipt_random match loaded\n");
5653 +static void __exit fini(void)
5655 + ipt_unregister_match(&ipt_rand_reg);
5656 + printk("ipt_random match unloaded\n");
5661 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_realm.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_realm.c
5662 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_realm.c 1970-01-01 00:00:00.000000000 +0000
5663 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_realm.c 2004-03-22 08:29:57.000000000 +0000
5665 +/* IP tables module for matching the routing realm
5669 + * (C) 2003 by Sampsa Ranta <sampsa@netsonic.fi>
5671 + * This program is free software; you can redistribute it and/or modify
5672 + * it under the terms of the GNU General Public License version 2 as
5673 + * published by the Free Software Foundation.
5676 +#include <linux/module.h>
5677 +#include <linux/skbuff.h>
5678 +#include <linux/netdevice.h>
5679 +#include <net/route.h>
5681 +#include <linux/netfilter_ipv4/ipt_realm.h>
5682 +#include <linux/netfilter_ipv4/ip_tables.h>
5684 +MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>");
5685 +MODULE_LICENSE("GPL");
5688 +match(const struct sk_buff *skb,
5689 + const struct net_device *in,
5690 + const struct net_device *out,
5691 + const void *matchinfo,
5695 + const struct ipt_realm_info *info = matchinfo;
5696 + struct dst_entry *dst = skb->dst;
5701 + return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
5704 +static int check(const char *tablename,
5705 + const struct ipt_ip *ip,
5707 + unsigned int matchsize,
5708 + unsigned int hook_mask)
5711 + & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
5712 + (1 << NF_IP_LOCAL_OUT)| (1 << NF_IP_LOCAL_IN))) {
5713 + printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, "
5714 + "LOCAL_IN or FORWARD.\n");
5718 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info)))
5724 +static struct ipt_match realm_match = {
5727 + .checkentry = check,
5731 +static int __init init(void)
5733 + return ipt_register_match(&realm_match);
5736 +static void __exit fini(void)
5738 + ipt_unregister_match(&realm_match);
5743 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_sctp.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_sctp.c
5744 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_sctp.c 1970-01-01 00:00:00.000000000 +0000
5745 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_sctp.c 2004-03-22 08:30:03.000000000 +0000
5747 +#include <linux/module.h>
5748 +#include <linux/skbuff.h>
5749 +#include <net/ip.h>
5750 +#include <linux/sctp.h>
5752 +#include <linux/netfilter_ipv4/ip_tables.h>
5753 +#include <linux/netfilter_ipv4/ipt_sctp.h>
5756 +#define duprintf(format, args...) printk(format , ## args)
5758 +#define duprintf(format, args...)
5761 +#define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \
5762 + || (!!((invflag) & (option)) ^ (cond)))
5765 +match_flags(const struct ipt_sctp_flag_info *flag_info,
5766 + const int flag_count,
5767 + u_int8_t chunktype,
5768 + u_int8_t chunkflags)
5772 + for (i = 0; i < flag_count; i++) {
5773 + if (flag_info[i].chunktype == chunktype) {
5774 + return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag;
5782 +match_packet(const struct sk_buff *skb,
5783 + const u_int32_t *chunkmap,
5784 + int chunk_match_type,
5785 + const struct ipt_sctp_flag_info *flag_info,
5786 + const int flag_count,
5790 + u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
5791 + sctp_chunkhdr_t sch;
5795 + if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) {
5796 + SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap);
5799 + offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t);
5801 + if (skb_copy_bits(skb, offset, &sch, sizeof(sch)) < 0) {
5802 + duprintf("Dropping invalid SCTP packet.\n");
5807 + duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n",
5808 + ++i, offset, sch.type, htons(sch.length), sch.flags);
5810 + offset += (htons(sch.length) + 3) & ~3;
5812 + duprintf("skb->len: %d\toffset: %d\n", skb->len, offset);
5814 + if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch.type)) {
5815 + switch (chunk_match_type) {
5816 + case SCTP_CHUNK_MATCH_ANY:
5817 + if (match_flags(flag_info, flag_count,
5818 + sch.type, sch.flags)) {
5823 + case SCTP_CHUNK_MATCH_ALL:
5824 + if (match_flags(flag_info, flag_count,
5825 + sch.type, sch.flags)) {
5826 + SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch.type);
5830 + case SCTP_CHUNK_MATCH_ONLY:
5831 + if (!match_flags(flag_info, flag_count,
5832 + sch.type, sch.flags)) {
5838 + switch (chunk_match_type) {
5839 + case SCTP_CHUNK_MATCH_ONLY:
5843 + } while (offset < skb->len);
5845 + switch (chunk_match_type) {
5846 + case SCTP_CHUNK_MATCH_ALL:
5847 + return SCTP_CHUNKMAP_IS_CLEAR(chunkmap);
5848 + case SCTP_CHUNK_MATCH_ANY:
5850 + case SCTP_CHUNK_MATCH_ONLY:
5854 + /* This will never be reached, but required to stop compiler whine */
5859 +match(const struct sk_buff *skb,
5860 + const struct net_device *in,
5861 + const struct net_device *out,
5862 + const void *matchinfo,
5866 + const struct ipt_sctp_info *info;
5867 + sctp_sctphdr_t sh;
5869 + info = (const struct ipt_sctp_info *)matchinfo;
5872 + duprintf("Dropping non-first fragment.. FIXME\n");
5876 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &sh, sizeof(sh)) < 0) {
5877 + duprintf("Dropping evil TCP offset=0 tinygram.\n");
5881 + duprintf("spt: %d\tdpt: %d\n", ntohs(sh.source), ntohs(sh.dest));
5883 + return SCCHECK(((ntohs(sh.source) >= info->spts[0])
5884 + && (ntohs(sh.source) <= info->spts[1])),
5885 + IPT_SCTP_SRC_PORTS, info->flags, info->invflags)
5886 + && SCCHECK(((ntohs(sh.dest) >= info->dpts[0])
5887 + && (ntohs(sh.dest) <= info->dpts[1])),
5888 + IPT_SCTP_DEST_PORTS, info->flags, info->invflags)
5889 + && SCCHECK(match_packet(skb, info->chunkmap, info->chunk_match_type,
5890 + info->flag_info, info->flag_count,
5892 + IPT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
5896 +checkentry(const char *tablename,
5897 + const struct ipt_ip *ip,
5899 + unsigned int matchsize,
5900 + unsigned int hook_mask)
5902 + const struct ipt_sctp_info *info;
5904 + info = (const struct ipt_sctp_info *)matchinfo;
5906 + return ip->proto == IPPROTO_SCTP
5907 + && !(ip->invflags & IPT_INV_PROTO)
5908 + && matchsize == IPT_ALIGN(sizeof(struct ipt_sctp_info))
5909 + && !(info->flags & ~IPT_SCTP_VALID_FLAGS)
5910 + && !(info->invflags & ~IPT_SCTP_VALID_FLAGS)
5911 + && !(info->invflags & ~info->flags)
5912 + && ((!(info->flags & IPT_SCTP_CHUNK_TYPES)) ||
5913 + (info->chunk_match_type &
5914 + (SCTP_CHUNK_MATCH_ALL
5915 + | SCTP_CHUNK_MATCH_ANY
5916 + | SCTP_CHUNK_MATCH_ONLY)));
5919 +static struct ipt_match sctp_match =
5921 + .list = { NULL, NULL},
5924 + .checkentry = &checkentry,
5929 +static int __init init(void)
5931 + return ipt_register_match(&sctp_match);
5934 +static void __exit fini(void)
5936 + ipt_unregister_match(&sctp_match);
5942 +MODULE_LICENSE("GPL");
5943 +MODULE_AUTHOR("Kiran Kumar Immidi");
5944 +MODULE_DESCRIPTION("Match for SCTP protocol packets");
5946 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_state.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_state.c
5947 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_state.c 2004-03-20 00:12:09.000000000 +0000
5948 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_state.c 2004-03-22 08:29:50.000000000 +0000
5950 enum ip_conntrack_info ctinfo;
5951 unsigned int statebit;
5953 - if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
5954 + if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
5955 + statebit = IPT_STATE_UNTRACKED;
5956 + else if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
5957 statebit = IPT_STATE_INVALID;
5959 statebit = IPT_STATE_BIT(ctinfo);
5960 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_time.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_time.c
5961 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_time.c 1970-01-01 00:00:00.000000000 +0000
5962 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_time.c 2004-03-22 08:30:10.000000000 +0000
5965 + This is a module which is used for time matching
5966 + It is using some modified code from dietlibc (localtime() function)
5967 + that you can find at http://www.fefe.de/dietlibc/
5968 + This file is distributed under the terms of the GNU General Public
5969 + License (GPL). Copies of the GPL can be obtained from: ftp://prep.ai.mit.edu/pub/gnu/GPL
5970 + 2001-05-04 Fabrice MARIE <fabrice@netfilter.org> : initial development.
5971 + 2001-21-05 Fabrice MARIE <fabrice@netfilter.org> : bug fix in the match code,
5972 + thanks to "Zeng Yu" <zengy@capitel.com.cn> for bug report.
5973 + 2001-26-09 Fabrice MARIE <fabrice@netfilter.org> : force the match to be in LOCAL_IN or PRE_ROUTING only.
5974 + 2001-30-11 Fabrice : added the possibility to use the match in FORWARD/OUTPUT with a little hack,
5975 + added Nguyen Dang Phuoc Dong <dongnd@tlnet.com.vn> patch to support timezones.
5978 +#include <linux/module.h>
5979 +#include <linux/skbuff.h>
5980 +#include <linux/netfilter_ipv4/ip_tables.h>
5981 +#include <linux/netfilter_ipv4/ipt_time.h>
5982 +#include <linux/time.h>
5984 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
5985 +MODULE_DESCRIPTION("Match arrival timestamp");
5986 +MODULE_LICENSE("GPL");
5990 + int tm_sec; /* Seconds. [0-60] (1 leap second) */
5991 + int tm_min; /* Minutes. [0-59] */
5992 + int tm_hour; /* Hours. [0-23] */
5993 + int tm_mday; /* Day. [1-31] */
5994 + int tm_mon; /* Month. [0-11] */
5995 + int tm_year; /* Year - 1900. */
5996 + int tm_wday; /* Day of week. [0-6] */
5997 + int tm_yday; /* Days in year.[0-365] */
5998 + int tm_isdst; /* DST. [-1/0/1]*/
6000 + long int tm_gmtoff; /* we don't care, we count from GMT */
6001 + const char *tm_zone; /* we don't care, we count from GMT */
6005 +localtime(const time_t *timepr, struct tm *r);
6008 +match(const struct sk_buff *skb,
6009 + const struct net_device *in,
6010 + const struct net_device *out,
6011 + const void *matchinfo,
6014 + u_int16_t datalen,
6017 + const struct ipt_time_info *info = matchinfo; /* match info for rule */
6018 + struct tm currenttime; /* time human readable */
6019 + u_int8_t days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
6020 + u_int16_t packet_time;
6021 + struct timeval kerneltimeval;
6022 + time_t packet_local_time;
6024 + /* if kerneltime=1, we don't read the skb->timestamp but kernel time instead */
6025 + if (info->kerneltime)
6027 + do_gettimeofday(&kerneltimeval);
6028 + packet_local_time = kerneltimeval.tv_sec;
6031 + packet_local_time = skb->stamp.tv_sec;
6033 + /* Transform the timestamp of the packet, in a human readable form */
6034 + localtime(&packet_local_time, ¤ttime);
6036 + /* check if we match this timestamp, we start by the days... */
6037 + if ((days_of_week[currenttime.tm_wday] & info->days_match) != days_of_week[currenttime.tm_wday])
6038 + return 0; /* the day doesn't match */
6040 + /* ... check the time now */
6041 + packet_time = (currenttime.tm_hour * 60) + currenttime.tm_min;
6042 + if ((packet_time < info->time_start) || (packet_time > info->time_stop))
6045 + /* here we match ! */
6050 +checkentry(const char *tablename,
6051 + const struct ipt_ip *ip,
6053 + unsigned int matchsize,
6054 + unsigned int hook_mask)
6056 + struct ipt_time_info *info = matchinfo; /* match info for rule */
6058 + /* First, check that we are in the correct hook */
6059 + /* PRE_ROUTING, LOCAL_IN or FROWARD */
6061 + & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
6063 + printk("ipt_time: error, only valid for PRE_ROUTING, LOCAL_IN, FORWARD and OUTPUT)\n");
6066 + /* we use the kerneltime if we are in forward or output */
6067 + info->kerneltime = 1;
6068 + if (hook_mask & ~((1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
6069 + /* if not, we use the skb time */
6070 + info->kerneltime = 0;
6072 + /* Check the size */
6073 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_time_info)))
6075 + /* Now check the coherence of the data ... */
6076 + if ((info->time_start > 1439) || /* 23*60+59 = 1439*/
6077 + (info->time_stop > 1439))
6079 + printk(KERN_WARNING "ipt_time: invalid argument\n");
6086 +static struct ipt_match time_match
6087 += { { NULL, NULL }, "time", &match, &checkentry, NULL, THIS_MODULE };
6089 +static int __init init(void)
6091 + printk("ipt_time loading\n");
6092 + return ipt_register_match(&time_match);
6095 +static void __exit fini(void)
6097 + ipt_unregister_match(&time_match);
6098 + printk("ipt_time unloaded\n");
6105 +/* The part below is borowed and modified from dietlibc */
6107 +/* seconds per day */
6108 +#define SPD 24*60*60
6111 +localtime(const time_t *timepr, struct tm *r) {
6114 + extern struct timezone sys_tz;
6115 + const unsigned int __spm[12] =
6122 + (31+28+31+30+31+30),
6123 + (31+28+31+30+31+30+31),
6124 + (31+28+31+30+31+30+31+31),
6125 + (31+28+31+30+31+30+31+31+30),
6126 + (31+28+31+30+31+30+31+31+30+31),
6127 + (31+28+31+30+31+30+31+31+30+31+30),
6129 + register time_t work;
6131 + timep = (*timepr) - (sys_tz.tz_minuteswest * 60);
6133 + r->tm_sec=work%60; work/=60;
6134 + r->tm_min=work%60; r->tm_hour=work/60;
6136 + r->tm_wday=(4+work)%7;
6137 + for (i=1970; ; ++i) {
6138 + register time_t k= (!(i%4) && ((i%100) || !(i%400)))?366:365;
6144 + r->tm_year=i-1900;
6145 + for (i=11; i && __spm[i]>work; --i) ;
6147 + r->tm_mday=work-__spm[i]+1;
6149 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_u32.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_u32.c
6150 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_u32.c 1970-01-01 00:00:00.000000000 +0000
6151 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_u32.c 2004-03-22 08:30:19.000000000 +0000
6153 +/* Kernel module to match u32 packet content. */
6156 +U32 tests whether quantities of up to 4 bytes extracted from a packet
6157 +have specified values. The specification of what to extract is general
6158 +enough to find data at given offsets from tcp headers or payloads.
6161 + The argument amounts to a program in a small language described below.
6162 + tests := location = value | tests && location = value
6163 + value := range | value , range
6164 + range := number | number : number
6165 + a single number, n, is interpreted the same as n:n
6166 + n:m is interpreted as the range of numbers >=n and <=m
6167 + location := number | location operator number
6168 + operator := & | << | >> | @
6170 + The operators &, <<, >>, && mean the same as in c. The = is really a set
6171 + membership operator and the value syntax describes a set. The @ operator
6172 + is what allows moving to the next header and is described further below.
6174 + *** Until I can find out how to avoid it, there are some artificial limits
6175 + on the size of the tests:
6176 + - no more than 10 ='s (and 9 &&'s) in the u32 argument
6177 + - no more than 10 ranges (and 9 commas) per value
6178 + - no more than 10 numbers (and 9 operators) per location
6180 + To describe the meaning of location, imagine the following machine that
6181 + interprets it. There are three registers:
6182 + A is of type char*, initially the address of the IP header
6183 + B and C are unsigned 32 bit integers, initially zero
6185 + The instructions are:
6186 + number B = number;
6187 + C = (*(A+B)<<24)+(*(A+B+1)<<16)+(*(A+B+2)<<8)+*(A+B+3)
6188 + &number C = C&number
6189 + <<number C = C<<number
6190 + >>number C = C>>number
6191 + @number A = A+C; then do the instruction number
6192 + Any access of memory outside [skb->head,skb->end] causes the match to fail.
6193 + Otherwise the result of the computation is the final value of C.
6195 + Whitespace is allowed but not required in the tests.
6196 + However the characters that do occur there are likely to require
6197 + shell quoting, so it's a good idea to enclose the arguments in quotes.
6200 + match IP packets with total length >= 256
6201 + The IP header contains a total length field in bytes 2-3.
6202 + --u32 "0&0xFFFF=0x100:0xFFFF"
6204 + AND that with FFFF (giving bytes 2-3),
6205 + and test whether that's in the range [0x100:0xFFFF]
6207 +Example: (more realistic, hence more complicated)
6208 + match icmp packets with icmp type 0
6209 + First test that it's an icmp packet, true iff byte 9 (protocol) = 1
6210 + --u32 "6&0xFF=1 && ...
6211 + read bytes 6-9, use & to throw away bytes 6-8 and compare the result to 1
6212 + Next test that it's not a fragment.
6213 + (If so it might be part of such a packet but we can't always tell.)
6214 + n.b. This test is generally needed if you want to match anything
6215 + beyond the IP header.
6216 + The last 6 bits of byte 6 and all of byte 7 are 0 iff this is a complete
6217 + packet (not a fragment). Alternatively, you can allow first fragments
6218 + by only testing the last 5 bits of byte 6.
6219 + ... 4&0x3FFF=0 && ...
6220 + Last test: the first byte past the IP header (the type) is 0
6221 + This is where we have to use the @syntax. The length of the IP header
6222 + (IHL) in 32 bit words is stored in the right half of byte 0 of the
6224 + ... 0>>22&0x3C@0>>24=0"
6225 + The first 0 means read bytes 0-3,
6226 + >>22 means shift that 22 bits to the right. Shifting 24 bits would give
6227 + the first byte, so only 22 bits is four times that plus a few more bits.
6228 + &3C then eliminates the two extra bits on the right and the first four
6229 + bits of the first byte.
6230 + For instance, if IHL=5 then the IP header is 20 (4 x 5) bytes long.
6231 + In this case bytes 0-1 are (in binary) xxxx0101 yyzzzzzz,
6232 + >>22 gives the 10 bit value xxxx0101yy and &3C gives 010100.
6233 + @ means to use this number as a new offset into the packet, and read
6234 + four bytes starting from there. This is the first 4 bytes of the icmp
6235 + payload, of which byte 0 is the icmp type. Therefore we simply shift
6236 + the value 24 to the right to throw out all but the first byte and compare
6237 + the result with 0.
6240 + tcp payload bytes 8-12 is any of 1, 2, 5 or 8
6241 + First we test that the packet is a tcp packet (similar to icmp).
6242 + --u32 "6&0xFF=6 && ...
6243 + Next, test that it's not a fragment (same as above).
6244 + ... 0>>22&0x3C@12>>26&0x3C@8=1,2,5,8"
6245 + 0>>22&3C as above computes the number of bytes in the IP header.
6246 + @ makes this the new offset into the packet, which is the start of the
6247 + tcp header. The length of the tcp header (again in 32 bit words) is
6248 + the left half of byte 12 of the tcp header. The 12>>26&3C
6249 + computes this length in bytes (similar to the IP header before).
6250 + @ makes this the new offset, which is the start of the tcp payload.
6251 + Finally 8 reads bytes 8-12 of the payload and = checks whether the
6252 + result is any of 1, 2, 5 or 8
6255 +#include <linux/module.h>
6256 +#include <linux/skbuff.h>
6258 +#include <linux/netfilter_ipv4/ipt_u32.h>
6259 +#include <linux/netfilter_ipv4/ip_tables.h>
6261 +/* #include <asm-i386/timex.h> for timing */
6263 +MODULE_AUTHOR("Don Cohen <don@isis.cs3-inc.com>");
6264 +MODULE_DESCRIPTION("IP tables u32 matching module");
6265 +MODULE_LICENSE("GPL");
6268 +match(const struct sk_buff *skb,
6269 + const struct net_device *in,
6270 + const struct net_device *out,
6271 + const void *matchinfo,
6274 + u_int16_t datalen,
6277 + const struct ipt_u32 *data = matchinfo;
6279 + unsigned char* origbase = (char*)skb->nh.iph;
6280 + unsigned char* base = origbase;
6281 + unsigned char* head = skb->head;
6282 + unsigned char* end = skb->end;
6284 + u_int32_t pos, val;
6285 + /* unsigned long long cycles1, cycles2, cycles3, cycles4;
6286 + cycles1 = get_cycles(); */
6288 + for (testind=0; testind < data->ntests; testind++) {
6289 + base = origbase; /* reset for each test */
6290 + pos = data->tests[testind].location[0].number;
6291 + if (base+pos+3 > end || base+pos < head)
6293 + val = (base[pos]<<24) + (base[pos+1]<<16) +
6294 + (base[pos+2]<<8) + base[pos+3];
6295 + nnums = data->tests[testind].nnums;
6296 + for (i=1; i < nnums; i++) {
6297 + u_int32_t number = data->tests[testind].location[i].number;
6298 + switch (data->tests[testind].location[i].nextop) {
6300 + val = val & number;
6302 + case IPT_U32_LEFTSH:
6303 + val = val << number;
6305 + case IPT_U32_RIGHTSH:
6306 + val = val >> number;
6309 + base = base + val;
6311 + if (base+pos+3 > end || base+pos < head)
6313 + val = (base[pos]<<24) + (base[pos+1]<<16) +
6314 + (base[pos+2]<<8) + base[pos+3];
6318 + nvals = data->tests[testind].nvalues;
6319 + for (i=0; i < nvals; i++) {
6320 + if ((data->tests[testind].value[i].min <= val) &&
6321 + (val <= data->tests[testind].value[i].max)) {
6325 + if (i >= data->tests[testind].nvalues) {
6326 + /* cycles2 = get_cycles();
6327 + printk("failed %d in %d cycles\n", testind,
6328 + cycles2-cycles1); */
6332 + /* cycles2 = get_cycles();
6333 + printk("succeeded in %d cycles\n", cycles2-cycles1); */
6338 +checkentry(const char *tablename,
6339 + const struct ipt_ip *ip,
6341 + unsigned int matchsize,
6342 + unsigned int hook_mask)
6344 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_u32)))
6349 +static struct ipt_match u32_match
6350 += { { NULL, NULL }, "u32", &match, &checkentry, NULL, THIS_MODULE };
6352 +static int __init init(void)
6354 + return ipt_register_match(&u32_match);
6357 +static void __exit fini(void)
6359 + ipt_unregister_match(&u32_match);
6364 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/iptable_raw.c linux-2.6.5-rc2/net/ipv4/netfilter/iptable_raw.c
6365 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/iptable_raw.c 1970-01-01 00:00:00.000000000 +0000
6366 +++ linux-2.6.5-rc2/net/ipv4/netfilter/iptable_raw.c 2004-03-22 08:29:50.000000000 +0000
6369 + * 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT .
6371 + * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
6373 +#include <linux/module.h>
6374 +#include <linux/netfilter_ipv4/ip_tables.h>
6376 +#define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
6378 +/* Standard entry. */
6379 +struct ipt_standard
6381 + struct ipt_entry entry;
6382 + struct ipt_standard_target target;
6385 +struct ipt_error_target
6387 + struct ipt_entry_target target;
6388 + char errorname[IPT_FUNCTION_MAXNAMELEN];
6393 + struct ipt_entry entry;
6394 + struct ipt_error_target target;
6399 + struct ipt_replace repl;
6400 + struct ipt_standard entries[2];
6401 + struct ipt_error term;
6402 +} initial_table __initdata
6403 += { { "raw", RAW_VALID_HOOKS, 3,
6404 + sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
6405 + { [NF_IP_PRE_ROUTING] 0,
6406 + [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
6407 + { [NF_IP_PRE_ROUTING] 0,
6408 + [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
6412 + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
6414 + sizeof(struct ipt_entry),
6415 + sizeof(struct ipt_standard),
6416 + 0, { 0, 0 }, { } },
6417 + { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
6418 + -NF_ACCEPT - 1 } },
6420 + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
6422 + sizeof(struct ipt_entry),
6423 + sizeof(struct ipt_standard),
6424 + 0, { 0, 0 }, { } },
6425 + { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
6426 + -NF_ACCEPT - 1 } }
6429 + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
6431 + sizeof(struct ipt_entry),
6432 + sizeof(struct ipt_error),
6433 + 0, { 0, 0 }, { } },
6434 + { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },
6441 +static struct ipt_table packet_raw = {
6443 + .table = &initial_table.repl,
6444 + .valid_hooks = RAW_VALID_HOOKS,
6445 + .lock = RW_LOCK_UNLOCKED,
6449 +/* The work comes in here from netfilter.c. */
6450 +static unsigned int
6451 +ipt_hook(unsigned int hook,
6452 + struct sk_buff **pskb,
6453 + const struct net_device *in,
6454 + const struct net_device *out,
6455 + int (*okfn)(struct sk_buff *))
6457 + return ipt_do_table(pskb, hook, in, out, &packet_raw, NULL);
6460 +/* 'raw' is the very first table. */
6461 +static struct nf_hook_ops ipt_ops[] = {
6465 + .hooknum = NF_IP_PRE_ROUTING,
6466 + .priority = NF_IP_PRI_RAW
6471 + .hooknum = NF_IP_LOCAL_OUT,
6472 + .priority = NF_IP_PRI_RAW
6476 +static int __init init(void)
6480 + /* Register table */
6481 + ret = ipt_register_table(&packet_raw);
6485 + /* Register hooks */
6486 + ret = nf_register_hook(&ipt_ops[0]);
6488 + goto cleanup_table;
6490 + ret = nf_register_hook(&ipt_ops[1]);
6492 + goto cleanup_hook0;
6497 + nf_unregister_hook(&ipt_ops[0]);
6499 + ipt_unregister_table(&packet_raw);
6504 +static void __exit fini(void)
6508 + for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++)
6509 + nf_unregister_hook(&ipt_ops[i]);
6511 + ipt_unregister_table(&packet_raw);
6516 +MODULE_LICENSE("GPL");
6517 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/Kconfig linux-2.6.5-rc2/net/ipv6/netfilter/Kconfig
6518 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/Kconfig 2004-03-20 00:11:42.000000000 +0000
6519 +++ linux-2.6.5-rc2/net/ipv6/netfilter/Kconfig 2004-03-22 08:29:50.000000000 +0000
6520 @@ -218,5 +218,42 @@
6521 To compile it as a module, choose M here. If unsure, say N.
6523 #dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
6524 +config IP6_NF_TARGET_HL
6525 + tristate 'HL target support'
6526 + depends on IP6_NF_MANGLE
6529 +config IP6_NF_TARGET_REJECT
6530 + tristate 'REJECT target support'
6531 + depends on IP6_NF_FILTER
6534 +config IP6_NF_MATCH_FUZZY
6535 + tristate 'Fuzzy match support'
6536 + depends on IP6_NF_FILTER
6539 +config IP6_NF_MATCH_NTH
6540 + tristate 'Nth match support'
6541 + depends on IP6_NF_IPTABLES
6544 +config IP6_NF_MATCH_RANDOM
6545 + tristate 'Random match support'
6546 + depends on IP6_NF_IPTABLES
6550 + tristate 'raw table support (required for TRACE)'
6551 + depends on IP6_NF_IPTABLES
6553 + This option adds a `raw' table to ip6tables. This table is the very
6554 + first in the netfilter framework and hooks in at the PREROUTING
6555 + and OUTPUT chains.
6557 + If you want to compile it as a module, say M here and read
6558 + <file:Documentation/modules.txt>. If unsure, say `N'.
6563 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/Makefile linux-2.6.5-rc2/net/ipv6/netfilter/Makefile
6564 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/Makefile 2004-03-20 00:11:32.000000000 +0000
6565 +++ linux-2.6.5-rc2/net/ipv6/netfilter/Makefile 2004-03-22 08:29:50.000000000 +0000
6567 obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
6568 obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
6569 obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
6570 +obj-$(CONFIG_IP6_NF_MATCH_FUZZY) += ip6t_fuzzy.o
6571 obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
6572 obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
6573 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
6575 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
6576 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
6577 obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
6578 +obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
6579 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
6580 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
6581 +obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
6583 +obj-$(CONFIG_IP6_NF_MATCH_RANDOM) += ip6t_random.o
6585 +obj-$(CONFIG_IP6_NF_MATCH_NTH) += ip6t_nth.o
6586 +obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
6587 obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
6588 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_HL.c linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_HL.c
6589 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_HL.c 1970-01-01 00:00:00.000000000 +0000
6590 +++ linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_HL.c 2004-03-22 08:27:23.000000000 +0000
6593 + * Hop Limit modification target for ip6tables
6594 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
6595 + * Based on HW's TTL module
6597 + * This software is distributed under the terms of GNU GPL
6600 +#include <linux/module.h>
6601 +#include <linux/skbuff.h>
6602 +#include <linux/ip.h>
6604 +#include <linux/netfilter_ipv6/ip6_tables.h>
6605 +#include <linux/netfilter_ipv6/ip6t_HL.h>
6607 +MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
6608 +MODULE_DESCRIPTION("IP tables Hop Limit modification module");
6609 +MODULE_LICENSE("GPL");
6611 +static unsigned int ip6t_hl_target(struct sk_buff **pskb, unsigned int hooknum,
6612 + const struct net_device *in, const struct net_device *out,
6613 + const void *targinfo, void *userinfo)
6615 + struct ipv6hdr *ip6h = (*pskb)->nh.ipv6h;
6616 + const struct ip6t_HL_info *info = targinfo;
6617 + u_int16_t diffs[2];
6620 + switch (info->mode) {
6622 + new_hl = info->hop_limit;
6625 + new_hl = ip6h->hop_limit + info->hop_limit;
6630 + new_hl = ip6h->hop_limit + info->hop_limit;
6635 + new_hl = ip6h->hop_limit;
6639 + if (new_hl != ip6h->hop_limit) {
6640 + diffs[0] = htons(((unsigned)ip6h->hop_limit) << 8) ^ 0xFFFF;
6641 + ip6h->hop_limit = new_hl;
6642 + diffs[1] = htons(((unsigned)ip6h->hop_limit) << 8);
6645 + return IP6T_CONTINUE;
6648 +static int ip6t_hl_checkentry(const char *tablename,
6649 + const struct ip6t_entry *e,
6651 + unsigned int targinfosize,
6652 + unsigned int hook_mask)
6654 + struct ip6t_HL_info *info = targinfo;
6656 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_HL_info))) {
6657 + printk(KERN_WARNING "HL: targinfosize %u != %Zu\n",
6659 + IP6T_ALIGN(sizeof(struct ip6t_HL_info)));
6663 + if (strcmp(tablename, "mangle")) {
6664 + printk(KERN_WARNING "HL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
6668 + if (info->mode > IP6T_HL_MAXMODE) {
6669 + printk(KERN_WARNING "HL: invalid or unknown Mode %u\n",
6674 + if ((info->mode != IP6T_HL_SET) && (info->hop_limit == 0)) {
6675 + printk(KERN_WARNING "HL: increment/decrement doesn't make sense with value 0\n");
6682 +static struct ip6t_target ip6t_HL = { { NULL, NULL }, "HL",
6683 + ip6t_hl_target, ip6t_hl_checkentry, NULL, THIS_MODULE };
6685 +static int __init init(void)
6687 + return ip6t_register_target(&ip6t_HL);
6690 +static void __exit fini(void)
6692 + ip6t_unregister_target(&ip6t_HL);
6697 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_LOG.c linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_LOG.c
6698 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_LOG.c 2004-03-20 00:11:04.000000000 +0000
6699 +++ linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_LOG.c 2004-03-22 08:27:15.000000000 +0000
6701 #include <net/udp.h>
6702 #include <net/tcp.h>
6703 #include <net/ipv6.h>
6704 +#include <linux/netfilter.h>
6705 #include <linux/netfilter_ipv6/ip6_tables.h>
6707 MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
6708 MODULE_DESCRIPTION("IP6 tables LOG target module");
6709 MODULE_LICENSE("GPL");
6711 +static unsigned int nflog = 1;
6712 +MODULE_PARM(nflog, "i");
6713 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
6716 #include <net/route.h>
6717 #include <linux/netfilter_ipv6/ip6t_LOG.h>
6718 @@ -265,40 +270,38 @@
6722 -static unsigned int
6723 -ip6t_log_target(struct sk_buff **pskb,
6724 - unsigned int hooknum,
6726 +ip6t_log_packet(unsigned int hooknum,
6727 + const struct sk_buff *skb,
6728 const struct net_device *in,
6729 const struct net_device *out,
6730 - const void *targinfo,
6732 + const struct ip6t_log_info *loginfo,
6733 + const char *level_string,
6734 + const char *prefix)
6736 - struct ipv6hdr *ipv6h = (*pskb)->nh.ipv6h;
6737 - const struct ip6t_log_info *loginfo = targinfo;
6738 - char level_string[4] = "< >";
6739 + struct ipv6hdr *ipv6h = skb->nh.ipv6h;
6741 - level_string[1] = '0' + (loginfo->level % 8);
6742 spin_lock_bh(&log_lock);
6743 printk(level_string);
6744 printk("%sIN=%s OUT=%s ",
6746 + prefix == NULL ? loginfo->prefix : prefix,
6748 out ? out->name : "");
6750 /* MAC logging for input chain only. */
6752 - if ((*pskb)->dev && (*pskb)->dev->hard_header_len && (*pskb)->mac.raw != (void*)ipv6h) {
6753 - if ((*pskb)->dev->type != ARPHRD_SIT){
6754 + if (skb->dev && skb->dev->hard_header_len && skb->mac.raw != (void*)ipv6h) {
6755 + if (skb->dev->type != ARPHRD_SIT){
6757 - unsigned char *p = (*pskb)->mac.raw;
6758 - for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++)
6759 + unsigned char *p = skb->mac.raw;
6760 + for (i = 0; i < skb->dev->hard_header_len; i++,p++)
6761 printk("%02x%c", *p,
6762 - i==(*pskb)->dev->hard_header_len - 1
6763 + i==skb->dev->hard_header_len - 1
6767 - unsigned char *p = (*pskb)->mac.raw;
6768 - if ( p - (ETH_ALEN*2+2) > (*pskb)->head ){
6769 + unsigned char *p = skb->mac.raw;
6770 + if ( p - (ETH_ALEN*2+2) > skb->head ){
6772 for (i = 0; i < (ETH_ALEN); i++,p++)
6773 printk("%02x%s", *p,
6774 @@ -309,10 +312,10 @@
6775 i == ETH_ALEN-1 ? ' ' : ':');
6778 - if (((*pskb)->dev->addr_len == 4) &&
6779 - (*pskb)->dev->hard_header_len > 20){
6780 + if ((skb->dev->addr_len == 4) &&
6781 + skb->dev->hard_header_len > 20){
6783 - p = (*pskb)->mac.raw + 12;
6784 + p = skb->mac.raw + 12;
6785 for (i = 0; i < 4; i++,p++)
6787 i == 3 ? "->" : ".");
6788 @@ -328,10 +331,41 @@
6789 dump_packet(loginfo, ipv6h, 1);
6791 spin_unlock_bh(&log_lock);
6794 +static unsigned int
6795 +ip6t_log_target(struct sk_buff **pskb,
6796 + unsigned int hooknum,
6797 + const struct net_device *in,
6798 + const struct net_device *out,
6799 + const void *targinfo,
6802 + const struct ip6t_log_info *loginfo = targinfo;
6803 + char level_string[4] = "< >";
6805 + level_string[1] = '0' + (loginfo->level % 8);
6806 + ip6t_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
6808 return IP6T_CONTINUE;
6812 +ip6t_logfn(unsigned int hooknum,
6813 + const struct sk_buff *skb,
6814 + const struct net_device *in,
6815 + const struct net_device *out,
6816 + const char *prefix)
6818 + struct ip6t_log_info loginfo = {
6820 + .logflags = IP6T_LOG_MASK,
6824 + ip6t_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
6827 static int ip6t_log_checkentry(const char *tablename,
6828 const struct ip6t_entry *e,
6830 @@ -360,20 +394,27 @@
6834 -static struct ip6t_target ip6t_log_reg
6835 -= { { NULL, NULL }, "LOG", ip6t_log_target, ip6t_log_checkentry, NULL,
6837 +static struct ip6t_target ip6t_log_reg = {
6839 + .target = ip6t_log_target,
6840 + .checkentry = ip6t_log_checkentry,
6841 + .me = THIS_MODULE,
6844 static int __init init(void)
6846 if (ip6t_register_target(&ip6t_log_reg))
6849 + nf_log_register(PF_INET6, &ip6t_logfn);
6854 static void __exit fini(void)
6857 + nf_log_unregister(PF_INET6, &ip6t_logfn);
6858 ip6t_unregister_target(&ip6t_log_reg);
6861 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_REJECT.c linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_REJECT.c
6862 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_REJECT.c 1970-01-01 00:00:00.000000000 +0000
6863 +++ linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_REJECT.c 2004-03-22 08:28:02.000000000 +0000
6866 + * This is a module which is used for rejecting packets.
6867 + * Added support for customized reject packets (Jozsef Kadlecsik).
6869 + * Port to IPv6 / ip6tables (Harald Welte <laforge@gnumonks.org>)
6871 +#include <linux/config.h>
6872 +#include <linux/module.h>
6873 +#include <linux/skbuff.h>
6874 +#include <linux/icmpv6.h>
6875 +#include <net/tcp.h>
6876 +#include <linux/netfilter_ipv6/ip6_tables.h>
6877 +#include <linux/netfilter_ipv6/ip6t_REJECT.h>
6880 +#define DEBUGP printk
6882 +#define DEBUGP(format, args...)
6886 +/* Send RST reply */
6887 +static void send_reset(struct sk_buff *oldskb)
6889 + struct sk_buff *nskb;
6890 + struct tcphdr *otcph, *tcph;
6891 + struct rtable *rt;
6892 + unsigned int otcplen;
6895 + /* IP header checks: fragment, too short. */
6896 + if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)
6897 + || oldskb->len < (oldskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
6900 + otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl);
6901 + otcplen = oldskb->len - oldskb->nh.iph->ihl*4;
6903 + /* No RST for RST. */
6907 + /* Check checksum. */
6908 + if (tcp_v4_check(otcph, otcplen, oldskb->nh.iph->saddr,
6909 + oldskb->nh.iph->daddr,
6910 + csum_partial((char *)otcph, otcplen, 0)) != 0)
6913 + /* Copy skb (even if skb is about to be dropped, we can't just
6914 + clone it because there may be other things, such as tcpdump,
6915 + interested in it) */
6916 + nskb = skb_copy(oldskb, GFP_ATOMIC);
6920 + /* This packet will not be the same as the other: clear nf fields */
6921 + nf_conntrack_put(nskb->nfct);
6922 + nskb->nfct = NULL;
6923 + nskb->nfcache = 0;
6924 +#ifdef CONFIG_NETFILTER_DEBUG
6925 + nskb->nf_debug = 0;
6928 + tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
6930 + nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
6931 + tcph->source = xchg(&tcph->dest, tcph->source);
6933 + /* Truncate to length (no data) */
6934 + tcph->doff = sizeof(struct tcphdr)/4;
6935 + skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
6936 + nskb->nh.iph->tot_len = htons(nskb->len);
6940 + tcph->seq = otcph->ack_seq;
6941 + tcph->ack_seq = 0;
6944 + tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin
6945 + + otcplen - (otcph->doff<<2));
6950 + ((u_int8_t *)tcph)[13] = 0;
6952 + tcph->ack = needs_ack;
6955 + tcph->urg_ptr = 0;
6957 + /* Adjust TCP checksum */
6959 + tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
6960 + nskb->nh.iph->saddr,
6961 + nskb->nh.iph->daddr,
6962 + csum_partial((char *)tcph,
6963 + sizeof(struct tcphdr), 0));
6965 + /* Adjust IP TTL, DF */
6966 + nskb->nh.iph->ttl = MAXTTL;
6967 + /* Set DF, id = 0 */
6968 + nskb->nh.iph->frag_off = htons(IP_DF);
6969 + nskb->nh.iph->id = 0;
6971 + /* Adjust IP checksum */
6972 + nskb->nh.iph->check = 0;
6973 + nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
6974 + nskb->nh.iph->ihl);
6977 + if (ip_route_output(&rt, nskb->nh.iph->daddr, nskb->nh.iph->saddr,
6978 + RT_TOS(nskb->nh.iph->tos) | RTO_CONN,
6982 + dst_release(nskb->dst);
6983 + nskb->dst = &rt->u.dst;
6985 + /* "Never happens" */
6986 + if (nskb->len > nskb->dst->pmtu)
6989 + NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
6990 + ip_finish_output);
6998 +static unsigned int reject6_target(struct sk_buff **pskb,
6999 + unsigned int hooknum,
7000 + const struct net_device *in,
7001 + const struct net_device *out,
7002 + const void *targinfo,
7005 + const struct ip6t_reject_info *reject = targinfo;
7007 + /* WARNING: This code causes reentry within ip6tables.
7008 + This means that the ip6tables jump stack is now crap. We
7009 + must return an absolute verdict. --RR */
7010 + DEBUGP("REJECTv6: calling icmpv6_send\n");
7011 + switch (reject->with) {
7012 + case IP6T_ICMP6_NO_ROUTE:
7013 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, out);
7015 + case IP6T_ICMP6_ADM_PROHIBITED:
7016 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADM_PROHIBITED, 0, out);
7018 + case IP6T_ICMP6_NOT_NEIGHBOUR:
7019 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOT_NEIGHBOUR, 0, out);
7021 + case IP6T_ICMP6_ADDR_UNREACH:
7022 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, out);
7024 + case IP6T_ICMP6_PORT_UNREACH:
7025 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, out);
7028 + case IPT_ICMP_ECHOREPLY: {
7029 + struct icmp6hdr *icmph = (struct icmphdr *)
7030 + ((u_int32_t *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl);
7031 + unsigned int datalen = (*pskb)->len - (*pskb)->nh.iph->ihl * 4;
7033 + /* Not non-head frags, or truncated */
7034 + if (((ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET) == 0)
7035 + && datalen >= 4) {
7036 + /* Usually I don't like cut & pasting code,
7037 + but dammit, my party is starting in 45
7039 + struct icmp_bxm icmp_param;
7041 + icmp_param.icmph=*icmph;
7042 + icmp_param.icmph.type=ICMP_ECHOREPLY;
7043 + icmp_param.data_ptr=(icmph+1);
7044 + icmp_param.data_len=datalen;
7045 + icmp_reply(&icmp_param, *pskb);
7049 + case IPT_TCP_RESET:
7050 + send_reset(*pskb);
7054 + printk(KERN_WARNING "REJECTv6: case %u not handled yet\n", reject->with);
7061 +static inline int find_ping_match(const struct ip6t_entry_match *m)
7063 + const struct ip6t_icmp *icmpinfo = (const struct ip6t_icmp *)m->data;
7065 + if (strcmp(m->u.kernel.match->name, "icmp6") == 0
7066 + && icmpinfo->type == ICMPV6_ECHO_REQUEST
7067 + && !(icmpinfo->invflags & IP6T_ICMP_INV))
7073 +static int check(const char *tablename,
7074 + const struct ip6t_entry *e,
7076 + unsigned int targinfosize,
7077 + unsigned int hook_mask)
7079 + const struct ip6t_reject_info *rejinfo = targinfo;
7081 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
7082 + DEBUGP("REJECTv6: targinfosize %u != 0\n", targinfosize);
7086 + /* Only allow these for packet filtering. */
7087 + if (strcmp(tablename, "filter") != 0) {
7088 + DEBUGP("REJECTv6: bad table `%s'.\n", tablename);
7091 + if ((hook_mask & ~((1 << NF_IP6_LOCAL_IN)
7092 + | (1 << NF_IP6_FORWARD)
7093 + | (1 << NF_IP6_LOCAL_OUT))) != 0) {
7094 + DEBUGP("REJECTv6: bad hook mask %X\n", hook_mask);
7098 + if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
7099 + /* Must specify that it's an ICMP ping packet. */
7100 + if (e->ipv6.proto != IPPROTO_ICMPV6
7101 + || (e->ipv6.invflags & IP6T_INV_PROTO)) {
7102 + DEBUGP("REJECTv6: ECHOREPLY illegal for non-icmp\n");
7105 + /* Must contain ICMP match. */
7106 + if (IP6T_MATCH_ITERATE(e, find_ping_match) == 0) {
7107 + DEBUGP("REJECTv6: ECHOREPLY illegal for non-ping\n");
7110 + } else if (rejinfo->with == IP6T_TCP_RESET) {
7111 + /* Must specify that it's a TCP packet */
7112 + if (e->ipv6.proto != IPPROTO_TCP
7113 + || (e->ipv6.invflags & IP6T_INV_PROTO)) {
7114 + DEBUGP("REJECTv6: TCP_RESET illegal for non-tcp\n");
7122 +static struct ip6t_target ip6t_reject_reg
7123 += { { NULL, NULL }, "REJECT", reject6_target, check, NULL, THIS_MODULE };
7125 +static int __init init(void)
7127 + if (ip6t_register_target(&ip6t_reject_reg))
7132 +static void __exit fini(void)
7134 + ip6t_unregister_target(&ip6t_reject_reg);
7139 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_fuzzy.c linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_fuzzy.c
7140 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_fuzzy.c 1970-01-01 00:00:00.000000000 +0000
7141 +++ linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_fuzzy.c 2004-03-22 08:28:32.000000000 +0000
7144 + * This module implements a simple TSK FLC
7145 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
7146 + * to limit , in an adaptive and flexible way , the packet rate crossing
7147 + * a given stream . It serves as an initial and very simple (but effective)
7148 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
7149 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
7150 + * into our code in a precise , adaptive and efficient manner.
7151 + * The goal is very similar to that of "limit" match , but using techniques of
7152 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
7153 + * avoiding over and undershoots - and stuff like that .
7156 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
7157 + * 2002-08-17 : Changed to eliminate floating point operations .
7158 + * 2002-08-23 : Coding style changes .
7159 + * 2003-04-08 Maciej Soltysiak <solt@dns.toxicilms.tv> : IPv6 Port
7162 +#include <linux/module.h>
7163 +#include <linux/skbuff.h>
7164 +#include <linux/ipv6.h>
7165 +#include <linux/random.h>
7166 +#include <net/tcp.h>
7167 +#include <linux/spinlock.h>
7168 +#include <linux/netfilter_ipv6/ip6_tables.h>
7169 +#include <linux/netfilter_ipv6/ip6t_fuzzy.h>
7172 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
7173 + Expressed in percentage
7176 +#define PAR_LOW 1/100
7179 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED;
7181 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
7182 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
7183 +MODULE_LICENSE("GPL");
7185 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
7187 + if (tx >= maxi) return 100;
7189 + if (tx <= mini) return 0;
7191 + return ((100 * (tx-mini)) / (maxi-mini));
7194 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
7196 + if (tx <= mini) return 100;
7198 + if (tx >= maxi) return 0;
7200 + return ((100 * (maxi - tx)) / (maxi - mini));
7205 +ip6t_fuzzy_match(const struct sk_buff *pskb,
7206 + const struct net_device *in,
7207 + const struct net_device *out,
7208 + const void *matchinfo,
7211 + u_int16_t datalen,
7214 + /* From userspace */
7216 + struct ip6t_fuzzy_info *info = (struct ip6t_fuzzy_info *) matchinfo;
7218 + u_int8_t random_number;
7219 + unsigned long amount;
7220 + u_int8_t howhigh, howlow;
7223 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
7225 + info->bytes_total += pskb->len;
7226 + info->packets_total++;
7228 + info->present_time = jiffies;
7230 + if (info->present_time >= info->previous_time)
7231 + amount = info->present_time - info->previous_time;
7233 + /* There was a transition : I choose to re-sample
7234 + and keep the old acceptance rate...
7238 + info->previous_time = info->present_time;
7239 + info->bytes_total = info->packets_total = 0;
7242 + if ( amount > HZ/10) {/* More than 100 ms elapsed ... */
7244 + info->mean_rate = (u_int32_t) ((HZ * info->packets_total) \
7247 + info->previous_time = info->present_time;
7248 + info->bytes_total = info->packets_total = 0;
7250 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
7251 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
7253 + info->acceptance_rate = (u_int8_t) \
7254 + (howhigh * PAR_LOW + PAR_HIGH * howlow);
7256 + /* In fact, the above defuzzification would require a denominator
7257 + * proportional to (howhigh+howlow) but, in this particular case,
7258 + * that expression is constant.
7259 + * An imediate consequence is that it is not necessary to call
7260 + * both mf_high and mf_low - but to keep things understandable,
7266 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
7269 + if (info->acceptance_rate < 100)
7271 + get_random_bytes((void *)(&random_number), 1);
7273 + /* If within the acceptance , it can pass => don't match */
7274 + if (random_number <= (255 * info->acceptance_rate) / 100)
7277 + return 1; /* It can't pass (It matches) */
7280 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
7285 +ip6t_fuzzy_checkentry(const char *tablename,
7286 + const struct ip6t_ip6 *ip,
7288 + unsigned int matchsize,
7289 + unsigned int hook_mask)
7292 + const struct ip6t_fuzzy_info *info = matchinfo;
7294 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info))) {
7295 + printk("ip6t_fuzzy: matchsize %u != %u\n", matchsize,
7296 + IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info)));
7300 + if ((info->minimum_rate < MINFUZZYRATE) || (info->maximum_rate > MAXFUZZYRATE)
7301 + || (info->minimum_rate >= info->maximum_rate)) {
7302 + printk("ip6t_fuzzy: BAD limits , please verify !!!\n");
7309 +static struct ip6t_match ip6t_fuzzy_reg = {
7313 + ip6t_fuzzy_checkentry,
7317 +static int __init init(void)
7319 + if (ip6t_register_match(&ip6t_fuzzy_reg))
7325 +static void __exit fini(void)
7327 + ip6t_unregister_match(&ip6t_fuzzy_reg);
7332 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_nth.c linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_nth.c
7333 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_nth.c 1970-01-01 00:00:00.000000000 +0000
7334 +++ linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_nth.c 2004-03-22 08:29:02.000000000 +0000
7337 + This is a module which is used for match support for every Nth packet
7338 + This file is distributed under the terms of the GNU General Public
7339 + License (GPL). Copies of the GPL can be obtained from:
7340 + ftp://prep.ai.mit.edu/pub/gnu/GPL
7342 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
7343 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
7344 + * added support for multiple counters
7345 + * added support for matching on individual packets
7346 + in the counter cycle
7347 + 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
7351 +#include <linux/module.h>
7352 +#include <linux/skbuff.h>
7353 +#include <linux/ip.h>
7354 +#include <net/tcp.h>
7355 +#include <linux/spinlock.h>
7356 +#include <linux/netfilter_ipv6/ip6_tables.h>
7357 +#include <linux/netfilter_ipv6/ip6t_nth.h>
7359 +MODULE_LICENSE("GPL");
7362 + * State information.
7369 +static struct state states[IP6T_NTH_NUM_COUNTERS];
7372 +ip6t_nth_match(const struct sk_buff *pskb,
7373 + const struct net_device *in,
7374 + const struct net_device *out,
7375 + const void *matchinfo,
7378 + u_int16_t datalen,
7381 + /* Parameters from userspace */
7382 + const struct ip6t_nth_info *info = matchinfo;
7383 + unsigned counter = info->counter;
7384 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
7386 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
7390 + spin_lock(&states[counter].lock);
7392 + /* Are we matching every nth packet?*/
7393 + if (info->packet == 0xFF)
7395 + /* We're matching every nth packet and only every nth packet*/
7396 + /* Do we match or invert match? */
7397 + if (info->not == 0)
7399 + if (states[counter].number == 0)
7401 + ++states[counter].number;
7404 + if (states[counter].number >= info->every)
7405 + states[counter].number = 0; /* reset the counter */
7407 + ++states[counter].number;
7412 + if (states[counter].number == 0)
7414 + ++states[counter].number;
7417 + if (states[counter].number >= info->every)
7418 + states[counter].number = 0;
7420 + ++states[counter].number;
7426 + /* We're using the --packet, so there must be a rule for every value */
7427 + if (states[counter].number == info->packet)
7429 + /* only increment the counter when a match happens */
7430 + if (states[counter].number >= info->every)
7431 + states[counter].number = 0; /* reset the counter */
7433 + ++states[counter].number;
7442 + spin_unlock(&states[counter].lock);
7446 + spin_unlock(&states[counter].lock);
7451 +ip6t_nth_checkentry(const char *tablename,
7452 + const struct ip6t_ip6 *e,
7454 + unsigned int matchsize,
7455 + unsigned int hook_mask)
7457 + /* Parameters from userspace */
7458 + const struct ip6t_nth_info *info = matchinfo;
7459 + unsigned counter = info->counter;
7460 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
7462 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
7466 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_nth_info))) {
7467 + printk("nth: matchsize %u != %u\n", matchsize,
7468 + IP6T_ALIGN(sizeof(struct ip6t_nth_info)));
7472 + states[counter].number = info->startat;
7477 +static struct ip6t_match ip6t_nth_reg = {
7481 + ip6t_nth_checkentry,
7485 +static int __init init(void)
7488 + memset(&states, 0, sizeof(states));
7489 + if (ip6t_register_match(&ip6t_nth_reg))
7492 + for(counter = 0; counter < IP6T_NTH_NUM_COUNTERS; counter++)
7494 + spin_lock_init(&(states[counter].lock));
7497 + printk("ip6t_nth match loaded\n");
7501 +static void __exit fini(void)
7503 + ip6t_unregister_match(&ip6t_nth_reg);
7504 + printk("ip6t_nth match unloaded\n");
7509 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_random.c linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_random.c
7510 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_random.c 1970-01-01 00:00:00.000000000 +0000
7511 +++ linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_random.c 2004-03-22 08:29:43.000000000 +0000
7514 + This is a module which is used for a "random" match support.
7515 + This file is distributed under the terms of the GNU General Public
7516 + License (GPL). Copies of the GPL can be obtained from:
7517 + ftp://prep.ai.mit.edu/pub/gnu/GPL
7519 + 2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
7520 + 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
7523 +#include <linux/module.h>
7524 +#include <linux/skbuff.h>
7525 +#include <linux/ip.h>
7526 +#include <linux/random.h>
7527 +#include <net/tcp.h>
7528 +#include <linux/spinlock.h>
7529 +#include <linux/netfilter_ipv6/ip6_tables.h>
7530 +#include <linux/netfilter_ipv6/ip6t_random.h>
7532 +MODULE_LICENSE("GPL");
7535 +ip6t_rand_match(const struct sk_buff *pskb,
7536 + const struct net_device *in,
7537 + const struct net_device *out,
7538 + const void *matchinfo,
7541 + u_int16_t datalen,
7544 + /* Parameters from userspace */
7545 + const struct ip6t_rand_info *info = matchinfo;
7546 + u_int8_t random_number;
7548 + /* get 1 random number from the kernel random number generation routine */
7549 + get_random_bytes((void *)(&random_number), 1);
7551 + /* Do we match ? */
7552 + if (random_number <= info->average)
7559 +ip6t_rand_checkentry(const char *tablename,
7560 + const struct ip6t_ip6 *e,
7562 + unsigned int matchsize,
7563 + unsigned int hook_mask)
7565 + /* Parameters from userspace */
7566 + const struct ip6t_rand_info *info = matchinfo;
7568 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_rand_info))) {
7569 + printk("ip6t_random: matchsize %u != %u\n", matchsize,
7570 + IP6T_ALIGN(sizeof(struct ip6t_rand_info)));
7574 + /* must be 1 <= average % <= 99 */
7575 + /* 1 x 2.55 = 2 */
7576 + /* 99 x 2.55 = 252 */
7577 + if ((info->average < 2) || (info->average > 252)) {
7578 + printk("ip6t_random: invalid average %u\n", info->average);
7585 +static struct ip6t_match ip6t_rand_reg = {
7589 + ip6t_rand_checkentry,
7593 +static int __init init(void)
7595 + if (ip6t_register_match(&ip6t_rand_reg))
7598 + printk("ip6t_random match loaded\n");
7602 +static void __exit fini(void)
7604 + ip6t_unregister_match(&ip6t_rand_reg);
7605 + printk("ip6t_random match unloaded\n");
7610 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6table_raw.c linux-2.6.5-rc2/net/ipv6/netfilter/ip6table_raw.c
7611 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6table_raw.c 1970-01-01 00:00:00.000000000 +0000
7612 +++ linux-2.6.5-rc2/net/ipv6/netfilter/ip6table_raw.c 2004-03-22 08:29:50.000000000 +0000
7615 + * IPv6 raw table, a port of the IPv4 raw table to IPv6
7617 + * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
7619 +#include <linux/module.h>
7620 +#include <linux/netfilter_ipv6/ip6_tables.h>
7622 +#define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT))
7625 +#define DEBUGP(x, args...) printk(KERN_DEBUG x, ## args)
7627 +#define DEBUGP(x, args...)
7630 +/* Standard entry. */
7631 +struct ip6t_standard
7633 + struct ip6t_entry entry;
7634 + struct ip6t_standard_target target;
7637 +struct ip6t_error_target
7639 + struct ip6t_entry_target target;
7640 + char errorname[IP6T_FUNCTION_MAXNAMELEN];
7645 + struct ip6t_entry entry;
7646 + struct ip6t_error_target target;
7651 + struct ip6t_replace repl;
7652 + struct ip6t_standard entries[2];
7653 + struct ip6t_error term;
7654 +} initial_table __initdata
7655 += { { "raw", RAW_VALID_HOOKS, 3,
7656 + sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error),
7657 + { [NF_IP6_PRE_ROUTING] 0,
7658 + [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) },
7659 + { [NF_IP6_PRE_ROUTING] 0,
7660 + [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) },
7664 + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
7666 + sizeof(struct ip6t_entry),
7667 + sizeof(struct ip6t_standard),
7668 + 0, { 0, 0 }, { } },
7669 + { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
7670 + -NF_ACCEPT - 1 } },
7672 + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
7674 + sizeof(struct ip6t_entry),
7675 + sizeof(struct ip6t_standard),
7676 + 0, { 0, 0 }, { } },
7677 + { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
7678 + -NF_ACCEPT - 1 } },
7681 + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
7683 + sizeof(struct ip6t_entry),
7684 + sizeof(struct ip6t_error),
7685 + 0, { 0, 0 }, { } },
7686 + { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } },
7693 +static struct ip6t_table packet_raw = {
7695 + .table = &initial_table.repl,
7696 + .valid_hooks = RAW_VALID_HOOKS,
7697 + .lock = RW_LOCK_UNLOCKED,
7701 +/* The work comes in here from netfilter.c. */
7702 +static unsigned int
7703 +ip6t_hook(unsigned int hook,
7704 + struct sk_buff **pskb,
7705 + const struct net_device *in,
7706 + const struct net_device *out,
7707 + int (*okfn)(struct sk_buff *))
7709 + return ip6t_do_table(pskb, hook, in, out, &packet_raw, NULL);
7712 +static struct nf_hook_ops ip6t_ops[] = {
7714 + .hook = ip6t_hook,
7716 + .hooknum = NF_IP6_PRE_ROUTING,
7717 + .priority = NF_IP6_PRI_FIRST
7720 + .hook = ip6t_hook,
7722 + .hooknum = NF_IP6_LOCAL_OUT,
7723 + .priority = NF_IP6_PRI_FIRST
7727 +static int __init init(void)
7731 + /* Register table */
7732 + ret = ip6t_register_table(&packet_raw);
7736 + /* Register hooks */
7737 + ret = nf_register_hook(&ip6t_ops[0]);
7739 + goto cleanup_table;
7741 + ret = nf_register_hook(&ip6t_ops[1]);
7743 + goto cleanup_hook0;
7748 + nf_unregister_hook(&ip6t_ops[0]);
7750 + ip6t_unregister_table(&packet_raw);
7755 +static void __exit fini(void)
7759 + for (i = 0; i < sizeof(ip6t_ops)/sizeof(struct nf_hook_ops); i++)
7760 + nf_unregister_hook(&ip6t_ops[i]);
7762 + ip6t_unregister_table(&packet_raw);
7767 +MODULE_LICENSE("GPL");