Use netlink to achieve user mode and kernel interaction
Hi, nowadays i am learning how to use netlink achieve user mode and kernel interaction. and when i finsh it ,i found kernel can not get the data from user mode. next is my code. can you tell me why? thank u user mode code: #include <stdio.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <linux/netlink.h> #include <fcntl.h> #include <sys/stat.h> #include <stdlib.h> #include <string.h> void myerr(const char * err_string,int line) { fprintf(stderr,"line:%d ",line); perror(err_string); exit(1); } #define MAX_PAYLOAD 2046 #define NETLINK_TEST 26 /*struct req { struct nlmsghdr nlh; char buf[MAX_PAYLOAD]; }*/ int main (int argc,char * argv[]) { int fd; struct sockaddr_nl saddr,daddr; int sock_fd; struct nlmsghdr *nlhdr = NULL; struct iovec iov; struct msghdr msg; char text[MAX_PAYLOAD]; int ret; if(argc < 2){ printf("Usage:%s textfile\n",argv[0]); exit(1); } if(fd = (open(argv[1],O_RDWR|O_CREAT,S_IRWXU)) == -1){ myerr("open",__LINE__); }else{ printf("file open success!\n"); } sock_fd = socket( AF_NETLINK,SOCK_RAW,NETLINK_TEST); if( sock_fd < 0 ){ myerr("sock_fd",__LINE__); } memset(&saddr,0,sizeof(saddr)); memset(&daddr,0,sizeof(daddr)); saddr.nl_family = AF_NETLINK; saddr.nl_pid = getpid(); saddr.nl_groups = 0; if(bind(sock_fd,(struct sockaddr * )&saddr,sizeof( saddr))) { myerr("bind",__LINE__); } daddr.nl_family = AF_NETLINK; daddr.nl_pid = 0; daddr.nl_groups = 0; nlhdr = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); while(1){ if(read(fd,text,MAX_PAYLOAD) == -1){ myerr("read",__LINE__); } // while(read(fd,text,MAX_PAYLOAD)){ memcpy(NLMSG_DATA(nlhdr),text,strlen(text)); memset(&msg,0,sizeof(struct msghdr)); nlhdr->nlmsg_len = NLMSG_LENGTH(strlen(text)); nlhdr->nlmsg_pid = getpid(); nlhdr->nlmsg_flags = 0; iov.iov_base = (void *)nlhdr; iov.iov_len = nlhdr->nlmsg_len; msg.msg_name = (void * )&daddr; msg.msg_namelen = sizeof(daddr); msg.msg_iov = &iov; msg.msg_iovlen = 1; ret = sendmsg(sock_fd,&msg,0); if(ret == -1){ myerr("sendmsg",__LINE__); }else{ printf("usr send message to kernel\n"); } } close(sock_fd); } kernel module: #include <linux/module.h> //#include <linux/kernel.h> #include <linux/netlink.h> #include <linux/skbuff.h> #include <net/sock.h> struct sock *nl_sk = NULL; #define MAX_PAYLOAD 2046 #define NETLINK_TEST 26 void nl_data_handler(struct sk_buff *__skb) { struct sk_buff *skb; struct nlmsghdr *nlh; pid_t pid; char str[2046]; // int len = NLMSG_SPACE(MAX_PAYLOAD); int rc; printk("start reading...\n"); skb = skb_get(__skb); if(skb->len >= NLMSG_SPACE(0)) { nlh = nlmsg_hdr(skb); printk("recv:%s\n",(char *)NLMSG_DATA(nlh)); memcpy(str,NLMSG_DATA(nlh),sizeof(str)); pid = nlh->nlmsg_pid; printk("pid is %d\n",pid); kfree_skb(skb); skb = alloc_skb(NLMSG_SPACE(MAX_PAYLOAD),GFP_ATOMIC); if(!skb){ printk(KERN_ERR "allocate failed!\n"); return ; } nlh = nlmsg_put(skb,0,0,0,MAX_PAYLOAD,0); NETLINK_CB(skb).pid = 0; memcpy(NLMSG_DATA(nlh),str,sizeof(str)); printk("net_link: ready send message\n"); rc = netlink_unicast(nl_sk,skb,pid,MSG_DONTWAIT); if(rc < 0){ printk("can`t unicast skb\n"); } printk("send ok!\n"); } } static int __init net_init(void) { struct net init_net; // struct sock *nl_sk = NULL; printk("net creat start.....\n"); nl_sk = netlink_kernel_create(&init_net,NETLINK_TEST,0,nl_data_handler,NULL,THIS_MODULE); if(nl_sk == 0) { printk("create netlink faile!\n"); return -1; }else{ printk("netlink create success!\n"); } return 0; } static void __exit net_exit(void) { printk("lal\n"); sock_release(nl_sk->sk_socket); printk("netlink over!\n"); } module_init(net_init); module_exit(net_exit); MODULE_LICENSE("GPL");
participants (1)
-
于运超