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

📄 pfkey_v2.c

📁 This a good VPN source
💻 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.85 2004/12/03 21:25:57 mcr 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/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>#ifdef NET_21# include <asm/uaccess.h># include <linux/in6.h>#endif /* NET_21 */#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 */extern struct proto_ops pfkey_ops;#ifdef NET_26HLIST_HEAD(pfkey_sock_list);static DECLARE_WAIT_QUEUE_HEAD(pfkey_sock_wait);static rwlock_t pfkey_sock_lock = RW_LOCK_UNLOCKED;static atomic_t pfkey_sock_users = ATOMIC_INIT(0);#elseextern struct proto_ops pfkey_ops;struct 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 **);#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 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 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;}  #ifndef NET_21DEBUG_NO_STATIC voidpfkey_state_change(struct sock *sk){	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_state_change: .\n");	if(!sk->dead) {		wake_up_interruptible(sk->sleep);	}}#endif /* !NET_21 */#ifndef NET_21DEBUG_NO_STATIC voidpfkey_data_ready(struct sock *sk, int len){	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_data_ready: "		    "sk=0p%p len=%d\n",		    sk,		    len);	if(!sk->dead) {		wake_up_interruptible(sk->sleep);		sock_wake_async(sk->socket, 1);	}}DEBUG_NO_STATIC voidpfkey_write_space(struct sock *sk){	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_write_space: .\n");	if(!sk->dead) {		wake_up_interruptible(sk->sleep);		sock_wake_async(sk->socket, 2);	}}#endif /* !NET_21 */DEBUG_NO_STATIC voidpfkey_insert_socket(struct sock *sk){	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_insert_socket: "		    "sk=0p%p\n",		    sk);#ifdef NET_26	pfkey_sock_list_grab();	sk_add_node(sk, &pfkey_sock_list);	pfkey_sock_list_ungrab();#else	cli();	sk->next=pfkey_sock_list;	pfkey_sock_list=sk;	sti();#endif}DEBUG_NO_STATIC voidpfkey_remove_socket(struct sock *sk){	struct sock **s;	s = NULL;	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_remove_socket: .\n");#ifdef NET_26	pfkey_sock_list_grab();	sk_del_node_init(sk);	pfkey_sock_list_ungrab();#else	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();#endif	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_remove_socket: "		    "not found.\n");	return;}DEBUG_NO_STATIC voidpfkey_destroy_socket(struct sock *sk){	struct sk_buff *skb;	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_destroy_socket: .\n");	pfkey_remove_socket(sk);	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_destroy_socket: "		    "pfkey_remove_socket called.\n");		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 NET_21#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(" list:0p%p", skb->list);			printk(" sk:0p%p", skb->sk);			printk(" stamp:%ld.%ld", skb->stamp.tv_sec, skb->stamp.tv_usec);			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);			printk(" nh:0p%p", skb->nh.raw);			printk(" mac:0p%p", skb->mac.raw);			printk(" dst:0p%p", skb->dst);			if(sysctl_ipsec_debug_verbose) {				int i;								printk(" cb");				for(i=0; i<48; i++) {					printk(":%2x", skb->cb[i]);				}			}			printk(" len:%d", skb->len);			printk(" csum:%d", skb->csum);#ifndef NETDEV_23			printk(" used:%d", skb->used);			printk(" is_clone:%d", skb->is_clone);#endif /* NETDEV_23 */			printk(" cloned:%d", skb->cloned);			printk(" pkt_type:%d", skb->pkt_type);			printk(" ip_summed:%d", skb->ip_summed);			printk(" priority:%d", skb->priority);			printk(" protocol:%d", skb->protocol);			printk(" security:%d", skb->security);			printk(" truesize:%d", skb->truesize);			printk(" head:0p%p", skb->head);			printk(" data:0p%p", skb->data);			printk(" tail:0p%p", skb->tail);			printk(" end:0p%p", skb->end);			if(sysctl_ipsec_debug_verbose) {				unsigned char* i;				printk(" data");				for(i = skb->head; i < skb->end; i++) {					printk(":%2x", (unsigned char)(*(i)));				}			}			printk(" destructor:0p%p", skb->destructor);			printk("\n");		}#endif /* CONFIG_KLIPS_DEBUG */#endif /* NET_21 */		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_destroy_socket: "			    "skb=0p%p freed.\n",			    skb);		ipsec_kfree_skb(skb);	}#ifdef NET_26	sock_set_flag(sk, SOCK_DEAD);#else	sk->dead = 1;#endif	sk_free(sk);	KLIPS_PRINT(debug_pfkey,		    "klips_debug:pfkey_destroy_socket: destroyed.\n");}intpfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg){	int error = 0;	struct sk_buff * skb = NULL;	struct sock *sk;	if(sock == NULL) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_upmsg: "			    "NULL socket passed in.\n");		return -EINVAL;	}	if(pfkey_msg == NULL) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_upmsg: "			    "NULL pfkey_msg passed in.\n");		return -EINVAL;	}#ifdef NET_21	sk = sock->sk;#else /* NET_21 */	sk = sock->data;#endif /* NET_21 */	if(sk == NULL) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:pfkey_upmsg: "			    "NULL sock passed in.\n");		return -EINVAL;	}

⌨️ 快捷键说明

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