{"id":883,"date":"2014-09-20T14:37:42","date_gmt":"2014-09-20T06:37:42","guid":{"rendered":"http:\/\/www.menglanglang.cn\/?p=883"},"modified":"2014-09-20T14:37:42","modified_gmt":"2014-09-20T06:37:42","slug":"linux%e4%b8%ad%e4%b8%8e%e5%86%85%e6%a0%b8%e9%80%9a%e4%bf%a1%e7%9a%84netlink%e6%9c%ba%e5%88%b6","status":"publish","type":"post","link":"http:\/\/www.menglanglang.cn\/?p=883","title":{"rendered":"Linux\u4e2d\u4e0e\u5185\u6838\u901a\u4fe1\u7684Netlink\u673a\u5236"},"content":{"rendered":"<p>netlink_k.c\u4e3a\u5185\u6838\u7684\u7a7a\u95f4\u7684\u7a0b\u5e8f,netlink_u.c\u4e3a\u7528\u6237\u7684\u7a7a\u95f4\u7684\u7a0b\u5e8f\u3002\u7a0b\u5e8f\u6e90\u4ee3\u7801\u9644\u5728\u540e\u9762\uff1a<\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0\u5148\u8fd0\u884c\u5185\u6838\u4ee3\u7801netlink_k.ko\uff0c\u4e5f\u5c31\u662f\u5728\u6267\u884c\u5b8cmakefile\u6587\u4ef6\u540e\uff0c\u4f1a\u751f\u6210\u4e00\u4e2anetlink_k.ko\u6587\u4ef6\uff0c\u53ef\u4ee5\u4f7f\u7528\u4e0b\u9762\u7684\u547d\u4ee4\u8fdb\u884c\u5b89\u88c5\uff0cinsmod netlink_k.ko\uff0c\u4f7f\u7528lsmod\u67e5\u770b\uff0c\u5f53\u5b89\u88c5\u6210\u529f\u540e\uff0c\u7136\u540e\uff0c\u6267\u884c.\/netlink\u7528\u6237\u7a7a\u95f4\u7a0b\u5e8f\uff0c\u53ef\u4ee5\u5728\u53e6\u4e00\u4e2a\u7ec8\u7aef\u4e0b\u6267\u884cdmesg\u547d\u4ee4\uff0c\u67e5\u770b\u5185\u6838\u901a\u4fe1\u7684\u60c5\u51b5\u3002\u8fd9\u91ccnetlink\u7a0b\u5e8f\u5411\u5185\u6838\u7a7a\u95f4\u53d1\u9001\u4e00\u4e2ahello you\uff01\u5185\u6838\u8fd4\u56de\u7ed9\u4e00\u4e2aI am from kernel!\u5728\u8fd9\u91cc\u4f7f\u7528\u4e86\u4e00\u4e2a\u5b9a\u65f6\u5668\uff0c\u4e5f\u5c31\u662f\u6bcf3\u79d2\u4e2d\u53d1\u9001\u4e00\u6b21I am from kernel!\u53ea\u6709\u5185\u6838\u628a10\u4e2a\u5b57\u7b26\u4e32\u5168\u90e8\u53d1\u9001\u5b8c\u6bd5\u540e\uff0c\u7528\u6237\u7a7a\u95f4\u7684sendmsg()\u624d\u4f1a\u8fd4\u56de\uff0c\u4e5f\u5c31\u662f\u5728\u7528\u6237\u7a7a\u95f4\u7684netlink\u624d\u4f1a\u8f93\u51fa\u5185\u6838\u7a7a\u95f4\u53d1\u9001\u8fc7\u6765\u7684\u6570\u636e\uff0c\u8fd9\u91cc\u53ea\u6709\u4e00\u4e2a\u7b80\u5355\u7684\u7a0b\u5e8f\uff0c\u5e76\u6ca1\u6709\u4ec0\u4e48\u5b9e\u9645\u7684\u610f\u4e49\uff0c\u56e0\u4e3a\uff0c\u6b63\u5982\u524d\u9762\u6240\u8bf4\u7684\u4e00\u822c\u60c5\u51b5\u4e0b\u4e0d\u4f1a\u5728\u56de\u8c03\u51fd\u6570\u4e2d\u5904\u7406\u592a\u591a\u7684\u4e1c\u897f\uff0c\u4ee5\u514dsendmsg()\u51fd\u6570\u8fd4\u56de\u4e0d\u53ca\u65f6\u3002<\/wbr><\/wbr><\/wbr><\/p>\n<p>&nbsp;<\/p>\n<p><strong>netlink_k.c\uff1a<\/strong><\/p>\n<p>#include &lt;linux\/init.h&gt;<br \/>\n#include &lt;linux\/module.h&gt;<br \/>\n#include &lt;linux\/timer.h&gt;<br \/>\n#include &lt;linux\/time.h&gt;<br \/>\n#include &lt;linux\/types.h&gt;<br \/>\n#include &lt;net\/sock.h&gt;<br \/>\n#include &lt;net\/netlink.h&gt;<\/p>\n<p>#define NETLINK_TEST 25<br \/>\n#define MAX_MSGSIZE 1024<br \/>\nint stringlength(char *s);<br \/>\nvoid sendnlmsg(char * message);<br \/>\nint pid;<br \/>\nint err;<br \/>\nstruct sock *nl_sk = NULL;<br \/>\nint flag = 0;<\/p>\n<p>void sendnlmsg(char *message)<br \/>\n{<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0struct sk_buff *skb_1;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0struct nlmsghdr *nlh;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0int len = NLMSG_SPACE(MAX_MSGSIZE);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0int slen = 0;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0if(!message || !nl_sk)<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0{<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0return ;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0}<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0skb_1 = alloc_skb(len,GFP_KERNEL);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0if(!skb_1)<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0{<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0printk(KERN_ERR &#8220;my_net_link:alloc_skb_1 error\\n&#8221;);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0}<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0slen = stringlength(message);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0nlh = nlmsg_put(skb_1,0,0,0,MAX_MSGSIZE,0);<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0NETLINK_CB(skb_1).pid = 0;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0NETLINK_CB(skb_1).dst_group = 0;<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0message[slen]= &#8216;\\0&#8217;;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0memcpy(NLMSG_DATA(nlh),message,slen+1);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0printk(&#8220;my_net_link:send message &#8216;%s&#8217;.\\n&#8221;,(char *)NLMSG_DATA(nlh));<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0netlink_unicast(nl_sk,skb_1,pid,MSG_DONTWAIT);<\/wbr><\/wbr><\/wbr><\/p>\n<p>}<\/p>\n<p>int stringlength(char *s)<br \/>\n{<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0int slen = 0;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0for(; *s; s++){<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0slen++;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0}<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0return slen;<br \/>\n}<\/wbr><\/wbr><\/wbr><\/p>\n<p>void nl_data_ready(struct sk_buff *__skb)<br \/>\n<wbr>{<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0struct sk_buff *skb;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0struct nlmsghdr *nlh;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0char str[100];<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0struct completion cmpl;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0int i=10;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0skb = skb_get (__skb);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0if(skb-&gt;len &gt;= NLMSG_SPACE(0))<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0{<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0nlh = nlmsg_hdr(skb);<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0memcpy(str, NLMSG_DATA(nlh), sizeof(str));<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0printk(&#8220;Message received:%s\\n&#8221;,str) ;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0pid = nlh-&gt;nlmsg_pid;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0while(i&#8211;)<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0{<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0init_completion(&amp;cmpl);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0wait_for_completion_timeout(&amp;cmpl,3 * HZ);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0sendnlmsg(&#8220;I am from kernel!&#8221;);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0}<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0flag = 1;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0kfree_skb(skb);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0}<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>}<\/wbr><\/p>\n<p>\/\/ Initialize netlink<\/p>\n<p>int netlink_init(void)<br \/>\n{<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0nl_sk = netlink_kernel_create(&amp;init_net, NETLINK_TEST, 1,<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0nl_data_ready, NULL, THIS_MODULE);<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0if(!nl_sk){<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0printk(KERN_ERR &#8220;my_net_link: create netlink socket error.\\n&#8221;);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0return 1;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0}<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0printk(&#8220;my_net_link_3: create netlink socket ok.\\n&#8221;);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0return 0;<br \/>\n}<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p>static void netlink_exit(void)<br \/>\n{<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0if(nl_sk != NULL){<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0sock_release(nl_sk-&gt;sk_socket);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0}<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0printk(&#8220;my_net_link: self module exited\\n&#8221;);<br \/>\n}<\/wbr><\/wbr><\/wbr><\/p>\n<p>module_init(netlink_init);<br \/>\nmodule_exit(netlink_exit);<\/p>\n<p>MODULE_AUTHOR(&#8220;frankzfz&#8221;);<br \/>\nMODULE_LICENSE(&#8220;GPL&#8221;);<\/p>\n<p>&nbsp;<\/p>\n<p><strong>netlink_u.c\uff1a<\/strong><\/p>\n<p>#include &lt;sys\/stat.h&gt;<br \/>\n#include &lt;unistd.h&gt;<br \/>\n#include &lt;stdio.h&gt;<br \/>\n#include &lt;stdlib.h&gt;<br \/>\n#include &lt;sys\/socket.h&gt;<br \/>\n#include &lt;sys\/types.h&gt;<br \/>\n#include &lt;string.h&gt;<br \/>\n#include &lt;asm\/types.h&gt;<br \/>\n#include &lt;linux\/netlink.h&gt;<br \/>\n#include &lt;linux\/socket.h&gt;<br \/>\n#include &lt;errno.h&gt;<\/p>\n<p>#define NETLINK_TEST 25<br \/>\n#define MAX_PAYLOAD 1024 \/\/ maximum payload size<\/p>\n<p>int main(int argc, char* argv[])<br \/>\n{<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0int state;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0struct sockaddr_nl src_addr, dest_addr;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0struct nlmsghdr *nlh = NULL;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0struct iovec iov;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0struct msghdr msg;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0int sock_fd, retval;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0int state_smg = 0;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0\/\/ Create a socket<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_TEST);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0if(sock_fd == -1){<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0printf(&#8220;error getting socket: %s&#8221;, strerror(errno));<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0return -1;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0}<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0\/\/ To prepare binding<\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0memset(&amp;msg,0,sizeof(msg));<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0memset(&amp;src_addr, 0, sizeof(src_addr));<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0src_addr.nl_family = AF_NETLINK;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0src_addr.nl_pid = getpid(); \/\/ self pid<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0src_addr.nl_groups = 0; \/\/ multi cast<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0retval = bind(sock_fd, (struct sockaddr*)&amp;src_addr, sizeof(src_addr));<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0if(retval &lt; 0){<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0printf(&#8220;bind failed: %s&#8221;, strerror(errno));<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0close(sock_fd);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0return -1;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0}<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0\/\/ To prepare recvmsg<\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0if(!nlh){<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0printf(&#8220;malloc nlmsghdr error!\\n&#8221;);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0close(sock_fd);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0return -1;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0}<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0memset(&amp;dest_addr,0,sizeof(dest_addr));<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0dest_addr.nl_family = AF_NETLINK;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0dest_addr.nl_pid = 0;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0dest_addr.nl_groups = 0;<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0nlh-&gt;nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0nlh-&gt;nlmsg_pid = getpid();<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0nlh-&gt;nlmsg_flags = 0;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0strcpy(NLMSG_DATA(nlh),&#8221;Hello you!&#8221;);<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0iov.iov_base = (void *)nlh;<br \/>\n<wbr>\u00a0<wbr>\u00a0iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0\/\/ iov.iov_len = nlh-&gt;nlmsg_len;<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0memset(&amp;msg, 0, sizeof(msg));<br \/>\n<wbr>\u00a0<wbr><br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0msg.msg_name = (void *)&amp;dest_addr;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0msg.msg_namelen = sizeof(dest_addr);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0msg.msg_iov = &amp;iov;<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0msg.msg_iovlen = 1;<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0printf(&#8220;state_smg\\n&#8221;);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0state_smg = sendmsg(sock_fd,&amp;msg,0);<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0if(state_smg == -1)<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0{<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0printf(&#8220;get error sendmsg = %s\\n&#8221;,strerror(errno));<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0}<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0memset(nlh,0,NLMSG_SPACE(MAX_PAYLOAD));<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0printf(&#8220;waiting received!\\n&#8221;);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0\/\/ Read message from kernel<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0while(1){<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0printf(&#8220;In while recvmsg\\n&#8221;);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0state = recvmsg(sock_fd, &amp;msg, 0);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0if(state&lt;0)<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0{<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0printf(&#8220;state&lt;1&#8221;);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0}<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0printf(&#8220;In while\\n&#8221;);<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0printf(&#8220;Received message: %s\\n&#8221;,(char *) NLMSG_DATA(nlh));<br \/>\n<wbr>\u00a0<wbr>\u00a0<wbr>\u00a0}<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0close(sock_fd);<\/wbr><\/wbr><\/wbr><\/p>\n<p><wbr>\u00a0<wbr>\u00a0<wbr>\u00a0return 0;<br \/>\n}<\/wbr><\/wbr><\/wbr><\/p>\n<p>&nbsp;<\/p>\n<p><strong>makefile\uff1a<\/strong><\/p>\n<p>obj-m := netlink_k.o<br \/>\nKERNELBUILD := \/lib\/modules\/`uname -r`\/build<br \/>\ndefault:<br \/>\n<wbr>@echo &#8220;BUILE Kmod&#8221;<br \/>\n<wbr>@make -C $(KERNELBUILD) M=$(shell pwd) modules<br \/>\n<wbr>gcc -o netlink_u netlink_u.c<br \/>\nclean:<br \/>\n<wbr>@echo &#8221; CLEAN kmod&#8221;<br \/>\n<wbr>@rm -rf *.o<br \/>\n<wbr>@rm -rf .depend .*.cmd *.ko *.mod.c .tmp_versions *.symvers .*.d<\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/wbr><\/p>\n<p>&nbsp;<\/p>\n<p><strong>\u4e0b\u9762\u662f\u4f7f\u7528dmesg\u547d\u4ee4\u8f93\u51fa\u7684\u4fe1\u606f\uff1a<\/strong><\/p>\n<p>[873791.498039] my_net_link_3: create netlink socket ok.<\/p>\n<p>[873810.263676] Message received:Hello<\/p>\n<p>[873813.260848] my_net_link_4:send message &#8216;I am from kernel!&#8217;.<\/p>\n<p>[873816.260821] my_net_link_4:send message &#8216;I am from kernel!&#8217;.<\/p>\n<p>[873819.260860] my_net_link_4:send message &#8216;I am from kernel!&#8217;.<\/p>\n<p>[873822.260762] my_net_link_4:send message &#8216;I am from kernel!&#8217;.<\/p>\n<p>[873825.260883] my_net_link_4:send message &#8216;I am from kernel!&#8217;.<\/p>\n<p>[873828.260669] my_net_link_4:send message &#8216;I am from kernel!&#8217;.<\/p>\n<p>[873831.260714] my_net_link_4:send message &#8216;I am from kernel!&#8217;.<\/p>\n<p>[873834.260683] my_net_link_4:send message &#8216;I am from kernel!&#8217;.<\/p>\n<p>[873837.260666] my_net_link_4:send message &#8216;I am from kernel!&#8217;.<\/p>\n<p>[873840.260632] my_net_link_4:send message &#8216;I am from kernel!&#8217;.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>netlink_k.c\u4e3a\u5185\u6838\u7684\u7a7a\u95f4\u7684\u7a0b\u5e8f,netlink_u.c\u4e3a\u7528\u6237\u7684\u7a7a\u95f4\u7684\u7a0b\u5e8f\u3002\u7a0b\u5e8f\u6e90\u4ee3\u7801\u9644\u5728\u540e\u9762\uff1a \u00a0\u00a0\u00a0\u5148\u8fd0\u884c\u5185\u6838\u4ee3\u7801netlink_k.ko\uff0c\u4e5f\u5c31\u662f\u5728\u6267\u884c\u5b8cmakefile\u6587\u4ef6\u540e\uff0c\u4f1a\u751f\u6210\u4e00\u4e2anetlink_k.ko\u6587\u4ef6\uff0c\u53ef\u4ee5\u4f7f\u7528\u4e0b &hellip; <a href=\"http:\/\/www.menglanglang.cn\/?p=883\">\u7ee7\u7eed\u9605\u8bfb <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ai_generated_summary":"","wpai_meta_description":"","footnotes":""},"categories":[227],"tags":[602,261,282],"class_list":["post-883","post","type-post","status-publish","format-standard","hentry","category-linux","tag-linux","tag-261","tag-282"],"_links":{"self":[{"href":"http:\/\/www.menglanglang.cn\/index.php?rest_route=\/wp\/v2\/posts\/883","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.menglanglang.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.menglanglang.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.menglanglang.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.menglanglang.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=883"}],"version-history":[{"count":0,"href":"http:\/\/www.menglanglang.cn\/index.php?rest_route=\/wp\/v2\/posts\/883\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.menglanglang.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=883"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.menglanglang.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=883"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.menglanglang.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=883"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}