⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ip_nat_helper_h323.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * H.323 extension for NAT alteration. * * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net> * * This source code is licensed under General Public License version 2. * * Based on the 'brute force' H.323 NAT module by * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> */#include <linux/module.h>#include <linux/netfilter_ipv4.h>#include <linux/netfilter.h>#include <linux/ip.h>#include <linux/tcp.h>#include <linux/moduleparam.h>#include <net/tcp.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_h323.h>#include <linux/netfilter_ipv4/ip_conntrack_helper.h>#if 0#define DEBUGP printk#else#define DEBUGP(format, args...)#endif/****************************************************************************/static int set_addr(struct sk_buff **pskb,		    unsigned char **data, int dataoff,		    unsigned int addroff, u_int32_t ip, u_int16_t port){	enum ip_conntrack_info ctinfo;	struct ip_conntrack *ct = ip_conntrack_get(*pskb, &ctinfo);	struct {		u_int32_t ip;		u_int16_t port;	} __attribute__ ((__packed__)) buf;	struct tcphdr _tcph, *th;	buf.ip = ip;	buf.port = htons(port);	addroff += dataoff;	if ((*pskb)->nh.iph->protocol == IPPROTO_TCP) {		if (!ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,					      addroff, sizeof(buf),					      (char *) &buf, sizeof(buf))) {			if (net_ratelimit())				printk("ip_nat_h323: ip_nat_mangle_tcp_packet"				       " error\n");			return -1;		}		/* Relocate data pointer */		th = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl * 4,					sizeof(_tcph), &_tcph);		if (th == NULL)			return -1;		*data = (*pskb)->data + (*pskb)->nh.iph->ihl * 4 +		    th->doff * 4 + dataoff;	} else {		if (!ip_nat_mangle_udp_packet(pskb, ct, ctinfo,					      addroff, sizeof(buf),					      (char *) &buf, sizeof(buf))) {			if (net_ratelimit())				printk("ip_nat_h323: ip_nat_mangle_udp_packet"				       " error\n");			return -1;		}		/* ip_nat_mangle_udp_packet uses skb_make_writable() to copy		 * or pull everything in a linear buffer, so we can safely		 * use the skb pointers now */		*data = (*pskb)->data + (*pskb)->nh.iph->ihl * 4 +		    sizeof(struct udphdr);	}	return 0;}/****************************************************************************/static int set_h225_addr(struct sk_buff **pskb,			 unsigned char **data, int dataoff,			 TransportAddress * addr,			 u_int32_t ip, u_int16_t port){	return set_addr(pskb, data, dataoff, addr->ipAddress.ip, ip, port);}/****************************************************************************/static int set_h245_addr(struct sk_buff **pskb,			 unsigned char **data, int dataoff,			 H245_TransportAddress * addr,			 u_int32_t ip, u_int16_t port){	return set_addr(pskb, data, dataoff,			addr->unicastAddress.iPAddress.network, ip, port);}/****************************************************************************/static int set_sig_addr(struct sk_buff **pskb, struct ip_conntrack *ct,			enum ip_conntrack_info ctinfo,			unsigned char **data,			TransportAddress * addr, int count){	struct ip_ct_h323_master *info = &ct->help.ct_h323_info;	int dir = CTINFO2DIR(ctinfo);	int i;	u_int32_t ip;	u_int16_t port;	for (i = 0; i < count; i++) {		if (get_h225_addr(*data, &addr[i], &ip, &port)) {			if (ip == ct->tuplehash[dir].tuple.src.ip &&			    port == info->sig_port[dir]) {				/* GW->GK */				/* Fix for Gnomemeeting */				if (i > 0 &&				    get_h225_addr(*data, &addr[0],						  &ip, &port) &&				    (ntohl(ip) & 0xff000000) == 0x7f000000)					i = 0;				DEBUGP				    ("ip_nat_ras: set signal address "				     "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",				     NIPQUAD(ip), port,				     NIPQUAD(ct->tuplehash[!dir].tuple.dst.					     ip), info->sig_port[!dir]);				return set_h225_addr(pskb, data, 0, &addr[i],						     ct->tuplehash[!dir].						     tuple.dst.ip,						     info->sig_port[!dir]);			} else if (ip == ct->tuplehash[dir].tuple.dst.ip &&				   port == info->sig_port[dir]) {				/* GK->GW */				DEBUGP				    ("ip_nat_ras: set signal address "				     "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",				     NIPQUAD(ip), port,				     NIPQUAD(ct->tuplehash[!dir].tuple.src.					     ip), info->sig_port[!dir]);				return set_h225_addr(pskb, data, 0, &addr[i],						     ct->tuplehash[!dir].						     tuple.src.ip,						     info->sig_port[!dir]);			}		}	}	return 0;}/****************************************************************************/static int set_ras_addr(struct sk_buff **pskb, struct ip_conntrack *ct,			enum ip_conntrack_info ctinfo,			unsigned char **data,			TransportAddress * addr, int count){	int dir = CTINFO2DIR(ctinfo);	int i;	u_int32_t ip;	u_int16_t port;	for (i = 0; i < count; i++) {		if (get_h225_addr(*data, &addr[i], &ip, &port) &&		    ip == ct->tuplehash[dir].tuple.src.ip &&		    port == ntohs(ct->tuplehash[dir].tuple.src.u.udp.port)) {			DEBUGP("ip_nat_ras: set rasAddress "			       "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",			       NIPQUAD(ip), port,			       NIPQUAD(ct->tuplehash[!dir].tuple.dst.ip),			       ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.				     port));			return set_h225_addr(pskb, data, 0, &addr[i],					     ct->tuplehash[!dir].tuple.dst.ip,					     ntohs(ct->tuplehash[!dir].tuple.						   dst.u.udp.port));		}	}	return 0;}/****************************************************************************/static int nat_rtp_rtcp(struct sk_buff **pskb, struct ip_conntrack *ct,			enum ip_conntrack_info ctinfo,			unsigned char **data, int dataoff,			H245_TransportAddress * addr,			u_int16_t port, u_int16_t rtp_port,			struct ip_conntrack_expect *rtp_exp,			struct ip_conntrack_expect *rtcp_exp){	struct ip_ct_h323_master *info = &ct->help.ct_h323_info;	int dir = CTINFO2DIR(ctinfo);	int i;	u_int16_t nated_port;	/* Set expectations for NAT */	rtp_exp->saved_proto.udp.port = rtp_exp->tuple.dst.u.udp.port;	rtp_exp->expectfn = ip_nat_follow_master;	rtp_exp->dir = !dir;	rtcp_exp->saved_proto.udp.port = rtcp_exp->tuple.dst.u.udp.port;	rtcp_exp->expectfn = ip_nat_follow_master;	rtcp_exp->dir = !dir;	/* Lookup existing expects */	for (i = 0; i < H323_RTP_CHANNEL_MAX; i++) {		if (info->rtp_port[i][dir] == rtp_port) {			/* Expected */			/* Use allocated ports first. This will refresh			 * the expects */			rtp_exp->tuple.dst.u.udp.port =			    htons(info->rtp_port[i][dir]);			rtcp_exp->tuple.dst.u.udp.port =			    htons(info->rtp_port[i][dir] + 1);			break;		} else if (info->rtp_port[i][dir] == 0) {			/* Not expected */			break;		}	}	/* Run out of expectations */	if (i >= H323_RTP_CHANNEL_MAX) {		if (net_ratelimit())			printk("ip_nat_h323: out of expectations\n");		return 0;	}	/* Try to get a pair of ports. */	for (nated_port = ntohs(rtp_exp->tuple.dst.u.udp.port);	     nated_port != 0; nated_port += 2) {		rtp_exp->tuple.dst.u.udp.port = htons(nated_port);		if (ip_conntrack_expect_related(rtp_exp) == 0) {			rtcp_exp->tuple.dst.u.udp.port =			    htons(nated_port + 1);			if (ip_conntrack_expect_related(rtcp_exp) == 0)				break;			ip_conntrack_unexpect_related(rtp_exp);		}	}	if (nated_port == 0) {	/* No port available */		if (net_ratelimit())			printk("ip_nat_h323: out of RTP ports\n");		return 0;	}	/* Modify signal */	if (set_h245_addr(pskb, data, dataoff, addr,			  ct->tuplehash[!dir].tuple.dst.ip,			  (port & 1) ? nated_port + 1 : nated_port) == 0) {		/* Save ports */		info->rtp_port[i][dir] = rtp_port;		info->rtp_port[i][!dir] = nated_port;	} else {		ip_conntrack_unexpect_related(rtp_exp);		ip_conntrack_unexpect_related(rtcp_exp);		return -1;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -