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