Sophie

Sophie

distrib > Fedora > 14 > x86_64 > media > updates > by-pkgid > 87b89b73c41f4440bb86afd421c7548f > files > 152

libnl-devel-1.1-14.fc14.x86_64.rpm

<!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&#160;<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&#160;Page</span></a></li>
      <li><a href="modules.html"><span>Modules</span></a></li>
      <li><a href="annotated.html"><span>Data&#160;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> &#124;
<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 &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structsockaddr__nl.html">sockaddr_nl</a></td></tr>
<tr><td class="mdescLeft">&#160;</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">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__cb.html">Callbacks/Customization</a></td></tr>

<p><tr><td class="mdescLeft">&#160;</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">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__msg.html">Messages</a></td></tr>

<p><tr><td class="mdescLeft">&#160;</td><td class="mdescRight"><p>Netlink Message Construction/Parsing Interface. </p>
<br/></td></tr>
</p>
<tr><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__socket.html">Socket</a></td></tr>

<p><tr><td class="mdescLeft">&#160;</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&#160;</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">&#160;</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&#160;</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">&#160;</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&#160;</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">&#160;</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&#160;</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">&#160;</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&#160;</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">&#160;</td><td class="mdescRight">Send netlink message.  <a href="#ga5f3fff85c39f18946100c85f09d2c41c"></a><br/></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">int&#160;</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">&#160;</td><td class="mdescRight">Send netlink message and check &amp; extend header values as needed.  <a href="#ga01a2aad82350f867e704d5c696438b60"></a><br/></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">int&#160;</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">&#160;</td><td class="mdescRight">Send simple netlink message using <a class="el" href="group__nl.html#ga01a2aad82350f867e704d5c696438b60" title="Send netlink message and check &amp; 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&#160;</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">&#160;</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&#160;</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">&#160;</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&#160;</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">&#160;</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&#160;</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">&#160;</td><td class="mdescRight">Wait for ACK.  <a href="#gaa65fec588e0a0a2de1881fb8366ccd79"></a><br/></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">#define&#160;</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-&gt;cb_recvmsgs_ow()
                 |
                 |               [Application provides <a class="code" href="group__nl.html#ga060acc8371fdb242c5ae3d5b761d28e1" title="Receive data from netlink socket.">nl_recv</a>() replacement]
 +--------------&gt;|- - - - - - - - - - - - - - - v
 |           <a class="code" href="group__nl.html#ga060acc8371fdb242c5ae3d5b761d28e1" title="Receive data from netlink socket.">nl_recv</a>()                   cb-&gt;cb_recv_ow()
 |  +-----------&gt;|&lt;- - - - - - - - - - - - - - -+
 |  |            v
 |  |      Parse Message
 |  |            |- - - - - - - - - - - - - - - v
 |  |            |                         <a class="code" href="group__cb.html#gga3f60f4515ada826d2bf16395ee722363a160d69995bab2c325bd25d7ee2d5292d" title="Called for every message received.">NL_CB_MSG_IN</a>()
 |  |            |&lt;- - - - - - - - - - - - - - -+
 |  |            |
 |  |            |- - - - - - - - - - - - - - - v
 |  |      Sequence Check                <a class="code" href="group__cb.html#gga3f60f4515ada826d2bf16395ee722363ae73e906b997f00e8911b09e0f254364d" title="Called instead of internal sequence number checking.">NL_CB_SEQ_CHECK</a>()
 |  |            |&lt;- - - - - - - - - - - - - - -+
 |  |            |
 |  |            |- - - - - - - - - - - - - - - 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>()
 |  |            |&lt;- - - - - - - - - - - - - - -+
 |  |            |
 |  |      +-----+------+--------------+----------------+--------------+
 |  |      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-&gt;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]    |&lt;-----------
 |  +----------------------------------|
 |                                     |
 |         [Multipart message]         |
 +-------------------------------------|  [Callback returned <a class="code" href="group__cb.html#gga0c50cb29c507b3d7e8bc7d76c74675f8aa87c4bfa1b41e2e06286a412dc2bc17b" title="Stop parsing altogether and discard remaining messages.">NL_STOP</a>]
                                       |&lt;-----------
                                       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;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-&gt;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>()
             |&lt;- - - - - - - - - - - - - - - - - - - -+
             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), &amp;hdr);

 <span class="comment">// You&#39;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;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&#39;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, &amp;peer, &amp;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">&#160;</td>
          <td class="paramname">cb, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">&#160;</td>
          <td class="paramname">type, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">&#160;</td>
          <td class="paramname">msg&#160;</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 *&#160;</td>
          <td class="paramname"><em>handle</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">int&#160;</td>
          <td class="paramname"><em>protocol</em>&#160;</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-&gt;h_fd = socket(AF_NETLINK, SOCK_RAW, protocol);
        <span class="keywordflow">if</span> (handle-&gt;h_fd &lt; 0) {
                err = nl_error(1, <span class="stringliteral">&quot;socket(AF_NETLINK, ...) failed&quot;</span>);
                <span class="keywordflow">goto</span> errout;
        }

        <span class="keywordflow">if</span> (!(handle-&gt;h_flags &amp; 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 &lt; 0)
                        <span class="keywordflow">goto</span> errout;
        }

        err = bind(handle-&gt;h_fd, (<span class="keyword">struct</span> sockaddr*) &amp;handle-&gt;h_local,
                   <span class="keyword">sizeof</span>(handle-&gt;h_local));
        <span class="keywordflow">if</span> (err &lt; 0) {
                err = nl_error(1, <span class="stringliteral">&quot;bind() failed&quot;</span>);
                <span class="keywordflow">goto</span> errout;
        }

        addrlen = <span class="keyword">sizeof</span>(handle-&gt;h_local);
        err = getsockname(handle-&gt;h_fd, (<span class="keyword">struct</span> sockaddr *) &amp;handle-&gt;h_local,
                          &amp;addrlen);
        <span class="keywordflow">if</span> (err &lt; 0) {
                err = nl_error(1, <span class="stringliteral">&quot;getsockname failed&quot;</span>);
                <span class="keywordflow">goto</span> errout;
        }

        <span class="keywordflow">if</span> (addrlen != <span class="keyword">sizeof</span>(handle-&gt;h_local)) {
                err = nl_error(EADDRNOTAVAIL, <span class="stringliteral">&quot;Invalid address length&quot;</span>);
                <span class="keywordflow">goto</span> errout;
        }

        <span class="keywordflow">if</span> (handle-&gt;h_local.nl_family != AF_NETLINK) {
                err = nl_error(EPFNOSUPPORT, <span class="stringliteral">&quot;Address format not supported&quot;</span>);
                <span class="keywordflow">goto</span> errout;
        }

        handle-&gt;h_proto = protocol;

        <span class="keywordflow">return</span> 0;
errout:
        close(handle-&gt;h_fd);
        handle-&gt;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 *&#160;</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-&gt;h_fd &gt;= 0) {
                close(handle-&gt;h_fd);
                handle-&gt;h_fd = -1;
        }

        handle-&gt;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 *&#160;</td>
          <td class="paramname"><em>handle</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">void *&#160;</td>
          <td class="paramname"><em>buf</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">size_t&#160;</td>
          <td class="paramname"><em>size</em>&#160;</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-&gt;h_fd, buf, size, 0, (<span class="keyword">struct</span> sockaddr *)
                     &amp;handle-&gt;h_peer, <span class="keyword">sizeof</span>(handle-&gt;h_peer));
        <span class="keywordflow">if</span> (ret &lt; 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 *&#160;</td>
          <td class="paramname"><em>handle</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">struct nl_msg *&#160;</td>
          <td class="paramname"><em>msg</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">struct msghdr *&#160;</td>
          <td class="paramname"><em>hdr</em>&#160;</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)-&gt;<a class="code" href="structnlmsghdr.html#a5a3fdb3436743ec73e75471c899fd4bc" title="Length of message including header.">nlmsg_len</a>,
        };

        hdr-&gt;msg_iov = &amp;iov;
        hdr-&gt;msg_iovlen = 1;

        nlmsg_set_src(msg, &amp;handle-&gt;h_local);

        cb = handle-&gt;h_cb;
        <span class="keywordflow">if</span> (cb-&gt;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-&gt;h_fd, hdr, 0);
        <span class="keywordflow">if</span> (ret &lt; 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 *&#160;</td>
          <td class="paramname"><em>handle</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">struct nl_msg *&#160;</td>
          <td class="paramname"><em>msg</em>&#160;</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> *) &amp;handle-&gt;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-&gt;<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(&amp;hdr);
                cmsg-&gt;cmsg_level = SOL_SOCKET;
                cmsg-&gt;cmsg_type = SCM_CREDENTIALS;
                cmsg-&gt;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, &amp;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 *&#160;</td>
          <td class="paramname"><em>handle</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">struct nl_msg *&#160;</td>
          <td class="paramname"><em>msg</em>&#160;</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-&gt;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-&gt;<a class="code" href="structnlmsghdr.html#a071903f5e2400298bca69ac70500421f" title="Netlink PID of the proccess sending the message.">nlmsg_pid</a> == 0)
                nlh-&gt;<a class="code" href="structnlmsghdr.html#a071903f5e2400298bca69ac70500421f" title="Netlink PID of the proccess sending the message.">nlmsg_pid</a> = handle-&gt;h_local.nl_pid;

        <span class="keywordflow">if</span> (nlh-&gt;<a class="code" href="structnlmsghdr.html#ad6c6a7aa9de65bb2da498c84148be7e6" title="Sequence number.">nlmsg_seq</a> == 0)
                nlh-&gt;<a class="code" href="structnlmsghdr.html#ad6c6a7aa9de65bb2da498c84148be7e6" title="Sequence number.">nlmsg_seq</a> = handle-&gt;h_seq_next++;

        <span class="keywordflow">if</span> (msg-&gt;nm_protocol == -1)
                msg-&gt;nm_protocol = handle-&gt;h_proto;
        
        nlh-&gt;<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-&gt;cb_send_ow)
                <span class="keywordflow">return</span> cb-&gt;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 *&#160;</td>
          <td class="paramname"><em>handle</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">int&#160;</td>
          <td class="paramname"><em>type</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">int&#160;</td>
          <td class="paramname"><em>flags</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">void *&#160;</td>
          <td class="paramname"><em>buf</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">size_t&#160;</td>
          <td class="paramname"><em>size</em>&#160;</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 &amp; 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 &amp;&amp; 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 &lt; 0)
                        <span class="keywordflow">goto</span> errout;
        }
        

        err = <a class="code" href="group__nl.html#ga01a2aad82350f867e704d5c696438b60" title="Send netlink message and check &amp;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 *&#160;</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> *&#160;</td>
          <td class="paramname"><em>nla</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">unsigned char **&#160;</td>
          <td class="paramname"><em>buf</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">struct ucred **&#160;</td>
          <td class="paramname"><em>creds</em>&#160;</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 = &amp;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-&gt;h_flags &amp; 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-&gt;h_flags &amp; 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-&gt;h_fd, &amp;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 &lt; 0) {
                <span class="keywordflow">if</span> (errno == EINTR) {
                        NL_DBG(3, <span class="stringliteral">&quot;recvmsg() returned EINTR, retrying\n&quot;</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">&quot;recvmsg() returned EAGAIN, aborting\n&quot;</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">&quot;recvmsg failed&quot;</span>);
                }
        }

        <span class="keywordflow">if</span> (iov.iov_len &lt; n ||
            msg.msg_flags &amp; 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 &amp; 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">&quot;socket address size mismatch&quot;</span>);
        }

        <span class="keywordflow">for</span> (cmsg = CMSG_FIRSTHDR(&amp;msg); cmsg; cmsg = CMSG_NXTHDR(&amp;msg, cmsg)) {
                <span class="keywordflow">if</span> (cmsg-&gt;cmsg_level == SOL_SOCKET &amp;&amp;
                    cmsg-&gt;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 *&#160;</td>
          <td class="paramname"><em>handle</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">struct nl_cb *&#160;</td>
          <td class="paramname"><em>cb</em>&#160;</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-&gt;cb_recvmsgs_ow)
                <span class="keywordflow">return</span> cb-&gt;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 *&#160;</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-&gt;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 *&#160;</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-&gt;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&#160;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.3 </small></address>
</body>
</html>