libnl 2.0

/tmp/buildd/libnl2-2.0/lib/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 (nl_cb_call(cb, NL_CB_MSG_OUT, msg) != NL_OK)
00215                         return 0;
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_auto_complete(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 /**
00312  * Send netlink message and check & extend header values as needed.
00313  * @arg sk              Netlink socket.
00314  * @arg msg             Netlink message to be sent.
00315  *
00316  * Checks the netlink message \c nlh for completness and extends it
00317  * as required before sending it out. Checked fields include pid,
00318  * sequence nr, and flags.
00319  *
00320  * @see nl_send()
00321  * @return Number of characters sent or a negative error code.
00322  */
00323 int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
00324 {
00325         struct nl_cb *cb = sk->s_cb;
00326 
00327         nl_auto_complete(sk, msg);
00328 
00329         if (cb->cb_send_ow)
00330                 return cb->cb_send_ow(sk, msg);
00331         else
00332                 return nl_send(sk, msg);
00333 }
00334 
00335 /**
00336  * Send simple netlink message using nl_send_auto_complete()
00337  * @arg sk              Netlink socket.
00338  * @arg type            Netlink message type.
00339  * @arg flags           Netlink message flags.
00340  * @arg buf             Data buffer.
00341  * @arg size            Size of data buffer.
00342  *
00343  * Builds a netlink message with the specified type and flags and
00344  * appends the specified data as payload to the message.
00345  *
00346  * @see nl_send_auto_complete()
00347  * @return Number of characters sent on success or a negative error code.
00348  */
00349 int nl_send_simple(struct nl_sock *sk, int type, int flags, void *buf,
00350                    size_t size)
00351 {
00352         int err;
00353         struct nl_msg *msg;
00354 
00355         msg = nlmsg_alloc_simple(type, flags);
00356         if (!msg)
00357                 return -NLE_NOMEM;
00358 
00359         if (buf && size) {
00360                 err = nlmsg_append(msg, buf, size, NLMSG_ALIGNTO);
00361                 if (err < 0)
00362                         goto errout;
00363         }
00364         
00365 
00366         err = nl_send_auto_complete(sk, msg);
00367 errout:
00368         nlmsg_free(msg);
00369 
00370         return err;
00371 }
00372 
00373 /** @} */
00374 
00375 /**
00376  * @name Receive
00377  * @{
00378  */
00379 
00380 /**
00381  * Receive data from netlink socket
00382  * @arg sk              Netlink socket.
00383  * @arg nla             Destination pointer for peer's netlink address.
00384  * @arg buf             Destination pointer for message content.
00385  * @arg creds           Destination pointer for credentials.
00386  *
00387  * Receives a netlink message, allocates a buffer in \c *buf and
00388  * stores the message content. The peer's netlink address is stored
00389  * in \c *nla. The caller is responsible for freeing the buffer allocated
00390  * in \c *buf if a positive value is returned.  Interrupted system calls
00391  * are handled by repeating the read. The input buffer size is determined
00392  * by peeking before the actual read is done.
00393  *
00394  * A non-blocking sockets causes the function to return immediately with
00395  * a return value of 0 if no data is available.
00396  *
00397  * @return Number of octets read, 0 on EOF or a negative error code.
00398  */
00399 int nl_recv(struct nl_sock *sk, struct sockaddr_nl *nla,
00400             unsigned char **buf, struct ucred **creds)
00401 {
00402         int n;
00403         int flags = 0;
00404         static int page_size = 0;
00405         struct iovec iov;
00406         struct msghdr msg = {
00407                 .msg_name = (void *) nla,
00408                 .msg_namelen = sizeof(struct sockaddr_nl),
00409                 .msg_iov = &iov,
00410                 .msg_iovlen = 1,
00411                 .msg_control = NULL,
00412                 .msg_controllen = 0,
00413                 .msg_flags = 0,
00414         };
00415         struct cmsghdr *cmsg;
00416 
00417         if (sk->s_flags & NL_MSG_PEEK)
00418                 flags |= MSG_PEEK;
00419 
00420         if (page_size == 0)
00421                 page_size = getpagesize();
00422 
00423         iov.iov_len = page_size;
00424         iov.iov_base = *buf = malloc(iov.iov_len);
00425 
00426         if (sk->s_flags & NL_SOCK_PASSCRED) {
00427                 msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred));
00428                 msg.msg_control = calloc(1, msg.msg_controllen);
00429         }
00430 retry:
00431 
00432         n = recvmsg(sk->s_fd, &msg, flags);
00433         if (!n)
00434                 goto abort;
00435         else if (n < 0) {
00436                 if (errno == EINTR) {
00437                         NL_DBG(3, "recvmsg() returned EINTR, retrying\n");
00438                         goto retry;
00439                 } else if (errno == EAGAIN) {
00440                         NL_DBG(3, "recvmsg() returned EAGAIN, aborting\n");
00441                         goto abort;
00442                 } else {
00443                         free(msg.msg_control);
00444                         free(*buf);
00445                         return -nl_syserr2nlerr(errno);
00446                 }
00447         }
00448 
00449         if (iov.iov_len < n ||
00450             msg.msg_flags & MSG_TRUNC) {
00451                 /* Provided buffer is not long enough, enlarge it
00452                  * and try again. */
00453                 iov.iov_len *= 2;
00454                 iov.iov_base = *buf = realloc(*buf, iov.iov_len);
00455                 goto retry;
00456         } else if (msg.msg_flags & MSG_CTRUNC) {
00457                 msg.msg_controllen *= 2;
00458                 msg.msg_control = realloc(msg.msg_control, msg.msg_controllen);
00459                 goto retry;
00460         } else if (flags != 0) {
00461                 /* Buffer is big enough, do the actual reading */
00462                 flags = 0;
00463                 goto retry;
00464         }
00465 
00466         if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
00467                 free(msg.msg_control);
00468                 free(*buf);
00469                 return -NLE_NOADDR;
00470         }
00471 
00472         for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
00473                 if (cmsg->cmsg_level == SOL_SOCKET &&
00474                     cmsg->cmsg_type == SCM_CREDENTIALS) {
00475                         *creds = calloc(1, sizeof(struct ucred));
00476                         memcpy(*creds, CMSG_DATA(cmsg), sizeof(struct ucred));
00477                         break;
00478                 }
00479         }
00480 
00481         free(msg.msg_control);
00482         return n;
00483 
00484 abort:
00485         free(msg.msg_control);
00486         free(*buf);
00487         return 0;
00488 }
00489 
00490 #define NL_CB_CALL(cb, type, msg) \
00491 do { \
00492         err = nl_cb_call(cb, type, msg); \
00493         switch (err) { \
00494         case NL_OK: \
00495                 err = 0; \
00496                 break; \
00497         case NL_SKIP: \
00498                 goto skip; \
00499         case NL_STOP: \
00500                 goto stop; \
00501         default: \
00502                 goto out; \
00503         } \
00504 } while (0)
00505 
00506 static int recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
00507 {
00508         int n, err = 0, multipart = 0;
00509         unsigned char *buf = NULL;
00510         struct nlmsghdr *hdr;
00511         struct sockaddr_nl nla = {0};
00512         struct nl_msg *msg = NULL;
00513         struct ucred *creds = NULL;
00514 
00515 continue_reading:
00516         NL_DBG(3, "Attempting to read from %p\n", sk);
00517         if (cb->cb_recv_ow)
00518                 n = cb->cb_recv_ow(sk, &nla, &buf, &creds);
00519         else
00520                 n = nl_recv(sk, &nla, &buf, &creds);
00521 
00522         if (n <= 0)
00523                 return n;
00524 
00525         NL_DBG(3, "recvmsgs(%p): Read %d bytes\n", sk, n);
00526 
00527         hdr = (struct nlmsghdr *) buf;
00528         while (nlmsg_ok(hdr, n)) {
00529                 NL_DBG(3, "recgmsgs(%p): Processing valid message...\n", sk);
00530 
00531                 nlmsg_free(msg);
00532                 msg = nlmsg_convert(hdr);
00533                 if (!msg) {
00534                         err = -NLE_NOMEM;
00535                         goto out;
00536                 }
00537 
00538                 nlmsg_set_proto(msg, sk->s_proto);
00539                 nlmsg_set_src(msg, &nla);
00540                 if (creds)
00541                         nlmsg_set_creds(msg, creds);
00542 
00543                 /* Raw callback is the first, it gives the most control
00544                  * to the user and he can do his very own parsing. */
00545                 if (cb->cb_set[NL_CB_MSG_IN])
00546                         NL_CB_CALL(cb, NL_CB_MSG_IN, msg);
00547 
00548                 /* Sequence number checking. The check may be done by
00549                  * the user, otherwise a very simple check is applied
00550                  * enforcing strict ordering */
00551                 if (cb->cb_set[NL_CB_SEQ_CHECK])
00552                         NL_CB_CALL(cb, NL_CB_SEQ_CHECK, msg);
00553                 else if (hdr->nlmsg_seq != sk->s_seq_expect) {
00554                         if (cb->cb_set[NL_CB_INVALID])
00555                                 NL_CB_CALL(cb, NL_CB_INVALID, msg);
00556                         else {
00557                                 err = -NLE_SEQ_MISMATCH;
00558                                 goto out;
00559                         }
00560                 }
00561 
00562                 if (hdr->nlmsg_type == NLMSG_DONE ||
00563                     hdr->nlmsg_type == NLMSG_ERROR ||
00564                     hdr->nlmsg_type == NLMSG_NOOP ||
00565                     hdr->nlmsg_type == NLMSG_OVERRUN) {
00566                         /* We can't check for !NLM_F_MULTI since some netlink
00567                          * users in the kernel are broken. */
00568                         sk->s_seq_expect++;
00569                         NL_DBG(3, "recvmsgs(%p): Increased expected " \
00570                                "sequence number to %d\n",
00571                                sk, sk->s_seq_expect);
00572                 }
00573 
00574                 if (hdr->nlmsg_flags & NLM_F_MULTI)
00575                         multipart = 1;
00576         
00577                 /* Other side wishes to see an ack for this message */
00578                 if (hdr->nlmsg_flags & NLM_F_ACK) {
00579                         if (cb->cb_set[NL_CB_SEND_ACK])
00580                                 NL_CB_CALL(cb, NL_CB_SEND_ACK, msg);
00581                         else {
00582                                 /* FIXME: implement */
00583                         }
00584                 }
00585 
00586                 /* messages terminates a multpart message, this is
00587                  * usually the end of a message and therefore we slip
00588                  * out of the loop by default. the user may overrule
00589                  * this action by skipping this packet. */
00590                 if (hdr->nlmsg_type == NLMSG_DONE) {
00591                         multipart = 0;
00592                         if (cb->cb_set[NL_CB_FINISH])
00593                                 NL_CB_CALL(cb, NL_CB_FINISH, msg);
00594                 }
00595 
00596                 /* Message to be ignored, the default action is to
00597                  * skip this message if no callback is specified. The
00598                  * user may overrule this action by returning
00599                  * NL_PROCEED. */
00600                 else if (hdr->nlmsg_type == NLMSG_NOOP) {
00601                         if (cb->cb_set[NL_CB_SKIPPED])
00602                                 NL_CB_CALL(cb, NL_CB_SKIPPED, msg);
00603                         else
00604                                 goto skip;
00605                 }
00606 
00607                 /* Data got lost, report back to user. The default action is to
00608                  * quit parsing. The user may overrule this action by retuning
00609                  * NL_SKIP or NL_PROCEED (dangerous) */
00610                 else if (hdr->nlmsg_type == NLMSG_OVERRUN) {
00611                         if (cb->cb_set[NL_CB_OVERRUN])
00612                                 NL_CB_CALL(cb, NL_CB_OVERRUN, msg);
00613                         else {
00614                                 err = -NLE_MSG_OVERFLOW;
00615                                 goto out;
00616                         }
00617                 }
00618 
00619                 /* Message carries a nlmsgerr */
00620                 else if (hdr->nlmsg_type == NLMSG_ERROR) {
00621                         struct nlmsgerr *e = nlmsg_data(hdr);
00622 
00623                         if (hdr->nlmsg_len < nlmsg_msg_size(sizeof(*e))) {
00624                                 /* Truncated error message, the default action
00625                                  * is to stop parsing. The user may overrule
00626                                  * this action by returning NL_SKIP or
00627                                  * NL_PROCEED (dangerous) */
00628                                 if (cb->cb_set[NL_CB_INVALID])
00629                                         NL_CB_CALL(cb, NL_CB_INVALID, msg);
00630                                 else {
00631                                         err = -NLE_MSG_TRUNC;
00632                                         goto out;
00633                                 }
00634                         } else if (e->error) {
00635                                 /* Error message reported back from kernel. */
00636                                 if (cb->cb_err) {
00637                                         err = cb->cb_err(&nla, e,
00638                                                            cb->cb_err_arg);
00639                                         if (err < 0)
00640                                                 goto out;
00641                                         else if (err == NL_SKIP)
00642                                                 goto skip;
00643                                         else if (err == NL_STOP) {
00644                                                 err = -nl_syserr2nlerr(e->error);
00645                                                 goto out;
00646                                         }
00647                                 } else {
00648                                         err = -nl_syserr2nlerr(e->error);
00649                                         goto out;
00650                                 }
00651                         } else if (cb->cb_set[NL_CB_ACK])
00652                                 NL_CB_CALL(cb, NL_CB_ACK, msg);
00653                 } else {
00654                         /* Valid message (not checking for MULTIPART bit to
00655                          * get along with broken kernels. NL_SKIP has no
00656                          * effect on this.  */
00657                         if (cb->cb_set[NL_CB_VALID])
00658                                 NL_CB_CALL(cb, NL_CB_VALID, msg);
00659                 }
00660 skip:
00661                 err = 0;
00662                 hdr = nlmsg_next(hdr, &n);
00663         }
00664         
00665         nlmsg_free(msg);
00666         free(buf);
00667         free(creds);
00668         buf = NULL;
00669         msg = NULL;
00670         creds = NULL;
00671 
00672         if (multipart) {
00673                 /* Multipart message not yet complete, continue reading */
00674                 goto continue_reading;
00675         }
00676 stop:
00677         err = 0;
00678 out:
00679         nlmsg_free(msg);
00680         free(buf);
00681         free(creds);
00682 
00683         return err;
00684 }
00685 
00686 /**
00687  * Receive a set of messages from a netlink socket.
00688  * @arg sk              Netlink socket.
00689  * @arg cb              set of callbacks to control behaviour.
00690  *
00691  * Repeatedly calls nl_recv() or the respective replacement if provided
00692  * by the application (see nl_cb_overwrite_recv()) and parses the
00693  * received data as netlink messages. Stops reading if one of the
00694  * callbacks returns NL_STOP or nl_recv returns either 0 or a negative error code.
00695  *
00696  * A non-blocking sockets causes the function to return immediately if
00697  * no data is available.
00698  *
00699  * @return 0 on success or a negative error code from nl_recv().
00700  */
00701 int nl_recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
00702 {
00703         if (cb->cb_recvmsgs_ow)
00704                 return cb->cb_recvmsgs_ow(sk, cb);
00705         else
00706                 return recvmsgs(sk, cb);
00707 }
00708 
00709 /**
00710  * Receive a set of message from a netlink socket using handlers in nl_sock.
00711  * @arg sk              Netlink socket.
00712  *
00713  * Calls nl_recvmsgs() with the handlers configured in the netlink socket.
00714  */
00715 int nl_recvmsgs_default(struct nl_sock *sk)
00716 {
00717         return nl_recvmsgs(sk, sk->s_cb);
00718 
00719 }
00720 
00721 static int ack_wait_handler(struct nl_msg *msg, void *arg)
00722 {
00723         return NL_STOP;
00724 }
00725 
00726 /**
00727  * Wait for ACK.
00728  * @arg sk              Netlink socket.
00729  * @pre The netlink socket must be in blocking state.
00730  *
00731  * Waits until an ACK is received for the latest not yet acknowledged
00732  * netlink message.
00733  */
00734 int nl_wait_for_ack(struct nl_sock *sk)
00735 {
00736         int err;
00737         struct nl_cb *cb;
00738 
00739         cb = nl_cb_clone(sk->s_cb);
00740         if (cb == NULL)
00741                 return -NLE_NOMEM;
00742 
00743         nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, NULL);
00744         err = nl_recvmsgs(sk, cb);
00745         nl_cb_put(cb);
00746 
00747         return err;
00748 }
00749 
00750 /** @} */
00751 
00752 /** @} */