?? ipt_ipp2p.c
字號(hào):
/*Search for appleJuice commands*/intsearch_apple (const unsigned char *payload, const u16 plen){ if ( (plen > 7) && (payload[6] == 0x0d) && (payload[7] == 0x0a) && (memcmp(payload, "ajprot", 6) == 0)) return (IPP2P_APPLE * 100); return 0;}/*Search for BitTorrent commands*/intsearch_bittorrent (const unsigned char *payload, const u16 plen){ if (plen > 20) { /* test for match 0x13+"BitTorrent protocol" */ if (payload[0] == 0x13) { if (memcmp(payload+1, "BitTorrent protocol", 19) == 0) return (IPP2P_BIT * 100); } /* get tracker commandos, all starts with GET / * then it can follow: scrape| announce * and then ?hash_info= */ if (memcmp(payload,"GET /",5) == 0) { /* message scrape */ if ( memcmp(payload+5,"scrape?info_hash=",17)==0 ) return (IPP2P_BIT * 100 + 1); /* message announce */ if ( memcmp(payload+5,"announce?info_hash=",19)==0 ) return (IPP2P_BIT * 100 + 2); } } else { /* bitcomet encryptes the first packet, so we have to detect another * one later in the flow */ /* first try failed, too many missdetections */ //if ( size == 5 && get_u32(t,0) == __constant_htonl(1) && t[4] < 3) return (IPP2P_BIT * 100 + 3); /* second try: block request packets */ if ( plen == 17 && get_u32(payload,0) == __constant_htonl(0x0d) && payload[4] == 0x06 && get_u32(payload,13) == __constant_htonl(0x4000) ) return (IPP2P_BIT * 100 + 3); } return 0;}/*check for Kazaa get command*/intsearch_kazaa (const unsigned char *payload, const u16 plen){ if ((payload[plen-2] == 0x0d) && (payload[plen-1] == 0x0a) && memcmp(payload, "GET /.hash=", 11) == 0) return (IPP2P_DATA_KAZAA * 100); return 0;}/*check for gnutella get command*/intsearch_gnu (const unsigned char *payload, const u16 plen){ if ((payload[plen-2] == 0x0d) && (payload[plen-1] == 0x0a)) { if (memcmp(payload, "GET /get/", 9) == 0) return ((IPP2P_DATA_GNU * 100) + 1); if (memcmp(payload, "GET /uri-res/", 13) == 0) return ((IPP2P_DATA_GNU * 100) + 2); } return 0;}/*check for gnutella get commands and other typical data*/intsearch_all_gnu (const unsigned char *payload, const u16 plen){ if ((payload[plen-2] == 0x0d) && (payload[plen-1] == 0x0a)) { if (memcmp(payload, "GNUTELLA CONNECT/", 17) == 0) return ((IPP2P_GNU * 100) + 1); if (memcmp(payload, "GNUTELLA/", 9) == 0) return ((IPP2P_GNU * 100) + 2); if ((memcmp(payload, "GET /get/", 9) == 0) || (memcmp(payload, "GET /uri-res/", 13) == 0)) { u16 c=8; const u16 end=plen-22; while (c < end) { if ( payload[c] == 0x0a && payload[c+1] == 0x0d && ((memcmp(&payload[c+2], "X-Gnutella-", 11) == 0) || (memcmp(&payload[c+2], "X-Queue:", 8) == 0))) return ((IPP2P_GNU * 100) + 3); c++; } } } return 0;}/*check for KaZaA download commands and other typical data*/intsearch_all_kazaa (const unsigned char *payload, const u16 plen){ if ((payload[plen-2] == 0x0d) && (payload[plen-1] == 0x0a)) { if (memcmp(payload, "GIVE ", 5) == 0) return ((IPP2P_KAZAA * 100) + 1); if (memcmp(payload, "GET /", 5) == 0) { u16 c = 8; const u16 end=plen-22; while (c < end) { if ( payload[c] == 0x0a && payload[c+1] == 0x0d && ((memcmp(&payload[c+2], "X-Kazaa-Username: ", 18) == 0) || (memcmp(&payload[c+2], "User-Agent: PeerEnabler/", 24) == 0))) return ((IPP2P_KAZAA * 100) + 2); c++; } } } return 0;}/*fast check for edonkey file segment transfer command*/intsearch_edk (const unsigned char *payload, const u16 plen){ if (payload[0] != 0xe3) return 0; else { if (payload[5] == 0x47) return (IPP2P_DATA_EDK * 100); else return 0; }}/*intensive but slower search for some edonkey packets including size-check*/intsearch_all_edk (const unsigned char *payload, const u16 plen){ if (payload[0] != 0xe3) return 0; else { //t += head_len; const u16 cmd = get_u16(payload, 1); if (cmd == (plen - 5)) { switch (payload[5]) { case 0x01: return ((IPP2P_EDK * 100) + 1); /*Client: hello or Server:hello*/ case 0x4c: return ((IPP2P_EDK * 100) + 9); /*Client: Hello-Answer*/ } } return 0; }}/*fast check for Direct Connect send command*/intsearch_dc (const unsigned char *payload, const u16 plen){ if (payload[0] != 0x24 ) return 0; else { if (memcmp(&payload[1], "Send|", 5) == 0) return (IPP2P_DATA_DC * 100); else return 0; } }/*intensive but slower check for all direct connect packets*/intsearch_all_dc (const unsigned char *payload, const u16 plen){// unsigned char *t = haystack; if (payload[0] == 0x24 && payload[plen-1] == 0x7c) { const unsigned char *t=&payload[1]; /* Client-Hub-Protocol */ if (memcmp(t, "Lock ", 5) == 0) return ((IPP2P_DC * 100) + 1); /* Client-Client-Protocol, some are already recognized by client-hub (like lock) */ if (memcmp(t, "MyNick ", 7) == 0) return ((IPP2P_DC * 100) + 38); } return 0;}/*check for mute*/intsearch_mute (const unsigned char *payload, const u16 plen){ if ( plen == 209 || plen == 345 || plen == 473 || plen == 609 || plen == 1121 ) { //printk(KERN_DEBUG "size hit: %u",size); if (memcmp(payload,"PublicKey: ",11) == 0 ) { return ((IPP2P_MUTE * 100) + 0); /* if (memcmp(t+size-14,"\x0aEndPublicKey\x0a",14) == 0) { printk(KERN_DEBUG "end pubic key hit: %u",size); }*/ } } return 0;}/* check for xdcc */intsearch_xdcc (const unsigned char *payload, const u16 plen){ /* search in small packets only */ if (plen > 20 && plen < 200 && payload[plen-1] == 0x0a && payload[plen-2] == 0x0d && memcmp(payload,"PRIVMSG ",8) == 0) { u16 x=10; const u16 end=plen - 13; /* is seems to be a irc private massage, chedck for xdcc command */ while (x < end) { if (payload[x] == ':') { if ( memcmp(&payload[x+1],"xdcc send #",11) == 0 ) return ((IPP2P_XDCC * 100) + 0); } x++; } } return 0;}/* search for waste */int search_waste(const unsigned char *payload, const u16 plen){ if ( plen >= 8 && memcmp(payload,"GET.sha1:",9) == 0) return ((IPP2P_WASTE * 100) + 0); return 0;}static struct { int command; __u8 short_hand; /*for fucntions included in short hands*/ int packet_len; int (*function_name) (const unsigned char *, const u16);} matchlist[] = { {IPP2P_EDK,SHORT_HAND_IPP2P,20, &search_all_edk},// {IPP2P_DATA_KAZAA,SHORT_HAND_DATA,200, &search_kazaa},// {IPP2P_DATA_EDK,SHORT_HAND_DATA,60, &search_edk},// {IPP2P_DATA_DC,SHORT_HAND_DATA,26, &search_dc}, {IPP2P_DC,SHORT_HAND_IPP2P,5, search_all_dc},// {IPP2P_DATA_GNU,SHORT_HAND_DATA,40, &search_gnu}, {IPP2P_GNU,SHORT_HAND_IPP2P,5, &search_all_gnu}, {IPP2P_KAZAA,SHORT_HAND_IPP2P,5, &search_all_kazaa}, {IPP2P_BIT,SHORT_HAND_IPP2P,20, &search_bittorrent}, {IPP2P_APPLE,SHORT_HAND_IPP2P,5, &search_apple}, {IPP2P_SOUL,SHORT_HAND_IPP2P,5, &search_soul}, {IPP2P_WINMX,SHORT_HAND_IPP2P,2, &search_winmx}, {IPP2P_ARES,SHORT_HAND_IPP2P,5, &search_ares}, {IPP2P_MUTE,SHORT_HAND_NONE,200, &search_mute}, {IPP2P_WASTE,SHORT_HAND_NONE,5, &search_waste}, {IPP2P_XDCC,SHORT_HAND_NONE,5, &search_xdcc}, {0,0,0,NULL}};static struct { int command; __u8 short_hand; /*for fucntions included in short hands*/ int packet_len; int (*function_name) (unsigned char *, int);} udp_list[] = { {IPP2P_KAZAA,SHORT_HAND_IPP2P,14, &udp_search_kazaa}, {IPP2P_BIT,SHORT_HAND_IPP2P,23, &udp_search_bit}, {IPP2P_GNU,SHORT_HAND_IPP2P,11, &udp_search_gnu}, {IPP2P_EDK,SHORT_HAND_IPP2P,9, &udp_search_edk}, {IPP2P_DC,SHORT_HAND_IPP2P,12, &udp_search_directconnect}, {0,0,0,NULL}};static intmatch(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *matchinfo, int offset,#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) const void *hdr, u_int16_t datalen,#endif int *hotdrop){ const struct ipt_p2p_info *info = matchinfo; unsigned char *haystack; struct iphdr *ip = skb->nh.iph; int p2p_result = 0, i = 0;// int head_len; int hlen = ntohs(ip->tot_len)-(ip->ihl*4); /*hlen = packet-data length*/ /*must not be a fragment*/ if (offset) { if (info->debug) printk("IPP2P.match: offset found %i \n",offset); return 0; } /*make sure that skb is linear*/ if(skb_is_nonlinear(skb)){ if (info->debug) printk("IPP2P.match: nonlinear skb found\n"); return 0; } haystack=(char *)ip+(ip->ihl*4); /*haystack = packet data*/ switch (ip->protocol){ case IPPROTO_TCP: /*what to do with a TCP packet*/ { struct tcphdr *tcph = (void *) ip + ip->ihl * 4; if (tcph->fin) return 0; /*if FIN bit is set bail out*/ if (tcph->syn) return 0; /*if SYN bit is set bail out*/ if (tcph->rst) return 0; /*if RST bit is set bail out*/ haystack += tcph->doff * 4; /*get TCP-Header-Size*/ hlen -= tcph->doff * 4; while (matchlist[i].command) { if ((((info->cmd & matchlist[i].command) == matchlist[i].command) || ((info->cmd & matchlist[i].short_hand) == matchlist[i].short_hand)) && (hlen > matchlist[i].packet_len)) { p2p_result = matchlist[i].function_name(haystack, hlen); if (p2p_result) { if (info->debug) printk("IPP2P.debug:TCP-match: %i from: %u.%u.%u.%u:%i to: %u.%u.%u.%u:%i Length: %i\n", p2p_result, NIPQUAD(ip->saddr),ntohs(tcph->source), NIPQUAD(ip->daddr),ntohs(tcph->dest),hlen); return p2p_result; } } i++; } return p2p_result; } case IPPROTO_UDP: /*what to do with an UDP packet*/ { struct udphdr *udph = (void *) ip + ip->ihl * 4; while (udp_list[i].command){ if ((((info->cmd & udp_list[i].command) == udp_list[i].command) || ((info->cmd & udp_list[i].short_hand) == udp_list[i].short_hand)) && (hlen > udp_list[i].packet_len)) { p2p_result = udp_list[i].function_name(haystack, hlen); if (p2p_result){ if (info->debug) printk("IPP2P.debug:UDP-match: %i from: %u.%u.%u.%u:%i to: %u.%u.%u.%u:%i Length: %i\n", p2p_result, NIPQUAD(ip->saddr),ntohs(udph->source), NIPQUAD(ip->daddr),ntohs(udph->dest),hlen); return p2p_result; } } i++; } return p2p_result; } default: return 0; }}static intcheckentry(const char *tablename, const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask){ /* Must specify -p tcp *//* if (ip->proto != IPPROTO_TCP || (ip->invflags & IPT_INV_PROTO)) { * printk("ipp2p: Only works on TCP packets, use -p tcp\n"); * return 0; * }*/ return 1;} static struct ipt_match ipp2p_match = { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) { NULL, NULL }, "ipp2p", &match, &checkentry, NULL, THIS_MODULE#endif#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) .name = "ipp2p", .match = &match, .checkentry = &checkentry, .me = THIS_MODULE,#endif};static int __init init(void){ printk(KERN_INFO "IPP2P v%s loading\n", IPP2P_VERSION); return ipt_register_match(&ipp2p_match);} static void __exit fini(void){ ipt_unregister_match(&ipp2p_match); printk(KERN_INFO "IPP2P v%s unloaded\n", IPP2P_VERSION); } module_init(init);module_exit(fini);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -