diff options
| -rw-r--r-- | target/linux/linux-2.4/config/brcm | 2 | ||||
| -rw-r--r-- | target/linux/linux-2.4/patches/generic/615-netfilter_nat_mms.patch | 739 | ||||
| -rw-r--r-- | target/linux/package/Config.in | 1 | 
3 files changed, 742 insertions, 0 deletions
| diff --git a/target/linux/linux-2.4/config/brcm b/target/linux/linux-2.4/config/brcm index 8bd18cf14..343b14c63 100644 --- a/target/linux/linux-2.4/config/brcm +++ b/target/linux/linux-2.4/config/brcm @@ -364,6 +364,7 @@ CONFIG_IP_NF_CT_PROTO_GRE=m  CONFIG_IP_NF_PPTP=m  CONFIG_IP_NF_SIP=m  CONFIG_IP_NF_H323=m +CONFIG_IP_NF_MMS=m  CONFIG_IP_NF_QUEUE=m  CONFIG_IP_NF_IPTABLES=y  CONFIG_IP_NF_MATCH_LIMIT=m @@ -414,6 +415,7 @@ CONFIG_IP_NF_TARGET_NETMAP=m  CONFIG_IP_NF_NAT_PPTP=m  CONFIG_IP_NF_NAT_SIP=m  CONFIG_IP_NF_NAT_H323=m +CONFIG_IP_NF_NAT_MMS=m  CONFIG_IP_NF_NAT_PROTO_GRE=m  CONFIG_IP_NF_NAT_AMANDA=m  CONFIG_IP_NF_NAT_SNMP_BASIC=m diff --git a/target/linux/linux-2.4/patches/generic/615-netfilter_nat_mms.patch b/target/linux/linux-2.4/patches/generic/615-netfilter_nat_mms.patch new file mode 100644 index 000000000..14e070a64 --- /dev/null +++ b/target/linux/linux-2.4/patches/generic/615-netfilter_nat_mms.patch @@ -0,0 +1,739 @@ +diff -urN linux-2.4.32/net/ipv4/netfilter/Config.in linux-2.4.32/net/ipv4/netfilter/Config.in +--- linux-2.4.32/net/ipv4/netfilter/Config.in	2005-12-12 16:29:01.000000000 +0100 ++++ linux-2.4.32/net/ipv4/netfilter/Config.in	2005-12-12 16:35:37.000000000 +0100 +@@ -17,6 +17,7 @@ +   dep_tristate '   PPTP protocol support' CONFIG_IP_NF_PPTP $CONFIG_IP_NF_CT_PROTO_GRE +   dep_tristate '  SIP protocol support' CONFIG_IP_NF_SIP $CONFIG_IP_NF_CONNTRACK +   dep_tristate '  H.323 (netmeeting) support' CONFIG_IP_NF_H323 $CONFIG_IP_NF_CONNTRACK ++  dep_tristate '  MMS protocol support' CONFIG_IP_NF_MMS $CONFIG_IP_NF_CONNTRACK + fi +  + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then +@@ -120,6 +121,13 @@ + 	  define_tristate CONFIG_IP_NF_NAT_H323 $CONFIG_IP_NF_NAT + 	fi +       fi ++      if [ "$CONFIG_IP_NF_MMS" = "m" ]; then ++	define_tristate CONFIG_IP_NF_NAT_MMS m ++      else ++	if [ "$CONFIG_IP_NF_MMS" = "y" ]; then ++	  define_tristate CONFIG_IP_NF_NAT_MMS $CONFIG_IP_NF_NAT ++	fi ++      fi +       if [ "$CONFIG_IP_NF_AMANDA" = "m" ]; then +         define_tristate CONFIG_IP_NF_NAT_AMANDA m +       else +diff -urN linux-2.4.32/net/ipv4/netfilter/Makefile linux-2.4.32/net/ipv4/netfilter/Makefile +--- linux-2.4.32/net/ipv4/netfilter/Makefile	2005-12-12 16:29:01.000000000 +0100 ++++ linux-2.4.32/net/ipv4/netfilter/Makefile	2005-12-12 16:36:26.000000000 +0100 +@@ -61,6 +61,10 @@ + ifdef CONFIG_IP_NF_NAT_H323 + 	export-objs += ip_conntrack_h323.o + endif ++obj-$(CONFIG_IP_NF_MMS) += ip_conntrack_mms.o ++ifdef CONFIG_IP_NF_NAT_MMS ++	export-objs += ip_conntrack_mms.o ++endif +  +  + # NAT helpers  +@@ -72,6 +76,7 @@ + obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o + obj-$(CONFIG_IP_NF_NAT_SIP) += ip_nat_sip.o + obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o ++obj-$(CONFIG_IP_NF_NAT_MMS) += ip_nat_mms.o +  + # generic IP tables  + obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o +diff -urN linux-2.4.32/net/ipv4/netfilter/ip_conntrack_mms.c linux-2.4.32/net/ipv4/netfilter/ip_conntrack_mms.c +--- linux-2.4.32/net/ipv4/netfilter/ip_conntrack_mms.c	1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32/net/ipv4/netfilter/ip_conntrack_mms.c	2005-12-12 16:32:54.000000000 +0100 +@@ -0,0 +1,292 @@ ++/* MMS extension for IP connection tracking ++ * (C) 2002 by Filip Sneppe <filip.sneppe@cronos.be> ++ * based on ip_conntrack_ftp.c and ip_conntrack_irc.c ++ * ++ * ip_conntrack_mms.c v0.3 2002-09-22 ++ * ++ *      This program is free software; you can redistribute it and/or ++ *      modify it under the terms of the GNU General Public License ++ *      as published by the Free Software Foundation; either version ++ *      2 of the License, or (at your option) any later version. ++ * ++ *      Module load syntax: ++ *      insmod ip_conntrack_mms.o ports=port1,port2,...port<MAX_PORTS> ++ * ++ *      Please give the ports of all MMS servers You wish to connect to. ++ *      If you don't specify ports, the default will be TCP port 1755. ++ * ++ *      More info on MMS protocol, firewalls and NAT: ++ *      http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/MMSFirewall.asp ++ *      http://www.microsoft.com/windows/windowsmedia/serve/firewall.asp ++ * ++ *      The SDP project people are reverse-engineering MMS: ++ *      http://get.to/sdp ++ */ ++ ++#include <linux/config.h> ++#include <linux/module.h> ++#include <linux/netfilter.h> ++#include <linux/ip.h> ++#include <linux/ctype.h> ++#include <net/checksum.h> ++#include <net/tcp.h> ++ ++#include <linux/netfilter_ipv4/lockhelp.h> ++#include <linux/netfilter_ipv4/ip_conntrack_helper.h> ++#include <linux/netfilter_ipv4/ip_conntrack_mms.h> ++ ++DECLARE_LOCK(ip_mms_lock); ++struct module *ip_conntrack_mms = THIS_MODULE; ++ ++#define MAX_PORTS 8 ++static int ports[MAX_PORTS]; ++static int ports_c; ++#ifdef MODULE_PARM ++MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); ++#endif ++ ++#define DEBUGP(format, args...) ++ ++#ifdef CONFIG_IP_NF_NAT_NEEDED ++EXPORT_SYMBOL(ip_mms_lock); ++#endif ++ ++MODULE_AUTHOR("Filip Sneppe <filip.sneppe@cronos.be>"); ++MODULE_DESCRIPTION("Microsoft Windows Media Services (MMS) connection tracking module"); ++MODULE_LICENSE("GPL"); ++ ++/* #define isdigit(c) (c >= '0' && c <= '9') */ ++ ++/* copied from drivers/usb/serial/io_edgeport.c - not perfect but will do the trick */ ++static void unicode_to_ascii (char *string, short *unicode, int unicode_size) ++{ ++	int i; ++	for (i = 0; i < unicode_size; ++i) { ++		string[i] = (char)(unicode[i]); ++	} ++	string[unicode_size] = 0x00; ++} ++ ++__inline static int atoi(char *s)  ++{ ++	int i=0; ++	while (isdigit(*s)) { ++		i = i*10 + *(s++) - '0'; ++	} ++	return i; ++} ++ ++/* convert ip address string like "192.168.0.10" to unsigned int */ ++__inline static u_int32_t asciiiptoi(char *s) ++{ ++	unsigned int i, j, k; ++ ++	for(i=k=0; k<3; ++k, ++s, i<<=8) { ++		i+=atoi(s); ++		for(j=0; (*(++s) != '.') && (j<3); ++j) ++			; ++	} ++	i+=atoi(s); ++	return ntohl(i); ++} ++ ++int parse_mms(const char *data,  ++	      const unsigned int datalen, ++	      u_int32_t *mms_ip, ++	      u_int16_t *mms_proto, ++	      u_int16_t *mms_port, ++	      char **mms_string_b, ++	      char **mms_string_e, ++	      char **mms_padding_e) ++{ ++	int unicode_size, i; ++	char tempstring[28];       /* "\\255.255.255.255\UDP\65535" */ ++	char getlengthstring[28]; ++	 ++	for(unicode_size=0;  ++	    (char) *(data+(MMS_SRV_UNICODE_STRING_OFFSET+unicode_size*2)) != (char)0; ++	    unicode_size++) ++		if ((unicode_size == 28) || (MMS_SRV_UNICODE_STRING_OFFSET+unicode_size*2 >= datalen))  ++			return -1; /* out of bounds - incomplete packet */ ++	 ++	unicode_to_ascii(tempstring, (short *)(data+MMS_SRV_UNICODE_STRING_OFFSET), unicode_size); ++	DEBUGP("ip_conntrack_mms: offset 60: %s\n", (const char *)(tempstring)); ++	 ++	/* IP address ? */ ++	*mms_ip = asciiiptoi(tempstring+2); ++	 ++	i=sprintf(getlengthstring, "%u.%u.%u.%u", HIPQUAD(*mms_ip)); ++		 ++	/* protocol ? */ ++	if(strncmp(tempstring+3+i, "TCP", 3)==0) ++		*mms_proto = IPPROTO_TCP; ++	else if(strncmp(tempstring+3+i, "UDP", 3)==0) ++		*mms_proto = IPPROTO_UDP; ++ ++	/* port ? */ ++	*mms_port = atoi(tempstring+7+i); ++ ++	/* we store a pointer to the beginning of the "\\a.b.c.d\proto\port"  ++	   unicode string, one to the end of the string, and one to the end  ++	   of the packet, since we must keep track of the number of bytes  ++	   between end of the unicode string and the end of packet (padding) */ ++	*mms_string_b  = (char *)(data + MMS_SRV_UNICODE_STRING_OFFSET); ++	*mms_string_e  = (char *)(data + MMS_SRV_UNICODE_STRING_OFFSET + unicode_size * 2); ++	*mms_padding_e = (char *)(data + datalen); /* looks funny, doesn't it */ ++	return 0; ++} ++ ++ ++static int help(const struct iphdr *iph, size_t len, ++		struct ip_conntrack *ct, ++		enum ip_conntrack_info ctinfo) ++{ ++	/* tcplen not negative guaranteed by ip_conntrack_tcp.c */ ++	struct tcphdr *tcph = (void *)iph + iph->ihl * 4; ++	const char *data = (const char *)tcph + tcph->doff * 4; ++	unsigned int tcplen = len - iph->ihl * 4; ++	unsigned int datalen = tcplen - tcph->doff * 4; ++	int dir = CTINFO2DIR(ctinfo); ++	struct ip_conntrack_expect expect, *exp = &expect;  ++	struct ip_ct_mms_expect *exp_mms_info = &exp->help.exp_mms_info; ++	 ++	u_int32_t mms_ip; ++	u_int16_t mms_proto; ++	char mms_proto_string[8]; ++	u_int16_t mms_port; ++	char *mms_string_b, *mms_string_e, *mms_padding_e; ++	      ++	/* Until there's been traffic both ways, don't look in packets. */ ++	if (ctinfo != IP_CT_ESTABLISHED ++	    && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) { ++		DEBUGP("ip_conntrack_mms: Conntrackinfo = %u\n", ctinfo); ++		return NF_ACCEPT; ++	} ++ ++	/* Not whole TCP header? */ ++	if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff*4) { ++		DEBUGP("ip_conntrack_mms: tcplen = %u\n", (unsigned)tcplen); ++		return NF_ACCEPT; ++	} ++ ++	/* Checksum invalid?  Ignore. */ ++	if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, ++	    csum_partial((char *)tcph, tcplen, 0))) { ++		DEBUGP("mms_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n", ++		       tcph, tcplen, NIPQUAD(iph->saddr), ++		       NIPQUAD(iph->daddr)); ++		return NF_ACCEPT; ++	} ++	 ++	/* Only look at packets with 0x00030002/196610 on bytes 36->39 of TCP payload */ ++	if( (MMS_SRV_MSG_OFFSET < datalen) &&  ++	    ((*(u32 *)(data+MMS_SRV_MSG_OFFSET)) == MMS_SRV_MSG_ID)) { ++		DEBUGP("ip_conntrack_mms: offset 37: %u %u %u %u, datalen:%u\n",  ++		       (u8)*(data+36), (u8)*(data+37),  ++		       (u8)*(data+38), (u8)*(data+39), ++		       datalen); ++		if(parse_mms(data, datalen, &mms_ip, &mms_proto, &mms_port, ++		             &mms_string_b, &mms_string_e, &mms_padding_e)) ++			if(net_ratelimit()) ++				printk(KERN_WARNING ++				       "ip_conntrack_mms: Unable to parse data payload\n"); ++ ++		memset(&expect, 0, sizeof(expect)); ++ ++		sprintf(mms_proto_string, "(%u)", mms_proto); ++		DEBUGP("ip_conntrack_mms: adding %s expectation %u.%u.%u.%u -> %u.%u.%u.%u:%u\n", ++		       mms_proto == IPPROTO_TCP ? "TCP" ++		       : mms_proto == IPPROTO_UDP ? "UDP":mms_proto_string, ++		       NIPQUAD(ct->tuplehash[!dir].tuple.src.ip), ++		       NIPQUAD(mms_ip), ++		       mms_port); ++		 ++		/* it's possible that the client will just ask the server to tunnel ++		   the stream over the same TCP session (from port 1755): there's  ++		   shouldn't be a need to add an expectation in that case, but it ++		   makes NAT packet mangling so much easier */ ++		LOCK_BH(&ip_mms_lock); ++ ++		DEBUGP("ip_conntrack_mms: tcph->seq = %u\n", tcph->seq); ++		 ++		exp->seq = ntohl(tcph->seq) + (mms_string_b - data); ++		exp_mms_info->len     = (mms_string_e  - mms_string_b); ++		exp_mms_info->padding = (mms_padding_e - mms_string_e); ++		exp_mms_info->port    = mms_port; ++		 ++		DEBUGP("ip_conntrack_mms: wrote info seq=%u (ofs=%u), len=%d, padding=%u\n", ++		       exp->seq, (mms_string_e - data), exp_mms_info->len, exp_mms_info->padding); ++		 ++		exp->tuple = ((struct ip_conntrack_tuple) ++		              { { ct->tuplehash[!dir].tuple.src.ip, { 0 } }, ++		              { mms_ip, ++		                { (__u16) ntohs(mms_port) }, ++		                mms_proto } } ++		             ); ++		exp->mask  = ((struct ip_conntrack_tuple) ++		             { { 0xFFFFFFFF, { 0 } }, ++		               { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); ++		exp->expectfn = NULL; ++		ip_conntrack_expect_related(ct, &expect); ++		UNLOCK_BH(&ip_mms_lock); ++	} ++ ++	return NF_ACCEPT; ++} ++ ++static struct ip_conntrack_helper mms[MAX_PORTS]; ++static char mms_names[MAX_PORTS][10]; ++ ++/* Not __exit: called from init() */ ++static void fini(void) ++{ ++	int i; ++	for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { ++		DEBUGP("ip_conntrack_mms: unregistering helper for port %d\n", ++				ports[i]); ++		ip_conntrack_helper_unregister(&mms[i]); ++	} ++} ++ ++static int __init init(void) ++{ ++	int i, ret; ++	char *tmpname; ++ ++	if (ports[0] == 0) ++		ports[0] = MMS_PORT; ++ ++	for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { ++		memset(&mms[i], 0, sizeof(struct ip_conntrack_helper)); ++		mms[i].tuple.src.u.tcp.port = htons(ports[i]); ++		mms[i].tuple.dst.protonum = IPPROTO_TCP; ++		mms[i].mask.src.u.tcp.port = 0xFFFF; ++		mms[i].mask.dst.protonum = 0xFFFF; ++		mms[i].max_expected = 1; ++		mms[i].timeout = 0; ++		mms[i].flags = IP_CT_HELPER_F_REUSE_EXPECT; ++		mms[i].me = THIS_MODULE; ++		mms[i].help = help; ++ ++		tmpname = &mms_names[i][0]; ++		if (ports[i] == MMS_PORT) ++			sprintf(tmpname, "mms"); ++		else ++			sprintf(tmpname, "mms-%d", ports[i]); ++		mms[i].name = tmpname; ++ ++		DEBUGP("ip_conntrack_mms: registering helper for port %d\n",  ++				ports[i]); ++		ret = ip_conntrack_helper_register(&mms[i]); ++ ++		if (ret) { ++			fini(); ++			return ret; ++		} ++		ports_c++; ++	} ++	return 0; ++} ++ ++module_init(init); ++module_exit(fini); +diff -urN linux-2.4.32/net/ipv4/netfilter/ip_nat_mms.c linux-2.4.32/net/ipv4/netfilter/ip_nat_mms.c +--- linux-2.4.32/net/ipv4/netfilter/ip_nat_mms.c	1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32/net/ipv4/netfilter/ip_nat_mms.c	2005-12-12 16:32:54.000000000 +0100 +@@ -0,0 +1,330 @@ ++/* MMS extension for TCP NAT alteration. ++ * (C) 2002 by Filip Sneppe <filip.sneppe@cronos.be> ++ * based on ip_nat_ftp.c and ip_nat_irc.c ++ * ++ * ip_nat_mms.c v0.3 2002-09-22 ++ * ++ *      This program is free software; you can redistribute it and/or ++ *      modify it under the terms of the GNU General Public License ++ *      as published by the Free Software Foundation; either version ++ *      2 of the License, or (at your option) any later version. ++ * ++ *      Module load syntax: ++ *      insmod ip_nat_mms.o ports=port1,port2,...port<MAX_PORTS> ++ * ++ *      Please give the ports of all MMS servers You wish to connect to. ++ *      If you don't specify ports, the default will be TCP port 1755. ++ * ++ *      More info on MMS protocol, firewalls and NAT: ++ *      http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/MMSFirewall.asp ++ *      http://www.microsoft.com/windows/windowsmedia/serve/firewall.asp ++ * ++ *      The SDP project people are reverse-engineering MMS: ++ *      http://get.to/sdp ++ */ ++ ++ ++#include <linux/module.h> ++#include <linux/netfilter_ipv4.h> ++#include <linux/ip.h> ++#include <linux/tcp.h> ++#include <net/tcp.h> ++#include <linux/netfilter_ipv4/ip_nat.h> ++#include <linux/netfilter_ipv4/ip_nat_helper.h> ++#include <linux/netfilter_ipv4/ip_nat_rule.h> ++#include <linux/netfilter_ipv4/ip_conntrack_mms.h> ++#include <linux/netfilter_ipv4/ip_conntrack_helper.h> ++ ++#define DEBUGP(format, args...) ++#define DUMP_BYTES(address, counter) ++ ++#define MAX_PORTS 8 ++static int ports[MAX_PORTS]; ++static int ports_c = 0; ++ ++#ifdef MODULE_PARM ++MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); ++#endif ++ ++MODULE_AUTHOR("Filip Sneppe <filip.sneppe@cronos.be>"); ++MODULE_DESCRIPTION("Microsoft Windows Media Services (MMS) NAT module"); ++MODULE_LICENSE("GPL"); ++ ++DECLARE_LOCK_EXTERN(ip_mms_lock); ++ ++ ++static int mms_data_fixup(const struct ip_ct_mms_expect *ct_mms_info, ++                          struct ip_conntrack *ct, ++                          struct sk_buff **pskb, ++                          enum ip_conntrack_info ctinfo, ++                          struct ip_conntrack_expect *expect) ++{ ++	u_int32_t newip; ++	struct ip_conntrack_tuple t; ++	struct iphdr *iph = (*pskb)->nh.iph; ++	struct tcphdr *tcph = (void *) iph + iph->ihl * 4; ++	char *data = (char *)tcph + tcph->doff * 4; ++	int i, j, k, port; ++	u_int16_t mms_proto; ++ ++	u_int32_t *mms_chunkLenLV    = (u_int32_t *)(data + MMS_SRV_CHUNKLENLV_OFFSET); ++	u_int32_t *mms_chunkLenLM    = (u_int32_t *)(data + MMS_SRV_CHUNKLENLM_OFFSET); ++	u_int32_t *mms_messageLength = (u_int32_t *)(data + MMS_SRV_MESSAGELENGTH_OFFSET); ++ ++	int zero_padding; ++ ++	char buffer[28];         /* "\\255.255.255.255\UDP\65635" * 2 (for unicode) */ ++	char unicode_buffer[75]; /* 27*2 (unicode) + 20 + 1 */ ++	char proto_string[6]; ++	 ++	MUST_BE_LOCKED(&ip_mms_lock); ++ ++	/* what was the protocol again ? */ ++	mms_proto = expect->tuple.dst.protonum; ++	sprintf(proto_string, "%u", mms_proto); ++	 ++	DEBUGP("ip_nat_mms: mms_data_fixup: info (seq %u + %u) in %u, proto %s\n", ++	       expect->seq, ct_mms_info->len, ntohl(tcph->seq), ++	       mms_proto == IPPROTO_UDP ? "UDP" ++	       : mms_proto == IPPROTO_TCP ? "TCP":proto_string); ++	 ++	newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; ++ ++	/* Alter conntrack's expectations. */ ++	t = expect->tuple; ++	t.dst.ip = newip; ++	for (port = ct_mms_info->port; port != 0; port++) { ++		t.dst.u.tcp.port = htons(port); ++		if (ip_conntrack_change_expect(expect, &t) == 0) { ++			DEBUGP("ip_nat_mms: mms_data_fixup: using port %d\n", port); ++			break; ++		} ++	} ++	 ++	if(port == 0) ++		return 0; ++ ++	sprintf(buffer, "\\\\%u.%u.%u.%u\\%s\\%u", ++	        NIPQUAD(newip), ++		expect->tuple.dst.protonum == IPPROTO_UDP ? "UDP" ++		: expect->tuple.dst.protonum == IPPROTO_TCP ? "TCP":proto_string, ++		port); ++	DEBUGP("ip_nat_mms: new unicode string=%s\n", buffer); ++	 ++	memset(unicode_buffer, 0, sizeof(char)*75); ++ ++	for (i=0; i<strlen(buffer); ++i) ++		*(unicode_buffer+i*2)=*(buffer+i); ++	 ++	DEBUGP("ip_nat_mms: mms_data_fixup: padding: %u len: %u\n", ct_mms_info->padding, ct_mms_info->len); ++	DEBUGP("ip_nat_mms: mms_data_fixup: offset: %u\n", MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len); ++	DUMP_BYTES(data+MMS_SRV_UNICODE_STRING_OFFSET, 60); ++	 ++	/* add end of packet to it */ ++	for (j=0; j<ct_mms_info->padding; ++j) { ++		DEBUGP("ip_nat_mms: mms_data_fixup: i=%u j=%u byte=%u\n",  ++		       i, j, (u8)*(data+MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len+j)); ++		*(unicode_buffer+i*2+j) = *(data+MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len+j); ++	} ++ ++	/* pad with zeroes at the end ? see explanation of weird math below */ ++	zero_padding = (8-(strlen(buffer)*2 + ct_mms_info->padding + 4)%8)%8; ++	for (k=0; k<zero_padding; ++k) ++		*(unicode_buffer+i*2+j+k)= (char)0; ++	 ++	DEBUGP("ip_nat_mms: mms_data_fixup: zero_padding = %u\n", zero_padding); ++	DEBUGP("ip_nat_mms: original=> chunkLenLV=%u chunkLenLM=%u messageLength=%u\n", ++	       *mms_chunkLenLV, *mms_chunkLenLM, *mms_messageLength); ++	 ++	/* explanation, before I forget what I did: ++	   strlen(buffer)*2 + ct_mms_info->padding + 4 must be divisable by 8; ++	   divide by 8 and add 3 to compute the mms_chunkLenLM field, ++	   but note that things may have to be padded with zeroes to align by 8  ++	   bytes, hence we add 7 and divide by 8 to get the correct length */  ++	*mms_chunkLenLM    = (u_int32_t) (3+(strlen(buffer)*2+ct_mms_info->padding+11)/8); ++	*mms_chunkLenLV    = *mms_chunkLenLM+2; ++	*mms_messageLength = *mms_chunkLenLV*8; ++	 ++	DEBUGP("ip_nat_mms: modified=> chunkLenLV=%u chunkLenLM=%u messageLength=%u\n", ++	       *mms_chunkLenLV, *mms_chunkLenLM, *mms_messageLength); ++	 ++	ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,  ++	                         expect->seq - ntohl(tcph->seq), ++	                         ct_mms_info->len + ct_mms_info->padding, unicode_buffer, ++	                         strlen(buffer)*2 + ct_mms_info->padding + zero_padding); ++	DUMP_BYTES(unicode_buffer, 60); ++	 ++	return 1; ++} ++ ++static unsigned int ++mms_nat_expected(struct sk_buff **pskb, ++                 unsigned int hooknum, ++                 struct ip_conntrack *ct, ++                 struct ip_nat_info *info) ++{ ++	struct ip_nat_multi_range mr; ++	u_int32_t newdstip, newsrcip, newip; ++ ++	struct ip_conntrack *master = master_ct(ct); ++ ++	IP_NF_ASSERT(info); ++	IP_NF_ASSERT(master); ++ ++	IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum)))); ++ ++	DEBUGP("ip_nat_mms: mms_nat_expected: We have a connection!\n"); ++ ++	newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; ++	newsrcip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; ++	DEBUGP("ip_nat_mms: mms_nat_expected: hook %s: newsrc->newdst %u.%u.%u.%u->%u.%u.%u.%u\n", ++	       hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" ++	       : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" ++	       : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???", ++	       NIPQUAD(newsrcip), NIPQUAD(newdstip)); ++ ++	if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) ++		newip = newsrcip; ++	else ++		newip = newdstip; ++ ++	DEBUGP("ip_nat_mms: mms_nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip)); ++ ++	mr.rangesize = 1; ++	/* We don't want to manip the per-protocol, just the IPs. */ ++	mr.range[0].flags = IP_NAT_RANGE_MAP_IPS; ++	mr.range[0].min_ip = mr.range[0].max_ip = newip; ++ ++	return ip_nat_setup_info(ct, &mr, hooknum); ++} ++ ++ ++static unsigned int mms_nat_help(struct ip_conntrack *ct, ++			 struct ip_conntrack_expect *exp, ++			 struct ip_nat_info *info, ++			 enum ip_conntrack_info ctinfo, ++			 unsigned int hooknum, ++			 struct sk_buff **pskb) ++{ ++	struct iphdr *iph = (*pskb)->nh.iph; ++	struct tcphdr *tcph = (void *) iph + iph->ihl * 4; ++	unsigned int datalen; ++	int dir; ++	struct ip_ct_mms_expect *ct_mms_info; ++ ++	if (!exp) ++		DEBUGP("ip_nat_mms: no exp!!"); ++ ++	ct_mms_info = &exp->help.exp_mms_info; ++	 ++	/* Only mangle things once: original direction in POST_ROUTING ++	   and reply direction on PRE_ROUTING. */ ++	dir = CTINFO2DIR(ctinfo); ++	if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) ++	    ||(hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) { ++		DEBUGP("ip_nat_mms: mms_nat_help: not touching dir %s at hook %s\n", ++		       dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", ++		       hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" ++		       : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" ++		       : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); ++		return NF_ACCEPT; ++	} ++	DEBUGP("ip_nat_mms: mms_nat_help: beyond not touching (dir %s at hook %s)\n", ++	       dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", ++	       hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" ++	       : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" ++	       : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); ++	 ++	datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4; ++	 ++	DEBUGP("ip_nat_mms: mms_nat_help: %u+%u=%u %u %u\n", exp->seq, ct_mms_info->len, ++	       exp->seq + ct_mms_info->len, ++	       ntohl(tcph->seq), ++	       ntohl(tcph->seq) + datalen); ++	 ++	LOCK_BH(&ip_mms_lock); ++	/* Check wether the whole IP/proto/port pattern is carried in the payload */ ++	if (between(exp->seq + ct_mms_info->len, ++	    ntohl(tcph->seq), ++	    ntohl(tcph->seq) + datalen)) { ++		if (!mms_data_fixup(ct_mms_info, ct, pskb, ctinfo, exp)) { ++			UNLOCK_BH(&ip_mms_lock); ++			return NF_DROP; ++		} ++	} else { ++		/* Half a match?  This means a partial retransmisison. ++		   It's a cracker being funky. */ ++		if (net_ratelimit()) { ++			printk("ip_nat_mms: partial packet %u/%u in %u/%u\n", ++			       exp->seq, ct_mms_info->len, ++			       ntohl(tcph->seq), ++			       ntohl(tcph->seq) + datalen); ++		} ++		UNLOCK_BH(&ip_mms_lock); ++		return NF_DROP; ++	} ++	UNLOCK_BH(&ip_mms_lock); ++	 ++	return NF_ACCEPT; ++} ++ ++static struct ip_nat_helper mms[MAX_PORTS]; ++static char mms_names[MAX_PORTS][10]; ++ ++/* Not __exit: called from init() */ ++static void fini(void) ++{ ++	int i; ++ ++	for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { ++		DEBUGP("ip_nat_mms: unregistering helper for port %d\n", ports[i]); ++		ip_nat_helper_unregister(&mms[i]); ++	} ++} ++ ++static int __init init(void) ++{ ++	int i, ret = 0; ++	char *tmpname; ++ ++	if (ports[0] == 0) ++		ports[0] = MMS_PORT; ++ ++	for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { ++ ++		memset(&mms[i], 0, sizeof(struct ip_nat_helper)); ++ ++		mms[i].tuple.dst.protonum = IPPROTO_TCP; ++		mms[i].tuple.src.u.tcp.port = htons(ports[i]); ++		mms[i].mask.dst.protonum = 0xFFFF; ++		mms[i].mask.src.u.tcp.port = 0xFFFF; ++		mms[i].help = mms_nat_help; ++		mms[i].me = THIS_MODULE; ++		mms[i].flags = 0; ++		mms[i].expect = mms_nat_expected; ++ ++		tmpname = &mms_names[i][0]; ++		if (ports[i] == MMS_PORT) ++			sprintf(tmpname, "mms"); ++		else ++			sprintf(tmpname, "mms-%d", i); ++		mms[i].name = tmpname; ++ ++		DEBUGP("ip_nat_mms: register helper for port %d\n", ++				ports[i]); ++		ret = ip_nat_helper_register(&mms[i]); ++ ++		if (ret) { ++			printk("ip_nat_mms: error registering " ++			       "helper for port %d\n", ports[i]); ++			fini(); ++			return ret; ++		} ++		ports_c++; ++	} ++ ++	return ret; ++} ++ ++module_init(init); ++module_exit(fini); +diff -urN linux-2.4.32/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.4.32/include/linux/netfilter_ipv4/ip_conntrack.h +--- linux-2.4.32/include/linux/netfilter_ipv4/ip_conntrack.h	2005-12-12 16:29:01.000000000 +0100 ++++ linux-2.4.32/include/linux/netfilter_ipv4/ip_conntrack.h	2005-12-12 16:34:09.000000000 +0100 +@@ -73,6 +73,7 @@ + #include <linux/netfilter_ipv4/ip_conntrack_pptp.h> + #include <linux/netfilter_ipv4/ip_conntrack_sip.h> + #include <linux/netfilter_ipv4/ip_conntrack_h323.h> ++#include <linux/netfilter_ipv4/ip_conntrack_mms.h> +  + /* per expectation: application helper private data */ + union ip_conntrack_expect_help { +@@ -83,6 +84,7 @@ + 	struct ip_ct_pptp_expect exp_pptp_info; + 	struct ip_ct_sip_expect exp_sip_info; + 	struct ip_ct_h225_expect exp_h225_info; ++	struct ip_ct_mms_expect exp_mms_info; +  + #ifdef CONFIG_IP_NF_NAT_NEEDED + 	union { +@@ -99,6 +101,7 @@ + 	struct ip_ct_pptp_master ct_pptp_info; + 	struct ip_ct_sip_master ct_sip_info; + 	struct ip_ct_h225_master ct_h225_info; ++	struct ip_ct_mms_master ct_mms_info; + }; +  + #ifdef CONFIG_IP_NF_NAT_NEEDED +diff -urN linux-2.4.32/include/linux/netfilter_ipv4/ip_conntrack_mms.h linux-2.4.32/include/linux/netfilter_ipv4/ip_conntrack_mms.h +--- linux-2.4.32/include/linux/netfilter_ipv4/ip_conntrack_mms.h	1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32/include/linux/netfilter_ipv4/ip_conntrack_mms.h	2005-12-12 16:32:54.000000000 +0100 +@@ -0,0 +1,31 @@ ++#ifndef _IP_CONNTRACK_MMS_H ++#define _IP_CONNTRACK_MMS_H ++/* MMS tracking. */ ++ ++#ifdef __KERNEL__ ++#include <linux/netfilter_ipv4/lockhelp.h> ++ ++DECLARE_LOCK_EXTERN(ip_mms_lock); ++ ++#define MMS_PORT                         1755 ++#define MMS_SRV_MSG_ID                   196610 ++ ++#define MMS_SRV_MSG_OFFSET               36 ++#define MMS_SRV_UNICODE_STRING_OFFSET    60 ++#define MMS_SRV_CHUNKLENLV_OFFSET        16 ++#define MMS_SRV_CHUNKLENLM_OFFSET        32 ++#define MMS_SRV_MESSAGELENGTH_OFFSET     8 ++#endif ++ ++/* This structure is per expected connection */ ++struct ip_ct_mms_expect { ++	u_int32_t len; ++	u_int32_t padding; ++	u_int16_t port; ++}; ++ ++/* This structure exists only once per master */ ++struct ip_ct_mms_master { ++}; ++ ++#endif /* _IP_CONNTRACK_MMS_H */ diff --git a/target/linux/package/Config.in b/target/linux/package/Config.in index b58301db9..42acc3dfa 100644 --- a/target/linux/package/Config.in +++ b/target/linux/package/Config.in @@ -1,5 +1,6 @@  source "target/linux/package/alsa/Config.in"  source "target/linux/package/diag/Config.in" +source "target/linux/package/eagle-usb/Config.in"  source "target/linux/package/fuse/Config.in"  source "target/linux/package/hostap/Config.in"  source "target/linux/package/madwifi/Config.in" | 
