[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