1diff -uNr linux.orig/include/linux/netfilter_ipv4/ipt_fuzzy.h linux/include/linux/netfilter_ipv4/ipt_fuzzy.h
2--- linux.orig/include/linux/netfilter_ipv4/ipt_fuzzy.h	Wed Dec 31 21:00:00 1969
3+++ linux/include/linux/netfilter_ipv4/ipt_fuzzy.h	Fri Aug 23 20:47:16 2002
4@@ -0,0 +1,21 @@
5+#ifndef _IPT_FUZZY_H
6+#define _IPT_FUZZY_H
7+
8+#include <linux/param.h>
9+#include <linux/types.h>
10+
11+#define MAXFUZZYRATE 10000000
12+#define MINFUZZYRATE 3
13+
14+struct ipt_fuzzy_info {
15+	u_int32_t minimum_rate;
16+	u_int32_t maximum_rate;
17+	u_int32_t packets_total;
18+	u_int32_t bytes_total;
19+	u_int32_t previous_time;
20+	u_int32_t present_time;
21+	u_int32_t mean_rate;
22+	u_int8_t acceptance_rate;
23+};
24+
25+#endif /*_IPT_FUZZY_H*/
26diff -uNr linux.orig/net/ipv4/netfilter/ipt_fuzzy.c linux/net/ipv4/netfilter/ipt_fuzzy.c
27--- linux.orig/net/ipv4/netfilter/ipt_fuzzy.c	Wed Dec 31 21:00:00 1969
28+++ linux/net/ipv4/netfilter/ipt_fuzzy.c	Fri Aug 23 20:47:16 2002
29@@ -0,0 +1,190 @@
30+/*
31+ *  This module implements a simple TSK FLC 
32+ * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
33+ * to limit , in an adaptive and flexible way , the packet rate crossing 
34+ * a given stream . It serves as an initial and very simple (but effective)
35+ * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
36+ *  As a matter of fact , Fuzzy Logic can help us to insert any "behavior"  
37+ * into our code in a precise , adaptive and efficient manner. 
38+ *  The goal is very similar to that of "limit" match , but using techniques of
39+ * Fuzzy Control , that allow us to shape the transfer functions precisely ,
40+ * avoiding over and undershoots - and stuff like that .
41+ *
42+ *
43+ * 2002-08-10  Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
44+ * 2002-08-17  : Changed to eliminate floating point operations .
45+ * 2002-08-23  : Coding style changes .
46+*/
47+
48+#include <linux/module.h>
49+#include <linux/skbuff.h>
50+#include <linux/ip.h>
51+#include <linux/random.h>
52+#include <net/tcp.h>
53+#include <linux/spinlock.h>
54+#include <linux/netfilter_ipv4/ip_tables.h>
55+#include <linux/netfilter_ipv4/ipt_fuzzy.h>
56+
57+/*
58+ Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
59+ Expressed in percentage
60+*/
61+
62+#define PAR_LOW		0.01
63+#define PAR_HIGH	1
64+
65+static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED ;
66+
67+MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
68+MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
69+MODULE_LICENSE("GPL");
70+
71+static  u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
72+{
73+	if (tx >= maxi) return 100;
74+
75+	if (tx <= mini) return 0;
76+
77+	return ( (100*(tx-mini)) / (maxi-mini) ) ;
78+}
79+
80+static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
81+{
82+	if (tx <= mini) return 100;
83+
84+	if (tx >= maxi) return 0;
85+
86+	return ( (100*( maxi - tx ))  / ( maxi - mini ) ) ;
87+
88+}
89+
90+static int
91+ipt_fuzzy_match(const struct sk_buff *pskb,
92+	       const struct net_device *in,
93+	       const struct net_device *out,
94+	       const void *matchinfo,
95+	       int offset,
96+	       const void *hdr,
97+	       u_int16_t datalen,
98+	       int *hotdrop)
99+{
100+	/* From userspace */
101+	
102+	struct ipt_fuzzy_info *info = (struct ipt_fuzzy_info *) matchinfo;
103+
104+	u_int8_t random_number;
105+	unsigned long amount ;
106+	u_int8_t howhigh , howlow ;
107+	
108+
109+	spin_lock_bh(&fuzzy_lock) ; /* Rise the lock */
110+
111+	info->bytes_total += pskb->len ;
112+	info->packets_total++ ;
113+
114+	info->present_time = jiffies ;
115+	
116+	if ( info->present_time >= info->previous_time )
117+		amount = info->present_time - info->previous_time ;
118+	else { 
119+	       	/* There was a transition : I choose to re-sample 
120+		   and keep the old acceptance rate...
121+	        */
122+
123+		amount = 0 ;
124+		info->previous_time = info->present_time ;
125+		info->bytes_total = info->packets_total = 0;
126+	     };
127+	
128+	if (  amount > HZ/10 ) /* More than 100 ms elapsed ... */
129+		{
130+
131+	info->mean_rate = (u_int32_t) ( ( HZ * info->packets_total )  \
132+		  		        / amount ) ;
133+
134+		info->previous_time = info->present_time ;
135+		info->bytes_total = info->packets_total = 0 ;
136+
137+       howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
138+       howlow  = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
139+
140+    info->acceptance_rate = (u_int8_t) \
141+		           ( PAR_LOW*howhigh + PAR_HIGH*howlow ) ;
142+
143+    /* In fact , the above defuzzification would require a denominator
144+       proportional to (howhigh+howlow) but , in this particular case ,
145+       that expression is constant .
146+        An imediate consequence is that it isn't necessary to call 
147+       both mf_high and mf_low - but to keep things understandable ,
148+       I did so .
149+     */ 
150+
151+		}
152+	
153+	spin_unlock_bh(&fuzzy_lock) ; /* Release the lock */
154+
155+
156+	if ( info->acceptance_rate < 100 )
157+	{		 
158+		get_random_bytes((void *)(&random_number), 1);
159+
160+		/*  If within the acceptance , it can pass => don't match */
161+		if ( random_number <= 2.55 * info->acceptance_rate )
162+			return 0 ;
163+		else
164+			return 1; /* It can't pass ( It matches ) */
165+	} ;
166+
167+	return 0; /* acceptance_rate == 100 % => Everything passes ... */
168+	
169+}
170+
171+static int
172+ipt_fuzzy_checkentry(const char *tablename,
173+		   const struct ipt_ip *e,
174+		   void *matchinfo,
175+		   unsigned int matchsize,
176+		   unsigned int hook_mask)
177+{
178+	
179+	const struct ipt_fuzzy_info *info = matchinfo;
180+
181+	if (matchsize != IPT_ALIGN(sizeof(struct ipt_fuzzy_info))) {
182+		printk("ipt_fuzzy: matchsize %u != %u\n", matchsize,
183+		       IPT_ALIGN(sizeof(struct ipt_fuzzy_info)));
184+		return 0;
185+	}
186+
187+if ((info->minimum_rate < MINFUZZYRATE ) || (info->maximum_rate > MAXFUZZYRATE)
188+	|| (info->minimum_rate >= info->maximum_rate ))
189+		{
190+		printk("ipt_fuzzy: BAD limits , please verify !!!\n");
191+		return 0;
192+		}
193+
194+	return 1;
195+}
196+
197+static struct ipt_match ipt_fuzzy_reg = { 
198+	{NULL, NULL},
199+	"fuzzy",
200+	ipt_fuzzy_match,
201+	ipt_fuzzy_checkentry,
202+	NULL,
203+	THIS_MODULE };
204+
205+static int __init init(void)
206+{
207+	if (ipt_register_match(&ipt_fuzzy_reg))
208+		return -EINVAL;
209+
210+	return 0;
211+}
212+
213+static void __exit fini(void)
214+{
215+	ipt_unregister_match(&ipt_fuzzy_reg);
216+}
217+
218+module_init(init);
219+module_exit(fini);
220