ipsec_tunnel.c

来自「网上下到的一个很详细介绍VPN基础知识的资料」· C语言 代码 · 共 2,162 行 · 第 1/5 页

C
2,162
字号
				stats->tx_errors++;				goto cleanup;			}			#ifdef NET_21			skb->nh.raw = skb->data;#else /* NET_21 */			skb->ip_hdr = skb->h.iph = (struct iphdr *) skb->data;#endif /* NET_21 */			iph->check = 0;			iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);						KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,				    "klips_debug:ipsec_tunnel_start_xmit: "				    "after <%s%s%s>, SA:%s:\n",				    TDB_XFORM_NAME(tdbp),				    sa_len ? sa : " (error)");			KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, iph); 						tdbp->tdb_lifetime_bytes_c += len;			if(!tdbp->tdb_lifetime_usetime_c) {				tdbp->tdb_lifetime_usetime_c = jiffies / HZ;			}			tdbp->tdb_lifetime_usetime_l = jiffies / HZ;			tdbp->tdb_lifetime_packets_c += 1;			tdbprev = tdbp;			tdbp = tdbp->tdb_onext;					}		/* end encapsulation loop here XXX */		spin_unlock(&tdb_lock);		matcher.sen_ip_src.s_addr = iph->saddr;		matcher.sen_ip_dst.s_addr = iph->daddr;		spin_lock(&eroute_lock);		er = ipsec_findroute(&matcher);		if(er) {			outgoing_said = er->er_said;			eroute_pid = er->er_pid;			er->er_count++;			er->er_lasttime = jiffies/HZ;		}		spin_unlock(&eroute_lock);		KLIPS_PRINT((debug_tunnel & DB_TN_XMIT) &&			    /* ((orgdst != newdst) || (orgsrc != newsrc)) */			    (orgedst != outgoing_said.dst.s_addr) &&			    outgoing_said.dst.s_addr &&			    er,			    "klips_debug:ipsec_tunnel_start_xmit: "			    "We are recursing here.\n");	} while(/*((orgdst != newdst) || (orgsrc != newsrc))*/		(orgedst != outgoing_said.dst.s_addr) &&		outgoing_said.dst.s_addr &&		er);		KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,		    "klips_debug:ipsec_tunnel_start_xmit: "		    "After recursive xforms -- head,tailroom: %d,%d\n",		    skb_headroom(skb), skb_tailroom(skb));	if(sysctl_ipsec_icmp && (innersrc != newsrc) && (ntohs(iph->tot_len) > physmtu)) {		ICMP_SEND(oskb ? oskb : skb,			  ICMP_DEST_UNREACH,			  ICMP_FRAG_NEEDED,			  prv->mtu,			  physdev);		KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,			    "klips_debug:ipsec_tunnel_start_xmit: "			    "IPSEC tunnel mode packet is larger than MTU, ICMP sent.\n");	}	if(saved_header) {		if(skb_headroom(skb) < hard_header_len) {			printk(KERN_WARNING			       "klips_error:ipsec_tunnel_start_xmit: "			       "tried to skb_push hhlen=%d, %d available.  This should never happen, please report.\n",			       hard_header_len, skb_headroom(skb));			stats->tx_errors++;			goto cleanup;		}		skb_push(skb, hard_header_len);		for (i = 0; i < hard_header_len; i++) {			skb->data[i] = saved_header[i];		}	} bypass:	KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,		    "klips_debug:ipsec_tunnel_start_xmit: "		    "With hard_header, final head,tailroom: %d,%d\n",		    skb_headroom(skb), skb_tailroom(skb));#ifdef NET_21	/* 2.2 and 2.4 kernels */	/* new route/dst cache code from James Morris */	skb->dev = physdev;	/*skb_orphan(skb);*/	if((error = ip_route_output(&rt,				   skb->nh.iph->daddr,				   pass ? 0 : skb->nh.iph->saddr,				   RT_TOS(skb->nh.iph->tos),				   physdev->iflink))) {		stats->tx_errors++;		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,			    "klips_debug:ipsec_tunnel_start_xmit: "			    "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",			    error,			    rt->u.dst.dev->name);		goto cleanup;	}	if(dev == rt->u.dst.dev) {		ip_rt_put(rt);		/* This is recursion, drop it. */		stats->tx_errors++;		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,			    "klips_debug:ipsec_tunnel_start_xmit: "			    "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n", dev->name);		goto cleanup;	}	dst_release(skb->dst);	skb->dst = &rt->u.dst;	stats->tx_bytes += skb->len;	if(skb->len < skb->nh.raw - skb->data) {		stats->tx_errors++;		printk(KERN_WARNING		       "klips_error:ipsec_tunnel_start_xmit: "		       "tried to __skb_pull nh-data=%d, %d available.  This should never happen, please report.\n",		       skb->nh.raw - skb->data, skb->len);		goto cleanup;	}	__skb_pull(skb, skb->nh.raw - skb->data);#ifdef SKB_RESET_NFCT	nf_conntrack_put(skb->nfct);	skb->nfct = NULL;#ifdef CONFIG_NETFILTER_DEBUG	skb->nf_debug = 0;#endif /* CONFIG_NETFILTER_DEBUG */#endif /* SKB_RESET_NFCT */	KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,		    "klips_debug:ipsec_tunnel_start_xmit: "		    "...done, calling ip_send() on device:%s\n",		    skb->dev ? skb->dev->name : "NULL");	KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, skb->nh.iph);#ifdef NETDEV_23	/* 2.4 kernels */	{		int err;		err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,			      ipsec_tunnel_xmit2);		if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {			if(net_ratelimit())				printk(KERN_ERR				       "klips_error:ipsec_tunnel_start_xmit: "				       "ip_send() failed, err=%d\n", 				       -err);			stats->tx_errors++;			stats->tx_aborted_errors++;			skb = NULL;			goto cleanup;		}	}#else /* NETDEV_23 */	/* 2.2 kernels */	ip_send(skb);#endif /* NETDEV_23 */#else /* NET_21 */	/* 2.0 kernels */	skb->arp = 1;	/* ISDN/ASYNC PPP from Matjaz Godec. */	/*	skb->protocol = htons(ETH_P_IP); */	KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,		    "klips_debug:ipsec_tunnel_start_xmit: "		    "...done, calling dev_queue_xmit() or ip_fragment().\n");	IP_SEND(skb, physdev);#endif /* NET_21 */	stats->tx_packets++;	skb = NULL; cleanup:#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)	netif_wake_queue(dev);#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */	dev->tbusy = 0;#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */	if(saved_header) {		kfree(saved_header);	}	if(skb) {		dev_kfree_skb(skb, FREE_WRITE);	}	if(oskb) {		dev_kfree_skb(oskb, FREE_WRITE);	}	return 0;}DEBUG_NO_STATIC struct net_device_stats *ipsec_tunnel_get_stats(struct device *dev){	return &(((struct ipsecpriv *)(dev->priv))->mystats);}/* * Revectored calls. * For each of these calls, a field exists in our private structure. */DEBUG_NO_STATIC intipsec_tunnel_hard_header(struct sk_buff *skb, struct device *dev,	unsigned short type, void *daddr, void *saddr, unsigned len){	struct ipsecpriv *prv = dev->priv;	struct device *tmp;	int ret;	struct net_device_stats *stats;	/* This device's statistics */		if(skb == NULL) {		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,			    "klips_debug:ipsec_tunnel_hard_header: "			    "no skb...");		return -ENODATA;	}	if(dev == NULL) {		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,			    "klips_debug:ipsec_tunnel_hard_header: "			    "no device...");		return -ENODEV;	}	KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,		    "klips_debug:ipsec_tunnel_hard_header: "		    "skb->dev=%s dev=%s.",		    skb->dev ? skb->dev->name : "NULL",		    dev->name);		if(prv == NULL) {		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,			    "klips_debug:ipsec_tunnel_hard_header: "			    "no private space associated with dev=%s",			    dev->name ? dev->name : "NULL");		return -ENODEV;	}	stats = (struct net_device_stats *) &(prv->mystats);	if(prv->dev == NULL) {		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,			    "klips_debug:ipsec_tunnel_hard_header: "			    "no physical device associated with dev=%s",			    dev->name ? dev->name : "NULL");		stats->tx_dropped++;		return -ENODEV;	}	/* check if we have to send a IPv6 packet. It might be a Router	   Solicitation, where the building of the packet happens in	   reverse order:	   1. ll hdr,	   2. IPv6 hdr,	   3. ICMPv6 hdr	   -> skb->nh.raw is still uninitialized when this function is	   called!!  If this is no IPv6 packet, we can print debugging	   messages, otherwise we skip all debugging messages and just	   build the ll header */	if(type != ETH_P_IPV6) {		/* execute this only, if we don't have to build the		   header for a IPv6 packet */		if(!prv->hard_header) {			KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,				    "klips_debug:ipsec_tunnel_hard_header: "				    "physical device has been detached, packet dropped 0x%p->0x%p len=%d type=%d dev=%s->NULL ",				    saddr,				    daddr,				    len,				    type,				    dev->name);#ifdef NET_21			KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,					"ip=%08x->%08x\n",					(__u32)ntohl(skb->nh.iph->saddr),					(__u32)ntohl(skb->nh.iph->daddr) );#else /* NET_21 */			KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,					"ip=%08x->%08x\n",					(__u32)ntohl(skb->ip_hdr->saddr),					(__u32)ntohl(skb->ip_hdr->daddr) );#endif /* NET_21 */			stats->tx_dropped++;			return -ENODEV;		}		#define da ((struct device *)(prv->dev))->dev_addr		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,			    "klips_debug:ipsec_tunnel_hard_header: "			    "Revectored 0x%p->0x%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",			    saddr,			    daddr,			    len,			    type,			    dev->name,			    prv->dev->name,			    da[0], da[1], da[2], da[3], da[4], da[5]);#ifdef NET_21		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,			    "ip=%08x->%08x\n",			    (__u32)ntohl(skb->nh.iph->saddr),			    (__u32)ntohl(skb->nh.iph->daddr) );#else /* NET_21 */		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,			    "ip=%08x->%08x\n",			    (__u32)ntohl(skb->ip_hdr->saddr),			    (__u32)ntohl(skb->ip_hdr->daddr) );#endif /* NET_21 */	} else {		KLIPS_PRINT(debug_tunnel,			    "klips_debug:ipsec_tunnel_hard_header: "			    "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");	}                                                                       	tmp = skb->dev;	skb->dev = prv->dev;	ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);	skb->dev = tmp;	return ret;}DEBUG_NO_STATIC int#ifdef NET_21ipsec_tunnel_rebuild_header(struct sk_buff *skb)#else /* NET_21 */ipsec_tunnel_rebuild_header(void *buff, struct device *dev,			unsigned long raddr, struct sk_buff *skb)#endif /* NET_21 */{	struct ipsecpriv *prv = skb->dev->priv;	struct device *tmp;	int ret;	struct net_device_stats *stats;	/* This device's statistics */		if(skb->dev == NULL) {		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,			    "klips_debug:ipsec_tunnel_rebuild_header: "			    "no device...");		return -ENODEV;	}	if(prv == NULL) {		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,			    "klips_debug:ipsec_tunnel_rebuild_header: "			    "no private space associated with dev=%s",			    skb->dev->name ? skb->dev->name : "NULL");		return -ENODEV;	}	stats = (struct net_device_stats *) &(prv->mystats);	if(prv->dev == NULL) {		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,			    "klips_debug:ipsec_tunnel_rebuild_header: "			    "no physical device associated with dev=%s",			    skb->dev->name ? skb->dev->name : "NULL");		stats->tx_dropped++;		return -ENODEV;	}	if(!prv->rebuild_header) {		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,			    "klips_debug:ipsec_tunnel_rebuild_header: "			    "physical device has been detached, packet dropped skb->dev=%s->NULL ",			    skb->dev->name);#ifdef NET_21		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,			    "ip=%08x->%08x\n",			    (__u32)ntohl(skb->nh.iph->saddr),			    (__u32)ntohl(skb->nh.iph->daddr) );#else /* NET_21 */		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,			    "ip=%08x->%08x\n",			    (__u32)ntohl(skb->ip_hdr->saddr),			    (__u32)ntohl(skb->ip_hdr->daddr) );#endif /* NET_21 */		stats->tx_dropped++;		return -ENODEV;	}	KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,		    "klips_debug:ipsec_tunnel: "		    "Revectored rebuild_header dev=%s->%s ",		    skb->dev->name, prv->dev->name);#ifdef NET_21	KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,		    "ip=%08x->%08x\n",		    (__u32)ntohl(skb->nh.iph->saddr),		    (__u32)ntohl(skb->nh.iph->daddr) );#else /* NET_21 */	KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,		    "ip=%08x->%08x\n",		    (__u32)ntohl(skb->ip_hdr->saddr),		    (__u32)ntohl(skb->ip_hdr->daddr) );#endif /* NET_21 */	tmp = skb->dev;	skb->dev = prv->dev;	#ifdef NET_21	ret = prv->rebuild_header(skb);#else /* NET_21 */	ret = prv->rebuild_header(buff, prv->dev, raddr, skb);#endif /* NET_21 */	skb->dev = tmp;	return ret;}DEBUG_NO_STATIC intipsec_tunnel_set_mac_address(struct device *dev, void *addr){	struct ipsecpriv *prv = dev->priv;		struct net_device_stats *stats;	/* This device's statistics */		if(dev == NULL) {		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,			    "klips_debug:ipsec_tunnel_set_mac_address: "			    "no device...");		return -ENODEV;	}	if(prv == NULL) {		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,			    "klips_debug:ipsec_tunnel_set_mac_address: "			    "no private space associated with dev=%s",			    dev->name ? dev->name : "NULL");		return -E

⌨️ 快捷键说明

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