summaryrefslogtreecommitdiffstats
path: root/target/linux/linux-2.4/patches/101-netfilter_ipp2p.patch
diff options
context:
space:
mode:
authornbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>2005-05-28 09:17:29 +0000
committernbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>2005-05-28 09:17:29 +0000
commit76ed58d705e7f3892a1259abcd92882a527e7b53 (patch)
tree80dfa6ecb493ee8cb9ca1436f1b37ee89f320a55 /target/linux/linux-2.4/patches/101-netfilter_ipp2p.patch
parente285af3e184318b0fefeab597ae5ee4a2628422d (diff)
move package/linux into target/linux, use wbx' new kernel code. support building images with more than one kernel, split kernel module parts off of packages that use their own kernel modules (fuse, shfs, openswan). some cleanup in the image building process in target/. image builder is disabled for now, needs some fixing.
git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@1085 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/linux-2.4/patches/101-netfilter_ipp2p.patch')
-rw-r--r--target/linux/linux-2.4/patches/101-netfilter_ipp2p.patch720
1 files changed, 720 insertions, 0 deletions
diff --git a/target/linux/linux-2.4/patches/101-netfilter_ipp2p.patch b/target/linux/linux-2.4/patches/101-netfilter_ipp2p.patch
new file mode 100644
index 000000000..1314ae4fe
--- /dev/null
+++ b/target/linux/linux-2.4/patches/101-netfilter_ipp2p.patch
@@ -0,0 +1,720 @@
+diff -urN linux-2.4.29.old/include/linux/netfilter_ipv4/ipt_ipp2p.h linux-2.4.29/include/linux/netfilter_ipv4/ipt_ipp2p.h
+--- linux-2.4.29.old/include/linux/netfilter_ipv4/ipt_ipp2p.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.29/include/linux/netfilter_ipv4/ipt_ipp2p.h 2005-03-12 00:44:17.000000000 +0100
+@@ -0,0 +1,29 @@
++#ifndef __IPT_IPP2P_H
++#define __IPT_IPP2P_H
++#define IPP2P_VERSION "0.7.4"
++
++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 2
++#define IPP2P_DATA_KAZAA 8
++#define IPP2P_DATA_EDK 16
++#define IPP2P_DATA_DC 32
++#define IPP2P_DC 64
++#define IPP2P_DATA_GNU 128
++#define IPP2P_GNU 256
++#define IPP2P_KAZAA 512
++#define IPP2P_BIT 1024
++#define IPP2P_APPLE 2048
++#define IPP2P_SOUL 4096
++#define IPP2P_WINMX 8192
++#define IPP2P_ARES 16384
++
+diff -urN linux-2.4.29.old/net/ipv4/netfilter/Config.in linux-2.4.29/net/ipv4/netfilter/Config.in
+--- linux-2.4.29.old/net/ipv4/netfilter/Config.in 2005-03-12 00:40:38.000000000 +0100
++++ linux-2.4.29/net/ipv4/netfilter/Config.in 2005-03-12 00:42:57.000000000 +0100
+@@ -26,6 +26,7 @@
+ dep_tristate ' TOS match support' CONFIG_IP_NF_MATCH_TOS $CONFIG_IP_NF_IPTABLES
+ dep_tristate ' recent match support' CONFIG_IP_NF_MATCH_RECENT $CONFIG_IP_NF_IPTABLES
+ dep_tristate ' ECN match support' CONFIG_IP_NF_MATCH_ECN $CONFIG_IP_NF_IPTABLES
++ dep_tristate ' peer to peer traffic match support' CONFIG_IP_NF_MATCH_IPP2P $CONFIG_IP_NF_IPTABLES
+
+ dep_tristate ' DSCP match support' CONFIG_IP_NF_MATCH_DSCP $CONFIG_IP_NF_IPTABLES
+
+diff -urN linux-2.4.29.old/net/ipv4/netfilter/ipt_ipp2p.c linux-2.4.29/net/ipv4/netfilter/ipt_ipp2p.c
+--- linux-2.4.29.old/net/ipv4/netfilter/ipt_ipp2p.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.29/net/ipv4/netfilter/ipt_ipp2p.c 2005-03-12 00:44:02.000000000 +0100
+@@ -0,0 +1,661 @@
++#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 "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 <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]) {
++ /* e3 9a + 16Bytes Hash | size == 26 */
++ case 0x9a: if (packet_len == 26) return ((IPP2P_EDK * 100) + 1);
++ /* e3 96 xx yy zz kk | size == 14 | server status request */
++ case 0x96: if (packet_len == 14) return ((IPP2P_EDK * 100) + 2);
++ /* e3 a2 | size == 10 or 14 <-- recheck*/
++ }
++ }
++
++ case 0xc5: { /*emule*/
++ switch (t[1]) {
++ /* c5 91 xx yy | size == 12 (8+4) | xx != 0x00 -- xx yy queue rating */
++ case 0x91: if ((packet_len == 12) && (t[2] != 0x00)) return ((IPP2P_EDK * 100) + 3);
++ /* c5 90 xx .. yy | size == 26 (8+2+16) | xx .. yy == hash -- file ping */
++ case 0x90: if ((packet_len == 26) && (t[2] != 0x00)) return ((IPP2P_EDK * 100) + 4);
++ /* c5 92 | size == 10 (8+2) -- file not found */
++ case 0x92: if (packet_len == 10) return ((IPP2P_EDK * 100) + 5);
++ /* c5 93 | size == 10 (8+2) -- queue full */
++ case 0x93: if (packet_len == 10) return ((IPP2P_EDK * 100) + 6);
++ }
++ }
++
++ case 0xe4: { /*kad*/
++ switch (t[1]) {
++ /* e4 50 | size == 12 */
++ case 0x50: if (packet_len == 12) return ((IPP2P_EDK * 100) + 7);
++ /* e4 58 | size == 14 */
++ case 0x58: if ((packet_len == 14) && (t[2] != 0x00)) return ((IPP2P_EDK * 100) + 8);
++ /* e4 59 | size == 10 */
++ case 0x59: if (packet_len == 10) return ((IPP2P_EDK * 100) + 9);
++ /* e4 30 .. | t[18] == 0x01 | size > 26 | --> search */
++ case 0x30: if ((packet_len > 26) && (t[18] == 0x01)) return ((IPP2P_EDK * 100) + 10);
++ /* e4 28 .. 00 | t[68] == 0x00 | size > 76 */
++ case 0x28: if ((packet_len > 76) && (t[68] == 0x00)) return ((IPP2P_EDK * 100) + 11);
++ /* e4 20 .. | size == 43 */
++ case 0x20: if ((packet_len == 43) && (t[2] != 0x00) && (t[34] != 0x00)) return ((IPP2P_EDK * 100) + 12);
++ /* e4 00 .. 00 | size == 35 ? */
++ case 0x00: if ((packet_len == 35) && (t[26] == 0x00)) return ((IPP2P_EDK * 100) + 13);
++ /* e4 10 .. 00 | size == 35 ? */
++ case 0x10: if ((packet_len == 35) && (t[26] == 0x00)) return ((IPP2P_EDK * 100) + 14);
++ /* e4 18 .. 00 | size == 35 ? */
++ case 0x18: if ((packet_len == 35) && (t[26] == 0x00)) return ((IPP2P_EDK * 100) + 15);
++ /* e4 40 .. | t[18] == 0x01 | t[19] == 0x00 | size > 40 */
++ case 0x40: if ((packet_len > 40) && (t[18] == 0x01) && (t[19] == 0x00)) return ((IPP2P_EDK * 100) + 16);
++ }
++ }
++
++ default: return 0;
++ } /* end of switch (t[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) + 1);
++ if (memcmp(t, "GNUTELLA ", 9) == 0) return ((IPP2P_GNU * 100) + 2);
++ 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);
++ }
++ return 0;
++}/*udp_search_kazaa*/
++
++
++/*Search for UDP BitTorrent commands*/
++int
++udp_search_bit (unsigned char *haystack, int packet_len)
++{
++ unsigned char *t = haystack;
++
++ /* packet_len has to be 24 */
++ if (packet_len != 24) return 0;
++
++ t += 8;
++
++ /* ^ 00 00 04 17 27 10 19 80 */
++ if ((ntohl(get_u32(t, 0)) == 0x00000417) && (ntohl(get_u32(t, 4)) == 0x27101980)) return (IPP2P_BIT * 100);
++
++ return 0;
++}/*udp_search_bit*/
++
++
++
++/*Search for Ares commands*/
++int
++search_ares (unsigned char *haystack, int packet_len, int head_len)
++{
++ unsigned char *t = haystack;
++ t += head_len;
++
++ if ((packet_len - head_len) == 6){ /* possible connect command*/
++ if ((t[0] == 0x03) && (t[1] == 0x00) && (t[2] == 0x5a) && (t[3] == 0x04) && (t[4] == 0x03) && (t[5] == 0x05))
++ return ((IPP2P_ARES * 100) + 1); /* found connect packet: 03 00 5a 04 03 05 */
++ }
++ if ((packet_len - head_len) == 60){ /* possible download command*/
++ if ((t[59] == 0x0a) && (t[58] == 0x0a)){
++ if (memcmp(t, "PUSH SHA1:", 10) == 0) /* found download command */
++ return ((IPP2P_ARES * 100) + 2);
++ }
++ }
++ return 0;
++} /*search_ares*/
++
++
++/*Search for SoulSeek commands*/
++int
++search_soul (unsigned char *haystack, int packet_len, int head_len)
++{
++ unsigned char *t = haystack;
++ t += head_len;
++
++ if (get_u16(t, 0) == (packet_len - head_len - 4)){
++ /* xx xx 00 00 yy zz 00 00 .. | xx = sizeof(payload) - 4 */
++ if ((get_u16(t,2) == 0x0000) &&(t[4] != 0x00) && (get_u16(t,6) == 0x0000))
++ return ((IPP2P_SOUL * 100) + 1);
++ } else {
++ /* 00 00 00 00 00 00 00 00 + sizeof(payload) == 8*/
++ if (((packet_len - head_len) == 8) && (get_u32(t, 0) == 0x00000000) && (get_u32(t, 4) == 0x00000000))
++ return ((IPP2P_SOUL * 100) + 2);
++ }
++
++ /* 01 xx 00 00 00 yy .. zz 00 00 00 .. | xx == sizeof(nick) | yy .. zz == nick */
++ if ((t[0] == 0x01) && (t[2] == 0x00) && (get_u16(t,3) == 0x0000) && ((packet_len - head_len) > ((get_u8(t,1))+6)) &&
++ (t[(get_u8(t,1))+4] != 0x00) && (t[(get_u8(t,1))+5] == 0x01) && (t[(get_u8(t,1))+6] == 0x00))
++ return ((IPP2P_SOUL * 100) + 3);
++ return 0;
++}
++
++
++/*Search for WinMX commands*/
++int
++search_winmx (unsigned char *haystack, int packet_len, int head_len)
++{
++ unsigned char *t = haystack;
++ int c;
++ t += head_len;
++
++ if (((packet_len - head_len) == 4) && (memcmp(t, "SEND", 4) == 0)) return ((IPP2P_WINMX * 100) + 1);
++ if (((packet_len - head_len) == 3) && (memcmp(t, "GET", 3) == 0)) return ((IPP2P_WINMX * 100) + 2);
++ if (packet_len < (head_len + 10)) return 0;
++
++ if ((memcmp(t, "SEND", 4) == 0) || (memcmp(t, "GET", 3) == 0)){
++ c = head_len + 4;
++ t += 4;
++ while (c < packet_len - 5) {
++ if ((t[0] == 0x20) && (t[1] == 0x22)){
++ c += 2;
++ t += 2;
++ while (c < packet_len - 2) {
++ if ((t[0] == 0x22) && (t[1] == 0x20)) return ((IPP2P_WINMX * 100) + 3);
++ t++;
++ c++;
++ }
++ }
++ t++;
++ c++;
++ }
++ }
++ return 0;
++} /*search_winmx*/
++
++
++/*Search for appleJuice commands*/
++int
++search_apple (unsigned char *haystack, int packet_len, int head_len)
++{
++ unsigned char *t = haystack;
++ t += head_len;
++
++ if ((memcmp(t, "ajprot", 6) == 0) && (t[6] == 0x0d) && (t[7] == 0x0a)) return (IPP2P_APPLE * 100);
++
++ return 0;
++}
++
++
++/*Search for BitTorrent commands*/
++int
++search_bittorrent (unsigned char *haystack, int packet_len, int head_len)
++{
++
++ unsigned char *t = haystack;
++ if (*(haystack+head_len) != 0x13) return 0; /*Bail out of first byte != 0x13*/
++
++ t += head_len + 1;
++
++ if (memcmp(t, "BitTorrent protocol", 19) == 0) return (IPP2P_BIT * 100);
++ return 0;
++}
++
++
++
++/*check for Kazaa get command*/
++int
++search_kazaa (unsigned char *haystack, int packet_len, int head_len)
++{
++ unsigned char *t = haystack;
++
++ if (!((*(haystack + packet_len - 2) == 0x0d) && (*(haystack + packet_len - 1) == 0x0a))) return 0;
++
++ t += head_len;
++ if (memcmp(t, "GET /.hash=", 11) == 0)
++ return (IPP2P_DATA_KAZAA * 100);
++ else
++ return 0;
++}
++
++
++/*check for gnutella get command*/
++int
++search_gnu (unsigned char *haystack, int packet_len, int head_len)
++{
++ unsigned char *t = haystack;
++
++ if (!((*(haystack + packet_len - 2) == 0x0d) && (*(haystack + packet_len - 1) == 0x0a))) return 0;
++
++ t += head_len;
++ if (memcmp(t, "GET /get/", 9) == 0) return ((IPP2P_DATA_GNU * 100) + 1);
++ if (memcmp(t, "GET /uri-res/", 13) == 0) return ((IPP2P_DATA_GNU * 100) + 2);
++
++ return 0;
++}
++
++
++/*check for gnutella get commands and other typical data*/
++int
++search_all_gnu (unsigned char *haystack, int packet_len, int head_len)
++{
++ unsigned char *t = haystack;
++ int c;
++
++ if (!((*(haystack + packet_len - 2) == 0x0d) && (*(haystack + packet_len - 1) == 0x0a))) return 0;
++
++ t += head_len;
++
++ if (memcmp(t, "GNUTELLA CONNECT/", 17) == 0) return ((IPP2P_GNU * 100) + 1);
++ if (memcmp(t, "GNUTELLA/", 9) == 0) return ((IPP2P_GNU * 100) + 2);
++
++ if ((memcmp(t, "GET /get/", 9) == 0) || (memcmp(t, "GET /uri-res/", 13) == 0))
++ {
++ c = head_len + 8;
++ t += 8;
++ while (c < packet_len - 22) {
++ if ((t[0] == 0x0d) && (t[1] == 0x0a)) {
++ t += 2;
++ c += 2;
++ if ((memcmp(t, "X-Gnutella-", 11) == 0) || (memcmp(t, "X-Queue:", 8) == 0)) return ((IPP2P_GNU * 100) + 3);
++ } else {
++ t++;
++ c++;
++ }
++ }
++ }
++ return 0;
++}
++
++
++/*check for KaZaA download commands and other typical data*/
++int
++search_all_kazaa (unsigned char *haystack, int packet_len, int head_len)
++{
++ unsigned char *t = haystack;
++ int c;
++
++ if (!((*(haystack + packet_len - 2) == 0x0d) && (*(haystack + packet_len - 1) == 0x0a))) return 0;
++
++ t += head_len;
++ if (memcmp(t, "GIVE ", 5) == 0) return ((IPP2P_KAZAA * 100) + 1);
++
++ if (memcmp(t, "GET /", 5) == 0) {
++ c = head_len + 8;
++ t += 8;
++ while (c < packet_len - 22) {
++ if ((t[0] == 0x0d) && (t[1] == 0x0a)) {
++ t += 2;
++ c += 2;
++ if ( memcmp(t, "X-Kazaa-Username: ", 18) == 0 ) return ((IPP2P_KAZAA * 100) + 2);
++ if ( memcmp(t, "User-Agent: PeerEnabler/", 24) == 0 ) return ((IPP2P_KAZAA * 100) + 3);
++ } else {
++ t++;
++ c++;
++ }
++ }
++ }
++
++ return 0;
++}
++
++/*fast check for edonkey file segment transfer command*/
++int
++search_edk (unsigned char *haystack, int packet_len, int head_len)
++{
++ if (*(haystack+head_len) != 0xe3)
++ return 0;
++ else {
++ if (*(haystack+head_len+5) == 0x47)
++ return (IPP2P_DATA_EDK * 100);
++ else
++ return 0;
++ }
++}
++
++
++
++/*intensive but slower search for some edonkey packets including size-check*/
++int
++search_all_edk (unsigned char *haystack, int packet_len, int head_len)
++{
++ unsigned char *t = haystack;
++ int cmd;
++
++ if (*(haystack+head_len) == 0xd4) {
++ t += head_len;
++ cmd = get_u16(t, 1);
++ if (cmd == (packet_len - head_len - 5)) {
++ switch (t[5]) {
++ case 0x82: return ((IPP2P_EDK * 100) + 42);
++ case 0x15: return ((IPP2P_EDK * 100) + 43);
++ default: return 0;
++ }
++ }
++ return 0;
++ }
++
++
++ if (*(haystack+head_len) == 0xc5) { /*search for additional eMule packets*/
++ t += head_len;
++ cmd = get_u16(t, 1);
++
++ if (cmd == (packet_len - head_len - 5)) {
++ switch (t[5]) {
++ case 0x01: return ((IPP2P_EDK * 100) + 30);
++ case 0x02: return ((IPP2P_EDK * 100) + 31);
++ case 0x60: return ((IPP2P_EDK * 100) + 32);
++ case 0x81: return ((IPP2P_EDK * 100) + 33);
++ case 0x82: return ((IPP2P_EDK * 100) + 34);
++ case 0x85: return ((IPP2P_EDK * 100) + 35);
++ case 0x86: return ((IPP2P_EDK * 100) + 36);
++ case 0x87: return ((IPP2P_EDK * 100) + 37);
++ case 0x40: return ((IPP2P_EDK * 100) + 38);
++ case 0x92: return ((IPP2P_EDK * 100) + 39);
++ case 0x93: return ((IPP2P_EDK * 100) + 40);
++ case 0x12: return ((IPP2P_EDK * 100) + 41);
++ default: return 0;
++ }
++ }
++
++ return 0;
++ }
++
++
++ if (*(haystack+head_len) != 0xe3)
++ return 0;
++ else {
++ t += head_len;
++ cmd = get_u16(t, 1);
++ if (cmd == (packet_len - head_len - 5)) {
++ switch (t[5]) {
++ case 0x01: return ((IPP2P_EDK * 100) + 1); /*Client: hello or Server:hello*/
++ case 0x50: return ((IPP2P_EDK * 100) + 2); /*Client: file status*/
++ case 0x16: return ((IPP2P_EDK * 100) + 3); /*Client: search*/
++ case 0x58: return ((IPP2P_EDK * 100) + 4); /*Client: file request*/
++ case 0x48: return ((IPP2P_EDK * 100) + 5); /*???*/
++ case 0x54: return ((IPP2P_EDK * 100) + 6); /*???*/
++ case 0x47: return ((IPP2P_EDK * 100) + 7); /*Client: file segment request*/
++ case 0x46: return ((IPP2P_EDK * 100) + 8); /*Client: download segment*/
++ case 0x4c: return ((IPP2P_EDK * 100) + 9); /*Client: Hello-Answer*/
++ case 0x4f: return ((IPP2P_EDK * 100) + 10); /*Client: file status request*/
++ case 0x59: return ((IPP2P_EDK * 100) + 11); /*Client: file request answer*/
++ case 0x65: return ((IPP2P_EDK * 100) + 12); /*Client: ???*/
++ case 0x66: return ((IPP2P_EDK * 100) + 13); /*Client: ???*/
++ case 0x51: return ((IPP2P_EDK * 100) + 14); /*Client: ???*/
++ case 0x52: return ((IPP2P_EDK * 100) + 15); /*Client: ???*/
++ case 0x4d: return ((IPP2P_EDK * 100) + 16); /*Client: ???*/
++ case 0x5c: return ((IPP2P_EDK * 100) + 17); /*Client: ???*/
++ case 0x38: return ((IPP2P_EDK * 100) + 18); /*Client: ???*/
++ case 0x69: return ((IPP2P_EDK * 100) + 19); /*Client: ???*/
++ case 0x19: return ((IPP2P_EDK * 100) + 20); /*Client: ???*/
++ case 0x42: return ((IPP2P_EDK * 100) + 21); /*Client: ???*/
++ case 0x34: return ((IPP2P_EDK * 100) + 22); /*Client: ???*/
++ case 0x94: return ((IPP2P_EDK * 100) + 23); /*Client: ???*/
++ case 0x1c: return ((IPP2P_EDK * 100) + 24); /*Client: ???*/
++ case 0x6a: return ((IPP2P_EDK * 100) + 25); /*Client: ???*/
++ default: return 0;
++ }
++ } else {
++ if (cmd > packet_len - head_len - 5) {
++ if ((t[3] == 0x00) && (t[4] == 0x00)) {
++ if (t[5] == 0x01) return ((IPP2P_EDK * 100) + 26);
++ if (t[5] == 0x4c) return ((IPP2P_EDK * 100) + 27);
++ }
++ return 0;
++
++ } /*non edk packet*/
++ if (t[cmd+5] == 0xe3) return ((IPP2P_EDK * 100) + 28);/*found another edk-command*/
++ if (t[cmd+5] == 0xc5) return ((IPP2P_EDK * 100) + 29);/*found an emule-command*/
++ return 0;
++ }
++ }
++}
++
++
++/*fast check for Direct Connect send command*/
++int
++search_dc (unsigned char *haystack, int packet_len, int head_len)
++{
++ unsigned char *t = haystack;
++
++ if (*(haystack+head_len) != 0x24 )
++ return 0;
++ else {
++ t += head_len + 1;
++ if (memcmp(t, "Send|", 5) == 0)
++ return (IPP2P_DATA_DC * 100);
++ else
++ return 0;
++ }
++
++}
++
++
++/*intensive but slower check for all direct connect packets*/
++int
++search_all_dc (unsigned char *haystack, int packet_len, int head_len)
++{
++ unsigned char *t = haystack;
++
++ if ((*(haystack + head_len) == 0x24) && (*(haystack + packet_len - 1) == 0x7c)) {
++ t += head_len + 1;
++ if (memcmp(t, "Lock ", 5) == 0) return ((IPP2P_DC * 100) + 1); /*hub: hello*/
++ if (memcmp(t, "Key ", 4) == 0) return ((IPP2P_DC * 100) + 2); /*client: hello*/
++ if (memcmp(t, "Hello ", 6) == 0) return ((IPP2P_DC * 100) + 3); /*hub:connected*/
++ if (memcmp(t, "MyNick ", 7) == 0) return ((IPP2P_DC * 100) + 4); /*client-client: hello*/
++ if (memcmp(t, "Search ", 7) == 0) return ((IPP2P_DC * 100) + 5); /*client: search*/
++ if (memcmp(t, "Send", 4) == 0) return ((IPP2P_DC * 100) + 6); /*client: start download*/
++ return 0;
++ } else
++ return 0;
++}
++
++
++static struct {
++ int command;
++ __u8 short_hand; /*for fucntions included in short hands*/
++ int packet_len;
++ int (*function_name) (unsigned char *, int, int);
++} matchlist[] = {
++ {IPP2P_EDK,SHORT_HAND_IPP2P,40, &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,25, search_all_dc},
++ {IPP2P_DATA_GNU,SHORT_HAND_DATA,40, &search_gnu},
++ {IPP2P_GNU,SHORT_HAND_IPP2P,35, &search_all_gnu},
++ {IPP2P_KAZAA,SHORT_HAND_IPP2P,35, &search_all_kazaa},
++ {IPP2P_BIT,SHORT_HAND_NONE,40, &search_bittorrent},
++ {IPP2P_APPLE,SHORT_HAND_NONE,20, &search_apple},
++ {IPP2P_SOUL,SHORT_HAND_NONE,25, &search_soul},
++ {IPP2P_WINMX,SHORT_HAND_NONE,20, &search_winmx},
++ {IPP2P_ARES,SHORT_HAND_NONE,25, &search_ares},
++ {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_NONE,23, &udp_search_bit},
++ {IPP2P_GNU,SHORT_HAND_IPP2P,11, &udp_search_gnu},
++ {IPP2P_EDK,SHORT_HAND_IPP2P,9, &udp_search_edk},
++ {0,0,0,NULL}
++};
++
++
++static int
++match(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*/
++ head_len = tcph->doff * 4; /*get TCP-Header-Size*/
++ 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, head_len);
++ 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 int
++checkentry(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);
++
++
+diff -urN linux-2.4.29.old/net/ipv4/netfilter/Makefile linux-2.4.29/net/ipv4/netfilter/Makefile
+--- linux-2.4.29.old/net/ipv4/netfilter/Makefile 2005-03-12 00:40:38.000000000 +0100
++++ linux-2.4.29/net/ipv4/netfilter/Makefile 2005-03-12 00:42:57.000000000 +0100
+@@ -67,6 +67,7 @@
+ obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
+ obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
+ obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
++obj-$(CONFIG_IP_NF_MATCH_IPP2P) += ipt_ipp2p.o
+
+ obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
+ obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o