Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c0d4cfd9 authored by Jing Min Zhao's avatar Jing Min Zhao Committed by David S. Miller
Browse files

[NETFILTER]: H.323 helper: Add support for Call Forwarding

parent c9526169
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -154,6 +154,7 @@ struct ip_conntrack_expect
	unsigned int flags;
	unsigned int flags;


#ifdef CONFIG_IP_NF_NAT_NEEDED
#ifdef CONFIG_IP_NF_NAT_NEEDED
	u_int32_t saved_ip;
	/* This is the original per-proto part, used to map the
	/* This is the original per-proto part, used to map the
	 * expected connection the way the recipient expects. */
	 * expected connection the way the recipient expects. */
	union ip_conntrack_manip_proto saved_proto;
	union ip_conntrack_manip_proto saved_proto;
+7 −0
Original line number Original line Diff line number Diff line
@@ -71,6 +71,13 @@ extern int (*nat_h245_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct,
			     unsigned char **data, int dataoff,
			     unsigned char **data, int dataoff,
			     TransportAddress * addr, u_int16_t port,
			     TransportAddress * addr, u_int16_t port,
			     struct ip_conntrack_expect * exp);
			     struct ip_conntrack_expect * exp);
extern int (*nat_callforwarding_hook) (struct sk_buff ** pskb,
				       struct ip_conntrack * ct,
				       enum ip_conntrack_info ctinfo,
				       unsigned char **data, int dataoff,
				       TransportAddress * addr,
				       u_int16_t port,
				       struct ip_conntrack_expect * exp);
extern int (*nat_q931_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct,
extern int (*nat_q931_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct,
			     enum ip_conntrack_info ctinfo,
			     enum ip_conntrack_info ctinfo,
			     unsigned char **data, TransportAddress * addr,
			     unsigned char **data, TransportAddress * addr,
+2 −1
Original line number Original line Diff line number Diff line
/* Generated by Jing Min Zhao's ASN.1 parser, Mar 15 2006
/* Generated by Jing Min Zhao's ASN.1 parser, Apr 20 2006
 *
 *
 * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net>
 * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net>
 *
 *
@@ -412,6 +412,7 @@ typedef struct Facility_UUIE { /* SEQUENCE */
		eFacility_UUIE_destinationInfo = (1 << 14),
		eFacility_UUIE_destinationInfo = (1 << 14),
		eFacility_UUIE_h245SecurityMode = (1 << 13),
		eFacility_UUIE_h245SecurityMode = (1 << 13),
	} options;
	} options;
	TransportAddress alternativeAddress;
	FacilityReason reason;
	FacilityReason reason;
	TransportAddress h245Address;
	TransportAddress h245Address;
	Facility_UUIE_fastStart fastStart;
	Facility_UUIE_fastStart fastStart;
+4 −4
Original line number Original line Diff line number Diff line
@@ -183,10 +183,10 @@ config IP_NF_H323
	  With this module you can support H.323 on a connection tracking/NAT
	  With this module you can support H.323 on a connection tracking/NAT
	  firewall.
	  firewall.


	  This module supports RAS, Fast-start, H.245 tunnelling, RTP/RTCP
	  This module supports RAS, Fast Start, H.245 Tunnelling, Call
	  and T.120 based data and applications including audio, video, FAX,
	  Forwarding, RTP/RTCP and T.120 based audio, video, fax, chat,
	  chat, whiteboard, file transfer, etc. For more information, please
	  whiteboard, file transfer, etc. For more information, please
	  see http://nath323.sourceforge.net/.
	  visit http://nath323.sourceforge.net/.


	  If you want to compile it as a module, say 'M' here and read
	  If you want to compile it as a module, say 'M' here and read
	  Documentation/modules.txt.  If unsure, say 'N'.
	  Documentation/modules.txt.  If unsure, say 'N'.
+112 −0
Original line number Original line Diff line number Diff line
@@ -22,6 +22,8 @@
#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
#include <linux/moduleparam.h>
#include <linux/moduleparam.h>
#include <linux/ctype.h>
#include <linux/inet.h>


#if 0
#if 0
#define DEBUGP printk
#define DEBUGP printk
@@ -38,6 +40,13 @@ static int gkrouted_only = 1;
module_param(gkrouted_only, int, 0600);
module_param(gkrouted_only, int, 0600);
MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper");
MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper");


static char *internal_net = NULL;
static u_int32_t internal_net_addr = 0;
static u_int32_t internal_net_mask = 0;
module_param(internal_net, charp, 0600);
MODULE_PARM_DESC(internal_net, "specify your internal network using format "
		 "address/mask. this is used by call forwarding support");

/* Hooks for NAT */
/* Hooks for NAT */
int (*set_h245_addr_hook) (struct sk_buff ** pskb,
int (*set_h245_addr_hook) (struct sk_buff ** pskb,
			   unsigned char **data, int dataoff,
			   unsigned char **data, int dataoff,
@@ -77,6 +86,12 @@ int (*nat_h245_hook) (struct sk_buff ** pskb,
		      unsigned char **data, int dataoff,
		      unsigned char **data, int dataoff,
		      TransportAddress * addr, u_int16_t port,
		      TransportAddress * addr, u_int16_t port,
		      struct ip_conntrack_expect * exp);
		      struct ip_conntrack_expect * exp);
int (*nat_callforwarding_hook) (struct sk_buff ** pskb,
				struct ip_conntrack * ct,
				enum ip_conntrack_info ctinfo,
				unsigned char **data, int dataoff,
				TransportAddress * addr, u_int16_t port,
				struct ip_conntrack_expect * exp);
int (*nat_q931_hook) (struct sk_buff ** pskb,
int (*nat_q931_hook) (struct sk_buff ** pskb,
		      struct ip_conntrack * ct,
		      struct ip_conntrack * ct,
		      enum ip_conntrack_info ctinfo,
		      enum ip_conntrack_info ctinfo,
@@ -683,6 +698,76 @@ static int expect_h245(struct sk_buff **pskb, struct ip_conntrack *ct,
	return ret;
	return ret;
}
}


/* Forwarding declaration */
void ip_conntrack_q931_expect(struct ip_conntrack *new,
			      struct ip_conntrack_expect *this);

/****************************************************************************/
static int expect_callforwarding(struct sk_buff **pskb,
				 struct ip_conntrack *ct,
				 enum ip_conntrack_info ctinfo,
				 unsigned char **data, int dataoff,
				 TransportAddress * addr)
{
	int dir = CTINFO2DIR(ctinfo);
	int ret = 0;
	u_int32_t ip;
	u_int16_t port;
	struct ip_conntrack_expect *exp = NULL;

	/* Read alternativeAddress */
	if (!get_h225_addr(*data, addr, &ip, &port) || port == 0)
		return 0;

	/* If the calling party is on the same side of the forward-to party,
	 * we don't need to track the second call */
	if (internal_net &&
	    ((ip & internal_net_mask) == internal_net_addr) ==
	    ((ct->tuplehash[!dir].tuple.src.ip & internal_net_mask) ==
	     internal_net_addr)) {
		DEBUGP("ip_ct_q931: Call Forwarding not tracked\n");
		return 0;
	}

	/* Create expect for the second call leg */
	if ((exp = ip_conntrack_expect_alloc(ct)) == NULL)
		return -1;
	exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
	exp->tuple.src.u.tcp.port = 0;
	exp->tuple.dst.ip = ip;
	exp->tuple.dst.u.tcp.port = htons(port);
	exp->tuple.dst.protonum = IPPROTO_TCP;
	exp->mask.src.ip = 0xFFFFFFFF;
	exp->mask.src.u.tcp.port = 0;
	exp->mask.dst.ip = 0xFFFFFFFF;
	exp->mask.dst.u.tcp.port = 0xFFFF;
	exp->mask.dst.protonum = 0xFF;
	exp->flags = 0;

	if (ct->tuplehash[dir].tuple.src.ip !=
	    ct->tuplehash[!dir].tuple.dst.ip && nat_callforwarding_hook) {
		/* Need NAT */
		ret = nat_callforwarding_hook(pskb, ct, ctinfo, data, dataoff,
					      addr, port, exp);
	} else {		/* Conntrack only */
		exp->expectfn = ip_conntrack_q931_expect;

		if (ip_conntrack_expect_related(exp) == 0) {
			DEBUGP("ip_ct_q931: expect Call Forwarding "
			       "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
			       NIPQUAD(exp->tuple.src.ip),
			       ntohs(exp->tuple.src.u.tcp.port),
			       NIPQUAD(exp->tuple.dst.ip),
			       ntohs(exp->tuple.dst.u.tcp.port));
		} else
			ret = -1;
	}

	ip_conntrack_expect_put(exp);

	return ret;
}

/****************************************************************************/
/****************************************************************************/
static int process_setup(struct sk_buff **pskb, struct ip_conntrack *ct,
static int process_setup(struct sk_buff **pskb, struct ip_conntrack *ct,
			 enum ip_conntrack_info ctinfo,
			 enum ip_conntrack_info ctinfo,
@@ -878,6 +963,15 @@ static int process_facility(struct sk_buff **pskb, struct ip_conntrack *ct,


	DEBUGP("ip_ct_q931: Facility\n");
	DEBUGP("ip_ct_q931: Facility\n");


	if (facility->reason.choice == eFacilityReason_callForwarded) {
		if (facility->options & eFacility_UUIE_alternativeAddress)
			return expect_callforwarding(pskb, ct, ctinfo, data,
						     dataoff,
						     &facility->
						     alternativeAddress);
		return 0;
	}

	if (facility->options & eFacility_UUIE_h245Address) {
	if (facility->options & eFacility_UUIE_h245Address) {
		ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
		ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
				  &facility->h245Address);
				  &facility->h245Address);
@@ -1668,6 +1762,7 @@ static void fini(void)
static int __init init(void)
static int __init init(void)
{
{
	int ret;
	int ret;
	char *p;


	h323_buffer = kmalloc(65536, GFP_KERNEL);
	h323_buffer = kmalloc(65536, GFP_KERNEL);
	if (!h323_buffer)
	if (!h323_buffer)
@@ -1678,6 +1773,22 @@ static int __init init(void)
		return ret;
		return ret;
	}
	}


	if (internal_net) {
		if ((p = strchr(internal_net, '/')))
			*p++ = 0;
		if (isdigit(internal_net[0])) {
			internal_net_addr = in_aton(internal_net);
			if (p && isdigit(p[0]))
				internal_net_mask = in_aton(p);
			else
				internal_net_mask = 0xffffffff;
			internal_net_addr &= internal_net_mask;
		}
		DEBUGP("ip_ct_h323: internal_net = %u.%u.%u.%u/%u.%u.%u.%u\n",
		       NIPQUAD(internal_net_addr),
		       NIPQUAD(internal_net_mask));
	}

	DEBUGP("ip_ct_h323: init success\n");
	DEBUGP("ip_ct_h323: init success\n");
	return 0;
	return 0;
}
}
@@ -1696,6 +1807,7 @@ EXPORT_SYMBOL_GPL(set_ras_addr_hook);
EXPORT_SYMBOL_GPL(nat_rtp_rtcp_hook);
EXPORT_SYMBOL_GPL(nat_rtp_rtcp_hook);
EXPORT_SYMBOL_GPL(nat_t120_hook);
EXPORT_SYMBOL_GPL(nat_t120_hook);
EXPORT_SYMBOL_GPL(nat_h245_hook);
EXPORT_SYMBOL_GPL(nat_h245_hook);
EXPORT_SYMBOL_GPL(nat_callforwarding_hook);
EXPORT_SYMBOL_GPL(nat_q931_hook);
EXPORT_SYMBOL_GPL(nat_q931_hook);


MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>");
MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>");
Loading