NetLink Communication--The realization of user state and kernel state communication

Source: Internet
Author: User

http://blog.csdn.net/hustfoxy/article/details/8706275


This article mainly explains through the NetLink communication mechanism, realizes the user state and the kernel state data transmission concretely. Our kernel environment is version 2.6.35.6.

The </usr/include/linux/netlink.h> file contains predefined protocols that have been defined by the NetLink protocol cluster:

[CPP] View Plain copy #define  netlink_route           0        /* Routing/device hook                            */   #define  NETLINK_UNUSED           1       /* Unused number                                  */   #define  NETLINK_USERSOCK         2       /* Reserved for  user mode socket protocols      */   #define   Netlink_firewall &nbsP;      3       /* firewalling hook                               */   #define  netlink_inet_diag        4       /* inet socket  monitoring                        */   #define  NETLINK_NFLOG            5       /* netfilter/ iptables ulog */   #define  NETLINK_XFRM             6       /* ipsec */   # Define netlink_selinux         7       /*  selinux event notifications */   #define  NETLINK_ISCSI            8       /* open-iscsi * /   #define  netlink_audit           9        /* auditing */   #define  netlink_fib_lookup       10   #define  NETLINK_CONNECTOR        11   #define  NETLINK_NETFILTER       12       /* netfilter subsystem */   #define &NBSP;NETLINK_IP6_FW           13   #define  NETLINK_DNRTMSG     &nbsP;    14      /* decnet routing messages  */   #define  netlink_kobject_uevent  15      /*  Kernel messages to userspace */   #define  NETLINK_GENERIC          16  /* leave room for netlink_dm  (dm events)  */   #define  NETLINK_SCSITRANSPORT   18       /* SCSI Transports */   #define  NETLINK_ECRYPTFS         19      #define  NETLINK_MYTEST 20  

If we develop a new protocol in the NetLink protocol cluster, just define the protocol number in that file, for example, we define a custom protocol with a protocol number of 20 based on the NetLink protocol cluster, as shown above. At the same time remember, the kernel header file directory netlink.h also do the corresponding modification, in my system its path is:/usr/src/kernels/2.6.35.6-45.fc14.i686/include/linux/netlink.h

We can then use this protocol in the development of user space and kernel space modules, it should be explained that if you do not add the protocol number in these two files, you need to add the two protocol numbers in the specific communication implementation code file, which is used in my specific implementation.

User-State communication Code (MYNLUSR.C):

[CPP] View plain copy #include  <stdio.h>   #include  <stdlib.h>   #include   <sys/stat.h>   #include  <sys/socket.h>   #include  <sys/types.h>    #include  <sys/stat.h>   #include  <string.h>   #include  <linux/netlink.h>   #include  <linux/socket.h>      #define  NETLINK_MYTEST 20   #define  MAX_PAYLOAD 1024      int  Main (INT&NBSP;ARGC,&NBSP;CHAR&NBSP;**&NBSP;ARGV)    {       struct  sockaddr_nl src_addr,dest_addr;       struct nlmsghdr *nlh =  NULL;       struct msghdr msg;        struct iovec iov;       int sock_fd = -1;       /* Create socket */       if ( -1 ==  (sock_fd =  Socket (af_netlink,sock_raw,netlink_mytest)) {            printf ("Can ' t create netlink socket!\n");            return -1;       }       /* SET SRC_ADDR structure * *        memset (&src_addr, 0, sizeof (src_addr));        src_addr.nl_family = AF_NETLINK;       src_addr.nl_ Pid = getpid ()/* own pid*/       src_addr.nl_groups = 0;               /* bind sockets and NetLink address structures */        if ( -1 == bind sock_fd,  (struct sockaddr*) &src_addr, sizeof (src_ Addr)) {&NBsp;          printf ("Can" t bind sock_fd with  Sockaddr_nl ");           return -1;        }       if (null ==  nlh= (struct nlmsghdr*) malloc (Nlmsg_space (max_payload))) {           printf ("alloc mem failed!\n");            return -1;       }        memset (nlh, 0, max_payload);        /* Fill NetLink message head */       nlh->nlmsg_len = nlmsg_space (MAX_PAYLOAD);        nlh->nlmsg_pid = getpid ();        nlh->nlmsg_type = NLMSG_NOOP;       nlh->nlmsg_flags = 0;              /* Set message content for NetLink */       strcpy (Nlmsg_data (NLH),  argv[1]);               memset (&iov, 0, sizeof (IOV));        iov.iov_base =  (void *) nlh;       iov.iov_len =  nlh->nlmsg_len;              /* Settings dest_ Addr Structure */       memset (&dest_addr, 0, sizeof (dest_addr));        dest_addr.nl_family = AF_NETLINK;        dest_addr.nl_pid = 0;/* is the PID of the destination address, which is sent to the kernel */       dest_addr.nl_groups  = 0;              memset (&msg, 0 ,  sizeof (MSg);       msg.msg_name =  (void *) &dest_addr;       msg.msg_namelen = sizeof (dest_addr);        msg.msg_iov = &iov;       msg.msg_iovlen = 1;              /* sends messages through Netlink socket to the content */        sendmsg (sock_fd, &msg, 0);              /* accepts kernel messages */       printf ("Waiting message from  kernel!\n ");       memset ((char *) Nlmsg_data (NLH), 0,1024);       recvmsg (sock_fd,&msg,0);       printf ("response:%s\n" , Nlmsg_data (NLH));              /* Close netlink socket */    &Nbsp;   close (SOCK_FD);       free (NLH);        return 0;  }  

Kernel-State Communication Code (MYNLKERN.C):

[CPP] View plain copy #include  <linux/kernel.h>   #include  <linux/module.h>   # include <linux/moduleparam.h>   #include  <linux/skbuff.h>   #include  <linux/init.h>   #include  <linux/ip.h>   #include  <linux/ types.h>   #include  <linux/sched.h>   #include  <linux/netlink.h>    #include  <net/sock.h>   #include  <net/netlink.h>       #define  NETLINK_MYTEST 20   #define  MAX_MSGSIZE 1024   struct  sock *nl_sk = NULL;      static void sendnlmsg (char * Message, int dstpid)    {       struct sk_buff *skb;        struct nlmsghdr *nlh;       int  len = nlmsg_space (max_msgsize);       int slen = 0;        if (!message | |  !nl_sk) {           return ;        }       /* for the new Sk_buffer application space */       &NBSP;SKB&NBSP;=&NBSP;ALLOC_SKB (Len,gfp_kernel);       if (!SKB) {   &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;PRINTK (kern_err  "my_net_link:alloc_skb error!\n");            return ;       }        slen = strlen (message);               /* use Nlmsg_put to set NetLink message head */       nlh =  nlmsg_put (skb,0,0,0,max_msgsize,0);   &NBSP;&NBSP;&NBSP;&NBSP;&NBsp;      /* Set the NetLink control block */   &NBSP;&NBSP;&NBSP;&NBSP;NETLINK_CB (SKB). PID  = 0;/* the ID of the sender of the message, if it is issued within the 0*/   &NBSP;&NBSP;&NBSP;&NBSP;NETLINK_CB (SKB). dst_group =  0;/* If the purpose of the group is the kernel or a process, the field 0*/               message[slen] =  ';   '     memcpy (Nlmsg_data (NLH), message,slen+1);               /* sends messages to user space via Netlink_unicast */    &NBSP;&NBSP;&NBSP;&NBSP;PRINTK ("kernel:begin send\n");       netlink_ Unicast (nl_sk,skb,dstpid,0);       printk ("kernel:send ok!\n");       return ;  }      Static void nl_data_ready ( STRUCT&NBSP;SK_BUFF*&NBSP;SKB)    {       struct nlmsghdr *nlh;       u64 rlen;       void *data;               while (skb->len >= nlmsg_space (0)) {    &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;NLH&NBSP;=&NBSP;NLMSG_HDR (SKB);      &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;PRINTK ("Nlh->nlmsg_pid=%u skb->len =%d nlmsg_space" (0) =%d\n ", Nlh->nlmsg_pid,skb->len,nlmsg_space (0));            if (nlh->nlmsg_len < nlmsg_hdrlen | |  skb->len < nlh->nlmsg_len)                 return ;                       rlen = nlmsg_align (Nlh->nlmsg_len);            if (rlen&Nbsp;> skb->len)                 rlen = skb->len;                      data = nlmsg_data (NLH);      &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;PRINTK ("received netlink message: %s\n", (char *) data);            skb_pull (skb, rlen);                       sendnlmsg (" Send from kernel ", nlh->nlmsg_pid);       }      &NBSP;&NBSP;PRINTK ("received finished!\n");  }      static int __ Init myinit_module (void)    {       printk ("my netlink in! \ n ");       nl_sk = netlink_kernel_create (&init_net, netlink_mytest, 0,  nl_data_ready, null, this_module);       if (!nl_sk) {   &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;PRINTK (kern_err  "My_net_link: create netlink  socket error!\n ");           return 1;        }else{           return 0;        }  }      static void __exit  Myexit_module (void)    {       printk ("my netlink out!\n");        if (nl_sk != null) {            sock_release (nl_sk->sk_socket);       }  }     &nbsp Module_author ("Fang xieyun");   module_license ("GPL");      Module_init (myinit _module);   module_exit (myexit_module); 


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.