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

📄 ipsec_rcv.c

📁 openswan
💻 C
📖 第 1 页 / 共 5 页
字号:
	return skb;}#endifintipsec_rcv(struct sk_buff *skb#ifndef PROTO_HANDLER_SINGLE_PARM	  unsigned short xlen#endif /* PROTO_HANDLER_SINGLE_PARM */	  ){#ifdef CONFIG_KLIPS_DEBUG	struct net_device *dev = skb->dev;#endif /* CONFIG_KLIPS_DEBUG */	unsigned char protoc;	struct net_device_stats *stats = NULL;		/* This device's statistics */	struct net_device *ipsecdev = NULL, *prvdev;	struct ipsecpriv *prv;	struct ipsec_rcv_state nirs, *irs = &nirs;	struct iphdr *ipp;	char name[9];	int i;	/* Don't unlink in the middle of a turnaround */	KLIPS_INC_USE;	memset(&nirs, 0, sizeof(struct ipsec_rcv_state));	if (skb == NULL) {		KLIPS_PRINT(debug_rcv,			    "klips_debug:ipsec_rcv: "			    "NULL skb passed in.\n");		goto rcvleave;	}	if (skb->data == NULL) {		KLIPS_PRINT(debug_rcv,			    "klips_debug:ipsec_rcv: "			    "NULL skb->data passed in, packet is bogus, dropping.\n");		goto rcvleave;	}#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(NET_26)	{		/* NET_26 NAT-T is handled by seperate function */		struct sk_buff *nskb;		int udp_decap_ret = 0;		nskb = ipsec_rcv_natt_decap(skb, irs, &udp_decap_ret);		if(nskb == NULL) {			/* return with non-zero, because UDP.c code			 * need to send it upstream.			 */			if(skb && udp_decap_ret == 0) {				ipsec_kfree_skb(skb);			}			KLIPS_DEC_USE;			return(udp_decap_ret);		}		skb = nskb;	}#endif /* NAT_T */	/* dev->hard_header_len is unreliable and should not be used */	irs->hard_header_len = skb->mac.raw ? (skb->nh.raw - skb->mac.raw) : 0;	if((irs->hard_header_len < 0) || (irs->hard_header_len > skb_headroom(skb)))		irs->hard_header_len = 0;	skb = ipsec_rcv_unclone(skb, irs);	if(skb == NULL) {		goto rcvleave;	}#if IP_FRAGMENT_LINEARIZE	/* In Linux 2.4.4, we may have to reassemble fragments. They are	   not assembled automatically to save TCP from having to copy	   twice.	*/	if (skb_is_nonlinear(skb)) {#ifdef HAVE_NEW_SKB_LINEARIZE		if (skb_linearize_cow(skb) != 0)#else		if (skb_linearize(skb, GFP_ATOMIC) != 0) #endif		{			goto rcvleave;		}	}#endif /* IP_FRAGMENT_LINEARIZE */#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(NET_26)	if (irs->natt_len) {		/**		 * Now, we are sure packet is ESPinUDP, and we have a private		 * copy that has been linearized, remove natt_len bytes		 * from packet and modify protocol to ESP.		 */		if (((unsigned char *)skb->data > (unsigned char *)skb->nh.iph)		    && ((unsigned char *)skb->nh.iph > (unsigned char *)skb->head))		{			unsigned int _len = (unsigned char *)skb->data -				(unsigned char *)skb->nh.iph;			KLIPS_PRINT(debug_rcv,				"klips_debug:ipsec_rcv: adjusting skb: skb_push(%u)\n",				_len);			skb_push(skb, _len);		}		KLIPS_PRINT(debug_rcv,		    "klips_debug:ipsec_rcv: "			"removing %d bytes from ESPinUDP packet\n", irs->natt_len);		ipp = skb->nh.iph;		irs->iphlen = ipp->ihl << 2;		ipp->tot_len = htons(ntohs(ipp->tot_len) - irs->natt_len);		if (skb->len < irs->iphlen + irs->natt_len) {			printk(KERN_WARNING		       "klips_error:ipsec_rcv: "		       "ESPinUDP packet is too small (%d < %d+%d). "			   "This should never happen, please report.\n",		       (int)(skb->len), irs->iphlen, irs->natt_len);			goto rcvleave;		}		/* advance payload pointer to point past the UDP header */		skb->h.raw = skb->h.raw + irs->natt_len;		/* modify protocol */		ipp->protocol = IPPROTO_ESP;		skb->sk = NULL;		KLIPS_IP_PRINT(debug_rcv, skb->nh.iph);	}#endif	ipp = skb->nh.iph;	{	  	struct in_addr ipsaddr;		struct in_addr ipdaddr;		ipsaddr.s_addr = ipp->saddr;		addrtoa(ipsaddr, 0, irs->ipsaddr_txt			, sizeof(irs->ipsaddr_txt));		ipdaddr.s_addr = ipp->daddr;		addrtoa(ipdaddr, 0, irs->ipdaddr_txt			, sizeof(irs->ipdaddr_txt));	}	irs->iphlen = ipp->ihl << 2;	KLIPS_PRINT(debug_rcv,		    "klips_debug:ipsec_rcv: "		    "<<< Info -- ");	KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ",			skb->dev->name ? skb->dev->name : "NULL");	KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ",			dev->name ? dev->name : "NULL");	KLIPS_PRINTMORE(debug_rcv, "\n");	KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)),		    "klips_debug:ipsec_rcv: "		    "Informational -- **if this happens, find out why** skb->dev:%s is not equal to dev:%s\n",		    skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL",		    dev ? (dev->name ? dev->name : "NULL") : "NULL");	protoc = ipp->protocol;#ifndef NET_21	if((!protocol) || (protocol->protocol != protoc)) {		KLIPS_PRINT(debug_rcv & DB_RX_IPSA,			    "klips_debug:ipsec_rcv: "			    "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n");	}#endif /* !NET_21 */	if( (protoc != IPPROTO_AH) &&#ifdef CONFIG_KLIPS_IPCOMP_disabled_until_we_register_IPCOMP_HANDLER	    (protoc != IPPROTO_COMP) &&#endif /* CONFIG_KLIPS_IPCOMP */	    (protoc != IPPROTO_ESP) ) {		KLIPS_PRINT(debug_rcv & DB_RX_IPSA,			    "klips_debug:ipsec_rcv: Why the hell is someone "			    "passing me a non-ipsec protocol = %d packet? -- dropped.\n",			    protoc);		goto rcvleave;	}	if(skb->dev) {		for(i = 0; i < IPSEC_NUM_IF; i++) {			sprintf(name, IPSEC_DEV_FORMAT, i);			if(!strcmp(name, skb->dev->name)) {				prv = (struct ipsecpriv *)(skb->dev->priv);				if(prv) {					stats = (struct net_device_stats *) &(prv->mystats);				}				ipsecdev = skb->dev;				KLIPS_PRINT(debug_rcv,					    "klips_debug:ipsec_rcv: "					    "Info -- pkt already proc'ed a group of ipsec headers, processing next group of ipsec headers.\n");				break;			}			if((ipsecdev = __ipsec_dev_get(name)) == NULL) {				KLIPS_PRINT(debug_rcv,					    "klips_error:ipsec_rcv: "					    "device %s does not exist\n",					    name);			}			prv = ipsecdev ? (struct ipsecpriv *)(ipsecdev->priv) : NULL;			prvdev = prv ? (struct net_device *)(prv->dev) : NULL;#if 0			KLIPS_PRINT(debug_rcv && prvdev,				    "klips_debug:ipsec_rcv: "				    "physical device for device %s is %s\n",				    name,				    prvdev->name);#endif			if(prvdev && skb->dev &&			   !strcmp(prvdev->name, skb->dev->name)) {				stats = prv ? ((struct net_device_stats *) &(prv->mystats)) : NULL;				skb->dev = ipsecdev;				KLIPS_PRINT(debug_rcv && prvdev,					    "klips_debug:ipsec_rcv: "					    "assigning packet ownership to virtual device %s from physical device %s.\n",					    name, prvdev->name);				if(stats) {					stats->rx_packets++;				}				break;			}		}	} else {		KLIPS_PRINT(debug_rcv,			    "klips_debug:ipsec_rcv: "			    "device supplied with skb is NULL\n");	}	if(stats == NULL) {		KLIPS_PRINT((debug_rcv),			    "klips_error:ipsec_rcv: "			    "packet received from physical I/F (%s) not connected to ipsec I/F.  Cannot record stats.  May not have SA for decoding.  Is IPSEC traffic expected on this I/F?  Check routing.\n",			    skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL");	}			KLIPS_IP_PRINT(debug_rcv, ipp);	/* set up for decap loop */	irs->stats= stats;	irs->ipp  = ipp;	irs->ipsp = NULL;	irs->ilen = 0;	irs->authlen=0;	irs->authfuncs=NULL;	irs->skb = skb;	ipsec_rcv_decap(irs);	KLIPS_DEC_USE;	return(0); rcvleave:	if(skb) {		ipsec_kfree_skb(skb);	}	KLIPS_DEC_USE;	return(0);}#ifdef NET_26/* * this entry point is not a protocol entry point, so the entry * is a bit different. * * skb->iph->tot_len has been byte-swapped, and reduced by the size of *              the IP header (and options). *  * skb->h.raw has been pulled up the ESP header. * * skb->iph->protocol = 50 IPPROTO_ESP; * */int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type){	struct ipsec_rcv_state nirs, *irs = &nirs;	struct iphdr *ipp;	/* Don't unlink in the middle of a turnaround */	KLIPS_INC_USE;	memset(irs, 0, sizeof(*irs));	/* XXX fudge it so that all nat-t stuff comes from ipsec0    */	/*     eventually, the SA itself will determine which device	 *     it comes from	 */ 	{	  skb->dev = ipsec_get_device(0);	}	/* set up for decap loop */	irs->hard_header_len = skb->dev->hard_header_len;	skb = ipsec_rcv_unclone(skb, irs);#if IP_FRAGMENT_LINEARIZE	/* In Linux 2.4.4, we may have to reassemble fragments. They are	   not assembled automatically to save TCP from having to copy	   twice.	*/	if (skb_is_nonlinear(skb)) {#ifdef HAVE_NEW_SKB_LINEARIZE		if (skb_linearize_cow(skb) != 0) #else		if (skb_linearize(skb, GFP_ATOMIC) != 0) #endif		{			goto rcvleave;		}	}#endif /* IP_FRAGMENT_LINEARIZE */	ipp = skb->nh.iph;	{	  	struct in_addr ipsaddr;		struct in_addr ipdaddr;		ipsaddr.s_addr = ipp->saddr;		addrtoa(ipsaddr, 0, irs->ipsaddr_txt			, sizeof(irs->ipsaddr_txt));		ipdaddr.s_addr = ipp->daddr;		addrtoa(ipdaddr, 0, irs->ipdaddr_txt			, sizeof(irs->ipdaddr_txt));	}	irs->iphlen = ipp->ihl << 2;	KLIPS_IP_PRINT(debug_rcv, ipp);	irs->stats= NULL;	irs->ipp  = ipp;	irs->ipsp = NULL;	irs->ilen = 0;	irs->authlen=0;	irs->authfuncs=NULL;	irs->skb = skb;#ifdef CONFIG_IPSEC_NAT_TRAVERSAL	switch(encap_type) {	case UDP_ENCAP_ESPINUDP:	  irs->natt_type = ESPINUDP_WITH_NON_ESP;	  break;	  	case UDP_ENCAP_ESPINUDP_NON_IKE:	  irs->natt_type = ESPINUDP_WITH_NON_IKE;	  break;	  	default:	  if(printk_ratelimit()) {	    printk(KERN_INFO "KLIPS received unknown UDP-ESP encap type %u\n",		   encap_type);	  }	  return -1;	}#endif	ipsec_rcv_decap(irs);	KLIPS_DEC_USE;	return 0;rcvleave:	if(skb) {		ipsec_kfree_skb(skb);	}	KLIPS_DEC_USE;	return 0;}#endif/* * $Log: ipsec_rcv.c,v $ * Revision 1.171.2.9  2006/07/30 02:09:33  paul * Author: Bart Trojanowski <bart@xelerance.com> * This fixes a NATT+ESP bug in rcv path. * *     We only want to test NATT policy on the ESP packet.  Doing so on the *     bundled SA breaks because the next layer does not know anything about *     NATT. * *     Fix just puts an if(proto == IPPROTO_ESP) around the NATT policy check. * * Revision 1.171.2.8  2006/07/29 05:03:04  paul * Added check for new version of skb_linearize that only takes 1 argument, * for 2.6.18+ kernels. * * Revision 1.171.2.7  2006/04/20 16:33:07  mcr * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it. * Fix in-kernel module compilation. Sub-makefiles do not work. * * Revision 1.171.2.6  2005/12/07 06:07:04  paul * comment out KLIPS_DEC_USE in ipsec_rcv_decap. Likely an artifact from * refactoring. http://bugs.xelerance.com/view.php?id=454 * * Revision 1.171.2.5  2005/10/21 02:22:29  mcr * 	pull up of another try at 2.4.x kernel fix * * Revision 1.171.2.4  2005/10/21 01:39:56  mcr *     nat-t fix is 2.4/2.6 specific * * Revision 1.178  2005/10/21 02:19:34  mcr * 	on 2.4 systems, we have to fix up the length as well. * * Revision 1.177  2005/10/21 00:18:31  mcr * 	nat-t fix is 2.4 specific. * * Revision 1.176  2005/10/20 21:06:11  mcr * 	possible fix for nat-t problem on 2.4 kernels. * * Revision 1.175  2005/10/13 02:49:24  mcr * 	tested UDP-encapsulated ESP packets that were not actually ESP, * 	(but IKE) were being eaten. * * Revision 1.174  2005/10/13 01:25:22  mcr * 	UDP-encapsulated ESP packets that were not actually ESP, * 	(but IKE) were being eaten. * * Revision 1.173  2005/08/31 23:26:11  mcr * 	fixes for 2.6.13 * * Revision 1.172  2005/08/05 08:44:54  mcr * 	ipsec_kern24.h (compat code for 2.4) must be include * 	explicitely now. * * Revision 1.171  2005/07/08 23:56:06  ken * #ifdef * * Revision 1.170  2005/07/08 23:50:05  ken * Don't attempt to decapsulate if NAT-T isn't available in the code * * Revision 1.169  2005/06/06 00:27:31  mcr * 	fix for making tcpdump (packet capture) work correctly for

⌨️ 快捷键说明

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