Theory:
http://blog.csdn.net/unbutun/article/details/3394061
Further in-depth:
http://edsionte.com/techblog/archives/4134
http://edsionte.com/techblog/archives/4140
http://edsionte.com/techblog/archives/4134
Practice:
Http://bbs.chinaunix.net/thread-3766684-1-1.html
Appendix Code:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include < fcntl.h> #include <errno.h> #include <string.h> #include <asm/types.h> #include <sys/socket.h > #include <linux/netlink.h> #include <linux/inet_diag.h> #include <netinet/tcp.h> #define Netlink_test 18#define max_payload 1024struct req {struct NLMSGHDR nlh;char [max_payload];}; void Eprint (int err_no, char *str, int line) {printf (' Error%d in line%d:%s () with%s\n ', err_no, line, str, strerror (ERRN o));} int main () {int sock_fd;sock_fd = socket (Pf_netlink, Sock_raw, Netlink_test), if (SOCK_FD < 0) {eprint (errno, "socket", _ _LINE__); return errno;} Binds the local socket to the source address struct sockaddr_nl src_addr;memset (&src_addr, 0, sizeof (SRC_ADDR)); src_addr.nl_family = Af_netlink ; src_addr.nl_pid = Getpid (); The Nl_pid field indicates the pidsrc_addr.nl_groups = 0;//nl_groups of the multicast group that sent the message. We're not involved in multicasting here. So the default feels 0if (bind (SOCK_FD, struct sockaddr *) &src_addr, siZeof (src_addr)) < 0) {eprint (errno, "bind", __line__); return errno;} After the socket has been bound. The user process finally sends the message of the MSGHDR structure, so the structure must be initialized,//and the MSGHDR structure is SOCKADDR_NL with the//initialization of the MSGHDR structure. Iovec and NLMSGHDR are three structures related. Therefore, these data structures must be initialized in turn/*struct msghdr {void*msg_name;//Socket nameintmsg_namelen;//length of namestruct Iovec *msg_iov;// Data blocks__kernel_size_tmsg_iovlen;//number of blocksvoid *msg_control;//Per protocol magic (eg BSD file descriptor pa ssing) __kernel_size_tmsg_controllen;//Length of cmsg list unsignedmsg_flags;}; *//*struct sockaddr_nl {__kernel_sa_family_tnl_family;//af_netlinkunsigned shortnl_pad;//zero__u32nl_pid;//port ID __u32nl_groups;//Multicast groups Mask};*/struct sockaddr_nl dest_addr;memset (&dest_addr, 0, sizeof (DEST_ADDR)); dest_addr.nl_family = Af_netlink;dest_addr.nl_pid = 0; That is, the nl_pid must be 0, which means the receiver is the kernel.dest_addr.nl_groups = 0; The req type of datagram is initialized. That is, the two data structures it encapsulates are initialized: struct req r;//itself defines the protocol data structure using NetLink for user process and kernel data interaction using R.nlh.nlmsg_len = Nlmsg_space (max_payload);/* The Nlmsg_len here is the sum of the +max_payload for sizeof (STRUCTNLMSGHDR).
Macro Nlmsg_space will take its own initiative to add the length of both # define NLMSG_LENGTH (len) (len) + nlmsg_hdrlen) #define NLMSG_SPACE (len) nlmsg_align (nlmsg_ LENGTH (len)) */r.nlh.nlmsg_pid = Getpid (); r.nlh.nlmsg_flags = 0;memset (r.buf, 0, Max_payload) strcpy (Nlmsg_data (& (R.NLH)), "Hello, I am edsionte!"); /#define NLMSG_DATA (NLH) ((void*) (((char*) NLH) + nlmsg_length (0))//Next initializes the buffer vector Iov, letting the Iov_base field point to the datagram structure, and IOV_ Len is the datagram length. struct Iovec iov;iov.iov_base = (void *) &r;iov.iov_len = sizeof (R);//When All is ready, bind the destination socket address with the message msg that is currently being sent and copy the destination socket address to MSG _name. The data to be sent Iov and Msg_iov bound, assuming that a///sex to send multiple packets, create an array of type Iovec.
struct MSGHDR msg;msg.msg_name = (void *) &dest_addr;msg.msg_namelen = sizeof (DEST_ADDR); Msg.msg_iov = &iov; Msg.msg_iovlen = 1;//. Send Message to Kernel if (sendmsg (sock_fd, &msg, 0) < 0) {eprint (errno, "sendmsg", __line__); return errno;} Receive messages from the kernel memset (&R.NLH, 0, Nlmsg_space (max_payload)), if (Recvmsg (sock_fd, &msg, 0) < 0) {Eprint (errno , "Recvmsg", __line__); return errno;} printf ("Received Message payload:%s\n", (char *) nlmsg_data (R.NLH)); close (SOCK_FD);}
Linux NetLink Socket Learning materials