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

📄 ipsec_rcv.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 5 页
字号:
	  struct udp_opt *tp =  &us->udp;	  struct iphdr *ip = (struct iphdr *)skb->nh.iph;	  struct udphdr *udp = (struct udphdr *)((__u32 *)ip+ip->ihl);	  __u8 *udpdata = (__u8 *)udp + sizeof(struct udphdr);	  __u32 *udpdata32 = (__u32 *)udpdata;	  irs.natt_sport = ntohs(udp->source);	  irs.natt_dport = ntohs(udp->dest);	  KLIPS_PRINT(debug_rcv,		      "klips_debug:ipsec_rcv: "		      "suspected ESPinUDP packet (NAT-Traversal) [%d].\n",		      tp->esp_in_udp);	  KLIPS_IP_PRINT(debug_rcv, ip);	  	  if (udpdata < skb->tail) {	    unsigned int len = skb->tail - udpdata;	    if ((len==1) && (udpdata[0]==0xff)) {	      KLIPS_PRINT(debug_rcv,			  "klips_debug:ipsec_rcv: "			  /* not IPv6 compliant message */			  "NAT-keepalive from %d.%d.%d.%d.\n", NIPQUAD(ip->saddr));	      goto rcvleave;	    }	    else if ( (tp->encap_type == ESPINUDP_WITH_NON_IKE) &&		      (len > (2*sizeof(__u32) + sizeof(struct esphdr))) &&		      (udpdata32[0]==0) && (udpdata32[1]==0) ) {	      /* ESP Packet with Non-IKE header */	      KLIPS_PRINT(debug_rcv, 			  "klips_debug:ipsec_rcv: "			  "ESPinUDP pkt with Non-IKE - spi=0x%x\n",			  ntohl(udpdata32[2]));	      irs.natt_type = ESPINUDP_WITH_NON_IKE;	      irs.natt_len = sizeof(struct udphdr)+(2*sizeof(__u32));	    }	    else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_ESP) &&		      (len > sizeof(struct esphdr)) &&		      (udpdata32[0]!=0) ) {	      /* ESP Packet without Non-ESP header */	      irs.natt_type = ESPINUDP_WITH_NON_ESP;	      irs.natt_len = sizeof(struct udphdr);	      KLIPS_PRINT(debug_rcv, 			  "klips_debug:ipsec_rcv: "			  "ESPinUDP pkt without Non-ESP - spi=0x%x\n",			  ntohl(udpdata32[0]));	    }	    else {	      KLIPS_PRINT(debug_rcv,			  "klips_debug:ipsec_rcv: "			  "IKE packet - not handled here\n");	      KLIPS_DEC_USE;	      return -1;	    }	  }	  else {	    KLIPS_DEC_USE;	    return -1;	  }#endif /* NAT-T not supported on 2.6. */#else  /* NET_26 */#ifndef UDP_OPT_IN_SOCK	  struct udp_opt {	    __u32 esp_in_udp;	  };	  struct udp_opt *tp =  (struct udp_opt *)&(skb->sk->tp_pinfo.af_tcp);#else	  struct udp_opt *tp =  &(skb->sk->tp_pinfo.af_udp);#endif	  struct iphdr *ip = (struct iphdr *)skb->nh.iph;	  struct udphdr *udp = (struct udphdr *)((__u32 *)ip+ip->ihl);	  __u8 *udpdata = (__u8 *)udp + sizeof(struct udphdr);	  __u32 *udpdata32 = (__u32 *)udpdata;	  	  irs.natt_sport = ntohs(udp->source);	  irs.natt_dport = ntohs(udp->dest);	  	  KLIPS_PRINT(debug_rcv,		      "klips_debug:ipsec_rcv: "		      "suspected ESPinUDP packet (NAT-Traversal) [%d].\n",		      tp->esp_in_udp);	  KLIPS_IP_PRINT(debug_rcv, ip);	  	  if (udpdata < skb->tail) {	    unsigned int len = skb->tail - udpdata;	    if ((len==1) && (udpdata[0]==0xff)) {	      KLIPS_PRINT(debug_rcv,			  "klips_debug:ipsec_rcv: "			  /* not IPv6 compliant message */			  "NAT-keepalive from %d.%d.%d.%d.\n", NIPQUAD(ip->saddr));	      goto rcvleave;	    }	    else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_IKE) &&		      (len > (2*sizeof(__u32) + sizeof(struct esphdr))) &&		      (udpdata32[0]==0) && (udpdata32[1]==0) ) {	      /* ESP Packet with Non-IKE header */	      KLIPS_PRINT(debug_rcv, 			  "klips_debug:ipsec_rcv: "			  "ESPinUDP pkt with Non-IKE - spi=0x%x\n",			  ntohl(udpdata32[2]));	      irs.natt_type = ESPINUDP_WITH_NON_IKE;	      irs.natt_len = sizeof(struct udphdr)+(2*sizeof(__u32));	    }	    else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_ESP) &&		      (len > sizeof(struct esphdr)) &&		      (udpdata32[0]!=0) ) {	      /* ESP Packet without Non-ESP header */	      irs.natt_type = ESPINUDP_WITH_NON_ESP;	      irs.natt_len = sizeof(struct udphdr);	      KLIPS_PRINT(debug_rcv, 			  "klips_debug:ipsec_rcv: "			  "ESPinUDP pkt without Non-ESP - spi=0x%x\n",			  ntohl(udpdata32[0]));	    }	    else {	      KLIPS_PRINT(debug_rcv,			  "klips_debug:ipsec_rcv: "			  "IKE packet - not handled here\n");	      KLIPS_INC_USE;	      return -1;	    }	  }	  else {	    KLIPS_DEC_USE;	    return -1;	  }#endif /* NET_26 */	}#endif /* NAT_T */#ifdef IPH_is_SKB_PULLED	/* In Linux 2.4.4, the IP header has been skb_pull()ed before the	   packet is passed to us. So we'll skb_push() to get back to it. */	if (skb->data == skb->h.raw) {		skb_push(skb, skb->h.raw - skb->nh.raw);	}#endif /* IPH_is_SKB_PULLED */	/* dev->hard_header_len is unreliable and should not be used */	irs.hard_header_len = skb->mac.raw ? (skb->data - skb->mac.raw) : 0;	if((irs.hard_header_len < 0) || (irs.hard_header_len > skb_headroom(skb)))		irs.hard_header_len = 0;#ifdef NET_21	/* if skb was cloned (most likely due to a packet sniffer such as	   tcpdump being momentarily attached to the interface), make	   a copy of our own to modify */	if(skb_cloned(skb)) {		/* include any mac header while copying.. */		if(skb_headroom(skb) < irs.hard_header_len) {			printk(KERN_WARNING "klips_error:ipsec_rcv: "			       "tried to skb_push hhlen=%d, %d available.  This should never happen, please report.\n",			       irs.hard_header_len,			       skb_headroom(skb));			goto rcvleave;		}		skb_push(skb, irs.hard_header_len);		if#ifdef SKB_COW_NEW		  (skb_cow(skb, skb_headroom(skb)) != 0)#else /* SKB_COW_NEW */		  ((skb = skb_cow(skb, skb_headroom(skb))) == NULL)#endif /* SKB_COW_NEW */		{			goto rcvleave;		}		if(skb->len < irs.hard_header_len) {			printk(KERN_WARNING "klips_error:ipsec_rcv: "			       "tried to skb_pull hhlen=%d, %d available.  This should never happen, please report.\n",			       irs.hard_header_len,			       skb->len);			goto rcvleave;		}		skb_pull(skb, irs.hard_header_len);	}#endif /* NET_21 */#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)) {		if (skb_linearize(skb, GFP_ATOMIC) != 0) {			goto rcvleave;		}	}#endif /* IP_FRAGMENT_LINEARIZE */#ifdef CONFIG_IPSEC_NAT_TRAVERSAL	if (irs.natt_len) {		/**		 * Now, we are sure packet is ESPinUDP. 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 = (struct iphdr *)skb->data;		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;		}		memmove(skb->data + irs.natt_len, skb->data, irs.iphlen);		skb_pull(skb, irs.natt_len);		/* update nh.iph */		ipp = skb->nh.iph = (struct iphdr *)skb->data;		/* modify protocol */		ipp->protocol = IPPROTO_ESP;		skb->sk = NULL;		KLIPS_IP_PRINT(debug_rcv, skb->nh.iph);	}#endif	ipp = skb->nh.iph;	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);	/* begin decapsulating loop here */	/*	  The spinlock is to prevent any other process from	  accessing or deleting the ipsec_sa hash table or any of the	  ipsec_sa s while we are using and updating them.	  This is not optimal, but was relatively straightforward	  at the time.  A better way to do it has been planned for	  more than a year, to lock the hash table and put reference	  counts on each ipsec_sa instead.  This is not likely to happen	  in KLIPS1 unless a volunteer contributes it, but will be	  designed into KLIPS2.	*/	spin_lock(&tdb_lock);	/* 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;	do {	        int decap_stat;		struct xform_functions *proto_funcs;		switch(irs.ipp->protocol) {		case IPPROTO_ESP:		  proto_funcs = esp_xform_funcs;		  break;		  #ifdef CONFIG_KLIPS_AH		case IPPROTO_AH:		  proto_funcs = ah_xform_funcs;		  break;#endif /* !CONFIG_KLIPS_AH */		  #ifdef CONFIG_KLIPS_IPCOMP		case IPPROTO_COMP:		  proto_funcs = ipcomp_xform_funcs;		  break;#endif /* !CONFIG_KLIPS_IPCOMP */		default:		  if(irs.stats) {		    irs.stats->rx_errors++;		  }		  decap_stat = IPSEC_RCV_BADPROTO;		  goto rcvleave;		}	        decap_stat = ipsec_rcv_decap_once(&irs, proto_funcs);		if(decap_stat != IPSEC_RCV_OK) {			spin_unlock(&tdb_lock);			KLIPS_PRINT(debug_rcv,				    "klips_debug:ipsec_rcv: decap_once failed: %d\n",				    decap_stat);					goto rcvleave;		}	/* end decapsulation loop here */	} while(   (irs.ipp->protocol == IPPROTO_ESP )		|| (irs.ipp->protocol == IPPROTO_AH  )#ifdef CONFIG_KLIPS_IPCOMP		|| (irs.ipp->protocol == IPPROTO_COMP)#endif /* CONFIG_KLIPS_IPCOMP */		);	/* set up for decap loop */	ipp  =irs.ipp;	ipsp =irs.ipsp;

⌨️ 快捷键说明

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