linux netlink详解3-netlink总结
1 netlink初始化
2 内核netlink创建
3 应用层netlink创建
4 应用层向内核发送消息
5 应用层接收内核消息
6 内核向应用层发送消息
7 内核和应用层netlink通信实例
7.1 应用层代码实例
1 /*应用层代码*/ 2 #include <sys/stat.h> 3 #include <unistd.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <sys/socket.h> 7 #include <sys/types.h> 8 #include <string.h> 9 #include <asm/types.h> 10 #include <linux/netlink.h> 11 #include <linux/socket.h> 12 13 #define MAX_PAYLOAD 1024 /* maximum payload size*/ 14 struct sockaddr_nl src_addr, dest_addr; 15 struct nlmsghdr *nlh = NULL; 16 struct iovec iov; 17 int sock_fd; 18 struct msghdr msg; 19 20 int main(int argc, char* argv[]) 21 { 22 sock_fd = socket(PF_NETLINK, SOCK_RAW, 21); 23 memset(&msg, 0, sizeof(msg)); 24 memset(&src_addr, 0, sizeof(src_addr)); 25 src_addr.nl_family = AF_NETLINK; 26 src_addr.nl_pid = getpid(); /* self pid */ 27 src_addr.nl_groups = 0; /* not in mcast groups */ 28 bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr)); 29 memset(&dest_addr, 0, sizeof(dest_addr)); 30 dest_addr.nl_family = AF_NETLINK; 31 dest_addr.nl_pid = 0; /* For Linux Kernel */ 32 dest_addr.nl_groups = 0; /* unicast */ 33 34 nlh=(struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); 35 /* Fill the netlink message header */ 36 nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); 37 nlh->nlmsg_pid = getpid(); /* self pid */ 38 nlh->nlmsg_flags = 0; 39 /* Fill in the netlink message payload */ 40 strcpy(NLMSG_DATA(nlh), "Hello you!"); 41 42 iov.iov_base = (void *)nlh; 43 iov.iov_len = nlh->nlmsg_len; 44 msg.msg_name = (void *)&dest_addr; 45 msg.msg_namelen = sizeof(dest_addr); 46 msg.msg_iov = &iov; 47 msg.msg_iovlen = 1; 48 49 printf(" Sending message. ...\n"); 50 sendmsg(sock_fd, &msg, 0);//向内核发送消息 51 52 /* Read message from kernel */ 53 memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); 54 printf(" Waiting message. ...\n"); 55 recvmsg(sock_fd, &msg, 0);//接收内核的消息 56 printf(" Received message payload: %s\n",NLMSG_DATA(nlh)); 57 58 /* Close Netlink Socket */ 59 close(sock_fd); 60 }
7.2 内核层代码实例
1 /*内核层代码*/ 2 3 #include <linux/kernel.h> 4 #include <linux/module.h> 5 #include <linux/types.h> 6 #include <linux/sched.h> 7 #include <net/sock.h> 8 #include <net/netlink.h> 9 10 #define NETLINK_TEST 21 11 12 struct sock *nl_sk = NULL; 13 EXPORT_SYMBOL_GPL(nl_sk); 14 15 void nl_send(struct sk_buff *__skb) 16 { 17 struct sk_buff *skb; 18 struct nlmsghdr *nlh; 19 u32 pid; 20 int rc; 21 int len = NLMSG_SPACE(1200); 22 char str[100]; 23 24 printk("net_link: data is ready to read.\n"); 25 skb = skb_get(__skb); 26 27 if (skb->len >= NLMSG_SPACE(0)) { 28 nlh = nlmsg_hdr(skb);//接收应用层的消息头 29 printk("nl_send: recv %s.\n", (char *)NLMSG_DATA(nlh));//NLMSG_DATA(nlh)接收应用层消息数据 30 memcpy(str,NLMSG_DATA(nlh), sizeof(str)); 31 pid = nlh->nlmsg_pid; /*pid of sending process */ 32 printk("nl_send: pid is %d\n", pid); 33 kfree_skb(skb); 34 35 skb = alloc_skb(len, GFP_ATOMIC); 36 if (!skb){ 37 printk(KERN_ERR "nl_send: allocate failed.\n"); 38 return; 39 } 40 nlh = nlmsg_put(skb,0,0,0,1200,0); 41 NETLINK_CB(skb).pid = 0; /* from kernel */ 42 43 memcpy(NLMSG_DATA(nlh), str, sizeof(str)); 44 printk("nl_send: going to send.\n"); 45 rc = netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT);//向应用层发送消息 46 if (rc < 0) { 47 printk(KERN_ERR "nl_send: can not unicast skb (%d)\n", rc); 48 } 49 printk("nl_send: send is ok.\n"); 50 } 51 return; 52 } 53 54 static int kernel_netlink_test(void) { 55 nl_sk = netlink_kernel_create(&init_net, NETLINK_TEST, 0, nl_send, NULL, THIS_MODULE);//创建netlink socket 56 57 if (!nl_sk) { 58 printk(KERN_ERR "kernel_netlink_test: Cannot create netlink socket.\n"); 59 return -EIO; 60 } 61 printk("kernel_netlink_test: create socket ok.\n"); 62 return 0; 63 } 64 65 int init_module() 66 { 67 kernel_netlink_test(); 68 return 0; 69 } 70 void cleanup_module( ) 71 { 72 if (nl_sk != NULL){ 73 sock_release(nl_sk->sk_socket); 74 } 75 printk("kernel_netlink_test: remove ok.\n"); 76 } 77 MODULE_LICENSE("GPL"); 78 MODULE_AUTHOR("action_er");
待测试。。。
行胜于言,自强不息。