Added support for the H323 connection tracking module
SVN-Revision: 2639
This commit is contained in:
parent
87a9a4bf58
commit
f922715fbb
3 changed files with 825 additions and 0 deletions
|
@ -363,6 +363,7 @@ CONFIG_IP_NF_MATCH_CONNBYTES=m
|
||||||
CONFIG_IP_NF_CT_PROTO_GRE=m
|
CONFIG_IP_NF_CT_PROTO_GRE=m
|
||||||
CONFIG_IP_NF_PPTP=m
|
CONFIG_IP_NF_PPTP=m
|
||||||
CONFIG_IP_NF_SIP=m
|
CONFIG_IP_NF_SIP=m
|
||||||
|
CONFIG_IP_NF_H323=m
|
||||||
CONFIG_IP_NF_QUEUE=m
|
CONFIG_IP_NF_QUEUE=m
|
||||||
CONFIG_IP_NF_IPTABLES=y
|
CONFIG_IP_NF_IPTABLES=y
|
||||||
CONFIG_IP_NF_MATCH_LIMIT=m
|
CONFIG_IP_NF_MATCH_LIMIT=m
|
||||||
|
@ -412,6 +413,7 @@ CONFIG_IP_NF_TARGET_REDIRECT=m
|
||||||
CONFIG_IP_NF_TARGET_NETMAP=m
|
CONFIG_IP_NF_TARGET_NETMAP=m
|
||||||
CONFIG_IP_NF_NAT_PPTP=m
|
CONFIG_IP_NF_NAT_PPTP=m
|
||||||
CONFIG_IP_NF_NAT_SIP=m
|
CONFIG_IP_NF_NAT_SIP=m
|
||||||
|
CONFIG_IP_NF_NAT_H323=m
|
||||||
CONFIG_IP_NF_NAT_PROTO_GRE=m
|
CONFIG_IP_NF_NAT_PROTO_GRE=m
|
||||||
CONFIG_IP_NF_NAT_AMANDA=m
|
CONFIG_IP_NF_NAT_AMANDA=m
|
||||||
CONFIG_IP_NF_NAT_SNMP_BASIC=m
|
CONFIG_IP_NF_NAT_SNMP_BASIC=m
|
||||||
|
|
|
@ -287,6 +287,7 @@ CONFIG_IP_NF_MATCH_CONNBYTES=m
|
||||||
CONFIG_IP_NF_CT_PROTO_GRE=m
|
CONFIG_IP_NF_CT_PROTO_GRE=m
|
||||||
CONFIG_IP_NF_PPTP=m
|
CONFIG_IP_NF_PPTP=m
|
||||||
CONFIG_IP_NF_SIP=m
|
CONFIG_IP_NF_SIP=m
|
||||||
|
CONFIG_IP_NF_H323=m
|
||||||
CONFIG_IP_NF_QUEUE=m
|
CONFIG_IP_NF_QUEUE=m
|
||||||
CONFIG_IP_NF_IPTABLES=y
|
CONFIG_IP_NF_IPTABLES=y
|
||||||
CONFIG_IP_NF_MATCH_LIMIT=m
|
CONFIG_IP_NF_MATCH_LIMIT=m
|
||||||
|
@ -336,6 +337,7 @@ CONFIG_IP_NF_TARGET_REDIRECT=m
|
||||||
CONFIG_IP_NF_TARGET_NETMAP=m
|
CONFIG_IP_NF_TARGET_NETMAP=m
|
||||||
CONFIG_IP_NF_NAT_PPTP=m
|
CONFIG_IP_NF_NAT_PPTP=m
|
||||||
CONFIG_IP_NF_NAT_SIP=m
|
CONFIG_IP_NF_NAT_SIP=m
|
||||||
|
CONFIG_IP_NF_NAT_H323=m
|
||||||
CONFIG_IP_NF_NAT_PROTO_GRE=m
|
CONFIG_IP_NF_NAT_PROTO_GRE=m
|
||||||
CONFIG_IP_NF_NAT_AMANDA=m
|
CONFIG_IP_NF_NAT_AMANDA=m
|
||||||
CONFIG_IP_NF_NAT_SNMP_BASIC=m
|
CONFIG_IP_NF_NAT_SNMP_BASIC=m
|
||||||
|
|
|
@ -0,0 +1,821 @@
|
||||||
|
diff -urN linux-2.4.32/net/ipv4/netfilter/Config.in linux-2.4.32/net/ipv4/netfilter/Config.in
|
||||||
|
--- linux-2.4.32/net/ipv4/netfilter/Config.in 2005-12-12 11:13:17.000000000 +0100
|
||||||
|
+++ linux-2.4.32/net/ipv4/netfilter/Config.in 2005-12-12 11:18:47.000000000 +0100
|
||||||
|
@@ -16,6 +16,7 @@
|
||||||
|
dep_tristate ' GRE protocol support' CONFIG_IP_NF_CT_PROTO_GRE $CONFIG_IP_NF_CONNTRACK
|
||||||
|
dep_tristate ' PPTP protocol support' CONFIG_IP_NF_PPTP $CONFIG_IP_NF_CT_PROTO_GRE
|
||||||
|
dep_tristate ' SIP protocol support' CONFIG_IP_NF_SIP $CONFIG_IP_NF_CONNTRACK
|
||||||
|
+ dep_tristate ' H.323 (netmeeting) support' CONFIG_IP_NF_H323 $CONFIG_IP_NF_CONNTRACK
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
|
||||||
|
@@ -112,6 +113,13 @@
|
||||||
|
define_tristate CONFIG_IP_NF_NAT_SIP $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_IP_NF_AMANDA" = "m" ]; then
|
||||||
|
define_tristate CONFIG_IP_NF_NAT_AMANDA m
|
||||||
|
else
|
||||||
|
diff -urN linux-2.4.32/net/ipv4/netfilter/Makefile linux-2.4.32/net/ipv4/netfilter/Makefile
|
||||||
|
--- linux-2.4.32/net/ipv4/netfilter/Makefile 2005-12-12 11:13:17.000000000 +0100
|
||||||
|
+++ linux-2.4.32/net/ipv4/netfilter/Makefile 2005-12-12 11:17:37.000000000 +0100
|
||||||
|
@@ -57,6 +57,10 @@
|
||||||
|
ifdef CONFIG_IP_NF_NAT_SIP
|
||||||
|
export-objs += ip_conntrack_sip.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
|
||||||
|
@@ -67,6 +71,7 @@
|
||||||
|
obj-$(CONFIG_IP_NF_NAT_PROTO_GRE) += ip_nat_proto_gre.o
|
||||||
|
obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o
|
||||||
|
obj-$(CONFIG_IP_NF_NAT_SIP) += ip_nat_sip.o
|
||||||
|
+obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o
|
||||||
|
|
||||||
|
# generic IP tables
|
||||||
|
obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
|
||||||
|
diff -urN linux-2.4.32/net/ipv4/netfilter/ip_conntrack_h323.c linux-2.4.32/net/ipv4/netfilter/ip_conntrack_h323.c
|
||||||
|
--- linux-2.4.32/net/ipv4/netfilter/ip_conntrack_h323.c 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ linux-2.4.32/net/ipv4/netfilter/ip_conntrack_h323.c 2005-12-12 11:14:54.000000000 +0100
|
||||||
|
@@ -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);
|
||||||
|
diff -urN linux-2.4.32/net/ipv4/netfilter/ip_nat_h323.c /linux-2.4.32/net/ipv4/netfilter/ip_nat_h323.c
|
||||||
|
--- linux-2.4.32/net/ipv4/netfilter/ip_nat_h323.c 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ linux-2.4.32/net/ipv4/netfilter/ip_nat_h323.c 2005-12-12 11:14:54.000000000 +0100
|
||||||
|
@@ -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);
|
||||||
|
diff -urN linux-2.4.32/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.4.32/include/linux/netfilter_ipv4/ip_conntrack.h
|
||||||
|
--- linux-2.4.32/include/linux/netfilter_ipv4/ip_conntrack.h 2005-12-12 11:13:17.000000000 +0100
|
||||||
|
+++ linux-2.4.32/include/linux/netfilter_ipv4/ip_conntrack.h 2005-12-12 11:16:13.000000000 +0100
|
||||||
|
@@ -72,6 +72,7 @@
|
||||||
|
#include <linux/netfilter_ipv4/ip_conntrack_irc.h>
|
||||||
|
#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
|
||||||
|
#include <linux/netfilter_ipv4/ip_conntrack_sip.h>
|
||||||
|
+#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
|
||||||
|
|
||||||
|
/* per expectation: application helper private data */
|
||||||
|
union ip_conntrack_expect_help {
|
||||||
|
@@ -81,6 +82,7 @@
|
||||||
|
struct ip_ct_irc_expect exp_irc_info;
|
||||||
|
struct ip_ct_pptp_expect exp_pptp_info;
|
||||||
|
struct ip_ct_sip_expect exp_sip_info;
|
||||||
|
+ struct ip_ct_h225_expect exp_h225_info;
|
||||||
|
|
||||||
|
#ifdef CONFIG_IP_NF_NAT_NEEDED
|
||||||
|
union {
|
||||||
|
@@ -96,6 +98,7 @@
|
||||||
|
struct ip_ct_irc_master ct_irc_info;
|
||||||
|
struct ip_ct_pptp_master ct_pptp_info;
|
||||||
|
struct ip_ct_sip_master ct_sip_info;
|
||||||
|
+ struct ip_ct_h225_master ct_h225_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_IP_NF_NAT_NEEDED
|
||||||
|
diff -urN linux-2.4.32/include/linux/netfilter_ipv4/ip_conntrack_h323.h linux-2.4.32/include/linux/netfilter_ipv4/ip_conntrack_h323.h
|
||||||
|
--- linux-2.4.32/include/linux/netfilter_ipv4/ip_conntrack_h323.h 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ linux-2.4.32/include/linux/netfilter_ipv4/ip_conntrack_h323.h 2005-12-12 11:14:54.000000000 +0100
|
||||||
|
@@ -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 */
|
Loading…
Reference in a new issue