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

📄 ip_conntrack_proto_sctp.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
		return -1;	/* Check the verification tag (Sec 8.5) */	if (!test_bit(SCTP_CID_INIT, (void *)map)		&& !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, (void *)map)		&& !test_bit(SCTP_CID_COOKIE_ECHO, (void *)map)		&& !test_bit(SCTP_CID_ABORT, (void *)map)		&& !test_bit(SCTP_CID_SHUTDOWN_ACK, (void *)map)		&& (sh->vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {		DEBUGP("Verification tag check failed\n");		return -1;	}	oldsctpstate = newconntrack = SCTP_CONNTRACK_MAX;	for_each_sctp_chunk (skb, sch, _sch, offset, count) {		write_lock_bh(&sctp_lock);		/* Special cases of Verification tag check (Sec 8.5.1) */		if (sch->type == SCTP_CID_INIT) {			/* Sec 8.5.1 (A) */			if (sh->vtag != 0) {				write_unlock_bh(&sctp_lock);				return -1;			}		} else if (sch->type == SCTP_CID_ABORT) {			/* Sec 8.5.1 (B) */			if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])				&& !(sh->vtag == conntrack->proto.sctp.vtag							[1 - CTINFO2DIR(ctinfo)])) {				write_unlock_bh(&sctp_lock);				return -1;			}		} else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {			/* Sec 8.5.1 (C) */			if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])				&& !(sh->vtag == conntrack->proto.sctp.vtag							[1 - CTINFO2DIR(ctinfo)] 					&& (sch->flags & 1))) {				write_unlock_bh(&sctp_lock);				return -1;			}		} else if (sch->type == SCTP_CID_COOKIE_ECHO) {			/* Sec 8.5.1 (D) */			if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {				write_unlock_bh(&sctp_lock);				return -1;			}		}		oldsctpstate = conntrack->proto.sctp.state;		newconntrack = new_state(CTINFO2DIR(ctinfo), oldsctpstate, sch->type);		/* Invalid */		if (newconntrack == SCTP_CONNTRACK_MAX) {			DEBUGP("ip_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u\n",			       CTINFO2DIR(ctinfo), sch->type, oldsctpstate);			write_unlock_bh(&sctp_lock);			return -1;		}		/* If it is an INIT or an INIT ACK note down the vtag */		if (sch->type == SCTP_CID_INIT 			|| sch->type == SCTP_CID_INIT_ACK) {			sctp_inithdr_t _inithdr, *ih;			ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),			                        sizeof(_inithdr), &_inithdr);			if (ih == NULL) {					write_unlock_bh(&sctp_lock);					return -1;			}			DEBUGP("Setting vtag %x for dir %d\n", 					ih->init_tag, !CTINFO2DIR(ctinfo));			conntrack->proto.sctp.vtag[!CTINFO2DIR(ctinfo)] = ih->init_tag;		}		conntrack->proto.sctp.state = newconntrack;		if (oldsctpstate != newconntrack)			ip_conntrack_event_cache(IPCT_PROTOINFO, skb);		write_unlock_bh(&sctp_lock);	}	ip_ct_refresh_acct(conntrack, ctinfo, skb, *sctp_timeouts[newconntrack]);	if (oldsctpstate == SCTP_CONNTRACK_COOKIE_ECHOED		&& CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY		&& newconntrack == SCTP_CONNTRACK_ESTABLISHED) {		DEBUGP("Setting assured bit\n");		set_bit(IPS_ASSURED_BIT, &conntrack->status);		ip_conntrack_event_cache(IPCT_STATUS, skb);	}	return NF_ACCEPT;}/* Called when a new connection for this protocol found. */static int sctp_new(struct ip_conntrack *conntrack, 		    const struct sk_buff *skb){	enum sctp_conntrack newconntrack;	struct iphdr *iph = skb->nh.iph;	sctp_sctphdr_t _sctph, *sh;	sctp_chunkhdr_t _sch, *sch;	u_int32_t offset, count;	char map[256 / sizeof (char)] = {0};	DEBUGP(__FUNCTION__);	DEBUGP("\n");	sh = skb_header_pointer(skb, iph->ihl * 4, sizeof(_sctph), &_sctph);	if (sh == NULL)		return 0;	if (do_basic_checks(conntrack, skb, map) != 0)		return 0;	/* If an OOTB packet has any of these chunks discard (Sec 8.4) */	if ((test_bit (SCTP_CID_ABORT, (void *)map))		|| (test_bit (SCTP_CID_SHUTDOWN_COMPLETE, (void *)map))		|| (test_bit (SCTP_CID_COOKIE_ACK, (void *)map))) {		return 0;	}	newconntrack = SCTP_CONNTRACK_MAX;	for_each_sctp_chunk (skb, sch, _sch, offset, count) {		/* Don't need lock here: this conntrack not in circulation yet */		newconntrack = new_state (IP_CT_DIR_ORIGINAL, 						SCTP_CONNTRACK_NONE, sch->type);		/* Invalid: delete conntrack */		if (newconntrack == SCTP_CONNTRACK_MAX) {			DEBUGP("ip_conntrack_sctp: invalid new deleting.\n");			return 0;		}		/* Copy the vtag into the state info */		if (sch->type == SCTP_CID_INIT) {			if (sh->vtag == 0) {				sctp_inithdr_t _inithdr, *ih;				ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),				                        sizeof(_inithdr), &_inithdr);				if (ih == NULL)					return 0;				DEBUGP("Setting vtag %x for new conn\n", 					ih->init_tag);				conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = 								ih->init_tag;			} else {				/* Sec 8.5.1 (A) */				return 0;			}		}		/* If it is a shutdown ack OOTB packet, we expect a return		   shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */		else {			DEBUGP("Setting vtag %x for new conn OOTB\n", 				sh->vtag);			conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;		}		conntrack->proto.sctp.state = newconntrack;	}	return 1;}static struct ip_conntrack_protocol ip_conntrack_protocol_sctp = { 	.proto 		 = IPPROTO_SCTP, 	.name 		 = "sctp",	.pkt_to_tuple 	 = sctp_pkt_to_tuple, 	.invert_tuple 	 = sctp_invert_tuple, 	.print_tuple 	 = sctp_print_tuple, 	.print_conntrack = sctp_print_conntrack,	.packet 	 = sctp_packet, 	.new 		 = sctp_new, 	.destroy 	 = NULL, 	.me 		 = THIS_MODULE,#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \    defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)	.tuple_to_nfattr = ip_ct_port_tuple_to_nfattr,	.nfattr_to_tuple = ip_ct_port_nfattr_to_tuple,#endif};#ifdef CONFIG_SYSCTLstatic ctl_table ip_ct_sysctl_table[] = {	{		.ctl_name	= NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,		.procname	= "ip_conntrack_sctp_timeout_closed",		.data		= &ip_ct_sctp_timeout_closed,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,		.procname	= "ip_conntrack_sctp_timeout_cookie_wait",		.data		= &ip_ct_sctp_timeout_cookie_wait,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,		.procname	= "ip_conntrack_sctp_timeout_cookie_echoed",		.data		= &ip_ct_sctp_timeout_cookie_echoed,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,		.procname	= "ip_conntrack_sctp_timeout_established",		.data		= &ip_ct_sctp_timeout_established,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,		.procname	= "ip_conntrack_sctp_timeout_shutdown_sent",		.data		= &ip_ct_sctp_timeout_shutdown_sent,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,		.procname	= "ip_conntrack_sctp_timeout_shutdown_recd",		.data		= &ip_ct_sctp_timeout_shutdown_recd,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,		.procname	= "ip_conntrack_sctp_timeout_shutdown_ack_sent",		.data		= &ip_ct_sctp_timeout_shutdown_ack_sent,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{ .ctl_name = 0 }};static ctl_table ip_ct_netfilter_table[] = {	{		.ctl_name	= NET_IPV4_NETFILTER,		.procname	= "netfilter",		.mode		= 0555,		.child		= ip_ct_sysctl_table,	},	{ .ctl_name = 0 }};static ctl_table ip_ct_ipv4_table[] = {	{		.ctl_name	= NET_IPV4,		.procname	= "ipv4",		.mode		= 0555,		.child		= ip_ct_netfilter_table,	},	{ .ctl_name = 0 }};static ctl_table ip_ct_net_table[] = {	{		.ctl_name	= CTL_NET,		.procname	= "net",		.mode		= 0555, 		.child		= ip_ct_ipv4_table,	},	{ .ctl_name = 0 }};static struct ctl_table_header *ip_ct_sysctl_header;#endifstatic int __init init(void){	int ret;	ret = ip_conntrack_protocol_register(&ip_conntrack_protocol_sctp);	if (ret) {		printk("ip_conntrack_proto_sctp: protocol register failed\n");		goto out;	}#ifdef CONFIG_SYSCTL	ip_ct_sysctl_header = register_sysctl_table(ip_ct_net_table, 0);	if (ip_ct_sysctl_header == NULL) {		ret = -ENOMEM;		printk("ip_conntrack_proto_sctp: can't register to sysctl.\n");		goto cleanup;	}#endif	return ret;#ifdef CONFIG_SYSCTL cleanup:	ip_conntrack_protocol_unregister(&ip_conntrack_protocol_sctp);#endif out:	DEBUGP("SCTP conntrack module loading %s\n", 					ret ? "failed": "succeeded");	return ret;}static void __exit fini(void){	ip_conntrack_protocol_unregister(&ip_conntrack_protocol_sctp);#ifdef CONFIG_SYSCTL 	unregister_sysctl_table(ip_ct_sysctl_header);#endif	DEBUGP("SCTP conntrack module unloaded\n");}module_init(init);module_exit(fini);MODULE_LICENSE("GPL");MODULE_AUTHOR("Kiran Kumar Immidi");MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");

⌨️ 快捷键说明

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