remove generic linux 2.4 support
[openwrt/svn-archive/archive.git] / target / linux / generic-2.4 / patches / 613-netfilter_nat_h323.patch
diff --git a/target/linux/generic-2.4/patches/613-netfilter_nat_h323.patch b/target/linux/generic-2.4/patches/613-netfilter_nat_h323.patch
deleted file mode 100644 (file)
index 9505160..0000000
+++ /dev/null
@@ -1,814 +0,0 @@
---- a/net/ipv4/netfilter/Config.in
-+++ b/net/ipv4/netfilter/Config.in
-@@ -13,6 +13,7 @@ if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ];
-   dep_tristate '  IRC protocol support' CONFIG_IP_NF_IRC $CONFIG_IP_NF_CONNTRACK
-   dep_tristate '  Connection tracking flow accounting' CONFIG_IP_NF_CT_ACCT $CONFIG_IP_NF_CONNTRACK
-   dep_tristate '  Connection byte counter support' CONFIG_IP_NF_MATCH_CONNBYTES $CONFIG_IP_NF_CT_ACCT $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES
-+  dep_tristate '  H.323 (netmeeting) support' CONFIG_IP_NF_H323 $CONFIG_IP_NF_CONNTRACK
- fi
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-@@ -80,6 +81,13 @@ if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; 
-           define_tristate CONFIG_IP_NF_NAT_AMANDA $CONFIG_IP_NF_NAT
-         fi
-       fi
-+      if [ "$CONFIG_IP_NF_H323" = "m" ]; then
-+       define_tristate CONFIG_IP_NF_NAT_H323 m
-+      else
-+       if [ "$CONFIG_IP_NF_H323" = "y" ]; then
-+         define_tristate CONFIG_IP_NF_NAT_H323 $CONFIG_IP_NF_NAT
-+       fi
-+      fi
-       if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-         dep_tristate '    Basic SNMP-ALG support (EXPERIMENTAL)' CONFIG_IP_NF_NAT_SNMP_BASIC $CONFIG_IP_NF_NAT
-       fi
---- a/net/ipv4/netfilter/Makefile
-+++ b/net/ipv4/netfilter/Makefile
-@@ -47,12 +47,17 @@ obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_
- ifdef CONFIG_IP_NF_IRC
-       export-objs += ip_conntrack_irc.o
- endif
-+obj-$(CONFIG_IP_NF_H323) += ip_conntrack_h323.o
-+ifdef CONFIG_IP_NF_NAT_H323
-+       export-objs += ip_conntrack_h323.o
-+endif
- # NAT helpers 
- 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
- obj-$(CONFIG_IP_NF_NAT_IRC) += ip_nat_irc.o
-+obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o
- # generic IP tables 
- obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
---- /dev/null
-+++ b/net/ipv4/netfilter/ip_conntrack_h323.c
-@@ -0,0 +1,302 @@
-+/* 
-+ * H.323 'brute force' extension for H.323 connection tracking. 
-+ * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
-+ *
-+ * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project.
-+ * (http://www.coritel.it/projects/sofia/nat/)
-+ * Uses Sampsa Ranta's excellent idea on using expectfn to 'bind'
-+ * the unregistered helpers to the conntrack entries.
-+ */
-+
-+
-+#include <linux/module.h>
-+#include <linux/netfilter.h>
-+#include <linux/ip.h>
-+#include <net/checksum.h>
-+#include <net/tcp.h>
-+
-+#include <linux/netfilter_ipv4/lockhelp.h>
-+#include <linux/netfilter_ipv4/ip_conntrack.h>
-+#include <linux/netfilter_ipv4/ip_conntrack_core.h>
-+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
-+#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
-+#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
-+
-+MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
-+MODULE_DESCRIPTION("H.323 'brute force' connection tracking module");
-+MODULE_LICENSE("GPL");
-+
-+DECLARE_LOCK(ip_h323_lock);
-+struct module *ip_conntrack_h323 = THIS_MODULE;
-+
-+#define DEBUGP(format, args...)
-+
-+static int h245_help(const struct iphdr *iph, size_t len,
-+                   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;
-+      unsigned char *data_limit;
-+      u_int32_t tcplen = len - iph->ihl * 4;
-+      u_int32_t datalen = tcplen - tcph->doff * 4;
-+      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;
-+      u_int16_t data_port;
-+      u_int32_t data_ip;
-+      unsigned int i;
-+
-+      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) {
-+              DEBUGP("ct_h245_help: Conntrackinfo = %u\n", ctinfo);
-+              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);
-+              return NF_ACCEPT;
-+      }
-+
-+      /* Checksum invalid?  Ignore. */
-+      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));
-+              return NF_ACCEPT;
-+      }
-+
-+      data_limit = (unsigned char *) data + datalen;
-+      /* bytes: 0123   45
-+                ipadrr port */
-+      for (i = 0; data < (data_limit - 5); data++, i++) {
-+              memcpy(&data_ip, data, sizeof(u_int32_t));
-+              if (data_ip == iph->saddr) {
-+                      memcpy(&data_port, data + 4, sizeof(u_int16_t));
-+                      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));
-+                      LOCK_BH(&ip_h323_lock);
-+                      info->is_h225 = H225_PORT + 1;
-+                      exp_info->port = data_port;
-+                      exp_info->dir = dir;
-+                      exp_info->offset = i;
-+
-+                      exp->seq = ntohl(tcph->seq) + i;
-+                  
-+                      exp->tuple = ((struct ip_conntrack_tuple)
-+                              { { ct->tuplehash[!dir].tuple.src.ip,
-+                                  { 0 } },
-+                                { data_ip,
-+                                  { data_port },
-+                                  IPPROTO_UDP }});
-+                      exp->mask = ((struct ip_conntrack_tuple)
-+                              { { 0xFFFFFFFF, { 0 } },
-+                                { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }});
-+      
-+                      exp->expectfn = NULL;
-+                      
-+                      /* Ignore failure; should only happen with NAT */
-+                      ip_conntrack_expect_related(ct, exp);
-+
-+                      UNLOCK_BH(&ip_h323_lock);
-+              }
-+      }
-+
-+      return NF_ACCEPT;
-+
-+}
-+
-+/* 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 int h225_expect(struct ip_conntrack *ct)
-+{
-+      WRITE_LOCK(&ip_conntrack_lock);
-+      ct->helper = &h245;
-+      DEBUGP("h225_expect: helper for %p added\n", ct);
-+      WRITE_UNLOCK(&ip_conntrack_lock);
-+      
-+      return NF_ACCEPT;       /* unused */
-+}
-+
-+static int h225_help(const struct iphdr *iph, size_t len,
-+                   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;
-+      unsigned char *data_limit;
-+      u_int32_t tcplen = len - iph->ihl * 4;
-+      u_int32_t datalen = tcplen - tcph->doff * 4;
-+      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;
-+      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));
-+
-+      /* 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) {
-+              DEBUGP("ct_h225_help: Conntrackinfo = %u\n", ctinfo);
-+              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);
-+              return NF_ACCEPT;
-+      }
-+
-+      /* Checksum invalid?  Ignore. */
-+      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));
-+              return NF_ACCEPT;
-+      }
-+      
-+      data_limit = (unsigned char *) data + datalen;
-+      /* bytes: 0123   45
-+                ipadrr port */
-+      for (i = 0; data < (data_limit - 5); data++, i++) {
-+              memcpy(&data_ip, data, sizeof(u_int32_t));
-+              if (data_ip == iph->saddr) {
-+                      memcpy(&data_port, data + 4, sizeof(u_int16_t));
-+                      if (data_port == tcph->source) {
-+                              /* 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
-+                              LOCK_BH(&ip_h323_lock);
-+                              info->dir = dir;
-+                              info->seq[IP_CT_DIR_ORIGINAL] = ntohl(tcph->seq) + i;
-+                              info->offset[IP_CT_DIR_ORIGINAL] = i;
-+                              UNLOCK_BH(&ip_h323_lock);
-+#endif
-+                      } else {
-+                              memset(&expect, 0, sizeof(expect));
-+
-+                              /* update the H.225 info */
-+                              LOCK_BH(&ip_h323_lock);
-+                              info->is_h225 = H225_PORT;
-+                              exp_info->port = data_port;
-+                              exp_info->dir = dir;
-+                              exp_info->offset = i;
-+
-+                              exp->seq = ntohl(tcph->seq) + i;
-+
-+                              exp->tuple = ((struct ip_conntrack_tuple)
-+                                      { { ct->tuplehash[!dir].tuple.src.ip,
-+                                          { 0 } },
-+                                        { data_ip,
-+                                          { data_port },
-+                                          IPPROTO_TCP }});
-+                              exp->mask = ((struct ip_conntrack_tuple)
-+                                      { { 0xFFFFFFFF, { 0 } },
-+                                        { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }});
-+      
-+                              exp->expectfn = h225_expect;
-+                              
-+                              /* Ignore failure */
-+                              ip_conntrack_expect_related(ct, exp);
-+
-+                              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) {
-+                      memcpy(&data_port, data + 4, sizeof(u_int16_t));
-+                      if (data_port == tcph->dest) {
-+                              /* 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! */
-+                              LOCK_BH(&ip_h323_lock);
-+                              info->dir = dir;
-+                              info->seq[IP_CT_DIR_REPLY] = ntohl(tcph->seq) + i;
-+                              info->offset[IP_CT_DIR_REPLY] = i;
-+                              UNLOCK_BH(&ip_h323_lock);
-+                      }
-+#endif
-+              }
-+      }
-+
-+      return NF_ACCEPT;
-+
-+}
-+
-+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 int __init init(void)
-+{
-+      return ip_conntrack_helper_register(&h225);
-+}
-+
-+static void __exit fini(void)
-+{
-+      /* Unregister H.225 helper */   
-+      ip_conntrack_helper_unregister(&h225);
-+}
-+
-+#ifdef CONFIG_IP_NF_NAT_NEEDED
-+EXPORT_SYMBOL(ip_h323_lock);
-+#endif
-+
-+module_init(init);
-+module_exit(fini);
---- /dev/null
-+++ b/net/ipv4/netfilter/ip_nat_h323.c
-@@ -0,0 +1,403 @@
-+/* 
-+ * H.323 'brute force' extension for NAT alteration. 
-+ * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
-+ *
-+ * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project.
-+ * (http://www.coritel.it/projects/sofia/nat.html)
-+ * Uses Sampsa Ranta's excellent idea on using expectfn to 'bind'
-+ * the unregistered helpers to the conntrack entries.
-+ */
-+
-+
-+#include <linux/module.h>
-+#include <linux/netfilter.h>
-+#include <linux/ip.h>
-+#include <net/checksum.h>
-+#include <net/tcp.h>
-+
-+#include <linux/netfilter_ipv4/lockhelp.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_tuple.h>
-+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
-+#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
-+
-+MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
-+MODULE_DESCRIPTION("H.323 'brute force' connection tracking module");
-+MODULE_LICENSE("GPL");
-+
-+DECLARE_LOCK_EXTERN(ip_h323_lock);
-+struct module *ip_nat_h323 = THIS_MODULE;
-+
-+#define DEBUGP(format, args...)
-+
-+
-+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 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 */
-+      };
-+
-+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;
-+      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->expectant->help.ct_h225_info;
-+      exp_info = &ct->master->help.exp_h225_info;
-+
-+      LOCK_BH(&ip_h323_lock);
-+
-+      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;
-+      UNLOCK_BH(&ip_h323_lock);
-+      
-+      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));
-+
-+      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;
-+
-+      /* ... 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
-+                      = ((union ip_conntrack_manip_proto)
-+                              { port });
-+      }
-+
-+      ret = ip_nat_setup_info(ct, &mr, 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 */
-+              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 = (void *)iph + iph->ihl*4;
-+      unsigned char *data;
-+      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;
-+      u_int8_t buffer[6];
-+      int i;
-+
-+      MUST_BE_LOCKED(&ip_h323_lock);
-+
-+      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) {
-+                      newip = ct->tuplehash[!info->dir].tuple.dst.ip;
-+                      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;
-+              }
-+
-+              data = (char *) tcph + tcph->doff * 4 + info->offset[i];
-+
-+              DEBUGP("h323_signal_address_fixup: orig %s IP:port %u.%u.%u.%u:%u\n", 
-+                      i == IP_CT_DIR_ORIGINAL ? "source" : "dest  ", 
-+                      data[0], data[1], data[2], data[3],
-+                      (data[4] << 8 | data[5]));
-+
-+              /* Modify the packet */
-+              memcpy(buffer, &newip, 4);
-+              memcpy(buffer + 4, &port, 2);
-+              if (!ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, info->offset[i],
-+                                            6, buffer, 6))
-+                      return 0;
-+
-+              DEBUGP("h323_signal_address_fixup:  new %s IP:port %u.%u.%u.%u:%u\n", 
-+                      i == IP_CT_DIR_ORIGINAL ? "source" : "dest  ", 
-+                      data[0], data[1], data[2], data[3],
-+                      (data[4] << 8 | data[5]));
-+      }
-+
-+      return 1;
-+}
-+
-+static int h323_data_fixup(struct ip_ct_h225_expect *info,
-+                         struct ip_conntrack *ct,
-+                         struct sk_buff **pskb,
-+                         enum ip_conntrack_info ctinfo,
-+                         struct ip_conntrack_expect *expect)
-+{
-+      u_int32_t newip;
-+      u_int16_t port;
-+      u_int8_t buffer[6];
-+      struct ip_conntrack_tuple newtuple;
-+      struct iphdr *iph = (*pskb)->nh.iph;
-+      struct tcphdr *tcph = (void *)iph + iph->ihl*4;
-+      unsigned char *data;
-+      u_int32_t tcplen = (*pskb)->len - iph->ihl*4;
-+      struct ip_ct_h225_master *master_info = &ct->help.ct_h225_info;
-+      int is_h225;
-+
-+      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);
-+      DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
-+
-+      if (!between(expect->seq + 6, ntohl(tcph->seq),
-+                  ntohl(tcph->seq) + tcplen - tcph->doff * 4)) {
-+              /* Partial retransmisison. It's a cracker being funky. */
-+              if (net_ratelimit()) {
-+                      printk("H.323_NAT: partial packet %u/6 in %u/%u\n",
-+                           expect->seq,
-+                           ntohl(tcph->seq),
-+                           ntohl(tcph->seq) + tcplen - tcph->doff * 4);
-+              }
-+              return 0;
-+      }
-+
-+      /* 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 */
-+              newip = 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;
-+              /* 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 (port = ntohs(info->port); port != 0; port++) {
-+              if (is_h225)
-+                      newtuple.dst.u.tcp.port = htons(port);
-+              else
-+                      newtuple.dst.u.udp.port = htons(port);
-+
-+              if (ip_conntrack_change_expect(expect, &newtuple) == 0)
-+                      break;
-+      }
-+      if (port == 0) {
-+              DEBUGP("h323_data_fixup: no free port found!\n");
-+              return 0;
-+      }
-+
-+      port = htons(port);
-+
-+      data = (char *) tcph + tcph->doff * 4 + info->offset;
-+
-+      DEBUGP("h323_data_fixup: orig IP:port %u.%u.%u.%u:%u\n", 
-+              data[0], data[1], data[2], data[3],
-+              (data[4] << 8 | data[5]));
-+
-+      /* Modify the packet */
-+      memcpy(buffer, &newip, 4);
-+      memcpy(buffer + 4, &port, 2);
-+      if (!ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, info->offset,
-+                                    6, buffer, 6))
-+              return 0;
-+      
-+      DEBUGP("h323_data_fixup: new IP:port %u.%u.%u.%u:%u\n", 
-+              data[0], data[1], data[2], data[3],
-+              (data[4] << 8 | data[5]));
-+
-+      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)
-+{
-+      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);
-+      DEBUGP("nat_h323: dir %s at hook %s\n",
-+             dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
-+             hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
-+             : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
-+             : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???");
-+      if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
-+            || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) {
-+              DEBUGP("nat_h323: Not touching dir %s at hook %s\n",
-+                     dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
-+                     hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
-+                     : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
-+                     : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???");
-+              return NF_ACCEPT;
-+      }
-+
-+      if (!exp) {
-+              LOCK_BH(&ip_h323_lock);
-+              if (!h323_signal_address_fixup(ct, pskb, ctinfo)) {
-+                      UNLOCK_BH(&ip_h323_lock);
-+                      return NF_DROP;
-+              }
-+              UNLOCK_BH(&ip_h323_lock);
-+              return NF_ACCEPT;
-+      }
-+              
-+      exp_info = &exp->help.exp_h225_info;
-+
-+      LOCK_BH(&ip_h323_lock);
-+      if (!h323_data_fixup(exp_info, ct, pskb, ctinfo, exp)) {
-+              UNLOCK_BH(&ip_h323_lock);
-+              return NF_DROP;
-+      }
-+      UNLOCK_BH(&ip_h323_lock);
-+
-+      return NF_ACCEPT;
-+}
-+
-+static struct ip_nat_helper h225 = 
-+      { { NULL, NULL },
-+        "H.225",                                      /* name */
-+        IP_NAT_HELPER_F_ALWAYS,                       /* flags */
-+        THIS_MODULE,                                  /* module */
-+        { { 0, { __constant_htons(H225_PORT) } },     /* tuple */
-+          { 0, { 0 }, IPPROTO_TCP } },
-+        { { 0, { 0xFFFF } },                          /* mask */
-+          { 0, { 0 }, 0xFFFF } },
-+        h225_nat_help,                                /* helper */
-+        h225_nat_expected                             /* expectfn */
-+      };
-+
-+static int __init init(void)
-+{
-+      int ret;
-+      
-+      ret = ip_nat_helper_register(&h225);
-+
-+      if (ret != 0)
-+              printk("ip_nat_h323: cannot initialize the module!\n");
-+
-+      return ret;
-+}
-+
-+static void __exit fini(void)
-+{
-+      ip_nat_helper_unregister(&h225);
-+}
-+
-+module_init(init);
-+module_exit(fini);
---- a/include/linux/netfilter_ipv4/ip_conntrack.h
-+++ b/include/linux/netfilter_ipv4/ip_conntrack.h
-@@ -67,6 +67,7 @@ union ip_conntrack_expect_proto {
- #include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
- #include <linux/netfilter_ipv4/ip_conntrack_irc.h>
-+#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
- /* per expectation: application helper private data */
- union ip_conntrack_expect_help {
-@@ -74,6 +75,7 @@ union ip_conntrack_expect_help {
-       struct ip_ct_amanda_expect exp_amanda_info;
-       struct ip_ct_ftp_expect exp_ftp_info;
-       struct ip_ct_irc_expect exp_irc_info;
-+      struct ip_ct_h225_expect exp_h225_info;
- #ifdef CONFIG_IP_NF_NAT_NEEDED
-       union {
-@@ -87,6 +89,7 @@ union ip_conntrack_help {
-       /* insert conntrack helper private data (master) here */
-       struct ip_ct_ftp_master ct_ftp_info;
-       struct ip_ct_irc_master ct_irc_info;
-+      struct ip_ct_h225_master ct_h225_info;
- };
- #ifdef CONFIG_IP_NF_NAT_NEEDED
---- /dev/null
-+++ b/include/linux/netfilter_ipv4/ip_conntrack_h323.h
-@@ -0,0 +1,30 @@
-+#ifndef _IP_CONNTRACK_H323_H
-+#define _IP_CONNTRACK_H323_H
-+/* H.323 connection tracking. */
-+
-+#ifdef __KERNEL__
-+/* Protects H.323 related data */
-+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
-+};
-+
-+#endif /* _IP_CONNTRACK_H323_H */