SOURCES (LINUX_2_6_20): nf_conntrack_mms.patch (NEW) - adds conntr...

mguevara mguevara at pld-linux.org
Sat Mar 31 01:07:30 CEST 2007


Author: mguevara                     Date: Fri Mar 30 23:07:30 2007 GMT
Module: SOURCES                       Tag: LINUX_2_6_20
---- Log message:
- adds conntrack and nat support for mms protocol based on new nf_conntrack
- adds nf_conntrack_mms.ko and nf_nat_mms.ko modules
- based on ip_conntrack_mms

---- Files affected:
SOURCES:
   nf_conntrack_mms.patch (NONE -> 1.1.2.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/nf_conntrack_mms.patch
diff -u /dev/null SOURCES/nf_conntrack_mms.patch:1.1.2.1
--- /dev/null	Sat Mar 31 01:07:30 2007
+++ SOURCES/nf_conntrack_mms.patch	Sat Mar 31 01:07:24 2007
@@ -0,0 +1,736 @@
+diff -NurpP --minimal linux-2.6.20.mms-clean/include/linux/netfilter/nf_conntrack_mms.h linux-2.6.20.b/include/linux/netfilter/nf_conntrack_mms.h
+--- linux-2.6.20.mms-clean/include/linux/netfilter/nf_conntrack_mms.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20.b/include/linux/netfilter/nf_conntrack_mms.h	2007-03-30 15:41:47.000000000 +0200
+@@ -0,0 +1,36 @@
++#ifndef _IP_CONNTRACK_MMS_H
++#define _IP_CONNTRACK_MMS_H
++/* MMS tracking. */
++
++#ifdef __KERNEL__
++
++extern spinlock_t mms_buffer_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
++
++/* This structure is per expected connection */
++struct nf_ct_mms_expect {
++	u_int32_t offset;
++	u_int32_t len;
++	u_int32_t padding;
++	u_int16_t port;
++};
++
++/* This structure exists only once per master */
++struct nf_ct_mms_master {
++};
++
++struct nf_conntrack_expect;
++extern unsigned int (*nf_nat_mms_hook)(struct sk_buff **pskb,
++				       enum ip_conntrack_info ctinfo,
++				       const struct nf_ct_mms_expect *exp_mms_info,
++				       struct nf_conntrack_expect *exp);
++#endif
++#endif /* _IP_CONNTRACK_MMS_H */
+diff -NurpP --minimal linux-2.6.20.mms-clean/include/net/netfilter/nf_conntrack.h linux-2.6.20.b/include/net/netfilter/nf_conntrack.h
+--- linux-2.6.20.mms-clean/include/net/netfilter/nf_conntrack.h	2007-03-30 15:35:24.000000000 +0200
++++ linux-2.6.20.b/include/net/netfilter/nf_conntrack.h	2007-03-30 15:38:10.000000000 +0200
+@@ -45,6 +45,7 @@ union nf_conntrack_expect_proto {
+ #include <linux/netfilter/nf_conntrack_ftp.h>
+ #include <linux/netfilter/nf_conntrack_pptp.h>
+ #include <linux/netfilter/nf_conntrack_h323.h>
++#include <linux/netfilter/nf_conntrack_mms.h>
+ 
+ /* per conntrack: application helper private data */
+ union nf_conntrack_help {
+@@ -52,6 +53,7 @@ union nf_conntrack_help {
+ 	struct nf_ct_ftp_master ct_ftp_info;
+ 	struct nf_ct_pptp_master ct_pptp_info;
+ 	struct nf_ct_h323_master ct_h323_info;
++	struct nf_ct_mms_master ct_mms_info;
+ };
+ 
+ #include <linux/types.h>
+diff -NurpP --minimal linux-2.6.20.mms-clean/include/net/netfilter/nf_conntrack_mms.h linux-2.6.20.b/include/net/netfilter/nf_conntrack_mms.h
+--- linux-2.6.20.mms-clean/include/net/netfilter/nf_conntrack_mms.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20.b/include/net/netfilter/nf_conntrack_mms.h	2007-03-30 15:45:58.000000000 +0200
+@@ -0,0 +1,36 @@
++#ifndef _IP_CONNTRACK_MMS_H
++#define _IP_CONNTRACK_MMS_H
++/* MMS tracking. */
++
++#ifdef __KERNEL__
++
++extern spinlock_t mms_buffer_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
++
++/* This structure is per expected connection */
++struct nf_ct_mms_expect {
++	u_int32_t offset;
++	u_int32_t len;
++	u_int32_t padding;
++	u_int16_t port;
++};
++
++/* This structure exists only once per master */
++struct nf_ct_mms_master {
++};
++
++struct nf_conntrack_expect;
++extern unsigned int (*nf_nat_mms_hook)(struct sk_buff **pskb,
++				       enum ip_conntrack_info ctinfo,
++				       const struct nf_ct_mms_expect *exp_mms_info,
++				       struct nf_conntrack_expect *exp);
++#endif
++#endif /* _IP_CONNTRACK_MMS_H */
+diff -NurpP --minimal linux-2.6.20.mms-clean/net/ipv4/netfilter/Kconfig linux-2.6.20.b/net/ipv4/netfilter/Kconfig
+--- linux-2.6.20.mms-clean/net/ipv4/netfilter/Kconfig	2007-03-30 15:30:40.000000000 +0200
++++ linux-2.6.20.b/net/ipv4/netfilter/Kconfig	2007-03-30 15:38:10.000000000 +0200
+@@ -602,6 +602,11 @@ config NF_NAT_H323
+ 	depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+ 	default NF_NAT && NF_CONNTRACK_H323
+ 
++config NF_NAT_MMS
++        tristate
++        depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
++        default NF_NAT && NF_CONNTRACK_MMS
++
+ config IP_NF_NAT_SIP
+ 	tristate
+ 	depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
+diff -NurpP --minimal linux-2.6.20.mms-clean/net/ipv4/netfilter/Makefile linux-2.6.20.b/net/ipv4/netfilter/Makefile
+--- linux-2.6.20.mms-clean/net/ipv4/netfilter/Makefile	2007-03-30 15:30:39.000000000 +0200
++++ linux-2.6.20.b/net/ipv4/netfilter/Makefile	2007-03-30 15:38:10.000000000 +0200
+@@ -65,6 +65,7 @@ obj-$(CONFIG_IP_NF_NAT_SIP) += ip_nat_si
+ # NAT helpers (nf_conntrack)
+ obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
+ obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
++obj-$(CONFIG_NF_NAT_MMS) += nf_nat_mms.o
+ obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o
+ obj-$(CONFIG_NF_NAT_IRC) += nf_nat_irc.o
+ obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o
+diff -NurpP --minimal linux-2.6.20.mms-clean/net/ipv4/netfilter/nf_nat_mms.c linux-2.6.20.b/net/ipv4/netfilter/nf_nat_mms.c
+--- linux-2.6.20.mms-clean/net/ipv4/netfilter/nf_nat_mms.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20.b/net/ipv4/netfilter/nf_nat_mms.c	2007-03-30 15:46:04.000000000 +0200
+@@ -0,0 +1,196 @@
++/* MMS extension for TCP NAT alteration.
++ * (C) 2002 by Filip Sneppe <filip.sneppe at 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
++ *
++ *  2005-02-13: Harald Welte <laforge at netfilter.org>
++ *  	- port to 2.6.x
++ *  	- update to work with post 2.6.11 helper API changes
++ *
++ *  2007-03-30: Marek Guevara Braun <mguevara at pld-linux.org>
++ *	- port to nf_conntrack
++ */
++
++/* FIXME: issue with UDP & fragmentation with this URL:
++   http://www.cnn.com/video/world/2002/01/21/jb.shoe.bomb.cafe.cnn.low.asx
++   may be related to out-of-order first packets:
++   basically the expectation is set up correctly, then the server sends
++   a first UDP packet which is fragmented plus arrives out-of-order.
++   the MASQUERADING firewall with ip_nat_mms loaded responds with
++   an ICMP unreachable back to the server */
++
++#include <linux/module.h>
++#include <linux/netfilter_ipv4.h>
++#include <linux/ip.h>
++#include <linux/tcp.h>
++#include <net/tcp.h>
++#include <net/netfilter/nf_nat.h>
++#include <net/netfilter/nf_nat_helper.h>
++#include <net/netfilter/nf_nat_rule.h>
++#include <net/netfilter/nf_conntrack_helper.h>
++#include <net/netfilter/nf_conntrack_expect.h>
++#include <linux/netfilter/nf_conntrack_mms.h>
++
++#if 0
++#define DEBUGP printk
++#define DUMP_BYTES(address, counter)                                \
++({                                                                  \
++	int temp_counter;                                           \
++	for(temp_counter=0; temp_counter<counter; ++temp_counter) { \
++		DEBUGP("%u ", (u8)*(address+temp_counter));         \
++	};                                                          \
++	DEBUGP("\n");                                               \
++})
++#else
++#define DEBUGP(format, args...)
++#define DUMP_BYTES(address, counter)
++#endif
++
++MODULE_AUTHOR("Filip Sneppe <filip.sneppe at cronos.be>");
++MODULE_DESCRIPTION("Microsoft Windows Media Services (MMS) NAT module");
++MODULE_LICENSE("GPL");
++
++static unsigned int mms_data_fixup(struct sk_buff **pskb,
++                          enum ip_conntrack_info ctinfo,
++			  const struct nf_ct_mms_expect *ct_mms_info,
++                          struct nf_conntrack_expect *expect)
++{
++	u_int32_t newip;
++	struct nf_conn *ct = expect->master;
++	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];
++
++	/* what was the protocol again ? */
++	mms_proto = expect->tuple.dst.protonum;
++	sprintf(proto_string, "%u", mms_proto);
++
++	DEBUGP("nf_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.u3.ip;
++	expect->saved_proto.tcp.port = expect->tuple.dst.u.tcp.port;
++	expect->expectfn = nf_nat_follow_master;
++
++	/* Alter conntrack's expectations. */
++	for (port = ct_mms_info->port; port != 0; port++) {
++		expect->tuple.dst.u.tcp.port = htons(port);
++		if (nf_conntrack_expect_related(expect) == 0) {
++			DEBUGP("nf_nat_mms: mms_data_fixup: using port %d\n",
++				port);
++			break;
++		}
++	}
++
++	if (port == 0)
++		return NF_DROP;
++
++	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("nf_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("nf_nat_mms: mms_data_fixup: padding: %u len: %u\n",
++		ct_mms_info->padding, ct_mms_info->len);
++	DEBUGP("nf_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("nf_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("nf_nat_mms: mms_data_fixup: zero_padding = %u\n", zero_padding);
++	DEBUGP("nf_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("nf_nat_mms: modified=> chunkLenLV=%u chunkLenLM=%u"
++	       " messageLength=%u\n", *mms_chunkLenLV, *mms_chunkLenLM,
++	       *mms_messageLength);
++
++	nf_nat_mangle_tcp_packet(pskb, ct, ctinfo,
++	                         ct_mms_info->offset,
++	                         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 NF_ACCEPT;
++}
++
++static void __exit fini(void)
++{
++	nf_nat_mms_hook = NULL;
++	synchronize_net();
++}
++
++static int __init init(void)
++{
++	BUG_ON(nf_nat_mms_hook);
++	nf_nat_mms_hook = &mms_data_fixup;
++
++	return 0;
++}
++
++module_init(init);
++module_exit(fini);
+diff -NurpP --minimal linux-2.6.20.mms-clean/net/netfilter/Kconfig linux-2.6.20.b/net/netfilter/Kconfig
+--- linux-2.6.20.mms-clean/net/netfilter/Kconfig	2007-03-30 15:31:01.000000000 +0200
++++ linux-2.6.20.b/net/netfilter/Kconfig	2007-03-30 15:38:10.000000000 +0200
+@@ -258,6 +258,18 @@ config NF_CONNTRACK_TFTP
+ 
+ 	  To compile it as a module, choose M here.  If unsure, say N.
+ 
++config NF_CONNTRACK_MMS
++	tristate 'MMS protocol support'
++	depends on NF_CONNTRACK
++	help
++	  Tracking MMS (Microsoft Windows Media Services) connections
++	  could be problematic if random ports are used to send the
++	  streaming content. This option allows users to track streaming
++	  connections over random UDP or TCP ports.
++
++	  If you want to compile it as a module, say M here and read
++	  <file:Documentation/modules.txt>.  If unsure, say `Y'.
++	
+ config NF_CT_NETLINK
+ 	tristate 'Connection tracking netlink interface (EXPERIMENTAL)'
+ 	depends on EXPERIMENTAL && NF_CONNTRACK && NETFILTER_NETLINK
+diff -NurpP --minimal linux-2.6.20.mms-clean/net/netfilter/Makefile linux-2.6.20.b/net/netfilter/Makefile
+--- linux-2.6.20.mms-clean/net/netfilter/Makefile	2007-03-30 15:31:01.000000000 +0200
++++ linux-2.6.20.b/net/netfilter/Makefile	2007-03-30 15:38:10.000000000 +0200
+@@ -26,6 +26,7 @@ nf_conntrack_h323-objs := nf_conntrack_h
+ obj-$(CONFIG_NF_CONNTRACK_AMANDA) += nf_conntrack_amanda.o
+ obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o
+ obj-$(CONFIG_NF_CONNTRACK_H323) += nf_conntrack_h323.o
++obj-$(CONFIG_NF_CONNTRACK_MMS) += nf_conntrack_mms.o
+ obj-$(CONFIG_NF_CONNTRACK_IRC) += nf_conntrack_irc.o
+ obj-$(CONFIG_NF_CONNTRACK_NETBIOS_NS) += nf_conntrack_netbios_ns.o
+ obj-$(CONFIG_NF_CONNTRACK_PPTP) += nf_conntrack_pptp.o
+diff -NurpP --minimal linux-2.6.20.mms-clean/net/netfilter/nf_conntrack_mms.c linux-2.6.20.b/net/netfilter/nf_conntrack_mms.c
+--- linux-2.6.20.mms-clean/net/netfilter/nf_conntrack_mms.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20.b/net/netfilter/nf_conntrack_mms.c	2007-03-30 15:45:54.000000000 +0200
+@@ -0,0 +1,374 @@
++/* MMS extension for IP connection tracking
++ * (C) 2002 by Filip Sneppe <filip.sneppe at 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 nf_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
++ *
++ *  2005-02-13: Harald Welte <laforge at netfilter.org>
++ *  	- port to 2.6.x
++ *  	- update to work with post 2.6.11 helper API changes
++ *
++ *  2007-03-30: Marek Guevara Braun <mguevara at pld-linux.org>
++ *	- port to nf_conntrack
++ */
++
++
++#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 <net/netfilter/nf_conntrack.h>
++#include <net/netfilter/nf_conntrack_helper.h>
++#include <net/netfilter/nf_conntrack_expect.h>
++#include <linux/netfilter/nf_conntrack_mms.h>
++
++#define MAX_PORTS 8
++static int ports[MAX_PORTS];
++static int ports_c;
++module_param_array(ports, int, &ports_c, 0400);
++MODULE_PARM_DESC(ports, "port numbers of MMS");
++
++static char mms_buffer[65536];
++static DEFINE_SPINLOCK(mms_buffer_lock);
++
++unsigned int (*nf_nat_mms_hook)(struct sk_buff **pskb,
++				enum ip_conntrack_info ctinfo,
++				const struct nf_ct_mms_expect *exp_mms_info,
++				struct nf_conntrack_expect *exp);
++EXPORT_SYMBOL(nf_nat_mms_hook);
++
++#if 0
++#define DEBUGP printk
++#else
++#define DEBUGP(format, args...)
++#endif
++
++MODULE_AUTHOR("Filip Sneppe <filip.sneppe at 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("nf_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;
++}
++
++
++/* FIXME: This should be in userspace.  Later. */
++static int help(struct sk_buff **pskb,
++		unsigned int protoff,
++		struct nf_conn *ct,
++		enum ip_conntrack_info ctinfo)
++{
++	int ret = NF_DROP;
++	struct tcphdr _tcph, *th;
++	char *data, *mb_ptr;
++	unsigned int datalen, dataoff;
++
++
++	//struct tcphdr *tcph = (void *)iph + iph->ihl * 4;
++	//unsigned int tcplen = len - iph->ihl * 4;
++	//unsigned int datalen = tcplen - tcph->doff * 4;
++	int dir = CTINFO2DIR(ctinfo);
++	struct nf_conntrack_expect *exp;
++	struct nf_conntrack_tuple *tuple;
++	struct nf_ct_mms_expect _emmi, *exp_mms_info = &_emmi;
++
++	u_int32_t mms_ip;
++	u_int16_t mms_proto;
++	char mms_proto_string[8];
++	u_int16_t mms_port;
++	__be16 port;
++	char *mms_string_b, *mms_string_e, *mms_padding_e;
++	typeof(nf_nat_mms_hook) nf_nat_mms;
++
++	/* 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("nf_conntrack_mms: Conntrackinfo = %u\n", ctinfo);
++		return NF_ACCEPT;
++	}
++
++	/* Not whole TCP header? */
++	th = skb_header_pointer(*pskb, protoff, sizeof(_tcph), &_tcph);
++	if (th == NULL)
++		return NF_ACCEPT;
++
++	/* No data ? */
++	dataoff = protoff + th->doff*4;
++	if (dataoff >= (*pskb)->len)
++		return NF_ACCEPT;
++
++	datalen = (*pskb)->len - dataoff;
++	DEBUGP("nf_conntrack_mms: datalen:%u\n", datalen);
++
++	spin_lock_bh(&mms_buffer_lock);
++	mb_ptr = skb_header_pointer(*pskb, dataoff,
++				    (*pskb)->len - dataoff, mms_buffer);
++	BUG_ON(mb_ptr == NULL);
++
++	data = mb_ptr;
++
++#if 0
++	/* Checksum invalid?  Ignore. */
++	/* FIXME: Source route IP option packets --RR */
++	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;
++	}
++#endif
++
++	/* Only look at packets with 0x00030002/196610 on bytes 36->39 of TCP
++	 * payload */
++
++	/* FIXME: There is an issue with only looking at this packet: before
++	 * this packet, the client has already sent a packet to the server with
++	 * the server's hostname according to the client (think of it as the
++	 * "Host: " header in HTTP/1.1). The server will break the connection
++	 * if this doesn't correspond to its own host header. The client can
++	 * also connect to an IP address; if it's the server's IP address, it
++	 * will not break the connection. When doing DNAT on a connection where
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list