]> git.pld-linux.org Git - packages/kernel.git/blob - 2.6.4-rc1-04-ipp2p.patch
- update for cset 20040707_...
[packages/kernel.git] / 2.6.4-rc1-04-ipp2p.patch
1 diff -uNr linux-2.6.4-rc1/include/linux.orig/netfilter_ipv4/ipt_ipp2p.h linux-2.6.4-rc1/include/linux/netfilter_ipv4/ipt_ipp2p.h
2 --- linux-2.6.4-rc1/include/linux.orig/netfilter_ipv4/ipt_ipp2p.h       1970-01-01 01:00:00.000000000 +0100
3 +++ linux-2.6.4-rc1/include/linux/netfilter_ipv4/ipt_ipp2p.h    2004-03-03 04:06:59.299251608 +0100
4 @@ -0,0 +1,9 @@
5 +#ifndef __IPT_IPP2P_H
6 +#define __IPT_IPP2P_H
7 +#define IPP2P_VERSION "0.5a"
8 +
9 +struct ipt_p2p_info {
10 +    int cmd;    
11 +};
12 +
13 +#endif //__IPT_IPP2P_H
14 diff -uNr linux-2.6.4-rc1/net/ipv4.orig/netfilter/ipt_ipp2p.c linux-2.6.4-rc1/net/ipv4/netfilter/ipt_ipp2p.c
15 --- linux-2.6.4-rc1/net/ipv4.orig/netfilter/ipt_ipp2p.c 1970-01-01 01:00:00.000000000 +0100
16 +++ linux-2.6.4-rc1/net/ipv4/netfilter/ipt_ipp2p.c      2004-03-03 04:06:59.311249784 +0100
17 @@ -0,0 +1,507 @@
18 +#include <linux/kernel.h>
19 +#include <linux/module.h>
20 +#include <linux/skbuff.h>
21 +#include <linux/netfilter_ipv4.h>
22 +#include <linux/netfilter_ipv4/ip_tables.h>
23 +#include <linux/ip.h>
24 +#include <asm/uaccess.h>
25 +#include <linux/spinlock.h>
26 +
27 +#include <linux/netfilter_ipv4/ipt_ipp2p.h>
28 +
29 +#define get_u16(X,O)  (*(__u16 *)(X + O))
30 +
31 +MODULE_AUTHOR("Eicke Friedrich");
32 +MODULE_DESCRIPTION("An extension to iptables to identify P2P traffic.");
33 +MODULE_LICENSE("GPL");
34 +
35 +/*Search for appleJuice commands*/
36 +int
37 +search_apple (unsigned char *haystack, int packet_len, int head_len)
38 +{
39 +    unsigned char *t = haystack;
40 +    t += head_len;
41 +    
42 +    if ((memcmp(t, "ajprot", 6) == 0) && (t[6] == 0x0d) && (t[7] == 0x0a))  return 1;            
43 +    
44 +    return 0;
45 +}
46 +
47 +
48 +/*Search for BitTorrent commands*/
49 +int
50 +search_bittorrent (unsigned char *haystack, int head_len)
51 +{
52 +
53 +    unsigned char *t = haystack;
54 +    if (*(haystack+head_len) != 0x13) return 0; //Bail out of first byte != 0x13
55 +    
56 +    t += head_len + 1;
57 +    
58 +    if (memcmp(t, "BitTorrent protocol", 19) == 0) return 1;        
59 +
60 +    return 0;
61 +}
62 +
63 +
64 +
65 +/*check for Kazaa get command*/
66 +int
67 +search_kazaa (unsigned char *haystack, int packet_len, int head_len)
68 +{
69 +    unsigned char *t = haystack;
70 +
71 +    if (!((*(haystack + packet_len - 2) == 0x0d) && (*(haystack + packet_len - 1) == 0x0a))) return 0;    
72 +
73 +    t += head_len;
74 +    if (memcmp(t, "GET /.hash=", 11) == 0)
75 +       return 1;
76 +    else
77 +       return 0;
78 +}
79 +
80 +
81 +/*check for gnutella get command*/
82 +int
83 +search_gnu (unsigned char *haystack, int packet_len, int head_len)
84 +{
85 +    unsigned char *t = haystack;
86 +
87 +    if (!((*(haystack + packet_len - 2) == 0x0d) && (*(haystack + packet_len - 1) == 0x0a))) return 0;    
88 +
89 +    t += head_len;
90 +    if (memcmp(t, "GET /get/", 9) == 0)        return 1;
91 +    if (memcmp(t, "GET /uri-res/", 13) == 0) return 1; 
92 +    
93 +    return 0;
94 +}
95 +
96 +
97 +/*check for gnutella get commands and other typical data*/
98 +int
99 +search_all_gnu (unsigned char *haystack, int packet_len, int head_len)
100 +{
101 +    unsigned char *t = haystack;
102 +    int c;    
103 +
104 +    if (!((*(haystack + packet_len - 2) == 0x0d) && (*(haystack + packet_len - 1) == 0x0a))) return 0;
105 +
106 +    t += head_len;
107 +
108 +    if (memcmp(t, "GNUTELLA CONNECT/", 17) == 0) return 1;        
109 +    if (memcmp(t, "GNUTELLA/", 9) == 0) return 1;    
110 +
111 +    if ((memcmp(t, "GET /get/", 9) == 0) || (memcmp(t, "GET /uri-res/", 13) == 0))
112 +    {        
113 +        c = head_len + 8;
114 +       t += 8;
115 +       while (c < packet_len - 22)
116 +       {
117 +           if (t[0] == 0x0d)
118 +           {
119 +               t++;
120 +               c++;
121 +               if (t[0] == 0x0a)
122 +               {
123 +                   t++;
124 +                   c++;
125 +                   if ( memcmp(t, "X-Gnutella-", 11) == 0 ) return 1;
126 +               }
127 +           }
128 +           else
129 +           {
130 +               t++;
131 +               c++;
132 +           }    
133 +       }
134 +    }
135 +    
136 +    return 0;
137 +}
138 +
139 +
140 +/*check for KaZaA download commands and other typical data*/
141 +int
142 +search_all_kazaa (unsigned char *haystack, int packet_len, int head_len)
143 +{
144 +    unsigned char *t = haystack;
145 +    int c;    
146 +
147 +    if (!((*(haystack + packet_len - 2) == 0x0d) && (*(haystack + packet_len - 1) == 0x0a))) return 0;
148 +
149 +    t += head_len;
150 +    if (memcmp(t, "GIVE ", 5) == 0) return 1;    
151 +    
152 +    if (memcmp(t, "GET /.hash=", 11) == 0)
153 +    {
154 +        c = head_len + 8;
155 +       t += 8;
156 +       while (c < packet_len - 22)
157 +       {
158 +           if (t[0] == 0x0d)
159 +           {
160 +               t++;
161 +               c++;
162 +               if (t[0] == 0x0a)
163 +               {
164 +                   t++;
165 +                   c++;
166 +                   if ( memcmp(t, "UserAgent:", 10) == 0 ) return 1;
167 +               }
168 +           }
169 +           else
170 +           {
171 +               t++;
172 +               c++;
173 +           }    
174 +       }
175 +    }
176 +    
177 +    return 0;
178 +}
179 +
180 +/*fast check for edonkey file segment transfer command*/
181 +int
182 +search_edk (unsigned char *haystack, int head_len)
183 +{
184 +    if (*(haystack+head_len) != 0xe3) 
185 +       return 0;
186 +    else
187 +    {
188 +       if (*(haystack+head_len+5) == 0x47) 
189 +           return 1;
190 +       else    
191 +           return 0;
192 +    }
193 +}
194 +
195 +
196 +
197 +/*intensive but slow search for some edonkey packets incl. size-check*/
198 +int
199 +search_all_edk (unsigned char *haystack, int packet_len, int head_len)
200 +{
201 +    unsigned char *t = haystack;
202 +    int cmd;
203 +    
204 +//Comment the next lines to turn OFF debug information    
205 +//debug starts here
206 +    if (*(haystack+head_len) == 0xc5) //search for additional eMule packets
207 +    {
208 +       t += head_len;  
209 +       cmd = get_u16(t, 1);    
210 +
211 +       if (cmd == (packet_len - head_len - 5))
212 +       {
213 +           if (t[5] == 0x01) return 1; 
214 +           if (t[5] == 0x02) return 1;                     
215 +           if (t[5] == 0x60) return 1;
216 +           if (t[5] == 0x81) return 1;
217 +           if (t[5] == 0x82) return 1;     
218 +           if (t[5] == 0x85) return 1;     
219 +           if (t[5] == 0x86) return 1;
220 +           if (t[5] == 0x87) return 1;
221 +           if (t[5] == 0x40) return 1;
222 +//         printk("IPP2P.search_all_edk: new eMule match: %x %x %x %x %x %x (size %i ok)\n", t[0], t[1], t[2], t[3], t[4], t[5], packet_len);
223 +           return 0;
224 +       }
225 +       
226 +/*     if (cmd > packet_len - head_len - 5)
227 +       {
228 +           if (t[cmd+5] == 0xe3)
229 +           {
230 +               printk("IPP2P.search_all_edk: new eMule match with second eDonkey match: %x %x %x %x %x %x (packet: %i)\n", t[0], t[1], t[2], t[3], t[4], t[5], packet_len);
231 +               return 0;
232 +           }
233 +           if (t[cmd+5] == 0xc5)
234 +           {
235 +               printk("IPP2P.search_all_edk: new eMule match with second eDonkey match: %x %x %x %x %x %x (packet: %i)\n", t[0], t[1], t[2], t[3], t[4], t[5], packet_len);
236 +               return 0;
237 +           }
238 +       }*/
239 +       return 0;
240 +    }
241 +//debug ends here    
242 +
243 +
244 +    if (*(haystack+head_len) != 0xe3) 
245 +       return 0;
246 +    else
247 +    {
248 +       t += head_len;  
249 +       cmd = get_u16(t, 1);    
250 +       if (cmd == (packet_len - head_len - 5)) 
251 +       {
252 +           t += 5;
253 +           if (t[0] == 0x01) return 1; //Client: hello or Server:hello
254 +           if (t[0] == 0x50) return 1; //Client: file status
255 +           if (t[0] == 0x16) return 1; //Client: search
256 +           if (t[0] == 0x58) return 1; //Client: file request
257 +           if (t[0] == 0x48) return 1; //???
258 +           if (t[0] == 0x54) return 1; //???               
259 +           if (t[0] == 0x47) return 1; //Client: file segment request
260 +           if (t[0] == 0x46) return 1; //Client: download segment          
261 +           if (t[0] == 0x4c) return 1; //Client: Hello-Answer
262 +           if (t[0] == 0x4f) return 1; //Client: file status request
263 +           if (t[0] == 0x59) return 1; //Client: file request answer
264 +           if (t[0] == 0x65) return 1; //Client: ???
265 +           if (t[0] == 0x66) return 1; //Client: ???       
266 +           if (t[0] == 0x51) return 1; //Client: ???               
267 +           if (t[0] == 0x52) return 1; //Client: ???                   
268 +           if (t[0] == 0x4d) return 1; //Client: ???       
269 +           if (t[0] == 0x5c) return 1; //Client: ???       
270 +           if (t[0] == 0x38) return 1; //Client: ???       
271 +           if (t[0] == 0x69) return 1; //Client: ???               
272 +           if (t[0] == 0x19) return 1; //Client: ???               
273 +           if (t[0] == 0x42) return 1; //Client: ???       
274 +           if (t[0] == 0x34) return 1; //Client: ???
275 +           if (t[0] == 0x94) return 1; //Client: ???       
276 +//Comment the next line to turn OFF debug information                              
277 +//         printk("IPP2P.search_all_edk: size (%i) ok, no match (%x)\n", packet_len, t[0]);
278 +           return 0;   
279 +       }
280 +       else
281 +       {
282 +           if (cmd > packet_len - head_len - 5) 
283 +           {
284 +               if ((t[3] == 0x00) && (t[4] == 0x00))
285 +               {
286 +                   if (t[5] == 0x01) return 1;
287 +                   if (t[5] == 0x4c) return 1;
288 +               } 
289 +               return 0;
290 +               
291 +           }   //non edk packet
292 +           if (t[cmd+5] == 0xe3) return 1;             //found another edk-command
293 +           if (t[cmd+5] == 0xc5) return 1;             //found an emule-command            
294 +//Comment the next line to turn OFF debug information
295 +//         printk("IPP2P.search_all_edk: size (%i vs %i) WRONG, no second match: %x %x %x %x %x %x  - %x %x %x %x %x %x\n", packet_len, cmd, t[0],
296 +//         t[1], t[2], t[3], t[4], t[5], t[cmd+5], t[cmd+6], t[cmd+7], t[cmd+8], t[cmd+9], t[cmd+10]);
297 +           return 0;
298 +       }
299 +    }
300 +}
301 +
302 +
303 +/*fast check for Direct Connect send command*/
304 +int
305 +search_dc (unsigned char *haystack, int packet_len, int head_len)
306 +{
307 +    unsigned char *t = haystack;
308 +
309 +    if (*(haystack+head_len) != 0x24 ) 
310 +       return 0;
311 +    else
312 +    {
313 +       t += head_len + 1;
314 +        if (memcmp(t, "Send|", 5) == 0)
315 +           return 1;
316 +       else
317 +           return 0;
318 +    }  
319 +
320 +}
321 +
322 +
323 +/*intensive but slower check for all direct connect packets*/
324 +int
325 +search_all_dc (unsigned char *haystack, int packet_len, int head_len)
326 +{
327 +    unsigned char *t = haystack;
328 +
329 +    if ((*(haystack + head_len) == 0x24) && (*(haystack + packet_len - 1) == 0x7c)) 
330 +    {
331 +       t += head_len + 1;
332 +       if (memcmp(t, "Lock ", 5) == 0)  return 1;      //hub: hello
333 +       if (memcmp(t, "Key ", 4) == 0)   return 1;      //client: hello
334 +       if (memcmp(t, "Hello ", 6) == 0) return 1;      //hub:connected
335 +       if (memcmp(t, "MyNick ", 7) == 0) return 1;     //client-client: hello
336 +       if (memcmp(t, "Search ", 7) == 0) return 1;     //client: search
337 +       if (memcmp(t, "Send", 4) == 0)   return 1;      //client: start download
338 +//Comment the next line to turn OFF debug information  
339 +//     printk("IPP2P.search_all_dc:$ %x%x%x%x%x%x%x%x%x%x |\n",t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9]);
340 +       return 0;
341 +    }
342 +    else
343 +       return 0;
344 +       
345 +
346 +}
347 +
348 +
349 +
350 +static int
351 +match(const struct sk_buff *skb,
352 +      const struct net_device *in,
353 +      const struct net_device *out,
354 +      const void *matchinfo,
355 +      int offset,
356 +      int *hotdrop)
357 +{
358 +    const struct ipt_p2p_info *info = matchinfo;
359 +    unsigned char  *haystack;
360 +    struct iphdr *ip = skb->nh.iph;
361 +    int p2p_result = 0;
362 +    int head_len;
363 +
364 +    int hlen = ntohs(ip->tot_len)-(ip->ihl*4); //hlen = packet-data length    
365 +    haystack=(char *)ip+(ip->ihl*4);           //haystack = packet data    
366 +
367 +
368 +    if (((*(haystack+13)) & 1) == 1) return 0;  //if FIN bit is set bail out
369 +    if (((*(haystack+13)) & 2) == 2) return 0;  //if SYN bit is set bail out
370 +    if (((*(haystack+13)) & 4) == 4) return 0;  //if RST bit is set bail out
371 +           
372 +
373 +    head_len = (*(haystack+12))/4; //get TCP-Header-Size
374 +
375 +    
376 +    if (((info->cmd & 8) == 8) || ((info->cmd & 4) == 4))      //cmd: kazaa-data || ipp2p-data
377 +    {
378 +       if (hlen > 200)
379 +       {
380 +           p2p_result = search_kazaa(haystack, hlen, head_len);
381 +           if (p2p_result == 1) return p2p_result;
382 +       }
383 +       
384 +    }
385 +       
386 +
387 +    if (((info->cmd & 2) == 2) || ((info->cmd & 1) == 1))      //cmd: edk || ipp2p
388 +    {
389 +       if (hlen > 40)
390 +       {       
391 +           p2p_result = search_all_edk(haystack, hlen, head_len);
392 +           if (p2p_result == 1) return p2p_result;         
393 +       }
394 +    }
395 +    
396 +    
397 +           
398 +
399 +    if (((info->cmd & 16) == 16) || ((info->cmd & 4) == 4))    //cmd: edk-data || ipp2p-data
400 +    {
401 +       if (hlen > 60)
402 +       {       
403 +           p2p_result = search_edk(haystack, head_len);
404 +           if (p2p_result == 1) return p2p_result;             
405 +       }
406 +    }
407 +
408 +    if (((info->cmd & 32) == 32) || ((info->cmd & 4) == 4))    //cmd: dc-data || ipp2p-data
409 +    {
410 +       if (hlen == 26)
411 +       {
412 +           p2p_result = search_dc(haystack, hlen, head_len);
413 +           if (p2p_result == 1) return p2p_result;         
414 +       }    
415 +    }
416 +
417 +    if (((info->cmd & 64) == 64) || ((info->cmd & 1) == 1))    //cmd: dc || ipp2p
418 +    {
419 +       if (hlen > 25)
420 +       {
421 +           p2p_result = search_all_dc(haystack, hlen, head_len);
422 +           if (p2p_result == 1) return p2p_result;         
423 +       }    
424 +    }
425 +    
426 +    if (((info->cmd & 128) == 128) || ((info->cmd & 4) == 4))  //cmd: gnu-data || ipp2p-data
427 +    {
428 +       if (hlen > 40)
429 +       {
430 +           p2p_result = search_gnu(haystack, hlen, head_len);
431 +           if (p2p_result == 1) return p2p_result;         
432 +       }    
433 +    }
434 +    
435 +    if (((info->cmd & 256) == 256) || ((info->cmd & 1) == 1))  //cmd: gnu || ipp2p
436 +    {
437 +       if (hlen > 35)
438 +       {
439 +           p2p_result = search_all_gnu(haystack, hlen, head_len);
440 +           if (p2p_result == 1) return p2p_result;         
441 +       }    
442 +    }
443 +
444 +
445 +    if (((info->cmd & 1) == 1) || ((info->cmd & 512) == 512))  //cmd:  ipp2p || kazaa
446 +    {
447 +       if (hlen > 35)
448 +       {
449 +           p2p_result = search_all_kazaa(haystack, hlen, head_len);
450 +           if (p2p_result == 1) return p2p_result;         
451 +       }    
452 +    }
453 +
454 +
455 +
456 +    if ((info->cmd & 1024) == 1024)                            //cmd:  bit
457 +    {
458 +       if (hlen > 40)
459 +       {
460 +           p2p_result = search_bittorrent(haystack, head_len);
461 +           if (p2p_result == 1) return p2p_result;         
462 +       }    
463 +    }
464 +
465 +
466 +    if ((info->cmd & 2048) == 2048)                            //cmd:  apple
467 +    {
468 +       if (hlen > 20)
469 +       {
470 +           p2p_result = search_apple(haystack, hlen, head_len);
471 +           if (p2p_result == 1) return p2p_result;         
472 +       }    
473 +    }
474 +
475 +
476 +    return p2p_result;
477 +}
478 +                                                                 
479 +
480 +
481 +
482 +static int
483 +checkentry(const char *tablename,
484 +            const struct ipt_ip *ip,
485 +           void *matchinfo,
486 +           unsigned int matchsize,
487 +           unsigned int hook_mask)
488 +{
489 +        /* Must specify -p tcp */
490 +    if (ip->proto != IPPROTO_TCP || (ip->invflags & IPT_INV_PROTO)) {
491 +       printk("ipp2p: Only works on TCP packets, use -p tcp\n");
492 +       return 0;
493 +    }
494 +                                                       
495 +
496 +    return 1;
497 +}
498 +                                                                           
499 +
500 +
501 +
502 +static struct ipt_match ipp2p_match
503 += { 
504 +       .name           = "ipp2p", 
505 +       .match          = &match, 
506 +       .checkentry     = &checkentry, 
507 +       .me             = THIS_MODULE
508 +};
509 +
510 +
511 +static int __init init(void)
512 +{
513 +    return ipt_register_match(&ipp2p_match);
514 +}
515 +       
516 +static void __exit fini(void)
517 +{
518 +    ipt_unregister_match(&ipp2p_match);
519 +}
520 +       
521 +module_init(init);
522 +module_exit(fini);
523 +
524 +
525 diff -uNr linux-2.6.4-rc1/net/ipv4.orig/netfilter/Kconfig linux-2.6.4-rc1/net/ipv4/netfilter/Kconfig
526 --- linux-2.6.4-rc1/net/ipv4.orig/netfilter/Kconfig     2004-03-03 03:58:03.000000000 +0100
527 +++ linux-2.6.4-rc1/net/ipv4/netfilter/Kconfig  2004-03-03 04:06:59.300251456 +0100
528 @@ -274,6 +274,16 @@
529  
530           To compile it as a module, choose M here.  If unsure, say N.
531  
532 +config IP_NF_MATCH_IPP2P
533 +       tristate "IPP2P match support"
534 +       depends on IP_NF_IPTABLES
535 +       help
536 +         IPP2P allows you to match certain packets of some popular
537 +         peer-to-peer networks. Use it to drop packets or mark them
538 +         for further use (with CONNMARK for example).
539 +         
540 +         To compile it as a module, choose M here.  If unsure, say N.
541 +
542  config IP_NF_MATCH_OWNER
543         tristate "Owner match support"
544         depends on IP_NF_IPTABLES
545 diff -uNr linux-2.6.4-rc1/net/ipv4.orig/netfilter/Makefile linux-2.6.4-rc1/net/ipv4/netfilter/Makefile
546 --- linux-2.6.4-rc1/net/ipv4.orig/netfilter/Makefile    2004-03-03 04:01:17.000000000 +0100
547 +++ linux-2.6.4-rc1/net/ipv4/netfilter/Makefile 2004-03-03 04:08:22.720569640 +0100
548 @@ -79,6 +79,7 @@
549  obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o
550  obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
551  obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
552 +obj-$(CONFIG_IP_NF_MATCH_IPP2P) += ipt_ipp2p.o
553  obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
554  
555  obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
This page took 0.079238 seconds and 3 git commands to generate.