nl.c

00001 /*
00002  * lib/nl.c             Core Netlink Interface
00003  *
00004  *      This library is free software; you can redistribute it and/or
00005  *      modify it under the terms of the GNU Lesser General Public
00006  *      License as published by the Free Software Foundation version 2.1
00007  *      of the License.
00008  *
00009  * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
00010  */
00011 
00012 /**
00013  * @defgroup core Core
00014  *
00015  * @details
00016  * @par 1) Connecting the socket
00017  * @code
00018  * // Bind and connect the socket to a protocol, NETLINK_ROUTE in this example.
00019  * nl_connect(sk, NETLINK_ROUTE);
00020  * @endcode
00021  *
00022  * @par 2) Sending data
00023  * @code
00024  * // The most rudimentary method is to use nl_sendto() simply pushing
00025  * // a piece of data to the other netlink peer. This method is not
00026  * // recommended.
00027  * const char buf[] = { 0x01, 0x02, 0x03, 0x04 };
00028  * nl_sendto(sk, buf, sizeof(buf));
00029  *
00030  * // A more comfortable interface is nl_send() taking a pointer to
00031  * // a netlink message.
00032  * struct nl_msg *msg = my_msg_builder();
00033  * nl_send(sk, nlmsg_hdr(msg));
00034  *
00035  * // nl_sendmsg() provides additional control over the sendmsg() message
00036  * // header in order to allow more specific addressing of multiple peers etc.
00037  * struct msghdr hdr = { ... };
00038  * nl_sendmsg(sk, nlmsg_hdr(msg), &hdr);
00039  *
00040  * // You're probably too lazy to fill out the netlink pid, sequence number
00041  * // and message flags all the time. nl_send_auto_complete() automatically
00042  * // extends your message header as needed with an appropriate sequence
00043  * // number, the netlink pid stored in the netlink socket and the message
00044  * // flags NLM_F_REQUEST and NLM_F_ACK (if not disabled in the socket)
00045  * nl_send_auto_complete(sk, nlmsg_hdr(msg));
00046  *
00047  * // Simple protocols don't require the complex message construction interface
00048  * // and may favour nl_send_simple() to easly send a bunch of payload
00049  * // encapsulated in a netlink message header.
00050  * nl_send_simple(sk, MY_MSG_TYPE, 0, buf, sizeof(buf));
00051  * @endcode
00052  *
00053  * @par 3) Receiving data
00054  * @code
00055  * // nl_recv() receives a single message allocating a buffer for the message
00056  * // content and gives back the pointer to you.
00057  * struct sockaddr_nl peer;
00058  * unsigned char *msg;
00059  * nl_recv(sk, &peer, &msg);
00060  *
00061  * // nl_recvmsgs() receives a bunch of messages until the callback system
00062  * // orders it to state, usually after receving a compolete multi part
00063  * // message series.
00064  * nl_recvmsgs(sk, my_callback_configuration);
00065  *
00066  * // nl_recvmsgs_default() acts just like nl_recvmsg() but uses the callback
00067  * // configuration stored in the socket.
00068  * nl_recvmsgs_default(sk);
00069  *
00070  * // In case you want to wait for the ACK to be recieved that you requested
00071  * // with your latest message, you can call nl_wait_for_ack()
00072  * nl_wait_for_ack(sk);
00073  * @endcode
00074  *
00075  * @par 4) Closing
00076  * @code
00077  * // Close the socket first to release kernel memory
00078  * nl_close(sk);
00079  * @endcode
00080  * 
00081  * @{
00082  */
00083 
00084 #include <netlink-local.h>
00085 #include <netlink/netlink.h>
00086 #include <netlink/utils.h>
00087 #include <netlink/handlers.h>
00088 #include <netlink/msg.h>
00089 #include <netlink/attr.h>
00090 
00091 /**
00092  * @name Connection Management
00093  * @{
00094  */
00095 
00096 /**
00097  * Create and connect netlink socket.
00098  * @arg sk              Netlink socket.
00099  * @arg protocol        Netlink protocol to use.
00100  *
00101  * Creates a netlink socket using the specified protocol, binds the socket
00102  * and issues a connection attempt.
00103  *
00104  * @return 0 on success or a negative error code.
00105  */
00106 int nl_connect(struct nl_sock *sk, int protocol)
00107 {
00108         int err;
00109         socklen_t addrlen;
00110 
00111         sk->s_fd = socket(AF_NETLINK, SOCK_RAW, protocol);
00112         if (sk->s_fd < 0) {
00113                 err = -nl_syserr2nlerr(errno);
00114                 goto errout;
00115         }
00116 
00117         if (!(sk->s_flags & NL_SOCK_BUFSIZE_SET)) {
00118                 err = nl_socket_set_buffer_size(sk, 0, 0);
00119                 if (err < 0)
00120                         goto errout;
00121         }
00122 
00123         err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local,
00124                    sizeof(sk->s_local));
00125         if (err < 0) {
00126                 err = -nl_syserr2nlerr(errno);
00127                 goto errout;
00128         }
00129 
00130         addrlen = sizeof(sk->s_local);
00131         err = getsockname(sk->s_fd, (struct sockaddr *) &sk->s_local,
00132                           &addrlen);
00133         if (err < 0) {
00134                 err = -nl_syserr2nlerr(errno);
00135                 goto errout;
00136         }
00137 
00138         if (addrlen != sizeof(sk->s_local)) {
00139                 err = -NLE_NOADDR;
00140                 goto errout;
00141         }
00142 
00143         if (sk->s_local.nl_family != AF_NETLINK) {
00144                 err = -NLE_AF_NOSUPPORT;
00145                 goto errout;
00146         }
00147 
00148         sk->s_proto = protocol;
00149 
00150         return 0;
00151 errout:
00152         close(sk->s_fd);
00153         sk->s_fd = -1;
00154 
00155         return err;
00156 }
00157 
00158 /**
00159  * Close/Disconnect netlink socket.
00160  * @arg sk              Netlink socket.
00161  */
00162 void nl_close(struct nl_sock *sk)
00163 {
00164         if (sk->s_fd >= 0) {
00165                 close(sk->s_fd);
00166                 sk->s_fd = -1;
00167         }
00168 
00169         sk->s_proto = 0;
00170 }
00171 
00172 /** @} */
00173 
00174 /**
00175  * @name Send
00176  * @{
00177  */
00178 
00179 /**
00180  * Send raw data over netlink socket.
00181  * @arg sk              Netlink socket.
00182  * @arg buf             Data buffer.
00183  * @arg size            Size of data buffer.
00184  * @return Number of characters written on success or a negative error code.
00185  */
00186 int nl_sendto(struct nl_sock *sk, void *buf, size_t size)
00187 {
00188         int ret;
00189 
00190         ret = sendto(sk->s_fd, buf, size, 0, (struct sockaddr *)
00191                      &sk->s_peer, sizeof(sk->s_peer));
00192         if (ret < 0)
00193                 return -nl_syserr2nlerr(errno);
00194 
00195         return ret;
00196 }
00197 
00198 /**
00199  * Send netlink message with control over sendmsg() message header.
00200  * @arg sk              Netlink socket.
00201  * @arg msg             Netlink message to be sent.
00202  * @arg hdr             Sendmsg() message header.
00203  * @return Number of characters sent on sucess or a negative error code.
00204  */
00205 int nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr)
00206 {
00207         struct nl_cb *cb;
00208         int ret;
00209 
00210         nlmsg_set_src(msg, &sk->s_local);
00211 
00212         cb = sk->s_cb;
00213         if (cb->cb_set[NL_CB_MSG_OUT])
00214                 if ((ret = nl_cb_call(cb, NL_CB_MSG_OUT, msg)) != NL_OK)
00215                         return ret;
00216 
00217         ret = sendmsg(sk->s_fd, hdr, 0);
00218         if (ret < 0)
00219                 return -nl_syserr2nlerr(errno);
00220 
00221         NL_DBG(4, "sent %d bytes\n", ret);
00222         return ret;
00223 }
00224 
00225 
00226 /**
00227  * Send netlink message.
00228  * @arg sk              Netlink socket.
00229  * @arg msg             Netlink message to be sent.
00230  * @arg iov             iovec to be sent.
00231  * @arg iovlen          number of struct iovec to be sent.
00232  * @see nl_sendmsg()
00233  * @return Number of characters sent on success or a negative error code.
00234  */
00235 int nl_send_iovec(struct nl_sock *sk, struct nl_msg *msg, struct iovec *iov, unsigned iovlen)
00236 {
00237         struct sockaddr_nl *dst;
00238         struct ucred *creds;
00239         struct msghdr hdr = {
00240                 .msg_name = (void *) &sk->s_peer,
00241                 .msg_namelen = sizeof(struct sockaddr_nl),
00242                 .msg_iov = iov,
00243                 .msg_iovlen = iovlen,
00244         };
00245 
00246         /* Overwrite destination if specified in the message itself, defaults
00247          * to the peer address of the socket.
00248          */
00249         dst = nlmsg_get_dst(msg);
00250         if (dst->nl_family == AF_NETLINK)
00251                 hdr.msg_name = dst;
00252 
00253         /* Add credentials if present. */
00254         creds = nlmsg_get_creds(msg);
00255         if (creds != NULL) {
00256                 char buf[CMSG_SPACE(sizeof(struct ucred))];
00257                 struct cmsghdr *cmsg;
00258 
00259                 hdr.msg_control = buf;
00260                 hdr.msg_controllen = sizeof(buf);
00261 
00262                 cmsg = CMSG_FIRSTHDR(&hdr);
00263                 cmsg->cmsg_level = SOL_SOCKET;
00264                 cmsg->cmsg_type = SCM_CREDENTIALS;
00265                 cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
00266                 memcpy(CMSG_DATA(cmsg), creds, sizeof(struct ucred));
00267         }
00268 
00269         return nl_sendmsg(sk, msg, &hdr);
00270 }
00271 
00272 
00273 
00274 /**
00275 * Send netlink message.
00276 * @arg sk               Netlink socket.
00277 * @arg msg              Netlink message to be sent.
00278 * @see nl_sendmsg()
00279 * @return Number of characters sent on success or a negative error code.
00280 */
00281 int nl_send(struct nl_sock *sk, struct nl_msg *msg)
00282 {
00283         struct iovec iov = {
00284                 .iov_base = (void *) nlmsg_hdr(msg),
00285                 .iov_len = nlmsg_hdr(msg)->nlmsg_len,
00286         };
00287 
00288         return nl_send_iovec(sk, msg, &iov, 1);
00289 }
00290 
00291 void nl_complete_msg(struct nl_sock *sk, struct nl_msg *msg)
00292 {
00293         struct nlmsghdr *nlh;
00294 
00295         nlh = nlmsg_hdr(msg);
00296         if (nlh->nlmsg_pid == 0)
00297                 nlh->nlmsg_pid = sk->s_local.nl_pid;
00298 
00299         if (nlh->nlmsg_seq == 0)
00300                 nlh->nlmsg_seq = sk->s_seq_next++;
00301 
00302         if (msg->nm_protocol == -1)
00303                 msg->nm_protocol = sk->s_proto;
00304 
00305         nlh->nlmsg_flags |= NLM_F_REQUEST;
00306 
00307         if (!(sk->s_flags & NL_NO_AUTO_ACK))
00308                 nlh->nlmsg_flags |= NLM_F_ACK;
00309 }
00310 
00311 void nl_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
00312 {
00313         nl_complete_msg(sk, msg);
00314 }
00315 
00316 /**
00317  * Automatically complete and send a netlink message
00318  * @arg sk              Netlink socket.
00319  * @arg msg             Netlink message to be sent.
00320  *
00321  * This function takes a netlink message and passes it on to
00322  * nl_auto_complete() for completion.
00323  *
00324  * Checks the netlink message \c nlh for completness and extends it
00325  * as required before sending it out. Checked fields include pid,
00326  * sequence nr, and flags.
00327  *
00328  * @see nl_send()
00329  * @return Number of characters sent or a negative error code.
00330  */
00331 int nl_send_auto(struct nl_sock *sk, struct nl_msg *msg)
00332 {
00333         struct nl_cb *cb = sk->s_cb;
00334 
00335         nl_complete_msg(sk, msg);
00336 
00337         if (cb->cb_send_ow)
00338                 return cb->cb_send_ow(sk, msg);
00339         else
00340                 return nl_send(sk, msg);
00341 }
00342 
00343 int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
00344 {
00345         return nl_send_auto(sk, msg);
00346 }
00347 
00348 /**
00349  * Send simple netlink message using nl_send_auto_complete()
00350  * @arg sk              Netlink socket.
00351  * @arg type            Netlink message type.
00352  * @arg flags           Netlink message flags.
00353  * @arg buf             Data buffer.
00354  * @arg size            Size of data buffer.
00355  *
00356  * Builds a netlink message with the specified type and flags and
00357  * appends the specified data as payload to the message.
00358  *
00359  * @see nl_send_auto_complete()
00360  * @return Number of characters sent on success or a negative error code.
00361  */
00362 int nl_send_simple(struct nl_sock *sk, int type, int flags, void *buf,
00363                    size_t size)
00364 {
00365         int err;
00366         struct nl_msg *msg;
00367 
00368         msg = nlmsg_alloc_simple(type, flags);
00369         if (!msg)
00370                 return -NLE_NOMEM;
00371 
00372         if (buf && size) {
00373                 err = nlmsg_append(msg, buf, size, NLMSG_ALIGNTO);
00374                 if (err < 0)
00375                         goto errout;
00376         }
00377         
00378 
00379         err = nl_send_auto_complete(sk, msg);
00380 errout:
00381         nlmsg_free(msg);
00382 
00383         return err;
00384 }
00385 
00386 /** @} */
00387 
00388 /**
00389  * @name Receive
00390  * @{
00391  */
00392 
00393 /**
00394  * Receive data from netlink socket
00395  * @arg sk              Netlink socket.
00396  * @arg nla             Destination pointer for peer's netlink address.
00397  * @arg buf             Destination pointer for message content.
00398  * @arg creds           Destination pointer for credentials.
00399  *
00400  * Receives a netlink message, allocates a buffer in \c *buf and
00401  * stores the message content. The peer's netlink address is stored
00402  * in \c *nla. The caller is responsible for freeing the buffer allocated
00403  * in \c *buf if a positive value is returned.  Interrupted system calls
00404  * are handled by repeating the read. The input buffer size is determined
00405  * by peeking before the actual read is done.
00406  *
00407  * A non-blocking sockets causes the function to return immediately with
00408  * a return value of 0 if no data is available.
00409  *
00410  * @return Number of octets read, 0 on EOF or a negative error code.
00411  */
00412 int nl_recv(struct nl_sock *sk, struct sockaddr_nl *nla,
00413             unsigned char **buf, struct ucred **creds)
00414 {
00415         int n;
00416         int flags = 0;
00417         static int page_size = 0;
00418         struct iovec iov;
00419         struct msghdr msg = {
00420                 .msg_name = (void *) nla,
00421                 .msg_namelen = sizeof(struct sockaddr_nl),
00422                 .msg_iov = &iov,
00423                 .msg_iovlen = 1,
00424                 .msg_control = NULL,
00425                 .msg_controllen = 0,
00426                 .msg_flags = 0,
00427         };
00428         struct cmsghdr *cmsg;
00429 
00430         memset(nla, 0, sizeof(*nla));
00431 
00432         if (sk->s_flags & NL_MSG_PEEK)
00433                 flags |= MSG_PEEK;
00434 
00435         if (page_size == 0)
00436                 page_size = getpagesize();
00437 
00438         iov.iov_len = page_size;
00439         iov.iov_base = *buf = malloc(iov.iov_len);
00440 
00441         if (sk->s_flags & NL_SOCK_PASSCRED) {
00442                 msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred));
00443                 msg.msg_control = calloc(1, msg.msg_controllen);
00444         }
00445 retry:
00446 
00447         n = recvmsg(sk->s_fd, &msg, flags);
00448         if (!n)
00449                 goto abort;
00450         else if (n < 0) {
00451                 if (errno == EINTR) {
00452                         NL_DBG(3, "recvmsg() returned EINTR, retrying\n");
00453                         goto retry;
00454                 } else if (errno == EAGAIN) {
00455                         NL_DBG(3, "recvmsg() returned EAGAIN, aborting\n");
00456                         goto abort;
00457                 } else {
00458                         free(msg.msg_control);
00459                         free(*buf);
00460                         return -nl_syserr2nlerr(errno);
00461                 }
00462         }
00463 
00464         if (iov.iov_len < n ||
00465             msg.msg_flags & MSG_TRUNC) {
00466                 /* Provided buffer is not long enough, enlarge it
00467                  * and try again. */
00468                 iov.iov_len *= 2;
00469                 iov.iov_base = *buf = realloc(*buf, iov.iov_len);
00470                 goto retry;
00471         } else if (msg.msg_flags & MSG_CTRUNC) {
00472                 msg.msg_controllen *= 2;
00473                 msg.msg_control = realloc(msg.msg_control, msg.msg_controllen);
00474                 goto retry;
00475         } else if (flags != 0) {
00476                 /* Buffer is big enough, do the actual reading */
00477                 flags = 0;
00478                 goto retry;
00479         }
00480 
00481         if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
00482                 free(msg.msg_control);
00483                 free(*buf);
00484                 return -NLE_NOADDR;
00485         }
00486 
00487         for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
00488                 if (cmsg->cmsg_level == SOL_SOCKET &&
00489                     cmsg->cmsg_type == SCM_CREDENTIALS) {
00490                         if (creds) {
00491                                 *creds = calloc(1, sizeof(struct ucred));
00492                                 memcpy(*creds, CMSG_DATA(cmsg), sizeof(struct ucred));
00493                         }
00494                         break;
00495                 }
00496         }
00497 
00498         free(msg.msg_control);
00499         return n;
00500 
00501 abort:
00502         free(msg.msg_control);
00503         free(*buf);
00504         return 0;
00505 }
00506 
00507 #define NL_CB_CALL(cb, type, msg) \
00508 do { \
00509         err = nl_cb_call(cb, type, msg); \
00510         switch (err) { \
00511         case NL_OK: \
00512                 err = 0; \
00513                 break; \
00514         case NL_SKIP: \
00515                 goto skip; \
00516         case NL_STOP: \
00517                 goto stop; \
00518         default: \
00519                 goto out; \
00520         } \
00521 } while (0)
00522 
00523 static int recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
00524 {
00525         int n, err = 0, multipart = 0;
00526         unsigned char *buf = NULL;
00527         struct nlmsghdr *hdr;
00528         struct sockaddr_nl nla = {0};
00529         struct nl_msg *msg = NULL;
00530         struct ucred *creds = NULL;
00531 
00532 continue_reading:
00533         NL_DBG(3, "Attempting to read from %p\n", sk);
00534         if (cb->cb_recv_ow)
00535                 n = cb->cb_recv_ow(sk, &nla, &buf, &creds);
00536         else
00537                 n = nl_recv(sk, &nla, &buf, &creds);
00538 
00539         if (n <= 0)
00540                 return n;
00541 
00542         NL_DBG(3, "recvmsgs(%p): Read %d bytes\n", sk, n);
00543 
00544         hdr = (struct nlmsghdr *) buf;
00545         while (nlmsg_ok(hdr, n)) {
00546                 NL_DBG(3, "recgmsgs(%p): Processing valid message...\n", sk);
00547 
00548                 nlmsg_free(msg);
00549                 msg = nlmsg_convert(hdr);
00550                 if (!msg) {
00551                         err = -NLE_NOMEM;
00552                         goto out;
00553                 }
00554 
00555                 nlmsg_set_proto(msg, sk->s_proto);
00556                 nlmsg_set_src(msg, &nla);
00557                 if (creds)
00558                         nlmsg_set_creds(msg, creds);
00559 
00560                 /* Raw callback is the first, it gives the most control
00561                  * to the user and he can do his very own parsing. */
00562                 if (cb->cb_set[NL_CB_MSG_IN])
00563                         NL_CB_CALL(cb, NL_CB_MSG_IN, msg);
00564 
00565                 /* Sequence number checking. The check may be done by
00566                  * the user, otherwise a very simple check is applied
00567                  * enforcing strict ordering */
00568                 if (cb->cb_set[NL_CB_SEQ_CHECK]) {
00569                         NL_CB_CALL(cb, NL_CB_SEQ_CHECK, msg);
00570 
00571                 /* Only do sequence checking if auto-ack mode is enabled */
00572                 } else if (!(sk->s_flags & NL_NO_AUTO_ACK)) {
00573                         if (hdr->nlmsg_seq != sk->s_seq_expect) {
00574                                 if (cb->cb_set[NL_CB_INVALID])
00575                                         NL_CB_CALL(cb, NL_CB_INVALID, msg);
00576                                 else {
00577                                         err = -NLE_SEQ_MISMATCH;
00578                                         goto out;
00579                                 }
00580                         }
00581                 }
00582 
00583                 if (hdr->nlmsg_type == NLMSG_DONE ||
00584                     hdr->nlmsg_type == NLMSG_ERROR ||
00585                     hdr->nlmsg_type == NLMSG_NOOP ||
00586                     hdr->nlmsg_type == NLMSG_OVERRUN) {
00587                         /* We can't check for !NLM_F_MULTI since some netlink
00588                          * users in the kernel are broken. */
00589                         sk->s_seq_expect++;
00590                         NL_DBG(3, "recvmsgs(%p): Increased expected " \
00591                                "sequence number to %d\n",
00592                                sk, sk->s_seq_expect);
00593                 }
00594 
00595                 if (hdr->nlmsg_flags & NLM_F_MULTI)
00596                         multipart = 1;
00597         
00598                 /* Other side wishes to see an ack for this message */
00599                 if (hdr->nlmsg_flags & NLM_F_ACK) {
00600                         if (cb->cb_set[NL_CB_SEND_ACK])
00601                                 NL_CB_CALL(cb, NL_CB_SEND_ACK, msg);
00602                         else {
00603                                 /* FIXME: implement */
00604                         }
00605                 }
00606 
00607                 /* messages terminates a multpart message, this is
00608                  * usually the end of a message and therefore we slip
00609                  * out of the loop by default. the user may overrule
00610                  * this action by skipping this packet. */
00611                 if (hdr->nlmsg_type == NLMSG_DONE) {
00612                         multipart = 0;
00613                         if (cb->cb_set[NL_CB_FINISH])
00614                                 NL_CB_CALL(cb, NL_CB_FINISH, msg);
00615                 }
00616 
00617                 /* Message to be ignored, the default action is to
00618                  * skip this message if no callback is specified. The
00619                  * user may overrule this action by returning
00620                  * NL_PROCEED. */
00621                 else if (hdr->nlmsg_type == NLMSG_NOOP) {
00622                         if (cb->cb_set[NL_CB_SKIPPED])
00623                                 NL_CB_CALL(cb, NL_CB_SKIPPED, msg);
00624                         else
00625                                 goto skip;
00626                 }
00627 
00628                 /* Data got lost, report back to user. The default action is to
00629                  * quit parsing. The user may overrule this action by retuning
00630                  * NL_SKIP or NL_PROCEED (dangerous) */
00631                 else if (hdr->nlmsg_type == NLMSG_OVERRUN) {
00632                         if (cb->cb_set[NL_CB_OVERRUN])
00633                                 NL_CB_CALL(cb, NL_CB_OVERRUN, msg);
00634                         else {
00635                                 err = -NLE_MSG_OVERFLOW;
00636                                 goto out;
00637                         }
00638                 }
00639 
00640                 /* Message carries a nlmsgerr */
00641                 else if (hdr->nlmsg_type == NLMSG_ERROR) {
00642                         struct nlmsgerr *e = nlmsg_data(hdr);
00643 
00644                         if (hdr->nlmsg_len < nlmsg_size(sizeof(*e))) {
00645                                 /* Truncated error message, the default action
00646                                  * is to stop parsing. The user may overrule
00647                                  * this action by returning NL_SKIP or
00648                                  * NL_PROCEED (dangerous) */
00649                                 if (cb->cb_set[NL_CB_INVALID])
00650                                         NL_CB_CALL(cb, NL_CB_INVALID, msg);
00651                                 else {
00652                                         err = -NLE_MSG_TRUNC;
00653                                         goto out;
00654                                 }
00655                         } else if (e->error) {
00656                                 /* Error message reported back from kernel. */
00657                                 if (cb->cb_err) {
00658                                         err = cb->cb_err(&nla, e,
00659                                                            cb->cb_err_arg);
00660                                         if (err < 0)
00661                                                 goto out;
00662                                         else if (err == NL_SKIP)
00663                                                 goto skip;
00664                                         else if (err == NL_STOP) {
00665                                                 err = -nl_syserr2nlerr(e->error);
00666                                                 goto out;
00667                                         }
00668                                 } else {
00669                                         err = -nl_syserr2nlerr(e->error);
00670                                         goto out;
00671                                 }
00672                         } else if (cb->cb_set[NL_CB_ACK])
00673                                 NL_CB_CALL(cb, NL_CB_ACK, msg);
00674                 } else {
00675                         /* Valid message (not checking for MULTIPART bit to
00676                          * get along with broken kernels. NL_SKIP has no
00677                          * effect on this.  */
00678                         if (cb->cb_set[NL_CB_VALID])
00679                                 NL_CB_CALL(cb, NL_CB_VALID, msg);
00680                 }
00681 skip:
00682                 err = 0;
00683                 hdr = nlmsg_next(hdr, &n);
00684         }
00685         
00686         nlmsg_free(msg);
00687         free(buf);
00688         free(creds);
00689         buf = NULL;
00690         msg = NULL;
00691         creds = NULL;
00692 
00693         if (multipart) {
00694                 /* Multipart message not yet complete, continue reading */
00695                 goto continue_reading;
00696         }
00697 stop:
00698         err = 0;
00699 out:
00700         nlmsg_free(msg);
00701         free(buf);
00702         free(creds);
00703 
00704         return err;
00705 }
00706 
00707 /**
00708  * Receive a set of messages from a netlink socket.
00709  * @arg sk              Netlink socket.
00710  * @arg cb              set of callbacks to control behaviour.
00711  *
00712  * Repeatedly calls nl_recv() or the respective replacement if provided
00713  * by the application (see nl_cb_overwrite_recv()) and parses the
00714  * received data as netlink messages. Stops reading if one of the
00715  * callbacks returns NL_STOP or nl_recv returns either 0 or a negative error code.
00716  *
00717  * A non-blocking sockets causes the function to return immediately if
00718  * no data is available.
00719  *
00720  * @return 0 on success or a negative error code from nl_recv().
00721  */
00722 int nl_recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
00723 {
00724         if (cb->cb_recvmsgs_ow)
00725                 return cb->cb_recvmsgs_ow(sk, cb);
00726         else
00727                 return recvmsgs(sk, cb);
00728 }
00729 
00730 /**
00731  * Receive a set of message from a netlink socket using handlers in nl_sock.
00732  * @arg sk              Netlink socket.
00733  *
00734  * Calls nl_recvmsgs() with the handlers configured in the netlink socket.
00735  */
00736 int nl_recvmsgs_default(struct nl_sock *sk)
00737 {
00738         return nl_recvmsgs(sk, sk->s_cb);
00739 
00740 }
00741 
00742 static int ack_wait_handler(struct nl_msg *msg, void *arg)
00743 {
00744         return NL_STOP;
00745 }
00746 
00747 /**
00748  * Wait for ACK.
00749  * @arg sk              Netlink socket.
00750  * @pre The netlink socket must be in blocking state.
00751  *
00752  * Waits until an ACK is received for the latest not yet acknowledged
00753  * netlink message.
00754  */
00755 int nl_wait_for_ack(struct nl_sock *sk)
00756 {
00757         int err;
00758         struct nl_cb *cb;
00759 
00760         cb = nl_cb_clone(sk->s_cb);
00761         if (cb == NULL)
00762                 return -NLE_NOMEM;
00763 
00764         nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, NULL);
00765         err = nl_recvmsgs(sk, cb);
00766         nl_cb_put(cb);
00767 
00768         return err;
00769 }
00770 
00771 /** @} */
00772 
00773 /** @} */