]>
Commit | Line | Data |
---|---|---|
b724f160 | 1 | diff -Nur linux-2.6.0-test11.org/include/linux/netfilter_ipv4/ipt_ipp2p.h linux-2.6.0-test11/include/linux/netfilter_ipv4/ipt_ipp2p.h |
2 | --- linux-2.6.0-test11.org/include/linux/netfilter_ipv4/ipt_ipp2p.h 1970-01-01 01:00:00.000000000 +0100 | |
3 | +++ linux-2.6.0-test11/include/linux/netfilter_ipv4/ipt_ipp2p.h 2003-12-11 00:02:06.929074768 +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 -Nur linux-2.6.0-test11.org/net/ipv4/netfilter/ipt_ipp2p.c linux-2.6.0-test11/net/ipv4/netfilter/ipt_ipp2p.c | |
15 | --- linux-2.6.0-test11.org/net/ipv4/netfilter/ipt_ipp2p.c 1970-01-01 01:00:00.000000000 +0100 | |
16 | +++ linux-2.6.0-test11/net/ipv4/netfilter/ipt_ipp2p.c 2003-12-11 00:02:06.930074616 +0100 | |
17 | @@ -0,0 +1,510 @@ | |
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 | + const void *hdr, | |
357 | + u_int16_t datalen, | |
358 | + int *hotdrop) | |
359 | +{ | |
360 | + const struct ipt_p2p_info *info = matchinfo; | |
361 | + unsigned char *haystack; | |
362 | + struct iphdr *ip = skb->nh.iph; | |
363 | + int p2p_result = 0; | |
364 | + int head_len; | |
365 | + | |
366 | + int hlen = ntohs(ip->tot_len)-(ip->ihl*4); //hlen = packet-data length | |
367 | + haystack=(char *)ip+(ip->ihl*4); //haystack = packet data | |
368 | + | |
369 | + | |
370 | + if (((*(haystack+13)) & 1) == 1) return 0; //if FIN bit is set bail out | |
371 | + if (((*(haystack+13)) & 2) == 2) return 0; //if SYN bit is set bail out | |
372 | + if (((*(haystack+13)) & 4) == 4) return 0; //if RST bit is set bail out | |
373 | + | |
374 | + | |
375 | + head_len = (*(haystack+12))/4; //get TCP-Header-Size | |
376 | + | |
377 | + | |
378 | + if (((info->cmd & 8) == 8) || ((info->cmd & 4) == 4)) //cmd: kazaa-data || ipp2p-data | |
379 | + { | |
380 | + if (hlen > 200) | |
381 | + { | |
382 | + p2p_result = search_kazaa(haystack, hlen, head_len); | |
383 | + if (p2p_result == 1) return p2p_result; | |
384 | + } | |
385 | + | |
386 | + } | |
387 | + | |
388 | + | |
389 | + if (((info->cmd & 2) == 2) || ((info->cmd & 1) == 1)) //cmd: edk || ipp2p | |
390 | + { | |
391 | + if (hlen > 40) | |
392 | + { | |
393 | + p2p_result = search_all_edk(haystack, hlen, head_len); | |
394 | + if (p2p_result == 1) return p2p_result; | |
395 | + } | |
396 | + } | |
397 | + | |
398 | + | |
399 | + | |
400 | + | |
401 | + if (((info->cmd & 16) == 16) || ((info->cmd & 4) == 4)) //cmd: edk-data || ipp2p-data | |
402 | + { | |
403 | + if (hlen > 60) | |
404 | + { | |
405 | + p2p_result = search_edk(haystack, head_len); | |
406 | + if (p2p_result == 1) return p2p_result; | |
407 | + } | |
408 | + } | |
409 | + | |
410 | + if (((info->cmd & 32) == 32) || ((info->cmd & 4) == 4)) //cmd: dc-data || ipp2p-data | |
411 | + { | |
412 | + if (hlen == 26) | |
413 | + { | |
414 | + p2p_result = search_dc(haystack, hlen, head_len); | |
415 | + if (p2p_result == 1) return p2p_result; | |
416 | + } | |
417 | + } | |
418 | + | |
419 | + if (((info->cmd & 64) == 64) || ((info->cmd & 1) == 1)) //cmd: dc || ipp2p | |
420 | + { | |
421 | + if (hlen > 25) | |
422 | + { | |
423 | + p2p_result = search_all_dc(haystack, hlen, head_len); | |
424 | + if (p2p_result == 1) return p2p_result; | |
425 | + } | |
426 | + } | |
427 | + | |
428 | + if (((info->cmd & 128) == 128) || ((info->cmd & 4) == 4)) //cmd: gnu-data || ipp2p-data | |
429 | + { | |
430 | + if (hlen > 40) | |
431 | + { | |
432 | + p2p_result = search_gnu(haystack, hlen, head_len); | |
433 | + if (p2p_result == 1) return p2p_result; | |
434 | + } | |
435 | + } | |
436 | + | |
437 | + if (((info->cmd & 256) == 256) || ((info->cmd & 1) == 1)) //cmd: gnu || ipp2p | |
438 | + { | |
439 | + if (hlen > 35) | |
440 | + { | |
441 | + p2p_result = search_all_gnu(haystack, hlen, head_len); | |
442 | + if (p2p_result == 1) return p2p_result; | |
443 | + } | |
444 | + } | |
445 | + | |
446 | + | |
447 | + if (((info->cmd & 1) == 1) || ((info->cmd & 512) == 512)) //cmd: ipp2p || kazaa | |
448 | + { | |
449 | + if (hlen > 35) | |
450 | + { | |
451 | + p2p_result = search_all_kazaa(haystack, hlen, head_len); | |
452 | + if (p2p_result == 1) return p2p_result; | |
453 | + } | |
454 | + } | |
455 | + | |
456 | + | |
457 | + | |
458 | + if ((info->cmd & 1024) == 1024) //cmd: bit | |
459 | + { | |
460 | + if (hlen > 40) | |
461 | + { | |
462 | + p2p_result = search_bittorrent(haystack, head_len); | |
463 | + if (p2p_result == 1) return p2p_result; | |
464 | + } | |
465 | + } | |
466 | + | |
467 | + | |
468 | + if ((info->cmd & 2048) == 2048) //cmd: apple | |
469 | + { | |
470 | + if (hlen > 20) | |
471 | + { | |
472 | + p2p_result = search_apple(haystack, hlen, head_len); | |
473 | + if (p2p_result == 1) return p2p_result; | |
474 | + } | |
475 | + } | |
476 | + | |
477 | + | |
478 | + return p2p_result; | |
479 | +} | |
480 | + | |
481 | + | |
482 | + | |
483 | + | |
484 | +static int | |
485 | +checkentry(const char *tablename, | |
486 | + const struct ipt_ip *ip, | |
487 | + void *matchinfo, | |
488 | + unsigned int matchsize, | |
489 | + unsigned int hook_mask) | |
490 | +{ | |
491 | + /* Must specify -p tcp */ | |
492 | + if (ip->proto != IPPROTO_TCP || (ip->invflags & IPT_INV_PROTO)) { | |
493 | + printk("ipp2p: Only works on TCP packets, use -p tcp\n"); | |
494 | + return 0; | |
495 | + } | |
496 | + | |
497 | + | |
498 | + return 1; | |
499 | +} | |
500 | + | |
501 | + | |
502 | + | |
503 | + | |
504 | +static struct ipt_match ipp2p_match | |
505 | += { | |
506 | + { NULL, NULL }, | |
507 | + "ipp2p", | |
508 | + &match, | |
509 | + &checkentry, | |
510 | + NULL, | |
511 | + THIS_MODULE }; | |
512 | + | |
513 | + | |
514 | +static int __init init(void) | |
515 | +{ | |
516 | + return ipt_register_match(&ipp2p_match); | |
517 | +} | |
518 | + | |
519 | +static void __exit fini(void) | |
520 | +{ | |
521 | + ipt_unregister_match(&ipp2p_match); | |
522 | +} | |
523 | + | |
524 | +module_init(init); | |
525 | +module_exit(fini); | |
526 | + | |
527 | + | |
528 | diff -Nur linux-2.6.0-test11.org/net/ipv4/netfilter/Makefile linux-2.6.0-test11/net/ipv4/netfilter/Makefile | |
529 | --- linux-2.6.0-test11.org/net/ipv4/netfilter/Makefile 2003-12-10 23:24:46.000000000 +0100 | |
530 | +++ linux-2.6.0-test11/net/ipv4/netfilter/Makefile 2003-12-11 00:02:07.013062000 +0100 | |
531 | @@ -96,6 +96,7 @@ | |
532 | obj-$(CONFIG_IP_NF_MATCH_PSD) += ipt_psd.o | |
533 | ||
534 | obj-$(CONFIG_IP_NF_MATCH_OSF) += ipt_osf.o | |
535 | +obj-$(CONFIG_IP_NF_MATCH_IPP2P) += ipt_ipp2p.o | |
536 | ||
537 | ||
538 | obj-$(CONFIG_IP_NF_MATCH_NTH) += ipt_nth.o | |
539 | --- linux-2.6.0-test11.org/net/ipv4/netfilter/Kconfig 2003-12-10 23:13:25.000000000 +0100 | |
540 | +++ linux-2.6.0-test11/net/ipv4/netfilter/Kconfig 2003-12-11 00:20:03.590397368 +0100 | |
541 | @@ -611,5 +611,16 @@ | |
542 | ||
543 | To compile it as a module, choose M here. If unsure, say N. | |
544 | ||
545 | +config IP_NF_MATCH_IPP2P | |
546 | + tristate ' IPP2P match support (EXPERIMENTAL)' | |
547 | + depends on IP_NF_IPTABLES | |
548 | + help | |
549 | + IPP2P allows you to match certain packets of some popular | |
550 | + peer-to-peer networks. Use it to drop packets or mark them | |
551 | + for further use (with CONNMARK for example). | |
552 | + | |
553 | + If you want to compile it as a module, say M here and read | |
554 | + Documentation/modules.txt. If unsure, say `N'. | |
555 | + | |
556 | endmenu | |
557 |