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(+)
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
18 +#include <linux/param.h>
19 +#include <linux/types.h>
21 +#define MAXFUZZYRATE 10000000
22 +#define MINFUZZYRATE 3
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;
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
40 +#ifndef _IP6T_FUZZY_H
41 +#define _IP6T_FUZZY_H
43 +#include <linux/param.h>
44 +#include <linux/types.h>
46 +#define MAXFUZZYRATE 10000000
47 +#define MINFUZZYRATE 3
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;
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
65 Allows altering the ARP packet payload: source and destination
66 hardware and network addresses.
68 +config IP_NF_MATCH_FUZZY
69 + tristate 'fuzzy match support'
70 + depends on IP_NF_IPTABLES
72 + This option adds a `fuzzy' match, which allows you to match
73 + packets according to a fuzzy logic based law.
75 + If you want to compile it as a module, say M here and read
76 + Documentation/modules.txt. If unsure, say `N'.
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
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
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 .
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 .
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>
117 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
118 + Expressed in percentage
121 +#define PAR_LOW 1/100
124 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED ;
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");
130 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
138 + return ( (100*(tx-mini)) / (maxi-mini) );
141 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
149 + return ( (100*( maxi - tx )) / ( maxi - mini ) );
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,
158 + unsigned int protoff,
161 + /* From userspace */
163 + struct ipt_fuzzy_info *info = (struct ipt_fuzzy_info *) matchinfo;
165 + u_int8_t random_number;
166 + unsigned long amount;
167 + u_int8_t howhigh, howlow;
170 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
172 + info->bytes_total += pskb->len;
173 + info->packets_total++;
175 + info->present_time = jiffies;
177 + if (info->present_time >= info->previous_time)
178 + amount = info->present_time - info->previous_time;
180 + /* There was a transition : I choose to re-sample
181 + and keep the old acceptance rate...
185 + info->previous_time = info->present_time;
186 + info->bytes_total = info->packets_total = 0;
189 + if (amount > HZ/10) /* More than 100 ms elapsed ... */
192 + info->mean_rate = (u_int32_t) ((HZ*info->packets_total) \
195 + info->previous_time = info->present_time;
196 + info->bytes_total = info->packets_total = 0;
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);
201 + info->acceptance_rate = (u_int8_t) \
202 + (howhigh*PAR_LOW + PAR_HIGH*howlow);
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 ,
213 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
216 + if ( info->acceptance_rate < 100 )
218 + get_random_bytes((void *)(&random_number), 1);
220 + /* If within the acceptance , it can pass => don't match */
221 + if (random_number <= (255 * info->acceptance_rate) / 100)
224 + return 1; /* It can't pass ( It matches ) */
227 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
232 +ipt_fuzzy_checkentry(const char *tablename,
233 + const struct ipt_ip *e,
235 + unsigned int matchsize,
236 + unsigned int hook_mask)
239 + const struct ipt_fuzzy_info *info = matchinfo;
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)));
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");
256 +static struct ipt_match ipt_fuzzy_reg = {
258 + .match = ipt_fuzzy_match,
259 + .checkentry = ipt_fuzzy_checkentry,
263 +static int __init init(void)
265 + return ipt_register_match(&ipt_fuzzy_reg);
268 +static void __exit fini(void)
270 + ipt_unregister_match(&ipt_fuzzy_reg);
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
279 If you want to compile it as a module, say M here and read
280 <file:Documentation/modules.txt>. If unsure, say `N'.
282 +config IP6_NF_MATCH_FUZZY
283 + tristate 'Fuzzy match support'
284 + depends on IP6_NF_FILTER
286 + This option adds a `fuzzy' match, which allows you to match
287 + packets according to a fuzzy logic based law.
289 + If you want to compile it as a module, say M here and read
290 + Documentation/modules.txt. If unsure, say `N'.
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
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
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 .
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
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>
332 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
333 + Expressed in percentage
336 +#define PAR_LOW 1/100
339 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED;
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");
345 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
347 + if (tx >= maxi) return 100;
349 + if (tx <= mini) return 0;
351 + return ((100 * (tx-mini)) / (maxi-mini));
354 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
356 + if (tx <= mini) return 100;
358 + if (tx >= maxi) return 0;
360 + return ((100 * (maxi - tx)) / (maxi - mini));
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,
370 + unsigned int protoff,
373 + /* From userspace */
375 + struct ip6t_fuzzy_info *info = (struct ip6t_fuzzy_info *) matchinfo;
377 + u_int8_t random_number;
378 + unsigned long amount;
379 + u_int8_t howhigh, howlow;
382 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
384 + info->bytes_total += pskb->len;
385 + info->packets_total++;
387 + info->present_time = jiffies;
389 + if (info->present_time >= info->previous_time)
390 + amount = info->present_time - info->previous_time;
392 + /* There was a transition : I choose to re-sample
393 + and keep the old acceptance rate...
397 + info->previous_time = info->present_time;
398 + info->bytes_total = info->packets_total = 0;
401 + if ( amount > HZ/10) {/* More than 100 ms elapsed ... */
403 + info->mean_rate = (u_int32_t) ((HZ * info->packets_total) \
406 + info->previous_time = info->present_time;
407 + info->bytes_total = info->packets_total = 0;
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);
412 + info->acceptance_rate = (u_int8_t) \
413 + (howhigh * PAR_LOW + PAR_HIGH * howlow);
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,
425 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
428 + if (info->acceptance_rate < 100)
430 + get_random_bytes((void *)(&random_number), 1);
432 + /* If within the acceptance , it can pass => don't match */
433 + if (random_number <= (255 * info->acceptance_rate) / 100)
436 + return 1; /* It can't pass (It matches) */
439 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
444 +ip6t_fuzzy_checkentry(const char *tablename,
445 + const struct ip6t_ip6 *ip,
447 + unsigned int matchsize,
448 + unsigned int hook_mask)
451 + const struct ip6t_fuzzy_info *info = matchinfo;
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)));
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");
468 +static struct ip6t_match ip6t_fuzzy_reg = {
470 + .match = ip6t_fuzzy_match,
471 + .checkentry = ip6t_fuzzy_checkentry,
472 + .me = THIS_MODULE };
474 +static int __init init(void)
476 + if (ip6t_register_match(&ip6t_fuzzy_reg))
482 +static void __exit fini(void)
484 + ip6t_unregister_match(&ip6t_fuzzy_reg);