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

📄 ip_conntrack_helper_h323.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	int ret;	int i;	DEBUGP("ip_ct_q931: Information\n");	if (info->options & eInformation_UUIE_fastStart) {		for (i = 0; i < info->fastStart.count; i++) {			ret = process_olc(pskb, ct, ctinfo, data, dataoff,					  &info->fastStart.item[i]);			if (ret < 0)				return -1;		}	}	return 0;}/****************************************************************************/static int process_facility(struct sk_buff **pskb, struct ip_conntrack *ct,			    enum ip_conntrack_info ctinfo,			    unsigned char **data, int dataoff,			    Facility_UUIE * facility){	int ret;	int i;	DEBUGP("ip_ct_q931: Facility\n");	if (facility->options & eFacility_UUIE_h245Address) {		ret = expect_h245(pskb, ct, ctinfo, data, dataoff,				  &facility->h245Address);		if (ret < 0)			return -1;	}	if (facility->options & eFacility_UUIE_fastStart) {		for (i = 0; i < facility->fastStart.count; i++) {			ret = process_olc(pskb, ct, ctinfo, data, dataoff,					  &facility->fastStart.item[i]);			if (ret < 0)				return -1;		}	}	return 0;}/****************************************************************************/static int process_progress(struct sk_buff **pskb, struct ip_conntrack *ct,			    enum ip_conntrack_info ctinfo,			    unsigned char **data, int dataoff,			    Progress_UUIE * progress){	int ret;	int i;	DEBUGP("ip_ct_q931: Progress\n");	if (progress->options & eProgress_UUIE_h245Address) {		ret = expect_h245(pskb, ct, ctinfo, data, dataoff,				  &progress->h245Address);		if (ret < 0)			return -1;	}	if (progress->options & eProgress_UUIE_fastStart) {		for (i = 0; i < progress->fastStart.count; i++) {			ret = process_olc(pskb, ct, ctinfo, data, dataoff,					  &progress->fastStart.item[i]);			if (ret < 0)				return -1;		}	}	return 0;}/****************************************************************************/static int process_q931(struct sk_buff **pskb, struct ip_conntrack *ct,			enum ip_conntrack_info ctinfo,			unsigned char **data, int dataoff, Q931 * q931){	H323_UU_PDU *pdu = &q931->UUIE.h323_uu_pdu;	int i;	int ret = 0;	switch (pdu->h323_message_body.choice) {	case eH323_UU_PDU_h323_message_body_setup:		ret = process_setup(pskb, ct, ctinfo, data, dataoff,				    &pdu->h323_message_body.setup);		break;	case eH323_UU_PDU_h323_message_body_callProceeding:		ret = process_callproceeding(pskb, ct, ctinfo, data, dataoff,					     &pdu->h323_message_body.					     callProceeding);		break;	case eH323_UU_PDU_h323_message_body_connect:		ret = process_connect(pskb, ct, ctinfo, data, dataoff,				      &pdu->h323_message_body.connect);		break;	case eH323_UU_PDU_h323_message_body_alerting:		ret = process_alerting(pskb, ct, ctinfo, data, dataoff,				       &pdu->h323_message_body.alerting);		break;	case eH323_UU_PDU_h323_message_body_information:		ret = process_information(pskb, ct, ctinfo, data, dataoff,					  &pdu->h323_message_body.					  information);		break;	case eH323_UU_PDU_h323_message_body_facility:		ret = process_facility(pskb, ct, ctinfo, data, dataoff,				       &pdu->h323_message_body.facility);		break;	case eH323_UU_PDU_h323_message_body_progress:		ret = process_progress(pskb, ct, ctinfo, data, dataoff,				       &pdu->h323_message_body.progress);		break;	default:		DEBUGP("ip_ct_q931: Q.931 signal %d\n",		       pdu->h323_message_body.choice);		break;	}	if (ret < 0)		return -1;	if (pdu->options & eH323_UU_PDU_h245Control) {		for (i = 0; i < pdu->h245Control.count; i++) {			ret = process_h245(pskb, ct, ctinfo, data, dataoff,					   &pdu->h245Control.item[i]);			if (ret < 0)				return -1;		}	}	return 0;}/****************************************************************************/static int q931_help(struct sk_buff **pskb, struct ip_conntrack *ct,		     enum ip_conntrack_info ctinfo){	static Q931 q931;	unsigned char *data = NULL;	int datalen;	int dataoff;	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) {		return NF_ACCEPT;	}	DEBUGP("ip_ct_q931: skblen = %u\n", (*pskb)->len);	spin_lock_bh(&ip_h323_lock);	/* Process each TPKT */	while (get_tpkt_data(pskb, ct, ctinfo, &data, &datalen, &dataoff)) {		DEBUGP("ip_ct_q931: TPKT %u.%u.%u.%u->%u.%u.%u.%u, len=%d\n",		       NIPQUAD((*pskb)->nh.iph->saddr),		       NIPQUAD((*pskb)->nh.iph->daddr), datalen);		/* Decode Q.931 signal */		ret = DecodeQ931(data, datalen, &q931);		if (ret < 0) {			if (net_ratelimit())				printk("ip_ct_q931: decoding error: %s\n",				       ret == H323_ERROR_BOUND ?				       "out of bound" : "out of range");			/* We don't drop when decoding error */			break;		}		/* Process Q.931 signal */		if (process_q931(pskb, ct, ctinfo, &data, dataoff, &q931) < 0)			goto drop;	}	spin_unlock_bh(&ip_h323_lock);	return NF_ACCEPT;      drop:	spin_unlock_bh(&ip_h323_lock);	if (net_ratelimit())		printk("ip_ct_q931: packet dropped\n");	return NF_DROP;}/****************************************************************************/static struct ip_conntrack_helper ip_conntrack_helper_q931 = {	.name = "Q.931",	.me = THIS_MODULE,	.max_expected = H323_RTP_CHANNEL_MAX * 4 + 4 /* T.120 and H.245 */ ,	.timeout = 240,	.tuple = {.src = {.u = {__constant_htons(Q931_PORT)}},		  .dst = {.protonum = IPPROTO_TCP}},	.mask = {.src = {.u = {0xFFFF}},		 .dst = {.protonum = 0xFF}},	.help = q931_help};/****************************************************************************/void ip_conntrack_q931_expect(struct ip_conntrack *new,			      struct ip_conntrack_expect *this){	write_lock_bh(&ip_conntrack_lock);	new->helper = &ip_conntrack_helper_q931;	write_unlock_bh(&ip_conntrack_lock);}/****************************************************************************/static unsigned char *get_udp_data(struct sk_buff **pskb, int *datalen){	struct udphdr _uh, *uh;	int dataoff;	uh = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl * 4, sizeof(_uh),				&_uh);	if (uh == NULL)		return NULL;	dataoff = (*pskb)->nh.iph->ihl * 4 + sizeof(_uh);	if (dataoff >= (*pskb)->len)		return NULL;	*datalen = (*pskb)->len - dataoff;	return skb_header_pointer(*pskb, dataoff, *datalen, h323_buffer);}/****************************************************************************/static struct ip_conntrack_expect *find_expect(struct ip_conntrack *ct,					       u_int32_t ip, u_int16_t port){	struct ip_conntrack_expect *exp;	struct ip_conntrack_tuple tuple;	tuple.src.ip = 0;	tuple.src.u.tcp.port = 0;	tuple.dst.ip = ip;	tuple.dst.u.tcp.port = htons(port);	tuple.dst.protonum = IPPROTO_TCP;	exp = __ip_conntrack_expect_find(&tuple);	if (exp && exp->master == ct)		return exp;	return NULL;}/****************************************************************************/static int set_expect_timeout(struct ip_conntrack_expect *exp,			      unsigned timeout){	if (!exp || !del_timer(&exp->timeout))		return 0;	exp->timeout.expires = jiffies + timeout * HZ;	add_timer(&exp->timeout);	return 1;}/****************************************************************************/static int expect_q931(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 ret = 0;	int i;	u_int32_t ip;	u_int16_t port;	struct ip_conntrack_expect *exp;	/* Look for the first related address */	for (i = 0; i < count; i++) {		if (get_h225_addr(*data, &addr[i], &ip, &port) &&		    ip == ct->tuplehash[dir].tuple.src.ip && port != 0)			break;	}	if (i >= count)		/* Not found */		return 0;	/* Create expect for Q.931 */	if ((exp = ip_conntrack_expect_alloc(ct)) == NULL)		return -1;	exp->tuple.src.ip = gkrouted_only ?	/* only accept calls from GK? */	    ct->tuplehash[!dir].tuple.src.ip : 0;	exp->tuple.src.u.tcp.port = 0;	exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;	exp->tuple.dst.u.tcp.port = htons(port);	exp->tuple.dst.protonum = IPPROTO_TCP;	exp->mask.src.ip = gkrouted_only ? 0xFFFFFFFF : 0;	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 = IP_CT_EXPECT_PERMANENT;	/* Accept multiple calls */	if (nat_q931_hook) {	/* Need NAT */		ret = nat_q931_hook(pskb, ct, ctinfo, data, addr, i,				    port, exp);	} else {		/* Conntrack only */		exp->expectfn = ip_conntrack_q931_expect;		if (ip_conntrack_expect_related(exp) == 0) {			DEBUGP("ip_ct_ras: expect Q.931 "			       "%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));			/* Save port for looking up expect in processing RCF */			info->sig_port[dir] = port;		} else			ret = -1;	}	ip_conntrack_expect_put(exp);	return ret;}/****************************************************************************/static int process_grq(struct sk_buff **pskb, struct ip_conntrack *ct,		       enum ip_conntrack_info ctinfo,		       unsigned char **data, GatekeeperRequest * grq){	DEBUGP("ip_ct_ras: GRQ\n");	if (set_ras_addr_hook)	/* NATed */		return set_ras_addr_hook(pskb, ct, ctinfo, data,					 &grq->rasAddress, 1);	return 0;}/* Declare before using */static void ip_conntrack_ras_expect(struct ip_conntrack *new,				    struct ip_conntrack_expect *this);/****************************************************************************/static int process_gcf(struct sk_buff **pskb, struct ip_conntrack *ct,		       enum ip_conntrack_info ctinfo,		       unsigned char **data, GatekeeperConfirm * gcf){	int dir = CTINFO2DIR(ctinfo);	int ret = 0;	u_int32_t ip;	u_int16_t port;	struct ip_conntrack_expect *exp;	DEBUGP("ip_ct_ras: GCF\n");	if (!get_h225_addr(*data, &gcf->rasAddress, &ip, &port))		return 0;	/* Registration port is the same as discovery port */	if (ip == ct->tuplehash[dir].tuple.src.ip &&	    port == ntohs(ct->tuplehash[dir].tuple.src.u.udp.port))		return 0;	/* Avoid RAS expectation loops. A GCF is never expected. */	if (test_bit(IPS_EXPECTED_BIT, &ct->status))		return 0;	/* Need new expect */	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_UDP;	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;	exp->expectfn = ip_conntrack_ras_expect;	if (ip_conntrack_expect_related(exp) == 0) {		DEBUGP("ip_ct_ras: expect RAS "		       "%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_rrq(struct sk_buff **pskb, struct ip_conntrack *ct,		       enum ip_conntrack_info ctinfo,		       unsigned char **data, RegistrationRequest * rrq){	struct ip_ct_h323_master *info = &ct->help.ct_h323_info;	int ret;	DEBUGP("ip_ct_ras: RRQ\n");	ret = expect_q931(pskb, ct, ctinfo, data,			  rrq->callSignalAddress.item,			  rrq->callSignalAddress.count);	if (ret < 0)		return -1;	if (set_ras_addr_hook) {		ret = set_ras_addr_hook(pskb, ct, ctinfo, data,					rrq->rasAddress.item,					rrq->rasAddress.count);		if (ret < 0)			return -1;	}	if (rrq->options & eRegistrationRequest_timeToLive) {		DEBUGP("ip_ct_ras: RRQ TTL = %u seconds\n", rrq->timeToLive);		info->timeout = rrq->timeToLive;	} else		info->timeout = default_rrq_ttl;

⌨️ 快捷键说明

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