📄 pfkey_v2.c
字号:
"shutdown.\n"); send_sig(SIGPIPE, current, 0); SENDERR(EPIPE); } if(len < sizeof(struct sadb_msg)) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "bogus msg len of %d, too small.\n", len); SENDERR(EMSGSIZE); } KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "allocating %d bytes for downward message.\n", len); if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "memory allocation error.\n"); SENDERR(ENOBUFS); } memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len); if(pfkey_msg->sadb_msg_version != PF_KEY_V2) { KLIPS_PRINT(1 || debug_pfkey, "klips_debug:pfkey_sendmsg: " "not PF_KEY_V2 msg, found %d, should be %d.\n", pfkey_msg->sadb_msg_version, PF_KEY_V2); kfree((void*)pfkey_msg); return -EINVAL; } if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "bogus msg len of %d, not %d byte aligned.\n", len, (int)IPSEC_PFKEYv2_ALIGN); SENDERR(EMSGSIZE); }#if 0 /* This check is questionable, since a downward message could be the result of an ACQUIRE either from kernel (PID==0) or userspace (some other PID). */ /* check PID */ if(pfkey_msg->sadb_msg_pid != current->pid) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "pid (%d) does not equal sending process pid (%d).\n", pfkey_msg->sadb_msg_pid, current->pid); SENDERR(EINVAL); }#endif if(pfkey_msg->sadb_msg_reserved) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "reserved field must be zero, set to %d.\n", pfkey_msg->sadb_msg_reserved); SENDERR(EINVAL); } if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "msg type too large or small:%d.\n", pfkey_msg->sadb_msg_type); SENDERR(EINVAL); } KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "msg sent for parsing.\n"); if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) { struct socket_list *pfkey_socketsp; KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "pfkey_msg_parse returns %d.\n", error); if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "memory allocation error.\n"); SENDERR(ENOBUFS); } memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg)); pfkey_reply->sadb_msg_errno = -error; pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN; for(pfkey_socketsp = pfkey_open_sockets; pfkey_socketsp; pfkey_socketsp = pfkey_socketsp->next) { int error_upmsg = 0; KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "sending up error=%d message=0p%p to socket=0p%p.\n", error, pfkey_reply, pfkey_socketsp->socketp); if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "sending up error message to socket=0p%p failed with error=%d.\n", pfkey_socketsp->socketp, error_upmsg); /* pfkey_msg_free(&pfkey_reply); */ /* SENDERR(-error); */ } KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "sending up error message to socket=0p%p succeeded.\n", pfkey_socketsp->socketp); } pfkey_msg_free(&pfkey_reply); SENDERR(-error); } errlab: if (pfkey_msg) { kfree((void*)pfkey_msg); } if(error) { return error; } else { return len; }}/* * Receive PF_KEY data up. */ DEBUG_NO_STATIC int#ifdef NET_21#ifdef NET_26pfkey_recvmsg(struct kiocb *kiocb , struct socket *sock , struct msghdr *msg , size_t size , int flags)#elsepfkey_recvmsg(struct socket *sock , struct msghdr *msg , int size, int flags , struct scm_cookie *scm)#endif#else /* NET_21 */pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock, int flags, int *addr_len)#endif /* NET_21 */{ struct sock *sk;#ifdef NET_21 int noblock = flags & MSG_DONTWAIT;#endif /* NET_21 */ struct sk_buff *skb; int error; if(sock == NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_recvmsg: " "Null socket 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_recvmsg: " "Null sock passed in for sock=0p%p.\n", sock); return -EINVAL; } if(msg == NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_recvmsg: " "Null msghdr passed in for sock=0p%p, sk=0p%p.\n", sock, sk); return -EINVAL; } KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, "klips_debug:pfkey_recvmsg: sock=0p%p sk=0p%p msg=0p%p size=%d.\n", sock, sk, msg, size); if(flags & ~MSG_PEEK) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "flags (%d) other than MSG_PEEK not supported.\n", flags); return -EOPNOTSUPP; } #ifdef NET_21 msg->msg_namelen = 0; /* sizeof(*ska); */#else /* NET_21 */ if(addr_len) { *addr_len = 0; /* sizeof(*ska); */ }#endif /* NET_21 */ if(sk->sk_err) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "sk->sk_err=%d.\n", sk->sk_err); return sock_error(sk); } if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) { return error; } if(size > skb->len) { size = skb->len; }#ifdef NET_21 else if(size <skb->len) { msg->msg_flags |= MSG_TRUNC; }#endif /* NET_21 */ skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size); sk->sk_stamp=skb->stamp; skb_free_datagram(sk, skb); return size;}#ifdef NET_21struct 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 */#else /* NET_21 */struct proto_ops pfkey_proto_ops = { PF_KEY, pfkey_create, pfkey_dup, pfkey_release, pfkey_bind, pfkey_connect, pfkey_socketpair, pfkey_accept, pfkey_getname, pfkey_select, pfkey_ioctl, pfkey_listen, pfkey_shutdown, pfkey_setsockopt, pfkey_getsockopt, pfkey_fcntl, pfkey_sendmsg, pfkey_recvmsg};#endif /* NET_21 */ #ifdef CONFIG_PROC_FS#ifndef PROC_FS_2325DEBUG_NO_STATIC#endif /* PROC_FS_2325 */intpfkey_get_info(char *buffer, char **start, off_t offset, int length#ifndef PROC_NO_DUMMY, int dummy#endif /* !PROC_NO_DUMMY */){ const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */#ifdef NET_26 struct hlist_node *node;#endif off_t begin=0; int len=0; struct sock *sk; #ifdef CONFIG_KLIPS_DEBUG if(!sysctl_ipsec_debug_verbose) {#endif /* CONFIG_KLIPS_DEBUG */ len += ipsec_snprintf(buffer, length, " sock pid socket next prev e n p sndbf Flags Type St\n");#ifdef CONFIG_KLIPS_DEBUG } else { len += ipsec_snprintf(buffer, length, " sock pid d sleep socket next prev e r z n p sndbf stamp Flags Type St\n"); }#endif /* CONFIG_KLIPS_DEBUG */ sk_for_each(sk, node, &pfkey_sock_list) {#ifdef CONFIG_KLIPS_DEBUG if(!sysctl_ipsec_debug_verbose) {#endif /* CONFIG_KLIPS_DEBUG */ len += ipsec_snprintf(buffer+len, length-len, "%8p %5d %8p %d %d %5d %08lX %8X %2X\n", sk, key_pid(sk), sk->sk_socket, sk->sk_err, sk->sk_protocol, sk->sk_sndbuf, sk->sk_socket->flags, sk->sk_socket->type, sk->sk_socket->state);#ifdef CONFIG_KLIPS_DEBUG } else { len += ipsec_snprintf(buffer+len, length-len, "%8p %5d %d %8p %8p %d %d %d %d %5d %d.%06d %08lX %8X %2X\n", sk, key_pid(sk), sock_flag(sk, SOCK_DEAD), sk->sk_sleep, sk->sk_socket, sk->sk_err, sk->sk_reuse, sk->sk_zapped, sk->sk_protocol, sk->sk_sndbuf, (unsigned int)sk->sk_stamp.tv_sec, (unsigned int)sk->sk_stamp.tv_usec, sk->sk_socket->flags, sk->sk_socket->type, sk->sk_socket->state); }#endif /* CONFIG_KLIPS_DEBUG */ if (len >= max_content) { /* we've done all that can fit -- stop loop */ len = max_content; /* truncate crap */ break; } else { const off_t pos = begin + len; /* file position of end of what we've generated */ if (pos <= offset) { /* all is before first interesting character: * discard, but note where we are. */ len = 0; begin = pos; } } } *start = buffer + (offset - begin); /* Start of wanted data */ return len - (offset - begin);}#ifndef PROC_FS_2325DEBUG_NO_STATIC#endif /* PROC_FS_2325 */intpfkey_supported_get_info(char *buffer, char **start, off_t offset, int length#ifndef PROC_NO_DUMMY, int dummy#endif /* !PROC_NO_DUMMY */){ const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */ off_t begin=0; int len=0; int satype; struct supported_list *pfkey_supported_p; len += ipsec_snprintf(buffer, length, "satype exttype alg_id ivlen minbits maxbits\n"); for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) { pfkey_supported_p = pfkey_supported_list[satype]; while(pfkey_supported_p) { len += ipsec_snprintf(buffer+len, length-len, " %2d %2d %2d %3d %3d %3d\n", satype, pfkey_supported_p->supportedp->supported_alg_exttype, pfkey_supported_p->supportedp->supported_alg_id, pfkey_supported_p->supportedp->supported_alg_ivlen, pfkey_supported_p->supportedp->supported_alg_minbits, pfkey_supported_p->supportedp->supported_alg_maxbits); if (len >= max_content) { /* we've done all that can fit -- stop loop */ len = max_content; /* truncate crap */ break; } else { const off_t pos = begin + len; /* file position of end of what we've generated */ if (pos <= offset) { /* all is before first interesting character: * discard, but note where we are. */ len = 0; begin = pos; } } pfkey_supported_p = pfkey_supported_p->next; } } *start = buffer + (offset - begin); /* Start of wanted data */ return len - (offset - begin);}#ifndef PROC_FS_2325DEBUG_NO_STATIC#endif /* PROC_FS_2325 */intpfkey_registered_get_info(char *buffer, char **start, off_t offset, int length#ifndef PROC_NO_DUMMY, int dummy#endif /* !PROC_NO_DUMMY */){ const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */ off_t begin=0; int len=0; int satype; struct socket_list *pfkey_sockets; len += ipsec_snprintf(buffer, length, "satype socket pid sk\n"); for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) { pfkey_sockets = pfkey_registered_sockets[satype]; while(pfkey_sockets) {#ifdef NET_21 len += ipsec_snprintf(buffer+len, length-len, " %2d %8p %5d %8p\n", satype, pfkey_sockets->socketp, key_pid(pfkey_sockets->socketp->sk), pfkey_sockets->socketp->sk);#else /* NET_21 */ len += ipsec_snprintf(buffer+len, " %2d %8p N/A %8p\n", satype, pfkey_sockets->socketp,#if 0 key_pid((pfkey_sockets->socketp)->data),#endif (pfkey_sockets->socketp)->data);#endif /* NET_21 */ if (len >= max_content) { /* we've done all that can fit -- stop loop (could stop two) */ len = max_content; /* truncate crap */ break; } else { const off_t pos = begin + len; /* file position of end of what we've generated */ if (pos <= offset) { /* all is before first interesting character: * discard, but note where we are. */ len = 0; begin = pos; } } pfkey_sockets = pfkey_sockets->next; } } *start = buffer + (offset - begin); /* Start of wanted data */ return len - (offset - begin);}#ifndef PROC_FS_2325struct proc_dir_entry proc_net_pfkey ={ 0, 6, "pf_key", S_IFREG | S_IRUGO, 1, 0, 0, 0, &proc_net_inode_operations, pfkey_get_info};struct proc_dir_entry proc_net_pfkey_supported ={ 0, 16, "pf_key_supported", S_IFREG | S_IRUGO, 1, 0, 0, 0, &proc_net_inode_operations, pfkey_supported_get_info};struct proc_dir_entry proc_net_pfkey_registered ={ 0, 17, "pf_key_registered", S_IFREG | S_IRUGO, 1, 0, 0, 0, &proc_net_inode_operations, pfkey_registered_get_info};#endif /* !PROC_FS_2325 */#endif /* CONFIG_PROC_FS */DEBUG_NO_STATIC intsupported_add_all(int satype, struct supported supported[], int size){ int i; int error = 0; KLIPS_PRINT(debug_pfkey, "klips_debug:init_pfkey: " "sizeof(supported_init_<satype=%d>)[%d]/sizeof(struct supported)[%d]=%d.\n", satype, size, (int)sizeof(struct supported), (int)(size/sizeof(struct supported))); for(i = 0; i < size / sizeof(struct supported); i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -