📄 pfkey_v2.c
字号:
}DEBUG_NO_STATIC intpfkey_listen(struct socket *sock, int backlog){ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_listen: " "not supported.\n"); return -EINVAL;}#endif /* !NET_21 */DEBUG_NO_STATIC intpfkey_shutdown(struct socket *sock, int mode){ struct sock *sk; if(sock == NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_shutdown: " "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_shutdown: " "No sock attached to socket.\n"); return -EINVAL; } KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_shutdown: " "mode=%x.\n", mode); mode++; if(mode&SEND_SHUTDOWN) { sk->sk_shutdown|=SEND_SHUTDOWN; sk->sk_state_change(sk); } if(mode&RCV_SHUTDOWN) { sk->sk_shutdown|=RCV_SHUTDOWN; sk->sk_state_change(sk); } return 0;}#ifndef NET_21DEBUG_NO_STATIC intpfkey_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen){#ifndef NET_21 struct sock *sk; if(sock == NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_setsockopt: " "Null socket passed in.\n"); return -EINVAL; } sk=sock->data; if(sk == NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_setsockopt: " "Null sock passed in.\n"); return -EINVAL; }#endif /* !NET_21 */ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_setsockopt: .\n"); if(level!=SOL_SOCKET) { return -EOPNOTSUPP; }#ifdef NET_21 return sock_setsockopt(sock, level, optname, optval, optlen);#else /* NET_21 */ return sock_setsockopt(sk, level, optname, optval, optlen);#endif /* NET_21 */}DEBUG_NO_STATIC intpfkey_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen){#ifndef NET_21 struct sock *sk; if(sock == NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_setsockopt: " "Null socket passed in.\n"); return -EINVAL; } sk=sock->data; if(sk == NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_setsockopt: " "Null sock passed in.\n"); return -EINVAL; }#endif /* !NET_21 */ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getsockopt: .\n"); if(level!=SOL_SOCKET) { return -EOPNOTSUPP; }#ifdef NET_21 return sock_getsockopt(sock, level, optname, optval, optlen);#else /* NET_21 */ return sock_getsockopt(sk, level, optname, optval, optlen);#endif /* NET_21 */}DEBUG_NO_STATIC intpfkey_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg){ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_fcntl: " "not supported.\n"); return -EINVAL;}#endif /* !NET_21 *//* * Send PF_KEY data down. */ DEBUG_NO_STATIC int#ifdef NET_21#ifdef NET_26pfkey_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)#elsepfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)#endif#else /* NET_21 */pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags)#endif /* NET_21 */{ struct sock *sk; int error = 0; struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL; if(sock == NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "Null socket passed in.\n"); SENDERR(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_sendmsg: " "Null sock passed in.\n"); SENDERR(EINVAL); } if(msg == NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "Null msghdr passed in.\n"); SENDERR(EINVAL); } KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: .\n"); if(sk->sk_err) { error = sock_error(sk); KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "sk->err is non-zero, returns %d.\n", error); SENDERR(-error); } if((current->uid != 0)) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "must be root to send messages to pfkey sockets.\n"); SENDERR(EACCES); }#ifdef NET_21 if(msg->msg_control)#else /* NET_21 */ if(flags || msg->msg_control)#endif /* NET_21 */ { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "can't set flags or set msg_control.\n"); SENDERR(EINVAL); } if(sk->sk_shutdown & SEND_SHUTDOWN) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "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", (int)len); SENDERR(EMSGSIZE); } KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " "allocating %d bytes for downward message.\n", (int)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", (int)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, (int)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);#ifdef HAVE_TSTAMP sk->sk_stamp.tv_sec = skb->tstamp.off_sec; sk->sk_stamp.tv_usec = skb->tstamp.off_usec;#else sk->sk_stamp=skb->stamp;#endif skb_free_datagram(sk, skb); return size;}#ifdef NET_21struct net_proto_family pfkey_family_ops = {#ifdef NET_26_12_SKALLOC .family = PF_KEY, .create = pfkey_create, .owner = THIS_MODULE,#else PF_KEY, pfkey_create#endif};struct proto_ops pfkey_ops = { family: PF_KEY,#ifdef NET_26_12_SKALLOC owner: THIS_MODULE,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -