1 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter.h linux-2.6.5-rc1/include/linux/netfilter.h
2 --- linux-2.6.5-rc1.org/include/linux/netfilter.h 2004-03-16 05:46:35.000000000 +0000
3 +++ linux-2.6.5-rc1/include/linux/netfilter.h 2004-03-16 11:53:42.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-rc1.org/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack.h
30 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-16 05:47:19.000000000 +0000
31 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-16 11:53:55.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-rc1.org/include/linux/netfilter_ipv4/ipt_TTL.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_TTL.h
43 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_TTL.h 1970-01-01 00:00:00.000000000 +0000
44 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_TTL.h 2004-03-16 11:53:46.000000000 +0000
46 +/* TTL modification module for IP tables
47 + * (C) 2000 by Harald Welte <laforge@gnumonks.org> */
58 +#define IPT_TTL_MAXMODE IPT_TTL_DEC
60 +struct ipt_TTL_info {
67 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_ULOG.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_ULOG.h
68 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_ULOG.h 2004-03-16 05:46:09.000000000 +0000
69 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_ULOG.h 2004-03-16 11:53:42.000000000 +0000
71 #define NETLINK_NFLOG 5
74 +#define ULOG_DEFAULT_NLGROUP 1
75 +#define ULOG_DEFAULT_QTHRESHOLD 1
77 #define ULOG_MAC_LEN 80
78 #define ULOG_PREFIX_LEN 32
80 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_connlimit.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_connlimit.h
81 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_connlimit.h 1970-01-01 00:00:00.000000000 +0000
82 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_connlimit.h 2004-03-16 11:53:47.000000000 +0000
84 +#ifndef _IPT_CONNLIMIT_H
85 +#define _IPT_CONNLIMIT_H
87 +struct ipt_connlimit_data;
89 +struct ipt_connlimit_info {
93 + struct ipt_connlimit_data *data;
95 +#endif /* _IPT_CONNLIMIT_H */
96 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_conntrack.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_conntrack.h
97 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_conntrack.h 2004-03-16 05:47:04.000000000 +0000
98 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_conntrack.h 2004-03-16 11:53:55.000000000 +0000
101 #define IPT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1))
102 #define IPT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2))
103 +#define IPT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3))
105 /* flags, invflags: */
106 #define IPT_CONNTRACK_STATE 0x01
107 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_dstlimit.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_dstlimit.h
108 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_dstlimit.h 1970-01-01 00:00:00.000000000 +0000
109 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_dstlimit.h 2004-03-16 11:53:48.000000000 +0000
111 +#ifndef _IPT_DSTLIMIT_H
112 +#define _IPT_DSTLIMIT_H
114 +/* timings are in milliseconds. */
115 +#define IPT_DSTLIMIT_SCALE 10000
116 +/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490
117 + seconds, or one every 59 hours. */
119 +/* details of this structure hidden by the implementation */
120 +struct ipt_dstlimit_htable;
122 +#define IPT_DSTLIMIT_HASH_DIP 0x0001
123 +#define IPT_DSTLIMIT_HASH_DPT 0x0002
124 +#define IPT_DSTLIMIT_HASH_SIP 0x0004
126 +struct dstlimit_cfg {
127 + u_int32_t mode; /* bitmask of IPT_DSTLIMIT_HASH_* */
128 + u_int32_t avg; /* Average secs between packets * scale */
129 + u_int32_t burst; /* Period multiplier for upper limit. */
131 + /* user specified */
132 + u_int32_t size; /* how many buckets */
133 + u_int32_t max; /* max number of entries */
134 + u_int32_t gc_interval; /* gc interval */
135 + u_int32_t expire; /* when do entries expire? */
138 +struct ipt_dstlimit_info {
139 + char name [IFNAMSIZ]; /* name */
140 + struct dstlimit_cfg cfg;
141 + struct ipt_dstlimit_htable *hinfo;
143 + /* Used internally by the kernel */
146 + struct ipt_dstlimit_info *master;
149 +#endif /*_IPT_DSTLIMIT_H*/
150 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_fuzzy.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_fuzzy.h
151 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_fuzzy.h 1970-01-01 00:00:00.000000000 +0000
152 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_fuzzy.h 2004-03-16 11:53:50.000000000 +0000
154 +#ifndef _IPT_FUZZY_H
155 +#define _IPT_FUZZY_H
157 +#include <linux/param.h>
158 +#include <linux/types.h>
160 +#define MAXFUZZYRATE 10000000
161 +#define MINFUZZYRATE 3
163 +struct ipt_fuzzy_info {
164 + u_int32_t minimum_rate;
165 + u_int32_t maximum_rate;
166 + u_int32_t packets_total;
167 + u_int32_t bytes_total;
168 + u_int32_t previous_time;
169 + u_int32_t present_time;
170 + u_int32_t mean_rate;
171 + u_int8_t acceptance_rate;
174 +#endif /*_IPT_FUZZY_H*/
175 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_ipv4options.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_ipv4options.h
176 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_ipv4options.h 1970-01-01 00:00:00.000000000 +0000
177 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_ipv4options.h 2004-03-16 11:53:51.000000000 +0000
179 +#ifndef __ipt_ipv4options_h_included__
180 +#define __ipt_ipv4options_h_included__
182 +#define IPT_IPV4OPTION_MATCH_SSRR 0x01 /* For strict source routing */
183 +#define IPT_IPV4OPTION_MATCH_LSRR 0x02 /* For loose source routing */
184 +#define IPT_IPV4OPTION_DONT_MATCH_SRR 0x04 /* any source routing */
185 +#define IPT_IPV4OPTION_MATCH_RR 0x08 /* For Record route */
186 +#define IPT_IPV4OPTION_DONT_MATCH_RR 0x10
187 +#define IPT_IPV4OPTION_MATCH_TIMESTAMP 0x20 /* For timestamp request */
188 +#define IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP 0x40
189 +#define IPT_IPV4OPTION_MATCH_ROUTER_ALERT 0x80 /* For router-alert */
190 +#define IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT 0x100
191 +#define IPT_IPV4OPTION_MATCH_ANY_OPT 0x200 /* match packet with any option */
192 +#define IPT_IPV4OPTION_DONT_MATCH_ANY_OPT 0x400 /* match packet with no option */
194 +struct ipt_ipv4options_info {
199 +#endif /* __ipt_ipv4options_h_included__ */
200 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_mport.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_mport.h
201 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_mport.h 1970-01-01 00:00:00.000000000 +0000
202 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_mport.h 2004-03-16 11:53:52.000000000 +0000
204 +#ifndef _IPT_MPORT_H
205 +#define _IPT_MPORT_H
206 +#include <linux/netfilter_ipv4/ip_tables.h>
208 +#define IPT_MPORT_SOURCE (1<<0)
209 +#define IPT_MPORT_DESTINATION (1<<1)
210 +#define IPT_MPORT_EITHER (IPT_MPORT_SOURCE|IPT_MPORT_DESTINATION)
212 +#define IPT_MULTI_PORTS 15
214 +/* Must fit inside union ipt_matchinfo: 32 bytes */
215 +/* every entry in ports[] except for the last one has one bit in pflags
216 + * associated with it. If this bit is set, the port is the first port of
217 + * a portrange, with the next entry being the last.
218 + * End of list is marked with pflags bit set and port=65535.
219 + * If 14 ports are used (last one does not have a pflag), the last port
220 + * is repeated to fill the last entry in ports[] */
223 + u_int8_t flags:2; /* Type of comparison */
224 + u_int16_t pflags:14; /* Port flags */
225 + u_int16_t ports[IPT_MULTI_PORTS]; /* Ports */
227 +#endif /*_IPT_MPORT_H*/
228 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_nth.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_nth.h
229 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_nth.h 1970-01-01 00:00:00.000000000 +0000
230 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_nth.h 2004-03-16 11:53:53.000000000 +0000
235 +#include <linux/param.h>
236 +#include <linux/types.h>
238 +#ifndef IPT_NTH_NUM_COUNTERS
239 +#define IPT_NTH_NUM_COUNTERS 16
242 +struct ipt_nth_info {
250 +#endif /*_IPT_NTH_H*/
251 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_quota.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_quota.h
252 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_quota.h 1970-01-01 00:00:00.000000000 +0000
253 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_quota.h 2004-03-16 11:53:54.000000000 +0000
255 +#ifndef _IPT_QUOTA_H
256 +#define _IPT_QUOTA_H
258 +/* print debug info in both kernel/netfilter module & iptable library */
259 +//#define DEBUG_IPT_QUOTA
261 +struct ipt_quota_info {
265 +#endif /*_IPT_QUOTA_H*/
266 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_realm.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_realm.h
267 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_realm.h 1970-01-01 00:00:00.000000000 +0000
268 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_realm.h 2004-03-16 11:53:56.000000000 +0000
270 +#ifndef _IPT_REALM_H
271 +#define _IPT_REALM_H
273 +struct ipt_realm_info {
278 +#endif /*_IPT_REALM_H*/
279 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_sctp.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_sctp.h
280 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_sctp.h 1970-01-01 00:00:00.000000000 +0000
281 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_sctp.h 2004-03-16 11:53:57.000000000 +0000
283 +#ifndef _IPT_SCTP_H_
284 +#define _IPT_SCTP_H_
286 +#define IPT_SCTP_SRC_PORTS 0x01
287 +#define IPT_SCTP_DEST_PORTS 0x02
288 +#define IPT_SCTP_CHUNK_TYPES 0x04
290 +#define IPT_SCTP_VALID_FLAGS 0x07
292 +#define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0]))
295 +struct ipt_sctp_flag_info {
296 + u_int8_t chunktype;
298 + u_int8_t flag_mask;
301 +#define IPT_NUM_SCTP_FLAGS 4
303 +struct ipt_sctp_info {
304 + u_int16_t dpts[2]; /* Min, Max */
305 + u_int16_t spts[2]; /* Min, Max */
307 + u_int32_t chunkmap[256 / sizeof (u_int32_t)]; /* Bit mask of chunks to be matched according to RFC 2960 */
309 +#define SCTP_CHUNK_MATCH_ANY 0x01 /* Match if any of the chunk types are present */
310 +#define SCTP_CHUNK_MATCH_ALL 0x02 /* Match if all of the chunk types are present */
311 +#define SCTP_CHUNK_MATCH_ONLY 0x04 /* Match if these are the only chunk types present */
313 + u_int32_t chunk_match_type;
314 + struct ipt_sctp_flag_info flag_info[IPT_NUM_SCTP_FLAGS];
318 + u_int32_t invflags;
321 +#define bytes(type) (sizeof(type) * 8)
323 +#define SCTP_CHUNKMAP_SET(chunkmap, type) \
325 + chunkmap[type / bytes(u_int32_t)] |= \
326 + 1 << (type % bytes(u_int32_t)); \
329 +#define SCTP_CHUNKMAP_CLEAR(chunkmap, type) \
331 + chunkmap[type / bytes(u_int32_t)] &= \
332 + ~(1 << (type % bytes(u_int32_t))); \
335 +#define SCTP_CHUNKMAP_IS_SET(chunkmap, type) \
337 + (chunkmap[type / bytes (u_int32_t)] & \
338 + (1 << (type % bytes (u_int32_t)))) ? 1: 0; \
341 +#define SCTP_CHUNKMAP_RESET(chunkmap) \
344 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
348 +#define SCTP_CHUNKMAP_SET_ALL(chunkmap) \
351 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
352 + chunkmap[i] = ~0; \
355 +#define SCTP_CHUNKMAP_COPY(destmap, srcmap) \
358 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
359 + destmap[i] = srcmap[i]; \
362 +#define SCTP_CHUNKMAP_IS_CLEAR(chunkmap) \
366 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \
367 + if (chunkmap[i]) { \
375 +#define SCTP_CHUNKMAP_IS_ALL_SET(chunkmap) \
379 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \
380 + if (chunkmap[i] != ~0) { \
388 +#endif /* _IPT_SCTP_H_ */
390 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_state.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_state.h
391 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_state.h 2004-03-16 05:47:18.000000000 +0000
392 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_state.h 2004-03-16 11:53:55.000000000 +0000
394 #define IPT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
395 #define IPT_STATE_INVALID (1 << 0)
397 +#define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1))
399 struct ipt_state_info
401 unsigned int statemask;
402 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_u32.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_u32.h
403 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_u32.h 1970-01-01 00:00:00.000000000 +0000
404 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_u32.h 2004-03-16 11:53:58.000000000 +0000
408 +#include <linux/netfilter_ipv4/ip_tables.h>
418 +struct ipt_u32_location_element
423 +struct ipt_u32_value_element
428 +/* *** any way to allow for an arbitrary number of elements?
429 + for now I settle for a limit of 10 of each */
430 +#define U32MAXSIZE 10
434 + struct ipt_u32_location_element location[U32MAXSIZE+1];
436 + struct ipt_u32_value_element value[U32MAXSIZE+1];
442 + struct ipt_u32_test tests[U32MAXSIZE+1];
445 +#endif /*_IPT_U32_H*/
446 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4.h linux-2.6.5-rc1/include/linux/netfilter_ipv4.h
447 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4.h 2004-03-16 05:47:18.000000000 +0000
448 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4.h 2004-03-16 11:53:55.000000000 +0000
451 enum nf_ip_hook_priorities {
452 NF_IP_PRI_FIRST = INT_MIN,
453 + NF_IP_PRI_CONNTRACK_DEFRAG = -400,
454 + NF_IP_PRI_RAW = -300,
455 NF_IP_PRI_SELINUX_FIRST = -225,
456 NF_IP_PRI_CONNTRACK = -200,
457 NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
458 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv6/ip6t_HL.h linux-2.6.5-rc1/include/linux/netfilter_ipv6/ip6t_HL.h
459 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv6/ip6t_HL.h 1970-01-01 00:00:00.000000000 +0000
460 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv6/ip6t_HL.h 2004-03-16 11:53:43.000000000 +0000
462 +/* Hop Limit modification module for ip6tables
463 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
464 + * Based on HW's TTL module */
475 +#define IP6T_HL_MAXMODE IP6T_HL_DEC
477 +struct ip6t_HL_info {
479 + u_int8_t hop_limit;
484 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv6/ip6t_REJECT.h linux-2.6.5-rc1/include/linux/netfilter_ipv6/ip6t_REJECT.h
485 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-03-16 05:45:18.000000000 +0000
486 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-03-16 11:53:45.000000000 +0000
488 #define _IP6T_REJECT_H
490 enum ip6t_reject_with {
491 - IP6T_ICMP_NET_UNREACHABLE,
492 - IP6T_ICMP_HOST_UNREACHABLE,
493 - IP6T_ICMP_PROT_UNREACHABLE,
494 - IP6T_ICMP_PORT_UNREACHABLE,
495 - IP6T_ICMP_ECHOREPLY
496 + IP6T_ICMP6_NO_ROUTE,
497 + IP6T_ICMP6_ADM_PROHIBITED,
498 + IP6T_ICMP6_NOT_NEIGHBOUR,
499 + IP6T_ICMP6_ADDR_UNREACH,
500 + IP6T_ICMP6_PORT_UNREACH,
501 + IP6T_ICMP6_ECHOREPLY,
505 struct ip6t_reject_info {
506 enum ip6t_reject_with with; /* reject type */
509 -#endif /*_IPT_REJECT_H*/
510 +#endif /*_IP6T_REJECT_H*/
511 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h linux-2.6.5-rc1/include/linux/netfilter_ipv6/ip6t_fuzzy.h
512 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h 1970-01-01 00:00:00.000000000 +0000
513 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv6/ip6t_fuzzy.h 2004-03-16 11:53:50.000000000 +0000
515 +#ifndef _IP6T_FUZZY_H
516 +#define _IP6T_FUZZY_H
518 +#include <linux/param.h>
519 +#include <linux/types.h>
521 +#define MAXFUZZYRATE 10000000
522 +#define MINFUZZYRATE 3
524 +struct ip6t_fuzzy_info {
525 + u_int32_t minimum_rate;
526 + u_int32_t maximum_rate;
527 + u_int32_t packets_total;
528 + u_int32_t bytes_total;
529 + u_int32_t previous_time;
530 + u_int32_t present_time;
531 + u_int32_t mean_rate;
532 + u_int8_t acceptance_rate;
535 +#endif /*_IP6T_FUZZY_H*/
536 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv6/ip6t_nth.h linux-2.6.5-rc1/include/linux/netfilter_ipv6/ip6t_nth.h
537 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv6/ip6t_nth.h 1970-01-01 00:00:00.000000000 +0000
538 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv6/ip6t_nth.h 2004-03-16 11:53:53.000000000 +0000
543 +#include <linux/param.h>
544 +#include <linux/types.h>
546 +#ifndef IP6T_NTH_NUM_COUNTERS
547 +#define IP6T_NTH_NUM_COUNTERS 16
550 +struct ip6t_nth_info {
558 +#endif /*_IP6T_NTH_H*/
559 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/core/netfilter.c linux-2.6.5-rc1/net/core/netfilter.c
560 --- linux-2.6.5-rc1.org/net/core/netfilter.c 2004-03-16 05:46:34.000000000 +0000
561 +++ linux-2.6.5-rc1/net/core/netfilter.c 2004-03-16 11:53:42.000000000 +0000
564 * February 2000: Modified by James Morris to have 1 queue per protocol.
565 * 15-Mar-2000: Added NF_REPEAT --RR.
566 + * 08-May-2003: Internal logging interface added by Jozsef Kadlecsik.
568 #include <linux/config.h>
569 +#include <linux/kernel.h>
570 #include <linux/netfilter.h>
571 #include <net/protocol.h>
572 #include <linux/init.h>
574 EXPORT_SYMBOL(skb_ip_make_writable);
575 #endif /*CONFIG_INET*/
577 +/* Internal logging interface, which relies on the real
578 + LOG target modules */
580 +#define NF_LOG_PREFIXLEN 128
582 +static nf_logfn *nf_logging[NPROTO]; /* = NULL */
583 +static int reported = 0;
584 +static spinlock_t nf_log_lock = SPIN_LOCK_UNLOCKED;
586 +int nf_log_register(int pf, nf_logfn *logfn)
590 + /* Any setup of logging members must be done before
591 + * substituting pointer. */
593 + spin_lock(&nf_log_lock);
594 + if (!nf_logging[pf]) {
595 + nf_logging[pf] = logfn;
598 + spin_unlock(&nf_log_lock);
602 +void nf_log_unregister(int pf, nf_logfn *logfn)
604 + spin_lock(&nf_log_lock);
605 + if (nf_logging[pf] == logfn)
606 + nf_logging[pf] = NULL;
607 + spin_unlock(&nf_log_lock);
609 + /* Give time to concurrent readers. */
613 +void nf_log_packet(int pf,
614 + unsigned int hooknum,
615 + const struct sk_buff *skb,
616 + const struct net_device *in,
617 + const struct net_device *out,
618 + const char *fmt, ...)
621 + char prefix[NF_LOG_PREFIXLEN];
625 + logfn = nf_logging[pf];
627 + va_start(args, fmt);
628 + vsnprintf(prefix, sizeof(prefix), fmt, args);
630 + /* We must read logging before nf_logfn[pf] */
631 + smp_read_barrier_depends();
632 + logfn(hooknum, skb, in, out, prefix);
633 + } else if (!reported) {
634 + printk(KERN_WARNING "nf_log_packet: can\'t log yet, "
635 + "no backend logging module loaded in!\n");
640 +EXPORT_SYMBOL(nf_log_register);
641 +EXPORT_SYMBOL(nf_log_unregister);
642 +EXPORT_SYMBOL(nf_log_packet);
644 /* This does not belong here, but ipt_REJECT needs it if connection
645 tracking in use: without this, connection may not be in hash table,
646 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/Kconfig linux-2.6.5-rc1/net/ipv4/netfilter/Kconfig
647 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/Kconfig 2004-03-16 05:47:17.000000000 +0000
648 +++ linux-2.6.5-rc1/net/ipv4/netfilter/Kconfig 2004-03-16 11:53:58.000000000 +0000
651 To compile it as a module, choose M here. If unsure, say N.
653 +config IP_NF_TARGET_IPV4OPTSSTRIP
654 + tristate 'IPV4OPTSSTRIP target support'
655 + depends on IP_NF_MANGLE
658 +config IP_NF_TARGET_TTL
659 + tristate 'TTL target support'
660 + depends on IP_NF_MANGLE
663 +config IP_NF_MATCH_CONNLIMIT
664 + tristate 'Connections/IP limit match support'
665 + depends on IP_NF_IPTABLES
668 +config IP_NF_MATCH_DSTLIMIT
669 + tristate 'dstlimit match support'
670 + depends on IP_NF_IPTABLES
673 +config IP_NF_MATCH_FUZZY
674 + tristate 'fuzzy match support'
675 + depends on IP_NF_IPTABLES
678 +config IP_NF_MATCH_IPV4OPTIONS
679 + tristate 'IPV4OPTIONS match support'
680 + depends on IP_NF_IPTABLES
683 +config IP_NF_MATCH_MPORT
684 + tristate 'Multiple port with ranges match support'
685 + depends on IP_NF_IPTABLES
688 +config IP_NF_MATCH_NTH
689 + tristate 'Nth match support'
690 + depends on IP_NF_IPTABLES
693 +config IP_NF_MATCH_QUOTA
694 + tristate 'quota match support'
695 + depends on IP_NF_IPTABLES
698 +config IP_NF_TARGET_NOTRACK
699 + tristate 'NOTRACK target support'
700 + depends on IP_NF_RAW
702 + The NOTRACK target allows a select rule to specify
703 + which packets *not* to enter the conntrack/NAT
704 + subsystem with all the consequences (no ICMP error tracking,
705 + no protocol helpers for the selected packets).
707 + If you want to compile it as a module, say M here and read
708 + <file:Documentation/modules.txt>. If unsure, say `N'.
711 + tristate 'raw table support (required for NOTRACK/TRACE)'
712 + depends on IP_NF_IPTABLES
714 + This option adds a `raw' table to iptables. This table is the very
715 + first in the netfilter framework and hooks in at the PREROUTING
718 + If you want to compile it as a module, say M here and read
719 + <file:Documentation/modules.txt>. If unsure, say `N'.
722 +config IP_NF_MATCH_REALM
723 + tristate 'realm match support'
724 + depends on IP_NF_IPTABLES && NET_CLS_ROUTE
727 +config IP_NF_MATCH_SCTP
728 + tristate 'SCTP protocol match support'
729 + depends on IP_NF_IPTABLES
732 +config IP_NF_MATCH_U32
733 + tristate 'U32 match support'
734 + depends on IP_NF_IPTABLES
739 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/Makefile linux-2.6.5-rc1/net/ipv4/netfilter/Makefile
740 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/Makefile 2004-03-16 05:45:49.000000000 +0000
741 +++ linux-2.6.5-rc1/net/ipv4/netfilter/Makefile 2004-03-16 11:53:58.000000000 +0000
743 obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
744 obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
745 obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
746 +obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
749 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
750 obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
751 +obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o
752 +obj-$(CONFIG_IP_NF_MATCH_QUOTA) += ipt_quota.o
753 +obj-$(CONFIG_IP_NF_MATCH_DSTLIMIT) += ipt_dstlimit.o
754 obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
755 obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
756 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
758 obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
759 obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
761 +obj-$(CONFIG_IP_NF_MATCH_MPORT) += ipt_mport.o
763 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
764 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
766 +obj-$(CONFIG_IP_NF_MATCH_NTH) += ipt_nth.o
768 +obj-$(CONFIG_IP_NF_MATCH_IPV4OPTIONS) += ipt_ipv4options.o
771 +obj-$(CONFIG_IP_NF_MATCH_FUZZY) += ipt_fuzzy.o
773 obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
775 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
778 obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o
780 +obj-$(CONFIG_IP_NF_MATCH_U32) += ipt_u32.o
783 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
784 obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
785 +obj-$(CONFIG_IP_NF_MATCH_CONNLIMIT) += ipt_connlimit.o
786 obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
787 obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
788 +obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
790 obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
793 obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
794 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
795 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
796 +obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
797 +obj-$(CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP) += ipt_IPV4OPTSSTRIP.o
798 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
799 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
800 +obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o
803 obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
804 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_core.c linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_core.c
805 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_core.c 2004-03-16 05:45:17.000000000 +0000
806 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_core.c 2004-03-16 11:53:55.000000000 +0000
808 static atomic_t ip_conntrack_count = ATOMIC_INIT(0);
809 struct list_head *ip_conntrack_hash;
810 static kmem_cache_t *ip_conntrack_cachep;
811 +struct ip_conntrack ip_conntrack_untracked;
813 extern struct ip_conntrack_protocol ip_conntrack_generic_protocol;
815 @@ -691,42 +692,50 @@
816 struct ip_conntrack_expect *, tuple);
817 READ_UNLOCK(&ip_conntrack_expect_tuple_lock);
819 - /* If master is not in hash table yet (ie. packet hasn't left
820 - this machine yet), how can other end know about expected?
821 - Hence these are not the droids you are looking for (if
822 - master ct never got confirmed, we'd hold a reference to it
823 - and weird things would happen to future packets). */
824 - if (expected && !is_confirmed(expected->expectant))
827 - /* Look up the conntrack helper for master connections only */
829 - conntrack->helper = ip_ct_find_helper(&repl_tuple);
831 - /* If the expectation is dying, then this is a loser. */
833 - && expected->expectant->helper->timeout
834 - && ! del_timer(&expected->timeout))
838 - DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
839 - conntrack, expected);
840 - /* Welcome, Mr. Bond. We've been expecting you... */
841 - IP_NF_ASSERT(master_ct(conntrack));
842 - __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
843 - conntrack->master = expected;
844 - expected->sibling = conntrack;
845 - LIST_DELETE(&ip_conntrack_expect_list, expected);
846 - expected->expectant->expecting--;
847 - nf_conntrack_get(&master_ct(conntrack)->infos[0]);
849 - atomic_inc(&ip_conntrack_count);
850 + /* If master is not in hash table yet (ie. packet hasn't left
851 + this machine yet), how can other end know about expected?
852 + Hence these are not the droids you are looking for (if
853 + master ct never got confirmed, we'd hold a reference to it
854 + and weird things would happen to future packets). */
855 + if (!is_confirmed(expected->expectant)) {
857 + conntrack->helper = ip_ct_find_helper(&repl_tuple);
861 + /* Expectation is dying... */
862 + if (expected->expectant->helper->timeout
863 + && ! del_timer(&expected->timeout)) {
867 + DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
868 + conntrack, expected);
869 + /* Welcome, Mr. Bond. We've been expecting you... */
870 + IP_NF_ASSERT(master_ct(conntrack));
871 + __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
872 + conntrack->master = expected;
873 + expected->sibling = conntrack;
874 + LIST_DELETE(&ip_conntrack_expect_list, expected);
875 + expected->expectant->expecting--;
876 + nf_conntrack_get(&master_ct(conntrack)->infos[0]);
878 + /* this is a braindead... --pablo */
879 + atomic_inc(&ip_conntrack_count);
880 + WRITE_UNLOCK(&ip_conntrack_lock);
882 + if (expected->expectfn)
883 + expected->expectfn(conntrack);
887 + conntrack->helper = ip_ct_find_helper(&repl_tuple);
889 +end: atomic_inc(&ip_conntrack_count);
890 WRITE_UNLOCK(&ip_conntrack_lock);
892 - if (expected && expected->expectfn)
893 - expected->expectfn(conntrack);
894 - return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
895 +ret: return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
898 /* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
904 + if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) {
905 + if (net_ratelimit()) {
906 + printk(KERN_ERR "ip_conntrack_in: Frag of proto %u (hook=%u)\n",
907 + (*pskb)->nh.iph->protocol, hooknum);
912 /* FIXME: Do this right please. --RR */
913 (*pskb)->nfcache |= NFC_UNKNOWN;
915 @@ -812,18 +830,10 @@
919 - /* Previously seen (loopback)? Ignore. Do this before
921 + /* Previously seen (loopback or untracked)? Ignore. */
925 - /* Gather fragments. */
926 - if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
927 - *pskb = ip_ct_gather_frags(*pskb);
932 proto = ip_ct_find_proto((*pskb)->nh.iph->protocol);
934 /* It may be an icmp error... */
935 @@ -1422,6 +1432,18 @@
937 /* For use by ipt_REJECT */
938 ip_ct_attach = ip_conntrack_attach;
940 + /* Set up fake conntrack:
941 + - to never be deleted, not in any hashes */
942 + atomic_set(&ip_conntrack_untracked.ct_general.use, 1);
943 + /* - and look it like as a confirmed connection */
944 + set_bit(IPS_CONFIRMED_BIT, &ip_conntrack_untracked.status);
945 + /* - and prepare the ctinfo field for REJECT & NAT. */
946 + ip_conntrack_untracked.infos[IP_CT_NEW].master =
947 + ip_conntrack_untracked.infos[IP_CT_RELATED].master =
948 + ip_conntrack_untracked.infos[IP_CT_RELATED + IP_CT_IS_REPLY].master =
949 + &ip_conntrack_untracked.ct_general;
954 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_standalone.c
955 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-16 05:46:27.000000000 +0000
956 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-16 11:53:55.000000000 +0000
958 return ip_conntrack_confirm(*pskb);
961 +static unsigned int ip_conntrack_defrag(unsigned int hooknum,
962 + struct sk_buff **pskb,
963 + const struct net_device *in,
964 + const struct net_device *out,
965 + int (*okfn)(struct sk_buff *))
967 + /* Previously seen (loopback)? Ignore. Do this before
972 + /* Gather fragments. */
973 + if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
974 + *pskb = ip_ct_gather_frags(*pskb);
981 static unsigned int ip_refrag(unsigned int hooknum,
982 struct sk_buff **pskb,
983 const struct net_device *in,
986 /* Connection tracking may drop packets, but never alters them, so
987 make it the first hook. */
988 +static struct nf_hook_ops ip_conntrack_defrag_ops = {
989 + .hook = ip_conntrack_defrag,
990 + .owner = THIS_MODULE,
992 + .hooknum = NF_IP_PRE_ROUTING,
993 + .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
996 static struct nf_hook_ops ip_conntrack_in_ops = {
997 .hook = ip_conntrack_in,
998 .owner = THIS_MODULE,
1000 .priority = NF_IP_PRI_CONNTRACK,
1003 +static struct nf_hook_ops ip_conntrack_defrag_local_out_ops = {
1004 + .hook = ip_conntrack_defrag,
1005 + .owner = THIS_MODULE,
1007 + .hooknum = NF_IP_LOCAL_OUT,
1008 + .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
1011 static struct nf_hook_ops ip_conntrack_local_out_ops = {
1012 .hook = ip_conntrack_local,
1013 .owner = THIS_MODULE,
1014 @@ -470,10 +506,20 @@
1015 if (!proc) goto cleanup_init;
1016 proc->owner = THIS_MODULE;
1018 + ret = nf_register_hook(&ip_conntrack_defrag_ops);
1020 + printk("ip_conntrack: can't register pre-routing defrag hook.\n");
1021 + goto cleanup_proc;
1023 + ret = nf_register_hook(&ip_conntrack_defrag_local_out_ops);
1025 + printk("ip_conntrack: can't register local_out defrag hook.\n");
1026 + goto cleanup_defragops;
1028 ret = nf_register_hook(&ip_conntrack_in_ops);
1030 printk("ip_conntrack: can't register pre-routing hook.\n");
1031 - goto cleanup_proc;
1032 + goto cleanup_defraglocalops;
1034 ret = nf_register_hook(&ip_conntrack_local_out_ops);
1036 @@ -511,6 +557,10 @@
1037 nf_unregister_hook(&ip_conntrack_local_out_ops);
1039 nf_unregister_hook(&ip_conntrack_in_ops);
1040 + cleanup_defraglocalops:
1041 + nf_unregister_hook(&ip_conntrack_defrag_local_out_ops);
1042 + cleanup_defragops:
1043 + nf_unregister_hook(&ip_conntrack_defrag_ops);
1045 proc_net_remove("ip_conntrack");
1048 EXPORT_SYMBOL(ip_conntrack_expect_list);
1049 EXPORT_SYMBOL(ip_conntrack_lock);
1050 EXPORT_SYMBOL(ip_conntrack_hash);
1051 +EXPORT_SYMBOL(ip_conntrack_untracked);
1052 EXPORT_SYMBOL_GPL(ip_conntrack_find_get);
1053 EXPORT_SYMBOL_GPL(ip_conntrack_put);
1054 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_nat_core.c linux-2.6.5-rc1/net/ipv4/netfilter/ip_nat_core.c
1055 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_nat_core.c 2004-03-16 05:45:35.000000000 +0000
1056 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_nat_core.c 2004-03-16 11:53:55.000000000 +0000
1057 @@ -1016,6 +1016,10 @@
1058 /* FIXME: Man, this is a hack. <SIGH> */
1059 IP_NF_ASSERT(ip_conntrack_destroyed == NULL);
1060 ip_conntrack_destroyed = &ip_nat_cleanup_conntrack;
1062 + /* Initialize fake conntrack so that NAT will skip it */
1063 + ip_conntrack_untracked.nat.info.initialized |=
1064 + (1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST);
1068 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c
1069 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 1970-01-01 00:00:00.000000000 +0000
1070 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 2004-03-16 11:53:44.000000000 +0000
1073 + * Strip all IP options in the IP packet header.
1075 + * (C) 2001 by Fabrice MARIE <fabrice@netfilter.org>
1076 + * This software is distributed under GNU GPL v2, 1991
1079 +#include <linux/module.h>
1080 +#include <linux/skbuff.h>
1081 +#include <linux/ip.h>
1082 +#include <net/checksum.h>
1084 +#include <linux/netfilter_ipv4/ip_tables.h>
1086 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
1087 +MODULE_DESCRIPTION("Strip all options in IPv4 packets");
1088 +MODULE_LICENSE("GPL");
1090 +static unsigned int
1091 +target(struct sk_buff **pskb,
1092 + const struct net_device *in,
1093 + const struct net_device *out,
1094 + unsigned int hooknum,
1095 + const void *targinfo,
1098 + struct iphdr *iph;
1099 + struct sk_buff *skb;
1100 + struct ip_options *opt;
1101 + unsigned char *optiph;
1104 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
1108 + iph = (*pskb)->nh.iph;
1109 + optiph = skb->nh.raw;
1110 + l = ((struct ip_options *)(&(IPCB(skb)->opt)))->optlen;
1112 + /* if no options in packet then nothing to clear. */
1113 + if (iph->ihl * 4 == sizeof(struct iphdr))
1114 + return IPT_CONTINUE;
1116 + /* else clear all options */
1117 + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
1118 + memset(optiph+sizeof(struct iphdr), IPOPT_NOOP, l);
1119 + opt = &(IPCB(skb)->opt);
1123 + skb->nfcache |= NFC_ALTERED;
1125 + return IPT_CONTINUE;
1129 +checkentry(const char *tablename,
1130 + const struct ipt_entry *e,
1132 + unsigned int targinfosize,
1133 + unsigned int hook_mask)
1135 + if (strcmp(tablename, "mangle")) {
1136 + printk(KERN_WARNING "IPV4OPTSSTRIP: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1139 + /* nothing else to check because no parameters */
1143 +static struct ipt_target ipt_ipv4optsstrip_reg = {
1144 + .name = "IPV4OPTSSTRIP",
1146 + .checkentry = checkentry,
1147 + .me = THIS_MODULE };
1149 +static int __init init(void)
1151 + return ipt_register_target(&ipt_ipv4optsstrip_reg);
1154 +static void __exit fini(void)
1156 + ipt_unregister_target(&ipt_ipv4optsstrip_reg);
1161 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_LOG.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_LOG.c
1162 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_LOG.c 2004-03-16 05:47:18.000000000 +0000
1163 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_LOG.c 2004-03-16 11:53:42.000000000 +0000
1165 #include <net/tcp.h>
1166 #include <net/route.h>
1168 +#include <linux/netfilter.h>
1169 #include <linux/netfilter_ipv4/ip_tables.h>
1170 #include <linux/netfilter_ipv4/ipt_LOG.h>
1173 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
1174 MODULE_DESCRIPTION("iptables syslog logging module");
1176 +static unsigned int nflog = 1;
1177 +MODULE_PARM(nflog, "i");
1178 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
1181 #define DEBUGP printk
1183 @@ -324,28 +329,25 @@
1184 /* maxlen = 230+ 91 + 230 + 252 = 803 */
1187 -static unsigned int
1188 -ipt_log_target(struct sk_buff **pskb,
1190 +ipt_log_packet(unsigned int hooknum,
1191 + const struct sk_buff *skb,
1192 const struct net_device *in,
1193 const struct net_device *out,
1194 - unsigned int hooknum,
1195 - const void *targinfo,
1197 + const struct ipt_log_info *loginfo,
1198 + const char *level_string,
1199 + const char *prefix)
1201 - const struct ipt_log_info *loginfo = targinfo;
1202 - char level_string[4] = "< >";
1204 - level_string[1] = '0' + (loginfo->level % 8);
1205 spin_lock_bh(&log_lock);
1206 printk(level_string);
1207 printk("%sIN=%s OUT=%s ",
1209 + prefix == NULL ? loginfo->prefix : prefix,
1211 out ? out->name : "");
1212 #ifdef CONFIG_BRIDGE_NETFILTER
1213 - if ((*pskb)->nf_bridge) {
1214 - struct net_device *physindev = (*pskb)->nf_bridge->physindev;
1215 - struct net_device *physoutdev = (*pskb)->nf_bridge->physoutdev;
1216 + if (skb->nf_bridge) {
1217 + struct net_device *physindev = skb->nf_bridge->physindev;
1218 + struct net_device *physoutdev = skb->nf_bridge->physoutdev;
1220 if (physindev && in != physindev)
1221 printk("PHYSIN=%s ", physindev->name);
1222 @@ -357,25 +359,56 @@
1224 /* MAC logging for input chain only. */
1226 - if ((*pskb)->dev && (*pskb)->dev->hard_header_len
1227 - && (*pskb)->mac.raw != (void*)(*pskb)->nh.iph) {
1228 + if (skb->dev && skb->dev->hard_header_len
1229 + && skb->mac.raw != (void*)skb->nh.iph) {
1231 - unsigned char *p = (*pskb)->mac.raw;
1232 - for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++)
1233 + unsigned char *p = skb->mac.raw;
1234 + for (i = 0; i < skb->dev->hard_header_len; i++,p++)
1235 printk("%02x%c", *p,
1236 - i==(*pskb)->dev->hard_header_len - 1
1237 + i==skb->dev->hard_header_len - 1
1243 - dump_packet(loginfo, *pskb, 0);
1244 + dump_packet(loginfo, skb, 0);
1246 spin_unlock_bh(&log_lock);
1249 +static unsigned int
1250 +ipt_log_target(struct sk_buff **pskb,
1251 + const struct net_device *in,
1252 + const struct net_device *out,
1253 + unsigned int hooknum,
1254 + const void *targinfo,
1257 + const struct ipt_log_info *loginfo = targinfo;
1258 + char level_string[4] = "< >";
1260 + level_string[1] = '0' + (loginfo->level % 8);
1261 + ipt_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
1263 return IPT_CONTINUE;
1267 +ipt_logfn(unsigned int hooknum,
1268 + const struct sk_buff *skb,
1269 + const struct net_device *in,
1270 + const struct net_device *out,
1271 + const char *prefix)
1273 + struct ipt_log_info loginfo = {
1275 + .logflags = IPT_LOG_MASK,
1279 + ipt_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
1282 static int ipt_log_checkentry(const char *tablename,
1283 const struct ipt_entry *e,
1285 @@ -413,11 +446,18 @@
1287 static int __init init(void)
1289 - return ipt_register_target(&ipt_log_reg);
1290 + if (ipt_register_target(&ipt_log_reg))
1293 + nf_log_register(PF_INET, &ipt_logfn);
1298 static void __exit fini(void)
1301 + nf_log_unregister(PF_INET, &ipt_logfn);
1302 ipt_unregister_target(&ipt_log_reg);
1305 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_NOTRACK.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_NOTRACK.c
1306 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_NOTRACK.c 1970-01-01 00:00:00.000000000 +0000
1307 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_NOTRACK.c 2004-03-16 11:53:55.000000000 +0000
1309 +/* This is a module which is used for setting up fake conntracks
1310 + * on packets so that they are not seen by the conntrack/NAT code.
1312 +#include <linux/module.h>
1313 +#include <linux/skbuff.h>
1315 +#include <linux/netfilter_ipv4/ip_tables.h>
1316 +#include <linux/netfilter_ipv4/ip_conntrack.h>
1318 +static unsigned int
1319 +target(struct sk_buff **pskb,
1320 + const struct net_device *in,
1321 + const struct net_device *out,
1322 + unsigned int hooknum,
1323 + const void *targinfo,
1326 + /* Previously seen (loopback)? Ignore. */
1327 + if ((*pskb)->nfct != NULL)
1328 + return IPT_CONTINUE;
1330 + /* Attach fake conntrack entry.
1331 + If there is a real ct entry correspondig to this packet,
1332 + it'll hang aroun till timing out. We don't deal with it
1333 + for performance reasons. JK */
1334 + (*pskb)->nfct = &ip_conntrack_untracked.infos[IP_CT_NEW];
1335 + nf_conntrack_get((*pskb)->nfct);
1337 + return IPT_CONTINUE;
1341 +checkentry(const char *tablename,
1342 + const struct ipt_entry *e,
1344 + unsigned int targinfosize,
1345 + unsigned int hook_mask)
1347 + if (targinfosize != 0) {
1348 + printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n",
1353 + if (strcmp(tablename, "raw") != 0) {
1354 + printk(KERN_WARNING "NOTRACK: can only be called from \"raw\" table, not \"%s\"\n", tablename);
1361 +static struct ipt_target ipt_notrack_reg = {
1362 + .name = "NOTRACK",
1364 + .checkentry = checkentry,
1368 +static int __init init(void)
1370 + if (ipt_register_target(&ipt_notrack_reg))
1376 +static void __exit fini(void)
1378 + ipt_unregister_target(&ipt_notrack_reg);
1383 +MODULE_LICENSE("GPL");
1384 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_TTL.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_TTL.c
1385 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_TTL.c 1970-01-01 00:00:00.000000000 +0000
1386 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_TTL.c 2004-03-16 11:53:46.000000000 +0000
1388 +/* TTL modification target for IP tables
1389 + * (C) 2000 by Harald Welte <laforge@gnumonks.org>
1391 + * Version: $Revision$
1393 + * This software is distributed under the terms of GNU GPL
1396 +#include <linux/module.h>
1397 +#include <linux/skbuff.h>
1398 +#include <linux/ip.h>
1399 +#include <net/checksum.h>
1401 +#include <linux/netfilter_ipv4/ip_tables.h>
1402 +#include <linux/netfilter_ipv4/ipt_TTL.h>
1404 +MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
1405 +MODULE_DESCRIPTION("IP tables TTL modification module");
1406 +MODULE_LICENSE("GPL");
1408 +static unsigned int
1409 +ipt_ttl_target(struct sk_buff **pskb, const struct net_device *in,
1410 + const struct net_device *out, unsigned int hooknum,
1411 + const void *targinfo, void *userinfo)
1413 + struct iphdr *iph;
1414 + const struct ipt_TTL_info *info = targinfo;
1415 + u_int16_t diffs[2];
1418 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
1421 + iph = (*pskb)->nh.iph;
1423 + switch (info->mode) {
1425 + new_ttl = info->ttl;
1428 + new_ttl = iph->ttl + info->ttl;
1429 + if (new_ttl > 255)
1433 + new_ttl = iph->ttl + info->ttl;
1438 + new_ttl = iph->ttl;
1442 + if (new_ttl != iph->ttl) {
1443 + diffs[0] = htons(((unsigned)iph->ttl) << 8) ^ 0xFFFF;
1444 + iph->ttl = new_ttl;
1445 + diffs[1] = htons(((unsigned)iph->ttl) << 8);
1446 + iph->check = csum_fold(csum_partial((char *)diffs,
1448 + iph->check^0xFFFF));
1449 + (*pskb)->nfcache |= NFC_ALTERED;
1452 + return IPT_CONTINUE;
1455 +static int ipt_ttl_checkentry(const char *tablename,
1456 + const struct ipt_entry *e,
1458 + unsigned int targinfosize,
1459 + unsigned int hook_mask)
1461 + struct ipt_TTL_info *info = targinfo;
1463 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_TTL_info))) {
1464 + printk(KERN_WARNING "TTL: targinfosize %u != %Zu\n",
1466 + IPT_ALIGN(sizeof(struct ipt_TTL_info)));
1470 + if (strcmp(tablename, "mangle")) {
1471 + printk(KERN_WARNING "TTL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1475 + if (info->mode > IPT_TTL_MAXMODE) {
1476 + printk(KERN_WARNING "TTL: invalid or unknown Mode %u\n",
1481 + if ((info->mode != IPT_TTL_SET) && (info->ttl == 0)) {
1482 + printk(KERN_WARNING "TTL: increment/decrement doesn't make sense with value 0\n");
1489 +static struct ipt_target ipt_TTL = {
1491 + .target = ipt_ttl_target,
1492 + .checkentry = ipt_ttl_checkentry,
1496 +static int __init init(void)
1498 + return ipt_register_target(&ipt_TTL);
1501 +static void __exit fini(void)
1503 + ipt_unregister_target(&ipt_TTL);
1508 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_ULOG.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_ULOG.c
1509 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_ULOG.c 2004-03-16 05:46:08.000000000 +0000
1510 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_ULOG.c 2004-03-16 11:53:42.000000000 +0000
1512 #include <linux/netlink.h>
1513 #include <linux/netdevice.h>
1514 #include <linux/mm.h>
1515 +#include <linux/netfilter.h>
1516 #include <linux/netfilter_ipv4/ip_tables.h>
1517 #include <linux/netfilter_ipv4/ipt_ULOG.h>
1518 #include <linux/netfilter_ipv4/lockhelp.h>
1520 MODULE_PARM(flushtimeout, "i");
1521 MODULE_PARM_DESC(flushtimeout, "buffer flush timeout");
1523 +static unsigned int nflog = 1;
1524 +MODULE_PARM(nflog, "i");
1525 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
1527 /* global data structures */
1530 @@ -157,17 +162,17 @@
1534 -static unsigned int ipt_ulog_target(struct sk_buff **pskb,
1535 - const struct net_device *in,
1536 - const struct net_device *out,
1537 - unsigned int hooknum,
1538 - const void *targinfo, void *userinfo)
1539 +static void ipt_ulog_packet(unsigned int hooknum,
1540 + const struct sk_buff *skb,
1541 + const struct net_device *in,
1542 + const struct net_device *out,
1543 + const struct ipt_ulog_info *loginfo,
1544 + const char *prefix)
1547 ulog_packet_msg_t *pm;
1548 size_t size, copy_len;
1549 struct nlmsghdr *nlh;
1550 - struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
1552 /* ffs == find first bit set, necessary because userspace
1553 * is already shifting groupnumber, but we need unshifted.
1556 /* calculate the size of the skb needed */
1557 if ((loginfo->copy_range == 0) ||
1558 - (loginfo->copy_range > (*pskb)->len)) {
1559 - copy_len = (*pskb)->len;
1560 + (loginfo->copy_range > skb->len)) {
1561 + copy_len = skb->len;
1563 copy_len = loginfo->copy_range;
1565 @@ -214,19 +219,21 @@
1567 /* copy hook, prefix, timestamp, payload, etc. */
1568 pm->data_len = copy_len;
1569 - pm->timestamp_sec = (*pskb)->stamp.tv_sec;
1570 - pm->timestamp_usec = (*pskb)->stamp.tv_usec;
1571 - pm->mark = (*pskb)->nfmark;
1572 + pm->timestamp_sec = skb->stamp.tv_sec;
1573 + pm->timestamp_usec = skb->stamp.tv_usec;
1574 + pm->mark = skb->nfmark;
1576 - if (loginfo->prefix[0] != '\0')
1577 + if (prefix != NULL)
1578 + strncpy(pm->prefix, prefix, sizeof(pm->prefix));
1579 + else if (loginfo->prefix[0] != '\0')
1580 strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix));
1582 *(pm->prefix) = '\0';
1584 if (in && in->hard_header_len > 0
1585 - && (*pskb)->mac.raw != (void *) (*pskb)->nh.iph
1586 + && skb->mac.raw != (void *) skb->nh.iph
1587 && in->hard_header_len <= ULOG_MAC_LEN) {
1588 - memcpy(pm->mac, (*pskb)->mac.raw, in->hard_header_len);
1589 + memcpy(pm->mac, skb->mac.raw, in->hard_header_len);
1590 pm->mac_len = in->hard_header_len;
1595 pm->outdev_name[0] = '\0';
1597 - /* copy_len <= (*pskb)->len, so can't fail. */
1598 - if (skb_copy_bits(*pskb, 0, pm->payload, copy_len) < 0)
1599 + /* copy_len <= skb->len, so can't fail. */
1600 + if (skb_copy_bits(skb, 0, pm->payload, copy_len) < 0)
1603 /* check if we are building multi-part messages */
1606 UNLOCK_BH(&ulog_lock);
1608 - return IPT_CONTINUE;
1613 PRINTR("ipt_ULOG: error during NLMSG_PUT\n");
1614 @@ -276,8 +282,35 @@
1615 PRINTR("ipt_ULOG: Error building netlink message\n");
1617 UNLOCK_BH(&ulog_lock);
1620 +static unsigned int ipt_ulog_target(struct sk_buff **pskb,
1621 + const struct net_device *in,
1622 + const struct net_device *out,
1623 + unsigned int hooknum,
1624 + const void *targinfo, void *userinfo)
1626 + struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
1628 - return IPT_CONTINUE;
1629 + ipt_ulog_packet(hooknum, *pskb, in, out, loginfo, NULL);
1631 + return IPT_CONTINUE;
1634 +static void ipt_logfn(unsigned int hooknum,
1635 + const struct sk_buff *skb,
1636 + const struct net_device *in,
1637 + const struct net_device *out,
1638 + const char *prefix)
1640 + struct ipt_ulog_info loginfo = {
1641 + .nl_group = ULOG_DEFAULT_NLGROUP,
1643 + .qthreshold = ULOG_DEFAULT_QTHRESHOLD,
1647 + ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
1650 static int ipt_ulog_checkentry(const char *tablename,
1652 sock_release(nflognl->sk_socket);
1657 + nf_log_register(PF_INET, &ipt_logfn);
1664 DEBUGP("ipt_ULOG: cleanup_module\n");
1667 + nf_log_unregister(PF_INET, &ipt_logfn);
1668 ipt_unregister_target(&ipt_ulog_reg);
1669 sock_release(nflognl->sk_socket);
1671 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_connlimit.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_connlimit.c
1672 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_connlimit.c 1970-01-01 00:00:00.000000000 +0000
1673 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_connlimit.c 2004-03-16 11:53:47.000000000 +0000
1676 + * netfilter module to limit the number of parallel tcp
1677 + * connections per IP address.
1678 + * (c) 2000 Gerd Knorr <kraxel@bytesex.org>
1679 + * Nov 2002: Martin Bene <martin.bene@icomedias.com>:
1680 + * only ignore TIME_WAIT or gone connections
1684 + * Kernel module to match connection tracking information.
1685 + * GPL (C) 1999 Rusty Russell (rusty@rustcorp.com.au).
1687 +#include <linux/module.h>
1688 +#include <linux/skbuff.h>
1689 +#include <linux/list.h>
1690 +#include <linux/netfilter_ipv4/ip_conntrack.h>
1691 +#include <linux/netfilter_ipv4/ip_conntrack_core.h>
1692 +#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
1693 +#include <linux/netfilter_ipv4/ip_tables.h>
1694 +#include <linux/netfilter_ipv4/ipt_connlimit.h>
1698 +MODULE_LICENSE("GPL");
1700 +/* we'll save the tuples of all connections we care about */
1701 +struct ipt_connlimit_conn
1703 + struct list_head list;
1704 + struct ip_conntrack_tuple tuple;
1707 +struct ipt_connlimit_data {
1709 + struct list_head iphash[256];
1712 +static int ipt_iphash(u_int32_t addr)
1716 + hash = addr & 0xff;
1717 + hash ^= (addr >> 8) & 0xff;
1718 + hash ^= (addr >> 16) & 0xff;
1719 + hash ^= (addr >> 24) & 0xff;
1723 +static int count_them(struct ipt_connlimit_data *data,
1724 + u_int32_t addr, u_int32_t mask,
1725 + struct ip_conntrack *ct)
1728 + const static char *tcp[] = { "none", "established", "syn_sent", "syn_recv",
1729 + "fin_wait", "time_wait", "close", "close_wait",
1730 + "last_ack", "listen" };
1732 + int addit = 1, matches = 0;
1733 + struct ip_conntrack_tuple tuple;
1734 + struct ip_conntrack_tuple_hash *found;
1735 + struct ipt_connlimit_conn *conn;
1736 + struct list_head *hash,*lh;
1738 + spin_lock(&data->lock);
1739 + tuple = ct->tuplehash[0].tuple;
1740 + hash = &data->iphash[ipt_iphash(addr & mask)];
1742 + /* check the saved connections */
1743 + for (lh = hash->next; lh != hash; lh = lh->next) {
1744 + conn = list_entry(lh,struct ipt_connlimit_conn,list);
1745 + found = ip_conntrack_find_get(&conn->tuple,ct);
1746 + if (0 == memcmp(&conn->tuple,&tuple,sizeof(tuple)) &&
1748 + found->ctrack->proto.tcp.state != TCP_CONNTRACK_TIME_WAIT) {
1749 + /* Just to be sure we have it only once in the list.
1750 + We should'nt see tuples twice unless someone hooks this
1751 + into a table without "-p tcp --syn" */
1755 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d %s\n",
1756 + ipt_iphash(addr & mask),
1757 + NIPQUAD(conn->tuple.src.ip), ntohs(conn->tuple.src.u.tcp.port),
1758 + NIPQUAD(conn->tuple.dst.ip), ntohs(conn->tuple.dst.u.tcp.port),
1759 + (NULL != found) ? tcp[found->ctrack->proto.tcp.state] : "gone");
1761 + if (NULL == found) {
1762 + /* this one is gone */
1764 + list_del(lh->next);
1768 + if (found->ctrack->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT) {
1769 + /* we don't care about connections which are
1770 + closed already -> ditch it */
1772 + list_del(lh->next);
1774 + nf_conntrack_put(&found->ctrack->infos[0]);
1777 + if ((addr & mask) == (conn->tuple.src.ip & mask)) {
1778 + /* same source IP address -> be counted! */
1781 + nf_conntrack_put(&found->ctrack->infos[0]);
1784 + /* save the new connection in our list */
1786 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d new\n",
1787 + ipt_iphash(addr & mask),
1788 + NIPQUAD(tuple.src.ip), ntohs(tuple.src.u.tcp.port),
1789 + NIPQUAD(tuple.dst.ip), ntohs(tuple.dst.u.tcp.port));
1791 + conn = kmalloc(sizeof(*conn),GFP_ATOMIC);
1794 + memset(conn,0,sizeof(*conn));
1795 + INIT_LIST_HEAD(&conn->list);
1796 + conn->tuple = tuple;
1797 + list_add(&conn->list,hash);
1800 + spin_unlock(&data->lock);
1805 +match(const struct sk_buff *skb,
1806 + const struct net_device *in,
1807 + const struct net_device *out,
1808 + const void *matchinfo,
1812 + const struct ipt_connlimit_info *info = matchinfo;
1813 + int connections, match;
1814 + struct ip_conntrack *ct;
1815 + enum ip_conntrack_info ctinfo;
1817 + ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
1819 + printk("ipt_connlimit: Oops: invalid ct state ?\n");
1823 + connections = count_them(info->data,skb->nh.iph->saddr,info->mask,ct);
1824 + if (-1 == connections) {
1825 + printk("ipt_connlimit: Hmm, kmalloc failed :-(\n");
1826 + *hotdrop = 1; /* let's free some memory :-) */
1829 + match = (info->inverse) ? (connections <= info->limit) : (connections > info->limit);
1831 + printk("ipt_connlimit: src=%u.%u.%u.%u mask=%u.%u.%u.%u "
1832 + "connections=%d limit=%d match=%s\n",
1833 + NIPQUAD(skb->nh.iph->saddr), NIPQUAD(info->mask),
1834 + connections, info->limit, match ? "yes" : "no");
1840 +static int check(const char *tablename,
1841 + const struct ipt_ip *ip,
1843 + unsigned int matchsize,
1844 + unsigned int hook_mask)
1846 + struct ipt_connlimit_info *info = matchinfo;
1850 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connlimit_info)))
1853 + /* refuse anything but tcp */
1854 + if (ip->proto != IPPROTO_TCP)
1857 + /* init private data */
1858 + info->data = kmalloc(sizeof(struct ipt_connlimit_data),GFP_KERNEL);
1859 + spin_lock_init(&(info->data->lock));
1860 + for (i = 0; i < 256; i++)
1861 + INIT_LIST_HEAD(&(info->data->iphash[i]));
1866 +static void destroy(void *matchinfo, unsigned int matchinfosize)
1868 + struct ipt_connlimit_info *info = matchinfo;
1869 + struct ipt_connlimit_conn *conn;
1870 + struct list_head *hash;
1874 + for (i = 0; i < 256; i++) {
1875 + hash = &(info->data->iphash[i]);
1876 + while (hash != hash->next) {
1877 + conn = list_entry(hash->next,struct ipt_connlimit_conn,list);
1878 + list_del(hash->next);
1882 + kfree(info->data);
1885 +static struct ipt_match connlimit_match = {
1886 + .name = "connlimit",
1888 + .checkentry = &check,
1889 + .destroy = &destroy,
1893 +static int __init init(void)
1895 + return ipt_register_match(&connlimit_match);
1898 +static void __exit fini(void)
1900 + ipt_unregister_match(&connlimit_match);
1905 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_conntrack.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_conntrack.c
1906 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_conntrack.c 2004-03-16 05:47:18.000000000 +0000
1907 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_conntrack.c 2004-03-16 11:53:55.000000000 +0000
1910 #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
1913 - statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
1915 - statebit = IPT_CONNTRACK_STATE_INVALID;
1917 + if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
1918 + statebit = IPT_CONNTRACK_STATE_UNTRACKED;
1920 + statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
1922 + statebit = IPT_CONNTRACK_STATE_INVALID;
1924 if(sinfo->flags & IPT_CONNTRACK_STATE) {
1926 if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip !=
1927 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_dstlimit.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_dstlimit.c
1928 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_dstlimit.c 1970-01-01 00:00:00.000000000 +0000
1929 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_dstlimit.c 2004-03-16 11:53:48.000000000 +0000
1931 +/* iptables match extension to limit the number of packets per second
1932 + * seperately for each destination.
1934 + * (C) 2003 by Harald Welte <laforge@netfilter.org>
1938 + * Development of this code was funded by Astaro AG, http://www.astaro.com/
1940 + * based on ipt_limit.c by:
1941 + * Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
1942 + * Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
1943 + * Rusty Russell <rusty@rustcorp.com.au>
1945 + * The general idea is to create a hash table for every dstip and have a
1946 + * seperate limit counter per tuple. This way you can do something like 'limit
1947 + * the number of syn packets for each of my internal addresses.
1949 + * Ideally this would just be implemented as a general 'hash' match, which would
1950 + * allow us to attach any iptables target to it's hash buckets. But this is
1951 + * not possible in the current iptables architecture. As always, pkttables for
1952 + * 2.7.x will help ;)
1954 +#include <linux/module.h>
1955 +#include <linux/skbuff.h>
1956 +#include <linux/spinlock.h>
1957 +#include <linux/random.h>
1958 +#include <linux/jhash.h>
1959 +#include <linux/slab.h>
1960 +#include <linux/vmalloc.h>
1961 +#include <linux/tcp.h>
1962 +#include <linux/udp.h>
1963 +#include <linux/proc_fs.h>
1964 +#include <linux/seq_file.h>
1966 +#define ASSERT_READ_LOCK(x)
1967 +#define ASSERT_WRITE_LOCK(x)
1968 +#include <linux/netfilter_ipv4/lockhelp.h>
1969 +#include <linux/netfilter_ipv4/listhelp.h>
1971 +#include <linux/netfilter_ipv4/ip_tables.h>
1972 +#include <linux/netfilter_ipv4/ipt_dstlimit.h>
1974 +/* FIXME: this is just for IP_NF_ASSERRT */
1975 +#include <linux/netfilter_ipv4/ip_conntrack.h>
1977 +#define MS2JIFFIES(x) ((x*HZ)/1000)
1979 +MODULE_LICENSE("GPL");
1980 +MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
1981 +MODULE_DESCRIPTION("iptables match for limiting per destination");
1983 +/* need to declare this at the top */
1984 +static struct proc_dir_entry *dstlimit_procdir;
1985 +static struct file_operations dl_file_ops;
1987 +/* hash table crap */
1989 +struct dsthash_dst {
1995 +struct dsthash_ent {
1996 + /* static / read-only parts in the beginning */
1997 + struct list_head list;
1998 + struct dsthash_dst dst;
2000 + /* modified structure members in the end */
2001 + unsigned long expires; /* precalculated expiry time */
2003 + unsigned long prev; /* last modification */
2005 + u_int32_t credit_cap, cost;
2009 +struct ipt_dstlimit_htable {
2010 + struct list_head list; /* global list of all htables */
2013 + struct dstlimit_cfg cfg; /* config */
2015 + /* used internally */
2016 + spinlock_t lock; /* lock for list_head */
2017 + u_int32_t rnd; /* random seed for hash */
2018 + struct timer_list timer; /* timer for gc */
2019 + atomic_t count; /* number entries in table */
2021 + /* seq_file stuff */
2022 + struct proc_dir_entry *pde;
2024 + struct list_head hash[0]; /* hashtable itself */
2027 +DECLARE_RWLOCK(dstlimit_lock); /* protects htables list */
2028 +static LIST_HEAD(dstlimit_htables);
2029 +static kmem_cache_t *dstlimit_cachep;
2031 +static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b)
2033 + return (ent->dst.dst_ip == b->dst_ip
2034 + && ent->dst.port == b->port
2035 + && ent->dst.src_ip == b->src_ip);
2038 +static inline u_int32_t
2039 +hash_dst(const struct ipt_dstlimit_htable *ht, const struct dsthash_dst *dst)
2041 + return (jhash_3words(dst->dst_ip, dst->port,
2042 + dst->src_ip, ht->rnd) % ht->cfg.size);
2045 +static inline struct dsthash_ent *
2046 +__dsthash_find(const struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
2048 + struct dsthash_ent *ent;
2049 + u_int32_t hash = hash_dst(ht, dst);
2050 + MUST_BE_LOCKED(&ht->lock);
2051 + ent = LIST_FIND(&ht->hash[hash], dst_cmp, struct dsthash_ent *, dst);
2055 +/* allocate dsthash_ent, initialize dst, put in htable and lock it */
2056 +static struct dsthash_ent *
2057 +__dsthash_alloc_init(struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
2059 + struct dsthash_ent *ent;
2061 + /* initialize hash with random val at the time we allocate
2062 + * the first hashtable entry */
2064 + get_random_bytes(&ht->rnd, 4);
2066 + if (ht->cfg.max &&
2067 + atomic_read(&ht->count) >= ht->cfg.max) {
2068 + /* FIXME: do something. question is what.. */
2069 + if (net_ratelimit())
2070 + printk(KERN_WARNING
2071 + "ipt_dstlimit: max count of %u reached\n",
2076 + ent = kmem_cache_alloc(dstlimit_cachep, GFP_ATOMIC);
2078 + if (net_ratelimit())
2080 + "ipt_dstlimit: can't allocate dsthash_ent\n");
2084 + atomic_inc(&ht->count);
2086 + ent->dst.dst_ip = dst->dst_ip;
2087 + ent->dst.port = dst->port;
2088 + ent->dst.src_ip = dst->src_ip;
2090 + list_add(&ent->list, &ht->hash[hash_dst(ht, dst)]);
2096 +__dsthash_free(struct ipt_dstlimit_htable *ht, struct dsthash_ent *ent)
2098 + MUST_BE_LOCKED(&ht->lock);
2100 + list_del(&ent->list);
2101 + kmem_cache_free(dstlimit_cachep, ent);
2102 + atomic_dec(&ht->count);
2104 +static void htable_gc(unsigned long htlong);
2106 +static int htable_create(struct ipt_dstlimit_info *minfo)
2109 + unsigned int size;
2110 + struct ipt_dstlimit_htable *hinfo;
2112 + if (minfo->cfg.size)
2113 + size = minfo->cfg.size;
2115 + size = (((num_physpages << PAGE_SHIFT) / 16384)
2116 + / sizeof(struct list_head));
2117 + if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
2122 + /* FIXME: don't use vmalloc() here or anywhere else -HW */
2123 + hinfo = vmalloc(sizeof(struct ipt_dstlimit_htable)
2124 + + (sizeof(struct list_head) * size));
2126 + printk(KERN_ERR "ipt_dstlimit: Unable to create hashtable\n");
2129 + minfo->hinfo = hinfo;
2131 + /* copy match config into hashtable config */
2132 + memcpy(&hinfo->cfg, &minfo->cfg, sizeof(hinfo->cfg));
2133 + hinfo->cfg.size = size;
2134 + if (!hinfo->cfg.max)
2135 + hinfo->cfg.max = 8 * hinfo->cfg.size;
2136 + else if (hinfo->cfg.max < hinfo->cfg.size)
2137 + hinfo->cfg.max = hinfo->cfg.size;
2139 + for (i = 0; i < hinfo->cfg.size; i++)
2140 + INIT_LIST_HEAD(&hinfo->hash[i]);
2142 + atomic_set(&hinfo->count, 0);
2143 + atomic_set(&hinfo->use, 1);
2145 + hinfo->lock = SPIN_LOCK_UNLOCKED;
2146 + hinfo->pde = create_proc_entry(minfo->name, 0, dstlimit_procdir);
2147 + if (!hinfo->pde) {
2151 + hinfo->pde->proc_fops = &dl_file_ops;
2152 + hinfo->pde->data = hinfo;
2154 + init_timer(&hinfo->timer);
2155 + hinfo->timer.expires = jiffies + MS2JIFFIES(hinfo->cfg.gc_interval);
2156 + hinfo->timer.data = (unsigned long )hinfo;
2157 + hinfo->timer.function = htable_gc;
2158 + add_timer(&hinfo->timer);
2160 + WRITE_LOCK(&dstlimit_lock);
2161 + list_add(&hinfo->list, &dstlimit_htables);
2162 + WRITE_UNLOCK(&dstlimit_lock);
2167 +static int select_all(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
2172 +static int select_gc(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
2174 + return (jiffies >= he->expires);
2177 +static void htable_selective_cleanup(struct ipt_dstlimit_htable *ht,
2178 + int (*select)(struct ipt_dstlimit_htable *ht,
2179 + struct dsthash_ent *he))
2183 + IP_NF_ASSERT(ht->cfg.size && ht->cfg.max);
2185 + /* lock hash table and iterate over it */
2186 + LOCK_BH(&ht->lock);
2187 + for (i = 0; i < ht->cfg.size; i++) {
2188 + struct dsthash_ent *dh, *n;
2189 + list_for_each_entry_safe(dh, n, &ht->hash[i], list) {
2190 + if ((*select)(ht, dh))
2191 + __dsthash_free(ht, dh);
2194 + UNLOCK_BH(&ht->lock);
2197 +/* hash table garbage collector, run by timer */
2198 +static void htable_gc(unsigned long htlong)
2200 + struct ipt_dstlimit_htable *ht = (struct ipt_dstlimit_htable *)htlong;
2202 + htable_selective_cleanup(ht, select_gc);
2204 + /* re-add the timer accordingly */
2205 + ht->timer.expires = jiffies + MS2JIFFIES(ht->cfg.gc_interval);
2206 + add_timer(&ht->timer);
2209 +static void htable_destroy(struct ipt_dstlimit_htable *hinfo)
2211 + /* remove timer, if it is pending */
2212 + if (timer_pending(&hinfo->timer))
2213 + del_timer(&hinfo->timer);
2215 + /* remove proc entry */
2216 + remove_proc_entry(hinfo->pde->name, dstlimit_procdir);
2218 + htable_selective_cleanup(hinfo, select_all);
2222 +static struct ipt_dstlimit_htable *htable_find_get(char *name)
2224 + struct ipt_dstlimit_htable *hinfo;
2226 + READ_LOCK(&dstlimit_lock);
2227 + list_for_each_entry(hinfo, &dstlimit_htables, list) {
2228 + if (!strcmp(name, hinfo->pde->name)) {
2229 + atomic_inc(&hinfo->use);
2230 + READ_UNLOCK(&dstlimit_lock);
2234 + READ_UNLOCK(&dstlimit_lock);
2239 +static void htable_put(struct ipt_dstlimit_htable *hinfo)
2241 + if (atomic_dec_and_test(&hinfo->use)) {
2242 + WRITE_LOCK(&dstlimit_lock);
2243 + list_del(&hinfo->list);
2244 + WRITE_UNLOCK(&dstlimit_lock);
2245 + htable_destroy(hinfo);
2250 +/* The algorithm used is the Simple Token Bucket Filter (TBF)
2251 + * see net/sched/sch_tbf.c in the linux source tree
2254 +/* Rusty: This is my (non-mathematically-inclined) understanding of
2255 + this algorithm. The `average rate' in jiffies becomes your initial
2256 + amount of credit `credit' and the most credit you can ever have
2257 + `credit_cap'. The `peak rate' becomes the cost of passing the
2260 + `prev' tracks the last packet hit: you gain one credit per jiffy.
2261 + If you get credit balance more than this, the extra credit is
2262 + discarded. Every time the match passes, you lose `cost' credits;
2263 + if you don't have that many, the test fails.
2265 + See Alexey's formal explanation in net/sched/sch_tbf.c.
2267 + To get the maximum range, we multiply by this factor (ie. you get N
2268 + credits per jiffy). We want to allow a rate as low as 1 per day
2269 + (slowest userspace tool allows), which means
2270 + CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32 ie.
2272 +#define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24))
2274 +/* Repeated shift and or gives us all 1s, final shift and add 1 gives
2275 + * us the power of 2 below the theoretical max, so GCC simply does a
2277 +#define _POW2_BELOW2(x) ((x)|((x)>>1))
2278 +#define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2))
2279 +#define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4))
2280 +#define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8))
2281 +#define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16))
2282 +#define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1)
2284 +#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
2286 +/* Precision saver. */
2287 +static inline u_int32_t
2288 +user2credits(u_int32_t user)
2290 + /* If multiplying would overflow... */
2291 + if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY))
2292 + /* Divide first. */
2293 + return (user / IPT_DSTLIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;
2295 + return (user * HZ * CREDITS_PER_JIFFY) / IPT_DSTLIMIT_SCALE;
2298 +static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
2300 + dh->rateinfo.credit += (now - xchg(&dh->rateinfo.prev, now))
2301 + * CREDITS_PER_JIFFY;
2302 + if (dh->rateinfo.credit > dh->rateinfo.credit_cap)
2303 + dh->rateinfo.credit = dh->rateinfo.credit_cap;
2307 +dstlimit_match(const struct sk_buff *skb,
2308 + const struct net_device *in,
2309 + const struct net_device *out,
2310 + const void *matchinfo,
2314 + struct ipt_dstlimit_info *r =
2315 + ((struct ipt_dstlimit_info *)matchinfo)->u.master;
2316 + struct ipt_dstlimit_htable *hinfo = r->hinfo;
2317 + unsigned long now = jiffies;
2318 + struct dsthash_ent *dh;
2319 + struct dsthash_dst dst;
2321 + memset(&dst, 0, sizeof(dst));
2323 + /* dest ip is always in hash */
2324 + dst.dst_ip = skb->nh.iph->daddr;
2326 + /* source ip only if respective hashmode, otherwise set to
2328 + if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_SIP)
2329 + dst.src_ip = skb->nh.iph->saddr;
2331 + /* dest port only if respective mode */
2332 + if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_DPT) {
2335 + /* Must not be a fragment. */
2339 + /* Must be big enough to read ports (both UDP and TCP have
2340 + them at the start). */
2341 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
2342 + /* We've been asked to examine this packet, and we
2343 + can't. Hence, no choice but to drop. */
2348 + switch (skb->nh.iph->protocol) {
2349 + struct tcphdr *th;
2350 + struct udphdr *uh;
2352 + th = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
2353 + dst.port = th->dest;
2356 + uh = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
2357 + dst.port = uh->dest;
2364 + LOCK_BH(&hinfo->lock);
2365 + dh = __dsthash_find(hinfo, &dst);
2367 + dh = __dsthash_alloc_init(hinfo, &dst);
2370 + /* enomem... don't match == DROP */
2371 + if (net_ratelimit())
2372 + printk(KERN_ERR "%s: ENOMEM\n", __FUNCTION__);
2373 + UNLOCK_BH(&hinfo->lock);
2377 + dh->expires = jiffies + MS2JIFFIES(hinfo->cfg.expire);
2379 + dh->rateinfo.prev = jiffies;
2380 + dh->rateinfo.credit = user2credits(hinfo->cfg.avg *
2381 + hinfo->cfg.burst);
2382 + dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg *
2383 + hinfo->cfg.burst);
2384 + dh->rateinfo.cost = user2credits(hinfo->cfg.avg);
2386 + UNLOCK_BH(&hinfo->lock);
2390 + /* update expiration timeout */
2391 + dh->expires = now + MS2JIFFIES(hinfo->cfg.expire);
2393 + rateinfo_recalc(dh, now);
2394 + if (dh->rateinfo.credit >= dh->rateinfo.cost) {
2395 + /* We're underlimit. */
2396 + dh->rateinfo.credit -= dh->rateinfo.cost;
2397 + UNLOCK_BH(&hinfo->lock);
2401 + UNLOCK_BH(&hinfo->lock);
2403 + /* default case: we're overlimit, thus don't match */
2408 +dstlimit_checkentry(const char *tablename,
2409 + const struct ipt_ip *ip,
2411 + unsigned int matchsize,
2412 + unsigned int hook_mask)
2414 + struct ipt_dstlimit_info *r = matchinfo;
2416 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_dstlimit_info)))
2419 + /* Check for overflow. */
2420 + if (r->cfg.burst == 0
2421 + || user2credits(r->cfg.avg * r->cfg.burst) <
2422 + user2credits(r->cfg.avg)) {
2423 + printk(KERN_ERR "ipt_dstlimit: Overflow, try lower: %u/%u\n",
2424 + r->cfg.avg, r->cfg.burst);
2428 + if (r->cfg.mode == 0
2429 + || r->cfg.mode > (IPT_DSTLIMIT_HASH_DPT
2430 + |IPT_DSTLIMIT_HASH_DIP
2431 + |IPT_DSTLIMIT_HASH_SIP))
2434 + if (!r->cfg.gc_interval)
2437 + if (!r->cfg.expire)
2440 + r->hinfo = htable_find_get(r->name);
2441 + if (!r->hinfo && (htable_create(r) != 0)) {
2445 + /* Ugly hack: For SMP, we only want to use one set */
2452 +dstlimit_destroy(void *matchinfo, unsigned int matchsize)
2454 + struct ipt_dstlimit_info *r = (struct ipt_dstlimit_info *) matchinfo;
2456 + htable_put(r->hinfo);
2459 +static struct ipt_match ipt_dstlimit = {
2460 + .list = { .prev = NULL, .next = NULL },
2461 + .name = "dstlimit",
2462 + .match = dstlimit_match,
2463 + .checkentry = dstlimit_checkentry,
2464 + .destroy = dstlimit_destroy,
2470 +static void *dl_seq_start(struct seq_file *s, loff_t *pos)
2472 + struct proc_dir_entry *pde = s->private;
2473 + struct ipt_dstlimit_htable *htable = pde->data;
2474 + unsigned int *bucket;
2476 + LOCK_BH(&htable->lock);
2477 + if (*pos >= htable->cfg.size)
2480 + bucket = kmalloc(sizeof(unsigned int), GFP_KERNEL);
2482 + return ERR_PTR(-ENOMEM);
2488 +static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
2490 + struct proc_dir_entry *pde = s->private;
2491 + struct ipt_dstlimit_htable *htable = pde->data;
2492 + unsigned int *bucket = (unsigned int *)v;
2494 + *pos = ++(*bucket);
2495 + if (*pos >= htable->cfg.size) {
2502 +static void dl_seq_stop(struct seq_file *s, void *v)
2504 + struct proc_dir_entry *pde = s->private;
2505 + struct ipt_dstlimit_htable *htable = pde->data;
2506 + unsigned int *bucket = (unsigned int *)v;
2510 + UNLOCK_BH(&htable->lock);
2513 +static inline int dl_seq_real_show(struct dsthash_ent *ent, struct seq_file *s)
2515 + /* recalculate to show accurate numbers */
2516 + rateinfo_recalc(ent, jiffies);
2518 + return seq_printf(s, "%ld %u.%u.%u.%u->%u.%u.%u.%u:%u %u %u %u\n",
2519 + (ent->expires - jiffies)/HZ,
2520 + NIPQUAD(ent->dst.src_ip),
2521 + NIPQUAD(ent->dst.dst_ip), ntohs(ent->dst.port),
2522 + ent->rateinfo.credit, ent->rateinfo.credit_cap,
2523 + ent->rateinfo.cost);
2526 +static int dl_seq_show(struct seq_file *s, void *v)
2528 + struct proc_dir_entry *pde = s->private;
2529 + struct ipt_dstlimit_htable *htable = pde->data;
2530 + unsigned int *bucket = (unsigned int *)v;
2532 + if (LIST_FIND_W(&htable->hash[*bucket], dl_seq_real_show,
2533 + struct dsthash_ent *, s)) {
2534 + /* buffer was filled and unable to print that tuple */
2540 +static struct seq_operations dl_seq_ops = {
2541 + .start = dl_seq_start,
2542 + .next = dl_seq_next,
2543 + .stop = dl_seq_stop,
2544 + .show = dl_seq_show
2547 +static int dl_proc_open(struct inode *inode, struct file *file)
2549 + int ret = seq_open(file, &dl_seq_ops);
2552 + struct seq_file *sf = file->private_data;
2553 + sf->private = PDE(inode);
2558 +static struct file_operations dl_file_ops = {
2559 + .owner = THIS_MODULE,
2560 + .open = dl_proc_open,
2562 + .llseek = seq_lseek,
2563 + .release = seq_release
2566 +static int init_or_fini(int fini)
2573 + if (ipt_register_match(&ipt_dstlimit)) {
2575 + goto cleanup_nothing;
2578 + /* FIXME: do we really want HWCACHE_ALIGN since our objects are
2579 + * quite small ? */
2580 + dstlimit_cachep = kmem_cache_create("ipt_dstlimit",
2581 + sizeof(struct dsthash_ent), 0,
2582 + SLAB_HWCACHE_ALIGN, NULL, NULL);
2583 + if (!dstlimit_cachep) {
2584 + printk(KERN_ERR "Unable to create ipt_dstlimit slab cache\n");
2586 + goto cleanup_unreg_match;
2589 + dstlimit_procdir = proc_mkdir("ipt_dstlimit", proc_net);
2590 + if (!dstlimit_procdir) {
2591 + printk(KERN_ERR "Unable to create proc dir entry\n");
2593 + goto cleanup_free_slab;
2599 + remove_proc_entry("ipt_dstlimit", proc_net);
2601 + kmem_cache_destroy(dstlimit_cachep);
2602 +cleanup_unreg_match:
2603 + ipt_unregister_match(&ipt_dstlimit);
2609 +static int __init init(void)
2611 + return init_or_fini(0);
2614 +static void __exit fini(void)
2621 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_fuzzy.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_fuzzy.c
2622 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_fuzzy.c 1970-01-01 00:00:00.000000000 +0000
2623 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_fuzzy.c 2004-03-16 11:53:50.000000000 +0000
2626 + * This module implements a simple TSK FLC
2627 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
2628 + * to limit , in an adaptive and flexible way , the packet rate crossing
2629 + * a given stream . It serves as an initial and very simple (but effective)
2630 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
2631 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
2632 + * into our code in a precise , adaptive and efficient manner.
2633 + * The goal is very similar to that of "limit" match , but using techniques of
2634 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
2635 + * avoiding over and undershoots - and stuff like that .
2638 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
2639 + * 2002-08-17 : Changed to eliminate floating point operations .
2640 + * 2002-08-23 : Coding style changes .
2643 +#include <linux/module.h>
2644 +#include <linux/skbuff.h>
2645 +#include <linux/ip.h>
2646 +#include <linux/random.h>
2647 +#include <net/tcp.h>
2648 +#include <linux/spinlock.h>
2649 +#include <linux/netfilter_ipv4/ip_tables.h>
2650 +#include <linux/netfilter_ipv4/ipt_fuzzy.h>
2653 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
2654 + Expressed in percentage
2657 +#define PAR_LOW 1/100
2660 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED ;
2662 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
2663 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
2664 +MODULE_LICENSE("GPL");
2666 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
2674 + return ( (100*(tx-mini)) / (maxi-mini) );
2677 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
2685 + return ( (100*( maxi - tx )) / ( maxi - mini ) );
2689 +ipt_fuzzy_match(const struct sk_buff *pskb,
2690 + const struct net_device *in,
2691 + const struct net_device *out,
2692 + const void *matchinfo,
2696 + /* From userspace */
2698 + struct ipt_fuzzy_info *info = (struct ipt_fuzzy_info *) matchinfo;
2700 + u_int8_t random_number;
2701 + unsigned long amount;
2702 + u_int8_t howhigh, howlow;
2705 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
2707 + info->bytes_total += pskb->len;
2708 + info->packets_total++;
2710 + info->present_time = jiffies;
2712 + if (info->present_time >= info->previous_time)
2713 + amount = info->present_time - info->previous_time;
2715 + /* There was a transition : I choose to re-sample
2716 + and keep the old acceptance rate...
2720 + info->previous_time = info->present_time;
2721 + info->bytes_total = info->packets_total = 0;
2724 + if (amount > HZ/10) /* More than 100 ms elapsed ... */
2727 + info->mean_rate = (u_int32_t) ((HZ*info->packets_total) \
2730 + info->previous_time = info->present_time;
2731 + info->bytes_total = info->packets_total = 0;
2733 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
2734 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
2736 + info->acceptance_rate = (u_int8_t) \
2737 + (howhigh*PAR_LOW + PAR_HIGH*howlow);
2739 + /* In fact , the above defuzzification would require a denominator
2740 + proportional to (howhigh+howlow) but , in this particular case ,
2741 + that expression is constant .
2742 + An imediate consequence is that it isn't necessary to call
2743 + both mf_high and mf_low - but to keep things understandable ,
2748 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
2751 + if ( info->acceptance_rate < 100 )
2753 + get_random_bytes((void *)(&random_number), 1);
2755 + /* If within the acceptance , it can pass => don't match */
2756 + if (random_number <= (255 * info->acceptance_rate) / 100)
2759 + return 1; /* It can't pass ( It matches ) */
2762 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
2767 +ipt_fuzzy_checkentry(const char *tablename,
2768 + const struct ipt_ip *e,
2770 + unsigned int matchsize,
2771 + unsigned int hook_mask)
2774 + const struct ipt_fuzzy_info *info = matchinfo;
2776 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_fuzzy_info))) {
2777 + printk("ipt_fuzzy: matchsize %u != %u\n", matchsize,
2778 + IPT_ALIGN(sizeof(struct ipt_fuzzy_info)));
2782 + if ((info->minimum_rate < MINFUZZYRATE ) || (info->maximum_rate > MAXFUZZYRATE)
2783 + || (info->minimum_rate >= info->maximum_rate )) {
2784 + printk("ipt_fuzzy: BAD limits , please verify !!!\n");
2791 +static struct ipt_match ipt_fuzzy_reg = {
2793 + .match = ipt_fuzzy_match,
2794 + .checkentry = ipt_fuzzy_checkentry,
2798 +static int __init init(void)
2800 + return ipt_register_match(&ipt_fuzzy_reg);
2803 +static void __exit fini(void)
2805 + ipt_unregister_match(&ipt_fuzzy_reg);
2810 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_ipv4options.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_ipv4options.c
2811 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_ipv4options.c 1970-01-01 00:00:00.000000000 +0000
2812 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_ipv4options.c 2004-03-16 11:53:51.000000000 +0000
2815 + This is a module which is used to match ipv4 options.
2816 + This file is distributed under the terms of the GNU General Public
2817 + License (GPL). Copies of the GPL can be obtained from:
2818 + ftp://prep.ai.mit.edu/pub/gnu/GPL
2820 + 11-mars-2001 Fabrice MARIE <fabrice@netfilter.org> : initial development.
2821 + 12-july-2001 Fabrice MARIE <fabrice@netfilter.org> : added router-alert otions matching. Fixed a bug with no-srr
2822 + 12-august-2001 Imran Patel <ipatel@crosswinds.net> : optimization of the match.
2823 + 18-november-2001 Fabrice MARIE <fabrice@netfilter.org> : added [!] 'any' option match.
2824 + 19-february-2004 Harald Welte <laforge@netfilter.org> : merge with 2.6.x
2827 +#include <linux/module.h>
2828 +#include <linux/skbuff.h>
2829 +#include <net/ip.h>
2831 +#include <linux/netfilter_ipv4/ip_tables.h>
2832 +#include <linux/netfilter_ipv4/ipt_ipv4options.h>
2834 +MODULE_LICENSE("GPL");
2835 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
2838 +match(const struct sk_buff *skb,
2839 + const struct net_device *in,
2840 + const struct net_device *out,
2841 + const void *matchinfo,
2845 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
2846 + const struct iphdr *iph = skb->nh.iph;
2847 + const struct ip_options *opt;
2849 + if (iph->ihl * 4 == sizeof(struct iphdr)) {
2850 + /* No options, so we match only the "DONTs" and the "IGNOREs" */
2852 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) ||
2853 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
2854 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
2855 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
2856 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
2857 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
2862 + if ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)
2863 + /* there are options, and we don't need to care which one */
2866 + if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
2867 + /* there are options but we don't want any ! */
2872 + opt = &(IPCB(skb)->opt);
2874 + /* source routing */
2875 + if ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) {
2876 + if (!((opt->srr) & (opt->is_strictroute)))
2879 + else if ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) {
2880 + if (!((opt->srr) & (!opt->is_strictroute)))
2883 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) {
2887 + /* record route */
2888 + if ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) {
2892 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) {
2897 + if ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) {
2901 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) {
2905 + /* router-alert option */
2906 + if ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) {
2907 + if (!opt->router_alert)
2910 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) {
2911 + if (opt->router_alert)
2920 +checkentry(const char *tablename,
2921 + const struct ipt_ip *ip,
2923 + unsigned int matchsize,
2924 + unsigned int hook_mask)
2926 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
2927 + /* Check the size */
2928 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_ipv4options_info)))
2930 + /* Now check the coherence of the data ... */
2931 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) &&
2932 + (((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) ||
2933 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) ||
2934 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) ||
2935 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) ||
2936 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)))
2937 + return 0; /* opposites */
2938 + if (((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) &&
2939 + (((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
2940 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
2941 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
2942 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
2943 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) ||
2944 + ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)))
2945 + return 0; /* opposites */
2946 + if (((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) &&
2947 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR))
2948 + return 0; /* cannot match in the same time loose and strict source routing */
2949 + if ((((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
2950 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR)) &&
2951 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR))
2952 + return 0; /* opposites */
2953 + if (((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) &&
2954 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR))
2955 + return 0; /* opposites */
2956 + if (((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) &&
2957 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
2958 + return 0; /* opposites */
2959 + if (((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) &&
2960 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
2961 + return 0; /* opposites */
2963 + /* everything looks ok. */
2967 +static struct ipt_match ipv4options_match = {
2968 + .name = "ipv4options",
2970 + .checkentry = checkentry,
2974 +static int __init init(void)
2976 + return ipt_register_match(&ipv4options_match);
2979 +static void __exit fini(void)
2981 + ipt_unregister_match(&ipv4options_match);
2986 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_mport.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_mport.c
2987 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_mport.c 1970-01-01 00:00:00.000000000 +0000
2988 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_mport.c 2004-03-16 11:53:52.000000000 +0000
2990 +/* Kernel module to match one of a list of TCP/UDP ports: ports are in
2991 + the same place so we can treat them as equal. */
2992 +#include <linux/module.h>
2993 +#include <linux/types.h>
2994 +#include <linux/udp.h>
2995 +#include <linux/skbuff.h>
2997 +#include <linux/netfilter_ipv4/ipt_mport.h>
2998 +#include <linux/netfilter_ipv4/ip_tables.h>
3000 +MODULE_LICENSE("GPL");
3003 +#define duprintf(format, args...) printk(format , ## args)
3005 +#define duprintf(format, args...)
3008 +/* Returns 1 if the port is matched by the test, 0 otherwise. */
3010 +ports_match(const struct ipt_mport *minfo, u_int16_t src, u_int16_t dst)
3014 + u_int16_t pflags = minfo->pflags;
3015 + for (i=0, m=1; i<IPT_MULTI_PORTS; i++, m<<=1) {
3019 + && minfo->ports[i] == 65535)
3022 + s = minfo->ports[i];
3025 + e = minfo->ports[++i];
3030 + if (minfo->flags & IPT_MPORT_SOURCE
3031 + && src >= s && src <= e)
3034 + if (minfo->flags & IPT_MPORT_DESTINATION
3035 + && dst >= s && dst <= e)
3043 +match(const struct sk_buff *skb,
3044 + const struct net_device *in,
3045 + const struct net_device *out,
3046 + const void *matchinfo,
3051 + const struct ipt_mport *minfo = matchinfo;
3056 + /* Must be big enough to read ports (both UDP and TCP have
3057 + them at the start). */
3058 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
3059 + /* We've been asked to examine this packet, and we
3060 + can't. Hence, no choice but to drop. */
3061 + duprintf("ipt_multiport:"
3062 + " Dropping evil offset=0 tinygram.\n");
3067 + return ports_match(minfo, ntohs(ports[0]), ntohs(ports[1]));
3070 +/* Called when user tries to insert an entry of this type. */
3072 +checkentry(const char *tablename,
3073 + const struct ipt_ip *ip,
3075 + unsigned int matchsize,
3076 + unsigned int hook_mask)
3078 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_mport)))
3081 + /* Must specify proto == TCP/UDP, no unknown flags or bad count */
3082 + return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
3083 + && !(ip->invflags & IPT_INV_PROTO)
3084 + && matchsize == IPT_ALIGN(sizeof(struct ipt_mport));
3087 +static struct ipt_match mport_match = {
3090 + .checkentry = &checkentry,
3094 +static int __init init(void)
3096 + return ipt_register_match(&mport_match);
3099 +static void __exit fini(void)
3101 + ipt_unregister_match(&mport_match);
3106 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_nth.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_nth.c
3107 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_nth.c 1970-01-01 00:00:00.000000000 +0000
3108 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_nth.c 2004-03-16 11:53:53.000000000 +0000
3111 + This is a module which is used for match support for every Nth packet
3112 + This file is distributed under the terms of the GNU General Public
3113 + License (GPL). Copies of the GPL can be obtained from:
3114 + ftp://prep.ai.mit.edu/pub/gnu/GPL
3116 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
3117 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
3118 + * added support for multiple counters
3119 + * added support for matching on individual packets
3120 + in the counter cycle
3121 + 2004-02-19 Harald Welte <laforge@netfilter.org>
3126 +#include <linux/module.h>
3127 +#include <linux/skbuff.h>
3128 +#include <linux/ip.h>
3129 +#include <net/tcp.h>
3130 +#include <linux/spinlock.h>
3131 +#include <linux/netfilter_ipv4/ip_tables.h>
3132 +#include <linux/netfilter_ipv4/ipt_nth.h>
3134 +MODULE_LICENSE("GPL");
3135 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
3138 + * State information.
3145 +static struct state states[IPT_NTH_NUM_COUNTERS];
3148 +ipt_nth_match(const struct sk_buff *pskb,
3149 + const struct net_device *in,
3150 + const struct net_device *out,
3151 + const void *matchinfo,
3155 + /* Parameters from userspace */
3156 + const struct ipt_nth_info *info = matchinfo;
3157 + unsigned counter = info->counter;
3158 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
3160 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
3164 + spin_lock(&states[counter].lock);
3166 + /* Are we matching every nth packet?*/
3167 + if (info->packet == 0xFF)
3169 + /* We're matching every nth packet and only every nth packet*/
3170 + /* Do we match or invert match? */
3171 + if (info->not == 0)
3173 + if (states[counter].number == 0)
3175 + ++states[counter].number;
3178 + if (states[counter].number >= info->every)
3179 + states[counter].number = 0; /* reset the counter */
3181 + ++states[counter].number;
3186 + if (states[counter].number == 0)
3188 + ++states[counter].number;
3191 + if (states[counter].number >= info->every)
3192 + states[counter].number = 0;
3194 + ++states[counter].number;
3200 + /* We're using the --packet, so there must be a rule for every value */
3201 + if (states[counter].number == info->packet)
3203 + /* only increment the counter when a match happens */
3204 + if (states[counter].number >= info->every)
3205 + states[counter].number = 0; /* reset the counter */
3207 + ++states[counter].number;
3216 + spin_unlock(&states[counter].lock);
3220 + spin_unlock(&states[counter].lock);
3225 +ipt_nth_checkentry(const char *tablename,
3226 + const struct ipt_ip *e,
3228 + unsigned int matchsize,
3229 + unsigned int hook_mask)
3231 + /* Parameters from userspace */
3232 + const struct ipt_nth_info *info = matchinfo;
3233 + unsigned counter = info->counter;
3234 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
3236 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
3240 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_nth_info))) {
3241 + printk("nth: matchsize %u != %u\n", matchsize,
3242 + IPT_ALIGN(sizeof(struct ipt_nth_info)));
3246 + states[counter].number = info->startat;
3251 +static struct ipt_match ipt_nth_reg = {
3253 + .match = ipt_nth_match,
3254 + .checkentry = ipt_nth_checkentry,
3258 +static int __init init(void)
3262 + memset(&states, 0, sizeof(states));
3263 + for (counter = 0; counter < IPT_NTH_NUM_COUNTERS; counter++)
3264 + spin_lock_init(&(states[counter].lock));
3266 + return ipt_register_match(&ipt_nth_reg);
3269 +static void __exit fini(void)
3271 + ipt_unregister_match(&ipt_nth_reg);
3276 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_quota.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_quota.c
3277 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_quota.c 1970-01-01 00:00:00.000000000 +0000
3278 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_quota.c 2004-03-16 11:53:54.000000000 +0000
3281 + * netfilter module to enforce network quotas
3283 + * Sam Johnston <samj@samj.net>
3285 +#include <linux/module.h>
3286 +#include <linux/skbuff.h>
3287 +#include <linux/spinlock.h>
3288 +#include <linux/interrupt.h>
3290 +#include <linux/netfilter_ipv4/ip_tables.h>
3291 +#include <linux/netfilter_ipv4/ipt_quota.h>
3293 +MODULE_LICENSE("GPL");
3294 +MODULE_AUTHOR("Sam Johnston <samj@samj.net>");
3296 +static spinlock_t quota_lock = SPIN_LOCK_UNLOCKED;
3299 +match(const struct sk_buff *skb,
3300 + const struct net_device *in,
3301 + const struct net_device *out,
3302 + const void *matchinfo,
3303 + int offset, int *hotdrop)
3305 + struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
3306 + unsigned int datalen;
3308 + if (skb->len < sizeof(struct iphdr))
3311 + datalen = skb->len - skb->nh.iph->ihl*4;
3313 + spin_lock_bh("a_lock);
3315 + if (q->quota >= datalen) {
3316 + /* we can afford this one */
3317 + q->quota -= datalen;
3318 + spin_unlock_bh("a_lock);
3320 +#ifdef DEBUG_IPT_QUOTA
3321 + printk("IPT Quota OK: %llu datlen %d \n", q->quota, datalen);
3326 + /* so we do not allow even small packets from now on */
3329 +#ifdef DEBUG_IPT_QUOTA
3330 + printk("IPT Quota Failed: %llu datlen %d \n", q->quota, datalen);
3333 + spin_unlock_bh("a_lock);
3338 +checkentry(const char *tablename,
3339 + const struct ipt_ip *ip,
3340 + void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
3342 + /* TODO: spinlocks? sanity checks? */
3343 + if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info)))
3349 +static struct ipt_match quota_match = {
3352 + .checkentry = checkentry,
3359 + return ipt_register_match("a_match);
3365 + ipt_unregister_match("a_match);
3371 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_realm.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_realm.c
3372 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_realm.c 1970-01-01 00:00:00.000000000 +0000
3373 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_realm.c 2004-03-16 11:53:56.000000000 +0000
3375 +/* IP tables module for matching the routing realm
3379 + * (C) 2003 by Sampsa Ranta <sampsa@netsonic.fi>
3381 + * This program is free software; you can redistribute it and/or modify
3382 + * it under the terms of the GNU General Public License version 2 as
3383 + * published by the Free Software Foundation.
3386 +#include <linux/module.h>
3387 +#include <linux/skbuff.h>
3388 +#include <linux/netdevice.h>
3389 +#include <net/route.h>
3391 +#include <linux/netfilter_ipv4/ipt_realm.h>
3392 +#include <linux/netfilter_ipv4/ip_tables.h>
3394 +MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>");
3395 +MODULE_LICENSE("GPL");
3398 +match(const struct sk_buff *skb,
3399 + const struct net_device *in,
3400 + const struct net_device *out,
3401 + const void *matchinfo,
3405 + const struct ipt_realm_info *info = matchinfo;
3406 + struct dst_entry *dst = skb->dst;
3411 + return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
3414 +static int check(const char *tablename,
3415 + const struct ipt_ip *ip,
3417 + unsigned int matchsize,
3418 + unsigned int hook_mask)
3421 + & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
3422 + (1 << NF_IP_LOCAL_OUT)| (1 << NF_IP_LOCAL_IN))) {
3423 + printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, "
3424 + "LOCAL_IN or FORWARD.\n");
3428 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info)))
3434 +static struct ipt_match realm_match = {
3437 + .checkentry = check,
3441 +static int __init init(void)
3443 + return ipt_register_match(&realm_match);
3446 +static void __exit fini(void)
3448 + ipt_unregister_match(&realm_match);
3453 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_sctp.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_sctp.c
3454 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_sctp.c 1970-01-01 00:00:00.000000000 +0000
3455 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_sctp.c 2004-03-16 11:53:57.000000000 +0000
3457 +#include <linux/module.h>
3458 +#include <linux/skbuff.h>
3459 +#include <net/ip.h>
3460 +#include <linux/sctp.h>
3462 +#include <linux/netfilter_ipv4/ip_tables.h>
3463 +#include <linux/netfilter_ipv4/ipt_sctp.h>
3466 +#define duprintf(format, args...) printk(format , ## args)
3468 +#define duprintf(format, args...)
3471 +#define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \
3472 + || (!!((invflag) & (option)) ^ (cond)))
3475 +match_flags(const struct ipt_sctp_flag_info *flag_info,
3476 + const int flag_count,
3477 + u_int8_t chunktype,
3478 + u_int8_t chunkflags)
3482 + for (i = 0; i < flag_count; i++) {
3483 + if (flag_info[i].chunktype == chunktype) {
3484 + return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag;
3492 +match_packet(const struct sk_buff *skb,
3493 + const u_int32_t *chunkmap,
3494 + int chunk_match_type,
3495 + const struct ipt_sctp_flag_info *flag_info,
3496 + const int flag_count,
3500 + u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
3501 + sctp_chunkhdr_t sch;
3503 + if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) {
3504 + SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap);
3507 + offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t);
3509 + if (skb_copy_bits(skb, offset, &sch, sizeof(sch)) < 0) {
3510 + duprintf("Dropping invalid SCTP packet.\n");
3515 + duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n",
3516 + ++i, offset, sch.type, htons(sch.length), sch.flags);
3518 + offset += (htons(sch.length) + 3) & ~3;
3520 + duprintf("skb->len: %d\toffset: %d\n", skb->len, offset);
3522 + if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch.type)) {
3523 + switch (chunk_match_type) {
3524 + case SCTP_CHUNK_MATCH_ANY:
3525 + if (match_flags(flag_info, flag_count,
3526 + sch.type, sch.flags)) {
3531 + case SCTP_CHUNK_MATCH_ALL:
3532 + if (match_flags(flag_info, flag_count,
3533 + sch.type, sch.flags)) {
3534 + SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch.type);
3538 + case SCTP_CHUNK_MATCH_ONLY:
3539 + if (!match_flags(flag_info, flag_count,
3540 + sch.type, sch.flags)) {
3546 + switch (chunk_match_type) {
3547 + case SCTP_CHUNK_MATCH_ONLY:
3551 + } while (offset < skb->len);
3553 + switch (chunk_match_type) {
3554 + case SCTP_CHUNK_MATCH_ALL:
3555 + return SCTP_CHUNKMAP_IS_CLEAR(chunkmap);
3556 + case SCTP_CHUNK_MATCH_ANY:
3558 + case SCTP_CHUNK_MATCH_ONLY:
3562 + /* This will never be reached, but required to stop compiler whine */
3567 +match(const struct sk_buff *skb,
3568 + const struct net_device *in,
3569 + const struct net_device *out,
3570 + const void *matchinfo,
3574 + const struct ipt_sctp_info *info;
3575 + sctp_sctphdr_t sh;
3577 + info = (const struct ipt_sctp_info *)matchinfo;
3580 + duprintf("Dropping non-first fragment.. FIXME\n");
3584 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &sh, sizeof(sh)) < 0) {
3585 + duprintf("Dropping evil TCP offset=0 tinygram.\n");
3589 + duprintf("spt: %d\tdpt: %d\n", ntohs(sh.source), ntohs(sh.dest));
3591 + return SCCHECK(((ntohs(sh.source) >= info->spts[0])
3592 + && (ntohs(sh.source) <= info->spts[1])),
3593 + IPT_SCTP_SRC_PORTS, info->flags, info->invflags)
3594 + && SCCHECK(((ntohs(sh.dest) >= info->dpts[0])
3595 + && (ntohs(sh.dest) <= info->dpts[1])),
3596 + IPT_SCTP_DEST_PORTS, info->flags, info->invflags)
3597 + && SCCHECK(match_packet(skb, info->chunkmap, info->chunk_match_type,
3598 + info->flag_info, info->flag_count,
3600 + IPT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
3604 +checkentry(const char *tablename,
3605 + const struct ipt_ip *ip,
3607 + unsigned int matchsize,
3608 + unsigned int hook_mask)
3610 + const struct ipt_sctp_info *info;
3612 + info = (const struct ipt_sctp_info *)matchinfo;
3614 + return ip->proto == IPPROTO_SCTP
3615 + && !(ip->invflags & IPT_INV_PROTO)
3616 + && matchsize == IPT_ALIGN(sizeof(struct ipt_sctp_info))
3617 + && !(info->flags & ~IPT_SCTP_VALID_FLAGS)
3618 + && !(info->invflags & ~IPT_SCTP_VALID_FLAGS)
3619 + && !(info->invflags & ~info->flags)
3620 + && ((!(info->flags & IPT_SCTP_CHUNK_TYPES)) ||
3621 + (info->chunk_match_type &
3622 + (SCTP_CHUNK_MATCH_ALL
3623 + | SCTP_CHUNK_MATCH_ANY
3624 + | SCTP_CHUNK_MATCH_ONLY)));
3627 +static struct ipt_match sctp_match =
3629 + .list = { NULL, NULL},
3632 + .checkentry = &checkentry,
3637 +static int __init init(void)
3639 + return ipt_register_match(&sctp_match);
3642 +static void __exit fini(void)
3644 + ipt_unregister_match(&sctp_match);
3650 +MODULE_LICENSE("GPL");
3651 +MODULE_AUTHOR("Kiran Kumar Immidi");
3652 +MODULE_DESCRIPTION("Match for SCTP protocol packets");
3654 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_state.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_state.c
3655 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_state.c 2004-03-16 05:47:39.000000000 +0000
3656 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_state.c 2004-03-16 11:53:55.000000000 +0000
3658 enum ip_conntrack_info ctinfo;
3659 unsigned int statebit;
3661 - if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
3662 + if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
3663 + statebit = IPT_STATE_UNTRACKED;
3664 + else if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
3665 statebit = IPT_STATE_INVALID;
3667 statebit = IPT_STATE_BIT(ctinfo);
3668 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_u32.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_u32.c
3669 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_u32.c 1970-01-01 00:00:00.000000000 +0000
3670 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_u32.c 2004-03-16 11:53:58.000000000 +0000
3672 +/* Kernel module to match u32 packet content. */
3675 +U32 tests whether quantities of up to 4 bytes extracted from a packet
3676 +have specified values. The specification of what to extract is general
3677 +enough to find data at given offsets from tcp headers or payloads.
3680 + The argument amounts to a program in a small language described below.
3681 + tests := location = value | tests && location = value
3682 + value := range | value , range
3683 + range := number | number : number
3684 + a single number, n, is interpreted the same as n:n
3685 + n:m is interpreted as the range of numbers >=n and <=m
3686 + location := number | location operator number
3687 + operator := & | << | >> | @
3689 + The operators &, <<, >>, && mean the same as in c. The = is really a set
3690 + membership operator and the value syntax describes a set. The @ operator
3691 + is what allows moving to the next header and is described further below.
3693 + *** Until I can find out how to avoid it, there are some artificial limits
3694 + on the size of the tests:
3695 + - no more than 10 ='s (and 9 &&'s) in the u32 argument
3696 + - no more than 10 ranges (and 9 commas) per value
3697 + - no more than 10 numbers (and 9 operators) per location
3699 + To describe the meaning of location, imagine the following machine that
3700 + interprets it. There are three registers:
3701 + A is of type char*, initially the address of the IP header
3702 + B and C are unsigned 32 bit integers, initially zero
3704 + The instructions are:
3705 + number B = number;
3706 + C = (*(A+B)<<24)+(*(A+B+1)<<16)+(*(A+B+2)<<8)+*(A+B+3)
3707 + &number C = C&number
3708 + <<number C = C<<number
3709 + >>number C = C>>number
3710 + @number A = A+C; then do the instruction number
3711 + Any access of memory outside [skb->head,skb->end] causes the match to fail.
3712 + Otherwise the result of the computation is the final value of C.
3714 + Whitespace is allowed but not required in the tests.
3715 + However the characters that do occur there are likely to require
3716 + shell quoting, so it's a good idea to enclose the arguments in quotes.
3719 + match IP packets with total length >= 256
3720 + The IP header contains a total length field in bytes 2-3.
3721 + --u32 "0&0xFFFF=0x100:0xFFFF"
3723 + AND that with FFFF (giving bytes 2-3),
3724 + and test whether that's in the range [0x100:0xFFFF]
3726 +Example: (more realistic, hence more complicated)
3727 + match icmp packets with icmp type 0
3728 + First test that it's an icmp packet, true iff byte 9 (protocol) = 1
3729 + --u32 "6&0xFF=1 && ...
3730 + read bytes 6-9, use & to throw away bytes 6-8 and compare the result to 1
3731 + Next test that it's not a fragment.
3732 + (If so it might be part of such a packet but we can't always tell.)
3733 + n.b. This test is generally needed if you want to match anything
3734 + beyond the IP header.
3735 + The last 6 bits of byte 6 and all of byte 7 are 0 iff this is a complete
3736 + packet (not a fragment). Alternatively, you can allow first fragments
3737 + by only testing the last 5 bits of byte 6.
3738 + ... 4&0x3FFF=0 && ...
3739 + Last test: the first byte past the IP header (the type) is 0
3740 + This is where we have to use the @syntax. The length of the IP header
3741 + (IHL) in 32 bit words is stored in the right half of byte 0 of the
3743 + ... 0>>22&0x3C@0>>24=0"
3744 + The first 0 means read bytes 0-3,
3745 + >>22 means shift that 22 bits to the right. Shifting 24 bits would give
3746 + the first byte, so only 22 bits is four times that plus a few more bits.
3747 + &3C then eliminates the two extra bits on the right and the first four
3748 + bits of the first byte.
3749 + For instance, if IHL=5 then the IP header is 20 (4 x 5) bytes long.
3750 + In this case bytes 0-1 are (in binary) xxxx0101 yyzzzzzz,
3751 + >>22 gives the 10 bit value xxxx0101yy and &3C gives 010100.
3752 + @ means to use this number as a new offset into the packet, and read
3753 + four bytes starting from there. This is the first 4 bytes of the icmp
3754 + payload, of which byte 0 is the icmp type. Therefore we simply shift
3755 + the value 24 to the right to throw out all but the first byte and compare
3756 + the result with 0.
3759 + tcp payload bytes 8-12 is any of 1, 2, 5 or 8
3760 + First we test that the packet is a tcp packet (similar to icmp).
3761 + --u32 "6&0xFF=6 && ...
3762 + Next, test that it's not a fragment (same as above).
3763 + ... 0>>22&0x3C@12>>26&0x3C@8=1,2,5,8"
3764 + 0>>22&3C as above computes the number of bytes in the IP header.
3765 + @ makes this the new offset into the packet, which is the start of the
3766 + tcp header. The length of the tcp header (again in 32 bit words) is
3767 + the left half of byte 12 of the tcp header. The 12>>26&3C
3768 + computes this length in bytes (similar to the IP header before).
3769 + @ makes this the new offset, which is the start of the tcp payload.
3770 + Finally 8 reads bytes 8-12 of the payload and = checks whether the
3771 + result is any of 1, 2, 5 or 8
3774 +#include <linux/module.h>
3775 +#include <linux/skbuff.h>
3777 +#include <linux/netfilter_ipv4/ipt_u32.h>
3778 +#include <linux/netfilter_ipv4/ip_tables.h>
3780 +/* #include <asm-i386/timex.h> for timing */
3782 +MODULE_AUTHOR("Don Cohen <don@isis.cs3-inc.com>");
3783 +MODULE_DESCRIPTION("IP tables u32 matching module");
3784 +MODULE_LICENSE("GPL");
3787 +match(const struct sk_buff *skb,
3788 + const struct net_device *in,
3789 + const struct net_device *out,
3790 + const void *matchinfo,
3793 + u_int16_t datalen,
3796 + const struct ipt_u32 *data = matchinfo;
3798 + unsigned char* origbase = (char*)skb->nh.iph;
3799 + unsigned char* base = origbase;
3800 + unsigned char* head = skb->head;
3801 + unsigned char* end = skb->end;
3803 + u_int32_t pos, val;
3804 + /* unsigned long long cycles1, cycles2, cycles3, cycles4;
3805 + cycles1 = get_cycles(); */
3807 + for (testind=0; testind < data->ntests; testind++) {
3808 + base = origbase; /* reset for each test */
3809 + pos = data->tests[testind].location[0].number;
3810 + if (base+pos+3 > end || base+pos < head)
3812 + val = (base[pos]<<24) + (base[pos+1]<<16) +
3813 + (base[pos+2]<<8) + base[pos+3];
3814 + nnums = data->tests[testind].nnums;
3815 + for (i=1; i < nnums; i++) {
3816 + u_int32_t number = data->tests[testind].location[i].number;
3817 + switch (data->tests[testind].location[i].nextop) {
3819 + val = val & number;
3821 + case IPT_U32_LEFTSH:
3822 + val = val << number;
3824 + case IPT_U32_RIGHTSH:
3825 + val = val >> number;
3828 + base = base + val;
3830 + if (base+pos+3 > end || base+pos < head)
3832 + val = (base[pos]<<24) + (base[pos+1]<<16) +
3833 + (base[pos+2]<<8) + base[pos+3];
3837 + nvals = data->tests[testind].nvalues;
3838 + for (i=0; i < nvals; i++) {
3839 + if ((data->tests[testind].value[i].min <= val) &&
3840 + (val <= data->tests[testind].value[i].max)) {
3844 + if (i >= data->tests[testind].nvalues) {
3845 + /* cycles2 = get_cycles();
3846 + printk("failed %d in %d cycles\n", testind,
3847 + cycles2-cycles1); */
3851 + /* cycles2 = get_cycles();
3852 + printk("succeeded in %d cycles\n", cycles2-cycles1); */
3857 +checkentry(const char *tablename,
3858 + const struct ipt_ip *ip,
3860 + unsigned int matchsize,
3861 + unsigned int hook_mask)
3863 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_u32)))
3868 +static struct ipt_match u32_match
3869 += { { NULL, NULL }, "u32", &match, &checkentry, NULL, THIS_MODULE };
3871 +static int __init init(void)
3873 + return ipt_register_match(&u32_match);
3876 +static void __exit fini(void)
3878 + ipt_unregister_match(&u32_match);
3883 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/iptable_raw.c linux-2.6.5-rc1/net/ipv4/netfilter/iptable_raw.c
3884 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/iptable_raw.c 1970-01-01 00:00:00.000000000 +0000
3885 +++ linux-2.6.5-rc1/net/ipv4/netfilter/iptable_raw.c 2004-03-16 11:53:55.000000000 +0000
3888 + * 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT .
3890 + * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
3892 +#include <linux/module.h>
3893 +#include <linux/netfilter_ipv4/ip_tables.h>
3895 +#define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
3897 +/* Standard entry. */
3898 +struct ipt_standard
3900 + struct ipt_entry entry;
3901 + struct ipt_standard_target target;
3904 +struct ipt_error_target
3906 + struct ipt_entry_target target;
3907 + char errorname[IPT_FUNCTION_MAXNAMELEN];
3912 + struct ipt_entry entry;
3913 + struct ipt_error_target target;
3918 + struct ipt_replace repl;
3919 + struct ipt_standard entries[2];
3920 + struct ipt_error term;
3921 +} initial_table __initdata
3922 += { { "raw", RAW_VALID_HOOKS, 3,
3923 + sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
3924 + { [NF_IP_PRE_ROUTING] 0,
3925 + [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
3926 + { [NF_IP_PRE_ROUTING] 0,
3927 + [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
3931 + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
3933 + sizeof(struct ipt_entry),
3934 + sizeof(struct ipt_standard),
3935 + 0, { 0, 0 }, { } },
3936 + { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
3937 + -NF_ACCEPT - 1 } },
3939 + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
3941 + sizeof(struct ipt_entry),
3942 + sizeof(struct ipt_standard),
3943 + 0, { 0, 0 }, { } },
3944 + { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
3945 + -NF_ACCEPT - 1 } }
3948 + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
3950 + sizeof(struct ipt_entry),
3951 + sizeof(struct ipt_error),
3952 + 0, { 0, 0 }, { } },
3953 + { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },
3960 +static struct ipt_table packet_raw = {
3962 + .table = &initial_table.repl,
3963 + .valid_hooks = RAW_VALID_HOOKS,
3964 + .lock = RW_LOCK_UNLOCKED,
3968 +/* The work comes in here from netfilter.c. */
3969 +static unsigned int
3970 +ipt_hook(unsigned int hook,
3971 + struct sk_buff **pskb,
3972 + const struct net_device *in,
3973 + const struct net_device *out,
3974 + int (*okfn)(struct sk_buff *))
3976 + return ipt_do_table(pskb, hook, in, out, &packet_raw, NULL);
3979 +/* 'raw' is the very first table. */
3980 +static struct nf_hook_ops ipt_ops[] = {
3984 + .hooknum = NF_IP_PRE_ROUTING,
3985 + .priority = NF_IP_PRI_RAW
3990 + .hooknum = NF_IP_LOCAL_OUT,
3991 + .priority = NF_IP_PRI_RAW
3995 +static int __init init(void)
3999 + /* Register table */
4000 + ret = ipt_register_table(&packet_raw);
4004 + /* Register hooks */
4005 + ret = nf_register_hook(&ipt_ops[0]);
4007 + goto cleanup_table;
4009 + ret = nf_register_hook(&ipt_ops[1]);
4011 + goto cleanup_hook0;
4016 + nf_unregister_hook(&ipt_ops[0]);
4018 + ipt_unregister_table(&packet_raw);
4023 +static void __exit fini(void)
4027 + for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++)
4028 + nf_unregister_hook(&ipt_ops[i]);
4030 + ipt_unregister_table(&packet_raw);
4035 +MODULE_LICENSE("GPL");
4036 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv6/netfilter/Kconfig linux-2.6.5-rc1/net/ipv6/netfilter/Kconfig
4037 --- linux-2.6.5-rc1.org/net/ipv6/netfilter/Kconfig 2004-03-16 05:47:18.000000000 +0000
4038 +++ linux-2.6.5-rc1/net/ipv6/netfilter/Kconfig 2004-03-16 11:53:55.000000000 +0000
4039 @@ -218,5 +218,37 @@
4040 To compile it as a module, choose M here. If unsure, say N.
4042 #dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
4043 +config IP6_NF_TARGET_HL
4044 + tristate 'HL target support'
4045 + depends on IP6_NF_MANGLE
4048 +config IP6_NF_TARGET_REJECT
4049 + tristate 'REJECT target support'
4050 + depends on IP6_NF_FILTER
4053 +config IP6_NF_MATCH_FUZZY
4054 + tristate 'Fuzzy match support'
4055 + depends on IP6_NF_FILTER
4058 +config IP6_NF_MATCH_NTH
4059 + tristate 'Nth match support'
4060 + depends on IP6_NF_IPTABLES
4064 + tristate 'raw table support (required for TRACE)'
4065 + depends on IP6_NF_IPTABLES
4067 + This option adds a `raw' table to ip6tables. This table is the very
4068 + first in the netfilter framework and hooks in at the PREROUTING
4069 + and OUTPUT chains.
4071 + If you want to compile it as a module, say M here and read
4072 + <file:Documentation/modules.txt>. If unsure, say `N'.
4077 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv6/netfilter/Makefile linux-2.6.5-rc1/net/ipv6/netfilter/Makefile
4078 --- linux-2.6.5-rc1.org/net/ipv6/netfilter/Makefile 2004-03-16 05:46:44.000000000 +0000
4079 +++ linux-2.6.5-rc1/net/ipv6/netfilter/Makefile 2004-03-16 11:53:55.000000000 +0000
4081 obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
4082 obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
4083 obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
4084 +obj-$(CONFIG_IP6_NF_MATCH_FUZZY) += ip6t_fuzzy.o
4085 obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
4086 obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
4087 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
4089 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
4090 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
4091 obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
4092 +obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
4093 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
4094 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
4095 +obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
4097 +obj-$(CONFIG_IP6_NF_MATCH_NTH) += ip6t_nth.o
4098 +obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
4099 obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
4100 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv6/netfilter/ip6t_HL.c linux-2.6.5-rc1/net/ipv6/netfilter/ip6t_HL.c
4101 --- linux-2.6.5-rc1.org/net/ipv6/netfilter/ip6t_HL.c 1970-01-01 00:00:00.000000000 +0000
4102 +++ linux-2.6.5-rc1/net/ipv6/netfilter/ip6t_HL.c 2004-03-16 11:53:43.000000000 +0000
4105 + * Hop Limit modification target for ip6tables
4106 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
4107 + * Based on HW's TTL module
4109 + * This software is distributed under the terms of GNU GPL
4112 +#include <linux/module.h>
4113 +#include <linux/skbuff.h>
4114 +#include <linux/ip.h>
4116 +#include <linux/netfilter_ipv6/ip6_tables.h>
4117 +#include <linux/netfilter_ipv6/ip6t_HL.h>
4119 +MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
4120 +MODULE_DESCRIPTION("IP tables Hop Limit modification module");
4121 +MODULE_LICENSE("GPL");
4123 +static unsigned int ip6t_hl_target(struct sk_buff **pskb, unsigned int hooknum,
4124 + const struct net_device *in, const struct net_device *out,
4125 + const void *targinfo, void *userinfo)
4127 + struct ipv6hdr *ip6h = (*pskb)->nh.ipv6h;
4128 + const struct ip6t_HL_info *info = targinfo;
4129 + u_int16_t diffs[2];
4132 + switch (info->mode) {
4134 + new_hl = info->hop_limit;
4137 + new_hl = ip6h->hop_limit + info->hop_limit;
4142 + new_hl = ip6h->hop_limit + info->hop_limit;
4147 + new_hl = ip6h->hop_limit;
4151 + if (new_hl != ip6h->hop_limit) {
4152 + diffs[0] = htons(((unsigned)ip6h->hop_limit) << 8) ^ 0xFFFF;
4153 + ip6h->hop_limit = new_hl;
4154 + diffs[1] = htons(((unsigned)ip6h->hop_limit) << 8);
4157 + return IP6T_CONTINUE;
4160 +static int ip6t_hl_checkentry(const char *tablename,
4161 + const struct ip6t_entry *e,
4163 + unsigned int targinfosize,
4164 + unsigned int hook_mask)
4166 + struct ip6t_HL_info *info = targinfo;
4168 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_HL_info))) {
4169 + printk(KERN_WARNING "HL: targinfosize %u != %Zu\n",
4171 + IP6T_ALIGN(sizeof(struct ip6t_HL_info)));
4175 + if (strcmp(tablename, "mangle")) {
4176 + printk(KERN_WARNING "HL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
4180 + if (info->mode > IP6T_HL_MAXMODE) {
4181 + printk(KERN_WARNING "HL: invalid or unknown Mode %u\n",
4186 + if ((info->mode != IP6T_HL_SET) && (info->hop_limit == 0)) {
4187 + printk(KERN_WARNING "HL: increment/decrement doesn't make sense with value 0\n");
4194 +static struct ip6t_target ip6t_HL = { { NULL, NULL }, "HL",
4195 + ip6t_hl_target, ip6t_hl_checkentry, NULL, THIS_MODULE };
4197 +static int __init init(void)
4199 + return ip6t_register_target(&ip6t_HL);
4202 +static void __exit fini(void)
4204 + ip6t_unregister_target(&ip6t_HL);
4209 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv6/netfilter/ip6t_LOG.c linux-2.6.5-rc1/net/ipv6/netfilter/ip6t_LOG.c
4210 --- linux-2.6.5-rc1.org/net/ipv6/netfilter/ip6t_LOG.c 2004-03-16 05:45:58.000000000 +0000
4211 +++ linux-2.6.5-rc1/net/ipv6/netfilter/ip6t_LOG.c 2004-03-16 11:53:42.000000000 +0000
4213 #include <net/udp.h>
4214 #include <net/tcp.h>
4215 #include <net/ipv6.h>
4216 +#include <linux/netfilter.h>
4217 #include <linux/netfilter_ipv6/ip6_tables.h>
4219 MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
4220 MODULE_DESCRIPTION("IP6 tables LOG target module");
4221 MODULE_LICENSE("GPL");
4223 +static unsigned int nflog = 1;
4224 +MODULE_PARM(nflog, "i");
4225 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
4228 #include <net/route.h>
4229 #include <linux/netfilter_ipv6/ip6t_LOG.h>
4230 @@ -265,40 +270,38 @@
4234 -static unsigned int
4235 -ip6t_log_target(struct sk_buff **pskb,
4236 - unsigned int hooknum,
4238 +ip6t_log_packet(unsigned int hooknum,
4239 + const struct sk_buff *skb,
4240 const struct net_device *in,
4241 const struct net_device *out,
4242 - const void *targinfo,
4244 + const struct ip6t_log_info *loginfo,
4245 + const char *level_string,
4246 + const char *prefix)
4248 - struct ipv6hdr *ipv6h = (*pskb)->nh.ipv6h;
4249 - const struct ip6t_log_info *loginfo = targinfo;
4250 - char level_string[4] = "< >";
4251 + struct ipv6hdr *ipv6h = skb->nh.ipv6h;
4253 - level_string[1] = '0' + (loginfo->level % 8);
4254 spin_lock_bh(&log_lock);
4255 printk(level_string);
4256 printk("%sIN=%s OUT=%s ",
4258 + prefix == NULL ? loginfo->prefix : prefix,
4260 out ? out->name : "");
4262 /* MAC logging for input chain only. */
4264 - if ((*pskb)->dev && (*pskb)->dev->hard_header_len && (*pskb)->mac.raw != (void*)ipv6h) {
4265 - if ((*pskb)->dev->type != ARPHRD_SIT){
4266 + if (skb->dev && skb->dev->hard_header_len && skb->mac.raw != (void*)ipv6h) {
4267 + if (skb->dev->type != ARPHRD_SIT){
4269 - unsigned char *p = (*pskb)->mac.raw;
4270 - for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++)
4271 + unsigned char *p = skb->mac.raw;
4272 + for (i = 0; i < skb->dev->hard_header_len; i++,p++)
4273 printk("%02x%c", *p,
4274 - i==(*pskb)->dev->hard_header_len - 1
4275 + i==skb->dev->hard_header_len - 1
4279 - unsigned char *p = (*pskb)->mac.raw;
4280 - if ( p - (ETH_ALEN*2+2) > (*pskb)->head ){
4281 + unsigned char *p = skb->mac.raw;
4282 + if ( p - (ETH_ALEN*2+2) > skb->head ){
4284 for (i = 0; i < (ETH_ALEN); i++,p++)
4285 printk("%02x%s", *p,
4286 @@ -309,10 +312,10 @@
4287 i == ETH_ALEN-1 ? ' ' : ':');
4290 - if (((*pskb)->dev->addr_len == 4) &&
4291 - (*pskb)->dev->hard_header_len > 20){
4292 + if ((skb->dev->addr_len == 4) &&
4293 + skb->dev->hard_header_len > 20){
4295 - p = (*pskb)->mac.raw + 12;
4296 + p = skb->mac.raw + 12;
4297 for (i = 0; i < 4; i++,p++)
4299 i == 3 ? "->" : ".");
4300 @@ -328,10 +331,41 @@
4301 dump_packet(loginfo, ipv6h, 1);
4303 spin_unlock_bh(&log_lock);
4306 +static unsigned int
4307 +ip6t_log_target(struct sk_buff **pskb,
4308 + unsigned int hooknum,
4309 + const struct net_device *in,
4310 + const struct net_device *out,
4311 + const void *targinfo,
4314 + const struct ip6t_log_info *loginfo = targinfo;
4315 + char level_string[4] = "< >";
4317 + level_string[1] = '0' + (loginfo->level % 8);
4318 + ip6t_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
4320 return IP6T_CONTINUE;
4324 +ip6t_logfn(unsigned int hooknum,
4325 + const struct sk_buff *skb,
4326 + const struct net_device *in,
4327 + const struct net_device *out,
4328 + const char *prefix)
4330 + struct ip6t_log_info loginfo = {
4332 + .logflags = IP6T_LOG_MASK,
4336 + ip6t_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
4339 static int ip6t_log_checkentry(const char *tablename,
4340 const struct ip6t_entry *e,
4342 @@ -360,20 +394,27 @@
4346 -static struct ip6t_target ip6t_log_reg
4347 -= { { NULL, NULL }, "LOG", ip6t_log_target, ip6t_log_checkentry, NULL,
4349 +static struct ip6t_target ip6t_log_reg = {
4351 + .target = ip6t_log_target,
4352 + .checkentry = ip6t_log_checkentry,
4353 + .me = THIS_MODULE,
4356 static int __init init(void)
4358 if (ip6t_register_target(&ip6t_log_reg))
4361 + nf_log_register(PF_INET6, &ip6t_logfn);
4366 static void __exit fini(void)
4369 + nf_log_unregister(PF_INET6, &ip6t_logfn);
4370 ip6t_unregister_target(&ip6t_log_reg);
4373 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv6/netfilter/ip6t_REJECT.c linux-2.6.5-rc1/net/ipv6/netfilter/ip6t_REJECT.c
4374 --- linux-2.6.5-rc1.org/net/ipv6/netfilter/ip6t_REJECT.c 1970-01-01 00:00:00.000000000 +0000
4375 +++ linux-2.6.5-rc1/net/ipv6/netfilter/ip6t_REJECT.c 2004-03-16 11:53:45.000000000 +0000
4378 + * This is a module which is used for rejecting packets.
4379 + * Added support for customized reject packets (Jozsef Kadlecsik).
4381 + * Port to IPv6 / ip6tables (Harald Welte <laforge@gnumonks.org>)
4383 +#include <linux/config.h>
4384 +#include <linux/module.h>
4385 +#include <linux/skbuff.h>
4386 +#include <linux/icmpv6.h>
4387 +#include <net/tcp.h>
4388 +#include <linux/netfilter_ipv6/ip6_tables.h>
4389 +#include <linux/netfilter_ipv6/ip6t_REJECT.h>
4392 +#define DEBUGP printk
4394 +#define DEBUGP(format, args...)
4398 +/* Send RST reply */
4399 +static void send_reset(struct sk_buff *oldskb)
4401 + struct sk_buff *nskb;
4402 + struct tcphdr *otcph, *tcph;
4403 + struct rtable *rt;
4404 + unsigned int otcplen;
4407 + /* IP header checks: fragment, too short. */
4408 + if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)
4409 + || oldskb->len < (oldskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
4412 + otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl);
4413 + otcplen = oldskb->len - oldskb->nh.iph->ihl*4;
4415 + /* No RST for RST. */
4419 + /* Check checksum. */
4420 + if (tcp_v4_check(otcph, otcplen, oldskb->nh.iph->saddr,
4421 + oldskb->nh.iph->daddr,
4422 + csum_partial((char *)otcph, otcplen, 0)) != 0)
4425 + /* Copy skb (even if skb is about to be dropped, we can't just
4426 + clone it because there may be other things, such as tcpdump,
4427 + interested in it) */
4428 + nskb = skb_copy(oldskb, GFP_ATOMIC);
4432 + /* This packet will not be the same as the other: clear nf fields */
4433 + nf_conntrack_put(nskb->nfct);
4434 + nskb->nfct = NULL;
4435 + nskb->nfcache = 0;
4436 +#ifdef CONFIG_NETFILTER_DEBUG
4437 + nskb->nf_debug = 0;
4440 + tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
4442 + nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
4443 + tcph->source = xchg(&tcph->dest, tcph->source);
4445 + /* Truncate to length (no data) */
4446 + tcph->doff = sizeof(struct tcphdr)/4;
4447 + skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
4448 + nskb->nh.iph->tot_len = htons(nskb->len);
4452 + tcph->seq = otcph->ack_seq;
4453 + tcph->ack_seq = 0;
4456 + tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin
4457 + + otcplen - (otcph->doff<<2));
4462 + ((u_int8_t *)tcph)[13] = 0;
4464 + tcph->ack = needs_ack;
4467 + tcph->urg_ptr = 0;
4469 + /* Adjust TCP checksum */
4471 + tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
4472 + nskb->nh.iph->saddr,
4473 + nskb->nh.iph->daddr,
4474 + csum_partial((char *)tcph,
4475 + sizeof(struct tcphdr), 0));
4477 + /* Adjust IP TTL, DF */
4478 + nskb->nh.iph->ttl = MAXTTL;
4479 + /* Set DF, id = 0 */
4480 + nskb->nh.iph->frag_off = htons(IP_DF);
4481 + nskb->nh.iph->id = 0;
4483 + /* Adjust IP checksum */
4484 + nskb->nh.iph->check = 0;
4485 + nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
4486 + nskb->nh.iph->ihl);
4489 + if (ip_route_output(&rt, nskb->nh.iph->daddr, nskb->nh.iph->saddr,
4490 + RT_TOS(nskb->nh.iph->tos) | RTO_CONN,
4494 + dst_release(nskb->dst);
4495 + nskb->dst = &rt->u.dst;
4497 + /* "Never happens" */
4498 + if (nskb->len > nskb->dst->pmtu)
4501 + NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
4502 + ip_finish_output);
4510 +static unsigned int reject6_target(struct sk_buff **pskb,
4511 + unsigned int hooknum,
4512 + const struct net_device *in,
4513 + const struct net_device *out,
4514 + const void *targinfo,
4517 + const struct ip6t_reject_info *reject = targinfo;
4519 + /* WARNING: This code causes reentry within ip6tables.
4520 + This means that the ip6tables jump stack is now crap. We
4521 + must return an absolute verdict. --RR */
4522 + DEBUGP("REJECTv6: calling icmpv6_send\n");
4523 + switch (reject->with) {
4524 + case IP6T_ICMP6_NO_ROUTE:
4525 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, out);
4527 + case IP6T_ICMP6_ADM_PROHIBITED:
4528 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADM_PROHIBITED, 0, out);
4530 + case IP6T_ICMP6_NOT_NEIGHBOUR:
4531 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOT_NEIGHBOUR, 0, out);
4533 + case IP6T_ICMP6_ADDR_UNREACH:
4534 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, out);
4536 + case IP6T_ICMP6_PORT_UNREACH:
4537 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, out);
4540 + case IPT_ICMP_ECHOREPLY: {
4541 + struct icmp6hdr *icmph = (struct icmphdr *)
4542 + ((u_int32_t *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl);
4543 + unsigned int datalen = (*pskb)->len - (*pskb)->nh.iph->ihl * 4;
4545 + /* Not non-head frags, or truncated */
4546 + if (((ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET) == 0)
4547 + && datalen >= 4) {
4548 + /* Usually I don't like cut & pasting code,
4549 + but dammit, my party is starting in 45
4551 + struct icmp_bxm icmp_param;
4553 + icmp_param.icmph=*icmph;
4554 + icmp_param.icmph.type=ICMP_ECHOREPLY;
4555 + icmp_param.data_ptr=(icmph+1);
4556 + icmp_param.data_len=datalen;
4557 + icmp_reply(&icmp_param, *pskb);
4561 + case IPT_TCP_RESET:
4562 + send_reset(*pskb);
4566 + printk(KERN_WARNING "REJECTv6: case %u not handled yet\n", reject->with);
4573 +static inline int find_ping_match(const struct ip6t_entry_match *m)
4575 + const struct ip6t_icmp *icmpinfo = (const struct ip6t_icmp *)m->data;
4577 + if (strcmp(m->u.kernel.match->name, "icmp6") == 0
4578 + && icmpinfo->type == ICMPV6_ECHO_REQUEST
4579 + && !(icmpinfo->invflags & IP6T_ICMP_INV))
4585 +static int check(const char *tablename,
4586 + const struct ip6t_entry *e,
4588 + unsigned int targinfosize,
4589 + unsigned int hook_mask)
4591 + const struct ip6t_reject_info *rejinfo = targinfo;
4593 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
4594 + DEBUGP("REJECTv6: targinfosize %u != 0\n", targinfosize);
4598 + /* Only allow these for packet filtering. */
4599 + if (strcmp(tablename, "filter") != 0) {
4600 + DEBUGP("REJECTv6: bad table `%s'.\n", tablename);
4603 + if ((hook_mask & ~((1 << NF_IP6_LOCAL_IN)
4604 + | (1 << NF_IP6_FORWARD)
4605 + | (1 << NF_IP6_LOCAL_OUT))) != 0) {
4606 + DEBUGP("REJECTv6: bad hook mask %X\n", hook_mask);
4610 + if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
4611 + /* Must specify that it's an ICMP ping packet. */
4612 + if (e->ipv6.proto != IPPROTO_ICMPV6
4613 + || (e->ipv6.invflags & IP6T_INV_PROTO)) {
4614 + DEBUGP("REJECTv6: ECHOREPLY illegal for non-icmp\n");
4617 + /* Must contain ICMP match. */
4618 + if (IP6T_MATCH_ITERATE(e, find_ping_match) == 0) {
4619 + DEBUGP("REJECTv6: ECHOREPLY illegal for non-ping\n");
4622 + } else if (rejinfo->with == IP6T_TCP_RESET) {
4623 + /* Must specify that it's a TCP packet */
4624 + if (e->ipv6.proto != IPPROTO_TCP
4625 + || (e->ipv6.invflags & IP6T_INV_PROTO)) {
4626 + DEBUGP("REJECTv6: TCP_RESET illegal for non-tcp\n");
4634 +static struct ip6t_target ip6t_reject_reg
4635 += { { NULL, NULL }, "REJECT", reject6_target, check, NULL, THIS_MODULE };
4637 +static int __init init(void)
4639 + if (ip6t_register_target(&ip6t_reject_reg))
4644 +static void __exit fini(void)
4646 + ip6t_unregister_target(&ip6t_reject_reg);
4651 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv6/netfilter/ip6t_fuzzy.c linux-2.6.5-rc1/net/ipv6/netfilter/ip6t_fuzzy.c
4652 --- linux-2.6.5-rc1.org/net/ipv6/netfilter/ip6t_fuzzy.c 1970-01-01 00:00:00.000000000 +0000
4653 +++ linux-2.6.5-rc1/net/ipv6/netfilter/ip6t_fuzzy.c 2004-03-16 11:53:50.000000000 +0000
4656 + * This module implements a simple TSK FLC
4657 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
4658 + * to limit , in an adaptive and flexible way , the packet rate crossing
4659 + * a given stream . It serves as an initial and very simple (but effective)
4660 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
4661 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
4662 + * into our code in a precise , adaptive and efficient manner.
4663 + * The goal is very similar to that of "limit" match , but using techniques of
4664 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
4665 + * avoiding over and undershoots - and stuff like that .
4668 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
4669 + * 2002-08-17 : Changed to eliminate floating point operations .
4670 + * 2002-08-23 : Coding style changes .
4671 + * 2003-04-08 Maciej Soltysiak <solt@dns.toxicilms.tv> : IPv6 Port
4674 +#include <linux/module.h>
4675 +#include <linux/skbuff.h>
4676 +#include <linux/ipv6.h>
4677 +#include <linux/random.h>
4678 +#include <net/tcp.h>
4679 +#include <linux/spinlock.h>
4680 +#include <linux/netfilter_ipv6/ip6_tables.h>
4681 +#include <linux/netfilter_ipv6/ip6t_fuzzy.h>
4684 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
4685 + Expressed in percentage
4688 +#define PAR_LOW 1/100
4691 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED;
4693 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
4694 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
4695 +MODULE_LICENSE("GPL");
4697 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
4699 + if (tx >= maxi) return 100;
4701 + if (tx <= mini) return 0;
4703 + return ((100 * (tx-mini)) / (maxi-mini));
4706 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
4708 + if (tx <= mini) return 100;
4710 + if (tx >= maxi) return 0;
4712 + return ((100 * (maxi - tx)) / (maxi - mini));
4717 +ip6t_fuzzy_match(const struct sk_buff *pskb,
4718 + const struct net_device *in,
4719 + const struct net_device *out,
4720 + const void *matchinfo,
4723 + u_int16_t datalen,
4726 + /* From userspace */
4728 + struct ip6t_fuzzy_info *info = (struct ip6t_fuzzy_info *) matchinfo;
4730 + u_int8_t random_number;
4731 + unsigned long amount;
4732 + u_int8_t howhigh, howlow;
4735 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
4737 + info->bytes_total += pskb->len;
4738 + info->packets_total++;
4740 + info->present_time = jiffies;
4742 + if (info->present_time >= info->previous_time)
4743 + amount = info->present_time - info->previous_time;
4745 + /* There was a transition : I choose to re-sample
4746 + and keep the old acceptance rate...
4750 + info->previous_time = info->present_time;
4751 + info->bytes_total = info->packets_total = 0;
4754 + if ( amount > HZ/10) {/* More than 100 ms elapsed ... */
4756 + info->mean_rate = (u_int32_t) ((HZ * info->packets_total) \
4759 + info->previous_time = info->present_time;
4760 + info->bytes_total = info->packets_total = 0;
4762 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
4763 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
4765 + info->acceptance_rate = (u_int8_t) \
4766 + (howhigh * PAR_LOW + PAR_HIGH * howlow);
4768 + /* In fact, the above defuzzification would require a denominator
4769 + * proportional to (howhigh+howlow) but, in this particular case,
4770 + * that expression is constant.
4771 + * An imediate consequence is that it is not necessary to call
4772 + * both mf_high and mf_low - but to keep things understandable,
4778 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
4781 + if (info->acceptance_rate < 100)
4783 + get_random_bytes((void *)(&random_number), 1);
4785 + /* If within the acceptance , it can pass => don't match */
4786 + if (random_number <= (255 * info->acceptance_rate) / 100)
4789 + return 1; /* It can't pass (It matches) */
4792 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
4797 +ip6t_fuzzy_checkentry(const char *tablename,
4798 + const struct ip6t_ip6 *ip,
4800 + unsigned int matchsize,
4801 + unsigned int hook_mask)
4804 + const struct ip6t_fuzzy_info *info = matchinfo;
4806 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info))) {
4807 + printk("ip6t_fuzzy: matchsize %u != %u\n", matchsize,
4808 + IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info)));
4812 + if ((info->minimum_rate < MINFUZZYRATE) || (info->maximum_rate > MAXFUZZYRATE)
4813 + || (info->minimum_rate >= info->maximum_rate)) {
4814 + printk("ip6t_fuzzy: BAD limits , please verify !!!\n");
4821 +static struct ip6t_match ip6t_fuzzy_reg = {
4825 + ip6t_fuzzy_checkentry,
4829 +static int __init init(void)
4831 + if (ip6t_register_match(&ip6t_fuzzy_reg))
4837 +static void __exit fini(void)
4839 + ip6t_unregister_match(&ip6t_fuzzy_reg);
4844 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv6/netfilter/ip6t_nth.c linux-2.6.5-rc1/net/ipv6/netfilter/ip6t_nth.c
4845 --- linux-2.6.5-rc1.org/net/ipv6/netfilter/ip6t_nth.c 1970-01-01 00:00:00.000000000 +0000
4846 +++ linux-2.6.5-rc1/net/ipv6/netfilter/ip6t_nth.c 2004-03-16 11:53:53.000000000 +0000
4849 + This is a module which is used for match support for every Nth packet
4850 + This file is distributed under the terms of the GNU General Public
4851 + License (GPL). Copies of the GPL can be obtained from:
4852 + ftp://prep.ai.mit.edu/pub/gnu/GPL
4854 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
4855 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
4856 + * added support for multiple counters
4857 + * added support for matching on individual packets
4858 + in the counter cycle
4859 + 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
4863 +#include <linux/module.h>
4864 +#include <linux/skbuff.h>
4865 +#include <linux/ip.h>
4866 +#include <net/tcp.h>
4867 +#include <linux/spinlock.h>
4868 +#include <linux/netfilter_ipv6/ip6_tables.h>
4869 +#include <linux/netfilter_ipv6/ip6t_nth.h>
4871 +MODULE_LICENSE("GPL");
4874 + * State information.
4881 +static struct state states[IP6T_NTH_NUM_COUNTERS];
4884 +ip6t_nth_match(const struct sk_buff *pskb,
4885 + const struct net_device *in,
4886 + const struct net_device *out,
4887 + const void *matchinfo,
4890 + u_int16_t datalen,
4893 + /* Parameters from userspace */
4894 + const struct ip6t_nth_info *info = matchinfo;
4895 + unsigned counter = info->counter;
4896 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
4898 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
4902 + spin_lock(&states[counter].lock);
4904 + /* Are we matching every nth packet?*/
4905 + if (info->packet == 0xFF)
4907 + /* We're matching every nth packet and only every nth packet*/
4908 + /* Do we match or invert match? */
4909 + if (info->not == 0)
4911 + if (states[counter].number == 0)
4913 + ++states[counter].number;
4916 + if (states[counter].number >= info->every)
4917 + states[counter].number = 0; /* reset the counter */
4919 + ++states[counter].number;
4924 + if (states[counter].number == 0)
4926 + ++states[counter].number;
4929 + if (states[counter].number >= info->every)
4930 + states[counter].number = 0;
4932 + ++states[counter].number;
4938 + /* We're using the --packet, so there must be a rule for every value */
4939 + if (states[counter].number == info->packet)
4941 + /* only increment the counter when a match happens */
4942 + if (states[counter].number >= info->every)
4943 + states[counter].number = 0; /* reset the counter */
4945 + ++states[counter].number;
4954 + spin_unlock(&states[counter].lock);
4958 + spin_unlock(&states[counter].lock);
4963 +ip6t_nth_checkentry(const char *tablename,
4964 + const struct ip6t_ip6 *e,
4966 + unsigned int matchsize,
4967 + unsigned int hook_mask)
4969 + /* Parameters from userspace */
4970 + const struct ip6t_nth_info *info = matchinfo;
4971 + unsigned counter = info->counter;
4972 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
4974 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
4978 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_nth_info))) {
4979 + printk("nth: matchsize %u != %u\n", matchsize,
4980 + IP6T_ALIGN(sizeof(struct ip6t_nth_info)));
4984 + states[counter].number = info->startat;
4989 +static struct ip6t_match ip6t_nth_reg = {
4993 + ip6t_nth_checkentry,
4997 +static int __init init(void)
5000 + memset(&states, 0, sizeof(states));
5001 + if (ip6t_register_match(&ip6t_nth_reg))
5004 + for(counter = 0; counter < IP6T_NTH_NUM_COUNTERS; counter++)
5006 + spin_lock_init(&(states[counter].lock));
5009 + printk("ip6t_nth match loaded\n");
5013 +static void __exit fini(void)
5015 + ip6t_unregister_match(&ip6t_nth_reg);
5016 + printk("ip6t_nth match unloaded\n");
5021 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv6/netfilter/ip6table_raw.c linux-2.6.5-rc1/net/ipv6/netfilter/ip6table_raw.c
5022 --- linux-2.6.5-rc1.org/net/ipv6/netfilter/ip6table_raw.c 1970-01-01 00:00:00.000000000 +0000
5023 +++ linux-2.6.5-rc1/net/ipv6/netfilter/ip6table_raw.c 2004-03-16 11:53:55.000000000 +0000
5026 + * IPv6 raw table, a port of the IPv4 raw table to IPv6
5028 + * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
5030 +#include <linux/module.h>
5031 +#include <linux/netfilter_ipv6/ip6_tables.h>
5033 +#define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT))
5036 +#define DEBUGP(x, args...) printk(KERN_DEBUG x, ## args)
5038 +#define DEBUGP(x, args...)
5041 +/* Standard entry. */
5042 +struct ip6t_standard
5044 + struct ip6t_entry entry;
5045 + struct ip6t_standard_target target;
5048 +struct ip6t_error_target
5050 + struct ip6t_entry_target target;
5051 + char errorname[IP6T_FUNCTION_MAXNAMELEN];
5056 + struct ip6t_entry entry;
5057 + struct ip6t_error_target target;
5062 + struct ip6t_replace repl;
5063 + struct ip6t_standard entries[2];
5064 + struct ip6t_error term;
5065 +} initial_table __initdata
5066 += { { "raw", RAW_VALID_HOOKS, 3,
5067 + sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error),
5068 + { [NF_IP6_PRE_ROUTING] 0,
5069 + [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) },
5070 + { [NF_IP6_PRE_ROUTING] 0,
5071 + [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) },
5075 + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
5077 + sizeof(struct ip6t_entry),
5078 + sizeof(struct ip6t_standard),
5079 + 0, { 0, 0 }, { } },
5080 + { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
5081 + -NF_ACCEPT - 1 } },
5083 + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
5085 + sizeof(struct ip6t_entry),
5086 + sizeof(struct ip6t_standard),
5087 + 0, { 0, 0 }, { } },
5088 + { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
5089 + -NF_ACCEPT - 1 } },
5092 + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
5094 + sizeof(struct ip6t_entry),
5095 + sizeof(struct ip6t_error),
5096 + 0, { 0, 0 }, { } },
5097 + { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } },
5104 +static struct ip6t_table packet_raw = {
5106 + .table = &initial_table.repl,
5107 + .valid_hooks = RAW_VALID_HOOKS,
5108 + .lock = RW_LOCK_UNLOCKED,
5112 +/* The work comes in here from netfilter.c. */
5113 +static unsigned int
5114 +ip6t_hook(unsigned int hook,
5115 + struct sk_buff **pskb,
5116 + const struct net_device *in,
5117 + const struct net_device *out,
5118 + int (*okfn)(struct sk_buff *))
5120 + return ip6t_do_table(pskb, hook, in, out, &packet_raw, NULL);
5123 +static struct nf_hook_ops ip6t_ops[] = {
5125 + .hook = ip6t_hook,
5127 + .hooknum = NF_IP6_PRE_ROUTING,
5128 + .priority = NF_IP6_PRI_FIRST
5131 + .hook = ip6t_hook,
5133 + .hooknum = NF_IP6_LOCAL_OUT,
5134 + .priority = NF_IP6_PRI_FIRST
5138 +static int __init init(void)
5142 + /* Register table */
5143 + ret = ip6t_register_table(&packet_raw);
5147 + /* Register hooks */
5148 + ret = nf_register_hook(&ip6t_ops[0]);
5150 + goto cleanup_table;
5152 + ret = nf_register_hook(&ip6t_ops[1]);
5154 + goto cleanup_hook0;
5159 + nf_unregister_hook(&ip6t_ops[0]);
5161 + ip6t_unregister_table(&packet_raw);
5166 +static void __exit fini(void)
5170 + for (i = 0; i < sizeof(ip6t_ops)/sizeof(struct nf_hook_ops); i++)
5171 + nf_unregister_hook(&ip6t_ops[i]);
5173 + ip6t_unregister_table(&packet_raw);
5178 +MODULE_LICENSE("GPL");