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

📄 nf_conntrack_h323_main.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		for (i = 0; i < callproc->fastStart.count; i++) {			ret = process_olc(skb, ct, ctinfo, data, dataoff,					  &callproc->fastStart.item[i]);			if (ret < 0)				return -1;		}	}	return 0;}/****************************************************************************/static int process_connect(struct sk_buff *skb, struct nf_conn *ct,			   enum ip_conntrack_info ctinfo,			   unsigned char **data, int dataoff,			   Connect_UUIE *connect){	int ret;	int i;	pr_debug("nf_ct_q931: Connect\n");	if (connect->options & eConnect_UUIE_h245Address) {		ret = expect_h245(skb, ct, ctinfo, data, dataoff,				  &connect->h245Address);		if (ret < 0)			return -1;	}	if (connect->options & eConnect_UUIE_fastStart) {		for (i = 0; i < connect->fastStart.count; i++) {			ret = process_olc(skb, ct, ctinfo, data, dataoff,					  &connect->fastStart.item[i]);			if (ret < 0)				return -1;		}	}	return 0;}/****************************************************************************/static int process_alerting(struct sk_buff *skb, struct nf_conn *ct,			    enum ip_conntrack_info ctinfo,			    unsigned char **data, int dataoff,			    Alerting_UUIE *alert){	int ret;	int i;	pr_debug("nf_ct_q931: Alerting\n");	if (alert->options & eAlerting_UUIE_h245Address) {		ret = expect_h245(skb, ct, ctinfo, data, dataoff,				  &alert->h245Address);		if (ret < 0)			return -1;	}	if (alert->options & eAlerting_UUIE_fastStart) {		for (i = 0; i < alert->fastStart.count; i++) {			ret = process_olc(skb, ct, ctinfo, data, dataoff,					  &alert->fastStart.item[i]);			if (ret < 0)				return -1;		}	}	return 0;}/****************************************************************************/static int process_facility(struct sk_buff *skb, struct nf_conn *ct,			    enum ip_conntrack_info ctinfo,			    unsigned char **data, int dataoff,			    Facility_UUIE *facility){	int ret;	int i;	pr_debug("nf_ct_q931: Facility\n");	if (facility->reason.choice == eFacilityReason_callForwarded) {		if (facility->options & eFacility_UUIE_alternativeAddress)			return expect_callforwarding(skb, ct, ctinfo, data,						     dataoff,						     &facility->						     alternativeAddress);		return 0;	}	if (facility->options & eFacility_UUIE_h245Address) {		ret = expect_h245(skb, 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(skb, ct, ctinfo, data, dataoff,					  &facility->fastStart.item[i]);			if (ret < 0)				return -1;		}	}	return 0;}/****************************************************************************/static int process_progress(struct sk_buff *skb, struct nf_conn *ct,			    enum ip_conntrack_info ctinfo,			    unsigned char **data, int dataoff,			    Progress_UUIE *progress){	int ret;	int i;	pr_debug("nf_ct_q931: Progress\n");	if (progress->options & eProgress_UUIE_h245Address) {		ret = expect_h245(skb, 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(skb, ct, ctinfo, data, dataoff,					  &progress->fastStart.item[i]);			if (ret < 0)				return -1;		}	}	return 0;}/****************************************************************************/static int process_q931(struct sk_buff *skb, struct nf_conn *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(skb, ct, ctinfo, data, dataoff,				    &pdu->h323_message_body.setup);		break;	case eH323_UU_PDU_h323_message_body_callProceeding:		ret = process_callproceeding(skb, ct, ctinfo, data, dataoff,					     &pdu->h323_message_body.					     callProceeding);		break;	case eH323_UU_PDU_h323_message_body_connect:		ret = process_connect(skb, ct, ctinfo, data, dataoff,				      &pdu->h323_message_body.connect);		break;	case eH323_UU_PDU_h323_message_body_alerting:		ret = process_alerting(skb, ct, ctinfo, data, dataoff,				       &pdu->h323_message_body.alerting);		break;	case eH323_UU_PDU_h323_message_body_facility:		ret = process_facility(skb, ct, ctinfo, data, dataoff,				       &pdu->h323_message_body.facility);		break;	case eH323_UU_PDU_h323_message_body_progress:		ret = process_progress(skb, ct, ctinfo, data, dataoff,				       &pdu->h323_message_body.progress);		break;	default:		pr_debug("nf_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(skb, ct, ctinfo, data, dataoff,					   &pdu->h245Control.item[i]);			if (ret < 0)				return -1;		}	}	return 0;}/****************************************************************************/static int q931_help(struct sk_buff *skb, unsigned int protoff,		     struct nf_conn *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;	}	pr_debug("nf_ct_q931: skblen = %u\n", skb->len);	spin_lock_bh(&nf_h323_lock);	/* Process each TPKT */	while (get_tpkt_data(skb, protoff, ct, ctinfo,			     &data, &datalen, &dataoff)) {		pr_debug("nf_ct_q931: TPKT len=%d ", datalen);		NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);		/* Decode Q.931 signal */		ret = DecodeQ931(data, datalen, &q931);		if (ret < 0) {			pr_debug("nf_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(skb, ct, ctinfo, &data, dataoff, &q931) < 0)			goto drop;	}	spin_unlock_bh(&nf_h323_lock);	return NF_ACCEPT;      drop:	spin_unlock_bh(&nf_h323_lock);	if (net_ratelimit())		printk("nf_ct_q931: packet dropped\n");	return NF_DROP;}/****************************************************************************/static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = {	{		.name			= "Q.931",		.me			= THIS_MODULE,					  /* T.120 and H.245 */		.max_expected		= H323_RTP_CHANNEL_MAX * 4 + 4,		.timeout		= 240,		.tuple.src.l3num	= AF_INET,		.tuple.src.u.tcp.port	= __constant_htons(Q931_PORT),		.tuple.dst.protonum	= IPPROTO_TCP,		.help			= q931_help	},	{		.name			= "Q.931",		.me			= THIS_MODULE,					  /* T.120 and H.245 */		.max_expected		= H323_RTP_CHANNEL_MAX * 4 + 4,		.timeout		= 240,		.tuple.src.l3num	= AF_INET6,		.tuple.src.u.tcp.port	= __constant_htons(Q931_PORT),		.tuple.dst.protonum	= IPPROTO_TCP,		.help			= q931_help	},};/****************************************************************************/static unsigned char *get_udp_data(struct sk_buff *skb, unsigned int protoff,				   int *datalen){	struct udphdr _uh, *uh;	int dataoff;	uh = skb_header_pointer(skb, protoff, sizeof(_uh), &_uh);	if (uh == NULL)		return NULL;	dataoff = protoff + sizeof(_uh);	if (dataoff >= skb->len)		return NULL;	*datalen = skb->len - dataoff;	return skb_header_pointer(skb, dataoff, *datalen, h323_buffer);}/****************************************************************************/static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,					       union nf_conntrack_address *addr,					       __be16 port){	struct nf_conntrack_expect *exp;	struct nf_conntrack_tuple tuple;	memset(&tuple.src.u3, 0, sizeof(tuple.src.u3));	tuple.src.u.tcp.port = 0;	memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3));	tuple.dst.u.tcp.port = port;	tuple.dst.protonum = IPPROTO_TCP;	exp = __nf_ct_expect_find(&tuple);	if (exp && exp->master == ct)		return exp;	return NULL;}/****************************************************************************/static int set_expect_timeout(struct nf_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 *skb, struct nf_conn *ct,		       enum ip_conntrack_info ctinfo,		       unsigned char **data,		       TransportAddress *taddr, int count){	struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;	int dir = CTINFO2DIR(ctinfo);	int ret = 0;	int i;	__be16 port;	union nf_conntrack_address addr;	struct nf_conntrack_expect *exp;	typeof(nat_q931_hook) nat_q931;	/* Look for the first related address */	for (i = 0; i < count; i++) {		if (get_h225_addr(ct, *data, &taddr[i], &addr, &port) &&		    memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3,			   sizeof(addr)) == 0 && port != 0)			break;	}	if (i >= count)		/* Not found */		return 0;	/* Create expect for Q.931 */	if ((exp = nf_ct_expect_alloc(ct)) == NULL)		return -1;	nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,			  gkrouted_only ? /* only accept calls from GK? */				&ct->tuplehash[!dir].tuple.src.u3 : NULL,			  &ct->tuplehash[!dir].tuple.dst.u3,			  IPPROTO_TCP, NULL, &port);	exp->helper = nf_conntrack_helper_q931;	exp->flags = NF_CT_EXPECT_PERMANENT;	/* Accept multiple calls */	nat_q931 = rcu_dereference(nat_q931_hook);	if (nat_q931 && ct->status & IPS_NAT_MASK) {	/* Need NAT */		ret = nat_q931(skb, ct, ctinfo, data, taddr, i, port, exp);	} else {		/* Conntrack only */		if (nf_ct_expect_related(exp) == 0) {			pr_debug("nf_ct_ras: expect Q.931 ");			NF_CT_DUMP_TUPLE(&exp->tuple);			/* Save port for looking up expect in processing RCF */			info->sig_port[dir] = port;		} else			ret = -1;	}	nf_ct_expect_put(exp);	return ret;}/****************************************************************************/static int process_grq(struct sk_buff *skb, struct nf_conn *ct,		       enum ip_conntrack_info ctinfo,		       unsigned char **data, GatekeeperRequest *grq){	typeof(set_ras_addr_hook) set_ras_addr;	pr_debug("nf_ct_ras: GRQ\n");	set_ras_addr = rcu_dereference(set_ras_addr_hook);	if (set_ras_addr && ct->status & IPS_NAT_MASK)	/* NATed */		return set_ras_addr(skb, ct, ctinfo, data,				    &grq->rasAddress, 1);	return 0;}/****************************************************************************/static int process_gcf(struct sk_buff *skb, struct nf_conn *ct,		       enum ip_conntrack_info ctinfo,		       unsigned char **data, GatekeeperConfirm *gcf){	int dir = CTINFO2DIR(ctinfo);	int ret = 0;	__be16 port;	union nf_conntrack_address addr;	struct nf_conntrack_expect *exp;	pr_debug("nf_ct_ras: GCF\n");	if (!get_h225_addr(ct, *data, &gcf->rasAddress, &addr, &port))		return 0;	/* Registration port is the same as discovery port */	if (!memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, sizeof(addr)) &&	    port == 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 = nf_ct_expect_alloc(ct)) == NULL)		return -1;	nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,			  &ct->tuplehash[!dir].tuple.src.u3, &addr,			  IPPROTO_UDP, NULL, &port);	exp->helper = nf_conntrack_helper_ras;	if (nf_ct_expect_related(exp) == 0) {		pr_debug("nf_ct_ras: expect RAS ");		NF_CT_DUMP_TUPLE(&exp->tuple);	} else		ret = -1;	nf_ct_expect_put(exp);	return ret;}/****************************************************************************/static int process_rrq(struct sk_buff *skb, struct nf_conn *ct,		       enum ip_conntrack_info ctinfo,		       unsigned char **data, RegistrationRequest *rrq){	struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;	int ret;	typeof(set_ras_addr_hook) set_ras_addr;	pr_debug("nf_ct_ras: RRQ\n");	ret = expect_q931(skb, ct, ctinfo, data,			  rrq->callSignalAddress.item,			  rrq->callSignalAddress.count);	if (ret < 0)

⌨️ 快捷键说明

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