netfilter-2.6/patch-o-matic-ng/trunk: include/linux/netfilter_ipv4/ip_conntrack.h
include/linux/netf...
pluto
cvs at pld-linux.org
Thu Jul 28 09:32:50 CEST 2005
Author: pluto
Date: Thu Jul 28 09:32:44 2005
New Revision: 6238
Added:
netfilter-2.6/patch-o-matic-ng/trunk/include/linux/netfilter_ipv4/ip_conntrack_mms.h
netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/ip_conntrack_mms.c
netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/ip_nat_mms.c
Modified:
netfilter-2.6/patch-o-matic-ng/trunk/include/linux/netfilter_ipv4/ip_conntrack.h
netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/Kconfig
netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/Makefile
netfilter-2.6/patch-o-matic-ng/trunk/status
Log:
- mms-conntrack-nat.
Modified: netfilter-2.6/patch-o-matic-ng/trunk/include/linux/netfilter_ipv4/ip_conntrack.h
==============================================================================
--- netfilter-2.6/patch-o-matic-ng/trunk/include/linux/netfilter_ipv4/ip_conntrack.h (original)
+++ netfilter-2.6/patch-o-matic-ng/trunk/include/linux/netfilter_ipv4/ip_conntrack.h Thu Jul 28 09:32:44 2005
@@ -148,6 +148,7 @@
};
/* Add protocol helper include file here */
+#include <linux/netfilter_ipv4/ip_conntrack_mms.h>
#include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
#include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
#include <linux/netfilter_ipv4/ip_conntrack_irc.h>
@@ -155,6 +156,7 @@
/* per conntrack: application helper private data */
union ip_conntrack_help {
/* insert conntrack helper private data (master) here */
+ struct ip_ct_mms_master ct_mms_info;
struct ip_ct_ftp_master ct_ftp_info;
struct ip_ct_irc_master ct_irc_info;
};
Added: netfilter-2.6/patch-o-matic-ng/trunk/include/linux/netfilter_ipv4/ip_conntrack_mms.h
==============================================================================
--- (empty file)
+++ netfilter-2.6/patch-o-matic-ng/trunk/include/linux/netfilter_ipv4/ip_conntrack_mms.h Thu Jul 28 09:32:44 2005
@@ -0,0 +1,37 @@
+#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
+
+/* This structure is per expected connection */
+struct ip_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 ip_ct_mms_master {
+};
+
+struct ip_conntrack_expect;
+extern unsigned int (*ip_nat_mms_hook)(struct sk_buff **pskb,
+ enum ip_conntrack_info ctinfo,
+ const struct ip_ct_mms_expect *exp_mms_info,
+ struct ip_conntrack_expect *exp);
+#endif
+#endif /* _IP_CONNTRACK_MMS_H */
Modified: netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/Kconfig
==============================================================================
--- netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/Kconfig (original)
+++ netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/Kconfig Thu Jul 28 09:32:44 2005
@@ -716,5 +716,23 @@
IF unsure, say `N'.
+config IP_NF_NAT_MMS
+ tristate
+ depends on IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
+ default IP_NF_NAT if IP_NF_MMS=y
+ default m if IP_NF_MMS=m
+
+config IP_NF_MMS
+ tristate 'MMS protocol support'
+ depends on IP_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'.
+
endmenu
Modified: netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/Makefile
==============================================================================
--- netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/Makefile (original)
+++ netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/Makefile Thu Jul 28 09:32:44 2005
@@ -13,12 +13,14 @@
obj-$(CONFIG_IP_NF_CT_PROTO_SCTP) += ip_conntrack_proto_sctp.o
# connection tracking helpers
+obj-$(CONFIG_IP_NF_MMS) += ip_conntrack_mms.o
obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o
obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o
obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o
obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o
# NAT helpers
+obj-$(CONFIG_IP_NF_NAT_MMS) += ip_nat_mms.o
obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o
obj-$(CONFIG_IP_NF_NAT_TFTP) += ip_nat_tftp.o
obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o
Added: netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/ip_conntrack_mms.c
==============================================================================
--- (empty file)
+++ netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/ip_conntrack_mms.c Thu Jul 28 09:32:44 2005
@@ -0,0 +1,353 @@
+/* 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 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
+ *
+ * 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
+ */
+
+#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>
+
+
+#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 DECLARE_LOCK(mms_buffer_lock);
+
+unsigned int (*ip_nat_mms_hook)(struct sk_buff **pskb,
+ enum ip_conntrack_info ctinfo,
+ const struct ip_ct_mms_expect *exp_mms_info,
+ struct ip_conntrack_expect *exp);
+EXPORT_SYMBOL(ip_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("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;
+}
+
+
+/* FIXME: This should be in userspace. Later. */
+static int help(struct sk_buff **pskb,
+ struct ip_conntrack *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 ip_conntrack_expect *exp;
+ struct ip_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;
+ 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? */
+ th = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl*4,
+ sizeof(_tcph), &_tcph);
+ if (!th)
+ return NF_ACCEPT;
+
+ /* No data ? */
+ dataoff = (*pskb)->nh.iph->ihl*4 + th->doff*4;
+ datalen = (*pskb)->len - dataoff;
+ if (dataoff >= (*pskb)->len)
+ return NF_ACCEPT;
+
+ 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
+ * the client uses a server's IP address, the nat module should detect
+ * this and change this string accordingly to the DNATed address. This
+ * should probably be done by checking for an IP address, then storing
+ * it as a member of struct ip_ct_mms_expect and checking for it in
+ * ip_nat_mms...
+ */
+ 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())
+ /* FIXME: more verbose debugging ? */
+ printk(KERN_WARNING
+ "ip_conntrack_mms: Unable to parse "
+ "data payload\n");
+
+ 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
+ * */
+
+ DEBUGP("ip_conntrack_mms: tcph->seq = %u\n", tcph->seq);
+
+ exp = ip_conntrack_expect_alloc();
+ if (!exp) {
+ ret = NF_DROP;
+ goto out;
+ }
+
+ exp_mms_info->offset = (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,
+ { .tcp = { (__u16) ntohs(mms_port) } },
+ mms_proto } }
+ );
+ exp->mask = ((struct ip_conntrack_tuple)
+ { { 0xFFFFFFFF, { 0 } },
+ { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
+ exp->expectfn = NULL;
+ exp->master = ct;
+
+ if (ip_nat_mms_hook)
+ ret = ip_nat_mms_hook(pskb, ctinfo, exp_mms_info, exp);
+ else if (ip_conntrack_expect_related(exp) != 0) {
+ ip_conntrack_expect_free(exp);
+ ret = NF_DROP;
+ }
+ goto out;
+ }
+out:
+ UNLOCK_BH(&mms_buffer_lock);
+ return ret;
+}
+
+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 = 0xFF;
+ mms[i].max_expected = 1;
+ mms[i].timeout = 120;
+ 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);
Added: netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/ip_nat_mms.c
==============================================================================
--- (empty file)
+++ netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/ip_nat_mms.c Thu Jul 28 09:32:44 2005
@@ -0,0 +1,197 @@
+/* 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
+
+ */
+
+/* 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 <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>
+
+#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 ip_ct_mms_expect *ct_mms_info,
+ struct ip_conntrack_expect *expect)
+{
+ u_int32_t newip;
+ struct ip_conntrack *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];
+
+ 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;
+ expect->saved_proto.tcp.port = expect->tuple.dst.u.tcp.port;
+ expect->expectfn = ip_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 (ip_conntrack_expect_related(expect) == 0) {
+ DEBUGP("ip_nat_mms: mms_data_fixup: using port %d\n",
+ port);
+ break;
+ }
+ }
+
+ if (port == 0) {
+ ip_conntrack_expect_free(expect);
+ 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("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,
+ 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)
+{
+ ip_nat_mms_hook = NULL;
+ synchronize_net();
+}
+
+static int __init init(void)
+{
+ BUG_ON(ip_nat_mms_hook);
+ ip_nat_mms_hook = &mms_data_fixup;
+
+ return 0;
+}
+
+module_init(init);
+module_exit(fini);
Modified: netfilter-2.6/patch-o-matic-ng/trunk/status
==============================================================================
--- netfilter-2.6/patch-o-matic-ng/trunk/status (original)
+++ netfilter-2.6/patch-o-matic-ng/trunk/status Thu Jul 28 09:32:44 2005
@@ -4,7 +4,7 @@
CLASSIFY updated
CLUSTERIP updated
connlimit added
-ctevent-api 2005/07/27 updated
+conntrack-event-api 2005/07/27 updated
ctnetlink added (v0.60)
fuzzy added
geoip added
@@ -19,7 +19,7 @@
ipv4options added
IPV4OPTSSTRIP added
layer7 added (v1.2)
-mms-conntrack-nat added
+mms-conntrack-nat 2005/07/28 updated
NETMAP updated
nf_conntrack 2005/07/27 updated
nfnetlink added
More information about the pld-cvs-commit
mailing list