[netfilter-cvslog] r3845 - in trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6.11: include/linux/netfilter_ipv4 net/ipv4/netfilter

laforge at netfilter.org laforge at netfilter.org
Sun Apr 10 22:40:41 CEST 2005


Author: laforge at netfilter.org
Date: 2005-04-10 22:40:40 +0200 (Sun, 10 Apr 2005)
New Revision: 3845

Modified:
   trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6.11/include/linux/netfilter_ipv4/ip_conntrack_h323.h
   trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323.c
   trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_nat_h323.c
Log:
update to Max Kellermann's port (get rid of my own)


Modified: trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6.11/include/linux/netfilter_ipv4/ip_conntrack_h323.h
===================================================================
--- trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6.11/include/linux/netfilter_ipv4/ip_conntrack_h323.h	2005-04-10 20:34:00 UTC (rev 3844)
+++ trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6.11/include/linux/netfilter_ipv4/ip_conntrack_h323.h	2005-04-10 20:40:40 UTC (rev 3845)
@@ -3,37 +3,35 @@
 /* H.323 connection tracking. */
 
 #ifdef __KERNEL__
-/* Protects H.323 related data */
-#include <linux/netfilter_ipv4/lockhelp.h>
-DECLARE_LOCK_EXTERN(ip_h323_lock);
-#endif
 
 /* Default H.225 port */
 #define H225_PORT	1720
 
-/* This structure is per expected connection */
-struct ip_ct_h225_expect {
-	u_int16_t port;			/* Port of the H.225 helper/RTCP/RTP channel */
-	enum ip_conntrack_dir dir;	/* Direction of the original connection */
-	unsigned int offset;		/* offset of the address in the payload */
-};
-
 /* This structure exists only once per master */
 struct ip_ct_h225_master {
-	int is_h225;				/* H.225 or H.245 connection */
-#ifdef CONFIG_IP_NF_NAT_NEEDED
-	enum ip_conntrack_dir dir;		/* Direction of the original connection */
-	u_int32_t seq[IP_CT_DIR_MAX];		/* Exceptional packet mangling for signal addressess... */
-	unsigned int offset[IP_CT_DIR_MAX];	/* ...and the offset of the addresses in the payload */
-#endif
+	int dummy;
 };
 
-struct ip_conntrack;
 struct ip_conntrack_expect;
-extern unsigned int (*ip_nat_h225_exp_hook)(struct ip_conntrack *ct,
-					    struct sk_buff **pskb, 
-					    enum ip_conntrack_info ctinfo,
-					    struct ip_ct_h225_expect *exp_info,
-					    struct ip_conntrack_expect *exp);
+struct ip_conntrack;
 
+extern int (*ip_nat_h245_hook)(struct sk_buff **pskb,
+			       enum ip_conntrack_info ctinfo,
+			       unsigned int offset,
+			       struct ip_conntrack_expect *exp);
+
+extern int (*ip_nat_h225_hook)(struct sk_buff **pskb,
+			       enum ip_conntrack_info ctinfo,
+			       unsigned int offset,
+			       struct ip_conntrack_expect *exp);
+
+extern void (*ip_nat_h225_signal_hook)(struct sk_buff **pskb,
+				       struct ip_conntrack *ct,
+				       enum ip_conntrack_info ctinfo,
+				       unsigned int offset,
+				       int dir,
+				       int orig_dir);
+
+#endif /* __KERNEL__ */
+
 #endif /* _IP_CONNTRACK_H323_H */

Modified: trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323.c
===================================================================
--- trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323.c	2005-04-10 20:34:00 UTC (rev 3844)
+++ trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323.c	2005-04-10 20:40:40 UTC (rev 3845)
@@ -2,7 +2,6 @@
  * 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>
- * (c) 2005 Harald Welte <laforge at netfilter.org>
  *
  * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project.
  * (http://www.coritel.it/projects/sofia/nat/)
@@ -30,15 +29,31 @@
 
 /* This is slow, but it's simple. --RR */
 static char h323_buffer[65536];
-static DECLARE_LOCK(h323_buffer_lock);
 
+static DECLARE_LOCK(ip_h323_lock);
+
 struct module *ip_conntrack_h323 = THIS_MODULE;
 
-static unsigned int (*ip_nat_h225_exp_hook)(struct ip_conntrack *ct,
-					    struct sk_buff **pskb, 
-					    enum ip_conntrack_info ctinfo,
-					    struct ip_ct_h225_expect *exp_info,
-					    struct ip_conntrack_expect *exp);
+int (*ip_nat_h245_hook)(struct sk_buff **pskb,
+			enum ip_conntrack_info ctinfo,
+			unsigned int offset,
+			struct ip_conntrack_expect *exp);
+EXPORT_SYMBOL_GPL(ip_nat_h245_hook);
+
+int (*ip_nat_h225_hook)(struct sk_buff **pskb,
+			enum ip_conntrack_info ctinfo,
+			unsigned int offset,
+			struct ip_conntrack_expect *exp);
+EXPORT_SYMBOL_GPL(ip_nat_h225_hook);
+
+void (*ip_nat_h225_signal_hook)(struct sk_buff **pskb,
+				struct ip_conntrack *ct,
+				enum ip_conntrack_info ctinfo,
+				unsigned int offset,
+				int dir,
+				int orig_dir);
+EXPORT_SYMBOL_GPL(ip_nat_h225_signal_hook);
+
 #if 0
 #define DEBUGP printk
 #else
@@ -50,15 +65,12 @@
 		     struct ip_conntrack *ct,
 		     enum ip_conntrack_info ctinfo)
 {
-	struct iphdr *iph = (*pskb)->nh.iph;
 	struct tcphdr _tcph, *tcph;
 	unsigned char *data;
 	unsigned char *data_limit;
 	unsigned dataoff, datalen;
 	int dir = CTINFO2DIR(ctinfo);
-	struct ip_ct_h225_master *info = &ct->help.ct_h225_info;
 	struct ip_conntrack_expect *exp;
-	struct ip_ct_h225_expect _h225e, *exp_info = &_h225e;
 	u_int16_t data_port;
 	u_int32_t data_ip;
 	unsigned int i;
@@ -77,8 +89,8 @@
 		return NF_ACCEPT;
 
 	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));
+		NIPQUAD((*pskb)->nh.iph->saddr), ntohs(tcph->source),
+		NIPQUAD((*pskb)->nh.iph->daddr), ntohs(tcph->dest));
 
 	dataoff = (*pskb)->nh.iph->ihl*4 + tcph->doff*4;
 	/* No data? */
@@ -88,8 +100,8 @@
 	}
 	datalen = (*pskb)->len - dataoff;
 
-	LOCK_BH(&h323_buffer_lock);
-	data = skb_header_pointer(*pskb, dataoff,
+	LOCK_BH(&ip_h323_lock);
+	data = skb_header_pointer((*pskb), dataoff,
 				  datalen, h323_buffer);
 	BUG_ON(data == NULL);
 
@@ -98,13 +110,13 @@
 	          ipadrr port */
 	for (i = 0; data <= data_limit; data++, i++) {
 		data_ip = *((u_int32_t *)data);
-		if (data_ip == iph->saddr) {
+		if (data_ip == ct->tuplehash[dir].tuple.src.ip) {
 			data_port = *((u_int16_t *)(data + 4));
 
 			/* 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));
+				NIPQUAD((*pskb)->nh.iph->saddr), ntohs(data_port));
 
 			exp = ip_conntrack_expect_alloc();
 			if (exp == NULL) {
@@ -112,11 +124,6 @@
 				goto out;
 			}
 
-			info->is_h225 = H225_PORT + 1;
-			exp_info->port = data_port;
-			exp_info->dir = dir;
-			exp_info->offset = i;
-
 			exp->tuple = ((struct ip_conntrack_tuple)
 				{ { ct->tuplehash[!dir].tuple.src.ip,
 				    { 0 } },
@@ -129,25 +136,25 @@
 
 			exp->expectfn = NULL;
 
-			if (ip_nat_h225_exp_hook)
-				ret = ip_nat_h225_exp_hook(ct, pskb, 
-						ctinfo, exp_info, exp);
-			else {
-				if (ip_conntrack_expect_related(exp)) {
+			if (ip_nat_h245_hook != NULL) {
+				ret = ip_nat_h245_hook(pskb, ctinfo, i,
+						       exp);
+			} else {
+				/* Can't expect this?  Best to drop packet now. */
+				if (ip_conntrack_expect_related(exp) != 0) {
 					ip_conntrack_expect_free(exp);
 					ret = NF_DROP;
-				} else {
+				} else
 					ret = NF_ACCEPT;
-
-					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));
-				}
 			}
+
+			break;
 		}
 	}
 
 	ret = NF_ACCEPT;
  out:
-	UNLOCK_BH(&h323_buffer_lock);
+	UNLOCK_BH(&ip_h323_lock);
 	return ret;
 }
 
@@ -162,12 +169,12 @@
 	.help = h245_help
 };
 
-static void h225_expect(struct ip_conntrack *ct,
-			struct ip_conntrack_expect *exp)
+static void h225_expect(struct ip_conntrack *new,
+			struct ip_conntrack_expect *this)
 {
 	WRITE_LOCK(&ip_conntrack_lock);
-	ct->helper = &h245;
-	DEBUGP("h225_expect: helper for %p added\n", ct);
+	new->helper = &h245;
+	DEBUGP("h225_expect: helper for %p added\n", new);
 	WRITE_UNLOCK(&ip_conntrack_lock);
 }
 
@@ -176,15 +183,12 @@
 		     struct ip_conntrack *ct,
 		     enum ip_conntrack_info ctinfo)
 {
-	struct iphdr *iph = (*pskb)->nh.iph;
 	struct tcphdr _tcph, *tcph;
 	unsigned char *data;
 	unsigned char *data_limit;
 	unsigned dataoff, datalen;
 	int dir = CTINFO2DIR(ctinfo);
-	struct ip_ct_h225_master *info = &ct->help.ct_h225_info;
 	struct ip_conntrack_expect *exp;
-	struct ip_ct_h225_expect _h225e, *exp_info = &_h225e;
 	u_int16_t data_port;
 	u_int32_t data_ip;
 	unsigned int i;
@@ -197,14 +201,14 @@
 		return NF_ACCEPT;
 	}
 
-	tcph = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl*4,
+	tcph = skb_header_pointer((*pskb), (*pskb)->nh.iph->ihl*4,
 				  sizeof(_tcph), &_tcph);
 	if (tcph == NULL)
 		return NF_ACCEPT;
 
 	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));
+		NIPQUAD((*pskb)->nh.iph->saddr), ntohs(tcph->source),
+		NIPQUAD((*pskb)->nh.iph->daddr), ntohs(tcph->dest));
 
 	dataoff = (*pskb)->nh.iph->ihl*4 + tcph->doff*4;
 	/* No data? */
@@ -214,8 +218,8 @@
 	}
 	datalen = (*pskb)->len - dataoff;
 
-	LOCK_BH(&h323_buffer_lock);
-	data = skb_header_pointer(*pskb, dataoff,
+	LOCK_BH(&ip_h323_lock);
+	data = skb_header_pointer((*pskb), dataoff,
 				  datalen, h323_buffer);
 	BUG_ON(data == NULL);
 
@@ -224,20 +228,17 @@
 	          ipadrr port */
 	for (i = 0; data <= data_limit; data++, i++) {
 		data_ip = *((u_int32_t *)data);
-		if (data_ip == iph->saddr) {
+		if (data_ip == ct->tuplehash[dir].tuple.src.ip) {
 			data_port = *((u_int16_t *)(data + 4));
-			if (data_port == tcph->source) {
+			if (data_port == ct->tuplehash[dir].tuple.src.u.tcp.port) {
 				/* Signal address */
 				DEBUGP("ct_h225_help: sourceCallSignalAddress from %u.%u.%u.%u\n",
-					NIPQUAD(iph->saddr));
-				/* Update the H.225 info so that NAT can mangle
-				 * the address/port even when we have no
-				 * expected connection! */
-#ifdef CONFIG_IP_NF_NAT_NEEDED
-				info->dir = dir;
-				info->seq[IP_CT_DIR_ORIGINAL] = ntohl(tcph->seq) + i;
-				info->offset[IP_CT_DIR_ORIGINAL] = i;
-#endif
+					NIPQUAD((*pskb)->nh.iph->saddr));
+				/* Update the H.225 info so that NAT can mangle the address/port
+				   even when we have no expected connection! */
+				if (ip_nat_h225_signal_hook != NULL)
+					ip_nat_h225_signal_hook(pskb, ct, ctinfo,
+								i, IP_CT_DIR_ORIGINAL, dir);
 			} else {
 				/* update the H.225 info */
 				exp = ip_conntrack_expect_alloc();
@@ -246,11 +247,6 @@
 					goto out;
 				}
 
-				info->is_h225 = H225_PORT;
-				exp_info->port = data_port;
-				exp_info->dir = dir;
-				exp_info->offset = i;
-
 				exp->tuple = ((struct ip_conntrack_tuple)
 					{ { ct->tuplehash[!dir].tuple.src.ip,
 					    { 0 } },
@@ -262,42 +258,40 @@
 					  { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
 
 				exp->expectfn = h225_expect;
+				exp->master = ct;
 
-				if (ip_nat_h225_exp_hook)
-					ret = ip_nat_h225_exp_hook(ct, pskb, 
-							ctinfo, exp_info, exp);
-				else {
-					if (ip_conntrack_expect_related(exp)) {
+				if (ip_nat_h225_hook != NULL) {
+					ret = ip_nat_h225_hook(pskb, ctinfo, i,
+							       exp);
+				} else {
+					/* Can't expect this?  Best to drop packet now. */
+					if (ip_conntrack_expect_related(exp) != 0) {
 						ip_conntrack_expect_free(exp);
 						ret = NF_DROP;
-					} else {
+					} else
 						ret = NF_ACCEPT;
-
-						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));
-					}
 				}
 			}
-#ifdef CONFIG_IP_NF_NAT_NEEDED
-		} else if (data_ip == iph->daddr) {
+
+			break;
+		} else if (data_ip == ct->tuplehash[dir].tuple.dst.ip) {
 			data_port = *((u_int16_t *)(data + 4));
-			if (data_port == tcph->dest) {
+			if (data_port == ct->tuplehash[dir].tuple.dst.u.tcp.port) {
 				/* Signal address */
 				DEBUGP("ct_h225_help: destCallSignalAddress %u.%u.%u.%u\n",
-					NIPQUAD(iph->daddr));
-				/* Update the H.225 info so that NAT can mangle
-				 * the address/port even when we have no
-				 * expected connection! */
-				info->dir = dir;
-				info->seq[IP_CT_DIR_REPLY] = ntohl(tcph->seq) + i;
-				info->offset[IP_CT_DIR_REPLY] = i;
+					NIPQUAD((*pskb)->nh.iph->daddr));
+				/* Update the H.225 info so that NAT can mangle the address/port
+				   even when we have no expected connection! */
+				if (ip_nat_h225_signal_hook != NULL)
+					ip_nat_h225_signal_hook(pskb, ct, ctinfo,
+								i, IP_CT_DIR_REPLY, dir);
 			}
-#endif
 		}
 	}
 
 	ret = NF_ACCEPT;
  out:
-	UNLOCK_BH(&h323_buffer_lock);
+	UNLOCK_BH(&ip_h323_lock);
 	return ret;
 }
 

Modified: trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_nat_h323.c
===================================================================
--- trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_nat_h323.c	2005-04-10 20:34:00 UTC (rev 3844)
+++ trunk/patch-o-matic-ng/h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_nat_h323.c	2005-04-10 20:40:40 UTC (rev 3845)
@@ -28,6 +28,7 @@
 MODULE_DESCRIPTION("H.323 'brute force' connection tracking module");
 MODULE_LICENSE("GPL");
 
+struct module *ip_nat_h323 = THIS_MODULE;
 
 #if 0
 #define DEBUGP printk
@@ -35,295 +36,100 @@
 #define DEBUGP(format, args...)
 #endif
 
-/* FIXME: Time out? --RR */
-
-static unsigned int
-h225_nat_expected(struct sk_buff **pskb,
-		  unsigned int hooknum,
-		  struct ip_conntrack *ct,
-		  struct ip_nat_info *info);
-
-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 unsigned int
-h225_nat_expected(struct sk_buff **pskb,
-		  unsigned int hooknum,
-		  struct ip_conntrack *ct,
-		  struct ip_nat_info *info)
+static void ip_nat_h225_signal(struct sk_buff **pskb,
+			       struct ip_conntrack *ct,
+			       enum ip_conntrack_info ctinfo,
+			       unsigned int offset,
+			       int dir,
+			       int orig_dir)
 {
-	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);
-
-	IP_NF_ASSERT(!(info->initialized & (1<<HOOK2MANIP(hooknum))));
-
-	DEBUGP("h225_nat_expected: We have a connection!\n");
-	master_info = &ct->master->help.ct_h225_info;
-	//exp_info = &ct->master->help.exp_h225_info;
-
-
-	DEBUGP("master: ");
-	DUMP_TUPLE(&master->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
-	DUMP_TUPLE(&master->tuplehash[IP_CT_DIR_REPLY].tuple);
-	DEBUGP("conntrack: ");
-	DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
-	if (exp_info->dir == IP_CT_DIR_ORIGINAL) {
-		/* Make connection go to the client. */
-		newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
-		newsrcip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
-		DEBUGP("h225_nat_expected: %u.%u.%u.%u->%u.%u.%u.%u (to client)\n",
-		       NIPQUAD(newsrcip), NIPQUAD(newdstip));
-	} else {
-		/* Make the connection go to the server */
-		newdstip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
-		newsrcip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
-		DEBUGP("h225_nat_expected: %u.%u.%u.%u->%u.%u.%u.%u (to server)\n",
-		       NIPQUAD(newsrcip), NIPQUAD(newdstip));
-	}
-	port = exp_info->port;
-	is_h225 = master_info->is_h225 == H225_PORT;
-
-	if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC)
-		newip = newsrcip;
-	else
-		newip = newdstip;
-
-	DEBUGP("h225_nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip));
-
-	/* We don't want to manip the per-protocol, just the IPs... */
-	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) {
-		range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
-		range.min = range.max
-			= ((union ip_conntrack_manip_proto)
-				{ .tcp = { port } });
-	}
-
-	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 */
-		// FIXME: info->helper = &h245;
-	}
-	return ret;
-}
-
-static int h323_signal_address_fixup(struct ip_conntrack *ct,
-				     struct sk_buff **pskb,
-				     enum ip_conntrack_info ctinfo)
-{
-	struct iphdr *iph = (*pskb)->nh.iph;
-	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;
-
-	DEBUGP("h323_signal_address_fixup: %s %s\n",
-		between(info->seq[IP_CT_DIR_ORIGINAL], ntohl(tcph->seq), ntohl(tcph->seq) + datalen)
-			? "yes" : "no",
-		between(info->seq[IP_CT_DIR_REPLY], ntohl(tcph->seq), ntohl(tcph->seq) + datalen)
-			? "yes" : "no");
-	if (!(between(info->seq[IP_CT_DIR_ORIGINAL], ntohl(tcph->seq), ntohl(tcph->seq) + datalen)
-		|| 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],
-		info->offset[IP_CT_DIR_REPLY],
-		tcplen);
-	DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
-	DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
-
-	for (i = 0; i < IP_CT_DIR_MAX; i++) {
-		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),
-			     ntohl(tcph->seq) + datalen))
-			continue;
-		if (!between(info->seq[i] + 6, ntohl(tcph->seq),
-			     ntohl(tcph->seq) + datalen)) {
-			/* Partial retransmisison. It's a cracker being funky. */
-			if (net_ratelimit()) {
-				printk("H.323_NAT: partial packet %u/6 in %u/%u\n",
-				     info->seq[i],
-				     ntohl(tcph->seq),
-				     ntohl(tcph->seq) + datalen);
-			}
-			return 0;
-		}
-
-		/* Change address inside packet to match way we're mapping
-		   this connection. */
-		if (i == IP_CT_DIR_ORIGINAL) {
-			newdata.ip = ct->tuplehash[!info->dir].tuple.dst.ip;
-			newdata.port = ct->tuplehash[!info->dir].tuple.dst.u.tcp.port;
-		} else {
-			newdata.ip = ct->tuplehash[!info->dir].tuple.src.ip;
-			newdata.port = ct->tuplehash[!info->dir].tuple.src.u.tcp.port;
-		}
-
-		/* Modify the packet */
-		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;
+	/* Change address inside packet to match way we're mapping
+	   this connection. */
+	if (dir == IP_CT_DIR_ORIGINAL) {
+		newdata.ip = ct->tuplehash[!orig_dir].tuple.dst.ip;
+		newdata.port = ct->tuplehash[!orig_dir].tuple.dst.u.tcp.port;
+	} else {
+		newdata.ip = ct->tuplehash[!orig_dir].tuple.src.ip;
+		newdata.port = ct->tuplehash[!orig_dir].tuple.src.u.tcp.port;
 	}
 
-	return 1;
+	/* Modify the packet */
+	ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
+				 offset,
+				 sizeof(newdata),
+				 (const char*)&newdata, sizeof(newdata));
 }
 
-static unsigned int h323_data_fixup(struct ip_conntrack *ct,
-			   struct sk_buff **pskb,
-			   enum ip_conntrack_info ctinfo,
-			   struct ip_ct_h225_expect *info,
-			   struct ip_conntrack_expect *expect)
+static int ip_nat_h225(struct sk_buff **pskb,
+		       enum ip_conntrack_info ctinfo,
+		       unsigned int offset,
+		       struct ip_conntrack_expect *exp)
 {
+	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, *tcph;
-	u_int32_t tcplen;
-	struct ip_ct_h225_master *master_info = &ct->help.ct_h225_info;
-	int is_h225;
+	int dir = CTINFO2DIR(ctinfo);
+	struct ip_conntrack *ct = exp->master;
 	int ret;
 
-	tcph = skb_header_pointer(*pskb, iph->ihl * 4, sizeof(_tcph), &_tcph);
-	if (tcph == NULL)
-		return NF_ACCEPT;
+	/* Connection will come from wherever this packet goes, hence !dir */
+	newdata.ip = ct->tuplehash[!dir].tuple.dst.ip;
+	exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
+	exp->dir = !dir;
 
-	tcplen = (*pskb)->len - iph->ihl * 4;
+	/* When you see the packet, we need to NAT it the same as the
+	 * this one. */
+	exp->expectfn = ip_nat_follow_master;
 
-	DEBUGP("h323_data_fixup: offset %u + 6 in %u\n", info->offset, tcplen);
-	DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
-	DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
-
-	/* Change address inside packet to match way we're mapping
-	   this connection. */
-	if (info->dir == IP_CT_DIR_REPLY) {
-		/* Must be where client thinks server is */
-		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 */
-		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;
-	}
-
-	is_h225 = (master_info->is_h225 == H225_PORT);
-
-	if (is_h225) {
-		newtuple.dst.protonum = IPPROTO_TCP;
-		newtuple.src.u.tcp.port = expect->tuple.src.u.tcp.port;
-	} else {
-		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 (newdata.port = ntohs(info->port); newdata.port != 0; 
-	     newdata.port++) {
-		if (is_h225)
-			expect->tuple.dst.u.tcp.port = htons(newdata.port);
-		else
-			expect->tuple.dst.u.udp.port = htons(newdata.port);
-
-		if (ip_conntrack_expect_related(expect) == 0)
+	for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
+		exp->tuple.dst.u.tcp.port = htons(port);
+		if (ip_conntrack_expect_related(exp) == 0)
 			break;
 	}
-	if (newdata.port == 0) {
-		DEBUGP("h323_data_fixup: no free port found!\n");
-		ip_conntrack_expect_free(expect);
+
+	if (port == 0) {
+		ip_conntrack_expect_free(exp);
 		return NF_DROP;
 	}
 
-	newdata.port = htons(newdata.port);
+	newdata.port = htons(port);
 
-	/* Modify the packet */
+	/* now mangle packet */
 	ret = ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
-				       info->offset,
+				       offset,
 				       sizeof(newdata),
 				       (const char*)&newdata, sizeof(newdata));
-	if (!ret) {
-		ip_conntrack_unexpect_related(expect);
+	if (!ret)
 		return NF_DROP;
-	}
 
 	return NF_ACCEPT;
 }
 
-#if 0
-static unsigned int h225_nat_help(struct ip_conntrack *ct,
-				  struct sk_buff **pskb,
-				  struct ip_conntrack_expect *exp,
-				  struct ip_ct_h225_expect *exp_info,
-				  enum ip_conntrack_info ctinfo)
-				  
-{
-	if (!exp) {
-		if (!h323_signal_address_fixup(ct, pskb, ctinfo)) {
-			return NF_DROP;
-		}
-		return NF_ACCEPT;
-	}
-
-	if (!h323_data_fixup(exp_info, ct, pskb, ctinfo, exp)) {
-		return NF_DROP;
-	}
-
-	return NF_ACCEPT;
-}
-#endif
-
 static int __init init(void)
 {
-	BUG_ON(ip_nat_h225_exp_hook);
-	ip_nat_h225_exp_hook = &h323_data_fixup;
+	BUG_ON(ip_nat_h225_hook != NULL);
+	BUG_ON(ip_nat_h245_hook != NULL);
 
+	ip_nat_h225_hook = ip_nat_h225;
+	ip_nat_h225_signal_hook = ip_nat_h225_signal;
+	ip_nat_h245_hook = ip_nat_h225;
+
 	return 0;
 }
 
 static void __exit fini(void)
 {
-	ip_nat_h225_exp_hook = NULL;
+	ip_nat_h225_hook = NULL;
+	ip_nat_h225_signal_hook = NULL;
+	ip_nat_h245_hook = NULL;
 }
 
 module_init(init);




More information about the netfilter-cvslog mailing list