📄 110-ipp2p_0.8.1rc1.patch
字号:
Index: linux-2.6.21.7/include/linux/netfilter_ipv4/ipt_ipp2p.h===================================================================--- /dev/null+++ linux-2.6.21.7/include/linux/netfilter_ipv4/ipt_ipp2p.h@@ -0,0 +1,31 @@+#ifndef __IPT_IPP2P_H+#define __IPT_IPP2P_H+#define IPP2P_VERSION "0.8.1_rc1"++struct ipt_p2p_info {+ int cmd;+ int debug;+};++#endif //__IPT_IPP2P_H++#define SHORT_HAND_IPP2P 1 /* --ipp2p switch*/+//#define SHORT_HAND_DATA 4 /* --ipp2p-data switch*/+#define SHORT_HAND_NONE 5 /* no short hand*/++#define IPP2P_EDK (1 << 1)+#define IPP2P_DATA_KAZAA (1 << 2)+#define IPP2P_DATA_EDK (1 << 3)+#define IPP2P_DATA_DC (1 << 4)+#define IPP2P_DC (1 << 5)+#define IPP2P_DATA_GNU (1 << 6)+#define IPP2P_GNU (1 << 7)+#define IPP2P_KAZAA (1 << 8)+#define IPP2P_BIT (1 << 9)+#define IPP2P_APPLE (1 << 10)+#define IPP2P_SOUL (1 << 11)+#define IPP2P_WINMX (1 << 12)+#define IPP2P_ARES (1 << 13)+#define IPP2P_MUTE (1 << 14)+#define IPP2P_WASTE (1 << 15)+#define IPP2P_XDCC (1 << 16)Index: linux-2.6.21.7/net/ipv4/netfilter/ipt_ipp2p.c===================================================================--- /dev/null+++ linux-2.6.21.7/net/ipv4/netfilter/ipt_ipp2p.c@@ -0,0 +1,882 @@+#if defined(MODVERSIONS)+#include <linux/modversions.h>+#endif+#include <linux/module.h>+#include <linux/netfilter_ipv4/ip_tables.h>+#include <linux/version.h>+#include <linux/netfilter_ipv4/ipt_ipp2p.h>+#include <net/tcp.h>+#include <net/udp.h>++#define get_u8(X,O) (*(__u8 *)(X + O))+#define get_u16(X,O) (*(__u16 *)(X + O))+#define get_u32(X,O) (*(__u32 *)(X + O))++MODULE_AUTHOR("Eicke Friedrich/Klaus Degner <ipp2p@ipp2p.org>");+MODULE_DESCRIPTION("An extension to iptables to identify P2P traffic.");+MODULE_LICENSE("GPL");+++/*Search for UDP eDonkey/eMule/Kad commands*/+int+udp_search_edk (unsigned char *haystack, int packet_len)+{+ unsigned char *t = haystack;+ t += 8;++ switch (t[0]) {+ case 0xe3:+ { /*edonkey*/+ switch (t[1])+ {+ /* client -> server status request */+ case 0x96:+ if (packet_len == 14) return ((IPP2P_EDK * 100) + 50);+ break;+ /* server -> client status request */+ case 0x97: if (packet_len == 42) return ((IPP2P_EDK * 100) + 51);+ break;+ /* server description request */+ /* e3 2a ff f0 .. | size == 6 */+ case 0xa2: if ( (packet_len == 14) && ( get_u16(t,2) == __constant_htons(0xfff0) ) ) return ((IPP2P_EDK * 100) + 52);+ break;+ /* server description response */+ /* e3 a3 ff f0 .. | size > 40 && size < 200 */+ //case 0xa3: return ((IPP2P_EDK * 100) + 53);+ // break;+ case 0x9a: if (packet_len==26) return ((IPP2P_EDK * 100) + 54);+ break;++ case 0x92: if (packet_len==18) return ((IPP2P_EDK * 100) + 55);+ break;+ }+ break;+ }+ case 0xe4:+ {+ switch (t[1])+ {+ /* e4 20 .. | size == 43 */+ case 0x20: if ((packet_len == 43) && (t[2] != 0x00) && (t[34] != 0x00)) return ((IPP2P_EDK * 100) + 60);+ break;+ /* e4 00 .. 00 | size == 35 ? */+ case 0x00: if ((packet_len == 35) && (t[26] == 0x00)) return ((IPP2P_EDK * 100) + 61);+ break;+ /* e4 10 .. 00 | size == 35 ? */+ case 0x10: if ((packet_len == 35) && (t[26] == 0x00)) return ((IPP2P_EDK * 100) + 62);+ break;+ /* e4 18 .. 00 | size == 35 ? */+ case 0x18: if ((packet_len == 35) && (t[26] == 0x00)) return ((IPP2P_EDK * 100) + 63);+ break;+ /* e4 52 .. | size = 44 */+ case 0x52: if (packet_len == 44 ) return ((IPP2P_EDK * 100) + 64);+ break;+ /* e4 58 .. | size == 6 */+ case 0x58: if (packet_len == 14 ) return ((IPP2P_EDK * 100) + 65);+ break;+ /* e4 59 .. | size == 2 */+ case 0x59: if (packet_len == 10 )return ((IPP2P_EDK * 100) + 66);+ break;+ /* e4 28 .. | packet_len == 52,77,102,127... */+ case 0x28: if (((packet_len-52) % 25) == 0) return ((IPP2P_EDK * 100) + 67);+ break;+ /* e4 50 xx xx | size == 4 */+ case 0x50: if (packet_len == 12) return ((IPP2P_EDK * 100) + 68);+ break;+ /* e4 40 xx xx | size == 48 */+ case 0x40: if (packet_len == 56) return ((IPP2P_EDK * 100) + 69);+ break;+ }+ break;+ }+ } /* end of switch (t[0]) */+ return 0;+}/*udp_search_edk*/+++/*Search for UDP Gnutella commands*/+int+udp_search_gnu (unsigned char *haystack, int packet_len)+{+ unsigned char *t = haystack;+ t += 8;++ if (memcmp(t, "GND", 3) == 0) return ((IPP2P_GNU * 100) + 51);+ if (memcmp(t, "GNUTELLA ", 9) == 0) return ((IPP2P_GNU * 100) + 52);+ return 0;+}/*udp_search_gnu*/+++/*Search for UDP KaZaA commands*/+int+udp_search_kazaa (unsigned char *haystack, int packet_len)+{+ unsigned char *t = haystack;++ if (t[packet_len-1] == 0x00){+ t += (packet_len - 6);+ if (memcmp(t, "KaZaA", 5) == 0) return (IPP2P_KAZAA * 100 +50);+ }++ return 0;+}/*udp_search_kazaa*/++/*Search for UDP DirectConnect commands*/+int+udp_search_directconnect (unsigned char *haystack, int packet_len)+{+ unsigned char *t = haystack;+ if ((*(t + 8) == 0x24) && (*(t + packet_len - 1) == 0x7c)) {+ t+=8;+ if (memcmp(t, "SR ", 3) == 0) return ((IPP2P_DC * 100) + 60);+ if (memcmp(t, "Ping ", 5) == 0) return ((IPP2P_DC * 100) + 61);+ }+ return 0;+}/*udp_search_directconnect*/++++/*Search for UDP BitTorrent commands*/+int+udp_search_bit (unsigned char *haystack, int packet_len)+{+ switch(packet_len)+ {+ case 24:+ /* ^ 00 00 04 17 27 10 19 80 */+ if ((ntohl(get_u32(haystack, 8)) == 0x00000417) && (ntohl(get_u32(haystack, 12)) == 0x27101980))+ return (IPP2P_BIT * 100 + 50);+ break;+ case 44:+ if (get_u32(haystack, 16) == __constant_htonl(0x00000400) && get_u32(haystack, 36) == __constant_htonl(0x00000104))+ return (IPP2P_BIT * 100 + 51);+ if (get_u32(haystack, 16) == __constant_htonl(0x00000400))+ return (IPP2P_BIT * 100 + 61);+ break;+ case 65:+ if (get_u32(haystack, 16) == __constant_htonl(0x00000404) && get_u32(haystack, 36) == __constant_htonl(0x00000104))+ return (IPP2P_BIT * 100 + 52);+ if (get_u32(haystack, 16) == __constant_htonl(0x00000404))+ return (IPP2P_BIT * 100 + 62);+ break;+ case 67:+ if (get_u32(haystack, 16) == __constant_htonl(0x00000406) && get_u32(haystack, 36) == __constant_htonl(0x00000104))+ return (IPP2P_BIT * 100 + 53);+ if (get_u32(haystack, 16) == __constant_htonl(0x00000406))+ return (IPP2P_BIT * 100 + 63);+ break;+ case 211:+ if (get_u32(haystack, 8) == __constant_htonl(0x00000405))+ return (IPP2P_BIT * 100 + 54);+ break;+ case 29:+ if ((get_u32(haystack, 8) == __constant_htonl(0x00000401)))+ return (IPP2P_BIT * 100 + 55);+ break;+ case 52:+ if (get_u32(haystack,8) == __constant_htonl(0x00000827) &&+ get_u32(haystack,12) == __constant_htonl(0x37502950))+ return (IPP2P_BIT * 100 + 80);+ break;+ default:+ /* this packet does not have a constant size */+ if (packet_len >= 40 && get_u32(haystack, 16) == __constant_htonl(0x00000402) && get_u32(haystack, 36) == __constant_htonl(0x00000104))+ return (IPP2P_BIT * 100 + 56);+ break;+ }++ /* some extra-bitcomet rules:+ * "d1:" [a|r] "d2:id20:"+ */+ if (packet_len > 30 && get_u8(haystack, 8) == 'd' && get_u8(haystack, 9) == '1' && get_u8(haystack, 10) == ':' )+ {+ if (get_u8(haystack, 11) == 'a' || get_u8(haystack, 11) == 'r')+ {+ if (memcmp(haystack+12,"d2:id20:",8)==0)+ return (IPP2P_BIT * 100 + 57);+ }+ }++#if 0+ /* bitlord rules */+ /* packetlen must be bigger than 40 */+ /* first 4 bytes are zero */+ if (packet_len > 40 && get_u32(haystack, 8) == 0x00000000)+ {+ /* first rule: 00 00 00 00 01 00 00 xx xx xx xx 00 00 00 00*/+ if (get_u32(haystack, 12) == 0x00000000 &&+ get_u32(haystack, 16) == 0x00010000 &&+ get_u32(haystack, 24) == 0x00000000 )+ return (IPP2P_BIT * 100 + 71);++ /* 00 01 00 00 0d 00 00 xx xx xx xx 00 00 00 00*/+ if (get_u32(haystack, 12) == 0x00000001 &&+ get_u32(haystack, 16) == 0x000d0000 &&+ get_u32(haystack, 24) == 0x00000000 )+ return (IPP2P_BIT * 100 + 71);+++ }+#endif++ return 0;+}/*udp_search_bit*/++++/*Search for Ares commands*/+//#define IPP2P_DEBUG_ARES+int+search_ares (const unsigned char *payload, const u16 plen)+//int search_ares (unsigned char *haystack, int packet_len, int head_len)+{+// const unsigned char *t = haystack + head_len;++ /* all ares packets start with */+ if (payload[1] == 0 && (plen - payload[0]) == 3)+ {+ switch (payload[2])+ {+ case 0x5a:+ /* ares connect */+ if ( plen == 6 && payload[5] == 0x05 ) return ((IPP2P_ARES * 100) + 1);+ break;+ case 0x09:+ /* ares search, min 3 chars --> 14 bytes+ * lets define a search can be up to 30 chars --> max 34 bytes+ */+ if ( plen >= 14 && plen <= 34 ) return ((IPP2P_ARES * 100) + 1);+ break;+#ifdef IPP2P_DEBUG_ARES+ default:+ printk(KERN_DEBUG "Unknown Ares command %x recognized, len: %u \n", (unsigned int) payload[2],plen);+#endif /* IPP2P_DEBUG_ARES */+ }+ }++#if 0+ /* found connect packet: 03 00 5a 04 03 05 */+ /* new version ares 1.8: 03 00 5a xx xx 05 */+ if ((plen) == 6){ /* possible connect command*/+ if ((payload[0] == 0x03) && (payload[1] == 0x00) && (payload[2] == 0x5a) && (payload[5] == 0x05))+ return ((IPP2P_ARES * 100) + 1);+ }+ if ((plen) == 60){ /* possible download command*/+ if ((payload[59] == 0x0a) && (payload[58] == 0x0a)){+ if (memcmp(t, "PUSH SHA1:", 10) == 0) /* found download command */+ return ((IPP2P_ARES * 100) + 2);+ }+ }+#endif++ return 0;+} /*search_ares*/++/*Search for SoulSeek commands*/+int+search_soul (const unsigned char *payload, const u16 plen)+{+//#define IPP2P_DEBUG_SOUL+ /* match: xx xx xx xx | xx = sizeof(payload) - 4 */+ if (get_u32(payload, 0) == (plen - 4)){+ const __u32 m=get_u32(payload, 4);+ /* match 00 yy yy 00, yy can be everything */+ if ( get_u8(payload, 4) == 0x00 && get_u8(payload, 7) == 0x00 )+ {+#ifdef IPP2P_DEBUG_SOUL+ printk(KERN_DEBUG "0: Soulseek command 0x%x recognized\n",get_u32(payload, 4));+#endif /* IPP2P_DEBUG_SOUL */+ return ((IPP2P_SOUL * 100) + 1);+ }++ /* next match: 01 yy 00 00 | yy can be everything */+ if ( get_u8(payload, 4) == 0x01 && get_u16(payload, 6) == 0x0000 )+ {+#ifdef IPP2P_DEBUG_SOUL+ printk(KERN_DEBUG "1: Soulseek command 0x%x recognized\n",get_u16(payload, 4));+#endif /* IPP2P_DEBUG_SOUL */+ return ((IPP2P_SOUL * 100) + 2);+ }++ /* other soulseek commandos are: 1-5,7,9,13-18,22,23,26,28,35-37,40-46,50,51,60,62-69,91,92,1001 */+ /* try to do this in an intelligent way */+ /* get all small commandos */+ switch(m)+ {+ case 7:+ case 9:+ case 22:+ case 23:+ case 26:+ case 28:+ case 50:+ case 51:+ case 60:+ case 91:+ case 92:+ case 1001:+#ifdef IPP2P_DEBUG_SOUL+ printk(KERN_DEBUG "2: Soulseek command 0x%x recognized\n",get_u16(payload, 4));+#endif /* IPP2P_DEBUG_SOUL */+ return ((IPP2P_SOUL * 100) + 3);+ }++ if (m > 0 && m < 6 )+ {+#ifdef IPP2P_DEBUG_SOUL+ printk(KERN_DEBUG "3: Soulseek command 0x%x recognized\n",get_u16(payload, 4));+#endif /* IPP2P_DEBUG_SOUL */+ return ((IPP2P_SOUL * 100) + 4);+ }+ if (m > 12 && m < 19 )+ {+#ifdef IPP2P_DEBUG_SOUL+ printk(KERN_DEBUG "4: Soulseek command 0x%x recognized\n",get_u16(payload, 4));+#endif /* IPP2P_DEBUG_SOUL */+ return ((IPP2P_SOUL * 100) + 5);+ }++ if (m > 34 && m < 38 )+ {+#ifdef IPP2P_DEBUG_SOUL+ printk(KERN_DEBUG "5: Soulseek command 0x%x recognized\n",get_u16(payload, 4));+#endif /* IPP2P_DEBUG_SOUL */+ return ((IPP2P_SOUL * 100) + 6);+ }++ if (m > 39 && m < 47 )+ {+#ifdef IPP2P_DEBUG_SOUL+ printk(KERN_DEBUG "6: Soulseek command 0x%x recognized\n",get_u16(payload, 4));+#endif /* IPP2P_DEBUG_SOUL */+ return ((IPP2P_SOUL * 100) + 7);+ }++ if (m > 61 && m < 70 )+ {+#ifdef IPP2P_DEBUG_SOUL+ printk(KERN_DEBUG "7: Soulseek command 0x%x recognized\n",get_u16(payload, 4));+#endif /* IPP2P_DEBUG_SOUL */+ return ((IPP2P_SOUL * 100) + 8);+ }++#ifdef IPP2P_DEBUG_SOUL+ printk(KERN_DEBUG "unknown SOULSEEK command: 0x%x, first 16 bit: 0x%x, first 8 bit: 0x%x ,soulseek ???\n",get_u32(payload, 4),get_u16(payload, 4) >> 16,get_u8(payload, 4) >> 24);+#endif /* IPP2P_DEBUG_SOUL */+ }++ /* match 14 00 00 00 01 yy 00 00 00 STRING(YY) 01 00 00 00 00 46|50 00 00 00 00 */+ /* without size at the beginning !!! */+ if ( get_u32(payload, 0) == 0x14 && get_u8(payload, 4) == 0x01 )+ {+ __u32 y=get_u32(payload, 5);+ /* we need 19 chars + string */+ if ( (y + 19) <= (plen) )+ {+ const unsigned char *w=payload+9+y;+ if (get_u32(w, 0) == 0x01 && ( get_u16(w, 4) == 0x4600 || get_u16(w, 4) == 0x5000) && get_u32(w, 6) == 0x00);+#ifdef IPP2P_DEBUG_SOUL+ printk(KERN_DEBUG "Soulssek special client command recognized\n");+#endif /* IPP2P_DEBUG_SOUL */+ return ((IPP2P_SOUL * 100) + 9);+ }+ }+ return 0;+}+++/*Search for WinMX commands*/+int+search_winmx (const unsigned char *payload, const u16 plen)+{+//#define IPP2P_DEBUG_WINMX+ if (((plen) == 4) && (memcmp(payload, "SEND", 4) == 0)) return ((IPP2P_WINMX * 100) + 1);+ if (((plen) == 3) && (memcmp(payload, "GET", 3) == 0)) return ((IPP2P_WINMX * 100) + 2);+ //if (packet_len < (head_len + 10)) return 0;+ if (plen < 10) return 0;++ if ((memcmp(payload, "SEND", 4) == 0) || (memcmp(payload, "GET", 3) == 0)){+ u16 c=4;+ const u16 end=plen-2;+ u8 count=0;+ while (c < end)+ {+ if (payload[c]== 0x20 && payload[c+1] == 0x22)+ {+ c++;+ count++;+ if (count>=2) return ((IPP2P_WINMX * 100) + 3);+ }+ c++;+ }+ }++ if ( plen == 149 && payload[0] == '8' )+ {+#ifdef IPP2P_DEBUG_WINMX+ printk(KERN_INFO "maybe WinMX\n");+#endif+ if (get_u32(payload,17) == 0 && get_u32(payload,21) == 0 && get_u32(payload,25) == 0 &&+// get_u32(payload,33) == __constant_htonl(0x71182b1a) && get_u32(payload,37) == __constant_htonl(0x05050000) &&+// get_u32(payload,133) == __constant_htonl(0x31097edf) && get_u32(payload,145) == __constant_htonl(0xdcb8f792))+ get_u16(payload,39) == 0 && get_u16(payload,135) == __constant_htons(0x7edf) && get_u16(payload,147) == __constant_htons(0xf792))++ {+#ifdef IPP2P_DEBUG_WINMX+ printk(KERN_INFO "got WinMX\n");+#endif+ return ((IPP2P_WINMX * 100) + 4);+ }+ }+ return 0;+} /*search_winmx*/+++/*Search for appleJuice commands*/+int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -