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

📄 pfkey_v2_parser.c

📁 openswan
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * @(#) RFC2367 PF_KEYv2 Key management API message parser * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs <rgb@freeswan.org> *  * 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_parser.c,v 1.134.2.1 2006/05/01 14:37:25 mcr Exp $ *//* *		Template from klips/net/ipsec/ipsec/ipsec_netlink.c. */char pfkey_v2_parser_c_version[] = "$Id: pfkey_v2_parser.c,v 1.134.2.1 2006/05/01 14:37:25 mcr Exp $";#include <linux/config.h>#include <linux/version.h>#include <linux/kernel.h> /* printk() */#include "openswan/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, and other headers */#include <linux/etherdevice.h> /* eth_type_trans */#include <linux/ip.h>          /* struct iphdr */#include <linux/skbuff.h>#include <openswan.h>#include <crypto/des.h>#ifdef SPINLOCK# ifdef SPINLOCK_23#  include <linux/spinlock.h> /* *lock* */# else /* SPINLOCK_23 */#  include <asm/spinlock.h> /* *lock* */# endif /* SPINLOCK_23 */#endif /* SPINLOCK */#include <linux/in6.h>#include <net/route.h>#include <net/ip.h>#ifdef NETLINK_SOCK# include <linux/netlink.h>#else# include <net/netlink.h>#endif#include <linux/random.h>	/* get_random_bytes() */#include "openswan/radij.h"#include "openswan/ipsec_encap.h"#include "openswan/ipsec_sa.h"#include "openswan/ipsec_radij.h"#include "openswan/ipsec_xform.h"#include "openswan/ipsec_ah.h"#include "openswan/ipsec_esp.h"#include "openswan/ipsec_tunnel.h"#include "openswan/ipsec_rcv.h"#include "openswan/ipcomp.h"#include <pfkeyv2.h>#include <pfkey.h>#include "openswan/ipsec_proto.h"#include "openswan/ipsec_alg.h"#include "openswan/ipsec_kern24.h"#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)struct sklist_t {	struct socket *sk;	struct sklist_t* next;} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev;__u32 pfkey_msg_seq = 0;#if 0#define DUMP_SAID dump_said(&extr->ips->ips_said, __LINE__)#define DUMP_SAID2 dump_said(&extr.ips->ips_said, __LINE__)static void dump_said(ip_said *s, int line){ 	char msa[SATOT_BUF];	size_t msa_len;		msa_len = satot(s, 0, msa, sizeof(msa));		printk("line: %d msa: %s\n", line, msa);}#endifintpfkey_alloc_eroute(struct eroute** eroute){	int error = 0;	if(*eroute) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_alloc_eroute: "			    "eroute struct already allocated\n");		SENDERR(EEXIST);	}	if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_alloc_eroute: "			    "memory allocation error\n");		SENDERR(ENOMEM);	}	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_alloc_eroute: "		    "allocating %lu bytes for an eroute at 0p%p\n",		    (unsigned long) sizeof(**eroute), *eroute);	memset((caddr_t)*eroute, 0, sizeof(**eroute));	(*eroute)->er_eaddr.sen_len =		(*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap);	(*eroute)->er_eaddr.sen_family =		(*eroute)->er_emask.sen_family = AF_ENCAP;	(*eroute)->er_eaddr.sen_type = SENT_IP4;	(*eroute)->er_emask.sen_type = 255;	(*eroute)->er_pid = 0;	(*eroute)->er_count = 0;	(*eroute)->er_lasttime = jiffies/HZ; errlab:	return(error);}DEBUG_NO_STATIC intpfkey_x_protocol_process(struct sadb_ext *pfkey_ext,			 struct pfkey_extracted_data *extr){	int error = 0;	struct sadb_protocol * p = (struct sadb_protocol *)pfkey_ext;	KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_protocol_process: %p\n", extr);	if (extr == 0) {		KLIPS_PRINT(debug_pfkey,                         "klips_debug:pfkey_x_protocol_process:"			    "extr is NULL, fatal\n");		SENDERR(EINVAL);	}	if (extr->eroute == 0) {		KLIPS_PRINT(debug_pfkey,                        "klips_debug:pfkey_x_protocol_process:"			    "extr->eroute is NULL, fatal\n");		SENDERR(EINVAL);	}	extr->eroute->er_eaddr.sen_proto = p->sadb_protocol_proto;	extr->eroute->er_emask.sen_proto = p->sadb_protocol_proto ? ~0:0;	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_x_protocol_process: protocol = %d.\n",		    p->sadb_protocol_proto); errlab:	return error;}DEBUG_NO_STATIC intpfkey_ipsec_sa_init(struct ipsec_sa *ipsp){	return ipsec_sa_init(ipsp);}intpfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1]){	KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: "		    "error=%d\n",		    error);	if (!error) {		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"			    "success.\n");		return 1;	} else {		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"			    "caught error %d\n",			    error);		pfkey_extensions_free(extensions);		return 0;	}}DEBUG_NO_STATIC intpfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr){	int error = 0;	ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L);	int found_avail = 0;	struct ipsec_sa *ipsq;	char sa[SATOT_BUF];	size_t sa_len;	struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];	struct sadb_msg *pfkey_reply = NULL;	struct socket_list *pfkey_socketsp;	uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_getspi_parse: .\n");	pfkey_extensions_init(extensions_reply);	if(extr == NULL || extr->ips == NULL) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_getspi_parse: "			    "error, extr or extr->ipsec_sa pointer NULL\n");		SENDERR(EINVAL);	}	if(extensions[SADB_EXT_SPIRANGE]) {		minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min;		maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max;	}	if(maxspi == minspi) {		extr->ips->ips_said.spi = maxspi;		ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));		if(ipsq != NULL) {			sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));			ipsec_sa_put(ipsq);			KLIPS_PRINT(debug_pfkey,				    "klips_debug:pfkey_getspi_parse: "				    "EMT_GETSPI found an old ipsec_sa for SA: %s, delete it first.\n",				    sa_len ? sa : " (error)");			SENDERR(EEXIST);		} else {			found_avail = 1;		}	} else {		int i = 0;		__u32 rand_val;		__u32 spi_diff;		while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) {			prng_bytes(&ipsec_prng, (char *) &(rand_val),					 ( (spi_diff < (2^8))  ? 1 :					   ( (spi_diff < (2^16)) ? 2 :					     ( (spi_diff < (2^24)) ? 3 :					   4 ) ) ) );			extr->ips->ips_said.spi = htonl(ntohl(minspi) +					      (rand_val %					      (spi_diff + 1)));			i++;			ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));			if(ipsq == NULL) {				found_avail = 1;			} else {				ipsec_sa_put(ipsq);			}		}	}	sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));	if (!found_avail) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_getspi_parse: "			    "found an old ipsec_sa for SA: %s, delete it first.\n",			    sa_len ? sa : " (error)");		SENDERR(EEXIST);	}	if(inet_addr_type((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == RTN_LOCAL) {		extr->ips->ips_flags |= EMT_INBOUND;	}		KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_getspi_parse: "		    "existing ipsec_sa not found (this is good) for SA: %s, %s-bound, allocating.\n",		    sa_len ? sa : " (error)",		    extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");		/* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/	extr->ips->ips_rcvif = NULL;	extr->ips->ips_life.ipl_addtime.ipl_count = jiffies/HZ;	extr->ips->ips_state = SADB_SASTATE_LARVAL;	if(!extr->ips->ips_life.ipl_allocations.ipl_count) {		extr->ips->ips_life.ipl_allocations.ipl_count += 1;	}	if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],							  SADB_GETSPI,							  satype,							  0,							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),			      extensions_reply)	     && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],							SADB_EXT_SA,							extr->ips->ips_said.spi,							0,							SADB_SASTATE_LARVAL,							0,							0,							0,							extr->ips->ips_ref),				 extensions_reply)	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],						     SADB_EXT_ADDRESS_SRC,						     0, /*extr->ips->ips_said.proto,*/						     0,						     extr->ips->ips_addr_s),				 extensions_reply)	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],						     SADB_EXT_ADDRESS_DST,						     0, /*extr->ips->ips_said.proto,*/						     0,						     extr->ips->ips_addr_d),				 extensions_reply) )) {		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "			    "failed to build the getspi reply message extensions\n");		goto errlab;	}		if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "			    "failed to build the getspi reply message\n");		SENDERR(-error);	}	for(pfkey_socketsp = pfkey_open_sockets;	    pfkey_socketsp;	    pfkey_socketsp = pfkey_socketsp->next) {		if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {			KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "				    "sending up getspi reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",				    satype,				    satype2name(satype),				    pfkey_socketsp->socketp,				    error);			SENDERR(-error);		}		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "			    "sending up getspi reply message for satype=%d(%s) to socket=0p%p succeeded.\n",			    satype,			    satype2name(satype),			    pfkey_socketsp->socketp);	}		if((error = ipsec_sa_add(extr->ips))) {		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "			    "failed to add the larval SA=%s with error=%d.\n",			    sa_len ? sa : " (error)",			    error);		SENDERR(-error);	}	extr->ips = NULL;		KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_getspi_parse: "		    "successful for SA: %s\n",		    sa_len ? sa : " (error)");	 errlab:	if (pfkey_reply) {		pfkey_msg_free(&pfkey_reply);	}	pfkey_extensions_free(extensions_reply);	return error;}DEBUG_NO_STATIC intpfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr){	int error = 0;	struct ipsec_sa* ipsq;	char sa[SATOT_BUF];	size_t sa_len;	struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];	struct sadb_msg *pfkey_reply = NULL;	struct socket_list *pfkey_socketsp;	uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;

⌨️ 快捷键说明

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