[netfilter-cvslog] r3601 - in trunk/patch-o-matic-ng/h323-conntrack-nat: . linux-2.6 linux-2.6/net/ipv4/netfilter

kadlec at netfilter.org kadlec at netfilter.org
Wed Jan 19 15:18:49 CET 2005


Author: kadlec at netfilter.org
Date: 2005-01-19 15:18:49 +0100 (Wed, 19 Jan 2005)
New Revision: 3601

Added:
   trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6/
Removed:
   trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6/Documentation/
Modified:
   trunk/patch-o-matic-ng/h323-conntrack-nat/info
   trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6/net/ipv4/netfilter/Makefile.ladd
   trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_conntrack_h323.c
   trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_nat_h323.c
Log:
Max Kellermann's 2.6 port added


Modified: trunk/patch-o-matic-ng/h323-conntrack-nat/info
===================================================================
--- trunk/patch-o-matic-ng/h323-conntrack-nat/info	2005-01-16 19:59:42 UTC (rev 3600)
+++ trunk/patch-o-matic-ng/h323-conntrack-nat/info	2005-01-19 14:18:49 UTC (rev 3601)
@@ -1,4 +1,4 @@
-Author: Jozsef Kadlecsik <kadlec at blackhole.kfki.hu>
+Author: Jozsef Kadlecsik <kadlec at blackhole.kfki.hu>, Max Kellermann <max at duempel.org>
 Status: Alpha
 Repository: extra
-Requires: linux < 2.6.0
+Requires: linux-2.6 >= 2.6.11

Copied: trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6 (from rev 3600, trunk/patch-o-matic-ng/h323-conntrack-nat/linux)

Modified: trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6/net/ipv4/netfilter/Makefile.ladd
===================================================================
--- trunk/patch-o-matic-ng/h323-conntrack-nat/linux/net/ipv4/netfilter/Makefile.ladd	2005-01-16 19:59:42 UTC (rev 3600)
+++ trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6/net/ipv4/netfilter/Makefile.ladd	2005-01-19 14:18:49 UTC (rev 3601)
@@ -2,8 +2,5 @@
  
 # H.323 support
 obj-$(CONFIG_IP_NF_H323) += ip_conntrack_h323.o
-ifdef CONFIG_IP_NF_H323
-	export-objs += ip_conntrack_h323.o
-endif
 obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o
 

Modified: trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_conntrack_h323.c
===================================================================
--- trunk/patch-o-matic-ng/h323-conntrack-nat/linux/net/ipv4/netfilter/ip_conntrack_h323.c	2005-01-16 19:59:42 UTC (rev 3600)
+++ trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_conntrack_h323.c	2005-01-19 14:18:49 UTC (rev 3601)
@@ -1,6 +1,7 @@
-/* 
- * H.323 'brute force' extension for H.323 connection tracking. 
+/*
+ * H.323 'brute force' extension for H.323 connection tracking.
  * Jozsef Kadlecsik <kadlec at blackhole.kfki.hu>
+ * (c) 2005 Max Kellermann <max at duempel.org>
  *
  * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project.
  * (http://www.coritel.it/projects/sofia/nat/)
@@ -26,6 +27,10 @@
 MODULE_DESCRIPTION("H.323 'brute force' connection tracking module");
 MODULE_LICENSE("GPL");
 
+/* This is slow, but it's simple. --RR */
+static char h323_buffer[65536];
+static DECLARE_LOCK(h323_buffer_lock);
+
 DECLARE_LOCK(ip_h323_lock);
 struct module *ip_conntrack_h323 = THIS_MODULE;
 
@@ -36,31 +41,24 @@
 #endif
 
 /* FIXME: This should be in userspace.  Later. */
-static int h245_help(const struct iphdr *iph, size_t len,
+static int h245_help(struct sk_buff *skb,
 		     struct ip_conntrack *ct,
 		     enum ip_conntrack_info ctinfo)
 {
-	struct tcphdr *tcph = (void *)iph + iph->ihl * 4;
-	unsigned char *data = (unsigned char *) tcph + tcph->doff * 4;
+	struct iphdr *iph = skb->nh.iph;
+	struct tcphdr _tcph, *tcph;
+	unsigned char *data;
 	unsigned char *data_limit;
-	u_int32_t tcplen = len - iph->ihl * 4;
-	u_int32_t datalen = tcplen - tcph->doff * 4;
+	unsigned dataoff, datalen;
 	int dir = CTINFO2DIR(ctinfo);
 	struct ip_ct_h225_master *info = &ct->help.ct_h225_info;
-	struct ip_conntrack_expect expect, *exp = &expect;
-	struct ip_ct_h225_expect *exp_info = &exp->help.exp_h225_info;
+	struct ip_conntrack_expect *exp;
+	struct ip_ct_h225_expect *exp_info;
 	u_int16_t data_port;
 	u_int32_t data_ip;
 	unsigned int i;
+	int ret;
 
-	DEBUGP("ct_h245_help: help entered %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
-		NIPQUAD(iph->saddr), ntohs(tcph->source),
-		NIPQUAD(iph->daddr), ntohs(tcph->dest));
-
-	/* Can't track connections formed before we registered */
-	if (!info)
-		return NF_ACCEPT;
-		
 	/* 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) {
@@ -68,34 +66,49 @@
 		return NF_ACCEPT;
 	}
 
-	/* Not whole TCP header or too short packet? */
-	if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4 + 5) {
-		DEBUGP("ct_h245_help: tcplen = %u\n", (unsigned)tcplen);
+	tcph = skb_header_pointer(skb, skb->nh.iph->ihl*4,
+				  sizeof(_tcph), &_tcph);
+	if (tcph == NULL)
 		return NF_ACCEPT;
-	}
 
-	/* 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("ct_h245_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n",
-		       tcph, tcplen, NIPQUAD(iph->saddr),
-		       NIPQUAD(iph->daddr));
+	DEBUGP("ct_h245_help: help entered %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
+		NIPQUAD(iph->saddr), ntohs(tcph->source),
+		NIPQUAD(iph->daddr), ntohs(tcph->dest));
+
+	dataoff = skb->nh.iph->ihl*4 + tcph->doff*4;
+	/* No data? */
+	if (dataoff >= skb->len) {
+		DEBUGP("ct_h245_help: skblen = %u\n", skb->len);
 		return NF_ACCEPT;
 	}
+	datalen = skb->len - dataoff;
 
-	data_limit = (unsigned char *) data + datalen;
+	LOCK_BH(&h323_buffer_lock);
+	data = skb_header_pointer(skb, dataoff,
+				  datalen, h323_buffer);
+	BUG_ON(data == NULL);
+
+	data_limit = data + datalen - 6;
 	/* bytes: 0123   45
 	          ipadrr port */
-	for (i = 0; data < (data_limit - 5); data++, i++) {
+	for (i = 0; data <= data_limit; data++, i++) {
 		data_ip = *((u_int32_t *)data);
 		if (data_ip == iph->saddr) {
 			data_port = *((u_int16_t *)(data + 4));
-			memset(&expect, 0, sizeof(expect));
+
 			/* update the H.225 info */
 			DEBUGP("ct_h245_help: new RTCP/RTP requested %u.%u.%u.%u:->%u.%u.%u.%u:%u\n",
 				NIPQUAD(ct->tuplehash[!dir].tuple.src.ip),
 				NIPQUAD(iph->saddr), ntohs(data_port));
+
+			exp = ip_conntrack_expect_alloc();
+			if (exp == NULL) {
+				ret = NF_ACCEPT;
+				goto out;
+			}
+
+			exp_info = &exp->help.exp_h225_info;
+
 			LOCK_BH(&ip_h323_lock);
 			info->is_h225 = H225_PORT + 1;
 			exp_info->port = data_port;
@@ -103,7 +116,7 @@
 			exp_info->offset = i;
 
 			exp->seq = ntohl(tcph->seq) + i;
-		    
+
 			exp->tuple = ((struct ip_conntrack_tuple)
 				{ { ct->tuplehash[!dir].tuple.src.ip,
 				    { 0 } },
@@ -113,34 +126,33 @@
 			exp->mask = ((struct ip_conntrack_tuple)
 				{ { 0xFFFFFFFF, { 0 } },
 				  { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFFFF }});
-	
+
 			exp->expectfn = NULL;
-			
+
 			/* Ignore failure; should only happen with NAT */
-			ip_conntrack_expect_related(ct, exp);
+			ip_conntrack_expect_related(exp, ct);
 
 			UNLOCK_BH(&ip_h323_lock);
 		}
 	}
 
-	return NF_ACCEPT;
-
+	ret = NF_ACCEPT;
+ out:
+	UNLOCK_BH(&h323_buffer_lock);
+	return ret;
 }
 
 /* H.245 helper is not registered! */
-static struct ip_conntrack_helper h245 = 
-	{ { NULL, NULL },
-          "H.245",				/* name */
-          IP_CT_HELPER_F_REUSE_EXPECT,		/* flags */
-          NULL,					/* module */
-          8,					/* max_ expected */
-          240,					/* timeout */
-          { { 0, { 0 } },			/* tuple */
-            { 0, { 0 }, IPPROTO_TCP } },
-          { { 0, { 0xFFFF } },			/* mask */
-            { 0, { 0 }, 0xFFFF } },
-          h245_help				/* helper */
-	};
+static struct ip_conntrack_helper h245 = {
+	.name = "H.245",
+	.flags = IP_CT_HELPER_F_REUSE_EXPECT,
+	.max_expected = 8,
+	.timeout = 240,
+	.tuple = { .dst = { .protonum = IPPROTO_TCP } },
+	.mask = { .src = { .u = { 0xFFFF } },
+		  .dst = { .protonum = 0xFFFF } },
+	.help = h245_help
+};
 
 static int h225_expect(struct ip_conntrack *ct)
 {
@@ -148,36 +160,29 @@
 	ct->helper = &h245;
 	DEBUGP("h225_expect: helper for %p added\n", ct);
 	WRITE_UNLOCK(&ip_conntrack_lock);
-	
+
 	return NF_ACCEPT;	/* unused */
 }
 
 /* FIXME: This should be in userspace.  Later. */
-static int h225_help(const struct iphdr *iph, size_t len,
+static int h225_help(struct sk_buff *skb,
 		     struct ip_conntrack *ct,
 		     enum ip_conntrack_info ctinfo)
 {
-	struct tcphdr *tcph = (void *)iph + iph->ihl * 4;
-	unsigned char *data = (unsigned char *) tcph + tcph->doff * 4;
+	struct iphdr *iph = skb->nh.iph;
+	struct tcphdr _tcph, *tcph;
+	unsigned char *data;
 	unsigned char *data_limit;
-	u_int32_t tcplen = len - iph->ihl * 4;
-	u_int32_t datalen = tcplen - tcph->doff * 4;
+	unsigned dataoff, datalen;
 	int dir = CTINFO2DIR(ctinfo);
 	struct ip_ct_h225_master *info = &ct->help.ct_h225_info;
-	struct ip_conntrack_expect expect, *exp = &expect;
-	struct ip_ct_h225_expect *exp_info = &exp->help.exp_h225_info;
+	struct ip_conntrack_expect *exp;
+	struct ip_ct_h225_expect *exp_info;
 	u_int16_t data_port;
 	u_int32_t data_ip;
 	unsigned int i;
-	
-	DEBUGP("ct_h225_help: help entered %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
-		NIPQUAD(iph->saddr), ntohs(tcph->source),
-		NIPQUAD(iph->daddr), ntohs(tcph->dest));
+	int ret;
 
-	/* Can't track connections formed before we registered */
-	if (!info)
-		return NF_ACCEPT;
-
 	/* 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) {
@@ -185,26 +190,32 @@
 		return NF_ACCEPT;
 	}
 
-	/* Not whole TCP header or too short packet? */
-	if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4 + 5) {
-		DEBUGP("ct_h225_help: tcplen = %u\n", (unsigned)tcplen);
+	tcph = skb_header_pointer(skb, skb->nh.iph->ihl*4,
+				  sizeof(_tcph), &_tcph);
+	if (tcph == NULL)
 		return NF_ACCEPT;
-	}
 
-	/* 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("ct_h225_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n",
-		       tcph, tcplen, NIPQUAD(iph->saddr),
-		       NIPQUAD(iph->daddr));
+	DEBUGP("ct_h225_help: help entered %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
+		NIPQUAD(iph->saddr), ntohs(tcph->source),
+		NIPQUAD(iph->daddr), ntohs(tcph->dest));
+
+	dataoff = skb->nh.iph->ihl*4 + tcph->doff*4;
+	/* No data? */
+	if (dataoff >= skb->len) {
+		DEBUGP("ct_h225_help: skblen = %u\n", skb->len);
 		return NF_ACCEPT;
 	}
-	
-	data_limit = (unsigned char *) data + datalen;
+	datalen = skb->len - dataoff;
+
+	LOCK_BH(&h323_buffer_lock);
+	data = skb_header_pointer(skb, dataoff,
+				  datalen, h323_buffer);
+	BUG_ON(data == NULL);
+
+	data_limit = data + datalen - 6;
 	/* bytes: 0123   45
 	          ipadrr port */
-	for (i = 0; data < (data_limit - 5); data++, i++) {
+	for (i = 0; data <= data_limit; data++, i++) {
 		data_ip = *((u_int32_t *)data);
 		if (data_ip == iph->saddr) {
 			data_port = *((u_int16_t *)(data + 4));
@@ -222,9 +233,15 @@
 				UNLOCK_BH(&ip_h323_lock);
 #endif
 			} else {
-				memset(&expect, 0, sizeof(expect));
+				/* update the H.225 info */
+				exp = ip_conntrack_expect_alloc();
+				if (exp == NULL) {
+					ret = NF_ACCEPT;
+					goto out;
+				}
 
-				/* update the H.225 info */
+				exp_info = &exp->help.exp_h225_info;
+
 				LOCK_BH(&ip_h323_lock);
 				info->is_h225 = H225_PORT;
 				exp_info->port = data_port;
@@ -242,18 +259,18 @@
 				exp->mask = ((struct ip_conntrack_tuple)
 					{ { 0xFFFFFFFF, { 0 } },
 					  { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFFFF }});
-	
+
 				exp->expectfn = h225_expect;
-				
+
 				/* Ignore failure */
-				ip_conntrack_expect_related(ct, exp);
+				ip_conntrack_expect_related(exp, ct);
 
 				DEBUGP("ct_h225_help: new H.245 requested %u.%u.%u.%u->%u.%u.%u.%u:%u\n",
 					NIPQUAD(ct->tuplehash[!dir].tuple.src.ip),
 					NIPQUAD(iph->saddr), ntohs(data_port));
 
 				UNLOCK_BH(&ip_h323_lock);
-                	}  
+			}
 #ifdef CONFIG_IP_NF_NAT_NEEDED
 		} else if (data_ip == iph->daddr) {
 			data_port = *((u_int16_t *)(data + 4));
@@ -273,23 +290,24 @@
 		}
 	}
 
-	return NF_ACCEPT;
-
+	ret = NF_ACCEPT;
+ out:
+	UNLOCK_BH(&h323_buffer_lock);
+	return ret;
 }
 
-static struct ip_conntrack_helper h225 = 
-	{ { NULL, NULL },
-	  "H.225",					/* name */
-	  IP_CT_HELPER_F_REUSE_EXPECT,			/* flags */
-	  THIS_MODULE,					/* module */
-	  2,						/* max_expected */
-	  240,						/* timeout */
-	  { { 0, { __constant_htons(H225_PORT) } },	/* tuple */
-	    { 0, { 0 }, IPPROTO_TCP } },
-	  { { 0, { 0xFFFF } },				/* mask */
-	    { 0, { 0 }, 0xFFFF } },
-	  h225_help					/* helper */
-	};
+static struct ip_conntrack_helper h225 = {
+	.name = "H.225",
+	.flags = IP_CT_HELPER_F_REUSE_EXPECT,
+	.me = THIS_MODULE,
+	.max_expected = 2,
+	.timeout = 240,
+	.tuple = { .src = { .u = { __constant_htons(H225_PORT) } },
+		   .dst = { .protonum = IPPROTO_TCP } },
+	.mask = { .src = { .u = { 0xFFFF } },
+		  .dst = { .protonum = 0xFFFF } },
+	.help = h225_help
+};
 
 static int __init init(void)
 {
@@ -298,11 +316,13 @@
 
 static void __exit fini(void)
 {
-	/* Unregister H.225 helper */	
+	/* Unregister H.225 helper */
 	ip_conntrack_helper_unregister(&h225);
 }
 
 EXPORT_SYMBOL(ip_h323_lock);
 
+PROVIDES_CONNTRACK(h225);
+PROVIDES_CONNTRACK(h245);
 module_init(init);
 module_exit(fini);

Modified: trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_nat_h323.c
===================================================================
--- trunk/patch-o-matic-ng/h323-conntrack-nat/linux/net/ipv4/netfilter/ip_nat_h323.c	2005-01-16 19:59:42 UTC (rev 3600)
+++ trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_nat_h323.c	2005-01-19 14:18:49 UTC (rev 3601)
@@ -1,6 +1,7 @@
-/* 
- * H.323 'brute force' extension for NAT alteration. 
+/*
+ * H.323 'brute force' extension for NAT alteration.
  * Jozsef Kadlecsik <kadlec at blackhole.kfki.hu>
+ * (c) 2005 Max Kellermann <max at duempel.org>
  *
  * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project.
  * (http://www.coritel.it/projects/sofia/nat.html)
@@ -38,7 +39,7 @@
 
 /* FIXME: Time out? --RR */
 
-static unsigned int 
+static unsigned int
 h225_nat_expected(struct sk_buff **pskb,
 		  unsigned int hooknum,
 		  struct ip_conntrack *ct,
@@ -46,38 +47,38 @@
 
 static unsigned int h225_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);
-		  
-static struct ip_nat_helper h245 = 
-	{ { NULL, NULL },
-          "H.245",				/* name */
-	  0,					/* flags */
-	  NULL,					/* module */
-	  { { 0, { 0 } },			/* tuple */
-	    { 0, { 0 }, IPPROTO_TCP } },
-	  { { 0, { 0xFFFF } },			/* mask */
-	    { 0, { 0 }, 0xFFFF } },
-	  h225_nat_help,			/* helper */
-	  h225_nat_expected			/* expectfn */
-	};
+				  struct ip_nat_info *info,
+				  enum ip_conntrack_info ctinfo,
+				  unsigned int hooknum,
+				  struct sk_buff **pskb);
 
+static struct ip_nat_helper h245 = {
+	.list = { NULL, NULL },
+	.name = "H.245",
+	.flags = 0,
+	.me = THIS_MODULE,
+	.tuple = { { 0, { 0 } },
+		   { 0, { 0 }, IPPROTO_TCP } },
+	.mask = { { 0, { 0xFFFF } },
+		  { 0, { 0 }, 0xFFFF } },
+	.help = h225_nat_help,
+	.expect = h225_nat_expected
+};
+
 static unsigned int
 h225_nat_expected(struct sk_buff **pskb,
 		  unsigned int hooknum,
 		  struct ip_conntrack *ct,
 		  struct ip_nat_info *info)
 {
-	struct ip_nat_multi_range mr;
+	struct ip_nat_range range;
 	u_int32_t newdstip, newsrcip, newip;
 	u_int16_t port;
 	struct ip_ct_h225_expect *exp_info;
 	struct ip_ct_h225_master *master_info;
 	struct ip_conntrack *master = master_ct(ct);
 	unsigned int is_h225, ret;
-	
+
 	IP_NF_ASSERT(info);
 	IP_NF_ASSERT(master);
 
@@ -110,7 +111,7 @@
 	port = exp_info->port;
 	is_h225 = master_info->is_h225 == H225_PORT;
 	UNLOCK_BH(&ip_h323_lock);
-	
+
 	if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC)
 		newip = newsrcip;
 	else
@@ -118,22 +119,21 @@
 
 	DEBUGP("h225_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;
+	range.flags = IP_NAT_RANGE_MAP_IPS;
+	range.min_ip = range.max_ip = newip;
 
 	/* ... unless we're doing a MANIP_DST, in which case, make
 	   sure we map to the correct port */
 	if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) {
-		mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
-		mr.range[0].min = mr.range[0].max
+		range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
+		range.min = range.max
 			= ((union ip_conntrack_manip_proto)
 				{ .tcp = { port } });
 	}
 
-	ret = ip_nat_setup_info(ct, &mr, hooknum);
-	
+	ret = ip_nat_setup_info(ct, &range, hooknum);
+
 	if (is_h225) {
 		DEBUGP("h225_nat_expected: H.225, setting NAT helper for %p\n", ct);
 		/* NAT expectfn called with ip_nat_lock write-locked */
@@ -143,19 +143,27 @@
 }
 
 static int h323_signal_address_fixup(struct ip_conntrack *ct,
-			      	     struct sk_buff **pskb,
-			      	     enum ip_conntrack_info ctinfo)
+				     struct sk_buff **pskb,
+				     enum ip_conntrack_info ctinfo)
 {
 	struct iphdr *iph = (*pskb)->nh.iph;
-	struct tcphdr *tcph = (void *)iph + iph->ihl*4;
-	char *data = (char *) tcph + tcph->doff * 4;
-	u_int32_t tcplen = (*pskb)->len - iph->ihl*4;
-	u_int32_t datalen = tcplen - tcph->doff*4;
-	struct ip_ct_h225_master *info = &ct->help.ct_h225_info; 
-	u_int32_t newip;
-	u_int16_t port;
+	struct tcphdr _tcph, *tcph;
+	u_int32_t tcplen, datalen;
+	struct ip_ct_h225_master *info = &ct->help.ct_h225_info;
+	struct {
+		u_int32_t ip;
+		u_int16_t port;
+	} __attribute__ ((__packed__)) newdata;
 	int i;
+	int ret;
 
+	tcph = skb_header_pointer(*pskb, iph->ihl * 4, sizeof(_tcph), &_tcph);
+	if (tcph == NULL)
+		return NF_ACCEPT;
+
+	tcplen = (*pskb)->len - iph->ihl * 4;
+	datalen = tcplen - tcph->doff * 4;
+
 	MUST_BE_LOCKED(&ip_h323_lock);
 
 	DEBUGP("h323_signal_address_fixup: %s %s\n",
@@ -167,8 +175,8 @@
 		|| between(info->seq[IP_CT_DIR_REPLY], ntohl(tcph->seq), ntohl(tcph->seq) + datalen)))
 		return 1;
 
-	DEBUGP("h323_signal_address_fixup: offsets %u + 6  and %u + 6 in %u\n", 
-		info->offset[IP_CT_DIR_ORIGINAL], 
+	DEBUGP("h323_signal_address_fixup: offsets %u + 6  and %u + 6 in %u\n",
+		info->offset[IP_CT_DIR_ORIGINAL],
 		info->offset[IP_CT_DIR_REPLY],
 		tcplen);
 	DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
@@ -178,7 +186,7 @@
 		DEBUGP("h323_signal_address_fixup: %s %s\n",
 			info->dir == IP_CT_DIR_ORIGINAL ? "original" : "reply",
 			i == IP_CT_DIR_ORIGINAL ? "caller" : "callee");
-		if (!between(info->seq[i], ntohl(tcph->seq), 
+		if (!between(info->seq[i], ntohl(tcph->seq),
 			     ntohl(tcph->seq) + datalen))
 			continue;
 		if (!between(info->seq[i] + 6, ntohl(tcph->seq),
@@ -196,39 +204,22 @@
 		/* Change address inside packet to match way we're mapping
 		   this connection. */
 		if (i == IP_CT_DIR_ORIGINAL) {
-			newip = ct->tuplehash[!info->dir].tuple.dst.ip;
-			port = ct->tuplehash[!info->dir].tuple.dst.u.tcp.port;
+			newdata.ip = ct->tuplehash[!info->dir].tuple.dst.ip;
+			newdata.port = ct->tuplehash[!info->dir].tuple.dst.u.tcp.port;
 		} else {
-			newip = ct->tuplehash[!info->dir].tuple.src.ip;
-			port = ct->tuplehash[!info->dir].tuple.src.u.tcp.port;
+			newdata.ip = ct->tuplehash[!info->dir].tuple.src.ip;
+			newdata.port = ct->tuplehash[!info->dir].tuple.src.u.tcp.port;
 		}
 
-		DEBUGP("h323_signal_address_fixup: orig %s IP:port %u.%u.%u.%u:%u\n", 
-			i == IP_CT_DIR_ORIGINAL ? "source" : "dest  ", 
-			NIPQUAD(*((u_int32_t *)(data + info->offset[i]))), 
-			ntohs(*((u_int16_t *)(data + info->offset[i] + 4))));
-
 		/* Modify the packet */
-		*(u_int32_t *)(data + info->offset[i]) = newip;
-		*(u_int16_t *)(data + info->offset[i] + 4) = port;
-	
-		DEBUGP("h323_signal_address_fixup:  new %s IP:port %u.%u.%u.%u:%u\n", 
-			i == IP_CT_DIR_ORIGINAL ? "source" : "dest  ", 
-			NIPQUAD(*((u_int32_t *)(data + info->offset[i]))), 
-			ntohs(*((u_int16_t *)(data + info->offset[i] + 4))));
+		ret = ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
+					       info->seq[i] - ntohl(tcph->seq),
+					       sizeof(newdata),
+					       (const char*)&newdata, sizeof(newdata));
+		if (!ret)
+			return 0;
 	}
 
-	/* fix checksum information */
-
-	(*pskb)->csum = csum_partial((char *)tcph + tcph->doff*4,
-				     datalen, 0);
-
-	tcph->check = 0;
-	tcph->check = tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
-				   csum_partial((char *)tcph, tcph->doff*4,
-					   (*pskb)->csum));
-	ip_send_check(iph);
-
 	return 1;
 }
 
@@ -238,16 +229,24 @@
 			   enum ip_conntrack_info ctinfo,
 			   struct ip_conntrack_expect *expect)
 {
-	u_int32_t newip;
-	u_int16_t port;
+	struct {
+		u_int32_t ip;
+		u_int16_t port;
+	} __attribute__ ((__packed__)) newdata;
 	struct ip_conntrack_tuple newtuple;
 	struct iphdr *iph = (*pskb)->nh.iph;
-	struct tcphdr *tcph = (void *)iph + iph->ihl*4;
-	char *data = (char *) tcph + tcph->doff * 4;
-	u_int32_t tcplen = (*pskb)->len - iph->ihl*4;
+	struct tcphdr _tcph, *tcph;
+	u_int32_t tcplen;
 	struct ip_ct_h225_master *master_info = &ct->help.ct_h225_info;
 	int is_h225;
+	int ret;
 
+	tcph = skb_header_pointer(*pskb, iph->ihl * 4, sizeof(_tcph), &_tcph);
+	if (tcph == NULL)
+		return NF_ACCEPT;
+
+	tcplen = (*pskb)->len - iph->ihl * 4;
+
 	MUST_BE_LOCKED(&ip_h323_lock);
 	DEBUGP("h323_data_fixup: offset %u + 6 in %u\n", info->offset, tcplen);
 	DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
@@ -269,13 +268,13 @@
 	   this connection. */
 	if (info->dir == IP_CT_DIR_REPLY) {
 		/* Must be where client thinks server is */
-		newip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
+		newdata.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
 		/* Expect something from client->server */
 		newtuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
 		newtuple.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
 	} else {
 		/* Must be where server thinks client is */
-		newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
+		newdata.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
 		/* Expect something from server->client */
 		newtuple.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
 		newtuple.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
@@ -290,61 +289,45 @@
 		newtuple.dst.protonum = IPPROTO_UDP;
 		newtuple.src.u.udp.port = expect->tuple.src.u.udp.port;
 	}
-	
+
 	/* Try to get same port: if not, try to change it. */
-	for (port = ntohs(info->port); port != 0; port++) {
+	for (newdata.port = ntohs(info->port); newdata.port != 0; newdata.port++) {
 		if (is_h225)
-			newtuple.dst.u.tcp.port = htons(port);
+			newtuple.dst.u.tcp.port = htons(newdata.port);
 		else
-			newtuple.dst.u.udp.port = htons(port);
+			newtuple.dst.u.udp.port = htons(newdata.port);
 
 		if (ip_conntrack_change_expect(expect, &newtuple) == 0)
 			break;
 	}
-	if (port == 0) {
+	if (newdata.port == 0) {
 		DEBUGP("h323_data_fixup: no free port found!\n");
 		return 0;
 	}
 
-	port = htons(port);
+	newdata.port = htons(newdata.port);
 
-	DEBUGP("h323_data_fixup: orig IP:port %u.%u.%u.%u:%u\n", 
-		NIPQUAD(*((u_int32_t *)(data + info->offset))), 
-		ntohs(*((u_int16_t *)(data + info->offset + 4))));
-
 	/* Modify the packet */
-	*(u_int32_t *)(data + info->offset) = newip;
-	*(u_int16_t *)(data + info->offset + 4) = port;
-	
-	DEBUGP("h323_data_fixup: new IP:port %u.%u.%u.%u:%u\n", 
-		NIPQUAD(*((u_int32_t *)(data + info->offset))), 
-		ntohs(*((u_int16_t *)(data + info->offset + 4))));
+	ret = ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
+				       expect->seq - ntohl(tcph->seq),
+				       sizeof(newdata),
+				       (const char*)&newdata, sizeof(newdata));
+	if (!ret)
+		return 0;
 
-	/* fix checksum information  */
-	/* FIXME: usually repeated multiple times in the case of H.245! */
-
-	(*pskb)->csum = csum_partial((char *)tcph + tcph->doff*4,
-				     tcplen - tcph->doff*4, 0);
-
-	tcph->check = 0;
-	tcph->check = tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
-				   csum_partial((char *)tcph, tcph->doff*4,
-					   (*pskb)->csum));
-	ip_send_check(iph);
-
 	return 1;
 }
 
 static unsigned int h225_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 ip_nat_info *info,
+				  enum ip_conntrack_info ctinfo,
+				  unsigned int hooknum,
+				  struct sk_buff **pskb)
 {
 	int dir;
 	struct ip_ct_h225_expect *exp_info;
-	
+
 	/* Only mangle things once: original direction in POST_ROUTING
 	   and reply direction on PRE_ROUTING. */
 	dir = CTINFO2DIR(ctinfo);
@@ -372,7 +355,7 @@
 		UNLOCK_BH(&ip_h323_lock);
 		return NF_ACCEPT;
 	}
-		
+
 	exp_info = &exp->help.exp_h225_info;
 
 	LOCK_BH(&ip_h323_lock);
@@ -385,23 +368,23 @@
 	return NF_ACCEPT;
 }
 
-static struct ip_nat_helper h225 = 
-	{ { NULL, NULL },
-	  "H.225",					/* name */
-	  IP_NAT_HELPER_F_ALWAYS, 			/* flags */
-	  THIS_MODULE,					/* module */
-	  { { 0, { .tcp = { __constant_htons(H225_PORT) } } },	/* tuple */
-	    { 0, { 0 }, IPPROTO_TCP } },
-	  { { 0, { .tcp = { 0xFFFF } } },		/* mask */
-	    { 0, { 0 }, 0xFFFF } },
-	  h225_nat_help,				/* helper */
-	  h225_nat_expected				/* expectfn */
-	};
+static struct ip_nat_helper h225 = {
+	.list = { NULL, NULL },
+	.name = "H.225",
+	.flags = IP_NAT_HELPER_F_ALWAYS,
+	.me = THIS_MODULE,
+	.tuple = { { 0, { .tcp = { __constant_htons(H225_PORT) } } },
+		   { 0, { 0 }, IPPROTO_TCP } },
+	.mask = { { 0, { .tcp = { 0xFFFF } } },
+		  { 0, { 0 }, 0xFFFF } },
+	.help = h225_nat_help,
+	.expect = h225_nat_expected
+};
 
 static int __init init(void)
 {
 	int ret;
-	
+
 	ret = ip_nat_helper_register(&h225);
 
 	if (ret != 0)
@@ -415,5 +398,7 @@
 	ip_nat_helper_unregister(&h225);
 }
 
+NEEDS_CONNTRACK(h225);
+NEEDS_CONNTRACK(h245);
 module_init(init);
 module_exit(fini);




More information about the netfilter-cvslog mailing list