[netfilter-cvslog] r4261 - in
trunk/patch-o-matic-ng/patchlets/h323-conntrack-nat:
linux-2.6.11/net/ipv4/netfilter linux-2.6.12/net/ipv4/netfilter
gandalf at netfilter.org
gandalf at netfilter.org
Wed Sep 14 21:17:43 CEST 2005
Author: gandalf at netfilter.org
Date: 2005-09-14 21:17:42 +0200 (Wed, 14 Sep 2005)
New Revision: 4261
Removed:
trunk/patch-o-matic-ng/patchlets/h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323.c
trunk/patch-o-matic-ng/patchlets/h323-conntrack-nat/linux-2.6.12/net/ipv4/netfilter/ip_conntrack_h323.c
Log:
Remove ip_conntrack_h323.c since it was split up into multiple files.
Deleted: trunk/patch-o-matic-ng/patchlets/h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323.c 2005-09-14 10:36:01 UTC (rev 4260)
+++ trunk/patch-o-matic-ng/patchlets/h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323.c 2005-09-14 19:17:42 UTC (rev 4261)
@@ -1,448 +0,0 @@
-/*
- * H.323 'brute force' extension for H.323 connection tracking.
- * Jozsef Kadlecsik <kadlec at blackhole.kfki.hu>
- * (c) 2005 Max Kellermann <max at duempel.org>
- *
- * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project.
- * (http://www.coritel.it/projects/sofia/nat/)
- * 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 at blackhole.kfki.hu>");
-MODULE_DESCRIPTION("H.323 'brute force' connection tracking module");
-MODULE_LICENSE("GPL");
-
-/* This is slow, but it's simple. --RR */
-static char h323_buffer[65536];
-
-static DECLARE_LOCK(ip_h323_lock);
-
-struct module *ip_conntrack_h323 = THIS_MODULE;
-
-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
-#define DEBUGP(format, args...)
-#endif
-
-/* FIXME: This should be in userspace. Later. */
-static int h245_help(struct sk_buff **pskb,
- struct ip_conntrack *ct,
- enum ip_conntrack_info ctinfo)
-{
- struct tcphdr _tcph, *tcph;
- unsigned char *data;
- unsigned char *data_limit;
- unsigned dataoff, datalen;
- int dir = CTINFO2DIR(ctinfo);
- struct ip_conntrack_expect *exp;
- u_int16_t data_port;
- u_int32_t data_ip;
- unsigned int i;
- int ret;
-
- /* 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;
- }
-
- tcph = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl*4,
- sizeof(_tcph), &_tcph);
- if (tcph == NULL)
- return NF_ACCEPT;
-
- DEBUGP("ct_h245_help: help entered %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
- 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? */
- if (dataoff >= (*pskb)->len) {
- DEBUGP("ct_h245_help: skblen = %u\n", (*pskb)->len);
- return NF_ACCEPT;
- }
- datalen = (*pskb)->len - dataoff;
-
- LOCK_BH(&ip_h323_lock);
- data = skb_header_pointer((*pskb), dataoff,
- datalen, h323_buffer);
- BUG_ON(data == NULL);
-
- data_limit = data + datalen - 6;
- /* bytes: 0123 45
- ipadrr port */
- for (i = 0; data <= data_limit; data++, i++) {
- data_ip = *((u_int32_t *)data);
- 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((*pskb)->nh.iph->saddr), ntohs(data_port));
-
- exp = ip_conntrack_expect_alloc();
- if (exp == NULL) {
- ret = NF_ACCEPT;
- goto out;
- }
-
- exp->tuple = ((struct ip_conntrack_tuple)
- { { ct->tuplehash[!dir].tuple.src.ip,
- { 0 } },
- { data_ip,
- { .tcp = { data_port } },
- IPPROTO_UDP }});
- exp->mask = ((struct ip_conntrack_tuple)
- { { 0xFFFFFFFF, { 0 } },
- { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
-
- exp->expectfn = NULL;
- exp->master = ct;
-
- 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
- ret = NF_ACCEPT;
- }
-
- break;
- }
- }
-
- ret = NF_ACCEPT;
- out:
- UNLOCK_BH(&ip_h323_lock);
- return ret;
-}
-
-/* H.245 helper is not registered! */
-static struct ip_conntrack_helper h245 =
-{
- .name = "H.245",
- .max_expected = 8,
- .timeout = 240,
- .tuple = { .dst = { .protonum = IPPROTO_TCP } },
- .mask = { .src = { .u = { 0xFFFF } },
- .dst = { .protonum = 0xFF } },
- .help = h245_help
-};
-
-void ip_conntrack_h245_expect(struct ip_conntrack *new,
- struct ip_conntrack_expect *this)
-{
- WRITE_LOCK(&ip_conntrack_lock);
- new->helper = &h245;
- DEBUGP("h225_expect: helper for %p added\n", new);
- WRITE_UNLOCK(&ip_conntrack_lock);
-}
-EXPORT_SYMBOL_GPL(ip_conntrack_h245_expect);
-
-/**
- * Parse a Q.931 CONNECT packet and handle NAT/expectations for the
- * H.245 transport address.
- */
-static int h225_parse_q931_connect(struct sk_buff **pskb,
- struct ip_conntrack *ct,
- enum ip_conntrack_info ctinfo,
- const unsigned char *data,
- unsigned i, unsigned length)
-{
- int dir = CTINFO2DIR(ctinfo);
- u_int32_t data_ip;
- u_int16_t data_port;
- struct ip_conntrack_expect *exp;
-
- /* protocol(1) + header(3) + protocolIdentifier(6) +
- h245ipAddress(1) + h245ipv4(4) + h245ipv4port(2) */
- if (length < 17)
- return NF_ACCEPT;
-
- if (data[i++] != 0x05) /* X.208 / X.209 */
- return NF_ACCEPT;
-
- /* XXX: h225 header connect? */
- if (data[i++] != 0x22 || data[i++] != 0xc0 || data[i++] != 0x06)
- return NF_ACCEPT;
-
- /* protocolIdentifier, ignore the last 2 bytes (minor
- version) */
- if (memcmp(data + i, "\x00\x08\x91\x4a", 4) != 0)
- return NF_ACCEPT;
-
- i += 6;
-
- if (data[i++] != 0x00) /* h245ipAddress? */
- return NF_ACCEPT;
-
- /* compare the IP address - this is only a valid H.245
- transport address, if it equals the source address of the
- packet */
- data_ip = *(u_int32_t *)(data + i);
- if (data_ip != ct->tuplehash[dir].tuple.src.ip)
- return NF_ACCEPT;
-
-
- data_port = *((u_int16_t *)(data + i + 4));
-
- /* match found: create an expectation */
- exp = ip_conntrack_expect_alloc();
- if (exp == NULL)
- return NF_ACCEPT;
-
- exp->tuple = ((struct ip_conntrack_tuple)
- { { ct->tuplehash[!dir].tuple.src.ip,
- { 0 } },
- { ct->tuplehash[!dir].tuple.dst.ip,
- { .tcp = { data_port } },
- IPPROTO_TCP }});
- exp->mask = ((struct ip_conntrack_tuple)
- { { 0xFFFFFFFF, { 0 } },
- { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
-
- exp->expectfn = ip_conntrack_h245_expect;
- exp->master = ct;
-
- /* call NAT hook and register expectation */
- if (ip_nat_h225_hook != NULL) {
- return 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);
- return NF_DROP;
- } else {
- return NF_ACCEPT;
- }
- }
-}
-
-/**
- * Scan a Q.931 packet for a user-to-user information element
- * (IE). Return the index, or 0 if none found.
- */
-static unsigned q931_find_u2u(const unsigned char *data,
- unsigned datalen,
- unsigned int i,
- unsigned *lengthp) {
- unsigned char type;
- unsigned length;
-
- /* traverse all Q.931 information elements (IE) */
- while (i + 2 <= datalen) {
- type = data[i++];
-
- /* highest bit set means one-byte IE */
- if (type & 0x80)
- continue;
-
- length = data[i++];
-
- if (type == 0x7e) { /* user-to-user */
- /* user-to-user IEs have a 16 bit length
- field */
- length = (length << 8) | data[i++];
- if (i + length > datalen)
- return 0;
-
- *lengthp = length;
- return i;
- }
-
- i += length;
- }
-
- return 0;
-}
-
-/**
- * Parse a Q.931/H.225 packet and handle NAT/expectations for the
- * H.245 transport address (if applicable).
- */
-static int h225_parse_q931(struct sk_buff **pskb,
- struct ip_conntrack *ct,
- enum ip_conntrack_info ctinfo,
- const unsigned char *data,
- unsigned datalen, unsigned i) {
- u_int8_t q931_message_type;
- unsigned length;
-
- /* parse Q.931 packet */
- if (data[i++] != 0x08) /* protocol discriminator */
- return NF_ACCEPT;
-
- /* call reference */
- i += 1 + data[i];
- if (i >= datalen)
- return NF_ACCEPT;
-
- /* only some Q.931 message types can contain a H.245 transport
- address - we can ignore the rest in this module */
- q931_message_type = data[i++];
- if (q931_message_type == 0x07) {
- /* CONNECT */
-
- /* find a user-to-user information element (IE) */
- i = q931_find_u2u(data, datalen, i, &length);
- if (i == 0)
- return NF_ACCEPT;
-
- return h225_parse_q931_connect(pskb, ct, ctinfo,
- data, i, length);
- } else {
- /* XXX handle q931_message_type 0x01, 0x02, 0x03 */
- return NF_ACCEPT;
- }
-}
-
-/**
- * Parse a TPKT/Q.931/H.225 packet and handle NAT/expectations for the
- * H.245 transport address (if applicable).
- */
-static int h225_parse_tpkt(struct sk_buff **pskb,
- struct ip_conntrack *ct,
- enum ip_conntrack_info ctinfo,
- const unsigned char *data,
- unsigned datalen) {
- unsigned int i = 0;
- u_int16_t tpkt_len;
-
- /* expect TPKT header, see RFC 1006 */
- if (data[0] != 0x03 || data[1] != 0x00)
- return NF_ACCEPT;
-
- i += 2;
-
- tpkt_len = ntohs(*(u_int16_t*)(data + i));
- if (tpkt_len < 16)
- return NF_ACCEPT;
-
- if (tpkt_len < datalen)
- datalen = tpkt_len;
-
- i += 2;
-
- /* parse Q.931 packet */
- return h225_parse_q931(pskb, ct, ctinfo,
- data, datalen, i);
-}
-
-static int h225_help(struct sk_buff **pskb,
- struct ip_conntrack *ct,
- enum ip_conntrack_info ctinfo)
-{
- struct tcphdr _tcph, *tcph;
- unsigned char *data;
- unsigned dataoff, datalen;
- int ret = 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;
- }
-
- 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((*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? */
- if (dataoff >= (*pskb)->len) {
- DEBUGP("ct_h225_help: skblen = %u\n", (*pskb)->len);
- return NF_ACCEPT;
- }
- datalen = (*pskb)->len - dataoff;
-
- if (datalen < 32)
- return NF_ACCEPT;
-
- /* get data portion, and evaluate it */
- LOCK_BH(&ip_h323_lock);
- data = skb_header_pointer((*pskb), dataoff,
- datalen, h323_buffer);
- BUG_ON(data == NULL);
-
- ret = h225_parse_tpkt(pskb, ct, ctinfo,
- data, datalen);
-
- UNLOCK_BH(&ip_h323_lock);
- return ret;
-}
-
-static struct ip_conntrack_helper h225 =
-{
- .name = "H.225",
- .me = THIS_MODULE,
- .max_expected = 2,
- .timeout = 240,
- .tuple = { .src = { .u = { __constant_htons(H225_PORT) } },
- .dst = { .protonum = IPPROTO_TCP } },
- .mask = { .src = { .u = { 0xFFFF } },
- .dst = { .protonum = 0xFF } },
- .help = h225_help
-};
-
-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);
-}
-
-module_init(init);
-module_exit(fini);
Deleted: trunk/patch-o-matic-ng/patchlets/h323-conntrack-nat/linux-2.6.12/net/ipv4/netfilter/ip_conntrack_h323.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/h323-conntrack-nat/linux-2.6.12/net/ipv4/netfilter/ip_conntrack_h323.c 2005-09-14 10:36:01 UTC (rev 4260)
+++ trunk/patch-o-matic-ng/patchlets/h323-conntrack-nat/linux-2.6.12/net/ipv4/netfilter/ip_conntrack_h323.c 2005-09-14 19:17:42 UTC (rev 4261)
@@ -1,447 +0,0 @@
-/*
- * H.323 'brute force' extension for H.323 connection tracking.
- * Jozsef Kadlecsik <kadlec at blackhole.kfki.hu>
- * (c) 2005 Max Kellermann <max at duempel.org>
- *
- * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project.
- * (http://www.coritel.it/projects/sofia/nat/)
- * 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/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 at blackhole.kfki.hu>");
-MODULE_DESCRIPTION("H.323 'brute force' connection tracking module");
-MODULE_LICENSE("GPL");
-
-/* This is slow, but it's simple. --RR */
-static char h323_buffer[65536];
-
-static DEFINE_SPINLOCK(ip_h323_lock);
-
-struct module *ip_conntrack_h323 = THIS_MODULE;
-
-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
-#define DEBUGP(format, args...)
-#endif
-
-/* FIXME: This should be in userspace. Later. */
-static int h245_help(struct sk_buff **pskb,
- struct ip_conntrack *ct,
- enum ip_conntrack_info ctinfo)
-{
- struct tcphdr _tcph, *tcph;
- unsigned char *data;
- unsigned char *data_limit;
- unsigned dataoff, datalen;
- int dir = CTINFO2DIR(ctinfo);
- struct ip_conntrack_expect *exp;
- u_int16_t data_port;
- u_int32_t data_ip;
- unsigned int i;
- int ret;
-
- /* 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;
- }
-
- tcph = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl*4,
- sizeof(_tcph), &_tcph);
- if (tcph == NULL)
- return NF_ACCEPT;
-
- DEBUGP("ct_h245_help: help entered %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
- 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? */
- if (dataoff >= (*pskb)->len) {
- DEBUGP("ct_h245_help: skblen = %u\n", (*pskb)->len);
- return NF_ACCEPT;
- }
- datalen = (*pskb)->len - dataoff;
-
- spin_lock_bh(&ip_h323_lock);
- data = skb_header_pointer((*pskb), dataoff,
- datalen, h323_buffer);
- BUG_ON(data == NULL);
-
- data_limit = data + datalen - 6;
- /* bytes: 0123 45
- ipadrr port */
- for (i = 0; data <= data_limit; data++, i++) {
- data_ip = *((u_int32_t *)data);
- 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((*pskb)->nh.iph->saddr), ntohs(data_port));
-
- exp = ip_conntrack_expect_alloc();
- if (exp == NULL) {
- ret = NF_ACCEPT;
- goto out;
- }
-
- exp->tuple = ((struct ip_conntrack_tuple)
- { { ct->tuplehash[!dir].tuple.src.ip,
- { 0 } },
- { data_ip,
- { .tcp = { data_port } },
- IPPROTO_UDP }});
- exp->mask = ((struct ip_conntrack_tuple)
- { { 0xFFFFFFFF, { 0 } },
- { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
-
- exp->expectfn = NULL;
- exp->master = ct;
-
- 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
- ret = NF_ACCEPT;
- }
-
- break;
- }
- }
-
- ret = NF_ACCEPT;
- out:
- spin_unlock_bh(&ip_h323_lock);
- return ret;
-}
-
-/* H.245 helper is not registered! */
-static struct ip_conntrack_helper h245 =
-{
- .name = "H.245",
- .max_expected = 8,
- .timeout = 240,
- .tuple = { .dst = { .protonum = IPPROTO_TCP } },
- .mask = { .src = { .u = { 0xFFFF } },
- .dst = { .protonum = 0xFF } },
- .help = h245_help
-};
-
-void ip_conntrack_h245_expect(struct ip_conntrack *new,
- struct ip_conntrack_expect *this)
-{
- write_lock_bh(&ip_conntrack_lock);
- new->helper = &h245;
- DEBUGP("h225_expect: helper for %p added\n", new);
- write_unlock_bh(&ip_conntrack_lock);
-}
-EXPORT_SYMBOL_GPL(ip_conntrack_h245_expect);
-
-/**
- * Parse a Q.931 CONNECT packet and handle NAT/expectations for the
- * H.245 transport address.
- */
-static int h225_parse_q931_connect(struct sk_buff **pskb,
- struct ip_conntrack *ct,
- enum ip_conntrack_info ctinfo,
- const unsigned char *data,
- unsigned i, unsigned length)
-{
- int dir = CTINFO2DIR(ctinfo);
- u_int32_t data_ip;
- u_int16_t data_port;
- struct ip_conntrack_expect *exp;
-
- /* protocol(1) + header(3) + protocolIdentifier(6) +
- h245ipAddress(1) + h245ipv4(4) + h245ipv4port(2) */
- if (length < 17)
- return NF_ACCEPT;
-
- if (data[i++] != 0x05) /* X.208 / X.209 */
- return NF_ACCEPT;
-
- /* XXX: h225 header connect? */
- if (data[i++] != 0x22 || data[i++] != 0xc0 || data[i++] != 0x06)
- return NF_ACCEPT;
-
- /* protocolIdentifier, ignore the last 2 bytes (minor
- version) */
- if (memcmp(data + i, "\x00\x08\x91\x4a", 4) != 0)
- return NF_ACCEPT;
-
- i += 6;
-
- if (data[i++] != 0x00) /* h245ipAddress? */
- return NF_ACCEPT;
-
- /* compare the IP address - this is only a valid H.245
- transport address, if it equals the source address of the
- packet */
- data_ip = *(u_int32_t *)(data + i);
- if (data_ip != ct->tuplehash[dir].tuple.src.ip)
- return NF_ACCEPT;
-
-
- data_port = *((u_int16_t *)(data + i + 4));
-
- /* match found: create an expectation */
- exp = ip_conntrack_expect_alloc();
- if (exp == NULL)
- return NF_ACCEPT;
-
- exp->tuple = ((struct ip_conntrack_tuple)
- { { ct->tuplehash[!dir].tuple.src.ip,
- { 0 } },
- { ct->tuplehash[!dir].tuple.dst.ip,
- { .tcp = { data_port } },
- IPPROTO_TCP }});
- exp->mask = ((struct ip_conntrack_tuple)
- { { 0xFFFFFFFF, { 0 } },
- { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
-
- exp->expectfn = ip_conntrack_h245_expect;
- exp->master = ct;
-
- /* call NAT hook and register expectation */
- if (ip_nat_h225_hook != NULL) {
- return 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);
- return NF_DROP;
- } else {
- return NF_ACCEPT;
- }
- }
-}
-
-/**
- * Scan a Q.931 packet for a user-to-user information element
- * (IE). Return the index, or 0 if none found.
- */
-static unsigned q931_find_u2u(const unsigned char *data,
- unsigned datalen,
- unsigned int i,
- unsigned *lengthp) {
- unsigned char type;
- unsigned length;
-
- /* traverse all Q.931 information elements (IE) */
- while (i + 2 <= datalen) {
- type = data[i++];
-
- /* highest bit set means one-byte IE */
- if (type & 0x80)
- continue;
-
- length = data[i++];
-
- if (type == 0x7e) { /* user-to-user */
- /* user-to-user IEs have a 16 bit length
- field */
- length = (length << 8) | data[i++];
- if (i + length > datalen)
- return 0;
-
- *lengthp = length;
- return i;
- }
-
- i += length;
- }
-
- return 0;
-}
-
-/**
- * Parse a Q.931/H.225 packet and handle NAT/expectations for the
- * H.245 transport address (if applicable).
- */
-static int h225_parse_q931(struct sk_buff **pskb,
- struct ip_conntrack *ct,
- enum ip_conntrack_info ctinfo,
- const unsigned char *data,
- unsigned datalen, unsigned i) {
- u_int8_t q931_message_type;
- unsigned length;
-
- /* parse Q.931 packet */
- if (data[i++] != 0x08) /* protocol discriminator */
- return NF_ACCEPT;
-
- /* call reference */
- i += 1 + data[i];
- if (i >= datalen)
- return NF_ACCEPT;
-
- /* only some Q.931 message types can contain a H.245 transport
- address - we can ignore the rest in this module */
- q931_message_type = data[i++];
- if (q931_message_type == 0x07) {
- /* CONNECT */
-
- /* find a user-to-user information element (IE) */
- i = q931_find_u2u(data, datalen, i, &length);
- if (i == 0)
- return NF_ACCEPT;
-
- return h225_parse_q931_connect(pskb, ct, ctinfo,
- data, i, length);
- } else {
- /* XXX handle q931_message_type 0x01, 0x02, 0x03 */
- return NF_ACCEPT;
- }
-}
-
-/**
- * Parse a TPKT/Q.931/H.225 packet and handle NAT/expectations for the
- * H.245 transport address (if applicable).
- */
-static int h225_parse_tpkt(struct sk_buff **pskb,
- struct ip_conntrack *ct,
- enum ip_conntrack_info ctinfo,
- const unsigned char *data,
- unsigned datalen) {
- unsigned int i = 0;
- u_int16_t tpkt_len;
-
- /* expect TPKT header, see RFC 1006 */
- if (data[0] != 0x03 || data[1] != 0x00)
- return NF_ACCEPT;
-
- i += 2;
-
- tpkt_len = ntohs(*(u_int16_t*)(data + i));
- if (tpkt_len < 16)
- return NF_ACCEPT;
-
- if (tpkt_len < datalen)
- datalen = tpkt_len;
-
- i += 2;
-
- /* parse Q.931 packet */
- return h225_parse_q931(pskb, ct, ctinfo,
- data, datalen, i);
-}
-
-static int h225_help(struct sk_buff **pskb,
- struct ip_conntrack *ct,
- enum ip_conntrack_info ctinfo)
-{
- struct tcphdr _tcph, *tcph;
- unsigned char *data;
- unsigned dataoff, datalen;
- int ret = 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;
- }
-
- 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((*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? */
- if (dataoff >= (*pskb)->len) {
- DEBUGP("ct_h225_help: skblen = %u\n", (*pskb)->len);
- return NF_ACCEPT;
- }
- datalen = (*pskb)->len - dataoff;
-
- if (datalen < 32)
- return NF_ACCEPT;
-
- /* get data portion, and evaluate it */
- spin_lock_bh(&ip_h323_lock);
- data = skb_header_pointer((*pskb), dataoff,
- datalen, h323_buffer);
- BUG_ON(data == NULL);
-
- ret = h225_parse_tpkt(pskb, ct, ctinfo,
- data, datalen);
-
- spin_unlock_bh(&ip_h323_lock);
- return ret;
-}
-
-static struct ip_conntrack_helper h225 =
-{
- .name = "H.225",
- .me = THIS_MODULE,
- .max_expected = 2,
- .timeout = 240,
- .tuple = { .src = { .u = { __constant_htons(H225_PORT) } },
- .dst = { .protonum = IPPROTO_TCP } },
- .mask = { .src = { .u = { 0xFFFF } },
- .dst = { .protonum = 0xFF } },
- .help = h225_help
-};
-
-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);
-}
-
-module_init(init);
-module_exit(fini);
More information about the netfilter-cvslog
mailing list