📄 pfkey_v2.c
字号:
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);#ifdef HAVE_SOCK_SECURITY printk(" security:%d", skb->security);#endif 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 */ 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; } sk = sock->sk; if(sk == NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_upmsg: " "NULL sock passed in.\n"); return -EINVAL; } KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_upmsg: " "allocating %d bytes...\n", (int)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)); if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_upmsg: " "no buffers left to send up a message.\n"); return -ENOBUFS; } KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_upmsg: " "...allocated at 0p%p.\n", skb); skb->dev = NULL; if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) { printk(KERN_WARNING "klips_error:pfkey_upmsg: " "tried to skb_put %ld, %d available. This should never happen, please report.\n", (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, skb_tailroom(skb)); ipsec_kfree_skb(skb); return -ENOBUFS; } skb->h.raw = skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN); memcpy(skb->h.raw, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN); if((error = sock_queue_rcv_skb(sk, skb)) < 0) { skb->sk=NULL; KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_upmsg: " "error=%d calling sock_queue_rcv_skb with skb=0p%p.\n", error, skb); ipsec_kfree_skb(skb); return error; } return error;}#ifdef NET_26_12_SKALLOCstatic struct proto key_proto = { .name = "KEY", .owner = THIS_MODULE, .obj_size = sizeof(struct sock), };#endifDEBUG_NO_STATIC intpfkey_create(struct socket *sock, int protocol){ struct sock *sk; if(sock == NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_create: " "socket NULL.\n"); return -EINVAL; } KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_create: " "sock=0p%p type:%d state:%d flags:%ld protocol:%d\n", sock, sock->type, (unsigned int)(sock->state), sock->flags, protocol); if(sock->type != SOCK_RAW) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_create: " "only SOCK_RAW supported.\n"); return -ESOCKTNOSUPPORT; } if(protocol != PF_KEY_V2) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_create: " "protocol not PF_KEY_V2.\n"); return -EPROTONOSUPPORT; } if((current->uid != 0)) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_create: " "must be root to open pfkey sockets.\n"); return -EACCES; } sock->state = SS_UNCONNECTED; KLIPS_INC_USE;#ifdef NET_26#ifdef NET_26_12_SKALLOC sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1);#else sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1, NULL);#endif#else /* 2.4 interface */ sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1);#endif if(sk == NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_create: " "Out of memory trying to allocate.\n"); KLIPS_DEC_USE; return -ENOMEM; } sock_init_data(sock, sk); sk->sk_destruct = NULL; sk->sk_reuse = 1; sock->ops = &pfkey_ops; sk->sk_family = PF_KEY;/* sk->num = protocol; */ sk->sk_protocol = protocol; key_pid(sk) = current->pid; KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_create: " "sock->fasync_list=0p%p sk->sleep=0p%p.\n", sock->fasync_list, sk->sk_sleep); pfkey_insert_socket(sk); pfkey_list_insert_socket(sock, &pfkey_open_sockets); KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_create: " "Socket sock=0p%p sk=0p%p initialised.\n", sock, sk); return 0;}DEBUG_NO_STATIC int#ifdef NETDEV_23pfkey_release(struct socket *sock)#else /* NETDEV_23 */pfkey_release(struct socket *sock, struct socket *peersock)#endif /* NETDEV_23 */{ struct sock *sk; int i; if(sock==NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_release: " "No socket attached.\n"); return 0; /* -EINVAL; */ } sk=sock->sk; /* May not have data attached */ if(sk==NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_release: " "No sk attached to sock=0p%p.\n", sock); return 0; /* -EINVAL; */ } KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_release: " "sock=0p%p sk=0p%p\n", sock, sk); if(sock_flag(sk, SOCK_DEAD)) if(sk->sk_state_change) { sk->sk_state_change(sk); } sock->sk = NULL; /* Try to flush out this socket. Throw out buffers at least */ pfkey_destroy_socket(sk); pfkey_list_remove_socket(sock, &pfkey_open_sockets); for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) { pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i])); } KLIPS_DEC_USE; KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_release: " "succeeded.\n"); return 0;}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; } sk=sock->sk; 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;}/* * Send PF_KEY data down. */ DEBUG_NO_STATIC int#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{ 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); } sk = sock->sk; 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); } if(msg->msg_control) { 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: "
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -