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

📄 pfkey_v2.c

📁 openswan
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F * 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.c,v 1.97.2.8 2006/07/10 15:56:11 paul Exp $ *//* *		Template from /usr/src/linux-2.0.36/net/unix/af_unix.c. *		Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c. */#define __NO_VERSION__#include <linux/module.h>#include <linux/version.h>#include <linux/config.h>#include <linux/kernel.h>#include "openswan/ipsec_param.h"#include <linux/major.h>#include <linux/signal.h>#include <linux/sched.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/stat.h>#include <linux/socket.h>#include <linux/un.h>#include <linux/fcntl.h>#include <linux/termios.h>#include <linux/socket.h>#include <linux/sockios.h>#include <linux/net.h> /* struct socket */#include <linux/in.h>#include <linux/fs.h>#ifdef MALLOC_SLAB# include <linux/slab.h> /* kmalloc() */#else /* MALLOC_SLAB */# include <linux/malloc.h> /* kmalloc() */#endif /* MALLOC_SLAB */#include <asm/segment.h>#include <linux/skbuff.h>#include <linux/netdevice.h>#include <net/sock.h> /* struct sock */#include <net/protocol.h>/* #include <net/tcp.h> */#include <net/af_unix.h>#ifdef CONFIG_PROC_FS# include <linux/proc_fs.h>#endif /* CONFIG_PROC_FS */#include <linux/types.h> #include <openswan.h>#include "openswan/radij.h"#include "openswan/ipsec_encap.h"#include "openswan/ipsec_sa.h"#include <pfkeyv2.h>#include <pfkey.h>#include "openswan/ipsec_proto.h"#include "openswan/ipsec_kern24.h"#ifdef CONFIG_KLIPS_DEBUGint debug_pfkey = 0;extern int sysctl_ipsec_debug_verbose;#endif /* CONFIG_KLIPS_DEBUG */#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)#ifndef SOCKOPS_WRAPPED#define SOCKOPS_WRAPPED(name) name#endif /* SOCKOPS_WRAPPED */#ifdef NET_26static rwlock_t pfkey_sock_lock = RW_LOCK_UNLOCKED;HLIST_HEAD(pfkey_sock_list);static DECLARE_WAIT_QUEUE_HEAD(pfkey_sock_wait);static atomic_t pfkey_sock_users = ATOMIC_INIT(0);#elsestruct sock *pfkey_sock_list = NULL;#endifstruct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];struct socket_list *pfkey_open_sockets = NULL;struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **);DEBUG_NO_STATIC int pfkey_create(struct socket *sock, int protocol);DEBUG_NO_STATIC int pfkey_shutdown(struct socket *sock, int mode);DEBUG_NO_STATIC int pfkey_release(struct socket *sock);#ifdef NET_26DEBUG_NO_STATIC int pfkey_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len);DEBUG_NO_STATIC int pfkey_recvmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg				  , size_t size, int flags);#elseDEBUG_NO_STATIC int pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm);DEBUG_NO_STATIC int pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm);#endifstruct net_proto_family pfkey_family_ops = {	PF_KEY,	pfkey_create};struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = {#ifdef NETDEV_23	family:		PF_KEY,	release:	pfkey_release,	bind:		sock_no_bind,	connect:	sock_no_connect,	socketpair:	sock_no_socketpair,	accept:		sock_no_accept,	getname:	sock_no_getname,	poll:		datagram_poll,	ioctl:		sock_no_ioctl,	listen:		sock_no_listen,	shutdown:	pfkey_shutdown,	setsockopt:	sock_no_setsockopt,	getsockopt:	sock_no_getsockopt,	sendmsg:	pfkey_sendmsg,	recvmsg:	pfkey_recvmsg,	mmap:		sock_no_mmap,#else /* NETDEV_23 */	PF_KEY,	sock_no_dup,	pfkey_release,	sock_no_bind,	sock_no_connect,	sock_no_socketpair,	sock_no_accept,	sock_no_getname,	datagram_poll,	sock_no_ioctl,	sock_no_listen,	pfkey_shutdown,	sock_no_setsockopt,	sock_no_getsockopt,	sock_no_fcntl,	pfkey_sendmsg,	pfkey_recvmsg#endif /* NETDEV_23 */};#ifdef NETDEV_23#include <linux/smp_lock.h>SOCKOPS_WRAP(pfkey, PF_KEY);#endif  /* NETDEV_23 */#ifdef NET_26static void pfkey_sock_list_grab(void){	write_lock_bh(&pfkey_sock_lock);	if (atomic_read(&pfkey_sock_users)) {		DECLARE_WAITQUEUE(wait, current);		add_wait_queue_exclusive(&pfkey_sock_wait, &wait);		for(;;) {			set_current_state(TASK_UNINTERRUPTIBLE);			if (atomic_read(&pfkey_sock_users) == 0)				break;			write_unlock_bh(&pfkey_sock_lock);			schedule();			write_lock_bh(&pfkey_sock_lock);		}		__set_current_state(TASK_RUNNING);		remove_wait_queue(&pfkey_sock_wait, &wait);	}}static __inline__ void pfkey_sock_list_ungrab(void){	write_unlock_bh(&pfkey_sock_lock);	wake_up(&pfkey_sock_wait);}static __inline__ void pfkey_lock_sock_list(void){	/* read_lock() synchronizes us to pfkey_table_grab */	read_lock(&pfkey_sock_lock);	atomic_inc(&pfkey_sock_users);	read_unlock(&pfkey_sock_lock);}static __inline__ void pfkey_unlock_sock_list(void){	if (atomic_dec_and_test(&pfkey_sock_users))		wake_up(&pfkey_sock_wait);}#endifintpfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets){	struct socket_list *socket_listp,*prev;	if(!socketp) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_list_remove_socket: "			    "NULL socketp handed in, failed.\n");		return -EINVAL;	}	if(!sockets) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_list_remove_socket: "			    "NULL sockets list handed in, failed.\n");		return -EINVAL;	}	socket_listp = *sockets;	prev = NULL;		KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_list_remove_socket: "		    "removing sock=0p%p\n",		    socketp);		while(socket_listp != NULL) {		if(socket_listp->socketp == socketp) {			if(prev != NULL) {				prev->next = socket_listp->next;			} else {				*sockets = socket_listp->next;			}						kfree((void*)socket_listp);						break;		}		prev = socket_listp;		socket_listp = socket_listp->next;	}	return 0;}intpfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets){	struct socket_list *socket_listp;	if(!socketp) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_list_insert_socket: "			    "NULL socketp handed in, failed.\n");		return -EINVAL;	}	if(!sockets) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_list_insert_socket: "			    "NULL sockets list handed in, failed.\n");		return -EINVAL;	}	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_list_insert_socket: "		    "allocating %lu bytes for socketp=0p%p\n",		    (unsigned long) sizeof(struct socket_list),		    socketp);		if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_list_insert_socket: "			    "memory allocation error.\n");		return -ENOMEM;	}		socket_listp->socketp = socketp;	socket_listp->next = *sockets;	*sockets = socket_listp;	return 0;}  intpfkey_list_remove_supported(struct ipsec_alg_supported *supported, struct supported_list **supported_list){	struct supported_list *supported_listp = *supported_list, *prev = NULL;		if(!supported) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_list_remove_supported: "			    "NULL supported handed in, failed.\n");		return -EINVAL;	}	if(!supported_list) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_list_remove_supported: "			    "NULL supported_list handed in, failed.\n");		return -EINVAL;	}	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_list_remove_supported: "		    "removing supported=0p%p\n",		    supported);		while(supported_listp != NULL) {		if(supported_listp->supportedp == supported) {			if(prev != NULL) {				prev->next = supported_listp->next;			} else {				*supported_list = supported_listp->next;			}						kfree((void*)supported_listp);						break;		}		prev = supported_listp;		supported_listp = supported_listp->next;	}	return 0;}intpfkey_list_insert_supported(struct ipsec_alg_supported *supported			    , struct supported_list **supported_list){	struct supported_list *supported_listp;	if(!supported) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_list_insert_supported: "			    "NULL supported handed in, failed.\n");		return -EINVAL;	}	if(!supported_list) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_list_insert_supported: "			    "NULL supported_list handed in, failed.\n");		return -EINVAL;	}	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_list_insert_supported: "		    "allocating %lu bytes for incoming, supported=0p%p, supported_list=0p%p\n",		    (unsigned long) sizeof(struct supported_list),		    supported,		    supported_list);		supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL);	if(supported_listp == NULL)	{		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_list_insert_supported: "			    "memory allocation error.\n");		return -ENOMEM;	}		supported_listp->supportedp = supported;	supported_listp->next = *supported_list;	*supported_list = supported_listp;	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_list_insert_supported: "		    "outgoing, supported=0p%p, supported_list=0p%p\n",		    supported,		    supported_list);	return 0;}  #ifdef NET_26DEBUG_NO_STATIC voidpfkey_insert_socket(struct sock *sk){	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_insert_socket: "		    "sk=0p%p\n",		    sk);	pfkey_sock_list_grab();	sk_add_node(sk, &pfkey_sock_list);	pfkey_sock_list_ungrab();}DEBUG_NO_STATIC voidpfkey_remove_socket(struct sock *sk){	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_remove_socket: 0p%p\n", sk);	pfkey_sock_list_grab();	sk_del_node_init(sk);	pfkey_sock_list_ungrab();	return;}#elseDEBUG_NO_STATIC voidpfkey_insert_socket(struct sock *sk){	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_insert_socket: "		    "sk=0p%p\n",		    sk);	cli();	sk->next=pfkey_sock_list;	pfkey_sock_list=sk;	sti();}DEBUG_NO_STATIC voidpfkey_remove_socket(struct sock *sk){	struct sock **s;	s = NULL;	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_remove_socket: .\n");	cli();	s=&pfkey_sock_list;	while(*s!=NULL) {		if(*s==sk) {			*s=sk->next;			sk->next=NULL;			sti();			KLIPS_PRINT(debug_pfkey,				    "klips_debug:pfkey_remove_socket: "				    "succeeded.\n");			return;		}		s=&((*s)->next);	}	sti();	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_remove_socket: "		    "not found.\n");	return;}#endifDEBUG_NO_STATIC voidpfkey_destroy_socket(struct sock *sk){	struct sk_buff *skb;	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_destroy_socket: 0p%p\n",sk);	pfkey_remove_socket(sk);	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_destroy_socket: "		    "pfkey_remove_socket called, sk=0p%p\n",sk);		KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_destroy_socket: "		    "sk(0p%p)->(&0p%p)receive_queue.{next=0p%p,prev=0p%p}.\n",		    sk,		    &(sk->sk_receive_queue),		    sk->sk_receive_queue.next,		    sk->sk_receive_queue.prev);	while(sk && ((skb=skb_dequeue(&(sk->sk_receive_queue)))!=NULL)) {#ifdef CONFIG_KLIPS_DEBUG		if(debug_pfkey && sysctl_ipsec_debug_verbose) {			KLIPS_PRINT(debug_pfkey,				    "klips_debug:pfkey_destroy_socket: "				    "skb=0p%p dequeued.\n", skb);			printk(KERN_INFO "klips_debug:pfkey_destroy_socket: "			       "pfkey_skb contents:");			printk(" next:0p%p", skb->next);			printk(" prev:0p%p", skb->prev);			printk(" sk:0p%p", skb->sk);			printk(" dev:0p%p", skb->dev);			if(skb->dev) {				if(skb->dev->name) {					printk(" dev->name:%s", skb->dev->name);				} else {					printk(" dev->name:NULL?");				}			} else {				printk(" dev:NULL");			}			printk(" h:0p%p", skb->h.raw);

⌨️ 快捷键说明

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