]> git.pld-linux.org Git - packages/kernel.git/blob - pom-ng-fuzzy-20060504.patch
- converted to utf8
[packages/kernel.git] / pom-ng-fuzzy-20060504.patch
1  include/linux/netfilter_ipv4/ipt_fuzzy.h  |   21 +++
2  include/linux/netfilter_ipv6/ip6t_fuzzy.h |   21 +++
3  net/ipv4/netfilter/Kconfig                |   10 +
4  net/ipv4/netfilter/Makefile               |    1 
5  net/ipv4/netfilter/ipt_fuzzy.c            |  185 +++++++++++++++++++++++++++++
6  net/ipv6/netfilter/Kconfig                |   10 +
7  net/ipv6/netfilter/Makefile               |    1 
8  net/ipv6/netfilter/ip6t_fuzzy.c           |  188 ++++++++++++++++++++++++++++++
9  8 files changed, 437 insertions(+)
10
11 diff -Nur --exclude '*.orig' linux.org/include/linux/netfilter_ipv4/ipt_fuzzy.h linux/include/linux/netfilter_ipv4/ipt_fuzzy.h
12 --- linux.org/include/linux/netfilter_ipv4/ipt_fuzzy.h  1970-01-01 01:00:00.000000000 +0100
13 +++ linux/include/linux/netfilter_ipv4/ipt_fuzzy.h      2006-05-04 10:09:04.000000000 +0200
14 @@ -0,0 +1,21 @@
15 +#ifndef _IPT_FUZZY_H
16 +#define _IPT_FUZZY_H
17 +
18 +#include <linux/param.h>
19 +#include <linux/types.h>
20 +
21 +#define MAXFUZZYRATE 10000000
22 +#define MINFUZZYRATE 3
23 +
24 +struct ipt_fuzzy_info {
25 +       u_int32_t minimum_rate;
26 +       u_int32_t maximum_rate;
27 +       u_int32_t packets_total;
28 +       u_int32_t bytes_total;
29 +       u_int32_t previous_time;
30 +       u_int32_t present_time;
31 +       u_int32_t mean_rate;
32 +       u_int8_t acceptance_rate;
33 +};
34 +
35 +#endif /*_IPT_FUZZY_H*/
36 diff -Nur --exclude '*.orig' linux.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h linux/include/linux/netfilter_ipv6/ip6t_fuzzy.h
37 --- linux.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h 1970-01-01 01:00:00.000000000 +0100
38 +++ linux/include/linux/netfilter_ipv6/ip6t_fuzzy.h     2006-05-04 10:09:04.000000000 +0200
39 @@ -0,0 +1,21 @@
40 +#ifndef _IP6T_FUZZY_H
41 +#define _IP6T_FUZZY_H
42 +
43 +#include <linux/param.h>
44 +#include <linux/types.h>
45 +
46 +#define MAXFUZZYRATE 10000000
47 +#define MINFUZZYRATE 3
48 +
49 +struct ip6t_fuzzy_info {
50 +       u_int32_t minimum_rate;
51 +       u_int32_t maximum_rate;
52 +       u_int32_t packets_total;
53 +       u_int32_t bytes_total;
54 +       u_int32_t previous_time;
55 +       u_int32_t present_time;
56 +       u_int32_t mean_rate;
57 +       u_int8_t acceptance_rate;
58 +};
59 +
60 +#endif /*_IP6T_FUZZY_H*/
61 diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/Kconfig linux/net/ipv4/netfilter/Kconfig
62 --- linux.org/net/ipv4/netfilter/Kconfig        2006-05-02 23:38:44.000000000 +0200
63 +++ linux/net/ipv4/netfilter/Kconfig    2006-05-04 10:09:04.000000000 +0200
64 @@ -606,5 +606,15 @@
65           Allows altering the ARP packet payload: source and destination
66           hardware and network addresses.
67  
68 +config IP_NF_MATCH_FUZZY
69 +       tristate  'fuzzy match support'
70 +       depends on IP_NF_IPTABLES
71 +       help
72 +         This option adds a `fuzzy' match, which allows you to match
73 +         packets according to a fuzzy logic based law.
74 +       
75 +         If you want to compile it as a module, say M here and read
76 +         Documentation/modules.txt.  If unsure, say `N'.
77 +
78  endmenu
79  
80 diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/Makefile linux/net/ipv4/netfilter/Makefile
81 --- linux.org/net/ipv4/netfilter/Makefile       2006-05-02 23:38:44.000000000 +0200
82 +++ linux/net/ipv4/netfilter/Makefile   2006-05-04 10:09:04.000000000 +0200
83 @@ -0,0 +0,1 @@
84 +obj-$(CONFIG_IP_NF_MATCH_FUZZY) += ipt_fuzzy.o
85 diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/ipt_fuzzy.c linux/net/ipv4/netfilter/ipt_fuzzy.c
86 --- linux.org/net/ipv4/netfilter/ipt_fuzzy.c    1970-01-01 01:00:00.000000000 +0100
87 +++ linux/net/ipv4/netfilter/ipt_fuzzy.c        2006-05-04 10:09:04.000000000 +0200
88 @@ -0,0 +1,186 @@
89 +/*
90 + *  This module implements a simple TSK FLC 
91 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
92 + * to limit , in an adaptive and flexible way , the packet rate crossing 
93 + * a given stream . It serves as an initial and very simple (but effective)
94 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
95 + *  As a matter of fact , Fuzzy Logic can help us to insert any "behavior"  
96 + * into our code in a precise , adaptive and efficient manner. 
97 + *  The goal is very similar to that of "limit" match , but using techniques of
98 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
99 + * avoiding over and undershoots - and stuff like that .
100 + *
101 + *
102 + * 2002-08-10  Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
103 + * 2002-08-17  : Changed to eliminate floating point operations .
104 + * 2002-08-23  : Coding style changes .
105 +*/
106 +
107 +#include <linux/module.h>
108 +#include <linux/skbuff.h>
109 +#include <linux/ip.h>
110 +#include <linux/random.h>
111 +#include <net/tcp.h>
112 +#include <linux/spinlock.h>
113 +#include <linux/netfilter_ipv4/ip_tables.h>
114 +#include <linux/netfilter_ipv4/ipt_fuzzy.h>
115 +
116 +/*
117 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
118 + Expressed in percentage
119 +*/
120 +
121 +#define PAR_LOW                1/100
122 +#define PAR_HIGH       1
123 +
124 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED ;
125 +
126 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
127 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
128 +MODULE_LICENSE("GPL");
129 +
130 +static  u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
131 +{
132 +       if (tx >= maxi)
133 +               return 100;
134 +
135 +       if (tx <= mini)
136 +               return 0;
137 +
138 +       return ( (100*(tx-mini)) / (maxi-mini) );
139 +}
140 +
141 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
142 +{
143 +       if (tx <= mini)
144 +               return 100;
145 +
146 +       if (tx >= maxi)
147 +               return 0;
148 +
149 +       return ( (100*( maxi - tx ))  / ( maxi - mini ) );
150 +}
151 +
152 +static int
153 +ipt_fuzzy_match(const struct sk_buff *pskb,
154 +              const struct net_device *in,
155 +              const struct net_device *out,
156 +              const void *matchinfo,
157 +              int offset,
158 +              unsigned int protoff,
159 +              int *hotdrop)
160 +{
161 +       /* From userspace */
162 +       
163 +       struct ipt_fuzzy_info *info = (struct ipt_fuzzy_info *) matchinfo;
164 +
165 +       u_int8_t random_number;
166 +       unsigned long amount;
167 +       u_int8_t howhigh, howlow;
168 +       
169 +
170 +       spin_lock_bh(&fuzzy_lock); /* Rise the lock */
171 +
172 +       info->bytes_total += pskb->len;
173 +       info->packets_total++;
174 +
175 +       info->present_time = jiffies;
176 +       
177 +       if (info->present_time >= info->previous_time)
178 +               amount = info->present_time - info->previous_time;
179 +       else { 
180 +               /* There was a transition : I choose to re-sample 
181 +                  and keep the old acceptance rate...
182 +               */
183 +
184 +               amount = 0;
185 +               info->previous_time = info->present_time;
186 +               info->bytes_total = info->packets_total = 0;
187 +       };
188 +       
189 +       if (amount > HZ/10) /* More than 100 ms elapsed ... */
190 +       {
191 +
192 +               info->mean_rate = (u_int32_t) ((HZ*info->packets_total)  \
193 +                                       / amount );
194 +
195 +               info->previous_time = info->present_time;
196 +               info->bytes_total = info->packets_total = 0;
197 +
198 +               howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
199 +               howlow  = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
200 +
201 +               info->acceptance_rate = (u_int8_t) \
202 +                          (howhigh*PAR_LOW + PAR_HIGH*howlow);
203 +
204 +               /* In fact , the above defuzzification would require a denominator
205 +                  proportional to (howhigh+howlow) but , in this particular case ,
206 +                  that expression is constant .
207 +                  An imediate consequence is that it isn't necessary to call 
208 +                  both mf_high and mf_low - but to keep things understandable ,
209 +                  I did so .  */ 
210 +
211 +       }
212 +       
213 +       spin_unlock_bh(&fuzzy_lock); /* Release the lock */
214 +
215 +
216 +       if ( info->acceptance_rate < 100 )
217 +       {                
218 +               get_random_bytes((void *)(&random_number), 1);
219 +
220 +               /*  If within the acceptance , it can pass => don't match */
221 +               if (random_number <= (255 * info->acceptance_rate) / 100)
222 +                       return 0;
223 +               else
224 +                       return 1; /* It can't pass ( It matches ) */
225 +       } ;
226 +
227 +       return 0; /* acceptance_rate == 100 % => Everything passes ... */
228 +       
229 +}
230 +
231 +static int
232 +ipt_fuzzy_checkentry(const char *tablename,
233 +                  const struct ipt_ip *e,
234 +                  void *matchinfo,
235 +                  unsigned int matchsize,
236 +                  unsigned int hook_mask)
237 +{
238 +       
239 +       const struct ipt_fuzzy_info *info = matchinfo;
240 +
241 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_fuzzy_info))) {
242 +               printk("ipt_fuzzy: matchsize %u != %zu\n", matchsize,
243 +                      IPT_ALIGN(sizeof(struct ipt_fuzzy_info)));
244 +               return 0;
245 +       }
246 +
247 +       if ((info->minimum_rate < MINFUZZYRATE ) || (info->maximum_rate > MAXFUZZYRATE)
248 +           || (info->minimum_rate >= info->maximum_rate )) {
249 +               printk("ipt_fuzzy: BAD limits , please verify !!!\n");
250 +               return 0;
251 +       }
252 +
253 +       return 1;
254 +}
255 +
256 +static struct ipt_match ipt_fuzzy_reg = { 
257 +       .name = "fuzzy",
258 +       .match = ipt_fuzzy_match,
259 +       .checkentry = ipt_fuzzy_checkentry,
260 +       .me = THIS_MODULE
261 +};
262 +
263 +static int __init init(void)
264 +{
265 +       return ipt_register_match(&ipt_fuzzy_reg);
266 +}
267 +
268 +static void __exit fini(void)
269 +{
270 +       ipt_unregister_match(&ipt_fuzzy_reg);
271 +}
272 +
273 +module_init(init);
274 +module_exit(fini);
275 diff -Nur --exclude '*.orig' linux.org/net/ipv6/netfilter/Kconfig linux/net/ipv6/netfilter/Kconfig
276 --- linux.org/net/ipv6/netfilter/Kconfig        2006-05-02 23:38:44.000000000 +0200
277 +++ linux/net/ipv6/netfilter/Kconfig    2006-05-04 10:09:04.000000000 +0200
278 @@ -210,5 +210,15 @@
279           If you want to compile it as a module, say M here and read
280           <file:Documentation/modules.txt>.  If unsure, say `N'.
281  
282 +config IP6_NF_MATCH_FUZZY
283 +       tristate  'Fuzzy match support'
284 +       depends on IP6_NF_FILTER
285 +       help
286 +         This option adds a `fuzzy' match, which allows you to match
287 +         packets according to a fuzzy logic based law.
288 +       
289 +         If you want to compile it as a module, say M here and read
290 +         Documentation/modules.txt.  If unsure, say `N'.
291 +
292  endmenu
293  
294 diff -Nur --exclude '*.orig' linux.org/net/ipv6/netfilter/Makefile linux/net/ipv6/netfilter/Makefile
295 --- linux.org/net/ipv6/netfilter/Makefile       2006-05-02 23:38:44.000000000 +0200
296 +++ linux/net/ipv6/netfilter/Makefile   2006-05-04 10:09:04.000000000 +0200
297 @@ -0,0 +0,1 @@
298 +obj-$(CONFIG_IP6_NF_MATCH_FUZZY) += ip6t_fuzzy.o
299 diff -Nur --exclude '*.orig' linux.org/net/ipv6/netfilter/ip6t_fuzzy.c linux/net/ipv6/netfilter/ip6t_fuzzy.c
300 --- linux.org/net/ipv6/netfilter/ip6t_fuzzy.c   1970-01-01 01:00:00.000000000 +0100
301 +++ linux/net/ipv6/netfilter/ip6t_fuzzy.c       2006-05-04 10:09:04.000000000 +0200
302 @@ -0,0 +1,186 @@
303 +/*
304 + * This module implements a simple TSK FLC
305 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
306 + * to limit , in an adaptive and flexible way , the packet rate crossing
307 + * a given stream . It serves as an initial and very simple (but effective)
308 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
309 + *  As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
310 + * into our code in a precise , adaptive and efficient manner.
311 + *  The goal is very similar to that of "limit" match , but using techniques of
312 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
313 + * avoiding over and undershoots - and stuff like that .
314 + *
315 + *
316 + * 2002-08-10  Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
317 + * 2002-08-17  : Changed to eliminate floating point operations .
318 + * 2002-08-23  : Coding style changes .
319 + * 2003-04-08  Maciej Soltysiak <solt@dns.toxicilms.tv> : IPv6 Port
320 + */
321 +
322 +#include <linux/module.h>
323 +#include <linux/skbuff.h>
324 +#include <linux/ipv6.h>
325 +#include <linux/random.h>
326 +#include <net/tcp.h>
327 +#include <linux/spinlock.h>
328 +#include <linux/netfilter_ipv6/ip6_tables.h>
329 +#include <linux/netfilter_ipv6/ip6t_fuzzy.h>
330 +
331 +/*
332 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
333 + Expressed in percentage
334 +*/
335 +
336 +#define PAR_LOW                1/100
337 +#define PAR_HIGH       1
338 +
339 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED;
340 +
341 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
342 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
343 +MODULE_LICENSE("GPL");
344 +
345 +static  u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
346 +{
347 +       if (tx >= maxi) return 100;
348 +
349 +       if (tx <= mini) return 0;
350 +
351 +       return ((100 * (tx-mini)) / (maxi-mini));
352 +}
353 +
354 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
355 +{
356 +       if (tx <= mini) return 100;
357 +
358 +       if (tx >= maxi) return 0;
359 +
360 +       return ((100 * (maxi - tx)) / (maxi - mini));
361 +
362 +}
363 +
364 +static int
365 +ip6t_fuzzy_match(const struct sk_buff *pskb,
366 +              const struct net_device *in,
367 +              const struct net_device *out,
368 +              const void *matchinfo,
369 +              int offset,
370 +              unsigned int protoff,
371 +              int *hotdrop)
372 +{
373 +       /* From userspace */
374 +
375 +       struct ip6t_fuzzy_info *info = (struct ip6t_fuzzy_info *) matchinfo;
376 +
377 +       u_int8_t random_number;
378 +       unsigned long amount;
379 +       u_int8_t howhigh, howlow;
380 +
381 +
382 +       spin_lock_bh(&fuzzy_lock); /* Rise the lock */
383 +
384 +       info->bytes_total += pskb->len;
385 +       info->packets_total++;
386 +
387 +       info->present_time = jiffies;
388 +
389 +       if (info->present_time >= info->previous_time)
390 +               amount = info->present_time - info->previous_time;
391 +       else {
392 +               /* There was a transition : I choose to re-sample
393 +                  and keep the old acceptance rate...
394 +               */
395 +
396 +               amount = 0;
397 +               info->previous_time = info->present_time;
398 +               info->bytes_total = info->packets_total = 0;
399 +            };
400 +
401 +       if ( amount > HZ/10) {/* More than 100 ms elapsed ... */
402 +
403 +               info->mean_rate = (u_int32_t) ((HZ * info->packets_total) \
404 +                                       / amount);
405 +
406 +               info->previous_time = info->present_time;
407 +               info->bytes_total = info->packets_total = 0;
408 +
409 +               howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
410 +               howlow  = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
411 +
412 +               info->acceptance_rate = (u_int8_t) \
413 +                               (howhigh * PAR_LOW + PAR_HIGH * howlow);
414 +
415 +       /* In fact, the above defuzzification would require a denominator
416 +        * proportional to (howhigh+howlow) but, in this particular case,
417 +        * that expression is constant.
418 +        * An imediate consequence is that it is not necessary to call
419 +        * both mf_high and mf_low - but to keep things understandable,
420 +        * I did so.
421 +        */
422 +
423 +       }
424 +
425 +       spin_unlock_bh(&fuzzy_lock); /* Release the lock */
426 +
427 +
428 +       if (info->acceptance_rate < 100)
429 +       {
430 +               get_random_bytes((void *)(&random_number), 1);
431 +
432 +               /*  If within the acceptance , it can pass => don't match */
433 +               if (random_number <= (255 * info->acceptance_rate) / 100)
434 +                       return 0;
435 +               else
436 +                       return 1; /* It can't pass (It matches) */
437 +       };
438 +
439 +       return 0; /* acceptance_rate == 100 % => Everything passes ... */
440 +
441 +}
442 +
443 +static int
444 +ip6t_fuzzy_checkentry(const char *tablename,
445 +                  const struct ip6t_ip6 *ip,
446 +                  void *matchinfo,
447 +                  unsigned int matchsize,
448 +                  unsigned int hook_mask)
449 +{
450 +
451 +       const struct ip6t_fuzzy_info *info = matchinfo;
452 +
453 +       if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info))) {
454 +               printk("ip6t_fuzzy: matchsize %u != %zu\n", matchsize,
455 +                      IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info)));
456 +               return 0;
457 +       }
458 +
459 +       if ((info->minimum_rate < MINFUZZYRATE) || (info->maximum_rate > MAXFUZZYRATE)
460 +        || (info->minimum_rate >= info->maximum_rate)) {
461 +               printk("ip6t_fuzzy: BAD limits , please verify !!!\n");
462 +               return 0;
463 +       }
464 +
465 +       return 1;
466 +}
467 +
468 +static struct ip6t_match ip6t_fuzzy_reg = {
469 +       .name           = "fuzzy",
470 +       .match          = ip6t_fuzzy_match,
471 +       .checkentry     = ip6t_fuzzy_checkentry,
472 +       .me             = THIS_MODULE };
473 +
474 +static int __init init(void)
475 +{
476 +       if (ip6t_register_match(&ip6t_fuzzy_reg))
477 +               return -EINVAL;
478 +
479 +       return 0;
480 +}
481 +
482 +static void __exit fini(void)
483 +{
484 +       ip6t_unregister_match(&ip6t_fuzzy_reg);
485 +}
486 +
487 +module_init(init);
488 +module_exit(fini);
This page took 0.054046 seconds and 3 git commands to generate.