]> git.pld-linux.org Git - packages/kernel.git/blob - 2.6.5-rc1-patch-o-matic-ng-base-20040316.patch
- obsolete
[packages/kernel.git] / 2.6.5-rc1-patch-o-matic-ng-base-20040316.patch
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
4 @@ -99,6 +99,24 @@
5  
6  extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
7  
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);
13 +
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);
17 +
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, ...);
25 +                   
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
28     the consequences).
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
32 @@ -251,6 +251,9 @@
33  /* Call me when a conntrack is destroyed. */
34  extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack);
35  
36 +/* Fake conntrack entry for untracked connections */
37 +extern struct ip_conntrack ip_conntrack_untracked;
38 +
39  /* Returns new sk_buff, or NULL */
40  struct sk_buff *
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
45 @@ -0,0 +1,21 @@
46 +/* TTL modification module for IP tables
47 + * (C) 2000 by Harald Welte <laforge@gnumonks.org> */
48 +
49 +#ifndef _IPT_TTL_H
50 +#define _IPT_TTL_H
51 +
52 +enum {
53 +       IPT_TTL_SET = 0,
54 +       IPT_TTL_INC,
55 +       IPT_TTL_DEC
56 +};
57 +
58 +#define IPT_TTL_MAXMODE        IPT_TTL_DEC
59 +
60 +struct ipt_TTL_info {
61 +       u_int8_t        mode;
62 +       u_int8_t        ttl;
63 +};
64 +
65 +
66 +#endif
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
70 @@ -11,6 +11,9 @@
71  #define NETLINK_NFLOG  5
72  #endif
73  
74 +#define ULOG_DEFAULT_NLGROUP   1
75 +#define ULOG_DEFAULT_QTHRESHOLD        1
76 +
77  #define ULOG_MAC_LEN   80
78  #define ULOG_PREFIX_LEN        32
79  
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
83 @@ -0,0 +1,12 @@
84 +#ifndef _IPT_CONNLIMIT_H
85 +#define _IPT_CONNLIMIT_H
86 +
87 +struct ipt_connlimit_data;
88 +
89 +struct ipt_connlimit_info {
90 +       int limit;
91 +       int inverse;
92 +       u_int32_t mask;
93 +       struct ipt_connlimit_data *data;
94 +};
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
99 @@ -10,6 +10,7 @@
100  
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))
104  
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
110 @@ -0,0 +1,39 @@
111 +#ifndef _IPT_DSTLIMIT_H
112 +#define _IPT_DSTLIMIT_H
113 +
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. */
118 +
119 +/* details of this structure hidden by the implementation */
120 +struct ipt_dstlimit_htable;
121 +
122 +#define IPT_DSTLIMIT_HASH_DIP  0x0001
123 +#define IPT_DSTLIMIT_HASH_DPT  0x0002
124 +#define IPT_DSTLIMIT_HASH_SIP  0x0004
125 +
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. */
130 +
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? */
136 +};
137 +
138 +struct ipt_dstlimit_info {
139 +       char name [IFNAMSIZ];           /* name */
140 +       struct dstlimit_cfg cfg;
141 +       struct ipt_dstlimit_htable *hinfo;
142 +
143 +       /* Used internally by the kernel */
144 +       union {
145 +               void *ptr;
146 +               struct ipt_dstlimit_info *master;
147 +       } u;
148 +};
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
153 @@ -0,0 +1,21 @@
154 +#ifndef _IPT_FUZZY_H
155 +#define _IPT_FUZZY_H
156 +
157 +#include <linux/param.h>
158 +#include <linux/types.h>
159 +
160 +#define MAXFUZZYRATE 10000000
161 +#define MINFUZZYRATE 3
162 +
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;
172 +};
173 +
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
178 @@ -0,0 +1,21 @@
179 +#ifndef __ipt_ipv4options_h_included__
180 +#define __ipt_ipv4options_h_included__
181 +
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 */
193 +
194 +struct ipt_ipv4options_info {
195 +       u_int16_t options;
196 +};
197 +
198 +
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
203 @@ -0,0 +1,24 @@
204 +#ifndef _IPT_MPORT_H
205 +#define _IPT_MPORT_H
206 +#include <linux/netfilter_ipv4/ip_tables.h>
207 +
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)
211 +
212 +#define IPT_MULTI_PORTS        15
213 +
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[] */
221 +struct ipt_mport
222 +{
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 */
226 +};
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
231 @@ -0,0 +1,19 @@
232 +#ifndef _IPT_NTH_H
233 +#define _IPT_NTH_H
234 +
235 +#include <linux/param.h>
236 +#include <linux/types.h>
237 +
238 +#ifndef IPT_NTH_NUM_COUNTERS
239 +#define IPT_NTH_NUM_COUNTERS 16
240 +#endif
241 +
242 +struct ipt_nth_info {
243 +       u_int8_t every;
244 +       u_int8_t not;
245 +       u_int8_t startat;
246 +       u_int8_t counter;
247 +       u_int8_t packet;
248 +};
249 +
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
254 @@ -0,0 +1,11 @@
255 +#ifndef _IPT_QUOTA_H
256 +#define _IPT_QUOTA_H
257 +
258 +/* print debug info in both kernel/netfilter module & iptable library */
259 +//#define DEBUG_IPT_QUOTA
260 +
261 +struct ipt_quota_info {
262 +        u_int64_t quota;
263 +};
264 +
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
269 @@ -0,0 +1,9 @@
270 +#ifndef _IPT_REALM_H
271 +#define _IPT_REALM_H
272 +
273 +struct ipt_realm_info {
274 +       u_int32_t id;
275 +       u_int32_t mask;
276 +       u_int8_t invert;
277 +};
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
282 @@ -0,0 +1,107 @@
283 +#ifndef _IPT_SCTP_H_
284 +#define _IPT_SCTP_H_
285 +
286 +#define IPT_SCTP_SRC_PORTS             0x01
287 +#define IPT_SCTP_DEST_PORTS            0x02
288 +#define IPT_SCTP_CHUNK_TYPES           0x04
289 +
290 +#define IPT_SCTP_VALID_FLAGS           0x07
291 +
292 +#define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0]))
293 +
294 +
295 +struct ipt_sctp_flag_info {
296 +       u_int8_t chunktype;
297 +       u_int8_t flag;
298 +       u_int8_t flag_mask;
299 +};
300 +
301 +#define IPT_NUM_SCTP_FLAGS     4
302 +
303 +struct ipt_sctp_info {
304 +       u_int16_t dpts[2];  /* Min, Max */
305 +       u_int16_t spts[2];  /* Min, Max */
306 +
307 +       u_int32_t chunkmap[256 / sizeof (u_int32_t)];  /* Bit mask of chunks to be matched according to RFC 2960 */
308 +
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 */
312 +
313 +       u_int32_t chunk_match_type;
314 +       struct ipt_sctp_flag_info flag_info[IPT_NUM_SCTP_FLAGS];
315 +       int flag_count;
316 +
317 +       u_int32_t flags;
318 +       u_int32_t invflags;
319 +};
320 +
321 +#define bytes(type) (sizeof(type) * 8)
322 +
323 +#define SCTP_CHUNKMAP_SET(chunkmap, type)              \
324 +       do {                                            \
325 +               chunkmap[type / bytes(u_int32_t)] |=    \
326 +                       1 << (type % bytes(u_int32_t)); \
327 +       } while (0)
328 +
329 +#define SCTP_CHUNKMAP_CLEAR(chunkmap, type)                    \
330 +       do {                                                    \
331 +               chunkmap[type / bytes(u_int32_t)] &=            \
332 +                       ~(1 << (type % bytes(u_int32_t)));      \
333 +       } while (0)
334 +
335 +#define SCTP_CHUNKMAP_IS_SET(chunkmap, type)                   \
336 +({                                                             \
337 +       (chunkmap[type / bytes (u_int32_t)] &                   \
338 +               (1 << (type % bytes (u_int32_t)))) ? 1: 0;      \
339 +})
340 +
341 +#define SCTP_CHUNKMAP_RESET(chunkmap)                          \
342 +       do {                                                    \
343 +               int i;                                          \
344 +               for (i = 0; i < ELEMCOUNT(chunkmap); i++)       \
345 +                       chunkmap[i] = 0;                        \
346 +       } while (0)
347 +
348 +#define SCTP_CHUNKMAP_SET_ALL(chunkmap)                        \
349 +       do {                                                    \
350 +               int i;                                          \
351 +               for (i = 0; i < ELEMCOUNT(chunkmap); i++)       \
352 +                       chunkmap[i] = ~0;                       \
353 +       } while (0)
354 +
355 +#define SCTP_CHUNKMAP_COPY(destmap, srcmap)                    \
356 +       do {                                                    \
357 +               int i;                                          \
358 +               for (i = 0; i < ELEMCOUNT(chunkmap); i++)       \
359 +                       destmap[i] = srcmap[i];                 \
360 +       } while (0)
361 +
362 +#define SCTP_CHUNKMAP_IS_CLEAR(chunkmap)               \
363 +({                                                     \
364 +       int i;                                          \
365 +       int flag = 1;                                   \
366 +       for (i = 0; i < ELEMCOUNT(chunkmap); i++) {     \
367 +               if (chunkmap[i]) {                      \
368 +                       flag = 0;                       \
369 +                       break;                          \
370 +               }                                       \
371 +       }                                               \
372 +        flag;                                          \
373 +})
374 +
375 +#define SCTP_CHUNKMAP_IS_ALL_SET(chunkmap)             \
376 +({                                                     \
377 +       int i;                                          \
378 +       int flag = 1;                                   \
379 +       for (i = 0; i < ELEMCOUNT(chunkmap); i++) {     \
380 +               if (chunkmap[i] != ~0) {                \
381 +                       flag = 0;                       \
382 +                               break;                  \
383 +               }                                       \
384 +       }                                               \
385 +        flag;                                          \
386 +})
387 +
388 +#endif /* _IPT_SCTP_H_ */
389 +
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
393 @@ -4,6 +4,8 @@
394  #define IPT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
395  #define IPT_STATE_INVALID (1 << 0)
396  
397 +#define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1))
398 +
399  struct ipt_state_info
400  {
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
405 @@ -0,0 +1,40 @@
406 +#ifndef _IPT_U32_H
407 +#define _IPT_U32_H
408 +#include <linux/netfilter_ipv4/ip_tables.h>
409 +
410 +enum ipt_u32_ops
411 +{
412 +       IPT_U32_AND,
413 +       IPT_U32_LEFTSH,
414 +       IPT_U32_RIGHTSH,
415 +       IPT_U32_AT
416 +};
417 +
418 +struct ipt_u32_location_element
419 +{
420 +       u_int32_t number;
421 +       u_int8_t nextop;
422 +};
423 +struct ipt_u32_value_element
424 +{
425 +       u_int32_t min;
426 +       u_int32_t max;
427 +};
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
431 +struct ipt_u32_test
432 +{
433 +       u_int8_t nnums;
434 +       struct ipt_u32_location_element location[U32MAXSIZE+1];
435 +       u_int8_t nvalues;
436 +       struct ipt_u32_value_element value[U32MAXSIZE+1];
437 +};
438 +
439 +struct ipt_u32
440 +{
441 +       u_int8_t ntests;
442 +       struct ipt_u32_test tests[U32MAXSIZE+1];
443 +};
444 +
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
449 @@ -51,6 +51,8 @@
450  
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
461 @@ -0,0 +1,22 @@
462 +/* Hop Limit modification module for ip6tables
463 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
464 + * Based on HW's TTL module */
465 +
466 +#ifndef _IP6T_HL_H
467 +#define _IP6T_HL_H
468 +
469 +enum {
470 +       IP6T_HL_SET = 0,
471 +       IP6T_HL_INC,
472 +       IP6T_HL_DEC
473 +};
474 +
475 +#define IP6T_HL_MAXMODE        IP6T_HL_DEC
476 +
477 +struct ip6t_HL_info {
478 +       u_int8_t        mode;
479 +       u_int8_t        hop_limit;
480 +};
481 +
482 +
483 +#endif
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
487 @@ -2,15 +2,17 @@
488  #define _IP6T_REJECT_H
489  
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,
502 +       IP6T_TCP_RESET
503  };
504  
505  struct ip6t_reject_info {
506         enum ip6t_reject_with with;      /* reject type */
507  };
508  
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
514 @@ -0,0 +1,21 @@
515 +#ifndef _IP6T_FUZZY_H
516 +#define _IP6T_FUZZY_H
517 +
518 +#include <linux/param.h>
519 +#include <linux/types.h>
520 +
521 +#define MAXFUZZYRATE 10000000
522 +#define MINFUZZYRATE 3
523 +
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;
533 +};
534 +
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
539 @@ -0,0 +1,19 @@
540 +#ifndef _IP6T_NTH_H
541 +#define _IP6T_NTH_H
542 +
543 +#include <linux/param.h>
544 +#include <linux/types.h>
545 +
546 +#ifndef IP6T_NTH_NUM_COUNTERS
547 +#define IP6T_NTH_NUM_COUNTERS 16
548 +#endif
549 +
550 +struct ip6t_nth_info {
551 +       u_int8_t every;
552 +       u_int8_t not;
553 +       u_int8_t startat;
554 +       u_int8_t counter;
555 +       u_int8_t packet;
556 +};
557 +
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
562 @@ -8,8 +8,10 @@
563   *
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.
567   */
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>
573 @@ -741,6 +743,72 @@
574  EXPORT_SYMBOL(skb_ip_make_writable);
575  #endif /*CONFIG_INET*/
576  
577 +/* Internal logging interface, which relies on the real 
578 +   LOG target modules */
579 +
580 +#define NF_LOG_PREFIXLEN               128
581 +
582 +static nf_logfn *nf_logging[NPROTO]; /* = NULL */
583 +static int reported = 0;
584 +static spinlock_t nf_log_lock = SPIN_LOCK_UNLOCKED;
585 +
586 +int nf_log_register(int pf, nf_logfn *logfn)
587 +{
588 +       int ret = -EBUSY;
589 +
590 +       /* Any setup of logging members must be done before
591 +        * substituting pointer. */
592 +       smp_wmb();
593 +       spin_lock(&nf_log_lock);
594 +       if (!nf_logging[pf]) {
595 +               nf_logging[pf] = logfn;
596 +               ret = 0;
597 +       }
598 +       spin_unlock(&nf_log_lock);
599 +       return ret;
600 +}              
601 +
602 +void nf_log_unregister(int pf, nf_logfn *logfn)
603 +{
604 +       spin_lock(&nf_log_lock);
605 +       if (nf_logging[pf] == logfn)
606 +               nf_logging[pf] = NULL;
607 +       spin_unlock(&nf_log_lock);
608 +
609 +       /* Give time to concurrent readers. */
610 +       synchronize_net();
611 +}              
612 +
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, ...)
619 +{
620 +       va_list args;
621 +       char prefix[NF_LOG_PREFIXLEN];
622 +       nf_logfn *logfn;
623 +       
624 +       rcu_read_lock();
625 +       logfn = nf_logging[pf];
626 +       if (logfn) {
627 +               va_start(args, fmt);
628 +               vsnprintf(prefix, sizeof(prefix), fmt, args);
629 +               va_end(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");
636 +               reported++;
637 +       }
638 +       rcu_read_unlock();
639 +}
640 +EXPORT_SYMBOL(nf_log_register);
641 +EXPORT_SYMBOL(nf_log_unregister);
642 +EXPORT_SYMBOL(nf_log_packet);
643  
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
649 @@ -579,5 +579,89 @@
650  
651           To compile it as a module, choose M here.  If unsure, say N.
652  
653 +config IP_NF_TARGET_IPV4OPTSSTRIP
654 +       tristate  'IPV4OPTSSTRIP target support'
655 +       depends on IP_NF_MANGLE
656 +         help
657 +
658 +config IP_NF_TARGET_TTL
659 +       tristate  'TTL target support'
660 +       depends on IP_NF_MANGLE
661 +         help
662 +
663 +config IP_NF_MATCH_CONNLIMIT
664 +       tristate  'Connections/IP limit match support'
665 +       depends on IP_NF_IPTABLES
666 +         help
667 +
668 +config IP_NF_MATCH_DSTLIMIT
669 +       tristate  'dstlimit match support'
670 +       depends on IP_NF_IPTABLES
671 +         help
672 +
673 +config IP_NF_MATCH_FUZZY
674 +       tristate  'fuzzy match support'
675 +       depends on IP_NF_IPTABLES
676 +         help
677 +
678 +config IP_NF_MATCH_IPV4OPTIONS
679 +       tristate  'IPV4OPTIONS match support'
680 +       depends on IP_NF_IPTABLES
681 +         help
682 +
683 +config IP_NF_MATCH_MPORT
684 +       tristate  'Multiple port with ranges match support'
685 +       depends on IP_NF_IPTABLES
686 +         help
687 +
688 +config IP_NF_MATCH_NTH
689 +       tristate  'Nth match support'
690 +       depends on IP_NF_IPTABLES
691 +         help
692 +
693 +config IP_NF_MATCH_QUOTA
694 +       tristate  'quota match support'
695 +       depends on IP_NF_IPTABLES
696 +         help
697 +
698 +config IP_NF_TARGET_NOTRACK
699 +       tristate  'NOTRACK target support'
700 +       depends on IP_NF_RAW
701 +       help
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).
706 +       
707 +         If you want to compile it as a module, say M here and read
708 +         <file:Documentation/modules.txt>.  If unsure, say `N'.
709 +
710 +config IP_NF_RAW
711 +       tristate  'raw table support (required for NOTRACK/TRACE)'
712 +       depends on IP_NF_IPTABLES
713 +       help
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
716 +         and OUTPUT chains.
717 +       
718 +         If you want to compile it as a module, say M here and read
719 +         <file:Documentation/modules.txt>.  If unsure, say `N'.
720 +         help
721 +
722 +config IP_NF_MATCH_REALM
723 +       tristate  'realm match support'
724 +       depends on IP_NF_IPTABLES && NET_CLS_ROUTE
725 +         help
726 +
727 +config IP_NF_MATCH_SCTP
728 +       tristate  'SCTP protocol match support'
729 +       depends on IP_NF_IPTABLES
730 +         help
731 +
732 +config IP_NF_MATCH_U32
733 +       tristate  'U32 match support'
734 +       depends on IP_NF_IPTABLES
735 +         help
736 +
737  endmenu
738  
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
742 @@ -38,19 +38,33 @@
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
747  
748  # matches
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
757  
758  obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
759  obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
760 +
761 +obj-$(CONFIG_IP_NF_MATCH_MPORT) += ipt_mport.o
762 +
763  obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
764  obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
765  
766 +obj-$(CONFIG_IP_NF_MATCH_NTH) += ipt_nth.o
767 +
768 +obj-$(CONFIG_IP_NF_MATCH_IPV4OPTIONS) += ipt_ipv4options.o
769 +
770 +
771 +obj-$(CONFIG_IP_NF_MATCH_FUZZY) += ipt_fuzzy.o
772 +
773  obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
774  
775  obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
776 @@ -59,10 +73,15 @@
777  
778  obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o
779  
780 +obj-$(CONFIG_IP_NF_MATCH_U32) += ipt_u32.o
781 +
782 +
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
789  
790  obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
791  
792 @@ -79,8 +98,11 @@
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
801  
802  # generic ARP tables
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
807 @@ -67,6 +67,7 @@
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;
812  
813  extern struct ip_conntrack_protocol ip_conntrack_generic_protocol;
814  
815 @@ -691,42 +692,50 @@
816                              struct ip_conntrack_expect *, tuple);
817         READ_UNLOCK(&ip_conntrack_expect_tuple_lock);
818  
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))
825 -               expected = NULL;
826 -
827 -       /* Look up the conntrack helper for master connections only */
828 -       if (!expected)
829 -               conntrack->helper = ip_ct_find_helper(&repl_tuple);
830 -
831 -       /* If the expectation is dying, then this is a loser. */
832 -       if (expected
833 -           && expected->expectant->helper->timeout
834 -           && ! del_timer(&expected->timeout))
835 -               expected = NULL;
836 -
837         if (expected) {
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]);
848 -       }
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)) {
856 +                       
857 +                       conntrack->helper = ip_ct_find_helper(&repl_tuple);
858 +                       goto end;
859 +               }
860 +
861 +               /* Expectation is dying... */
862 +               if (expected->expectant->helper->timeout
863 +                   && ! del_timer(&expected->timeout)) {
864 +                       goto end;       
865 +               }
866 +
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]);
877 +
878 +               /* this is a braindead... --pablo */
879 +               atomic_inc(&ip_conntrack_count);
880 +               WRITE_UNLOCK(&ip_conntrack_lock);
881 +
882 +               if (expected->expectfn)
883 +                       expected->expectfn(conntrack);
884 +
885 +               goto ret;
886 +        } else 
887 +                conntrack->helper = ip_ct_find_helper(&repl_tuple);
888 +
889 +end:   atomic_inc(&ip_conntrack_count);
890         WRITE_UNLOCK(&ip_conntrack_lock);
891  
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];
896  }
897  
898  /* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
899 @@ -794,6 +803,15 @@
900         int set_reply;
901         int ret;
902  
903 +       /* Never happen */
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);
908 +               }
909 +               return NF_DROP;
910 +       }
911 +
912         /* FIXME: Do this right please. --RR */
913         (*pskb)->nfcache |= NFC_UNKNOWN;
914  
915 @@ -812,18 +830,10 @@
916         }
917  #endif
918  
919 -       /* Previously seen (loopback)?  Ignore.  Do this before
920 -           fragment check. */
921 +       /* Previously seen (loopback or untracked)?  Ignore. */
922         if ((*pskb)->nfct)
923                 return NF_ACCEPT;
924  
925 -       /* Gather fragments. */
926 -       if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
927 -               *pskb = ip_ct_gather_frags(*pskb);
928 -               if (!*pskb)
929 -                       return NF_STOLEN;
930 -       }
931 -
932         proto = ip_ct_find_proto((*pskb)->nh.iph->protocol);
933  
934         /* It may be an icmp error... */
935 @@ -1422,6 +1432,18 @@
936  
937         /* For use by ipt_REJECT */
938         ip_ct_attach = ip_conntrack_attach;
939 +
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;
950 +
951         return ret;
952  
953  err_free_hash:
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
957 @@ -194,6 +194,26 @@
958         return ip_conntrack_confirm(*pskb);
959  }
960  
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 *))
966 +{
967 +       /* Previously seen (loopback)?  Ignore.  Do this before
968 +           fragment check. */
969 +       if ((*pskb)->nfct)
970 +               return NF_ACCEPT;
971 +
972 +       /* Gather fragments. */
973 +       if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
974 +               *pskb = ip_ct_gather_frags(*pskb);
975 +               if (!*pskb)
976 +                       return NF_STOLEN;
977 +       }
978 +       return NF_ACCEPT;
979 +}
980 +
981  static unsigned int ip_refrag(unsigned int hooknum,
982                               struct sk_buff **pskb,
983                               const struct net_device *in,
984 @@ -236,6 +256,14 @@
985  
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,
991 +       .pf             = PF_INET,
992 +       .hooknum        = NF_IP_PRE_ROUTING,
993 +       .priority       = NF_IP_PRI_CONNTRACK_DEFRAG,
994 +};
995 +
996  static struct nf_hook_ops ip_conntrack_in_ops = {
997         .hook           = ip_conntrack_in,
998         .owner          = THIS_MODULE,
999 @@ -244,6 +272,14 @@
1000         .priority       = NF_IP_PRI_CONNTRACK,
1001  };
1002  
1003 +static struct nf_hook_ops ip_conntrack_defrag_local_out_ops = {
1004 +       .hook           = ip_conntrack_defrag,
1005 +       .owner          = THIS_MODULE,
1006 +       .pf             = PF_INET,
1007 +       .hooknum        = NF_IP_LOCAL_OUT,
1008 +       .priority       = NF_IP_PRI_CONNTRACK_DEFRAG,
1009 +};
1010 +
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;
1017  
1018 +       ret = nf_register_hook(&ip_conntrack_defrag_ops);
1019 +       if (ret < 0) {
1020 +               printk("ip_conntrack: can't register pre-routing defrag hook.\n");
1021 +               goto cleanup_proc;
1022 +       }
1023 +       ret = nf_register_hook(&ip_conntrack_defrag_local_out_ops);
1024 +       if (ret < 0) {
1025 +               printk("ip_conntrack: can't register local_out defrag hook.\n");
1026 +               goto cleanup_defragops;
1027 +       }
1028         ret = nf_register_hook(&ip_conntrack_in_ops);
1029         if (ret < 0) {
1030                 printk("ip_conntrack: can't register pre-routing hook.\n");
1031 -               goto cleanup_proc;
1032 +               goto cleanup_defraglocalops;
1033         }
1034         ret = nf_register_hook(&ip_conntrack_local_out_ops);
1035         if (ret < 0) {
1036 @@ -511,6 +557,10 @@
1037         nf_unregister_hook(&ip_conntrack_local_out_ops);
1038   cleanup_inops:
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);
1044   cleanup_proc:
1045         proc_net_remove("ip_conntrack");
1046   cleanup_init:
1047 @@ -602,5 +652,6 @@
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;
1061 +       
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);
1065  
1066         return 0;
1067  }
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
1071 @@ -0,0 +1,89 @@
1072 +/**
1073 + * Strip all IP options in the IP packet header.
1074 + *
1075 + * (C) 2001 by Fabrice MARIE <fabrice@netfilter.org>
1076 + * This software is distributed under GNU GPL v2, 1991
1077 + */
1078 +
1079 +#include <linux/module.h>
1080 +#include <linux/skbuff.h>
1081 +#include <linux/ip.h>
1082 +#include <net/checksum.h>
1083 +
1084 +#include <linux/netfilter_ipv4/ip_tables.h>
1085 +
1086 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
1087 +MODULE_DESCRIPTION("Strip all options in IPv4 packets");
1088 +MODULE_LICENSE("GPL");
1089 +
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,
1096 +       void *userinfo)
1097 +{
1098 +       struct iphdr *iph;
1099 +       struct sk_buff *skb;
1100 +       struct ip_options *opt;
1101 +       unsigned char *optiph;
1102 +       int l;
1103 +       
1104 +       if (!skb_ip_make_writable(pskb, (*pskb)->len))
1105 +               return NF_DROP;
1106
1107 +       skb = (*pskb);
1108 +       iph = (*pskb)->nh.iph;
1109 +       optiph = skb->nh.raw;
1110 +       l = ((struct ip_options *)(&(IPCB(skb)->opt)))->optlen;
1111 +
1112 +       /* if no options in packet then nothing to clear. */
1113 +       if (iph->ihl * 4 == sizeof(struct iphdr))
1114 +               return IPT_CONTINUE;
1115 +
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);
1120 +       opt->is_data = 0;
1121 +       opt->optlen = l;
1122 +
1123 +       skb->nfcache |= NFC_ALTERED;
1124 +
1125 +        return IPT_CONTINUE;
1126 +}
1127 +
1128 +static int
1129 +checkentry(const char *tablename,
1130 +          const struct ipt_entry *e,
1131 +           void *targinfo,
1132 +           unsigned int targinfosize,
1133 +           unsigned int hook_mask)
1134 +{
1135 +       if (strcmp(tablename, "mangle")) {
1136 +               printk(KERN_WARNING "IPV4OPTSSTRIP: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1137 +               return 0;
1138 +       }
1139 +       /* nothing else to check because no parameters */
1140 +       return 1;
1141 +}
1142 +
1143 +static struct ipt_target ipt_ipv4optsstrip_reg = { 
1144 +       .name = "IPV4OPTSSTRIP",
1145 +       .target = target,
1146 +       .checkentry = checkentry,
1147 +       .me = THIS_MODULE };
1148 +
1149 +static int __init init(void)
1150 +{
1151 +       return ipt_register_target(&ipt_ipv4optsstrip_reg);
1152 +}
1153 +
1154 +static void __exit fini(void)
1155 +{
1156 +       ipt_unregister_target(&ipt_ipv4optsstrip_reg);
1157 +}
1158 +
1159 +module_init(init);
1160 +module_exit(fini);
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
1164 @@ -19,6 +19,7 @@
1165  #include <net/tcp.h>
1166  #include <net/route.h>
1167  
1168 +#include <linux/netfilter.h>
1169  #include <linux/netfilter_ipv4/ip_tables.h>
1170  #include <linux/netfilter_ipv4/ipt_LOG.h>
1171  
1172 @@ -26,6 +27,10 @@
1173  MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
1174  MODULE_DESCRIPTION("iptables syslog logging module");
1175  
1176 +static unsigned int nflog = 1;
1177 +MODULE_PARM(nflog, "i");
1178 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
1179
1180  #if 0
1181  #define DEBUGP printk
1182  #else
1183 @@ -324,28 +329,25 @@
1184         /* maxlen = 230+   91  + 230 + 252 = 803 */
1185  }
1186  
1187 -static unsigned int
1188 -ipt_log_target(struct sk_buff **pskb,
1189 +static void
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,
1196 -              void *userinfo)
1197 +              const struct ipt_log_info *loginfo,
1198 +              const char *level_string,
1199 +              const char *prefix)
1200  {
1201 -       const struct ipt_log_info *loginfo = targinfo;
1202 -       char level_string[4] = "< >";
1203 -
1204 -       level_string[1] = '0' + (loginfo->level % 8);
1205         spin_lock_bh(&log_lock);
1206         printk(level_string);
1207         printk("%sIN=%s OUT=%s ",
1208 -              loginfo->prefix,
1209 +              prefix == NULL ? loginfo->prefix : prefix,
1210                in ? in->name : "",
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;
1219  
1220                 if (physindev && in != physindev)
1221                         printk("PHYSIN=%s ", physindev->name);
1222 @@ -357,25 +359,56 @@
1223         if (in && !out) {
1224                 /* MAC logging for input chain only. */
1225                 printk("MAC=");
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) {
1230                         int i;
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
1238                                        ? ' ':':');
1239                 } else
1240                         printk(" ");
1241         }
1242  
1243 -       dump_packet(loginfo, *pskb, 0);
1244 +       dump_packet(loginfo, skb, 0);
1245         printk("\n");
1246         spin_unlock_bh(&log_lock);
1247 +}
1248 +
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,
1255 +              void *userinfo)
1256 +{
1257 +       const struct ipt_log_info *loginfo = targinfo;
1258 +       char level_string[4] = "< >";
1259 +
1260 +       level_string[1] = '0' + (loginfo->level % 8);
1261 +       ipt_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
1262  
1263         return IPT_CONTINUE;
1264  }
1265  
1266 +static void
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)
1272 +{
1273 +       struct ipt_log_info loginfo = { 
1274 +               .level = 0, 
1275 +               .logflags = IPT_LOG_MASK, 
1276 +               .prefix = "" 
1277 +       };
1278 +
1279 +       ipt_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
1280 +}
1281 +
1282  static int ipt_log_checkentry(const char *tablename,
1283                               const struct ipt_entry *e,
1284                               void *targinfo,
1285 @@ -413,11 +446,18 @@
1286  
1287  static int __init init(void)
1288  {
1289 -       return ipt_register_target(&ipt_log_reg);
1290 +       if (ipt_register_target(&ipt_log_reg))
1291 +               return -EINVAL;
1292 +       if (nflog)
1293 +               nf_log_register(PF_INET, &ipt_logfn);
1294 +       
1295 +       return 0;
1296  }
1297  
1298  static void __exit fini(void)
1299  {
1300 +       if (nflog)
1301 +               nf_log_unregister(PF_INET, &ipt_logfn);
1302         ipt_unregister_target(&ipt_log_reg);
1303  }
1304  
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
1308 @@ -0,0 +1,75 @@
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.
1311 + */
1312 +#include <linux/module.h>
1313 +#include <linux/skbuff.h>
1314 +
1315 +#include <linux/netfilter_ipv4/ip_tables.h>
1316 +#include <linux/netfilter_ipv4/ip_conntrack.h>
1317 +
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,
1324 +       void *userinfo)
1325 +{
1326 +       /* Previously seen (loopback)? Ignore. */
1327 +       if ((*pskb)->nfct != NULL)
1328 +               return IPT_CONTINUE;
1329 +
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);
1336 +
1337 +       return IPT_CONTINUE;
1338 +}
1339 +
1340 +static int
1341 +checkentry(const char *tablename,
1342 +          const struct ipt_entry *e,
1343 +           void *targinfo,
1344 +           unsigned int targinfosize,
1345 +           unsigned int hook_mask)
1346 +{
1347 +       if (targinfosize != 0) {
1348 +               printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n",
1349 +                      targinfosize);
1350 +               return 0;
1351 +       }
1352 +
1353 +       if (strcmp(tablename, "raw") != 0) {
1354 +               printk(KERN_WARNING "NOTRACK: can only be called from \"raw\" table, not \"%s\"\n", tablename);
1355 +               return 0;
1356 +       }
1357 +
1358 +       return 1;
1359 +}
1360 +
1361 +static struct ipt_target ipt_notrack_reg = { 
1362 +       .name = "NOTRACK", 
1363 +       .target = target, 
1364 +       .checkentry = checkentry,
1365 +       .me = THIS_MODULE 
1366 +};
1367 +
1368 +static int __init init(void)
1369 +{
1370 +       if (ipt_register_target(&ipt_notrack_reg))
1371 +               return -EINVAL;
1372 +
1373 +       return 0;
1374 +}
1375 +
1376 +static void __exit fini(void)
1377 +{
1378 +       ipt_unregister_target(&ipt_notrack_reg);
1379 +}
1380 +
1381 +module_init(init);
1382 +module_exit(fini);
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
1387 @@ -0,0 +1,120 @@
1388 +/* TTL modification target for IP tables
1389 + * (C) 2000 by Harald Welte <laforge@gnumonks.org>
1390 + *
1391 + * Version: $Revision$
1392 + *
1393 + * This software is distributed under the terms of GNU GPL
1394 + */
1395 +
1396 +#include <linux/module.h>
1397 +#include <linux/skbuff.h>
1398 +#include <linux/ip.h>
1399 +#include <net/checksum.h>
1400 +
1401 +#include <linux/netfilter_ipv4/ip_tables.h>
1402 +#include <linux/netfilter_ipv4/ipt_TTL.h>
1403 +
1404 +MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
1405 +MODULE_DESCRIPTION("IP tables TTL modification module");
1406 +MODULE_LICENSE("GPL");
1407 +
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)
1412 +{
1413 +       struct iphdr *iph;
1414 +       const struct ipt_TTL_info *info = targinfo;
1415 +       u_int16_t diffs[2];
1416 +       int new_ttl;
1417 +
1418 +       if (!skb_ip_make_writable(pskb, (*pskb)->len))
1419 +               return NF_DROP;
1420 +
1421 +       iph = (*pskb)->nh.iph;
1422 +                        
1423 +       switch (info->mode) {
1424 +               case IPT_TTL_SET:
1425 +                       new_ttl = info->ttl;
1426 +                       break;
1427 +               case IPT_TTL_INC:
1428 +                       new_ttl = iph->ttl + info->ttl;
1429 +                       if (new_ttl > 255)
1430 +                               new_ttl = 255;
1431 +                       break;
1432 +               case IPT_TTL_DEC:
1433 +                       new_ttl = iph->ttl + info->ttl;
1434 +                       if (new_ttl < 0)
1435 +                               new_ttl = 0;
1436 +                       break;
1437 +               default:
1438 +                       new_ttl = iph->ttl;
1439 +                       break;
1440 +       }
1441 +
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,
1447 +                                                   sizeof(diffs),
1448 +                                                   iph->check^0xFFFF));
1449 +                                                                                               (*pskb)->nfcache |= NFC_ALTERED;
1450 +       }
1451 +
1452 +       return IPT_CONTINUE;
1453 +}
1454 +
1455 +static int ipt_ttl_checkentry(const char *tablename,
1456 +               const struct ipt_entry *e,
1457 +               void *targinfo,
1458 +               unsigned int targinfosize,
1459 +               unsigned int hook_mask)
1460 +{
1461 +       struct ipt_TTL_info *info = targinfo;
1462 +
1463 +       if (targinfosize != IPT_ALIGN(sizeof(struct ipt_TTL_info))) {
1464 +               printk(KERN_WARNING "TTL: targinfosize %u != %Zu\n",
1465 +                               targinfosize,
1466 +                               IPT_ALIGN(sizeof(struct ipt_TTL_info)));
1467 +               return 0;       
1468 +       }       
1469 +
1470 +       if (strcmp(tablename, "mangle")) {
1471 +               printk(KERN_WARNING "TTL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1472 +               return 0;
1473 +       }
1474 +
1475 +       if (info->mode > IPT_TTL_MAXMODE) {
1476 +               printk(KERN_WARNING "TTL: invalid or unknown Mode %u\n", 
1477 +                       info->mode);
1478 +               return 0;
1479 +       }
1480 +
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");
1483 +               return 0;
1484 +       }
1485 +       
1486 +       return 1;
1487 +}
1488 +
1489 +static struct ipt_target ipt_TTL = { 
1490 +       .name = "TTL",
1491 +       .target = ipt_ttl_target, 
1492 +       .checkentry = ipt_ttl_checkentry, 
1493 +       .me = THIS_MODULE 
1494 +};
1495 +
1496 +static int __init init(void)
1497 +{
1498 +       return ipt_register_target(&ipt_TTL);
1499 +}
1500 +
1501 +static void __exit fini(void)
1502 +{
1503 +       ipt_unregister_target(&ipt_TTL);
1504 +}
1505 +
1506 +module_init(init);
1507 +module_exit(fini);
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
1511 @@ -50,6 +50,7 @@
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>
1519 @@ -80,6 +81,10 @@
1520  MODULE_PARM(flushtimeout, "i");
1521  MODULE_PARM_DESC(flushtimeout, "buffer flush timeout");
1522  
1523 +static unsigned int nflog = 1;
1524 +MODULE_PARM(nflog, "i");
1525 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
1526 +
1527  /* global data structures */
1528  
1529  typedef struct {
1530 @@ -157,17 +162,17 @@
1531         return skb;
1532  }
1533  
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)
1545  {
1546         ulog_buff_t *ub;
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;
1551  
1552         /* ffs == find first bit set, necessary because userspace
1553          * is already shifting groupnumber, but we need unshifted.
1554 @@ -176,8 +181,8 @@
1555  
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;
1562         } else {
1563                 copy_len = loginfo->copy_range;
1564         }
1565 @@ -214,19 +219,21 @@
1566  
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;
1575         pm->hook = hooknum;
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));
1581         else
1582                 *(pm->prefix) = '\0';
1583  
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;
1591         } else
1592                 pm->mac_len = 0;
1593 @@ -241,8 +248,8 @@
1594         else
1595                 pm->outdev_name[0] = '\0';
1596  
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)
1601                 BUG();
1602         
1603         /* check if we are building multi-part messages */
1604 @@ -266,8 +273,7 @@
1605  
1606         UNLOCK_BH(&ulog_lock);
1607  
1608 -       return IPT_CONTINUE;
1609 -
1610 +       return;
1611  
1612  nlmsg_failure:
1613         PRINTR("ipt_ULOG: error during NLMSG_PUT\n");
1614 @@ -276,8 +282,35 @@
1615         PRINTR("ipt_ULOG: Error building netlink message\n");
1616  
1617         UNLOCK_BH(&ulog_lock);
1618 +}
1619 +
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)
1625 +{
1626 +       struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
1627  
1628 -       return IPT_CONTINUE;
1629 +       ipt_ulog_packet(hooknum, *pskb, in, out, loginfo, NULL);
1630
1631 +       return IPT_CONTINUE;
1632 +}
1633
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)
1639 +{
1640 +       struct ipt_ulog_info loginfo = { 
1641 +               .nl_group = ULOG_DEFAULT_NLGROUP,
1642 +               .copy_range = 0,
1643 +               .qthreshold = ULOG_DEFAULT_QTHRESHOLD,
1644 +               .prefix = ""
1645 +       };
1646 +
1647 +       ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
1648  }
1649  
1650  static int ipt_ulog_checkentry(const char *tablename,
1651 @@ -341,7 +374,9 @@
1652                 sock_release(nflognl->sk_socket);
1653                 return -EINVAL;
1654         }
1655 -
1656 +       if (nflog)
1657 +               nf_log_register(PF_INET, &ipt_logfn);
1658 +       
1659         return 0;
1660  }
1661  
1662 @@ -352,6 +387,8 @@
1663  
1664         DEBUGP("ipt_ULOG: cleanup_module\n");
1665  
1666 +       if (nflog)
1667 +               nf_log_unregister(PF_INET, &ipt_logfn);
1668         ipt_unregister_target(&ipt_ulog_reg);
1669         sock_release(nflognl->sk_socket);
1670  
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
1674 @@ -0,0 +1,230 @@
1675 +/*
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
1681 + *
1682 + * based on ...
1683 + *
1684 + * Kernel module to match connection tracking information.
1685 + * GPL (C) 1999  Rusty Russell (rusty@rustcorp.com.au).
1686 + */
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>
1695 +
1696 +#define DEBUG 0
1697 +
1698 +MODULE_LICENSE("GPL");
1699 +
1700 +/* we'll save the tuples of all connections we care about */
1701 +struct ipt_connlimit_conn
1702 +{
1703 +        struct list_head list;
1704 +       struct ip_conntrack_tuple tuple;
1705 +};
1706 +
1707 +struct ipt_connlimit_data {
1708 +       spinlock_t lock;
1709 +       struct list_head iphash[256];
1710 +};
1711 +
1712 +static int ipt_iphash(u_int32_t addr)
1713 +{
1714 +       int hash;
1715 +
1716 +       hash  =  addr        & 0xff;
1717 +       hash ^= (addr >>  8) & 0xff;
1718 +       hash ^= (addr >> 16) & 0xff;
1719 +       hash ^= (addr >> 24) & 0xff;
1720 +       return hash;
1721 +}
1722 +
1723 +static int count_them(struct ipt_connlimit_data *data,
1724 +                     u_int32_t addr, u_int32_t mask,
1725 +                     struct ip_conntrack *ct)
1726 +{
1727 +#if DEBUG
1728 +       const static char *tcp[] = { "none", "established", "syn_sent", "syn_recv",
1729 +                                    "fin_wait", "time_wait", "close", "close_wait",
1730 +                                    "last_ack", "listen" };
1731 +#endif
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;
1737 +
1738 +       spin_lock(&data->lock);
1739 +       tuple = ct->tuplehash[0].tuple;
1740 +       hash = &data->iphash[ipt_iphash(addr & mask)];
1741 +
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)) &&
1747 +                   found != NULL &&
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" */
1752 +                       addit = 0;
1753 +               }
1754 +#if DEBUG
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");
1760 +#endif
1761 +               if (NULL == found) {
1762 +                       /* this one is gone */
1763 +                       lh = lh->prev;
1764 +                       list_del(lh->next);
1765 +                       kfree(conn);
1766 +                       continue;
1767 +               }
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 */
1771 +                       lh = lh->prev;
1772 +                       list_del(lh->next);
1773 +                       kfree(conn);
1774 +                       nf_conntrack_put(&found->ctrack->infos[0]);
1775 +                       continue;
1776 +               }
1777 +               if ((addr & mask) == (conn->tuple.src.ip & mask)) {
1778 +                       /* same source IP address -> be counted! */
1779 +                       matches++;
1780 +               }
1781 +               nf_conntrack_put(&found->ctrack->infos[0]);
1782 +       }
1783 +       if (addit) {
1784 +               /* save the new connection in our list */
1785 +#if DEBUG
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));
1790 +#endif
1791 +               conn = kmalloc(sizeof(*conn),GFP_ATOMIC);
1792 +               if (NULL == conn)
1793 +                       return -1;
1794 +               memset(conn,0,sizeof(*conn));
1795 +               INIT_LIST_HEAD(&conn->list);
1796 +               conn->tuple = tuple;
1797 +               list_add(&conn->list,hash);
1798 +               matches++;
1799 +       }
1800 +       spin_unlock(&data->lock);
1801 +       return matches;
1802 +}
1803 +
1804 +static int
1805 +match(const struct sk_buff *skb,
1806 +      const struct net_device *in,
1807 +      const struct net_device *out,
1808 +      const void *matchinfo,
1809 +      int offset,
1810 +      int *hotdrop)
1811 +{
1812 +       const struct ipt_connlimit_info *info = matchinfo;
1813 +       int connections, match;
1814 +       struct ip_conntrack *ct;
1815 +       enum ip_conntrack_info ctinfo;
1816 +
1817 +       ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
1818 +       if (NULL == ct) {
1819 +               printk("ipt_connlimit: Oops: invalid ct state ?\n");
1820 +               *hotdrop = 1;
1821 +               return 0;
1822 +       }
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 :-) */
1827 +               return 0;
1828 +       }
1829 +        match = (info->inverse) ? (connections <= info->limit) : (connections > info->limit);
1830 +#if DEBUG
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");
1835 +#endif
1836 +
1837 +       return match;
1838 +}
1839 +
1840 +static int check(const char *tablename,
1841 +                const struct ipt_ip *ip,
1842 +                void *matchinfo,
1843 +                unsigned int matchsize,
1844 +                unsigned int hook_mask)
1845 +{
1846 +       struct ipt_connlimit_info *info = matchinfo;
1847 +       int i;
1848 +
1849 +       /* verify size */
1850 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_connlimit_info)))
1851 +               return 0;
1852 +
1853 +       /* refuse anything but tcp */
1854 +       if (ip->proto != IPPROTO_TCP)
1855 +               return 0;
1856 +
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]));
1862 +       
1863 +       return 1;
1864 +}
1865 +
1866 +static void destroy(void *matchinfo, unsigned int matchinfosize)
1867 +{
1868 +       struct ipt_connlimit_info *info = matchinfo;
1869 +       struct ipt_connlimit_conn *conn;
1870 +       struct list_head *hash;
1871 +       int i;
1872 +
1873 +       /* cleanup */
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);
1879 +                       kfree(conn);
1880 +               }
1881 +       }
1882 +       kfree(info->data);
1883 +}
1884 +
1885 +static struct ipt_match connlimit_match = { 
1886 +       .name = "connlimit",
1887 +       .match = &match,
1888 +       .checkentry = &check,
1889 +       .destroy = &destroy,
1890 +       .me = THIS_MODULE
1891 +};
1892 +
1893 +static int __init init(void)
1894 +{
1895 +       return ipt_register_match(&connlimit_match);
1896 +}
1897 +
1898 +static void __exit fini(void)
1899 +{
1900 +       ipt_unregister_match(&connlimit_match);
1901 +}
1902 +
1903 +module_init(init);
1904 +module_exit(fini);
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
1908 @@ -35,11 +35,13 @@
1909  
1910  #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
1911  
1912 -       if (ct)
1913 -               statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
1914 -       else
1915 -               statebit = IPT_CONNTRACK_STATE_INVALID;
1916 -
1917 +       if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
1918 +               statebit = IPT_CONNTRACK_STATE_UNTRACKED;
1919 +       else if (ct)
1920 +               statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
1921 +       else
1922 +               statebit = IPT_CONNTRACK_STATE_INVALID;
1923
1924         if(sinfo->flags & IPT_CONNTRACK_STATE) {
1925                 if (ct) {
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
1930 @@ -0,0 +1,690 @@
1931 +/* iptables match extension to limit the number of packets per second
1932 + * seperately for each destination.
1933 + *
1934 + * (C) 2003 by Harald Welte <laforge@netfilter.org>
1935 + *
1936 + * $Id$
1937 + *
1938 + * Development of this code was funded by Astaro AG, http://www.astaro.com/
1939 + *
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>
1944 + *
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.
1948 + *
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 ;)
1953 + */
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>
1965 +
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>
1970 +
1971 +#include <linux/netfilter_ipv4/ip_tables.h>
1972 +#include <linux/netfilter_ipv4/ipt_dstlimit.h>
1973 +
1974 +/* FIXME: this is just for IP_NF_ASSERRT */
1975 +#include <linux/netfilter_ipv4/ip_conntrack.h>
1976 +
1977 +#define MS2JIFFIES(x) ((x*HZ)/1000)
1978 +
1979 +MODULE_LICENSE("GPL");
1980 +MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
1981 +MODULE_DESCRIPTION("iptables match for limiting per destination");
1982 +
1983 +/* need to declare this at the top */
1984 +static struct proc_dir_entry *dstlimit_procdir;
1985 +static struct file_operations dl_file_ops;
1986 +
1987 +/* hash table crap */
1988 +
1989 +struct dsthash_dst {
1990 +       u_int32_t src_ip;
1991 +       u_int32_t dst_ip;
1992 +       u_int16_t port;
1993 +};
1994 +
1995 +struct dsthash_ent {
1996 +       /* static / read-only parts in the beginning */
1997 +       struct list_head list;
1998 +       struct dsthash_dst dst;
1999 +
2000 +       /* modified structure members in the end */
2001 +       unsigned long expires;          /* precalculated expiry time */
2002 +       struct {
2003 +               unsigned long prev;     /* last modification */
2004 +               u_int32_t credit;
2005 +               u_int32_t credit_cap, cost;
2006 +       } rateinfo;
2007 +};
2008 +
2009 +struct ipt_dstlimit_htable {
2010 +       struct list_head list;          /* global list of all htables */
2011 +       atomic_t use;
2012 +
2013 +       struct dstlimit_cfg cfg;        /* config */
2014 +
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 */
2020 +
2021 +       /* seq_file stuff */
2022 +       struct proc_dir_entry *pde;
2023 +
2024 +       struct list_head hash[0];       /* hashtable itself */
2025 +};
2026 +
2027 +DECLARE_RWLOCK(dstlimit_lock);         /* protects htables list */
2028 +static LIST_HEAD(dstlimit_htables);
2029 +static kmem_cache_t *dstlimit_cachep;
2030 +
2031 +static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b)
2032 +{
2033 +       return (ent->dst.dst_ip == b->dst_ip 
2034 +               && ent->dst.port == b->port
2035 +               && ent->dst.src_ip == b->src_ip);
2036 +}
2037 +
2038 +static inline u_int32_t
2039 +hash_dst(const struct ipt_dstlimit_htable *ht, const struct dsthash_dst *dst)
2040 +{
2041 +       return (jhash_3words(dst->dst_ip, dst->port, 
2042 +                            dst->src_ip, ht->rnd) % ht->cfg.size);
2043 +}
2044 +
2045 +static inline struct dsthash_ent *
2046 +__dsthash_find(const struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
2047 +{
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);
2052 +       return ent;
2053 +}
2054 +
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)
2058 +{
2059 +       struct dsthash_ent *ent;
2060 +
2061 +       /* initialize hash with random val at the time we allocate
2062 +        * the first hashtable entry */
2063 +       if (!ht->rnd)
2064 +               get_random_bytes(&ht->rnd, 4);
2065 +
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", 
2072 +                               ht->cfg.max);
2073 +               return NULL;
2074 +       }
2075 +
2076 +       ent = kmem_cache_alloc(dstlimit_cachep, GFP_ATOMIC);
2077 +       if (!ent) {
2078 +               if (net_ratelimit())
2079 +                       printk(KERN_ERR 
2080 +                               "ipt_dstlimit: can't allocate dsthash_ent\n");
2081 +               return NULL;
2082 +       }
2083 +
2084 +       atomic_inc(&ht->count);
2085 +
2086 +       ent->dst.dst_ip = dst->dst_ip;
2087 +       ent->dst.port = dst->port;
2088 +       ent->dst.src_ip = dst->src_ip;
2089 +
2090 +       list_add(&ent->list, &ht->hash[hash_dst(ht, dst)]);
2091 +
2092 +       return ent;
2093 +}
2094 +
2095 +static inline void 
2096 +__dsthash_free(struct ipt_dstlimit_htable *ht, struct dsthash_ent *ent)
2097 +{
2098 +       MUST_BE_LOCKED(&ht->lock);
2099 +
2100 +       list_del(&ent->list);
2101 +       kmem_cache_free(dstlimit_cachep, ent);
2102 +       atomic_dec(&ht->count);
2103 +}
2104 +static void htable_gc(unsigned long htlong);
2105 +
2106 +static int htable_create(struct ipt_dstlimit_info *minfo)
2107 +{
2108 +       int i;
2109 +       unsigned int size;
2110 +       struct ipt_dstlimit_htable *hinfo;
2111 +
2112 +       if (minfo->cfg.size)
2113 +               size = minfo->cfg.size;
2114 +       else {
2115 +               size = (((num_physpages << PAGE_SHIFT) / 16384)
2116 +                        / sizeof(struct list_head));
2117 +               if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
2118 +                       size = 8192;
2119 +               if (size < 16)
2120 +                       size = 16;
2121 +       }
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));
2125 +       if (!hinfo) {
2126 +               printk(KERN_ERR "ipt_dstlimit: Unable to create hashtable\n");
2127 +               return -1;
2128 +       }
2129 +       minfo->hinfo = hinfo;
2130 +
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;
2138 +
2139 +       for (i = 0; i < hinfo->cfg.size; i++)
2140 +               INIT_LIST_HEAD(&hinfo->hash[i]);
2141 +
2142 +       atomic_set(&hinfo->count, 0);
2143 +       atomic_set(&hinfo->use, 1);
2144 +       hinfo->rnd = 0;
2145 +       hinfo->lock = SPIN_LOCK_UNLOCKED;
2146 +       hinfo->pde = create_proc_entry(minfo->name, 0, dstlimit_procdir);
2147 +       if (!hinfo->pde) {
2148 +               vfree(hinfo);
2149 +               return -1;
2150 +       }
2151 +       hinfo->pde->proc_fops = &dl_file_ops;
2152 +       hinfo->pde->data = hinfo;
2153 +
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);
2159 +
2160 +       WRITE_LOCK(&dstlimit_lock);
2161 +       list_add(&hinfo->list, &dstlimit_htables);
2162 +       WRITE_UNLOCK(&dstlimit_lock);
2163 +
2164 +       return 0;
2165 +}
2166 +
2167 +static int select_all(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
2168 +{
2169 +       return 1;
2170 +}
2171 +
2172 +static int select_gc(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
2173 +{
2174 +       return (jiffies >= he->expires);
2175 +}
2176 +
2177 +static void htable_selective_cleanup(struct ipt_dstlimit_htable *ht,
2178 +                               int (*select)(struct ipt_dstlimit_htable *ht, 
2179 +                                             struct dsthash_ent *he))
2180 +{
2181 +       int i;
2182 +
2183 +       IP_NF_ASSERT(ht->cfg.size && ht->cfg.max);
2184 +
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);
2192 +               }
2193 +       }
2194 +       UNLOCK_BH(&ht->lock);
2195 +}
2196 +
2197 +/* hash table garbage collector, run by timer */
2198 +static void htable_gc(unsigned long htlong)
2199 +{
2200 +       struct ipt_dstlimit_htable *ht = (struct ipt_dstlimit_htable *)htlong;
2201 +
2202 +       htable_selective_cleanup(ht, select_gc);
2203 +
2204 +       /* re-add the timer accordingly */
2205 +       ht->timer.expires = jiffies + MS2JIFFIES(ht->cfg.gc_interval);
2206 +       add_timer(&ht->timer);
2207 +}
2208 +
2209 +static void htable_destroy(struct ipt_dstlimit_htable *hinfo)
2210 +{
2211 +       /* remove timer, if it is pending */
2212 +       if (timer_pending(&hinfo->timer))
2213 +               del_timer(&hinfo->timer);
2214 +
2215 +       /* remove proc entry */
2216 +       remove_proc_entry(hinfo->pde->name, dstlimit_procdir);
2217 +
2218 +       htable_selective_cleanup(hinfo, select_all);
2219 +       vfree(hinfo);
2220 +}
2221 +
2222 +static struct ipt_dstlimit_htable *htable_find_get(char *name)
2223 +{
2224 +       struct ipt_dstlimit_htable *hinfo;
2225 +
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);
2231 +                       return hinfo;
2232 +               }
2233 +       }
2234 +       READ_UNLOCK(&dstlimit_lock);
2235 +
2236 +       return NULL;
2237 +}
2238 +
2239 +static void htable_put(struct ipt_dstlimit_htable *hinfo)
2240 +{
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);
2246 +       }
2247 +}
2248 +
2249 +
2250 +/* The algorithm used is the Simple Token Bucket Filter (TBF)
2251 + * see net/sched/sch_tbf.c in the linux source tree
2252 + */
2253 +
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
2258 +   test, `cost'.
2259 +
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.
2264 +
2265 +   See Alexey's formal explanation in net/sched/sch_tbf.c.
2266 +
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.
2271 +*/
2272 +#define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24))
2273 +
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
2276 + * shift. */
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)
2283 +
2284 +#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
2285 +
2286 +/* Precision saver. */
2287 +static inline u_int32_t
2288 +user2credits(u_int32_t user)
2289 +{
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;
2294 +
2295 +       return (user * HZ * CREDITS_PER_JIFFY) / IPT_DSTLIMIT_SCALE;
2296 +}
2297 +
2298 +static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
2299 +{
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;
2304 +}
2305 +
2306 +static int
2307 +dstlimit_match(const struct sk_buff *skb,
2308 +               const struct net_device *in,
2309 +               const struct net_device *out,
2310 +               const void *matchinfo,
2311 +               int offset,
2312 +               int *hotdrop)
2313 +{
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;
2320 +
2321 +       memset(&dst, 0, sizeof(dst));
2322 +
2323 +       /* dest ip is always in hash */
2324 +       dst.dst_ip = skb->nh.iph->daddr;
2325 +
2326 +       /* source ip only if respective hashmode, otherwise set to
2327 +        * zero */
2328 +       if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_SIP)
2329 +               dst.src_ip = skb->nh.iph->saddr;
2330 +
2331 +       /* dest port only if respective mode */
2332 +       if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_DPT) {
2333 +               u16 ports[2];
2334 +
2335 +               /* Must not be a fragment. */
2336 +               if (offset)
2337 +                       return 0;
2338 +
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. */
2344 +                       *hotdrop = 1;
2345 +                       return 0;
2346 +               }
2347 +
2348 +               switch (skb->nh.iph->protocol) {
2349 +                       struct tcphdr *th;
2350 +                       struct udphdr *uh;
2351 +               case IPPROTO_TCP:
2352 +                       th = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
2353 +                       dst.port = th->dest;
2354 +                       break;
2355 +               case IPPROTO_UDP:
2356 +                       uh = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
2357 +                       dst.port = uh->dest;
2358 +                       break;
2359 +               default:
2360 +                       break;
2361 +               }
2362 +       } 
2363 +
2364 +       LOCK_BH(&hinfo->lock);
2365 +       dh = __dsthash_find(hinfo, &dst);
2366 +       if (!dh) {
2367 +               dh = __dsthash_alloc_init(hinfo, &dst);
2368 +
2369 +               if (!dh) {
2370 +                       /* enomem... don't match == DROP */
2371 +                       if (net_ratelimit())
2372 +                               printk(KERN_ERR "%s: ENOMEM\n", __FUNCTION__);
2373 +                       UNLOCK_BH(&hinfo->lock);
2374 +                       return 0;
2375 +               }
2376 +
2377 +               dh->expires = jiffies + MS2JIFFIES(hinfo->cfg.expire);
2378 +
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);
2385 +
2386 +               UNLOCK_BH(&hinfo->lock);
2387 +               return 1;
2388 +       }
2389 +
2390 +       /* update expiration timeout */
2391 +       dh->expires = now + MS2JIFFIES(hinfo->cfg.expire);
2392 +
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);
2398 +               return 1;
2399 +       }
2400 +
2401 +               UNLOCK_BH(&hinfo->lock);
2402 +
2403 +       /* default case: we're overlimit, thus don't match */
2404 +       return 0;
2405 +}
2406 +
2407 +static int
2408 +dstlimit_checkentry(const char *tablename,
2409 +                    const struct ipt_ip *ip,
2410 +                    void *matchinfo,
2411 +                    unsigned int matchsize,
2412 +                    unsigned int hook_mask)
2413 +{
2414 +       struct ipt_dstlimit_info *r = matchinfo;
2415 +
2416 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_dstlimit_info)))
2417 +               return 0;
2418 +
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);
2425 +               return 0;
2426 +       }
2427 +
2428 +       if (r->cfg.mode == 0 
2429 +           || r->cfg.mode > (IPT_DSTLIMIT_HASH_DPT
2430 +                         |IPT_DSTLIMIT_HASH_DIP
2431 +                         |IPT_DSTLIMIT_HASH_SIP))
2432 +               return 0;
2433 +
2434 +       if (!r->cfg.gc_interval)
2435 +               return 0;
2436 +       
2437 +       if (!r->cfg.expire)
2438 +               return 0;
2439 +
2440 +       r->hinfo = htable_find_get(r->name);
2441 +       if (!r->hinfo && (htable_create(r) != 0)) {
2442 +               return 0;
2443 +       }
2444 +
2445 +       /* Ugly hack: For SMP, we only want to use one set */
2446 +       r->u.master = r;
2447 +
2448 +       return 1;
2449 +}
2450 +
2451 +static void
2452 +dstlimit_destroy(void *matchinfo, unsigned int matchsize)
2453 +{
2454 +       struct ipt_dstlimit_info *r = (struct ipt_dstlimit_info *) matchinfo;
2455 +
2456 +       htable_put(r->hinfo);
2457 +}
2458 +
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,
2465 +       .me = THIS_MODULE 
2466 +};
2467 +
2468 +/* PROC stuff */
2469 +
2470 +static void *dl_seq_start(struct seq_file *s, loff_t *pos)
2471 +{
2472 +       struct proc_dir_entry *pde = s->private;
2473 +       struct ipt_dstlimit_htable *htable = pde->data;
2474 +       unsigned int *bucket;
2475 +
2476 +       LOCK_BH(&htable->lock);
2477 +       if (*pos >= htable->cfg.size)
2478 +               return NULL;
2479 +
2480 +       bucket = kmalloc(sizeof(unsigned int), GFP_KERNEL);
2481 +       if (!bucket)
2482 +               return ERR_PTR(-ENOMEM);
2483 +
2484 +       *bucket = *pos;
2485 +       return bucket;
2486 +}
2487 +
2488 +static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
2489 +{
2490 +       struct proc_dir_entry *pde = s->private;
2491 +       struct ipt_dstlimit_htable *htable = pde->data;
2492 +       unsigned int *bucket = (unsigned int *)v;
2493 +
2494 +       *pos = ++(*bucket);
2495 +       if (*pos >= htable->cfg.size) {
2496 +               kfree(v);
2497 +               return NULL;
2498 +       }
2499 +       return bucket;
2500 +}
2501 +
2502 +static void dl_seq_stop(struct seq_file *s, void *v)
2503 +{
2504 +       struct proc_dir_entry *pde = s->private;
2505 +       struct ipt_dstlimit_htable *htable = pde->data;
2506 +       unsigned int *bucket = (unsigned int *)v;
2507 +
2508 +       kfree(bucket);
2509 +
2510 +       UNLOCK_BH(&htable->lock);
2511 +}
2512 +
2513 +static inline int dl_seq_real_show(struct dsthash_ent *ent, struct seq_file *s)
2514 +{
2515 +       /* recalculate to show accurate numbers */
2516 +       rateinfo_recalc(ent, jiffies);
2517 +
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);
2524 +}
2525 +
2526 +static int dl_seq_show(struct seq_file *s, void *v)
2527 +{
2528 +       struct proc_dir_entry *pde = s->private;
2529 +       struct ipt_dstlimit_htable *htable = pde->data;
2530 +       unsigned int *bucket = (unsigned int *)v;
2531 +
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 */
2535 +               return 1;
2536 +       }
2537 +       return 0;
2538 +}
2539 +
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
2545 +};
2546 +
2547 +static int dl_proc_open(struct inode *inode, struct file *file)
2548 +{
2549 +       int ret = seq_open(file, &dl_seq_ops);
2550 +
2551 +       if (!ret) {
2552 +               struct seq_file *sf = file->private_data;
2553 +               sf->private = PDE(inode);
2554 +       }
2555 +       return ret;
2556 +}
2557 +
2558 +static struct file_operations dl_file_ops = {
2559 +       .owner   = THIS_MODULE,
2560 +       .open    = dl_proc_open,
2561 +       .read    = seq_read,
2562 +       .llseek  = seq_lseek,
2563 +       .release = seq_release
2564 +};
2565 +
2566 +static int init_or_fini(int fini)
2567 +{
2568 +       int ret = 0;
2569 +
2570 +       if (fini)
2571 +               goto cleanup;
2572 +
2573 +       if (ipt_register_match(&ipt_dstlimit)) {
2574 +               ret = -EINVAL;
2575 +               goto cleanup_nothing;
2576 +       }
2577 +
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");
2585 +               ret = -ENOMEM;
2586 +               goto cleanup_unreg_match;
2587 +       }
2588 +
2589 +       dstlimit_procdir = proc_mkdir("ipt_dstlimit", proc_net);
2590 +       if (!dstlimit_procdir) {
2591 +               printk(KERN_ERR "Unable to create proc dir entry\n");
2592 +               ret = -ENOMEM;
2593 +               goto cleanup_free_slab;
2594 +       }
2595 +
2596 +       return ret;
2597 +
2598 +cleanup:
2599 +       remove_proc_entry("ipt_dstlimit", proc_net);
2600 +cleanup_free_slab:
2601 +       kmem_cache_destroy(dstlimit_cachep);
2602 +cleanup_unreg_match:
2603 +       ipt_unregister_match(&ipt_dstlimit);
2604 +cleanup_nothing:
2605 +       return ret;
2606 +       
2607 +}
2608 +
2609 +static int __init init(void)
2610 +{
2611 +       return init_or_fini(0);
2612 +}
2613 +
2614 +static void __exit fini(void)
2615 +{
2616 +       init_or_fini(1);
2617 +}
2618 +
2619 +module_init(init);
2620 +module_exit(fini);
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
2624 @@ -0,0 +1,185 @@
2625 +/*
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 .
2636 + *
2637 + *
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 .
2641 +*/
2642 +
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>
2651 +
2652 +/*
2653 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
2654 + Expressed in percentage
2655 +*/
2656 +
2657 +#define PAR_LOW                1/100
2658 +#define PAR_HIGH       1
2659 +
2660 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED ;
2661 +
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");
2665 +
2666 +static  u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
2667 +{
2668 +       if (tx >= maxi)
2669 +               return 100;
2670 +
2671 +       if (tx <= mini)
2672 +               return 0;
2673 +
2674 +       return ( (100*(tx-mini)) / (maxi-mini) );
2675 +}
2676 +
2677 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
2678 +{
2679 +       if (tx <= mini)
2680 +               return 100;
2681 +
2682 +       if (tx >= maxi)
2683 +               return 0;
2684 +
2685 +       return ( (100*( maxi - tx ))  / ( maxi - mini ) );
2686 +}
2687 +
2688 +static int
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,
2693 +              int offset,
2694 +              int *hotdrop)
2695 +{
2696 +       /* From userspace */
2697 +       
2698 +       struct ipt_fuzzy_info *info = (struct ipt_fuzzy_info *) matchinfo;
2699 +
2700 +       u_int8_t random_number;
2701 +       unsigned long amount;
2702 +       u_int8_t howhigh, howlow;
2703 +       
2704 +
2705 +       spin_lock_bh(&fuzzy_lock); /* Rise the lock */
2706 +
2707 +       info->bytes_total += pskb->len;
2708 +       info->packets_total++;
2709 +
2710 +       info->present_time = jiffies;
2711 +       
2712 +       if (info->present_time >= info->previous_time)
2713 +               amount = info->present_time - info->previous_time;
2714 +       else { 
2715 +               /* There was a transition : I choose to re-sample 
2716 +                  and keep the old acceptance rate...
2717 +               */
2718 +
2719 +               amount = 0;
2720 +               info->previous_time = info->present_time;
2721 +               info->bytes_total = info->packets_total = 0;
2722 +       };
2723 +       
2724 +       if (amount > HZ/10) /* More than 100 ms elapsed ... */
2725 +       {
2726 +
2727 +               info->mean_rate = (u_int32_t) ((HZ*info->packets_total)  \
2728 +                                       / amount );
2729 +
2730 +               info->previous_time = info->present_time;
2731 +               info->bytes_total = info->packets_total = 0;
2732 +
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);
2735 +
2736 +               info->acceptance_rate = (u_int8_t) \
2737 +                          (howhigh*PAR_LOW + PAR_HIGH*howlow);
2738 +
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 ,
2744 +                  I did so .  */ 
2745 +
2746 +       }
2747 +       
2748 +       spin_unlock_bh(&fuzzy_lock); /* Release the lock */
2749 +
2750 +
2751 +       if ( info->acceptance_rate < 100 )
2752 +       {                
2753 +               get_random_bytes((void *)(&random_number), 1);
2754 +
2755 +               /*  If within the acceptance , it can pass => don't match */
2756 +               if (random_number <= (255 * info->acceptance_rate) / 100)
2757 +                       return 0;
2758 +               else
2759 +                       return 1; /* It can't pass ( It matches ) */
2760 +       } ;
2761 +
2762 +       return 0; /* acceptance_rate == 100 % => Everything passes ... */
2763 +       
2764 +}
2765 +
2766 +static int
2767 +ipt_fuzzy_checkentry(const char *tablename,
2768 +                  const struct ipt_ip *e,
2769 +                  void *matchinfo,
2770 +                  unsigned int matchsize,
2771 +                  unsigned int hook_mask)
2772 +{
2773 +       
2774 +       const struct ipt_fuzzy_info *info = matchinfo;
2775 +
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)));
2779 +               return 0;
2780 +       }
2781 +
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");
2785 +               return 0;
2786 +       }
2787 +
2788 +       return 1;
2789 +}
2790 +
2791 +static struct ipt_match ipt_fuzzy_reg = { 
2792 +       .name = "fuzzy",
2793 +       .match = ipt_fuzzy_match,
2794 +       .checkentry = ipt_fuzzy_checkentry,
2795 +       .me = THIS_MODULE
2796 +};
2797 +
2798 +static int __init init(void)
2799 +{
2800 +       return ipt_register_match(&ipt_fuzzy_reg);
2801 +}
2802 +
2803 +static void __exit fini(void)
2804 +{
2805 +       ipt_unregister_match(&ipt_fuzzy_reg);
2806 +}
2807 +
2808 +module_init(init);
2809 +module_exit(fini);
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
2813 @@ -0,0 +1,172 @@
2814 +/*
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
2819 +
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
2825 +*/
2826 +
2827 +#include <linux/module.h>
2828 +#include <linux/skbuff.h>
2829 +#include <net/ip.h>
2830 +
2831 +#include <linux/netfilter_ipv4/ip_tables.h>
2832 +#include <linux/netfilter_ipv4/ipt_ipv4options.h>
2833 +
2834 +MODULE_LICENSE("GPL");
2835 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
2836 +
2837 +static int
2838 +match(const struct sk_buff *skb,
2839 +      const struct net_device *in,
2840 +      const struct net_device *out,
2841 +      const void *matchinfo,
2842 +      int offset,
2843 +      int *hotdrop)
2844 +{
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;
2848 +
2849 +       if (iph->ihl * 4 == sizeof(struct iphdr)) {
2850 +               /* No options, so we match only the "DONTs" and the "IGNOREs" */
2851 +
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))
2858 +                       return 0;
2859 +               return 1;
2860 +       }
2861 +       else {
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 */
2864 +                       return 1;
2865 +               else {
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 ! */
2868 +                               return 0;
2869 +               }
2870 +       }
2871 +
2872 +       opt = &(IPCB(skb)->opt);
2873 +
2874 +       /* source routing */
2875 +       if ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) {
2876 +               if (!((opt->srr) & (opt->is_strictroute)))
2877 +                       return 0;
2878 +       }
2879 +       else if ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) {
2880 +               if (!((opt->srr) & (!opt->is_strictroute)))
2881 +                       return 0;
2882 +       }
2883 +       else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) {
2884 +               if (opt->srr)
2885 +                       return 0;
2886 +       }
2887 +       /* record route */
2888 +       if ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) {
2889 +               if (!opt->rr)
2890 +                       return 0;
2891 +       }
2892 +       else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) {
2893 +               if (opt->rr)
2894 +                       return 0;
2895 +       }
2896 +       /* timestamp */
2897 +       if ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) {
2898 +               if (!opt->ts)
2899 +                       return 0;
2900 +       }
2901 +       else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) {
2902 +               if (opt->ts)
2903 +                       return 0;
2904 +       }
2905 +       /* router-alert option  */
2906 +       if ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) {
2907 +               if (!opt->router_alert)
2908 +                       return 0;
2909 +       }
2910 +       else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) {
2911 +               if (opt->router_alert)
2912 +                       return 0;
2913 +       }
2914 +
2915 +       /* we match ! */
2916 +       return 1;
2917 +}
2918 +
2919 +static int
2920 +checkentry(const char *tablename,
2921 +          const struct ipt_ip *ip,
2922 +          void *matchinfo,
2923 +          unsigned int matchsize,
2924 +          unsigned int hook_mask)
2925 +{
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)))
2929 +               return 0;
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 */
2962 +
2963 +       /* everything looks ok. */
2964 +       return 1;
2965 +}
2966 +
2967 +static struct ipt_match ipv4options_match = { 
2968 +       .name = "ipv4options",
2969 +       .match = match,
2970 +       .checkentry = checkentry,
2971 +       .me = THIS_MODULE
2972 +};
2973 +
2974 +static int __init init(void)
2975 +{
2976 +       return ipt_register_match(&ipv4options_match);
2977 +}
2978 +
2979 +static void __exit fini(void)
2980 +{
2981 +       ipt_unregister_match(&ipv4options_match);
2982 +}
2983 +
2984 +module_init(init);
2985 +module_exit(fini);
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
2989 @@ -0,0 +1,116 @@
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>
2996 +
2997 +#include <linux/netfilter_ipv4/ipt_mport.h>
2998 +#include <linux/netfilter_ipv4/ip_tables.h>
2999 +
3000 +MODULE_LICENSE("GPL");
3001 +
3002 +#if 0
3003 +#define duprintf(format, args...) printk(format , ## args)
3004 +#else
3005 +#define duprintf(format, args...)
3006 +#endif
3007 +
3008 +/* Returns 1 if the port is matched by the test, 0 otherwise. */
3009 +static inline int
3010 +ports_match(const struct ipt_mport *minfo, u_int16_t src, u_int16_t dst)
3011 +{
3012 +       unsigned int i;
3013 +        unsigned int m;
3014 +        u_int16_t pflags = minfo->pflags;
3015 +       for (i=0, m=1; i<IPT_MULTI_PORTS; i++, m<<=1) {
3016 +                u_int16_t s, e;
3017 +
3018 +                if (pflags & m
3019 +                    && minfo->ports[i] == 65535)
3020 +                        return 0;
3021 +
3022 +                s = minfo->ports[i];
3023 +
3024 +                if (pflags & m) {
3025 +                        e = minfo->ports[++i];
3026 +                        m <<= 1;
3027 +                } else
3028 +                        e = s;
3029 +
3030 +                if (minfo->flags & IPT_MPORT_SOURCE
3031 +                    && src >= s && src <= e)
3032 +                        return 1;
3033 +
3034 +               if (minfo->flags & IPT_MPORT_DESTINATION
3035 +                   && dst >= s && dst <= e)
3036 +                       return 1;
3037 +       }
3038 +
3039 +       return 0;
3040 +}
3041 +
3042 +static int
3043 +match(const struct sk_buff *skb,
3044 +      const struct net_device *in,
3045 +      const struct net_device *out,
3046 +      const void *matchinfo,
3047 +      int offset,
3048 +      int *hotdrop)
3049 +{
3050 +       u16 ports[2];
3051 +       const struct ipt_mport *minfo = matchinfo;
3052 +
3053 +       if (offset)
3054 +               return 0;
3055 +
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");
3063 +                       *hotdrop = 1;
3064 +                       return 0;
3065 +       }
3066 +
3067 +       return ports_match(minfo, ntohs(ports[0]), ntohs(ports[1]));
3068 +}
3069 +
3070 +/* Called when user tries to insert an entry of this type. */
3071 +static int
3072 +checkentry(const char *tablename,
3073 +          const struct ipt_ip *ip,
3074 +          void *matchinfo,
3075 +          unsigned int matchsize,
3076 +          unsigned int hook_mask)
3077 +{
3078 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_mport)))
3079 +               return 0;
3080 +
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));
3085 +}
3086 +
3087 +static struct ipt_match mport_match = { 
3088 +       .name = "mport",
3089 +       .match = &match,
3090 +       .checkentry = &checkentry,
3091 +       .me = THIS_MODULE
3092 +};
3093 +
3094 +static int __init init(void)
3095 +{
3096 +       return ipt_register_match(&mport_match);
3097 +}
3098 +
3099 +static void __exit fini(void)
3100 +{
3101 +       ipt_unregister_match(&mport_match);
3102 +}
3103 +
3104 +module_init(init);
3105 +module_exit(fini);
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
3109 @@ -0,0 +1,166 @@
3110 +/*
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
3115 +
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>
3122 +       * port to 2.6.x
3123 +
3124 +*/
3125 +
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>
3133 +
3134 +MODULE_LICENSE("GPL");
3135 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
3136 +
3137 +/*
3138 + * State information.
3139 + */
3140 +struct state {
3141 +       spinlock_t lock;
3142 +       u_int16_t number;
3143 +};
3144 +
3145 +static struct state states[IPT_NTH_NUM_COUNTERS];
3146 +
3147 +static int
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,
3152 +             int offset,
3153 +             int *hotdrop)
3154 +{
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)) 
3159 +       {
3160 +                       printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
3161 +               return 0;
3162 +        };
3163 +
3164 +        spin_lock(&states[counter].lock);
3165 +
3166 +        /* Are we matching every nth packet?*/
3167 +        if (info->packet == 0xFF)
3168 +        {
3169 +               /* We're matching every nth packet and only every nth packet*/
3170 +               /* Do we match or invert match? */
3171 +               if (info->not == 0)
3172 +               {
3173 +                       if (states[counter].number == 0)
3174 +                       {
3175 +                               ++states[counter].number;
3176 +                               goto match;
3177 +                       }
3178 +                       if (states[counter].number >= info->every)
3179 +                               states[counter].number = 0; /* reset the counter */
3180 +                       else
3181 +                               ++states[counter].number;
3182 +                       goto dontmatch;
3183 +               }
3184 +               else
3185 +               {
3186 +                       if (states[counter].number == 0)
3187 +                       {
3188 +                               ++states[counter].number;
3189 +                               goto dontmatch;
3190 +                       }
3191 +                       if (states[counter].number >= info->every)
3192 +                               states[counter].number = 0;
3193 +                       else
3194 +                               ++states[counter].number;
3195 +                       goto match;
3196 +               }
3197 +        }
3198 +        else
3199 +        {
3200 +               /* We're using the --packet, so there must be a rule for every value */
3201 +               if (states[counter].number == info->packet)
3202 +               {
3203 +                       /* only increment the counter when a match happens */
3204 +                       if (states[counter].number >= info->every)
3205 +                               states[counter].number = 0; /* reset the counter */
3206 +                       else
3207 +                               ++states[counter].number;
3208 +                       goto match;
3209 +               }
3210 +               else
3211 +                       goto dontmatch;
3212 +       }
3213 +
3214 + dontmatch:
3215 +       /* don't match */
3216 +       spin_unlock(&states[counter].lock);
3217 +       return 0;
3218 +
3219 + match:
3220 +       spin_unlock(&states[counter].lock);
3221 +       return 1;
3222 +}
3223 +
3224 +static int
3225 +ipt_nth_checkentry(const char *tablename,
3226 +                  const struct ipt_ip *e,
3227 +                  void *matchinfo,
3228 +                  unsigned int matchsize,
3229 +                  unsigned int hook_mask)
3230 +{
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)) 
3235 +       {
3236 +               printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
3237 +                       return 0;
3238 +               };
3239 +
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)));
3243 +               return 0;
3244 +       }
3245 +
3246 +       states[counter].number = info->startat;
3247 +
3248 +       return 1;
3249 +}
3250 +
3251 +static struct ipt_match ipt_nth_reg = { 
3252 +       .name = "nth",
3253 +       .match = ipt_nth_match,
3254 +       .checkentry = ipt_nth_checkentry,
3255 +       .me = THIS_MODULE
3256 +};
3257 +
3258 +static int __init init(void)
3259 +{
3260 +       unsigned counter;
3261 +
3262 +       memset(&states, 0, sizeof(states));
3263 +        for (counter = 0; counter < IPT_NTH_NUM_COUNTERS; counter++) 
3264 +               spin_lock_init(&(states[counter].lock));
3265 +
3266 +       return ipt_register_match(&ipt_nth_reg);
3267 +}
3268 +
3269 +static void __exit fini(void)
3270 +{
3271 +       ipt_unregister_match(&ipt_nth_reg);
3272 +}
3273 +
3274 +module_init(init);
3275 +module_exit(fini);
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
3279 @@ -0,0 +1,91 @@
3280 +/* 
3281 + * netfilter module to enforce network quotas
3282 + *
3283 + * Sam Johnston <samj@samj.net>
3284 + */
3285 +#include <linux/module.h>
3286 +#include <linux/skbuff.h>
3287 +#include <linux/spinlock.h>
3288 +#include <linux/interrupt.h>
3289 +
3290 +#include <linux/netfilter_ipv4/ip_tables.h>
3291 +#include <linux/netfilter_ipv4/ipt_quota.h>
3292 +
3293 +MODULE_LICENSE("GPL");
3294 +MODULE_AUTHOR("Sam Johnston <samj@samj.net>");
3295 +
3296 +static spinlock_t quota_lock = SPIN_LOCK_UNLOCKED;
3297 +
3298 +static int
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)
3304 +{
3305 +        struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
3306 +       unsigned int datalen;
3307 +
3308 +       if (skb->len < sizeof(struct iphdr))
3309 +               return NF_ACCEPT;
3310 +       
3311 +       datalen = skb->len - skb->nh.iph->ihl*4;
3312 +
3313 +        spin_lock_bh(&quota_lock);
3314 +
3315 +        if (q->quota >= datalen) {
3316 +                /* we can afford this one */
3317 +                q->quota -= datalen;
3318 +                spin_unlock_bh(&quota_lock);
3319 +
3320 +#ifdef DEBUG_IPT_QUOTA
3321 +                printk("IPT Quota OK: %llu datlen %d \n", q->quota, datalen);
3322 +#endif
3323 +                return 1;
3324 +        }
3325 +
3326 +        /* so we do not allow even small packets from now on */
3327 +        q->quota = 0;
3328 +
3329 +#ifdef DEBUG_IPT_QUOTA
3330 +        printk("IPT Quota Failed: %llu datlen %d \n", q->quota, datalen);
3331 +#endif
3332 +
3333 +        spin_unlock_bh(&quota_lock);
3334 +        return 0;
3335 +}
3336 +
3337 +static int
3338 +checkentry(const char *tablename,
3339 +           const struct ipt_ip *ip,
3340 +           void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
3341 +{
3342 +        /* TODO: spinlocks? sanity checks? */
3343 +        if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info)))
3344 +                return 0;
3345 +
3346 +        return 1;
3347 +}
3348 +
3349 +static struct ipt_match quota_match = {
3350 +       .name = "quota",
3351 +       .match = match,
3352 +       .checkentry = checkentry,
3353 +       .me = THIS_MODULE
3354 +};
3355 +
3356 +static int __init
3357 +init(void)
3358 +{
3359 +        return ipt_register_match(&quota_match);
3360 +}
3361 +
3362 +static void __exit
3363 +fini(void)
3364 +{
3365 +        ipt_unregister_match(&quota_match);
3366 +}
3367 +
3368 +module_init(init);
3369 +module_exit(fini);
3370 +
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
3374 @@ -0,0 +1,78 @@
3375 +/* IP tables module for matching the routing realm
3376 + *
3377 + * $Id$
3378 + *
3379 + * (C) 2003 by Sampsa Ranta <sampsa@netsonic.fi>
3380 + *
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.
3384 + */
3385 +
3386 +#include <linux/module.h>
3387 +#include <linux/skbuff.h>
3388 +#include <linux/netdevice.h>
3389 +#include <net/route.h>
3390 +
3391 +#include <linux/netfilter_ipv4/ipt_realm.h>
3392 +#include <linux/netfilter_ipv4/ip_tables.h>
3393 +
3394 +MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>");
3395 +MODULE_LICENSE("GPL");
3396 +
3397 +static int
3398 +match(const struct sk_buff *skb,
3399 +      const struct net_device *in,
3400 +      const struct net_device *out,
3401 +      const void *matchinfo,
3402 +      int offset,
3403 +      int *hotdrop)
3404 +{
3405 +       const struct ipt_realm_info *info = matchinfo;
3406 +       struct dst_entry *dst = skb->dst;
3407 +    
3408 +       if (!dst)
3409 +               return 0;
3410 +
3411 +       return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
3412 +}
3413 +
3414 +static int check(const char *tablename,
3415 +                 const struct ipt_ip *ip,
3416 +                 void *matchinfo,
3417 +                 unsigned int matchsize,
3418 +                 unsigned int hook_mask)
3419 +{
3420 +       if (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");
3425 +               return 0;
3426 +       }
3427 +
3428 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info)))
3429 +               return 0;
3430 +
3431 +       return 1;
3432 +}
3433 +
3434 +static struct ipt_match realm_match = {
3435 +       .name = "realm",
3436 +       .match = match, 
3437 +       .checkentry = check,
3438 +       .me = THIS_MODULE
3439 +};
3440 +
3441 +static int __init init(void)
3442 +{
3443 +       return ipt_register_match(&realm_match);
3444 +}
3445 +
3446 +static void __exit fini(void)
3447 +{
3448 +       ipt_unregister_match(&realm_match);
3449 +}
3450 +
3451 +module_init(init);
3452 +module_exit(fini);
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
3456 @@ -0,0 +1,197 @@
3457 +#include <linux/module.h>
3458 +#include <linux/skbuff.h>
3459 +#include <net/ip.h>
3460 +#include <linux/sctp.h>
3461 +
3462 +#include <linux/netfilter_ipv4/ip_tables.h>
3463 +#include <linux/netfilter_ipv4/ipt_sctp.h>
3464 +
3465 +#if 1
3466 +#define duprintf(format, args...) printk(format , ## args)
3467 +#else
3468 +#define duprintf(format, args...)
3469 +#endif
3470 +
3471 +#define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \
3472 +                                             || (!!((invflag) & (option)) ^ (cond)))
3473 +
3474 +static int
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)
3479 +{
3480 +       int i;
3481 +
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;
3485 +               }
3486 +       }
3487 +
3488 +       return 1;
3489 +}
3490 +
3491 +static int
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,
3497 +            int *hotdrop)
3498 +{
3499 +       int offset;
3500 +       u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
3501 +       sctp_chunkhdr_t sch;
3502 +
3503 +       if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) {
3504 +               SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap);
3505 +       }
3506 +
3507 +       offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t);
3508 +       do {
3509 +               if (skb_copy_bits(skb, offset, &sch, sizeof(sch)) < 0) {
3510 +                       duprintf("Dropping invalid SCTP packet.\n");
3511 +                       *hotdrop = 1;
3512 +                       return 0;
3513 +               }
3514 +
3515 +               duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n", 
3516 +                               ++i, offset, sch.type, htons(sch.length), sch.flags);
3517 +
3518 +               offset += (htons(sch.length) + 3) & ~3;
3519 +
3520 +               duprintf("skb->len: %d\toffset: %d\n", skb->len, offset);
3521 +
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)) {
3527 +                                       return 1;
3528 +                               }
3529 +                               break;
3530 +
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);
3535 +                               }
3536 +                               break;
3537 +
3538 +                       case SCTP_CHUNK_MATCH_ONLY:
3539 +                               if (!match_flags(flag_info, flag_count, 
3540 +                                       sch.type, sch.flags)) {
3541 +                                       return 0;
3542 +                               }
3543 +                               break;
3544 +                       }
3545 +               } else {
3546 +                       switch (chunk_match_type) {
3547 +                       case SCTP_CHUNK_MATCH_ONLY:
3548 +                               return 0;
3549 +                       }
3550 +               }
3551 +       } while (offset < skb->len);
3552 +
3553 +       switch (chunk_match_type) {
3554 +       case SCTP_CHUNK_MATCH_ALL:
3555 +               return SCTP_CHUNKMAP_IS_CLEAR(chunkmap);
3556 +       case SCTP_CHUNK_MATCH_ANY:
3557 +               return 0;
3558 +       case SCTP_CHUNK_MATCH_ONLY:
3559 +               return 1;
3560 +       }
3561 +
3562 +       /* This will never be reached, but required to stop compiler whine */
3563 +       return 0;
3564 +}
3565 +
3566 +static int
3567 +match(const struct sk_buff *skb,
3568 +      const struct net_device *in,
3569 +      const struct net_device *out,
3570 +      const void *matchinfo,
3571 +      int offset,
3572 +      int *hotdrop)
3573 +{
3574 +       const struct ipt_sctp_info *info;
3575 +       sctp_sctphdr_t sh;
3576 +
3577 +       info = (const struct ipt_sctp_info *)matchinfo;
3578 +
3579 +       if (offset) {
3580 +               duprintf("Dropping non-first fragment.. FIXME\n");
3581 +               return 0;
3582 +       }
3583 +       
3584 +       if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &sh, sizeof(sh)) < 0) {
3585 +               duprintf("Dropping evil TCP offset=0 tinygram.\n");
3586 +               *hotdrop = 1;
3587 +               return 0;
3588 +               }
3589 +       duprintf("spt: %d\tdpt: %d\n", ntohs(sh.source), ntohs(sh.dest));
3590 +
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, 
3599 +                                       hotdrop),
3600 +                          IPT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
3601 +}
3602 +
3603 +static int
3604 +checkentry(const char *tablename,
3605 +          const struct ipt_ip *ip,
3606 +          void *matchinfo,
3607 +          unsigned int matchsize,
3608 +          unsigned int hook_mask)
3609 +{
3610 +       const struct ipt_sctp_info *info;
3611 +
3612 +       info = (const struct ipt_sctp_info *)matchinfo;
3613 +
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)));
3625 +}
3626 +
3627 +static struct ipt_match sctp_match = 
3628 +{ 
3629 +       .list = { NULL, NULL},
3630 +       .name = "sctp",
3631 +       .match = &match,
3632 +       .checkentry = &checkentry,
3633 +       .destroy = NULL,
3634 +       .me = THIS_MODULE
3635 +};
3636 +
3637 +static int __init init(void)
3638 +{
3639 +       return ipt_register_match(&sctp_match);
3640 +}
3641 +
3642 +static void __exit fini(void)
3643 +{
3644 +       ipt_unregister_match(&sctp_match);
3645 +}
3646 +
3647 +module_init(init);
3648 +module_exit(fini);
3649 +
3650 +MODULE_LICENSE("GPL");
3651 +MODULE_AUTHOR("Kiran Kumar Immidi");
3652 +MODULE_DESCRIPTION("Match for SCTP protocol packets");
3653 +
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
3657 @@ -30,7 +30,9 @@
3658         enum ip_conntrack_info ctinfo;
3659         unsigned int statebit;
3660  
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;
3666         else
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
3671 @@ -0,0 +1,211 @@
3672 +/* Kernel module to match u32 packet content. */
3673 +
3674 +/* 
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.
3678 +
3679 + --u32 tests
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 := & | << | >> | @
3688 +
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.
3692 +
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
3698 +
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
3703 +
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.
3713 +
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.
3717 +
3718 +Example:
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" 
3722 + read bytes 0-3
3723 + AND that with FFFF (giving bytes 2-3),
3724 + and test whether that's in the range [0x100:0xFFFF]
3725 +
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
3742 + IP header itself.
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.
3757 +
3758 +Example: 
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
3772 +*/
3773 +
3774 +#include <linux/module.h>
3775 +#include <linux/skbuff.h>
3776 +
3777 +#include <linux/netfilter_ipv4/ipt_u32.h>
3778 +#include <linux/netfilter_ipv4/ip_tables.h>
3779 +
3780 +/* #include <asm-i386/timex.h> for timing */
3781 +
3782 +MODULE_AUTHOR("Don Cohen <don@isis.cs3-inc.com>");
3783 +MODULE_DESCRIPTION("IP tables u32 matching module");
3784 +MODULE_LICENSE("GPL");
3785 +
3786 +static int
3787 +match(const struct sk_buff *skb,
3788 +      const struct net_device *in,
3789 +      const struct net_device *out,
3790 +      const void *matchinfo,
3791 +      int offset,
3792 +      const void *hdr,
3793 +      u_int16_t datalen,
3794 +      int *hotdrop)
3795 +{
3796 +       const struct ipt_u32 *data = matchinfo;
3797 +       int testind, i;
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;
3802 +       int nnums, nvals;
3803 +       u_int32_t pos, val;
3804 +       /* unsigned long long cycles1, cycles2, cycles3, cycles4;
3805 +          cycles1 = get_cycles(); */
3806 +
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) 
3811 +                       return 0;
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) {
3818 +                       case IPT_U32_AND: 
3819 +                               val = val & number; 
3820 +                               break;
3821 +                       case IPT_U32_LEFTSH: 
3822 +                               val = val << number;
3823 +                               break;
3824 +                       case IPT_U32_RIGHTSH: 
3825 +                               val = val >> number; 
3826 +                               break;
3827 +                       case IPT_U32_AT:
3828 +                               base = base + val;
3829 +                               pos = number;
3830 +                               if (base+pos+3 > end || base+pos < head) 
3831 +                                       return 0;
3832 +                               val = (base[pos]<<24) + (base[pos+1]<<16) +
3833 +                                       (base[pos+2]<<8) + base[pos+3];
3834 +                               break;
3835 +                       }
3836 +               }
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)) {
3841 +                               break;
3842 +                       }
3843 +               }
3844 +               if (i >= data->tests[testind].nvalues) {
3845 +                       /* cycles2 = get_cycles(); 
3846 +                          printk("failed %d in %d cycles\n", testind, 
3847 +                                 cycles2-cycles1); */
3848 +                       return 0;
3849 +               }
3850 +       }
3851 +       /* cycles2 = get_cycles();
3852 +          printk("succeeded in %d cycles\n", cycles2-cycles1); */
3853 +       return 1;
3854 +}
3855 +
3856 +static int
3857 +checkentry(const char *tablename,
3858 +           const struct ipt_ip *ip,
3859 +           void *matchinfo,
3860 +           unsigned int matchsize,
3861 +           unsigned int hook_mask)
3862 +{
3863 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_u32)))
3864 +               return 0;
3865 +       return 1;
3866 +}
3867 +
3868 +static struct ipt_match u32_match
3869 += { { NULL, NULL }, "u32", &match, &checkentry, NULL, THIS_MODULE };
3870 +
3871 +static int __init init(void)
3872 +{
3873 +       return ipt_register_match(&u32_match);
3874 +}
3875 +
3876 +static void __exit fini(void)
3877 +{
3878 +       ipt_unregister_match(&u32_match);
3879 +}
3880 +
3881 +module_init(init);
3882 +module_exit(fini);
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
3886 @@ -0,0 +1,149 @@
3887 +/* 
3888 + * 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT .
3889 + *
3890 + * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
3891 + */
3892 +#include <linux/module.h>
3893 +#include <linux/netfilter_ipv4/ip_tables.h>
3894 +
3895 +#define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
3896 +
3897 +/* Standard entry. */
3898 +struct ipt_standard
3899 +{
3900 +       struct ipt_entry entry;
3901 +       struct ipt_standard_target target;
3902 +};
3903 +
3904 +struct ipt_error_target
3905 +{
3906 +       struct ipt_entry_target target;
3907 +       char errorname[IPT_FUNCTION_MAXNAMELEN];
3908 +};
3909 +
3910 +struct ipt_error
3911 +{
3912 +       struct ipt_entry entry;
3913 +       struct ipt_error_target target;
3914 +};
3915 +
3916 +static struct
3917 +{
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) },
3928 +      0, NULL, { } },
3929 +    {
3930 +           /* PRE_ROUTING */
3931 +           { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
3932 +               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 } },
3938 +           /* LOCAL_OUT */
3939 +           { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
3940 +               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 } }
3946 +    },
3947 +    /* ERROR */
3948 +    { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
3949 +       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 } },
3954 +         { } },
3955 +       "ERROR"
3956 +      }
3957 +    }
3958 +};
3959 +
3960 +static struct ipt_table packet_raw = { 
3961 +       .name = "raw", 
3962 +       .table = &initial_table.repl,
3963 +       .valid_hooks =  RAW_VALID_HOOKS, 
3964 +       .lock = RW_LOCK_UNLOCKED, 
3965 +       .me = THIS_MODULE
3966 +};
3967 +
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 *))
3975 +{
3976 +       return ipt_do_table(pskb, hook, in, out, &packet_raw, NULL);
3977 +}
3978 +
3979 +/* 'raw' is the very first table. */
3980 +static struct nf_hook_ops ipt_ops[] = {
3981 +       {
3982 +         .hook = ipt_hook, 
3983 +         .pf = PF_INET, 
3984 +         .hooknum = NF_IP_PRE_ROUTING, 
3985 +         .priority = NF_IP_PRI_RAW
3986 +       },
3987 +       {
3988 +         .hook = ipt_hook, 
3989 +         .pf = PF_INET, 
3990 +         .hooknum = NF_IP_LOCAL_OUT, 
3991 +         .priority = NF_IP_PRI_RAW
3992 +       },
3993 +};
3994 +
3995 +static int __init init(void)
3996 +{
3997 +       int ret;
3998 +
3999 +       /* Register table */
4000 +       ret = ipt_register_table(&packet_raw);
4001 +       if (ret < 0)
4002 +               return ret;
4003 +
4004 +       /* Register hooks */
4005 +       ret = nf_register_hook(&ipt_ops[0]);
4006 +       if (ret < 0)
4007 +               goto cleanup_table;
4008 +
4009 +       ret = nf_register_hook(&ipt_ops[1]);
4010 +       if (ret < 0)
4011 +               goto cleanup_hook0;
4012 +
4013 +       return ret;
4014 +
4015 + cleanup_hook0:
4016 +       nf_unregister_hook(&ipt_ops[0]);
4017 + cleanup_table:
4018 +       ipt_unregister_table(&packet_raw);
4019 +
4020 +       return ret;
4021 +}
4022 +
4023 +static void __exit fini(void)
4024 +{
4025 +       unsigned int i;
4026 +
4027 +       for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++)
4028 +               nf_unregister_hook(&ipt_ops[i]);
4029 +
4030 +       ipt_unregister_table(&packet_raw);
4031 +}
4032 +
4033 +module_init(init);
4034 +module_exit(fini);
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.
4041  
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
4046 +         help
4047 +
4048 +config IP6_NF_TARGET_REJECT
4049 +       tristate  'REJECT target support'
4050 +       depends on IP6_NF_FILTER
4051 +         help
4052 +
4053 +config IP6_NF_MATCH_FUZZY
4054 +       tristate  'Fuzzy match support'
4055 +       depends on IP6_NF_FILTER
4056 +         help
4057 +
4058 +config IP6_NF_MATCH_NTH
4059 +       tristate  'Nth match support'
4060 +       depends on IP6_NF_IPTABLES
4061 +         help
4062 +
4063 +config IP6_NF_RAW
4064 +       tristate  'raw table support (required for TRACE)'
4065 +       depends on IP6_NF_IPTABLES
4066 +       help
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.
4070 +       
4071 +         If you want to compile it as a module, say M here and read
4072 +         <file:Documentation/modules.txt>.  If unsure, say `N'.
4073 +         help
4074 +
4075  endmenu
4076  
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
4080 @@ -8,6 +8,7 @@
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
4088 @@ -19,6 +20,11 @@
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
4096 +
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
4103 @@ -0,0 +1,105 @@
4104 +/* 
4105 + * Hop Limit modification target for ip6tables
4106 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
4107 + * Based on HW's TTL module
4108 + *
4109 + * This software is distributed under the terms of GNU GPL
4110 + */
4111 +
4112 +#include <linux/module.h>
4113 +#include <linux/skbuff.h>
4114 +#include <linux/ip.h>
4115 +
4116 +#include <linux/netfilter_ipv6/ip6_tables.h>
4117 +#include <linux/netfilter_ipv6/ip6t_HL.h>
4118 +
4119 +MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
4120 +MODULE_DESCRIPTION("IP tables Hop Limit modification module");
4121 +MODULE_LICENSE("GPL");
4122 +
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)
4126 +{
4127 +       struct ipv6hdr *ip6h = (*pskb)->nh.ipv6h;
4128 +       const struct ip6t_HL_info *info = targinfo;
4129 +       u_int16_t diffs[2];
4130 +       int new_hl;
4131 +                        
4132 +       switch (info->mode) {
4133 +               case IP6T_HL_SET:
4134 +                       new_hl = info->hop_limit;
4135 +                       break;
4136 +               case IP6T_HL_INC:
4137 +                       new_hl = ip6h->hop_limit + info->hop_limit;
4138 +                       if (new_hl > 255)
4139 +                               new_hl = 255;
4140 +                       break;
4141 +               case IP6T_HL_DEC:
4142 +                       new_hl = ip6h->hop_limit + info->hop_limit;
4143 +                       if (new_hl < 0)
4144 +                               new_hl = 0;
4145 +                       break;
4146 +               default:
4147 +                       new_hl = ip6h->hop_limit;
4148 +                       break;
4149 +       }
4150 +
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);
4155 +       }
4156 +
4157 +       return IP6T_CONTINUE;
4158 +}
4159 +
4160 +static int ip6t_hl_checkentry(const char *tablename,
4161 +               const struct ip6t_entry *e,
4162 +               void *targinfo,
4163 +               unsigned int targinfosize,
4164 +               unsigned int hook_mask)
4165 +{
4166 +       struct ip6t_HL_info *info = targinfo;
4167 +
4168 +       if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_HL_info))) {
4169 +               printk(KERN_WARNING "HL: targinfosize %u != %Zu\n",
4170 +                               targinfosize,
4171 +                               IP6T_ALIGN(sizeof(struct ip6t_HL_info)));
4172 +               return 0;       
4173 +       }       
4174 +
4175 +       if (strcmp(tablename, "mangle")) {
4176 +               printk(KERN_WARNING "HL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
4177 +               return 0;
4178 +       }
4179 +
4180 +       if (info->mode > IP6T_HL_MAXMODE) {
4181 +               printk(KERN_WARNING "HL: invalid or unknown Mode %u\n", 
4182 +                       info->mode);
4183 +               return 0;
4184 +       }
4185 +
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");
4188 +               return 0;
4189 +       }
4190 +       
4191 +       return 1;
4192 +}
4193 +
4194 +static struct ip6t_target ip6t_HL = { { NULL, NULL }, "HL", 
4195 +       ip6t_hl_target, ip6t_hl_checkentry, NULL, THIS_MODULE };
4196 +
4197 +static int __init init(void)
4198 +{
4199 +       return ip6t_register_target(&ip6t_HL);
4200 +}
4201 +
4202 +static void __exit fini(void)
4203 +{
4204 +       ip6t_unregister_target(&ip6t_HL);
4205 +}
4206 +
4207 +module_init(init);
4208 +module_exit(fini);
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
4212 @@ -18,12 +18,17 @@
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>
4218  
4219  MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
4220  MODULE_DESCRIPTION("IP6 tables LOG target module");
4221  MODULE_LICENSE("GPL");
4222  
4223 +static unsigned int nflog = 1;
4224 +MODULE_PARM(nflog, "i");
4225 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
4226
4227  struct in_device;
4228  #include <net/route.h>
4229  #include <linux/netfilter_ipv6/ip6t_LOG.h>
4230 @@ -265,40 +270,38 @@
4231         }
4232  }
4233  
4234 -static unsigned int
4235 -ip6t_log_target(struct sk_buff **pskb,
4236 -               unsigned int hooknum,
4237 +static void
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,
4243 -               void *userinfo)
4244 +               const struct ip6t_log_info *loginfo,
4245 +               const char *level_string,
4246 +               const char *prefix)
4247  {
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;
4252  
4253 -       level_string[1] = '0' + (loginfo->level % 8);
4254         spin_lock_bh(&log_lock);
4255         printk(level_string);
4256         printk("%sIN=%s OUT=%s ",
4257 -               loginfo->prefix,
4258 +               prefix == NULL ? loginfo->prefix : prefix,
4259                 in ? in->name : "",
4260                 out ? out->name : "");
4261         if (in && !out) {
4262                 /* MAC logging for input chain only. */
4263                 printk("MAC=");
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){
4268                           int i;
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
4276                                         ? ' ':':');
4277                         } else {
4278                           int i;
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 ){
4283                             p -= (ETH_ALEN+2);
4284                             for (i = 0; i < (ETH_ALEN); i++,p++)
4285                                 printk("%02x%s", *p,
4286 @@ -309,10 +312,10 @@
4287                                         i == ETH_ALEN-1 ? ' ' : ':');
4288                           }
4289                           
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){
4294                             printk("TUNNEL=");
4295 -                           p = (*pskb)->mac.raw + 12;
4296 +                           p = skb->mac.raw + 12;
4297                             for (i = 0; i < 4; i++,p++)
4298                                 printk("%3d%s", *p,
4299                                         i == 3 ? "->" : ".");
4300 @@ -328,10 +331,41 @@
4301         dump_packet(loginfo, ipv6h, 1);
4302         printk("\n");
4303         spin_unlock_bh(&log_lock);
4304 +}
4305 +
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,
4312 +               void *userinfo)
4313 +{
4314 +       const struct ip6t_log_info *loginfo = targinfo;
4315 +       char level_string[4] = "< >";
4316 +
4317 +       level_string[1] = '0' + (loginfo->level % 8);
4318 +       ip6t_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
4319  
4320         return IP6T_CONTINUE;
4321  }
4322  
4323 +static void
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)
4329 +{
4330 +       struct ip6t_log_info loginfo = {
4331 +               .level = 0,
4332 +               .logflags = IP6T_LOG_MASK,
4333 +               .prefix = ""
4334 +       };
4335 +
4336 +       ip6t_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
4337 +}
4338 +
4339  static int ip6t_log_checkentry(const char *tablename,
4340                                const struct ip6t_entry *e,
4341                                void *targinfo,
4342 @@ -360,20 +394,27 @@
4343         return 1;
4344  }
4345  
4346 -static struct ip6t_target ip6t_log_reg
4347 -= { { NULL, NULL }, "LOG", ip6t_log_target, ip6t_log_checkentry, NULL, 
4348 -    THIS_MODULE };
4349 +static struct ip6t_target ip6t_log_reg = {
4350 +       .name           = "LOG",
4351 +       .target         = ip6t_log_target, 
4352 +       .checkentry     = ip6t_log_checkentry, 
4353 +       .me             = THIS_MODULE,
4354 +};
4355  
4356  static int __init init(void)
4357  {
4358         if (ip6t_register_target(&ip6t_log_reg))
4359                 return -EINVAL;
4360 +       if (nflog)
4361 +               nf_log_register(PF_INET6, &ip6t_logfn);
4362  
4363         return 0;
4364  }
4365  
4366  static void __exit fini(void)
4367  {
4368 +       if (nflog)
4369 +               nf_log_unregister(PF_INET6, &ip6t_logfn);
4370         ip6t_unregister_target(&ip6t_log_reg);
4371  }
4372  
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
4376 @@ -0,0 +1,274 @@
4377 +/*
4378 + * This is a module which is used for rejecting packets.
4379 + *     Added support for customized reject packets (Jozsef Kadlecsik).
4380 + * Sun 12 Nov 2000
4381 + *     Port to IPv6 / ip6tables (Harald Welte <laforge@gnumonks.org>)
4382 + */
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>
4390 +
4391 +#if 1
4392 +#define DEBUGP printk
4393 +#else
4394 +#define DEBUGP(format, args...)
4395 +#endif
4396 +
4397 +#if 0
4398 +/* Send RST reply */
4399 +static void send_reset(struct sk_buff *oldskb)
4400 +{
4401 +       struct sk_buff *nskb;
4402 +       struct tcphdr *otcph, *tcph;
4403 +       struct rtable *rt;
4404 +       unsigned int otcplen;
4405 +       int needs_ack;
4406 +
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))
4410 +               return;
4411 +
4412 +       otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl);
4413 +       otcplen = oldskb->len - oldskb->nh.iph->ihl*4;
4414 +
4415 +       /* No RST for RST. */
4416 +       if (otcph->rst)
4417 +               return;
4418 +
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)
4423 +               return;
4424 +
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);
4429 +       if (!nskb)
4430 +               return;
4431 +
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;
4438 +#endif
4439 +
4440 +       tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
4441 +
4442 +       nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
4443 +       tcph->source = xchg(&tcph->dest, tcph->source);
4444 +
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);
4449 +
4450 +       if (tcph->ack) {
4451 +               needs_ack = 0;
4452 +               tcph->seq = otcph->ack_seq;
4453 +               tcph->ack_seq = 0;
4454 +       } else {
4455 +               needs_ack = 1;
4456 +               tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin
4457 +                                     + otcplen - (otcph->doff<<2));
4458 +               tcph->seq = 0;
4459 +       }
4460 +
4461 +       /* Reset flags */
4462 +       ((u_int8_t *)tcph)[13] = 0;
4463 +       tcph->rst = 1;
4464 +       tcph->ack = needs_ack;
4465 +
4466 +       tcph->window = 0;
4467 +       tcph->urg_ptr = 0;
4468 +
4469 +       /* Adjust TCP checksum */
4470 +       tcph->check = 0;
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));
4476 +
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;
4482 +
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);
4487 +
4488 +       /* Routing */
4489 +       if (ip_route_output(&rt, nskb->nh.iph->daddr, nskb->nh.iph->saddr,
4490 +                           RT_TOS(nskb->nh.iph->tos) | RTO_CONN,
4491 +                           0) != 0)
4492 +               goto free_nskb;
4493 +
4494 +       dst_release(nskb->dst);
4495 +       nskb->dst = &rt->u.dst;
4496 +
4497 +       /* "Never happens" */
4498 +       if (nskb->len > nskb->dst->pmtu)
4499 +               goto free_nskb;
4500 +
4501 +       NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
4502 +               ip_finish_output);
4503 +       return;
4504 +
4505 + free_nskb:
4506 +       kfree_skb(nskb);
4507 +}
4508 +#endif
4509 +
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,
4515 +                          void *userinfo)
4516 +{
4517 +       const struct ip6t_reject_info *reject = targinfo;
4518 +
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);
4526 +               break;
4527 +       case IP6T_ICMP6_ADM_PROHIBITED:
4528 +               icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADM_PROHIBITED, 0, out);
4529 +               break;
4530 +       case IP6T_ICMP6_NOT_NEIGHBOUR:
4531 +               icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOT_NEIGHBOUR, 0, out);
4532 +               break;
4533 +       case IP6T_ICMP6_ADDR_UNREACH:
4534 +               icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, out);
4535 +               break;
4536 +       case IP6T_ICMP6_PORT_UNREACH:
4537 +               icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, out);
4538 +               break;
4539 +#if 0
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;
4544 +
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
4550 +                           mins! --RR */
4551 +                       struct icmp_bxm icmp_param;
4552 +
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);
4558 +               }
4559 +       }
4560 +       break;
4561 +       case IPT_TCP_RESET:
4562 +               send_reset(*pskb);
4563 +               break;
4564 +#endif
4565 +       default:
4566 +               printk(KERN_WARNING "REJECTv6: case %u not handled yet\n", reject->with);
4567 +               break;
4568 +       }
4569 +
4570 +       return NF_DROP;
4571 +}
4572 +
4573 +static inline int find_ping_match(const struct ip6t_entry_match *m)
4574 +{
4575 +       const struct ip6t_icmp *icmpinfo = (const struct ip6t_icmp *)m->data;
4576 +
4577 +       if (strcmp(m->u.kernel.match->name, "icmp6") == 0
4578 +           && icmpinfo->type == ICMPV6_ECHO_REQUEST
4579 +           && !(icmpinfo->invflags & IP6T_ICMP_INV))
4580 +               return 1;
4581 +
4582 +       return 0;
4583 +}
4584 +
4585 +static int check(const char *tablename,
4586 +                const struct ip6t_entry *e,
4587 +                void *targinfo,
4588 +                unsigned int targinfosize,
4589 +                unsigned int hook_mask)
4590 +{
4591 +       const struct ip6t_reject_info *rejinfo = targinfo;
4592 +
4593 +       if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
4594 +               DEBUGP("REJECTv6: targinfosize %u != 0\n", targinfosize);
4595 +               return 0;
4596 +       }
4597 +
4598 +       /* Only allow these for packet filtering. */
4599 +       if (strcmp(tablename, "filter") != 0) {
4600 +               DEBUGP("REJECTv6: bad table `%s'.\n", tablename);
4601 +               return 0;
4602 +       }
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);
4607 +               return 0;
4608 +       }
4609 +
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");
4615 +                       return 0;
4616 +               }
4617 +               /* Must contain ICMP match. */
4618 +               if (IP6T_MATCH_ITERATE(e, find_ping_match) == 0) {
4619 +                       DEBUGP("REJECTv6: ECHOREPLY illegal for non-ping\n");
4620 +                       return 0;
4621 +               }
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");
4627 +                       return 0;
4628 +               }
4629 +       }
4630 +
4631 +       return 1;
4632 +}
4633 +
4634 +static struct ip6t_target ip6t_reject_reg
4635 += { { NULL, NULL }, "REJECT", reject6_target, check, NULL, THIS_MODULE };
4636 +
4637 +static int __init init(void)
4638 +{
4639 +       if (ip6t_register_target(&ip6t_reject_reg))
4640 +               return -EINVAL;
4641 +       return 0;
4642 +}
4643 +
4644 +static void __exit fini(void)
4645 +{
4646 +       ip6t_unregister_target(&ip6t_reject_reg);
4647 +}
4648 +
4649 +module_init(init);
4650 +module_exit(fini);
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
4654 @@ -0,0 +1,189 @@
4655 +/*
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 .
4666 + *
4667 + *
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
4672 + */
4673 +
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>
4682 +
4683 +/*
4684 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
4685 + Expressed in percentage
4686 +*/
4687 +
4688 +#define PAR_LOW                1/100
4689 +#define PAR_HIGH       1
4690 +
4691 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED;
4692 +
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");
4696 +
4697 +static  u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
4698 +{
4699 +       if (tx >= maxi) return 100;
4700 +
4701 +       if (tx <= mini) return 0;
4702 +
4703 +       return ((100 * (tx-mini)) / (maxi-mini));
4704 +}
4705 +
4706 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
4707 +{
4708 +       if (tx <= mini) return 100;
4709 +
4710 +       if (tx >= maxi) return 0;
4711 +
4712 +       return ((100 * (maxi - tx)) / (maxi - mini));
4713 +
4714 +}
4715 +
4716 +static int
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,
4721 +              int offset,
4722 +              const void *hdr,
4723 +              u_int16_t datalen,
4724 +              int *hotdrop)
4725 +{
4726 +       /* From userspace */
4727 +
4728 +       struct ip6t_fuzzy_info *info = (struct ip6t_fuzzy_info *) matchinfo;
4729 +
4730 +       u_int8_t random_number;
4731 +       unsigned long amount;
4732 +       u_int8_t howhigh, howlow;
4733 +
4734 +
4735 +       spin_lock_bh(&fuzzy_lock); /* Rise the lock */
4736 +
4737 +       info->bytes_total += pskb->len;
4738 +       info->packets_total++;
4739 +
4740 +       info->present_time = jiffies;
4741 +
4742 +       if (info->present_time >= info->previous_time)
4743 +               amount = info->present_time - info->previous_time;
4744 +       else {
4745 +               /* There was a transition : I choose to re-sample
4746 +                  and keep the old acceptance rate...
4747 +               */
4748 +
4749 +               amount = 0;
4750 +               info->previous_time = info->present_time;
4751 +               info->bytes_total = info->packets_total = 0;
4752 +            };
4753 +
4754 +       if ( amount > HZ/10) {/* More than 100 ms elapsed ... */
4755 +
4756 +               info->mean_rate = (u_int32_t) ((HZ * info->packets_total) \
4757 +                                       / amount);
4758 +
4759 +               info->previous_time = info->present_time;
4760 +               info->bytes_total = info->packets_total = 0;
4761 +
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);
4764 +
4765 +               info->acceptance_rate = (u_int8_t) \
4766 +                               (howhigh * PAR_LOW + PAR_HIGH * howlow);
4767 +
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,
4773 +        * I did so.
4774 +        */
4775 +
4776 +       }
4777 +
4778 +       spin_unlock_bh(&fuzzy_lock); /* Release the lock */
4779 +
4780 +
4781 +       if (info->acceptance_rate < 100)
4782 +       {
4783 +               get_random_bytes((void *)(&random_number), 1);
4784 +
4785 +               /*  If within the acceptance , it can pass => don't match */
4786 +               if (random_number <= (255 * info->acceptance_rate) / 100)
4787 +                       return 0;
4788 +               else
4789 +                       return 1; /* It can't pass (It matches) */
4790 +       };
4791 +
4792 +       return 0; /* acceptance_rate == 100 % => Everything passes ... */
4793 +
4794 +}
4795 +
4796 +static int
4797 +ip6t_fuzzy_checkentry(const char *tablename,
4798 +                  const struct ip6t_ip6 *ip,
4799 +                  void *matchinfo,
4800 +                  unsigned int matchsize,
4801 +                  unsigned int hook_mask)
4802 +{
4803 +
4804 +       const struct ip6t_fuzzy_info *info = matchinfo;
4805 +
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)));
4809 +               return 0;
4810 +       }
4811 +
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");
4815 +               return 0;
4816 +       }
4817 +
4818 +       return 1;
4819 +}
4820 +
4821 +static struct ip6t_match ip6t_fuzzy_reg = {
4822 +       {NULL, NULL},
4823 +       "fuzzy",
4824 +       ip6t_fuzzy_match,
4825 +       ip6t_fuzzy_checkentry,
4826 +       NULL,
4827 +       THIS_MODULE };
4828 +
4829 +static int __init init(void)
4830 +{
4831 +       if (ip6t_register_match(&ip6t_fuzzy_reg))
4832 +               return -EINVAL;
4833 +
4834 +       return 0;
4835 +}
4836 +
4837 +static void __exit fini(void)
4838 +{
4839 +       ip6t_unregister_match(&ip6t_fuzzy_reg);
4840 +}
4841 +
4842 +module_init(init);
4843 +module_exit(fini);
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
4847 @@ -0,0 +1,173 @@
4848 +/*
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
4853 +
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
4860 +
4861 +*/
4862 +
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>
4870 +
4871 +MODULE_LICENSE("GPL");
4872 +
4873 +/*
4874 + * State information.
4875 + */
4876 +struct state {
4877 +       spinlock_t lock;
4878 +       u_int16_t number;
4879 +};
4880 +
4881 +static struct state states[IP6T_NTH_NUM_COUNTERS];
4882 +
4883 +static int
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,
4888 +             int offset,
4889 +             const void *hdr,
4890 +             u_int16_t datalen,
4891 +             int *hotdrop)
4892 +{
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)) 
4897 +       {
4898 +                       printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
4899 +               return 0;
4900 +        };
4901 +
4902 +        spin_lock(&states[counter].lock);
4903 +
4904 +        /* Are we matching every nth packet?*/
4905 +        if (info->packet == 0xFF)
4906 +        {
4907 +               /* We're matching every nth packet and only every nth packet*/
4908 +               /* Do we match or invert match? */
4909 +               if (info->not == 0)
4910 +               {
4911 +                       if (states[counter].number == 0)
4912 +                       {
4913 +                               ++states[counter].number;
4914 +                               goto match;
4915 +                       }
4916 +                       if (states[counter].number >= info->every)
4917 +                               states[counter].number = 0; /* reset the counter */
4918 +                       else
4919 +                               ++states[counter].number;
4920 +                       goto dontmatch;
4921 +               }
4922 +               else
4923 +               {
4924 +                       if (states[counter].number == 0)
4925 +                       {
4926 +                               ++states[counter].number;
4927 +                               goto dontmatch;
4928 +                       }
4929 +                       if (states[counter].number >= info->every)
4930 +                               states[counter].number = 0;
4931 +                       else
4932 +                               ++states[counter].number;
4933 +                       goto match;
4934 +               }
4935 +        }
4936 +        else
4937 +        {
4938 +               /* We're using the --packet, so there must be a rule for every value */
4939 +               if (states[counter].number == info->packet)
4940 +               {
4941 +                       /* only increment the counter when a match happens */
4942 +                       if (states[counter].number >= info->every)
4943 +                               states[counter].number = 0; /* reset the counter */
4944 +                       else
4945 +                               ++states[counter].number;
4946 +                       goto match;
4947 +               }
4948 +               else
4949 +                       goto dontmatch;
4950 +       }
4951 +
4952 + dontmatch:
4953 +       /* don't match */
4954 +       spin_unlock(&states[counter].lock);
4955 +       return 0;
4956 +
4957 + match:
4958 +       spin_unlock(&states[counter].lock);
4959 +       return 1;
4960 +}
4961 +
4962 +static int
4963 +ip6t_nth_checkentry(const char *tablename,
4964 +                  const struct ip6t_ip6 *e,
4965 +                  void *matchinfo,
4966 +                  unsigned int matchsize,
4967 +                  unsigned int hook_mask)
4968 +{
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)) 
4973 +       {
4974 +               printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
4975 +                       return 0;
4976 +               };
4977 +
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)));
4981 +               return 0;
4982 +       }
4983 +
4984 +       states[counter].number = info->startat;
4985 +
4986 +       return 1;
4987 +}
4988 +
4989 +static struct ip6t_match ip6t_nth_reg = { 
4990 +       {NULL, NULL},
4991 +       "nth",
4992 +       ip6t_nth_match,
4993 +       ip6t_nth_checkentry,
4994 +       NULL,
4995 +       THIS_MODULE };
4996 +
4997 +static int __init init(void)
4998 +{
4999 +       unsigned counter;
5000 +        memset(&states, 0, sizeof(states));
5001 +       if (ip6t_register_match(&ip6t_nth_reg))
5002 +               return -EINVAL;
5003 +
5004 +        for(counter = 0; counter < IP6T_NTH_NUM_COUNTERS; counter++) 
5005 +       {
5006 +               spin_lock_init(&(states[counter].lock));
5007 +        };
5008 +
5009 +       printk("ip6t_nth match loaded\n");
5010 +       return 0;
5011 +}
5012 +
5013 +static void __exit fini(void)
5014 +{
5015 +       ip6t_unregister_match(&ip6t_nth_reg);
5016 +       printk("ip6t_nth match unloaded\n");
5017 +}
5018 +
5019 +module_init(init);
5020 +module_exit(fini);
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
5024 @@ -0,0 +1,154 @@
5025 +/*
5026 + * IPv6 raw table, a port of the IPv4 raw table to IPv6
5027 + *
5028 + * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
5029 + */
5030 +#include <linux/module.h>
5031 +#include <linux/netfilter_ipv6/ip6_tables.h>
5032 +
5033 +#define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT))
5034 +
5035 +#if 0
5036 +#define DEBUGP(x, args...)     printk(KERN_DEBUG x, ## args)
5037 +#else
5038 +#define DEBUGP(x, args...)
5039 +#endif
5040 +
5041 +/* Standard entry. */
5042 +struct ip6t_standard
5043 +{
5044 +       struct ip6t_entry entry;
5045 +       struct ip6t_standard_target target;
5046 +};
5047 +
5048 +struct ip6t_error_target
5049 +{
5050 +       struct ip6t_entry_target target;
5051 +       char errorname[IP6T_FUNCTION_MAXNAMELEN];
5052 +};
5053 +
5054 +struct ip6t_error
5055 +{
5056 +       struct ip6t_entry entry;
5057 +       struct ip6t_error_target target;
5058 +};
5059 +
5060 +static struct
5061 +{
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) },
5072 +      0, NULL, { } },
5073 +    {
5074 +           /* PRE_ROUTING */
5075 +            { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
5076 +               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 } },
5082 +           /* LOCAL_OUT */
5083 +            { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
5084 +               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 } },
5090 +    },
5091 +    /* ERROR */
5092 +    { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
5093 +       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 } },
5098 +         { } },
5099 +       "ERROR"
5100 +      }
5101 +    }
5102 +};
5103 +
5104 +static struct ip6t_table packet_raw = { 
5105 +       .name = "raw", 
5106 +       .table = &initial_table.repl,
5107 +       .valid_hooks = RAW_VALID_HOOKS, 
5108 +       .lock = RW_LOCK_UNLOCKED, 
5109 +       .me = THIS_MODULE
5110 +};
5111 +
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 *))
5119 +{
5120 +       return ip6t_do_table(pskb, hook, in, out, &packet_raw, NULL);
5121 +}
5122 +
5123 +static struct nf_hook_ops ip6t_ops[] = { 
5124 +       {
5125 +         .hook = ip6t_hook, 
5126 +         .pf = PF_INET6,
5127 +         .hooknum = NF_IP6_PRE_ROUTING,
5128 +         .priority = NF_IP6_PRI_FIRST
5129 +       },
5130 +       {
5131 +         .hook = ip6t_hook, 
5132 +         .pf = PF_INET6, 
5133 +         .hooknum = NF_IP6_LOCAL_OUT,
5134 +         .priority = NF_IP6_PRI_FIRST
5135 +       },
5136 +};
5137 +
5138 +static int __init init(void)
5139 +{
5140 +       int ret;
5141 +
5142 +       /* Register table */
5143 +       ret = ip6t_register_table(&packet_raw);
5144 +       if (ret < 0)
5145 +               return ret;
5146 +
5147 +       /* Register hooks */
5148 +       ret = nf_register_hook(&ip6t_ops[0]);
5149 +       if (ret < 0)
5150 +               goto cleanup_table;
5151 +
5152 +       ret = nf_register_hook(&ip6t_ops[1]);
5153 +       if (ret < 0)
5154 +               goto cleanup_hook0;
5155 +
5156 +       return ret;
5157 +
5158 + cleanup_hook0:
5159 +       nf_unregister_hook(&ip6t_ops[0]);
5160 + cleanup_table:
5161 +       ip6t_unregister_table(&packet_raw);
5162 +
5163 +       return ret;
5164 +}
5165 +
5166 +static void __exit fini(void)
5167 +{
5168 +       unsigned int i;
5169 +
5170 +       for (i = 0; i < sizeof(ip6t_ops)/sizeof(struct nf_hook_ops); i++)
5171 +               nf_unregister_hook(&ip6t_ops[i]);
5172 +
5173 +       ip6t_unregister_table(&packet_raw);
5174 +}
5175 +
5176 +module_init(init);
5177 +module_exit(fini);
5178 +MODULE_LICENSE("GPL");
This page took 0.421914 seconds and 3 git commands to generate.