How to Use netlink in kernel 2.6.24 or later

Source: Internet
Author: User
Tags sendmsg

 

How to Use netlink in kernel 2.6.24 or later

Test environment: 2.6.28

Netlink has greatly changed in different versions of the 2.6 kernel. For details, refer to (note that the version number is not necessarily accurate ):

Http://blog.csdn.net/sealyao/archive/2009/10/02/4628141.aspx

 

0. Summary

The basic procedure is as follows:

Run the netlink kernel module;

Run the user-State program, send a connection message to the kernel, and notify the kernel's process id;

The kernel receives user messages and records the process id;

The kernel sends a netlink message to the user process id;

The user receives the netlink message sent by the kernel.

 

1. kernel Section

1.1 Related Data Structure Variables:

44 // --------- These are for netlink --------- // <br/> 45 # define NETLINK_REALNET 26 <br/> 46 struct sock * g_nl_sk = NULL; <br/> 48 struct sockaddr_nl src_addr, dest_addr; <br/> 50 struct iovec iov; <br/> 52 int pid; <br/> 53 struct msghdr msg; <br/> 55 //-----------------------------------------//
 

 

45 # define NETLINK_REALNET 26
 

Define the protocol family. This variable is used in the netlink_kernel_create function.

In kernel 2.6.28, netlink defines 20 protocols, each of which uses a unique integer identifier. A user program can define any 20 protocols other than the Protocol and identify them with a unique integer.

46 struct sock * g_nl_sk = NULL;

Sock data structure, which uniquely identifies the sock used by netlink, similar to sock in general socket programming.

48 struct sockaddr_nl src_addr, dest_addr;

Identifies the source address and destination address of netlink sock.

50 struct iovec iov;

The data structure used to receive and send netlink data.

53 struct msghdr msg;

Netlink message header.

 

1.2 call Process

1.2.1 create netlink socket

G_nl_sk = netlink_kernel_create (& init_net, NETLINK_REALNET, 0, nl_data_r eady, NULL, THIS_MODULE); <br/>

1.2.2 implement the callback function nl_data_ready

The following callback function is called by the system when netlink receives the complete NETLINK_REALNET packet. This function receives and determines the netlink message. If the first character is H, the process Number of the sender of the message is saved to send data packets to the process, then clear the contact with the process.

185 void nl_data_ready (struct sk_buff * _ skb) <br/> 186 {<br/> 187 struct sk_buff * skb; <br/> 188 struct nlmsghdr * nlh; <br/> 189 char str [100]; <br/> 190 <br/> 191 skb = skb_get (_ skb ); <br/> 192 <br/> 193 if (skb-> len> = NLMSG_SPACE (0 )) <br/> 194 {<br/> 195 nlh = nlmsg_hdr (skb); <br/> 196 <br/> 197 memcpy (str, NLMSG_DATA (nlh ), sizeof (str); <br/> 198 // dbuplint ("Message received ed: % s/n", str ); <br/> 199 <br/> 200 // H stands for Hello message. <br/> 201 if (str [0] = 'H') <br/> 202 {<br/> 203 pid = nlh-> nlmsg_pid; <br/> 204 u_connected = 1; <br/> 205 // sendnlmsg ("Hello reply. "); <br/> 206} <br/> 207 // E stands for Exit message <br/> 208 else if (str [0] = 'E ') <br/> 209 {<br/> 210 u_connected = 0; <br/> 211 pid = 0; <br/> 212} <br/> 213 kfree_skb (skb ); <br/> 214} <br/> 215}
 

191 skb = skb_get (_ skb );

Obtain the actual data packet.

The parameter of this function is the first address of the netlink packet, while sk_buff is the data structure used by the network protocol stack. There are slight differences between the two.

195 nlh = nlmsg_hdr (skb );

Obtain the starting address of the netlink header in The netlink packet.

197 memcpy (str, NLMSG_DATA (nlh), sizeof (str ));

Copy the data area of the netlink data packet to str. NLMSG_DATA (nlh) returns the data zone address. Macro definition reference:

Http://blog.csdn.net/wangjingfei/archive/2010/02/04/5288263.aspx

213 kfree_skb (skb );

Release received messages.

 

1.2.3 send netlink messages to user processes

The parameters of the following function are the sk_buff data packets captured by netfilter. The objective is to send the packets to user-State processes through netlink.

247 void send_to_user (struct sk_buff * skb) <br/> 248 {<br/> 249 struct iphdr * iph; <br/> 250 struct ethhdr * ehdr; <br/> 251 <br/> 252 struct nlmsghdr * nlh; <br/> 253 <br/> 254 struct sk_buff * nl_skb; <br/> 255 <br/> 256 // dbuplint ("Send packages to user/n "); <br/> 257 <br/> 258 if (skb = NULL) <br/> 259 {<br/> 260 return; <br/> 261} <br/> 262 if (! G_nl_sk) <br/> 263 {<br/> 264 return; <br/> 265} <br/> 266 if (pid = 0) <br/> 267 {<br/> 268 return; <br/> 269} <br/> 270 <br/> 271 nl_skb = alloc_skb (NLMSG_SPACE (1514 ), GFP_ATOMIC); <br/> 272 // nl_skb = alloc_skb (NLMSG_SPACE (0), GFP_ATOMIC); <br/> 273 if (nl_skb = NULL) <br/> 274 {<br/> 275 // allocate failed. <br/> 276 return; <br/> 277} <br/> 278 <br/> 279 ehdr = eth_hdr (skb ); <br/> 280 iph = ip_hdr (skb); <br/> 281 <br/> 282 nlh = nlmsg_put (nl_skb, 0, 0, 0, NLMSG_SPACE (1514) -sizeof (struct nlmsghdr), 0); <br/> 283 NETLINK_CB (nl_skb ). pid = 0; <br/> 284 <br/> 285 // dbuplint ("Data length: % d, len = % d/n", htons (iph-> tot_len) + ETH_HLEN, NLMSG_SPACE (1514); <br/> 286 <br/> 287 // Copy data to nlh <br/> 288 memcpy (NLMSG_DATA (nlh ), (char *) ehdr, htons (iph-> tot_len) + ETH_HLEN); <br/> 289 <br/> 290 netlink_unicast (g_nl_sk, nl_skb, pid, MSG_DONTWAIT ); <br/> 291}
 

247 void send_to_user (struct sk_buff * skb)

The skb parameter is the packet captured by netfilter, not the netlink packet. This is the data transmission of netlink.

271 nl_skb = alloc_skb (NLMSG_SPACE (1514), GFP_ATOMIC );

Apply for space for sending data packets. The size of the spatial data zone is 1514, that is, the maximum length of ethernet data packets. NLMSG_SPACE (1514) returns the size of the netlink packet whose data area size is 1514. For details, refer:

Http://blog.csdn.net/wangjingfei/archive/2010/02/04/5288263.aspx

282 nlh = nlmsg_put (nl_skb, 0, 0, 0, NLMSG_SPACE (1514)-sizeof (struct nlmsghdr), 0 );

Fill in the netlink data header.

283 NETLINK_CB (nl_skb). pid = 0;

Determine the process number of the sent data packet. 0 indicates the kernel process. For the macro definition, see:

Http://blog.csdn.net/wangjingfei/archive/2010/02/04/5288263.aspx

290 netlink_unicast (g_nl_sk, nl_skb, pid, MSG_DONTWAIT );

Send data packets in non-blocking mode. Note: After data packets are sent, the data space pointed to by nl_skb will be cleared. The next time you send data packets, you must call alloc_skb again to allocate space. Otherwise, the kernel will crash and you must restart it.

 

1.2.4 release netlink socket

After netlink is used, you must call sock_release. Otherwise

45 # define NETLINK_REALNET 26

The specified Protocol number is no longer available. The Code is as follows:

239 void destory_netlink (void) <br/> 240 {<br/> 241 if (g_nl_sk! = NULL) <br/> 242 {<br/> 243 sock_release (g_nl_sk-> sk_socket); <br/> 244} <br/> 245}
 

 

2. User State Program

2.1 Related Data Structure

28 // ---------------- for Netlink -------------- // <br/> 29 struct sockaddr_nl nl_src_addr, nl_dest_addr; <br/> 30 struct nlmsghdr * NlH = NULL; <br/> 31 struct iovec IOV; <br/> 32 int nl_fd; <br/> 33 struct msghdr nl_msg; <br/> 34 //-------------------------------------------//
 

Similar to the kernel-state data structure, we will not repeat it here.

 

2.2 running process

2.2.1 initialize netlink

114 void init_nl () <br/> 115 {<br/> 116 nl_fd = socket (pf_netlink, sock_raw, netlink_realnet); <br/> 117 memset (& nl_msg, 0, sizeof (nl_msg); <br/> 118 memset (& nl_src_addr, 0, sizeof (nl_src_addr); <br/> 119 nl_src_addr.nl_family = af_netlink; <br/> 120 nl_src_addr.nl_pid = getpid (); <br/> 121 nl_src_addr.nl_groups = 0; <br/> 122 <br/> 123 BIND (nl_fd, (struct sockaddr *) & nl_src_addr, sizeof (nl_src_addr); <br/> 124 memset (& nl_dest_addr, 0, sizeof (nl_dest_addr); <br/> 125 conflict = af_netlink; <br/> 126 nl_dest_addr.nl_pid = 0;/* for Linux kernel */<br/> 127 nl_dest_addr.nl_groups = 0; /* unicast */<br/> 128 <br/> 129 sendnlmsg ("H"); <br/> 130 <br/> 131 memset (NLH, 0, nlmsg_space (max_payload); <br/> 132}
 

116 nl_fd = socket (pf_netlink, sock_raw, netlink_realnet );

Create a user's netlink socket. The method for creating a socket is the same as that for a common socket. The protocol family is PF_NETLINK and the protocol type is user-defined NETLINK_REALNET, which is the same as the kernel state definition.

117 memset (& nl_msg, 0, sizeof (nl_msg ));

Clear netlink data packets.

118-127 rows

Similar to the initialization of a common socket, you can refer to socket programming if you are not familiar with it. Note that the data structure of nl_src_addr is somewhat different from that of a common socket.

129 sendnlmsg ("H ");

Sends a Hello Message to the kernel process to notify the kernel of its process id.

 

2.2.2 send messages to the kernel

The following function creates and sends a netlink message to the kernel process.

36 void sendnlmsg (const char * message) <br/> 37 {<br/> 38 printf ("Sending: % s/n", message ); <br/> 39 nlh = (struct nlmsghdr *) malloc (NLMSG_SPACE (MAX_PAYLOAD); <br/> 40 nlh-> nlmsg_len = NLMSG_SPACE (MAX_PAYLOAD ); <br/> 41 nlh-> nlmsg_pid = getpid (); <br/> 42 nlh-> nlmsg_flags = 0; <br/> 43 <br/> 44 strcpy (char *) NLMSG_DATA (nlh), message); <br/> 45 <br/> 46 iov. iov_base = (void *) nlh; <br/> 47 iov. iov_len = nlh-> nlmsg_len; <br/> 48 nl_msg.msg_name = (void *) & nl_dest_addr; <br/> 49 nl_msg.msg_namelen = sizeof (nl_dest_addr ); <br/> 50 nl_msg.msg_iov = & iov; <br/> 51 nl_msg.msg_iovlen = 1; <br/> 52 <br/> 53 printf ("Start to send message. "); <br/> 54 sendmsg (nl_fd, & nl_msg, 0); <br/> 55 printf (" Sending finishes. /n "); <br/> 56}
 

39 nlh = (struct nlmsghdr *) malloc (NLMSG_SPACE (MAX_PAYLOAD ));

Allocate storage space for netlink headers. MAX_PAYLOAD is defined by the user and is the maximum length of data sent (user.

40-51 rows

Specify parameters related to netlink and prepare to send messages.

54 sendmsg (nl_fd, & nl_msg, 0 );

The netlink packet is sent to the kernel process. It is used in the same way as the sendmsg message in a common socket. The last parameter 0 indicates the non-blocking mode. For more information, see socket programming.

 

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.