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

📄 ipsec_xform.c

📁 网上下到的一个很详细介绍VPN基础知识的资料
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Common routines for IPSEC transformations. * Copyright (C) 1996, 1997  John Ioannidis. * Copyright (C) 1998, 1999, 2000, 2001  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. * * RCSID $Id: ipsec_xform.c,v 1.52 2001/06/14 19:35:11 rgb Exp $ */#include <linux/config.h>#include <linux/version.h>#include <linux/kernel.h> /* printk() */#include <linux/malloc.h> /* kmalloc() */#include <linux/errno.h>  /* error codes */#include <linux/types.h>  /* size_t */#include <linux/interrupt.h> /* mark_bh */#include <linux/netdevice.h>   /* struct device, and other headers */#include <linux/etherdevice.h> /* eth_type_trans */#include <linux/ip.h>          /* struct iphdr */#include <linux/skbuff.h>#include <linux/random.h>	/* get_random_bytes() */#include <freeswan.h>#ifdef SPINLOCK#ifdef SPINLOCK_23#include <linux/spinlock.h> /* *lock* */#else /* SPINLOCK_23 */#include <asm/spinlock.h> /* *lock* */#endif /* SPINLOCK_23 */#endif /* SPINLOCK */#ifdef NET_21#include <asm/uaccess.h>#include <linux/in6.h>#endif#include <asm/checksum.h>#include <net/ip.h>#include "radij.h"#include "ipsec_encap.h"#include "ipsec_radij.h"#include "ipsec_netlink.h"#include "ipsec_xform.h"#include "ipsec_ipe4.h"#include "ipsec_ah.h"#include "ipsec_esp.h"#include <pfkeyv2.h>#include <pfkey.h>#ifdef CONFIG_IPSEC_DEBUGint debug_xform = 0;#endif /* CONFIG_IPSEC_DEBUG */#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)extern int des_set_key(caddr_t, caddr_t);struct xformsw xformsw[] = {{ XF_IP4,		0,		"IPv4_Encapsulation"},{ XF_AHHMACMD5,		XFT_AUTH,	"HMAC_MD5_Authentication"},{ XF_AHHMACSHA1,	XFT_AUTH,	"HMAC_SHA-1_Authentication"},{ XF_ESP3DES,		XFT_CONF,	"3DES_Encryption"},{ XF_ESP3DESMD596,	XFT_CONF,	"3DES-MD5-96_Encryption"},{ XF_ESP3DESSHA196,	XFT_CONF,	"3DES-SHA1-96_Encryption"},{ XF_ESPNULLMD596,	XFT_CONF,	"NULL-MD5-96_ESP_*Plaintext*"},{ XF_ESPNULLSHA196,	XFT_CONF,	"NULL-SHA1-96_ESP_*Plaintext*"},};struct tdb *tdbh[TDB_HASHMOD];#ifdef SPINLOCKspinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;#else /* SPINLOCK */spinlock_t tdb_lock;#endif /* SPINLOCK */struct xformsw *xformswNXFORMSW = &xformsw[sizeof(xformsw)/sizeof(xformsw[0])];intipsec_tdbinit(void){	int i;	for(i = 1; i < TDB_HASHMOD; i++) {		tdbh[i] = NULL;	}	return 0;}struct tdb *gettdb(struct sa_id *said){	int hashval;	struct tdb *tdbp;        char sa[SATOA_BUF];	size_t sa_len;	if(!said) {		KLIPS_PRINT(debug_xform,			    "klips_error:gettdb: "			    "null pointer passed in!\n");		return NULL;	}	sa_len = satoa(*said, 0, sa, SATOA_BUF);	hashval = (said->spi+said->dst.s_addr+said->proto) % TDB_HASHMOD;		KLIPS_PRINT(debug_xform,		    "klips_debug:gettdb: "		    "linked entry in tdb table for hash=%d of SA:%s requested.\n",		    hashval,		    sa_len ? sa : " (error)");	if(!(tdbp = tdbh[hashval])) {		KLIPS_PRINT(debug_xform,			    "klips_debug:gettdb: "			    "no entries in tdb table for hash=%d of SA:%s.\n",			    hashval,			    sa_len ? sa : " (error)");		return NULL;	}	for (; tdbp; tdbp = tdbp->tdb_hnext) {		if ((tdbp->tdb_said.spi == said->spi) &&		    (tdbp->tdb_said.dst.s_addr == said->dst.s_addr) &&		    (tdbp->tdb_said.proto == said->proto)) {			return tdbp;		}	}		KLIPS_PRINT(debug_xform,		    "klips_debug:gettdb: "		    "no entry in linked list for hash=%d of SA:%s.\n",		    hashval,		    sa_len ? sa : " (error)");	return NULL;}/*  The tdb table better *NOT* be locked before it is handed in, or SMP locks will happen*/intputtdb(struct tdb *tdbp){	int error = 0;	unsigned int hashval;	if(!tdbp) {		KLIPS_PRINT(debug_xform,			    "klips_error:puttdb: "			    "null pointer passed in!\n");		return -ENODATA;	}	hashval = ((tdbp->tdb_said.spi + tdbp->tdb_said.dst.s_addr + tdbp->tdb_said.proto) % TDB_HASHMOD);	spin_lock_bh(&tdb_lock);		tdbp->tdb_hnext = tdbh[hashval];	tdbh[hashval] = tdbp;		spin_unlock_bh(&tdb_lock);	return error;}/*  The tdb table better be locked before it is handed in, or races might happen*/intdeltdb(struct tdb *tdbp){	unsigned int hashval;	struct tdb *tdbtp;        char sa[SATOA_BUF];	size_t sa_len;	if(!tdbp) {		KLIPS_PRINT(debug_xform,			    "klips_error:deltdb: "			    "null pointer passed in!\n");		return -ENODATA;	}		sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);	if(tdbp->tdb_inext || tdbp->tdb_onext) {		KLIPS_PRINT(debug_xform,			    "klips_error:deltdb: "			    "SA:%s still linked!\n",			    sa_len ? sa : " (error)");		return -EMLINK;	}		hashval = ((tdbp->tdb_said.spi + tdbp->tdb_said.dst.s_addr + tdbp->tdb_said.proto) % TDB_HASHMOD);		KLIPS_PRINT(debug_xform,		    "klips_debug:deltdb: "		    "deleting SA:%s, hashval=%d.\n",		    sa_len ? sa : " (error)",		    hashval);	if(!tdbh[hashval]) {		KLIPS_PRINT(debug_xform,			    "klips_debug:deltdb: "			    "no entries in tdb table for hash=%d of SA:%s.\n",			    hashval,			    sa_len ? sa : " (error)");		return -ENOENT;	}		if (tdbp == tdbh[hashval]) {		tdbh[hashval] = tdbh[hashval]->tdb_hnext;		tdbp->tdb_hnext = NULL;		KLIPS_PRINT(debug_xform,			    "klips_debug:deltdb: "			    "successfully deleted first tdb in chain.\n");		return 0;	} else {		for (tdbtp = tdbh[hashval]; tdbtp; tdbtp = tdbtp->tdb_hnext) {			if (tdbtp->tdb_hnext == tdbp) {				tdbtp->tdb_hnext = tdbp->tdb_hnext;				tdbp->tdb_hnext = NULL;				KLIPS_PRINT(debug_xform,					    "klips_debug:deltdb: "					    "successfully deleted link in tdb chain.\n");				return 0;			}		}	}		KLIPS_PRINT(debug_xform,		    "klips_debug:deltdb: "		    "no entries in linked list for hash=%d of SA:%s.\n",		    hashval,		    sa_len ? sa : " (error)");	return -ENOENT;}/*  The tdb table better be locked before it is handed in, or races might happen*/intdeltdbchain(struct tdb *tdbp){	struct tdb *tdbdel;	int error = 0;        char sa[SATOA_BUF];	size_t sa_len;	if(!tdbp) {		KLIPS_PRINT(debug_xform,			    "klips_error:deltdbchain: "			    "null pointer passed in!\n");		return -ENODATA;	}	sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);	KLIPS_PRINT(debug_xform,		    "klips_debug:deltdbchain: "		    "passed SA:%s\n",		    sa_len ? sa : " (error)");	while(tdbp->tdb_onext) {		tdbp = tdbp->tdb_onext;	}	while(tdbp) {		/* XXX send a pfkey message up to advise of deleted TDB */		sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);		KLIPS_PRINT(debug_xform,			    "klips_debug:deltdbchain: "			    "unlinking and delting SA:%s",			    sa_len ? sa : " (error)");		tdbdel = tdbp;		tdbp = tdbp->tdb_inext;		if(tdbp) {			sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);			KLIPS_PRINT(debug_xform,				    ", inext=%s",				    sa_len ? sa : " (error)");			tdbdel->tdb_inext = NULL;			tdbp->tdb_onext = NULL;		}		KLIPS_PRINT(debug_xform,			    ".\n");		if((error = deltdb(tdbdel))) {			KLIPS_PRINT(debug_xform,				    "klips_debug:deltdbchain: "				    "deltdb returned error %d.\n", -error);			return error;		}		if((error = ipsec_tdbwipe(tdbdel))) {			KLIPS_PRINT(debug_xform,				    "klips_debug:deltdbchain: "				    "ipsec_tdbwipe returned error %d.\n", -error);			return error;		}	}	return error;}#if 0inttdb_init(struct tdb *tdbp, struct encap_msghdr *em){	int alg;	struct xformsw *xsp;	int error = 0;        int i;#if defined(CONFIG_IPSEC_ENC_3DES)        int error;#endif /* CONFIG_IPSEC_ENC_3DES */        char sa[SATOA_BUF];        size_t sa_len;	if(!tdbp || !em) {		KLIPS_PRINT(debug_xform,			    "klips_error:tdb_init: "			    "null pointer passed in!\n");		SENDERR(ENODATA);	}	sa_len = satoa(em->em_said, 0, sa, SATOA_BUF);        KLIPS_PRINT(debug_esp,		    "klips_debug:tdb_init: "		    "(algo_switch defined) called for SA:%s\n",		    sa_len ? sa : " (error)");	alg = em->em_alg;		for (xsp = xformsw; xsp < xformswNXFORMSW; xsp++) {		if (xsp->xf_type == alg) {			KLIPS_PRINT(debug_netlink,				    "klips_debug:tdb_init: "				    "called with tdbp=0x%p, xsp=0x%p, em=0x%p\n",				    tdbp, xsp, em);			KLIPS_PRINT(debug_netlink,				    "klips_debug:tdb_init: "				    "calling init routine of %s\n",				    xsp->xf_name);			tdbp->tdb_xform = xsp;			tdbp->tdb_replaywin_lastseq = 0;			tdbp->tdb_replaywin_bitmap = 0;			/* check size of message here XXX */			switch(alg) {#ifdef CONFIG_IPSEC_IPIP			case XF_IP4: {				struct ipe4_xdata *xd;				xd = (struct ipe4_xdata *)(em->em_dat);				tdbp->tdb_authalg = AH_NONE;				tdbp->tdb_encalg = ESP_NONE;				 				if((tdbp->tdb_addr_s = (struct sockaddr*)				   kmalloc((tdbp->tdb_addr_s_size = sizeof(struct sockaddr_in)),					   GFP_ATOMIC)) == NULL) {					SENDERR(ENOMEM);				}				if((tdbp->tdb_addr_d = (struct sockaddr*)				   kmalloc((tdbp->tdb_addr_d_size = sizeof(struct sockaddr_in)),					   GFP_ATOMIC)) == NULL) {					SENDERR(ENOMEM);				}								/* might want to use a different structure here, or set sin_family and sin_port */				((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr = xd->i4_src;				((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr = xd->i4_dst;			}				break;#endif /* !CONFIG_IPSEC_IPIP */#ifdef CONFIG_IPSEC_AH# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5			case XF_AHHMACMD5: {				struct ahhmacmd5_edata *ed;				unsigned char kb[AHMD596_BLKLEN];				MD5_CTX *ictx;				MD5_CTX *octx;				ed = (struct ahhmacmd5_edata *)em->em_dat;				tdbp->tdb_authalg = AH_MD5;				tdbp->tdb_encalg = ESP_NONE;								if (em->em_msglen - EMT_SETSPI_FLEN > sizeof (struct ahhmacmd5_edata))					SENDERR(EINVAL);								if (ed->ame_klen != AHMD596_KLEN) {					KLIPS_PRINT(debug_ah,						    "klips_debug:tdb_init: "						    "incorrect key size: %d -- must be %d octets (bytes)\n",						    ed->ame_klen, AHMD596_KLEN);					SENDERR(EINVAL);				}								if (ed->ame_alen != AHMD596_ALEN) {					KLIPS_PRINT(debug_ah,						    "klips_debug:tdb_init: "						    "authenticator size: %d -- must be %d octets (bytes)\n",						    ed->ame_alen, AHMD596_ALEN);					SENDERR(EINVAL);				}								KLIPS_PRINT(debug_ah,					    "klips_debug:tdb_init: "					    "hmac md5-96 key is 0x%08x %08x %08x %08x\n",					    (__u32)ntohl(*(((__u32 *)ed->ame_key)+0)),					    (__u32)ntohl(*(((__u32 *)ed->ame_key)+1)),

⌨️ 快捷键说明

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