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

📄 ipsec_mast.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * IPSEC MAST code. * Copyright (C) 1996, 1997  John Ioannidis. * Copyright (C) 1998, 1999, 2000, 2001, 2002  Richard Guy Briggs. *  * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>. *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * for more details. */char ipsec_mast_c_version[] = "RCSID $Id: ipsec_mast.c,v 1.6 2004/12/03 21:25:57 mcr Exp $";#define __NO_VERSION__#include <linux/module.h>#include <linux/config.h>	/* for CONFIG_IP_FORWARD */#include <linux/version.h>#include <linux/kernel.h> /* printk() */#include "freeswan/ipsec_param.h"#ifdef MALLOC_SLAB# include <linux/slab.h> /* kmalloc() */#else /* MALLOC_SLAB */# include <linux/malloc.h> /* kmalloc() */#endif /* MALLOC_SLAB */#include <linux/errno.h>  /* error codes */#include <linux/types.h>  /* size_t */#include <linux/interrupt.h> /* mark_bh */#include <linux/netdevice.h>   /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */#include <linux/etherdevice.h> /* eth_type_trans */#include <linux/ip.h>          /* struct iphdr */#include <linux/tcp.h>         /* struct tcphdr */#include <linux/udp.h>         /* struct udphdr */#include <linux/skbuff.h>#include <freeswan.h>#include <asm/uaccess.h>#include <linux/in6.h>#include <net/dst.h>#undef dev_kfree_skb#define dev_kfree_skb(a,b) kfree_skb(a)#define PHYSDEV_TYPE#include <asm/checksum.h>#include <net/icmp.h>		/* icmp_send() */#include <net/ip.h>#include <linux/netfilter_ipv4.h>#include <linux/if_arp.h>#include "freeswan/radij.h"#include "freeswan/ipsec_life.h"#include "freeswan/ipsec_xform.h"#include "freeswan/ipsec_eroute.h"#include "freeswan/ipsec_encap.h"#include "freeswan/ipsec_radij.h"#include "freeswan/ipsec_sa.h"#include "freeswan/ipsec_tunnel.h"#include "freeswan/ipsec_mast.h"#include "freeswan/ipsec_ipe4.h"#include "freeswan/ipsec_ah.h"#include "freeswan/ipsec_esp.h"#include <pfkeyv2.h>#include <pfkey.h>#include "freeswan/ipsec_proto.h"int ipsec_maxdevice_count = -1;DEBUG_NO_STATIC intipsec_mast_open(struct net_device *dev){	struct ipsecpriv *prv = dev->priv;		/*	 * Can't open until attached.	 */	KLIPS_PRINT(debug_mast & DB_MAST_INIT,		    "klips_debug:ipsec_mast_open: "		    "dev = %s, prv->dev = %s\n",		    dev->name, prv->dev?prv->dev->name:"NONE");	if (prv->dev == NULL)		return -ENODEV;		KLIPS_INC_USE;	return 0;}DEBUG_NO_STATIC intipsec_mast_close(struct net_device *dev){	KLIPS_DEC_USE;	return 0;}static inline int ipsec_mast_xmit2(struct sk_buff *skb){	return ip_send(skb);}enum ipsec_xmit_valueipsec_mast_send(struct ipsec_xmit_state*ixs){	/* new route/dst cache code from James Morris */	ixs->skb->dev = ixs->physdev;	/*skb_orphan(ixs->skb);*/	if((ixs->error = ip_route_output(&ixs->route,				    ixs->skb->nh.iph->daddr,				    ixs->pass ? 0 : ixs->skb->nh.iph->saddr,				    RT_TOS(ixs->skb->nh.iph->tos),				    ixs->physdev->iflink /* rgb: should this be 0? */))) {		ixs->stats->tx_errors++;		KLIPS_PRINT(debug_mast & DB_MAST_XMIT,			    "klips_debug:ipsec_xmit_send: "			    "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",			    ixs->error,			    ixs->route->u.dst.dev->name);		return IPSEC_XMIT_ROUTEERR;	}	if(ixs->dev == ixs->route->u.dst.dev) {		ip_rt_put(ixs->route);		/* This is recursion, drop it. */		ixs->stats->tx_errors++;		KLIPS_PRINT(debug_mast & DB_MAST_XMIT,			    "klips_debug:ipsec_xmit_send: "			    "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",			    ixs->dev->name);		return IPSEC_XMIT_RECURSDETECT;	}	dst_release(ixs->skb->dst);	ixs->skb->dst = &ixs->route->u.dst;	ixs->stats->tx_bytes += ixs->skb->len;	if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {		ixs->stats->tx_errors++;		printk(KERN_WARNING		       "klips_error:ipsec_xmit_send: "		       "tried to __skb_pull nh-data=%ld, %d available.  This should never happen, please report.\n",		       (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),		       ixs->skb->len);		return IPSEC_XMIT_PUSHPULLERR;	}	__skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);#ifdef SKB_RESET_NFCT	nf_conntrack_put(ixs->skb->nfct);	ixs->skb->nfct = NULL;#ifdef CONFIG_NETFILTER_DEBUG	ixs->skb->nf_debug = 0;#endif /* CONFIG_NETFILTER_DEBUG */#endif /* SKB_RESET_NFCT */	KLIPS_PRINT(debug_mast & DB_MAST_XMIT,		    "klips_debug:ipsec_xmit_send: "		    "...done, calling ip_send() on device:%s\n",		    ixs->skb->dev ? ixs->skb->dev->name : "NULL");	KLIPS_IP_PRINT(debug_mast & DB_MAST_XMIT, ixs->skb->nh.iph);	{		int err;		err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,			      ipsec_mast_xmit2);		if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {			if(net_ratelimit())				printk(KERN_ERR				       "klips_error:ipsec_xmit_send: "				       "ip_send() failed, err=%d\n", 				       -err);			ixs->stats->tx_errors++;			ixs->stats->tx_aborted_errors++;			ixs->skb = NULL;			return IPSEC_XMIT_IPSENDFAILURE;		}	}	ixs->stats->tx_packets++;	ixs->skb = NULL;		return IPSEC_XMIT_OK;}voidipsec_mast_cleanup(struct ipsec_xmit_state*ixs){#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)	netif_wake_queue(ixs->dev);#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */	ixs->dev->tbusy = 0;#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */	if(ixs->saved_header) {		kfree(ixs->saved_header);	}	if(ixs->skb) {		dev_kfree_skb(ixs->skb, FREE_WRITE);	}	if(ixs->oskb) {		dev_kfree_skb(ixs->oskb, FREE_WRITE);	}	if (ixs->ips.ips_ident_s.data) {		kfree(ixs->ips.ips_ident_s.data);	}	if (ixs->ips.ips_ident_d.data) {		kfree(ixs->ips.ips_ident_d.data);	}}#if 0/* *	This function assumes it is being called from dev_queue_xmit() *	and that skb is filled properly by that function. */intipsec_mast_start_xmit(struct sk_buff *skb, struct net_device *dev, IPsecSAref_t SAref){	struct ipsec_xmit_state ixs_mem;	struct ipsec_xmit_state *ixs = &ixs_mem;	enum ipsec_xmit_value stat = IPSEC_XMIT_OK;	/* dev could be a mast device, but should be optional, I think... */	/* SAref is also optional, but one of the two must be present. */	/* I wonder if it could accept no device or saref and guess? *//*	ipsec_xmit_sanity_check_dev(ixs); */	ipsec_xmit_sanity_check_skb(ixs);	ipsec_xmit_adjust_hard_header(ixs);	stat = ipsec_xmit_encap_bundle(ixs);	if(stat != IPSEC_XMIT_OK) {		/* SA processing failed */	}	ipsec_xmit_hard_header_restore();}#endifDEBUG_NO_STATIC struct net_device_stats *ipsec_mast_get_stats(struct net_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_mast_hard_header(struct sk_buff *skb, struct net_device *dev,	unsigned short type, void *daddr, void *saddr, unsigned len){	struct ipsecpriv *prv = dev->priv;	struct net_device *tmp;	int ret;	struct net_device_stats *stats;	/* This device's statistics */		if(skb == NULL) {		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_hard_header: "			    "no skb...\n");		return -ENODATA;	}	if(dev == NULL) {		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_hard_header: "			    "no device...\n");		return -ENODEV;	}	KLIPS_PRINT(debug_mast & DB_MAST_REVEC,		    "klips_debug:ipsec_mast_hard_header: "		    "skb->dev=%s dev=%s.\n",		    skb->dev ? skb->dev->name : "NULL",		    dev->name);		if(prv == NULL) {		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_hard_header: "			    "no private space associated with dev=%s\n",			    dev->name ? dev->name : "NULL");		return -ENODEV;	}	stats = (struct net_device_stats *) &(prv->mystats);	if(prv->dev == NULL) {		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_hard_header: "			    "no physical device associated with dev=%s\n",			    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_mast & DB_MAST_REVEC,				    "klips_debug:ipsec_mast_hard_header: "				    "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",				    saddr,				    daddr,				    len,				    type,				    dev->name);			KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,					"ip=%08x->%08x\n",					(__u32)ntohl(skb->nh.iph->saddr),					(__u32)ntohl(skb->nh.iph->daddr) );			stats->tx_dropped++;			return -ENODEV;		}		#define da ((struct net_device *)(prv->dev))->dev_addr		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_hard_header: "			    "Revectored 0p%p->0p%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]);		KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,			    "ip=%08x->%08x\n",			    (__u32)ntohl(skb->nh.iph->saddr),			    (__u32)ntohl(skb->nh.iph->daddr) );	} else {		KLIPS_PRINT(debug_mast,			    "klips_debug:ipsec_mast_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 intipsec_mast_rebuild_header(struct sk_buff *skb){	struct ipsecpriv *prv = skb->dev->priv;	struct net_device *tmp;	int ret;	struct net_device_stats *stats;	/* This device's statistics */		if(skb->dev == NULL) {		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_rebuild_header: "			    "no device...");		return -ENODEV;	}	if(prv == NULL) {		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_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_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_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_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_rebuild_header: "			    "physical device has been detached, packet dropped skb->dev=%s->NULL ",			    skb->dev->name);		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,			    "ip=%08x->%08x\n",			    (__u32)ntohl(skb->nh.iph->saddr),			    (__u32)ntohl(skb->nh.iph->daddr) );		stats->tx_dropped++;		return -ENODEV;	}	KLIPS_PRINT(debug_mast & DB_MAST_REVEC,		    "klips_debug:ipsec_mast: "		    "Revectored rebuild_header dev=%s->%s ",		    skb->dev->name, prv->dev->name);	KLIPS_PRINT(debug_mast & DB_MAST_REVEC,		    "ip=%08x->%08x\n",		    (__u32)ntohl(skb->nh.iph->saddr),		    (__u32)ntohl(skb->nh.iph->daddr) );	tmp = skb->dev;	skb->dev = prv->dev;		ret = prv->rebuild_header(skb);	skb->dev = tmp;	return ret;}DEBUG_NO_STATIC intipsec_mast_set_mac_address(struct net_device *dev, void *addr){	struct ipsecpriv *prv = dev->priv;		struct net_device_stats *stats;	/* This device's statistics */		if(dev == NULL) {		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_set_mac_address: "			    "no device...");		return -ENODEV;	}	if(prv == NULL) {		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_set_mac_address: "			    "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_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_set_mac_address: "			    "no physical device associated with dev=%s",			    dev->name ? dev->name : "NULL");		stats->tx_dropped++;		return -ENODEV;	}	if(!prv->set_mac_address) {		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_set_mac_address: "			    "physical device has been detached, cannot set - skb->dev=%s->NULL\n",			    dev->name);		return -ENODEV;	}	KLIPS_PRINT(debug_mast & DB_MAST_REVEC,		    "klips_debug:ipsec_mast_set_mac_address: "		    "Revectored dev=%s->%s addr=0p%p\n",		    dev->name, prv->dev->name, addr);	return prv->set_mac_address(prv->dev, addr);}DEBUG_NO_STATIC voidipsec_mast_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char *  haddr){	struct ipsecpriv *prv = dev->priv;		struct net_device_stats *stats;	/* This device's statistics */		if(dev == NULL) {		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_cache_update: "			    "no device...");		return;	}	if(prv == NULL) {		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_cache_update: "			    "no private space associated with dev=%s",			    dev->name ? dev->name : "NULL");		return;	}	stats = (struct net_device_stats *) &(prv->mystats);	if(prv->dev == NULL) {		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_cache_update: "			    "no physical device associated with dev=%s",			    dev->name ? dev->name : "NULL");		stats->tx_dropped++;		return;	}	if(!prv->header_cache_update) {		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,			    "klips_debug:ipsec_mast_cache_update: "			    "physical device has been detached, cannot set - skb->dev=%s->NULL\n",			    dev->name);		return;	}	KLIPS_PRINT(debug_mast & DB_MAST_REVEC,		    "klips_debug:ipsec_mast: "		    "Revectored cache_update\n");	prv->header_cache_update(hh, prv->dev, haddr);	return;}DEBUG_NO_STATIC intipsec_mast_neigh_setup(struct neighbour *n){	KLIPS_PRINT(debug_mast & DB_MAST_REVEC,		    "klips_debug:ipsec_mast_neigh_setup:\n");        if (n->nud_state == NUD_NONE) {                n->ops = &arp_broken_ops;                n->output = n->ops->output;        }        return 0;}DEBUG_NO_STATIC intipsec_mast_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p){	KLIPS_PRINT(debug_mast & DB_MAST_REVEC,		    "klips_debug:ipsec_mast_neigh_setup_dev: "		    "setting up %s\n",		    dev ? dev->name : "NULL");        if (p->tbl->family == AF_INET) {                p->neigh_setup = ipsec_mast_neigh_setup;                p->ucast_probes = 0;                p->mcast_probes = 0;        }        return 0;}

⌨️ 快捷键说明

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