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

📄 pfkey_v2_parse.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * RFC2367 PF_KEYv2 Key management API message parser * Copyright (C) 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: pfkey_v2_parse.c,v 1.63 2004/10/28 22:54:10 mcr Exp $ *//* *		Template from klips/net/ipsec/ipsec/ipsec_parser.c. */char pfkey_v2_parse_c_version[] = "$Id: pfkey_v2_parse.c,v 1.63 2004/10/28 22:54:10 mcr Exp $";/* * Some ugly stuff to allow consistent debugging code for use in the * kernel and in user space*/#ifdef __KERNEL__# include <linux/kernel.h>  /* for printk */#include "openswan/ipsec_kversion.h" /* for malloc switch */# 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, and other headers */# include <linux/etherdevice.h> /* eth_type_trans */# include <linux/ip.h>          /* struct iphdr */ # if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)#  include <linux/ipv6.h>        /* struct ipv6hdr */# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */extern int debug_pfkey;# include <openswan.h>#include "openswan/ipsec_encap.h"#else /* __KERNEL__ */# include <sys/types.h># include <linux/types.h># include <linux/errno.h># include <openswan.h># include "constants.h" # include "programs/pluto/defs.h"  /* for PRINTF_LIKE */#endif /* __KERNEL__ */#include <pfkeyv2.h>#include <pfkey.h>#include "openswan/ipsec_sa.h"  /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH *//*  * how to handle debugging for pfkey. */#include <openswan/pfkey_debug.h>unsigned int pfkey_lib_debug = PF_KEY_DEBUG_PARSE_NONE;void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)struct satype_tbl {	uint8_t proto;	uint8_t satype;	char* name;} static satype_tbl[] = {#ifdef __KERNEL__	{ IPPROTO_ESP,	SADB_SATYPE_ESP,	"ESP"  },	{ IPPROTO_AH,	SADB_SATYPE_AH,		"AH"   },	{ IPPROTO_IPIP,	SADB_X_SATYPE_IPIP,	"IPIP" },#ifdef CONFIG_KLIPS_IPCOMP	{ IPPROTO_COMP,	SADB_X_SATYPE_COMP,	"COMP" },#endif /* CONFIG_KLIPS_IPCOMP */	{ IPPROTO_INT,	SADB_X_SATYPE_INT,	"INT" },#else /* __KERNEL__ */	{ SA_ESP,	SADB_SATYPE_ESP,	"ESP"  },	{ SA_AH,	SADB_SATYPE_AH,		"AH"   },	{ SA_IPIP,	SADB_X_SATYPE_IPIP,	"IPIP" },	{ SA_COMP,	SADB_X_SATYPE_COMP,	"COMP" },	{ SA_INT,	SADB_X_SATYPE_INT,	"INT" },#endif /* __KERNEL__ */	{ 0,		0,			"UNKNOWN" }};uint8_tsatype2proto(uint8_t satype){	int i =0;	while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {		i++;	}	return satype_tbl[i].proto;}uint8_tproto2satype(uint8_t proto){	int i = 0;	while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {		i++;	}	return satype_tbl[i].satype;}char*satype2name(uint8_t satype){	int i = 0;	while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {		i++;	}	return satype_tbl[i].name;}char*proto2name(uint8_t proto){	int i = 0;	while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {		i++;	}	return satype_tbl[i].name;}/* Default extension parsers taken from the KLIPS code */DEBUG_NO_STATIC intpfkey_sa_parse(struct sadb_ext *pfkey_ext){	int error = 0;	struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;#if 0	struct sadb_sa sav2;#endif		/* sanity checks... */	if(!pfkey_sa) {		ERROR("pfkey_sa_parse: "			  "NULL pointer passed in.\n");		SENDERR(EINVAL);	}	#if 0	/* check if this structure is short, and if so, fix it up.	 * XXX this is NOT the way to do things.	 */	if(pfkey_sa->sadb_sa_len == sizeof(struct sadb_sa_v1)/IPSEC_PFKEYv2_ALIGN) {		/* yes, so clear out a temporary structure, and copy first */		memset(&sav2, 0, sizeof(sav2));		memcpy(&sav2, pfkey_sa, sizeof(struct sadb_sa_v1));		sav2.sadb_x_sa_ref=-1;		sav2.sadb_sa_len = sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN;				pfkey_sa = &sav2;	}#endif	if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) {		ERROR(			  "pfkey_sa_parse: "			  "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n",			  pfkey_sa->sadb_sa_len,			  (int)sizeof(struct sadb_sa));		SENDERR(EINVAL);	}#if SADB_EALG_MAX < 255		if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) {		ERROR(			  "pfkey_sa_parse: "			  "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n",			  pfkey_sa->sadb_sa_encrypt,			  SADB_EALG_MAX);		SENDERR(EINVAL);	}#endif	#if SADB_AALG_MAX < 255		if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) {		ERROR(			  "pfkey_sa_parse: "			  "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n",			  pfkey_sa->sadb_sa_auth,			  SADB_AALG_MAX);		SENDERR(EINVAL);	}#endif	#if SADB_SASTATE_MAX < 255		if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) {		ERROR(			  "pfkey_sa_parse: "			  "state=%d exceeds MAX=%d.\n",			  pfkey_sa->sadb_sa_state,			  SADB_SASTATE_MAX);		SENDERR(EINVAL);	}#endif		if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) {		ERROR(			  "pfkey_sa_parse: "			  "state=%d is DEAD=%d.\n",			  pfkey_sa->sadb_sa_state,			  SADB_SASTATE_DEAD);		SENDERR(EINVAL);	}		if(pfkey_sa->sadb_sa_replay > 64) {		ERROR(			  "pfkey_sa_parse: "			  "replay window size: %d -- must be 0 <= size <= 64\n",			  pfkey_sa->sadb_sa_replay);		SENDERR(EINVAL);	}		if(! ((pfkey_sa->sadb_sa_exttype ==  SADB_EXT_SA) ||	      (pfkey_sa->sadb_sa_exttype ==  SADB_X_EXT_SA2)))	{		ERROR(			  "pfkey_sa_parse: "			  "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n",			  pfkey_sa->sadb_sa_exttype,			  SADB_EXT_SA,			  SADB_X_EXT_SA2);		SENDERR(EINVAL);	}	if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref) && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {		ERROR(			  "pfkey_sa_parse: "			  "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",			  pfkey_sa->sadb_x_sa_ref,			  IPSEC_SAREF_NULL,			  IPSEC_SA_REF_TABLE_NUM_ENTRIES);		SENDERR(EINVAL);	}		DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,		  "pfkey_sa_parse: "		  "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n",		  pfkey_sa->sadb_sa_len,		  pfkey_sa->sadb_sa_exttype,		  pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype),		  (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi),		  pfkey_sa->sadb_sa_replay,		  pfkey_sa->sadb_sa_state,		  pfkey_sa->sadb_sa_auth,		  pfkey_sa->sadb_sa_encrypt,		  pfkey_sa->sadb_sa_flags,		  pfkey_sa->sadb_x_sa_ref);	 errlab:	return error;}	DEBUG_NO_STATIC intpfkey_lifetime_parse(struct sadb_ext  *pfkey_ext){	int error = 0;	struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;	DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,		  "pfkey_lifetime_parse:enter\n");	/* sanity checks... */	if(!pfkey_lifetime) {		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,			  "pfkey_lifetime_parse: "			  "NULL pointer passed in.\n");		SENDERR(EINVAL);	}	if(pfkey_lifetime->sadb_lifetime_len !=	   sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) {		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,			  "pfkey_lifetime_parse: "			  "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n",			  pfkey_lifetime->sadb_lifetime_len,			  (int)sizeof(struct sadb_lifetime));		SENDERR(EINVAL);	}	if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) &&	   (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) &&	   (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) {		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,			  "pfkey_lifetime_parse: "			  "unexpected ext_type=%d.\n", 			  pfkey_lifetime->sadb_lifetime_exttype); 		SENDERR(EINVAL);	}	DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,		  "pfkey_lifetime_parse: "		  "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u pkts=%u.\n", 		  pfkey_lifetime->sadb_lifetime_exttype,		  pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype),		  pfkey_lifetime->sadb_lifetime_allocations,		  (unsigned)pfkey_lifetime->sadb_lifetime_bytes,		  (unsigned)pfkey_lifetime->sadb_lifetime_addtime,		  (unsigned)pfkey_lifetime->sadb_lifetime_usetime,		  pfkey_lifetime->sadb_x_lifetime_packets); errlab:	return error;}DEBUG_NO_STATIC intpfkey_address_parse(struct sadb_ext *pfkey_ext){	int error = 0;	int saddr_len = 0;	struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;	struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));	char ipaddr_txt[ADDRTOT_BUF];		/* sanity checks... */	if(!pfkey_address) {		ERROR(			"pfkey_address_parse: "			"NULL pointer passed in.\n");		SENDERR(EINVAL);	}		if(pfkey_address->sadb_address_len <	   (sizeof(struct sadb_address) + sizeof(struct sockaddr))/	   IPSEC_PFKEYv2_ALIGN) {		ERROR("pfkey_address_parse: "			  "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",			  pfkey_address->sadb_address_len,			  (int)sizeof(struct sadb_address),			  (int)sizeof(struct sockaddr));		SENDERR(EINVAL);	}		if(pfkey_address->sadb_address_reserved) {		ERROR("pfkey_address_parse: "			  "res=%d, must be zero.\n",			  pfkey_address->sadb_address_reserved);		SENDERR(EINVAL);	}		switch(pfkey_address->sadb_address_exttype) {		case SADB_EXT_ADDRESS_SRC:	case SADB_EXT_ADDRESS_DST:	case SADB_EXT_ADDRESS_PROXY:	case SADB_X_EXT_ADDRESS_DST2:	case SADB_X_EXT_ADDRESS_SRC_FLOW:	case SADB_X_EXT_ADDRESS_DST_FLOW:	case SADB_X_EXT_ADDRESS_SRC_MASK:	case SADB_X_EXT_ADDRESS_DST_MASK:#ifdef NAT_TRAVERSAL	case SADB_X_EXT_NAT_T_OA:#endif		break;	default:		ERROR(			"pfkey_address_parse: "			"unexpected ext_type=%d.\n",			pfkey_address->sadb_address_exttype);		SENDERR(EINVAL);	}	switch(s->sa_family) {	case AF_INET:		saddr_len = sizeof(struct sockaddr_in);		sprintf(ipaddr_txt, "%d.%d.%d.%d"			, (((struct sockaddr_in*)s)->sin_addr.s_addr >>  0) & 0xFF			, (((struct sockaddr_in*)s)->sin_addr.s_addr >>  8) & 0xFF			, (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF			, (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF);		DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,			  "pfkey_address_parse: "			  "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n",			  pfkey_address->sadb_address_exttype,			  pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),			  s->sa_family,			  ipaddr_txt,			  pfkey_address->sadb_address_proto,			  ntohs(((struct sockaddr_in*)s)->sin_port));		break;	case AF_INET6:		saddr_len = sizeof(struct sockaddr_in6);		sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x"			, ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0])			, ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1])			, ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2])			, ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3])			, ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4])			, ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5])			, ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6])			, ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7]));		DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,			  "pfkey_address_parse: "			  "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n",			  pfkey_address->sadb_address_exttype,			  pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),			  s->sa_family,			  ipaddr_txt,			  pfkey_address->sadb_address_proto,			  ((struct sockaddr_in6*)s)->sin6_port);		break;	default:		ERROR(			"pfkey_address_parse: "			"s->sa_family=%d not supported.\n",			s->sa_family);		SENDERR(EPFNOSUPPORT);	}		if(pfkey_address->sadb_address_len !=	   DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) {		ERROR(			  "pfkey_address_parse: "			  "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",			  pfkey_address->sadb_address_len,			  (int)sizeof(struct sadb_address),			  saddr_len);		SENDERR(EINVAL);	}		if(pfkey_address->sadb_address_prefixlen != 0) {		ERROR(			"pfkey_address_parse: "			"address prefixes not supported yet.\n");		SENDERR(EAFNOSUPPORT); /* not supported yet */	}		/* XXX check if port!=0 */		DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,

⌨️ 快捷键说明

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