<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> <title>libnl: Core Netlink API</title> <link href="tabs.css" rel="stylesheet" type="text/css"/> <link href="doxygen.css" rel="stylesheet" type="text/css"/> </head> <body> <!-- Generated by Doxygen 1.7.3 --> <div id="top"> <div id="titlearea"> <table cellspacing="0" cellpadding="0"> <tbody> <tr style="height: 56px;"> <td style="padding-left: 0.5em;"> <div id="projectname">libnl <span id="projectnumber">1.1</span></div> </td> </tr> </tbody> </table> </div> <div id="navrow1" class="tabs"> <ul class="tablist"> <li><a href="index.html"><span>Main Page</span></a></li> <li><a href="modules.html"><span>Modules</span></a></li> <li><a href="annotated.html"><span>Data Structures</span></a></li> <li><a href="files.html"><span>Files</span></a></li> </ul> </div> </div> <div class="header"> <div class="summary"> <a href="#nested-classes">Data Structures</a> | <a href="#groups">Modules</a> </div> <div class="headertitle"> <h1>Core Netlink API</h1> </div> </div> <div class="contents"> <table class="memberdecls"> <tr><td colspan="2"><h2><a name="nested-classes"></a> Data Structures</h2></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="structsockaddr__nl.html">sockaddr_nl</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Netlink socket address. <a href="structsockaddr__nl.html#_details">More...</a><br/></td></tr> <tr><td colspan="2"><h2><a name="groups"></a> Modules</h2></td></tr> <tr><td class="memItemLeft" align="right" valign="top"> </td><td class="memItemRight" valign="bottom"><a class="el" href="group__cb.html">Callbacks/Customization</a></td></tr> <p><tr><td class="mdescLeft"> </td><td class="mdescRight"><p>Callbacks and overwriting capabilities are provided to take influence in various control flows inside the library. </p> <br/></td></tr> </p> <tr><td class="memItemLeft" align="right" valign="top"> </td><td class="memItemRight" valign="bottom"><a class="el" href="group__msg.html">Messages</a></td></tr> <p><tr><td class="mdescLeft"> </td><td class="mdescRight"><p>Netlink Message Construction/Parsing Interface. </p> <br/></td></tr> </p> <tr><td class="memItemLeft" align="right" valign="top"> </td><td class="memItemRight" valign="bottom"><a class="el" href="group__socket.html">Socket</a></td></tr> <p><tr><td class="mdescLeft"> </td><td class="mdescRight"><p>Handle representing a netlink socket. </p> <br/></td></tr> </p> <tr><td colspan="2"><h2><a name="member-group"></a> Connection Management</h2></td></tr> <tr><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__nl.html#ga68655d7fa8bd1944bec4761c95e576e9">nl_connect</a> (struct nl_handle *handle, int protocol)</td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Create and connect netlink socket. <a href="#ga68655d7fa8bd1944bec4761c95e576e9"></a><br/></td></tr> <tr><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__nl.html#ga25039e93db5ab64ce4345ffe14379530">nl_close</a> (struct nl_handle *handle)</td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Close/Disconnect netlink socket. <a href="#ga25039e93db5ab64ce4345ffe14379530"></a><br/></td></tr> <tr><td colspan="2"><h2><a name="member-group"></a> Send</h2></td></tr> <tr><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__nl.html#ga53ee384f123fa3c354ad43adb6cf647d">nl_sendto</a> (struct nl_handle *handle, void *buf, size_t size)</td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Send raw data over netlink socket. <a href="#ga53ee384f123fa3c354ad43adb6cf647d"></a><br/></td></tr> <tr><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__nl.html#gaf3dca993337ed2d60a42269eaab65585">nl_sendmsg</a> (struct nl_handle *handle, struct nl_msg *msg, struct msghdr *hdr)</td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Send netlink message with control over sendmsg() message header. <a href="#gaf3dca993337ed2d60a42269eaab65585"></a><br/></td></tr> <tr><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__nl.html#ga5f3fff85c39f18946100c85f09d2c41c">nl_send</a> (struct nl_handle *handle, struct nl_msg *msg)</td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Send netlink message. <a href="#ga5f3fff85c39f18946100c85f09d2c41c"></a><br/></td></tr> <tr><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__nl.html#ga01a2aad82350f867e704d5c696438b60">nl_send_auto_complete</a> (struct nl_handle *handle, struct nl_msg *msg)</td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Send netlink message and check & extend header values as needed. <a href="#ga01a2aad82350f867e704d5c696438b60"></a><br/></td></tr> <tr><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__nl.html#ga73ed88a505f2d67bcf328183fe1e692a">nl_send_simple</a> (struct nl_handle *handle, int type, int flags, void *buf, size_t size)</td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Send simple netlink message using <a class="el" href="group__nl.html#ga01a2aad82350f867e704d5c696438b60" title="Send netlink message and check & extend header values as needed.">nl_send_auto_complete()</a> <a href="#ga73ed88a505f2d67bcf328183fe1e692a"></a><br/></td></tr> <tr><td colspan="2"><h2><a name="member-group"></a> Receive</h2></td></tr> <tr><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__nl.html#ga060acc8371fdb242c5ae3d5b761d28e1">nl_recv</a> (struct nl_handle *handle, struct <a class="el" href="structsockaddr__nl.html">sockaddr_nl</a> *nla, unsigned char **buf, struct ucred **creds)</td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Receive data from netlink socket. <a href="#ga060acc8371fdb242c5ae3d5b761d28e1"></a><br/></td></tr> <tr><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__nl.html#ga1bb066e1772b89f79fe1d76a4ef243a6">nl_recvmsgs</a> (struct nl_handle *handle, struct nl_cb *cb)</td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Receive a set of messages from a netlink socket. <a href="#ga1bb066e1772b89f79fe1d76a4ef243a6"></a><br/></td></tr> <tr><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__nl.html#gab287fc77c46d80c4e22bc87494cbf853">nl_recvmsgs_default</a> (struct nl_handle *handle)</td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Receive a set of message from a netlink socket using handlers in nl_handle. <a href="#gab287fc77c46d80c4e22bc87494cbf853"></a><br/></td></tr> <tr><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__nl.html#gaa65fec588e0a0a2de1881fb8366ccd79">nl_wait_for_ack</a> (struct nl_handle *handle)</td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Wait for ACK. <a href="#gaa65fec588e0a0a2de1881fb8366ccd79"></a><br/></td></tr> <tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><b>NL_CB_CALL</b>(cb, type, msg)</td></tr> </table> <hr/><a name="_details"></a><h2>Detailed Description</h2> <dl class="user"><dt><b>Receiving Semantics</b></dt><dd><div class="fragment"><pre class="fragment"> <a class="code" href="group__nl.html#gab287fc77c46d80c4e22bc87494cbf853" title="Receive a set of message from a netlink socket using handlers in nl_handle.">nl_recvmsgs_default</a>(socket) | | cb = nl_socket_get_cb(socket) v <a class="code" href="group__nl.html#ga1bb066e1772b89f79fe1d76a4ef243a6" title="Receive a set of messages from a netlink socket.">nl_recvmsgs</a>(socket, cb) | [Application provides <a class="code" href="group__nl.html#ga1bb066e1772b89f79fe1d76a4ef243a6" title="Receive a set of messages from a netlink socket.">nl_recvmsgs</a>() replacement] |- - - - - - - - - - - - - - - v | cb->cb_recvmsgs_ow() | | [Application provides <a class="code" href="group__nl.html#ga060acc8371fdb242c5ae3d5b761d28e1" title="Receive data from netlink socket.">nl_recv</a>() replacement] +-------------->|- - - - - - - - - - - - - - - v | <a class="code" href="group__nl.html#ga060acc8371fdb242c5ae3d5b761d28e1" title="Receive data from netlink socket.">nl_recv</a>() cb->cb_recv_ow() | +----------->|<- - - - - - - - - - - - - - -+ | | v | | Parse Message | | |- - - - - - - - - - - - - - - v | | | <a class="code" href="group__cb.html#gga3f60f4515ada826d2bf16395ee722363a160d69995bab2c325bd25d7ee2d5292d" title="Called for every message received.">NL_CB_MSG_IN</a>() | | |<- - - - - - - - - - - - - - -+ | | | | | |- - - - - - - - - - - - - - - v | | Sequence Check <a class="code" href="group__cb.html#gga3f60f4515ada826d2bf16395ee722363ae73e906b997f00e8911b09e0f254364d" title="Called instead of internal sequence number checking.">NL_CB_SEQ_CHECK</a>() | | |<- - - - - - - - - - - - - - -+ | | | | | |- - - - - - - - - - - - - - - v [ <a class="code" href="group__msg.html#ga67d5b6ba8714b97d74df72d119351bee" title="Request for an acknowledgment on success.">NLM_F_ACK</a> is set ] | | | <a class="code" href="group__cb.html#gga3f60f4515ada826d2bf16395ee722363af2930b7775d1444c359cd11d7ce2cd02" title="Sending of an acknowledge message has been requested.">NL_CB_SEND_ACK</a>() | | |<- - - - - - - - - - - - - - -+ | | | | | +-----+------+--------------+----------------+--------------+ | | v v v v v | | Valid Message ACK NOOP Message End of Multipart Error Message | | | | | | | | | v v v v v | |<a class="code" href="group__cb.html#gga3f60f4515ada826d2bf16395ee722363a6e1f371d16186a460f25ea9bb1306c47" title="Message is valid.">NL_CB_VALID</a>() <a class="code" href="group__cb.html#gga3f60f4515ada826d2bf16395ee722363a8295b387c07bd076ccdee45b555f1134" title="Message is an acknowledge.">NL_CB_ACK</a>() <a class="code" href="group__cb.html#gga3f60f4515ada826d2bf16395ee722363a034ec83d5ba891deb3d3e54f9e15d3a0" title="Message wants to be skipped.">NL_CB_SKIPPED</a>() <a class="code" href="group__cb.html#gga3f60f4515ada826d2bf16395ee722363a044400d11ee451b692333a0d95cf3d32" title="Last message in a series of multi part messages received.">NL_CB_FINISH</a>() cb->cb_err() | | | | | | | | | +------------+--------------+----------------+ v | | | (FAILURE) | | | [Callback returned <a class="code" href="group__cb.html#gga0c50cb29c507b3d7e8bc7d76c74675f8af77d78aac004c6d4bee57741d3a295ae" title="Skip this message.">NL_SKIP</a>] | | [More messages to be parsed] |<----------- | +----------------------------------| | | | [Multipart message] | +-------------------------------------| [Callback returned <a class="code" href="group__cb.html#gga0c50cb29c507b3d7e8bc7d76c74675f8aa87c4bfa1b41e2e06286a412dc2bc17b" title="Stop parsing altogether and discard remaining messages.">NL_STOP</a>] |<----------- v (SUCCESS) At any time: Message Format Error |- - - - - - - - - - - - v v <a class="code" href="group__cb.html#gga3f60f4515ada826d2bf16395ee722363af5b5448bf122561db88d510e5d153a8a" title="Message is malformed and invalid.">NL_CB_INVALID</a>() (FAILURE) Message Overrun (Kernel Lost Data) |- - - - - - - - - - - - v v <a class="code" href="group__cb.html#gga3f60f4515ada826d2bf16395ee722363a25c8376dc758b16bcaeb76c329719dae" title="Report received that data was lost.">NL_CB_OVERRUN</a>() (FAILURE) Callback returned negative error code (FAILURE) </pre></div></dd></dl> <dl class="user"><dt><b>Sending Semantics</b></dt><dd><div class="fragment"><pre class="fragment"> <a class="code" href="group__nl.html#ga01a2aad82350f867e704d5c696438b60" title="Send netlink message and check &amp; extend header values as needed.">nl_send_auto_complete</a>() | | Automatically fill in PID and/or sequence number | | [Application provides <a class="code" href="group__nl.html#ga5f3fff85c39f18946100c85f09d2c41c" title="Send netlink message.">nl_send</a>() replacement] |- - - - - - - - - - - - - - - - - - - - v v cb->cb_send_ow() <a class="code" href="group__nl.html#ga5f3fff85c39f18946100c85f09d2c41c" title="Send netlink message.">nl_send</a>() | Add destination address and credentials v <a class="code" href="group__nl.html#gaf3dca993337ed2d60a42269eaab65585" title="Send netlink message with control over sendmsg() message header.">nl_sendmsg</a>() | Set source address | |- - - - - - - - - - - - - - - - - - - - v | <a class="code" href="group__cb.html#gga3f60f4515ada826d2bf16395ee722363a0b43ab5eccae67470bb8ed0b09e2f650" title="Called for every message sent out except for nl_sendto()">NL_CB_MSG_OUT</a>() |<- - - - - - - - - - - - - - - - - - - -+ v sendmsg() </pre></div></dd></dl> <dl class="user"><dt><b>1) Connecting the socket</b></dt><dd><div class="fragment"><pre class="fragment"> <span class="comment">// Bind and connect the socket to a protocol, NETLINK_ROUTE in this example.</span> <a class="code" href="group__nl.html#ga68655d7fa8bd1944bec4761c95e576e9" title="Create and connect netlink socket.">nl_connect</a>(handle, NETLINK_ROUTE); </pre></div></dd></dl> <dl class="user"><dt><b>2) Sending data</b></dt><dd><div class="fragment"><pre class="fragment"> <span class="comment">// The most rudimentary method is to use nl_sendto() simply pushing</span> <span class="comment">// a piece of data to the other netlink peer. This method is not</span> <span class="comment">// recommended.</span> <span class="keyword">const</span> <span class="keywordtype">char</span> buf[] = { 0x01, 0x02, 0x03, 0x04 }; <a class="code" href="group__nl.html#ga53ee384f123fa3c354ad43adb6cf647d" title="Send raw data over netlink socket.">nl_sendto</a>(handle, buf, <span class="keyword">sizeof</span>(buf)); <span class="comment">// A more comfortable interface is nl_send() taking a pointer to</span> <span class="comment">// a netlink message.</span> <span class="keyword">struct </span>nl_msg *msg = my_msg_builder(); <a class="code" href="group__nl.html#ga5f3fff85c39f18946100c85f09d2c41c" title="Send netlink message.">nl_send</a>(handle, <a class="code" href="group__msg.html#gaa5f29579d86d2bdab26c312b44b56de7" title="Return actual netlink message.">nlmsg_hdr</a>(msg)); <span class="comment">// nl_sendmsg() provides additional control over the sendmsg() message</span> <span class="comment">// header in order to allow more specific addressing of multiple peers etc.</span> <span class="keyword">struct </span>msghdr hdr = { ... }; <a class="code" href="group__nl.html#gaf3dca993337ed2d60a42269eaab65585" title="Send netlink message with control over sendmsg() message header.">nl_sendmsg</a>(handle, <a class="code" href="group__msg.html#gaa5f29579d86d2bdab26c312b44b56de7" title="Return actual netlink message.">nlmsg_hdr</a>(msg), &hdr); <span class="comment">// You're probably too lazy to fill out the netlink pid, sequence number</span> <span class="comment">// and message flags all the time. nl_send_auto_complete() automatically</span> <span class="comment">// extends your message header as needed with an appropriate sequence</span> <span class="comment">// number, the netlink pid stored in the netlink handle and the message</span> <span class="comment">// flags NLM_F_REQUEST and NLM_F_ACK</span> <a class="code" href="group__nl.html#ga01a2aad82350f867e704d5c696438b60" title="Send netlink message and check &amp; extend header values as needed.">nl_send_auto_complete</a>(handle, <a class="code" href="group__msg.html#gaa5f29579d86d2bdab26c312b44b56de7" title="Return actual netlink message.">nlmsg_hdr</a>(msg)); <span class="comment">// Simple protocols don't require the complex message construction interface</span> <span class="comment">// and may favour nl_send_simple() to easly send a bunch of payload</span> <span class="comment">// encapsulated in a netlink message header.</span> <a class="code" href="group__nl.html#ga73ed88a505f2d67bcf328183fe1e692a" title="Send simple netlink message using nl_send_auto_complete()">nl_send_simple</a>(handle, MY_MSG_TYPE, 0, buf, <span class="keyword">sizeof</span>(buf)); </pre></div></dd></dl> <dl class="user"><dt><b>3) Receiving data</b></dt><dd><div class="fragment"><pre class="fragment"> <span class="comment">// nl_recv() receives a single message allocating a buffer for the message</span> <span class="comment">// content and gives back the pointer to you.</span> <span class="keyword">struct </span><a class="code" href="structsockaddr__nl.html" title="Netlink socket address.">sockaddr_nl</a> peer; <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *msg; <a class="code" href="group__nl.html#ga060acc8371fdb242c5ae3d5b761d28e1" title="Receive data from netlink socket.">nl_recv</a>(handle, &peer, &msg); <span class="comment">// nl_recvmsgs() receives a bunch of messages until the callback system</span> <span class="comment">// orders it to state, usually after receving a compolete multi part</span> <span class="comment">// message series.</span> <a class="code" href="group__nl.html#ga1bb066e1772b89f79fe1d76a4ef243a6" title="Receive a set of messages from a netlink socket.">nl_recvmsgs</a>(handle, my_callback_configuration); <span class="comment">// nl_recvmsgs_default() acts just like nl_recvmsg() but uses the callback</span> <span class="comment">// configuration stored in the handle.</span> <a class="code" href="group__nl.html#gab287fc77c46d80c4e22bc87494cbf853" title="Receive a set of message from a netlink socket using handlers in nl_handle.">nl_recvmsgs_default</a>(handle); <span class="comment">// In case you want to wait for the ACK to be recieved that you requested</span> <span class="comment">// with your latest message, you can call nl_wait_for_ack()</span> <a class="code" href="group__nl.html#gaa65fec588e0a0a2de1881fb8366ccd79" title="Wait for ACK.">nl_wait_for_ack</a>(handle); </pre></div></dd></dl> <dl class="user"><dt><b>4) Closing</b></dt><dd><div class="fragment"><pre class="fragment"> <span class="comment">// Close the socket first to release kernel memory</span> <a class="code" href="group__nl.html#ga25039e93db5ab64ce4345ffe14379530" title="Close/Disconnect netlink socket.">nl_close</a>(handle); </pre></div> </dd></dl> <hr/><h2>Define Documentation</h2> <a class="anchor" id="ga8692eaac9695251616b5a826ebc23b70"></a><!-- doxytag: member="nl.c::NL_CB_CALL" ref="ga8692eaac9695251616b5a826ebc23b70" args="(cb, type, msg)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">#define NL_CB_CALL</td> <td>(</td> <td class="paramtype"> </td> <td class="paramname">cb, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype"> </td> <td class="paramname">type, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype"> </td> <td class="paramname">msg </td> </tr> <tr> <td></td> <td>)</td> <td></td><td></td> </tr> </table> </div> <div class="memdoc"> <b>Value:</b><div class="fragment"><pre class="fragment"><span class="keywordflow">do</span> { \ err = nl_cb_call(cb, type, msg); \ <span class="keywordflow">switch</span> (err) { \ <span class="keywordflow">case</span> <a class="code" href="group__cb.html#gga0c50cb29c507b3d7e8bc7d76c74675f8abce22d25ef3e2fed30f22f8bc27fc8f0" title="Proceed with wathever would come next.">NL_OK</a>: \ err = 0; \ <span class="keywordflow">break</span>; \ <span class="keywordflow">case</span> <a class="code" href="group__cb.html#gga0c50cb29c507b3d7e8bc7d76c74675f8af77d78aac004c6d4bee57741d3a295ae" title="Skip this message.">NL_SKIP</a>: \ <span class="keywordflow">goto</span> skip; \ <span class="keywordflow">case</span> <a class="code" href="group__cb.html#gga0c50cb29c507b3d7e8bc7d76c74675f8aa87c4bfa1b41e2e06286a412dc2bc17b" title="Stop parsing altogether and discard remaining messages.">NL_STOP</a>: \ <span class="keywordflow">goto</span> stop; \ <span class="keywordflow">default</span>: \ <span class="keywordflow">goto</span> out; \ } \ } <span class="keywordflow">while</span> (0) </pre></div> <p>Definition at line <a class="el" href="nl_8c_source.html#l00551">551</a> of file <a class="el" href="nl_8c_source.html">nl.c</a>.</p> </div> </div> <hr/><h2>Function Documentation</h2> <a class="anchor" id="ga68655d7fa8bd1944bec4761c95e576e9"></a><!-- doxytag: member="nl.c::nl_connect" ref="ga68655d7fa8bd1944bec4761c95e576e9" args="(struct nl_handle *handle, int protocol)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int nl_connect </td> <td>(</td> <td class="paramtype">struct nl_handle * </td> <td class="paramname"><em>handle</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">int </td> <td class="paramname"><em>protocol</em> </td> </tr> <tr> <td></td> <td>)</td> <td></td><td></td> </tr> </table> </div> <div class="memdoc"> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramname">handle</td><td>Netlink handle. </td></tr> <tr><td class="paramname">protocol</td><td>Netlink protocol to use.</td></tr> </table> </dd> </dl> <p>Creates a netlink socket using the specified protocol, binds the socket and issues a connection attempt.</p> <dl class="return"><dt><b>Returns:</b></dt><dd>0 on success or a negative error code. </dd></dl> <p>Definition at line <a class="el" href="nl_8c_source.html#l00191">191</a> of file <a class="el" href="nl_8c_source.html">nl.c</a>.</p> <p>References <a class="el" href="socket_8c_source.html#l00532">nl_set_buffer_size()</a>.</p> <p>Referenced by <a class="el" href="nfnl_8c_source.html#l00085">nfnl_connect()</a>, and <a class="el" href="cache__mngr_8c_source.html#l00149">nl_cache_mngr_alloc()</a>.</p> <div class="fragment"><pre class="fragment">{ <span class="keywordtype">int</span> err; socklen_t addrlen; handle->h_fd = socket(AF_NETLINK, SOCK_RAW, protocol); <span class="keywordflow">if</span> (handle->h_fd < 0) { err = nl_error(1, <span class="stringliteral">"socket(AF_NETLINK, ...) failed"</span>); <span class="keywordflow">goto</span> errout; } <span class="keywordflow">if</span> (!(handle->h_flags & NL_SOCK_BUFSIZE_SET)) { err = <a class="code" href="group__socket.html#ga0b6d4741ee2ec8f0392b600a626ff1fd" title="Set socket buffer size of netlink handle.">nl_set_buffer_size</a>(handle, 0, 0); <span class="keywordflow">if</span> (err < 0) <span class="keywordflow">goto</span> errout; } err = bind(handle->h_fd, (<span class="keyword">struct</span> sockaddr*) &handle->h_local, <span class="keyword">sizeof</span>(handle->h_local)); <span class="keywordflow">if</span> (err < 0) { err = nl_error(1, <span class="stringliteral">"bind() failed"</span>); <span class="keywordflow">goto</span> errout; } addrlen = <span class="keyword">sizeof</span>(handle->h_local); err = getsockname(handle->h_fd, (<span class="keyword">struct</span> sockaddr *) &handle->h_local, &addrlen); <span class="keywordflow">if</span> (err < 0) { err = nl_error(1, <span class="stringliteral">"getsockname failed"</span>); <span class="keywordflow">goto</span> errout; } <span class="keywordflow">if</span> (addrlen != <span class="keyword">sizeof</span>(handle->h_local)) { err = nl_error(EADDRNOTAVAIL, <span class="stringliteral">"Invalid address length"</span>); <span class="keywordflow">goto</span> errout; } <span class="keywordflow">if</span> (handle->h_local.nl_family != AF_NETLINK) { err = nl_error(EPFNOSUPPORT, <span class="stringliteral">"Address format not supported"</span>); <span class="keywordflow">goto</span> errout; } handle->h_proto = protocol; <span class="keywordflow">return</span> 0; errout: close(handle->h_fd); handle->h_fd = -1; <span class="keywordflow">return</span> err; } </pre></div> </div> </div> <a class="anchor" id="ga25039e93db5ab64ce4345ffe14379530"></a><!-- doxytag: member="nl.c::nl_close" ref="ga25039e93db5ab64ce4345ffe14379530" args="(struct nl_handle *handle)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">void nl_close </td> <td>(</td> <td class="paramtype">struct nl_handle * </td> <td class="paramname"><em>handle</em></td><td>)</td> <td></td> </tr> </table> </div> <div class="memdoc"> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramname">handle</td><td>Netlink handle </td></tr> </table> </dd> </dl> <p>Definition at line <a class="el" href="nl_8c_source.html#l00247">247</a> of file <a class="el" href="nl_8c_source.html">nl.c</a>.</p> <p>Referenced by <a class="el" href="cache__mngr_8c_source.html#l00373">nl_cache_mngr_free()</a>.</p> <div class="fragment"><pre class="fragment">{ <span class="keywordflow">if</span> (handle->h_fd >= 0) { close(handle->h_fd); handle->h_fd = -1; } handle->h_proto = 0; } </pre></div> </div> </div> <a class="anchor" id="ga53ee384f123fa3c354ad43adb6cf647d"></a><!-- doxytag: member="nl.c::nl_sendto" ref="ga53ee384f123fa3c354ad43adb6cf647d" args="(struct nl_handle *handle, void *buf, size_t size)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int nl_sendto </td> <td>(</td> <td class="paramtype">struct nl_handle * </td> <td class="paramname"><em>handle</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">void * </td> <td class="paramname"><em>buf</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">size_t </td> <td class="paramname"><em>size</em> </td> </tr> <tr> <td></td> <td>)</td> <td></td><td></td> </tr> </table> </div> <div class="memdoc"> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramname">handle</td><td>Netlink handle. </td></tr> <tr><td class="paramname">buf</td><td>Data buffer. </td></tr> <tr><td class="paramname">size</td><td>Size of data buffer. </td></tr> </table> </dd> </dl> <dl class="return"><dt><b>Returns:</b></dt><dd>Number of characters written on success or a negative error code. </dd></dl> <p>Definition at line <a class="el" href="nl_8c_source.html#l00271">271</a> of file <a class="el" href="nl_8c_source.html">nl.c</a>.</p> <div class="fragment"><pre class="fragment">{ <span class="keywordtype">int</span> ret; ret = sendto(handle->h_fd, buf, size, 0, (<span class="keyword">struct</span> sockaddr *) &handle->h_peer, <span class="keyword">sizeof</span>(handle->h_peer)); <span class="keywordflow">if</span> (ret < 0) <span class="keywordflow">return</span> nl_errno(errno); <span class="keywordflow">return</span> ret; } </pre></div> </div> </div> <a class="anchor" id="gaf3dca993337ed2d60a42269eaab65585"></a><!-- doxytag: member="nl.c::nl_sendmsg" ref="gaf3dca993337ed2d60a42269eaab65585" args="(struct nl_handle *handle, struct nl_msg *msg, struct msghdr *hdr)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int nl_sendmsg </td> <td>(</td> <td class="paramtype">struct nl_handle * </td> <td class="paramname"><em>handle</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">struct nl_msg * </td> <td class="paramname"><em>msg</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">struct msghdr * </td> <td class="paramname"><em>hdr</em> </td> </tr> <tr> <td></td> <td>)</td> <td></td><td></td> </tr> </table> </div> <div class="memdoc"> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramname">handle</td><td>Netlink handle. </td></tr> <tr><td class="paramname">msg</td><td>Netlink message to be sent. </td></tr> <tr><td class="paramname">hdr</td><td>Sendmsg() message header. </td></tr> </table> </dd> </dl> <dl class="return"><dt><b>Returns:</b></dt><dd>Number of characters sent on sucess or a negative error code. </dd></dl> <p>Definition at line <a class="el" href="nl_8c_source.html#l00290">290</a> of file <a class="el" href="nl_8c_source.html">nl.c</a>.</p> <p>References <a class="el" href="handlers_8h_source.html#l00107">NL_CB_MSG_OUT</a>, <a class="el" href="handlers_8h_source.html#l00060">NL_OK</a>, <a class="el" href="msg_8c_source.html#l00643">nlmsg_hdr()</a>, and <a class="el" href="netlink-kernel_8h_source.html#l00032">nlmsghdr::nlmsg_len</a>.</p> <p>Referenced by <a class="el" href="nl_8c_source.html#l00325">nl_send()</a>.</p> <div class="fragment"><pre class="fragment">{ <span class="keyword">struct </span>nl_cb *cb; <span class="keywordtype">int</span> ret; <span class="keyword">struct </span>iovec iov = { .iov_base = (<span class="keywordtype">void</span> *) <a class="code" href="group__msg.html#gaa5f29579d86d2bdab26c312b44b56de7" title="Return actual netlink message.">nlmsg_hdr</a>(msg), .iov_len = <a class="code" href="group__msg.html#gaa5f29579d86d2bdab26c312b44b56de7" title="Return actual netlink message.">nlmsg_hdr</a>(msg)-><a class="code" href="structnlmsghdr.html#a5a3fdb3436743ec73e75471c899fd4bc" title="Length of message including header.">nlmsg_len</a>, }; hdr->msg_iov = &iov; hdr->msg_iovlen = 1; nlmsg_set_src(msg, &handle->h_local); cb = handle->h_cb; <span class="keywordflow">if</span> (cb->cb_set[<a class="code" href="group__cb.html#gga3f60f4515ada826d2bf16395ee722363a0b43ab5eccae67470bb8ed0b09e2f650" title="Called for every message sent out except for nl_sendto()">NL_CB_MSG_OUT</a>]) <span class="keywordflow">if</span> (nl_cb_call(cb, <a class="code" href="group__cb.html#gga3f60f4515ada826d2bf16395ee722363a0b43ab5eccae67470bb8ed0b09e2f650" title="Called for every message sent out except for nl_sendto()">NL_CB_MSG_OUT</a>, msg) != <a class="code" href="group__cb.html#gga0c50cb29c507b3d7e8bc7d76c74675f8abce22d25ef3e2fed30f22f8bc27fc8f0" title="Proceed with wathever would come next.">NL_OK</a>) <span class="keywordflow">return</span> 0; ret = sendmsg(handle->h_fd, hdr, 0); <span class="keywordflow">if</span> (ret < 0) <span class="keywordflow">return</span> nl_errno(errno); <span class="keywordflow">return</span> ret; } </pre></div> </div> </div> <a class="anchor" id="ga5f3fff85c39f18946100c85f09d2c41c"></a><!-- doxytag: member="nl.c::nl_send" ref="ga5f3fff85c39f18946100c85f09d2c41c" args="(struct nl_handle *handle, struct nl_msg *msg)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int nl_send </td> <td>(</td> <td class="paramtype">struct nl_handle * </td> <td class="paramname"><em>handle</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">struct nl_msg * </td> <td class="paramname"><em>msg</em> </td> </tr> <tr> <td></td> <td>)</td> <td></td><td></td> </tr> </table> </div> <div class="memdoc"> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramname">handle</td><td>Netlink handle </td></tr> <tr><td class="paramname">msg</td><td>Netlink message to be sent. </td></tr> </table> </dd> </dl> <dl class="see"><dt><b>See also:</b></dt><dd><a class="el" href="group__nl.html#gaf3dca993337ed2d60a42269eaab65585" title="Send netlink message with control over sendmsg() message header.">nl_sendmsg()</a> </dd></dl> <dl class="return"><dt><b>Returns:</b></dt><dd>Number of characters sent on success or a negative error code. </dd></dl> <p>Definition at line <a class="el" href="nl_8c_source.html#l00325">325</a> of file <a class="el" href="nl_8c_source.html">nl.c</a>.</p> <p>References <a class="el" href="netlink-kernel_8h_source.html#l00011">sockaddr_nl::nl_family</a>, and <a class="el" href="nl_8c_source.html#l00290">nl_sendmsg()</a>.</p> <p>Referenced by <a class="el" href="nl_8c_source.html#l00373">nl_send_auto_complete()</a>.</p> <div class="fragment"><pre class="fragment">{ <span class="keyword">struct </span><a class="code" href="structsockaddr__nl.html" title="Netlink socket address.">sockaddr_nl</a> *dst; <span class="keyword">struct </span>ucred *creds; <span class="keyword">struct </span>msghdr hdr = { .msg_name = (<span class="keywordtype">void</span> *) &handle->h_peer, .msg_namelen = <span class="keyword">sizeof</span>(<span class="keyword">struct</span> <a class="code" href="structsockaddr__nl.html" title="Netlink socket address.">sockaddr_nl</a>), }; <span class="comment">/* Overwrite destination if specified in the message itself, defaults</span> <span class="comment"> * to the peer address of the handle.</span> <span class="comment"> */</span> dst = nlmsg_get_dst(msg); <span class="keywordflow">if</span> (dst-><a class="code" href="structsockaddr__nl.html#a28df558ea904fe04840eb2a4ce4b779d" title="socket family (AF_NETLINK)">nl_family</a> == AF_NETLINK) hdr.msg_name = dst; <span class="comment">/* Add credentials if present. */</span> creds = nlmsg_get_creds(msg); <span class="keywordflow">if</span> (creds != NULL) { <span class="keywordtype">char</span> buf[CMSG_SPACE(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> ucred))]; <span class="keyword">struct </span>cmsghdr *cmsg; hdr.msg_control = buf; hdr.msg_controllen = <span class="keyword">sizeof</span>(buf); cmsg = CMSG_FIRSTHDR(&hdr); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_CREDENTIALS; cmsg->cmsg_len = CMSG_LEN(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> ucred)); memcpy(CMSG_DATA(cmsg), creds, <span class="keyword">sizeof</span>(<span class="keyword">struct</span> ucred)); } <span class="keywordflow">return</span> <a class="code" href="group__nl.html#gaf3dca993337ed2d60a42269eaab65585" title="Send netlink message with control over sendmsg() message header.">nl_sendmsg</a>(handle, msg, &hdr); } </pre></div> </div> </div> <a class="anchor" id="ga01a2aad82350f867e704d5c696438b60"></a><!-- doxytag: member="nl.c::nl_send_auto_complete" ref="ga01a2aad82350f867e704d5c696438b60" args="(struct nl_handle *handle, struct nl_msg *msg)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int nl_send_auto_complete </td> <td>(</td> <td class="paramtype">struct nl_handle * </td> <td class="paramname"><em>handle</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">struct nl_msg * </td> <td class="paramname"><em>msg</em> </td> </tr> <tr> <td></td> <td>)</td> <td></td><td></td> </tr> </table> </div> <div class="memdoc"> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramname">handle</td><td>Netlink handle. </td></tr> <tr><td class="paramname">msg</td><td>Netlink message to be sent.</td></tr> </table> </dd> </dl> <p>Checks the netlink message <code>nlh</code> for completness and extends it as required before sending it out. Checked fields include pid, sequence nr, and flags.</p> <dl class="see"><dt><b>See also:</b></dt><dd><a class="el" href="group__nl.html#ga5f3fff85c39f18946100c85f09d2c41c" title="Send netlink message.">nl_send()</a> </dd></dl> <dl class="return"><dt><b>Returns:</b></dt><dd>Number of characters sent or a negative error code. </dd></dl> <p>Definition at line <a class="el" href="nl_8c_source.html#l00373">373</a> of file <a class="el" href="nl_8c_source.html">nl.c</a>.</p> <p>References <a class="el" href="nl_8c_source.html#l00325">nl_send()</a>, <a class="el" href="netlink-kernel_8h_source.html#l00076">NLM_F_ACK</a>, <a class="el" href="netlink-kernel_8h_source.html#l00065">NLM_F_REQUEST</a>, <a class="el" href="netlink-kernel_8h_source.html#l00042">nlmsghdr::nlmsg_flags</a>, <a class="el" href="msg_8c_source.html#l00643">nlmsg_hdr()</a>, <a class="el" href="netlink-kernel_8h_source.html#l00052">nlmsghdr::nlmsg_pid</a>, and <a class="el" href="netlink-kernel_8h_source.html#l00047">nlmsghdr::nlmsg_seq</a>.</p> <p>Referenced by <a class="el" href="lookup_8c_source.html#l00263">flnl_lookup()</a>, <a class="el" href="nl_8c_source.html#l00410">nl_send_simple()</a>, <a class="el" href="route_2addr_8c_source.html#l00765">rtnl_addr_add()</a>, <a class="el" href="route_2addr_8c_source.html#l00838">rtnl_addr_delete()</a>, <a class="el" href="class_8c_source.html#l00148">rtnl_class_add()</a>, <a class="el" href="classifier_8c_source.html#l00162">rtnl_cls_add()</a>, <a class="el" href="classifier_8c_source.html#l00208">rtnl_cls_change()</a>, <a class="el" href="classifier_8c_source.html#l00256">rtnl_cls_delete()</a>, <a class="el" href="link_8c_source.html#l01048">rtnl_link_change()</a>, <a class="el" href="neigh_8c_source.html#l00656">rtnl_neigh_add()</a>, <a class="el" href="neigh_8c_source.html#l00770">rtnl_neigh_change()</a>, <a class="el" href="neigh_8c_source.html#l00711">rtnl_neigh_delete()</a>, <a class="el" href="neightbl_8c_source.html#l00578">rtnl_neightbl_change()</a>, <a class="el" href="qdisc_8c_source.html#l00224">rtnl_qdisc_add()</a>, <a class="el" href="qdisc_8c_source.html#l00279">rtnl_qdisc_change()</a>, <a class="el" href="qdisc_8c_source.html#l00348">rtnl_qdisc_delete()</a>, <a class="el" href="rule_8c_source.html#l00581">rtnl_rule_add()</a>, and <a class="el" href="rule_8c_source.html#l00635">rtnl_rule_delete()</a>.</p> <div class="fragment"><pre class="fragment">{ <span class="keyword">struct </span><a class="code" href="structnlmsghdr.html" title="Netlink message header.">nlmsghdr</a> *nlh; <span class="keyword">struct </span>nl_cb *cb = handle->h_cb; nlh = <a class="code" href="group__msg.html#gaa5f29579d86d2bdab26c312b44b56de7" title="Return actual netlink message.">nlmsg_hdr</a>(msg); <span class="keywordflow">if</span> (nlh-><a class="code" href="structnlmsghdr.html#a071903f5e2400298bca69ac70500421f" title="Netlink PID of the proccess sending the message.">nlmsg_pid</a> == 0) nlh-><a class="code" href="structnlmsghdr.html#a071903f5e2400298bca69ac70500421f" title="Netlink PID of the proccess sending the message.">nlmsg_pid</a> = handle->h_local.nl_pid; <span class="keywordflow">if</span> (nlh-><a class="code" href="structnlmsghdr.html#ad6c6a7aa9de65bb2da498c84148be7e6" title="Sequence number.">nlmsg_seq</a> == 0) nlh-><a class="code" href="structnlmsghdr.html#ad6c6a7aa9de65bb2da498c84148be7e6" title="Sequence number.">nlmsg_seq</a> = handle->h_seq_next++; <span class="keywordflow">if</span> (msg->nm_protocol == -1) msg->nm_protocol = handle->h_proto; nlh-><a class="code" href="structnlmsghdr.html#abcf664d354ea35ebb9b3d8a50088fec6" title="Message flags.">nlmsg_flags</a> |= (<a class="code" href="group__msg.html#ga456954d27b8adedd78136a9511f13160" title="Must be set on all request messages (typically from user space to kernel space).">NLM_F_REQUEST</a> | <a class="code" href="group__msg.html#ga67d5b6ba8714b97d74df72d119351bee" title="Request for an acknowledgment on success.">NLM_F_ACK</a>); <span class="keywordflow">if</span> (cb->cb_send_ow) <span class="keywordflow">return</span> cb->cb_send_ow(handle, msg); <span class="keywordflow">else</span> <span class="keywordflow">return</span> <a class="code" href="group__nl.html#ga5f3fff85c39f18946100c85f09d2c41c" title="Send netlink message.">nl_send</a>(handle, msg); } </pre></div> </div> </div> <a class="anchor" id="ga73ed88a505f2d67bcf328183fe1e692a"></a><!-- doxytag: member="nl.c::nl_send_simple" ref="ga73ed88a505f2d67bcf328183fe1e692a" args="(struct nl_handle *handle, int type, int flags, void *buf, size_t size)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int nl_send_simple </td> <td>(</td> <td class="paramtype">struct nl_handle * </td> <td class="paramname"><em>handle</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">int </td> <td class="paramname"><em>type</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">int </td> <td class="paramname"><em>flags</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">void * </td> <td class="paramname"><em>buf</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">size_t </td> <td class="paramname"><em>size</em> </td> </tr> <tr> <td></td> <td>)</td> <td></td><td></td> </tr> </table> </div> <div class="memdoc"> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramname">handle</td><td>Netlink handle. </td></tr> <tr><td class="paramname">type</td><td>Netlink message type. </td></tr> <tr><td class="paramname">flags</td><td>Netlink message flags. </td></tr> <tr><td class="paramname">buf</td><td>Data buffer. </td></tr> <tr><td class="paramname">size</td><td>Size of data buffer.</td></tr> </table> </dd> </dl> <p>Builds a netlink message with the specified type and flags and appends the specified data as payload to the message.</p> <dl class="see"><dt><b>See also:</b></dt><dd><a class="el" href="group__nl.html#ga01a2aad82350f867e704d5c696438b60" title="Send netlink message and check & extend header values as needed.">nl_send_auto_complete()</a> </dd></dl> <dl class="return"><dt><b>Returns:</b></dt><dd>Number of characters sent on success or a negative error code. </dd></dl> <p>Definition at line <a class="el" href="nl_8c_source.html#l00410">410</a> of file <a class="el" href="nl_8c_source.html">nl.c</a>.</p> <p>References <a class="el" href="nl_8c_source.html#l00373">nl_send_auto_complete()</a>, <a class="el" href="msg_8c_source.html#l00448">nlmsg_alloc_simple()</a>, <a class="el" href="msg_8c_source.html#l00549">nlmsg_append()</a>, and <a class="el" href="msg_8c_source.html#l00656">nlmsg_free()</a>.</p> <p>Referenced by <a class="el" href="genl_8c_source.html#l00128">genl_send_simple()</a>, <a class="el" href="nfnl_8c_source.html#l00108">nfnl_send_simple()</a>, and <a class="el" href="rtnl_8c_source.html#l00040">nl_rtgen_request()</a>.</p> <div class="fragment"><pre class="fragment">{ <span class="keywordtype">int</span> err; <span class="keyword">struct </span>nl_msg *msg; msg = <a class="code" href="group__msg.html#ga580d8697d19050c55060bc10ab4eae9f" title="Allocate a new netlink message.">nlmsg_alloc_simple</a>(type, flags); <span class="keywordflow">if</span> (!msg) <span class="keywordflow">return</span> nl_errno(ENOMEM); <span class="keywordflow">if</span> (buf && size) { err = <a class="code" href="group__msg.html#gacc5e5ade5675d041f86c7c8693f7088d" title="Append data to tail of a netlink message.">nlmsg_append</a>(msg, buf, size, NLMSG_ALIGNTO); <span class="keywordflow">if</span> (err < 0) <span class="keywordflow">goto</span> errout; } err = <a class="code" href="group__nl.html#ga01a2aad82350f867e704d5c696438b60" title="Send netlink message and check &amp; extend header values as needed.">nl_send_auto_complete</a>(handle, msg); errout: <a class="code" href="group__msg.html#ga138ba9bee70553f9fbe7143deacad48c" title="Free a netlink message.">nlmsg_free</a>(msg); <span class="keywordflow">return</span> err; } </pre></div> </div> </div> <a class="anchor" id="ga060acc8371fdb242c5ae3d5b761d28e1"></a><!-- doxytag: member="nl.c::nl_recv" ref="ga060acc8371fdb242c5ae3d5b761d28e1" args="(struct nl_handle *handle, struct sockaddr_nl *nla, unsigned char **buf, struct ucred **creds)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int nl_recv </td> <td>(</td> <td class="paramtype">struct nl_handle * </td> <td class="paramname"><em>handle</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">struct <a class="el" href="structsockaddr__nl.html">sockaddr_nl</a> * </td> <td class="paramname"><em>nla</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">unsigned char ** </td> <td class="paramname"><em>buf</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">struct ucred ** </td> <td class="paramname"><em>creds</em> </td> </tr> <tr> <td></td> <td>)</td> <td></td><td></td> </tr> </table> </div> <div class="memdoc"> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramname">handle</td><td>Netlink handle. </td></tr> <tr><td class="paramname">nla</td><td>Destination pointer for peer's netlink address. </td></tr> <tr><td class="paramname">buf</td><td>Destination pointer for message content. </td></tr> <tr><td class="paramname">creds</td><td>Destination pointer for credentials.</td></tr> </table> </dd> </dl> <p>Receives a netlink message, allocates a buffer in <code>*buf</code> and stores the message content. The peer's netlink address is stored in <code>*nla</code>. The caller is responsible for freeing the buffer allocated in <code>*buf</code> if a positive value is returned. Interruped system calls are handled by repeating the read. The input buffer size is determined by peeking before the actual read is done.</p> <p>A non-blocking sockets causes the function to return immediately with a return value of 0 if no data is available.</p> <dl class="return"><dt><b>Returns:</b></dt><dd>Number of octets read, 0 on EOF or a negative error code. </dd></dl> <p>Definition at line <a class="el" href="nl_8c_source.html#l00460">460</a> of file <a class="el" href="nl_8c_source.html">nl.c</a>.</p> <div class="fragment"><pre class="fragment">{ <span class="keywordtype">int</span> n; <span class="keywordtype">int</span> flags = 0; <span class="keyword">static</span> <span class="keywordtype">int</span> page_size = 0; <span class="keyword">struct </span>iovec iov; <span class="keyword">struct </span>msghdr msg = { .msg_name = (<span class="keywordtype">void</span> *) nla, .msg_namelen = <span class="keyword">sizeof</span>(<span class="keyword">struct</span> <a class="code" href="structsockaddr__nl.html" title="Netlink socket address.">sockaddr_nl</a>), .msg_iov = &iov, .msg_iovlen = 1, .msg_control = NULL, .msg_controllen = 0, .msg_flags = 0, }; <span class="keyword">struct </span>cmsghdr *cmsg; <span class="keywordflow">if</span> (handle->h_flags & NL_MSG_PEEK) flags |= MSG_PEEK; <span class="keywordflow">if</span> (page_size == 0) page_size = getpagesize(); iov.iov_len = page_size; iov.iov_base = *buf = calloc(1, iov.iov_len); <span class="keywordflow">if</span> (handle->h_flags & NL_SOCK_PASSCRED) { msg.msg_controllen = CMSG_SPACE(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> ucred)); msg.msg_control = calloc(1, msg.msg_controllen); } retry: n = recvmsg(handle->h_fd, &msg, flags); <span class="keywordflow">if</span> (!n) <span class="keywordflow">goto</span> abort; <span class="keywordflow">else</span> <span class="keywordflow">if</span> (n < 0) { <span class="keywordflow">if</span> (errno == EINTR) { NL_DBG(3, <span class="stringliteral">"recvmsg() returned EINTR, retrying\n"</span>); <span class="keywordflow">goto</span> retry; } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (errno == EAGAIN) { NL_DBG(3, <span class="stringliteral">"recvmsg() returned EAGAIN, aborting\n"</span>); <span class="keywordflow">goto</span> abort; } <span class="keywordflow">else</span> { free(msg.msg_control); free(*buf); <span class="keywordflow">return</span> nl_error(errno, <span class="stringliteral">"recvmsg failed"</span>); } } <span class="keywordflow">if</span> (iov.iov_len < n || msg.msg_flags & MSG_TRUNC) { <span class="comment">/* Provided buffer is not long enough, enlarge it</span> <span class="comment"> * and try again. */</span> iov.iov_len *= 2; iov.iov_base = *buf = realloc(*buf, iov.iov_len); <span class="keywordflow">goto</span> retry; } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (msg.msg_flags & MSG_CTRUNC) { msg.msg_controllen *= 2; msg.msg_control = realloc(msg.msg_control, msg.msg_controllen); <span class="keywordflow">goto</span> retry; } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (flags != 0) { <span class="comment">/* Buffer is big enough, do the actual reading */</span> flags = 0; <span class="keywordflow">goto</span> retry; } <span class="keywordflow">if</span> (msg.msg_namelen != <span class="keyword">sizeof</span>(<span class="keyword">struct</span> <a class="code" href="structsockaddr__nl.html" title="Netlink socket address.">sockaddr_nl</a>)) { free(msg.msg_control); free(*buf); <span class="keywordflow">return</span> nl_error(EADDRNOTAVAIL, <span class="stringliteral">"socket address size mismatch"</span>); } <span class="keywordflow">for</span> (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { <span class="keywordflow">if</span> (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) { *creds = calloc(1, <span class="keyword">sizeof</span>(<span class="keyword">struct</span> ucred)); memcpy(*creds, CMSG_DATA(cmsg), <span class="keyword">sizeof</span>(<span class="keyword">struct</span> ucred)); <span class="keywordflow">break</span>; } } free(msg.msg_control); <span class="keywordflow">return</span> n; abort: free(msg.msg_control); free(*buf); <span class="keywordflow">return</span> 0; } </pre></div> </div> </div> <a class="anchor" id="ga1bb066e1772b89f79fe1d76a4ef243a6"></a><!-- doxytag: member="nl.c::nl_recvmsgs" ref="ga1bb066e1772b89f79fe1d76a4ef243a6" args="(struct nl_handle *handle, struct nl_cb *cb)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int nl_recvmsgs </td> <td>(</td> <td class="paramtype">struct nl_handle * </td> <td class="paramname"><em>handle</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">struct nl_cb * </td> <td class="paramname"><em>cb</em> </td> </tr> <tr> <td></td> <td>)</td> <td></td><td></td> </tr> </table> </div> <div class="memdoc"> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramname">handle</td><td>netlink handle </td></tr> <tr><td class="paramname">cb</td><td>set of callbacks to control behaviour.</td></tr> </table> </dd> </dl> <p>Repeatedly calls <a class="el" href="group__nl.html#ga060acc8371fdb242c5ae3d5b761d28e1" title="Receive data from netlink socket.">nl_recv()</a> or the respective replacement if provided by the application (see <a class="el" href="group__cb.html#ga0d2f92ed95a6d7a5f915e128d1643e24" title="Overwrite internal calls to nl_recv()">nl_cb_overwrite_recv()</a>) and parses the received data as netlink messages. Stops reading if one of the callbacks returns NL_STOP or nl_recv returns either 0 or a negative error code.</p> <p>A non-blocking sockets causes the function to return immediately if no data is available.</p> <dl class="return"><dt><b>Returns:</b></dt><dd>0 on success or a negative error code from <a class="el" href="group__nl.html#ga060acc8371fdb242c5ae3d5b761d28e1" title="Receive data from netlink socket.">nl_recv()</a>. </dd></dl> <p>Definition at line <a class="el" href="nl_8c_source.html#l00767">767</a> of file <a class="el" href="nl_8c_source.html">nl.c</a>.</p> <p>Referenced by <a class="el" href="nl_8c_source.html#l00781">nl_recvmsgs_default()</a>, and <a class="el" href="nl_8c_source.html#l00800">nl_wait_for_ack()</a>.</p> <div class="fragment"><pre class="fragment">{ <span class="keywordflow">if</span> (cb->cb_recvmsgs_ow) <span class="keywordflow">return</span> cb->cb_recvmsgs_ow(handle, cb); <span class="keywordflow">else</span> <span class="keywordflow">return</span> recvmsgs(handle, cb); } </pre></div> </div> </div> <a class="anchor" id="gab287fc77c46d80c4e22bc87494cbf853"></a><!-- doxytag: member="nl.c::nl_recvmsgs_default" ref="gab287fc77c46d80c4e22bc87494cbf853" args="(struct nl_handle *handle)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int nl_recvmsgs_default </td> <td>(</td> <td class="paramtype">struct nl_handle * </td> <td class="paramname"><em>handle</em></td><td>)</td> <td></td> </tr> </table> </div> <div class="memdoc"> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramname">handle</td><td>netlink handle</td></tr> </table> </dd> </dl> <p>Calls <a class="el" href="group__nl.html#ga1bb066e1772b89f79fe1d76a4ef243a6" title="Receive a set of messages from a netlink socket.">nl_recvmsgs()</a> with the handlers configured in the netlink handle. </p> <p>Definition at line <a class="el" href="nl_8c_source.html#l00781">781</a> of file <a class="el" href="nl_8c_source.html">nl.c</a>.</p> <p>References <a class="el" href="nl_8c_source.html#l00767">nl_recvmsgs()</a>.</p> <p>Referenced by <a class="el" href="cache__mngr_8c_source.html#l00356">nl_cache_mngr_data_ready()</a>.</p> <div class="fragment"><pre class="fragment">{ <span class="keywordflow">return</span> <a class="code" href="group__nl.html#ga1bb066e1772b89f79fe1d76a4ef243a6" title="Receive a set of messages from a netlink socket.">nl_recvmsgs</a>(handle, handle->h_cb); } </pre></div> </div> </div> <a class="anchor" id="gaa65fec588e0a0a2de1881fb8366ccd79"></a><!-- doxytag: member="nl.c::nl_wait_for_ack" ref="gaa65fec588e0a0a2de1881fb8366ccd79" args="(struct nl_handle *handle)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int nl_wait_for_ack </td> <td>(</td> <td class="paramtype">struct nl_handle * </td> <td class="paramname"><em>handle</em></td><td>)</td> <td></td> </tr> </table> </div> <div class="memdoc"> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramname">handle</td><td>netlink handle </td></tr> </table> </dd> </dl> <dl class="pre"><dt><b>Precondition:</b></dt><dd>The netlink socket must be in blocking state.</dd></dl> <p>Waits until an ACK is received for the latest not yet acknowledged netlink message. </p> <p>Definition at line <a class="el" href="nl_8c_source.html#l00800">800</a> of file <a class="el" href="nl_8c_source.html">nl.c</a>.</p> <p>References <a class="el" href="handlers_8h_source.html#l00103">NL_CB_ACK</a>, <a class="el" href="handlers_8c_source.html#l00285">nl_cb_clone()</a>, <a class="el" href="handlers_8h_source.html#l00083">NL_CB_CUSTOM</a>, <a class="el" href="handlers_8c_source.html#l00337">nl_cb_set()</a>, and <a class="el" href="nl_8c_source.html#l00767">nl_recvmsgs()</a>.</p> <p>Referenced by <a class="el" href="route_2addr_8c_source.html#l00765">rtnl_addr_add()</a>, <a class="el" href="route_2addr_8c_source.html#l00838">rtnl_addr_delete()</a>, <a class="el" href="class_8c_source.html#l00148">rtnl_class_add()</a>, <a class="el" href="classifier_8c_source.html#l00162">rtnl_cls_add()</a>, <a class="el" href="classifier_8c_source.html#l00208">rtnl_cls_change()</a>, <a class="el" href="classifier_8c_source.html#l00256">rtnl_cls_delete()</a>, <a class="el" href="link_8c_source.html#l01048">rtnl_link_change()</a>, <a class="el" href="neigh_8c_source.html#l00656">rtnl_neigh_add()</a>, <a class="el" href="neigh_8c_source.html#l00770">rtnl_neigh_change()</a>, <a class="el" href="neigh_8c_source.html#l00711">rtnl_neigh_delete()</a>, <a class="el" href="neightbl_8c_source.html#l00578">rtnl_neightbl_change()</a>, <a class="el" href="qdisc_8c_source.html#l00224">rtnl_qdisc_add()</a>, <a class="el" href="qdisc_8c_source.html#l00279">rtnl_qdisc_change()</a>, <a class="el" href="qdisc_8c_source.html#l00348">rtnl_qdisc_delete()</a>, <a class="el" href="rule_8c_source.html#l00581">rtnl_rule_add()</a>, and <a class="el" href="rule_8c_source.html#l00635">rtnl_rule_delete()</a>.</p> <div class="fragment"><pre class="fragment">{ <span class="keywordtype">int</span> err; <span class="keyword">struct </span>nl_cb *cb; cb = <a class="code" href="group__cb.html#gad438f32bb0f83bd1d15f53e9525f1f65" title="Clone an existing callback handle.">nl_cb_clone</a>(handle->h_cb); <span class="keywordflow">if</span> (cb == NULL) <span class="keywordflow">return</span> nl_get_errno(); <a class="code" href="group__cb.html#gabe7b2516f28fbb8bb9c5b1ea2dfaf1d3" title="Set up a callback.">nl_cb_set</a>(cb, <a class="code" href="group__cb.html#gga3f60f4515ada826d2bf16395ee722363a8295b387c07bd076ccdee45b555f1134" title="Message is an acknowledge.">NL_CB_ACK</a>, <a class="code" href="group__cb.html#ggaba3fabad0c62db483941101e1a18d14da22448271a402b4c4a55733ef4884c038" title="Customized handler specified by the user.">NL_CB_CUSTOM</a>, ack_wait_handler, NULL); err = <a class="code" href="group__nl.html#ga1bb066e1772b89f79fe1d76a4ef243a6" title="Receive a set of messages from a netlink socket.">nl_recvmsgs</a>(handle, cb); nl_cb_put(cb); <span class="keywordflow">return</span> err; } </pre></div> </div> </div> </div> <hr class="footer"/><address class="footer"><small>Generated on Mon Mar 21 2011 for libnl by  <a href="http://www.doxygen.org/index.html"> <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.3 </small></address> </body> </html>