/* * Copyright (c) 2010-~ zhouyongfei * * The source code is released for free distribution under the terms of the GNU General Public License * * * Author: alen Chou * Created Time: 2010年11月15日 星期一 09时24分23秒 * File Name: nl_k.c * Description: * */
#include <linux/module.h> #include <linux/init.h> #include <linux/netlink.h> #include <net/sock.h> #include "nl.h" static struct sock *nlfd; int send_to_user(char *info) //发送到用户态
{ int size; struct sk_buff *skb; unsigned char *old_tail; struct nlmsghdr *nlh;
int retval;
size = NLMSG_SPACE(strlen(info)); //size = NLMSG_SPACE(25);
skb = alloc_skb(size, GFP_ATOMIC);
//skb->data = "hello ,this is alen chou.\n";
//nlh = NLMSG_PUT(skb, 0, 0, K_MSG, size-sizeof(*nlh));
nlh = nlmsg_put(skb,0,0,0,NLMSG_SPACE(strlen(info))-sizeof(struct nlmsghdr),0); old_tail = skb->tail; memcpy(NLMSG_DATA(nlh),info,strlen(info)); nlh->nlmsg_len = skb->tail - old_tail; NETLINK_CB(skb).pid = 0; //NETLINK_CB(skb).dst_pid = user_proc.pid;
NETLINK_CB(skb).dst_group = 0;
printk("in kernel,skb->data:%s\n",(char *)NLMSG_DATA((struct nlmsghdr *)skb->data)); retval = netlink_unicast(nlfd, skb, user_proc.pid, MSG_DONTWAIT); printk("netlink_unicast retuen: %d\n",retval); return 0; //nlmsg_failure:
//if(skb)
// kfree_skb(skb);
// return -1;
} void kernel_receive(struct sk_buff* __skb) //内核接受函数
{ struct sk_buff *skb; struct nlmsghdr *nlh = NULL;
char *data = "hello,this is alenchou's message from kernel\n"; printk("begin kernel_receive\n"); skb = skb_get(__skb);
if(skb->len >= sizeof(struct nlmsghdr)){ printk("kernel coming here in if\n"); nlh = (struct nlmsghdr *)skb->data; //nlh = nlmsg_hdr(__skb);
//memcpy(data,NLMSG_DATA(nlh),sizeof(data));
if((nlh->nlmsg_len >= sizeof(struct nlmsghdr)) && (__skb->len >= nlh->nlmsg_len)){ user_proc.pid = nlh->nlmsg_pid; printk("data receive from user are:%s\n",(char *)NLMSG_DATA(nlh)); //printk("data receive from user are:%s\n",data);
printk("user_pid:%d\n",user_proc.pid); send_to_user(data); } }else{ printk("kernle coming here in else!!\n"); printk("user data:%s\n",(char *)NLMSG_DATA(nlmsg_hdr(__skb))); send_to_user(data); }
kfree_skb(skb); } int __init nl_init(void) { printk("nl start!!\n"); nlfd = netlink_kernel_create(&init_net, My_netlink, 0, kernel_receive, NULL, THIS_MODULE); if(!nlfd){ printk("can not create a netlink socket\n"); return -1; } return 0; } void __exit nl_exit(void) { sock_release(nlfd->sk_socket); printk("nl exit!!\n"); } MODULE_DESCRIPTION("NETLINK_TEST"); MODULE_LICENSE("GPL"); module_init(nl_init); module_exit(nl_exit);
|