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

📄 nf_conntrack_h323_main.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		return -1;	set_ras_addr = rcu_dereference(set_ras_addr_hook);	if (set_ras_addr && ct->status & IPS_NAT_MASK) {		ret = set_ras_addr(skb, ct, ctinfo, data,				   rrq->rasAddress.item,				   rrq->rasAddress.count);		if (ret < 0)			return -1;	}	if (rrq->options & eRegistrationRequest_timeToLive) {		pr_debug("nf_ct_ras: RRQ TTL = %u seconds\n", rrq->timeToLive);		info->timeout = rrq->timeToLive;	} else		info->timeout = default_rrq_ttl;	return 0;}/****************************************************************************/static int process_rcf(struct sk_buff *skb, struct nf_conn *ct,		       enum ip_conntrack_info ctinfo,		       unsigned char **data, RegistrationConfirm *rcf){	struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;	int dir = CTINFO2DIR(ctinfo);	int ret;	struct nf_conntrack_expect *exp;	typeof(set_sig_addr_hook) set_sig_addr;	pr_debug("nf_ct_ras: RCF\n");	set_sig_addr = rcu_dereference(set_sig_addr_hook);	if (set_sig_addr && ct->status & IPS_NAT_MASK) {		ret = set_sig_addr(skb, ct, ctinfo, data,					rcf->callSignalAddress.item,					rcf->callSignalAddress.count);		if (ret < 0)			return -1;	}	if (rcf->options & eRegistrationConfirm_timeToLive) {		pr_debug("nf_ct_ras: RCF TTL = %u seconds\n", rcf->timeToLive);		info->timeout = rcf->timeToLive;	}	if (info->timeout > 0) {		pr_debug("nf_ct_ras: set RAS connection timeout to "			 "%u seconds\n", info->timeout);		nf_ct_refresh(ct, skb, info->timeout * HZ);		/* Set expect timeout */		read_lock_bh(&nf_conntrack_lock);		exp = find_expect(ct, &ct->tuplehash[dir].tuple.dst.u3,				  info->sig_port[!dir]);		if (exp) {			pr_debug("nf_ct_ras: set Q.931 expect "				 "timeout to %u seconds for",				 info->timeout);			NF_CT_DUMP_TUPLE(&exp->tuple);			set_expect_timeout(exp, info->timeout);		}		read_unlock_bh(&nf_conntrack_lock);	}	return 0;}/****************************************************************************/static int process_urq(struct sk_buff *skb, struct nf_conn *ct,		       enum ip_conntrack_info ctinfo,		       unsigned char **data, UnregistrationRequest *urq){	struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;	int dir = CTINFO2DIR(ctinfo);	int ret;	typeof(set_sig_addr_hook) set_sig_addr;	pr_debug("nf_ct_ras: URQ\n");	set_sig_addr = rcu_dereference(set_sig_addr_hook);	if (set_sig_addr && ct->status & IPS_NAT_MASK) {		ret = set_sig_addr(skb, ct, ctinfo, data,				   urq->callSignalAddress.item,				   urq->callSignalAddress.count);		if (ret < 0)			return -1;	}	/* Clear old expect */	nf_ct_remove_expectations(ct);	info->sig_port[dir] = 0;	info->sig_port[!dir] = 0;	/* Give it 30 seconds for UCF or URJ */	nf_ct_refresh(ct, skb, 30 * HZ);	return 0;}/****************************************************************************/static int process_arq(struct sk_buff *skb, struct nf_conn *ct,		       enum ip_conntrack_info ctinfo,		       unsigned char **data, AdmissionRequest *arq){	struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;	int dir = CTINFO2DIR(ctinfo);	__be16 port;	union nf_conntrack_address addr;	typeof(set_h225_addr_hook) set_h225_addr;	pr_debug("nf_ct_ras: ARQ\n");	set_h225_addr = rcu_dereference(set_h225_addr_hook);	if ((arq->options & eAdmissionRequest_destCallSignalAddress) &&	    get_h225_addr(ct, *data, &arq->destCallSignalAddress,			  &addr, &port) &&	    !memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, sizeof(addr)) &&	    port == info->sig_port[dir] &&	    set_h225_addr && ct->status & IPS_NAT_MASK) {		/* Answering ARQ */		return set_h225_addr(skb, data, 0,				     &arq->destCallSignalAddress,				     &ct->tuplehash[!dir].tuple.dst.u3,				     info->sig_port[!dir]);	}	if ((arq->options & eAdmissionRequest_srcCallSignalAddress) &&	    get_h225_addr(ct, *data, &arq->srcCallSignalAddress,			  &addr, &port) &&	    !memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, sizeof(addr)) &&	    set_h225_addr && ct->status & IPS_NAT_MASK) {		/* Calling ARQ */		return set_h225_addr(skb, data, 0,				     &arq->srcCallSignalAddress,				     &ct->tuplehash[!dir].tuple.dst.u3,				     port);	}	return 0;}/****************************************************************************/static int process_acf(struct sk_buff *skb, struct nf_conn *ct,		       enum ip_conntrack_info ctinfo,		       unsigned char **data, AdmissionConfirm *acf){	int dir = CTINFO2DIR(ctinfo);	int ret = 0;	__be16 port;	union nf_conntrack_address addr;	struct nf_conntrack_expect *exp;	typeof(set_sig_addr_hook) set_sig_addr;	pr_debug("nf_ct_ras: ACF\n");	if (!get_h225_addr(ct, *data, &acf->destCallSignalAddress,			   &addr, &port))		return 0;	if (!memcmp(&addr, &ct->tuplehash[dir].tuple.dst.u3, sizeof(addr))) {		/* Answering ACF */		set_sig_addr = rcu_dereference(set_sig_addr_hook);		if (set_sig_addr && ct->status & IPS_NAT_MASK)			return set_sig_addr(skb, ct, ctinfo, data,					    &acf->destCallSignalAddress, 1);		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_TCP, NULL, &port);	exp->flags = NF_CT_EXPECT_PERMANENT;	exp->helper = nf_conntrack_helper_q931;	if (nf_ct_expect_related(exp) == 0) {		pr_debug("nf_ct_ras: expect Q.931 ");		NF_CT_DUMP_TUPLE(&exp->tuple);	} else		ret = -1;	nf_ct_expect_put(exp);	return ret;}/****************************************************************************/static int process_lrq(struct sk_buff *skb, struct nf_conn *ct,		       enum ip_conntrack_info ctinfo,		       unsigned char **data, LocationRequest *lrq){	typeof(set_ras_addr_hook) set_ras_addr;	pr_debug("nf_ct_ras: LRQ\n");	set_ras_addr = rcu_dereference(set_ras_addr_hook);	if (set_ras_addr && ct->status & IPS_NAT_MASK)		return set_ras_addr(skb, ct, ctinfo, data,				    &lrq->replyAddress, 1);	return 0;}/****************************************************************************/static int process_lcf(struct sk_buff *skb, struct nf_conn *ct,		       enum ip_conntrack_info ctinfo,		       unsigned char **data, LocationConfirm *lcf){	int dir = CTINFO2DIR(ctinfo);	int ret = 0;	__be16 port;	union nf_conntrack_address addr;	struct nf_conntrack_expect *exp;	pr_debug("nf_ct_ras: LCF\n");	if (!get_h225_addr(ct, *data, &lcf->callSignalAddress,			   &addr, &port))		return 0;	/* Need new expect for call signal */	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_TCP, NULL, &port);	exp->flags = NF_CT_EXPECT_PERMANENT;	exp->helper = nf_conntrack_helper_q931;	if (nf_ct_expect_related(exp) == 0) {		pr_debug("nf_ct_ras: expect Q.931 ");		NF_CT_DUMP_TUPLE(&exp->tuple);	} else		ret = -1;	nf_ct_expect_put(exp);	/* Ignore rasAddress */	return ret;}/****************************************************************************/static int process_irr(struct sk_buff *skb, struct nf_conn *ct,		       enum ip_conntrack_info ctinfo,		       unsigned char **data, InfoRequestResponse *irr){	int ret;	typeof(set_ras_addr_hook) set_ras_addr;	typeof(set_sig_addr_hook) set_sig_addr;	pr_debug("nf_ct_ras: IRR\n");	set_ras_addr = rcu_dereference(set_ras_addr_hook);	if (set_ras_addr && ct->status & IPS_NAT_MASK) {		ret = set_ras_addr(skb, ct, ctinfo, data,				   &irr->rasAddress, 1);		if (ret < 0)			return -1;	}	set_sig_addr = rcu_dereference(set_sig_addr_hook);	if (set_sig_addr && ct->status & IPS_NAT_MASK) {		ret = set_sig_addr(skb, ct, ctinfo, data,					irr->callSignalAddress.item,					irr->callSignalAddress.count);		if (ret < 0)			return -1;	}	return 0;}/****************************************************************************/static int process_ras(struct sk_buff *skb, struct nf_conn *ct,		       enum ip_conntrack_info ctinfo,		       unsigned char **data, RasMessage *ras){	switch (ras->choice) {	case eRasMessage_gatekeeperRequest:		return process_grq(skb, ct, ctinfo, data,				   &ras->gatekeeperRequest);	case eRasMessage_gatekeeperConfirm:		return process_gcf(skb, ct, ctinfo, data,				   &ras->gatekeeperConfirm);	case eRasMessage_registrationRequest:		return process_rrq(skb, ct, ctinfo, data,				   &ras->registrationRequest);	case eRasMessage_registrationConfirm:		return process_rcf(skb, ct, ctinfo, data,				   &ras->registrationConfirm);	case eRasMessage_unregistrationRequest:		return process_urq(skb, ct, ctinfo, data,				   &ras->unregistrationRequest);	case eRasMessage_admissionRequest:		return process_arq(skb, ct, ctinfo, data,				   &ras->admissionRequest);	case eRasMessage_admissionConfirm:		return process_acf(skb, ct, ctinfo, data,				   &ras->admissionConfirm);	case eRasMessage_locationRequest:		return process_lrq(skb, ct, ctinfo, data,				   &ras->locationRequest);	case eRasMessage_locationConfirm:		return process_lcf(skb, ct, ctinfo, data,				   &ras->locationConfirm);	case eRasMessage_infoRequestResponse:		return process_irr(skb, ct, ctinfo, data,				   &ras->infoRequestResponse);	default:		pr_debug("nf_ct_ras: RAS message %d\n", ras->choice);		break;	}	return 0;}/****************************************************************************/static int ras_help(struct sk_buff *skb, unsigned int protoff,		    struct nf_conn *ct, enum ip_conntrack_info ctinfo){	static RasMessage ras;	unsigned char *data;	int datalen = 0;	int ret;	pr_debug("nf_ct_ras: skblen = %u\n", skb->len);	spin_lock_bh(&nf_h323_lock);	/* Get UDP data */	data = get_udp_data(skb, protoff, &datalen);	if (data == NULL)		goto accept;	pr_debug("nf_ct_ras: RAS message len=%d ", datalen);	NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);	/* Decode RAS message */	ret = DecodeRasMessage(data, datalen, &ras);	if (ret < 0) {		pr_debug("nf_ct_ras: decoding error: %s\n",			 ret == H323_ERROR_BOUND ?			 "out of bound" : "out of range");		goto accept;	}	/* Process RAS message */	if (process_ras(skb, ct, ctinfo, &data, &ras) < 0)		goto drop;      accept:	spin_unlock_bh(&nf_h323_lock);	return NF_ACCEPT;      drop:	spin_unlock_bh(&nf_h323_lock);	if (net_ratelimit())		printk("nf_ct_ras: packet dropped\n");	return NF_DROP;}/****************************************************************************/static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = {	{		.name			= "RAS",		.me			= THIS_MODULE,		.max_expected		= 32,		.timeout		= 240,		.tuple.src.l3num	= AF_INET,		.tuple.src.u.udp.port	= __constant_htons(RAS_PORT),		.tuple.dst.protonum	= IPPROTO_UDP,		.help			= ras_help,	},	{		.name			= "RAS",		.me			= THIS_MODULE,		.max_expected		= 32,		.timeout		= 240,		.tuple.src.l3num	= AF_INET6,		.tuple.src.u.udp.port	= __constant_htons(RAS_PORT),		.tuple.dst.protonum	= IPPROTO_UDP,		.help			= ras_help,	},};/****************************************************************************/static void __exit nf_conntrack_h323_fini(void){	nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[1]);	nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[0]);	nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]);	nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]);	kfree(h323_buffer);	pr_debug("nf_ct_h323: fini\n");}/****************************************************************************/static int __init nf_conntrack_h323_init(void){	int ret;	h323_buffer = kmalloc(65536, GFP_KERNEL);	if (!h323_buffer)		return -ENOMEM;	ret = nf_conntrack_helper_register(&nf_conntrack_helper_q931[0]);	if (ret < 0)		goto err1;	ret = nf_conntrack_helper_register(&nf_conntrack_helper_q931[1]);	if (ret < 0)		goto err2;	ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[0]);	if (ret < 0)		goto err3;	ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[1]);	if (ret < 0)		goto err4;	pr_debug("nf_ct_h323: init success\n");	return 0;err4:	nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[0]);err3:	nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]);err2:	nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]);err1:	return ret;}/****************************************************************************/module_init(nf_conntrack_h323_init);module_exit(nf_conntrack_h323_fini);EXPORT_SYMBOL_GPL(get_h225_addr);EXPORT_SYMBOL_GPL(set_h245_addr_hook);EXPORT_SYMBOL_GPL(set_h225_addr_hook);EXPORT_SYMBOL_GPL(set_sig_addr_hook);EXPORT_SYMBOL_GPL(set_ras_addr_hook);EXPORT_SYMBOL_GPL(nat_rtp_rtcp_hook);EXPORT_SYMBOL_GPL(nat_t120_hook);EXPORT_SYMBOL_GPL(nat_h245_hook);EXPORT_SYMBOL_GPL(nat_callforwarding_hook);EXPORT_SYMBOL_GPL(nat_q931_hook);MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>");MODULE_DESCRIPTION("H.323 connection tracking helper");MODULE_LICENSE("GPL");MODULE_ALIAS("ip_conntrack_h323");

⌨️ 快捷键说明

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