libnl  3.2.3
/build/buildd/libnl3-3.2.3/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  * @note SOCK_CLOEXEC is set on the socket if available.
00105  *
00106  * @return 0 on success or a negative error code.
00107  */
00108 int nl_connect(struct nl_sock *sk, int protocol)
00109 {
00110         int err, flags = 0;
00111         socklen_t addrlen;
00112 
00113 #ifdef SOCK_CLOEXEC
00114         flags |= SOCK_CLOEXEC;
00115 #endif
00116 
00117         sk->s_fd = socket(AF_NETLINK, SOCK_RAW | flags, protocol);
00118         if (sk->s_fd < 0) {
00119                 err = -nl_syserr2nlerr(errno);
00120                 goto errout;
00121         }
00122 
00123         if (!(sk->s_flags & NL_SOCK_BUFSIZE_SET)) {
00124                 err = nl_socket_set_buffer_size(sk, 0, 0);
00125                 if (err < 0)
00126                         goto errout;
00127         }
00128 
00129         err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local,
00130                    sizeof(sk->s_local));
00131         if (err < 0) {
00132                 err = -nl_syserr2nlerr(errno);
00133                 goto errout;
00134         }
00135 
00136         addrlen = sizeof(sk->s_local);
00137         err = getsockname(sk->s_fd, (struct sockaddr *) &sk->s_local,
00138                           &addrlen);
00139         if (err < 0) {
00140                 err = -nl_syserr2nlerr(errno);
00141                 goto errout;
00142         }
00143 
00144         if (addrlen != sizeof(sk->s_local)) {
00145                 err = -NLE_NOADDR;
00146                 goto errout;
00147         }
00148 
00149         if (sk->s_local.nl_family != AF_NETLINK) {
00150                 err = -NLE_AF_NOSUPPORT;
00151                 goto errout;
00152         }
00153 
00154         sk->s_proto = protocol;
00155 
00156         return 0;
00157 errout:
00158         close(sk->s_fd);
00159         sk->s_fd = -1;
00160 
00161         return err;
00162 }
00163 
00164 /**
00165  * Close/Disconnect netlink socket.
00166  * @arg sk              Netlink socket.
00167  */
00168 void nl_close(struct nl_sock *sk)
00169 {
00170         if (sk->s_fd >= 0) {
00171                 close(sk->s_fd);
00172                 sk->s_fd = -1;
00173         }
00174 
00175         sk->s_proto = 0;
00176 }
00177 
00178 /** @} */
00179 
00180 /**
00181  * @name Send
00182  * @{
00183  */
00184 
00185 /**
00186  * Send raw data over netlink socket.
00187  * @arg sk              Netlink socket.
00188  * @arg buf             Data buffer.
00189  * @arg size            Size of data buffer.
00190  * @return Number of characters written on success or a negative error code.
00191  */
00192 int nl_sendto(struct nl_sock *sk, void *buf, size_t size)
00193 {
00194         int ret;
00195 
00196         ret = sendto(sk->s_fd, buf, size, 0, (struct sockaddr *)
00197                      &sk->s_peer, sizeof(sk->s_peer));
00198         if (ret < 0)
00199                 return -nl_syserr2nlerr(errno);
00200 
00201         return ret;
00202 }
00203 
00204 /**
00205  * Send netlink message with control over sendmsg() message header.
00206  * @arg sk              Netlink socket.
00207  * @arg msg             Netlink message to be sent.
00208  * @arg hdr             Sendmsg() message header.
00209  * @return Number of characters sent on sucess or a negative error code.
00210  */
00211 int nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr)
00212 {
00213         struct nl_cb *cb;
00214         int ret;
00215 
00216         nlmsg_set_src(msg, &sk->s_local);
00217 
00218         cb = sk->s_cb;
00219         if (cb->cb_set[NL_CB_MSG_OUT])
00220                 if ((ret = nl_cb_call(cb, NL_CB_MSG_OUT, msg)) != NL_OK)
00221                         return ret;
00222 
00223         ret = sendmsg(sk->s_fd, hdr, 0);
00224         if (ret < 0)
00225                 return -nl_syserr2nlerr(errno);
00226 
00227         NL_DBG(4, "sent %d bytes\n", ret);
00228         return ret;
00229 }
00230 
00231 
00232 /**
00233  * Send netlink message.
00234  * @arg sk              Netlink socket.
00235  * @arg msg             Netlink message to be sent.
00236  * @arg iov             iovec to be sent.
00237  * @arg iovlen          number of struct iovec to be sent.
00238  * @see nl_sendmsg()
00239  * @return Number of characters sent on success or a negative error code.
00240  */
00241 int nl_send_iovec(struct nl_sock *sk, struct nl_msg *msg, struct iovec *iov, unsigned iovlen)
00242 {
00243         struct sockaddr_nl *dst;
00244         struct ucred *creds;
00245         struct msghdr hdr = {
00246                 .msg_name = (void *) &sk->s_peer,
00247                 .msg_namelen = sizeof(struct sockaddr_nl),
00248                 .msg_iov = iov,
00249                 .msg_iovlen = iovlen,
00250         };
00251 
00252         /* Overwrite destination if specified in the message itself, defaults
00253          * to the peer address of the socket.
00254          */
00255         dst = nlmsg_get_dst(msg);
00256         if (dst->nl_family == AF_NETLINK)
00257                 hdr.msg_name = dst;
00258 
00259         /* Add credentials if present. */
00260         creds = nlmsg_get_creds(msg);
00261         if (creds != NULL) {
00262                 char buf[CMSG_SPACE(sizeof(struct ucred))];
00263                 struct cmsghdr *cmsg;
00264 
00265                 hdr.msg_control = buf;
00266                 hdr.msg_controllen = sizeof(buf);
00267 
00268                 cmsg = CMSG_FIRSTHDR(&hdr);
00269                 cmsg->cmsg_level = SOL_SOCKET;
00270                 cmsg->cmsg_type = SCM_CREDENTIALS;
00271                 cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
00272                 memcpy(CMSG_DATA(cmsg), creds, sizeof(struct ucred));
00273         }
00274 
00275         return nl_sendmsg(sk, msg, &hdr);
00276 }
00277 
00278 
00279 
00280 /**
00281 * Send netlink message.
00282 * @arg sk               Netlink socket.
00283 * @arg msg              Netlink message to be sent.
00284 * @see nl_sendmsg()
00285 * @return Number of characters sent on success or a negative error code.
00286 */
00287 int nl_send(struct nl_sock *sk, struct nl_msg *msg)
00288 {
00289         struct iovec iov = {
00290                 .iov_base = (void *) nlmsg_hdr(msg),
00291                 .iov_len = nlmsg_hdr(msg)->nlmsg_len,
00292         };
00293 
00294         return nl_send_iovec(sk, msg, &iov, 1);
00295 }
00296 
00297 void nl_complete_msg(struct nl_sock *sk, struct nl_msg *msg)
00298 {
00299         struct nlmsghdr *nlh;
00300 
00301         nlh = nlmsg_hdr(msg);
00302         if (nlh->nlmsg_pid == 0)
00303                 nlh->nlmsg_pid = sk->s_local.nl_pid;
00304 
00305         if (nlh->nlmsg_seq == 0)
00306                 nlh->nlmsg_seq = sk->s_seq_next++;
00307 
00308         if (msg->nm_protocol == -1)
00309                 msg->nm_protocol = sk->s_proto;
00310 
00311         nlh->nlmsg_flags |= NLM_F_REQUEST;
00312 
00313         if (!(sk->s_flags & NL_NO_AUTO_ACK))
00314                 nlh->nlmsg_flags |= NLM_F_ACK;
00315 }
00316 
00317 void nl_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
00318 {
00319         nl_complete_msg(sk, msg);
00320 }
00321 
00322 /**
00323  * Automatically complete and send a netlink message
00324  * @arg sk              Netlink socket.
00325  * @arg msg             Netlink message to be sent.
00326  *
00327  * This function takes a netlink message and passes it on to
00328  * nl_auto_complete() for completion.
00329  *
00330  * Checks the netlink message \c nlh for completness and extends it
00331  * as required before sending it out. Checked fields include pid,
00332  * sequence nr, and flags.
00333  *
00334  * @see nl_send()
00335  * @return Number of characters sent or a negative error code.
00336  */
00337 int nl_send_auto(struct nl_sock *sk, struct nl_msg *msg)
00338 {
00339         struct nl_cb *cb = sk->s_cb;
00340 
00341         nl_complete_msg(sk, msg);
00342 
00343         if (cb->cb_send_ow)
00344                 return cb->cb_send_ow(sk, msg);
00345         else
00346                 return nl_send(sk, msg);
00347 }
00348 
00349 int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
00350 {
00351         return nl_send_auto(sk, msg);
00352 }
00353 
00354 /**
00355  * Send netlink message and wait for response (sync request-response)
00356  * @arg sk              Netlink socket
00357  * @arg msg             Netlink message to be sent
00358  *
00359  * This function takes a netlink message and sends it using nl_send_auto().
00360  * It will then wait for the response (ACK or error message) to be
00361  * received. Threfore this function will block until the operation has
00362  * been completed.
00363  *
00364  * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause
00365  *       this function to return immediately after sending. In this case,
00366  *       it is the responsibility of the caller to handle any eventual
00367  *       error messages returned.
00368  *
00369  * @see nl_send_auto().
00370  *
00371  * @return 0 on success or a negative error code.
00372  */
00373 int nl_send_sync(struct nl_sock *sk, struct nl_msg *msg)
00374 {
00375         int err;
00376 
00377         err = nl_send_auto(sk, msg);
00378         nlmsg_free(msg);
00379         if (err < 0)
00380                 return err;
00381 
00382         return wait_for_ack(sk);
00383 }
00384 
00385 /**
00386  * Send simple netlink message using nl_send_auto_complete()
00387  * @arg sk              Netlink socket.
00388  * @arg type            Netlink message type.
00389  * @arg flags           Netlink message flags.
00390  * @arg buf             Data buffer.
00391  * @arg size            Size of data buffer.
00392  *
00393  * Builds a netlink message with the specified type and flags and
00394  * appends the specified data as payload to the message.
00395  *
00396  * @see nl_send_auto_complete()
00397  * @return Number of characters sent on success or a negative error code.
00398  */
00399 int nl_send_simple(struct nl_sock *sk, int type, int flags, void *buf,
00400                    size_t size)
00401 {
00402         int err;
00403         struct nl_msg *msg;
00404 
00405         msg = nlmsg_alloc_simple(type, flags);
00406         if (!msg)
00407                 return -NLE_NOMEM;
00408 
00409         if (buf && size) {
00410                 err = nlmsg_append(msg, buf, size, NLMSG_ALIGNTO);
00411                 if (err < 0)
00412                         goto errout;
00413         }
00414         
00415 
00416         err = nl_send_auto_complete(sk, msg);
00417 errout:
00418         nlmsg_free(msg);
00419 
00420         return err;
00421 }
00422 
00423 /** @} */
00424 
00425 /**
00426  * @name Receive
00427  * @{
00428  */
00429 
00430 /**
00431  * Receive data from netlink socket
00432  * @arg sk              Netlink socket.
00433  * @arg nla             Destination pointer for peer's netlink address.
00434  * @arg buf             Destination pointer for message content.
00435  * @arg creds           Destination pointer for credentials.
00436  *
00437  * Receives a netlink message, allocates a buffer in \c *buf and
00438  * stores the message content. The peer's netlink address is stored
00439  * in \c *nla. The caller is responsible for freeing the buffer allocated
00440  * in \c *buf if a positive value is returned.  Interrupted system calls
00441  * are handled by repeating the read. The input buffer size is determined
00442  * by peeking before the actual read is done.
00443  *
00444  * A non-blocking sockets causes the function to return immediately with
00445  * a return value of 0 if no data is available.
00446  *
00447  * @return Number of octets read, 0 on EOF or a negative error code.
00448  */
00449 int nl_recv(struct nl_sock *sk, struct sockaddr_nl *nla,
00450             unsigned char **buf, struct ucred **creds)
00451 {
00452         int n;
00453         int flags = 0;
00454         static int page_size = 0;
00455         struct iovec iov;
00456         struct msghdr msg = {
00457                 .msg_name = (void *) nla,
00458                 .msg_namelen = sizeof(struct sockaddr_nl),
00459                 .msg_iov = &iov,
00460                 .msg_iovlen = 1,
00461                 .msg_control = NULL,
00462                 .msg_controllen = 0,
00463                 .msg_flags = 0,
00464         };
00465         struct cmsghdr *cmsg;
00466 
00467         memset(nla, 0, sizeof(*nla));
00468 
00469         if (sk->s_flags & NL_MSG_PEEK)
00470                 flags |= MSG_PEEK;
00471 
00472         if (page_size == 0)
00473                 page_size = getpagesize();
00474 
00475         iov.iov_len = page_size;
00476         iov.iov_base = *buf = malloc(iov.iov_len);
00477 
00478         if (sk->s_flags & NL_SOCK_PASSCRED) {
00479                 msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred));
00480                 msg.msg_control = calloc(1, msg.msg_controllen);
00481         }
00482 retry:
00483 
00484         n = recvmsg(sk->s_fd, &msg, flags);
00485         if (!n)
00486                 goto abort;
00487         else if (n < 0) {
00488                 if (errno == EINTR) {
00489                         NL_DBG(3, "recvmsg() returned EINTR, retrying\n");
00490                         goto retry;
00491                 } else if (errno == EAGAIN) {
00492                         NL_DBG(3, "recvmsg() returned EAGAIN, aborting\n");
00493                         goto abort;
00494                 } else {
00495                         free(msg.msg_control);
00496                         free(*buf);
00497                         return -nl_syserr2nlerr(errno);
00498                 }
00499         }
00500 
00501         if (iov.iov_len < n ||
00502             msg.msg_flags & MSG_TRUNC) {
00503                 /* Provided buffer is not long enough, enlarge it
00504                  * and try again. */
00505                 iov.iov_len *= 2;
00506                 iov.iov_base = *buf = realloc(*buf, iov.iov_len);
00507                 goto retry;
00508         } else if (msg.msg_flags & MSG_CTRUNC) {
00509                 msg.msg_controllen *= 2;
00510                 msg.msg_control = realloc(msg.msg_control, msg.msg_controllen);
00511                 goto retry;
00512         } else if (flags != 0) {
00513                 /* Buffer is big enough, do the actual reading */
00514                 flags = 0;
00515                 goto retry;
00516         }
00517 
00518         if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
00519                 free(msg.msg_control);
00520                 free(*buf);
00521                 return -NLE_NOADDR;
00522         }
00523 
00524         for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
00525                 if (cmsg->cmsg_level == SOL_SOCKET &&
00526                     cmsg->cmsg_type == SCM_CREDENTIALS) {
00527                         if (creds) {
00528                                 *creds = calloc(1, sizeof(struct ucred));
00529                                 memcpy(*creds, CMSG_DATA(cmsg), sizeof(struct ucred));
00530                         }
00531                         break;
00532                 }
00533         }
00534 
00535         free(msg.msg_control);
00536         return n;
00537 
00538 abort:
00539         free(msg.msg_control);
00540         free(*buf);
00541         return 0;
00542 }
00543 
00544 #define NL_CB_CALL(cb, type, msg) \
00545 do { \
00546         err = nl_cb_call(cb, type, msg); \
00547         switch (err) { \
00548         case NL_OK: \
00549                 err = 0; \
00550                 break; \
00551         case NL_SKIP: \
00552                 goto skip; \
00553         case NL_STOP: \
00554                 goto stop; \
00555         default: \
00556                 goto out; \
00557         } \
00558 } while (0)
00559 
00560 static int recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
00561 {
00562         int n, err = 0, multipart = 0, interrupted = 0;
00563         unsigned char *buf = NULL;
00564         struct nlmsghdr *hdr;
00565         struct sockaddr_nl nla = {0};
00566         struct nl_msg *msg = NULL;
00567         struct ucred *creds = NULL;
00568 
00569 continue_reading:
00570         NL_DBG(3, "Attempting to read from %p\n", sk);
00571         if (cb->cb_recv_ow)
00572                 n = cb->cb_recv_ow(sk, &nla, &buf, &creds);
00573         else
00574                 n = nl_recv(sk, &nla, &buf, &creds);
00575 
00576         if (n <= 0)
00577                 return n;
00578 
00579         NL_DBG(3, "recvmsgs(%p): Read %d bytes\n", sk, n);
00580 
00581         hdr = (struct nlmsghdr *) buf;
00582         while (nlmsg_ok(hdr, n)) {
00583                 NL_DBG(3, "recvmsgs(%p): Processing valid message...\n", sk);
00584 
00585                 nlmsg_free(msg);
00586                 msg = nlmsg_convert(hdr);
00587                 if (!msg) {
00588                         err = -NLE_NOMEM;
00589                         goto out;
00590                 }
00591 
00592                 nlmsg_set_proto(msg, sk->s_proto);
00593                 nlmsg_set_src(msg, &nla);
00594                 if (creds)
00595                         nlmsg_set_creds(msg, creds);
00596 
00597                 /* Raw callback is the first, it gives the most control
00598                  * to the user and he can do his very own parsing. */
00599                 if (cb->cb_set[NL_CB_MSG_IN])
00600                         NL_CB_CALL(cb, NL_CB_MSG_IN, msg);
00601 
00602                 /* Sequence number checking. The check may be done by
00603                  * the user, otherwise a very simple check is applied
00604                  * enforcing strict ordering */
00605                 if (cb->cb_set[NL_CB_SEQ_CHECK]) {
00606                         NL_CB_CALL(cb, NL_CB_SEQ_CHECK, msg);
00607 
00608                 /* Only do sequence checking if auto-ack mode is enabled */
00609                 } else if (!(sk->s_flags & NL_NO_AUTO_ACK)) {
00610                         if (hdr->nlmsg_seq != sk->s_seq_expect) {
00611                                 if (cb->cb_set[NL_CB_INVALID])
00612                                         NL_CB_CALL(cb, NL_CB_INVALID, msg);
00613                                 else {
00614                                         err = -NLE_SEQ_MISMATCH;
00615                                         goto out;
00616                                 }
00617                         }
00618                 }
00619 
00620                 if (hdr->nlmsg_type == NLMSG_DONE ||
00621                     hdr->nlmsg_type == NLMSG_ERROR ||
00622                     hdr->nlmsg_type == NLMSG_NOOP ||
00623                     hdr->nlmsg_type == NLMSG_OVERRUN) {
00624                         /* We can't check for !NLM_F_MULTI since some netlink
00625                          * users in the kernel are broken. */
00626                         sk->s_seq_expect++;
00627                         NL_DBG(3, "recvmsgs(%p): Increased expected " \
00628                                "sequence number to %d\n",
00629                                sk, sk->s_seq_expect);
00630                 }
00631 
00632                 if (hdr->nlmsg_flags & NLM_F_MULTI)
00633                         multipart = 1;
00634 
00635                 if (hdr->nlmsg_flags & NLM_F_DUMP_INTR) {
00636                         if (cb->cb_set[NL_CB_DUMP_INTR])
00637                                 NL_CB_CALL(cb, NL_CB_DUMP_INTR, msg);
00638                         else {
00639                                 /*
00640                                  * We have to continue reading to clear
00641                                  * all messages until a NLMSG_DONE is
00642                                  * received and report the inconsistency.
00643                                  */
00644                                 interrupted = 1;
00645                         }
00646                 }
00647         
00648                 /* Other side wishes to see an ack for this message */
00649                 if (hdr->nlmsg_flags & NLM_F_ACK) {
00650                         if (cb->cb_set[NL_CB_SEND_ACK])
00651                                 NL_CB_CALL(cb, NL_CB_SEND_ACK, msg);
00652                         else {
00653                                 /* FIXME: implement */
00654                         }
00655                 }
00656 
00657                 /* messages terminates a multpart message, this is
00658                  * usually the end of a message and therefore we slip
00659                  * out of the loop by default. the user may overrule
00660                  * this action by skipping this packet. */
00661                 if (hdr->nlmsg_type == NLMSG_DONE) {
00662                         multipart = 0;
00663                         if (cb->cb_set[NL_CB_FINISH])
00664                                 NL_CB_CALL(cb, NL_CB_FINISH, msg);
00665                 }
00666 
00667                 /* Message to be ignored, the default action is to
00668                  * skip this message if no callback is specified. The
00669                  * user may overrule this action by returning
00670                  * NL_PROCEED. */
00671                 else if (hdr->nlmsg_type == NLMSG_NOOP) {
00672                         if (cb->cb_set[NL_CB_SKIPPED])
00673                                 NL_CB_CALL(cb, NL_CB_SKIPPED, msg);
00674                         else
00675                                 goto skip;
00676                 }
00677 
00678                 /* Data got lost, report back to user. The default action is to
00679                  * quit parsing. The user may overrule this action by retuning
00680                  * NL_SKIP or NL_PROCEED (dangerous) */
00681                 else if (hdr->nlmsg_type == NLMSG_OVERRUN) {
00682                         if (cb->cb_set[NL_CB_OVERRUN])
00683                                 NL_CB_CALL(cb, NL_CB_OVERRUN, msg);
00684                         else {
00685                                 err = -NLE_MSG_OVERFLOW;
00686                                 goto out;
00687                         }
00688                 }
00689 
00690                 /* Message carries a nlmsgerr */
00691                 else if (hdr->nlmsg_type == NLMSG_ERROR) {
00692                         struct nlmsgerr *e = nlmsg_data(hdr);
00693 
00694                         if (hdr->nlmsg_len < nlmsg_size(sizeof(*e))) {
00695                                 /* Truncated error message, the default action
00696                                  * is to stop parsing. The user may overrule
00697                                  * this action by returning NL_SKIP or
00698                                  * NL_PROCEED (dangerous) */
00699                                 if (cb->cb_set[NL_CB_INVALID])
00700                                         NL_CB_CALL(cb, NL_CB_INVALID, msg);
00701                                 else {
00702                                         err = -NLE_MSG_TRUNC;
00703                                         goto out;
00704                                 }
00705                         } else if (e->error) {
00706                                 /* Error message reported back from kernel. */
00707                                 if (cb->cb_err) {
00708                                         err = cb->cb_err(&nla, e,
00709                                                            cb->cb_err_arg);
00710                                         if (err < 0)
00711                                                 goto out;
00712                                         else if (err == NL_SKIP)
00713                                                 goto skip;
00714                                         else if (err == NL_STOP) {
00715                                                 err = -nl_syserr2nlerr(e->error);
00716                                                 goto out;
00717                                         }
00718                                 } else {
00719                                         err = -nl_syserr2nlerr(e->error);
00720                                         goto out;
00721                                 }
00722                         } else if (cb->cb_set[NL_CB_ACK])
00723                                 NL_CB_CALL(cb, NL_CB_ACK, msg);
00724                 } else {
00725                         /* Valid message (not checking for MULTIPART bit to
00726                          * get along with broken kernels. NL_SKIP has no
00727                          * effect on this.  */
00728                         if (cb->cb_set[NL_CB_VALID])
00729                                 NL_CB_CALL(cb, NL_CB_VALID, msg);
00730                 }
00731 skip:
00732                 err = 0;
00733                 hdr = nlmsg_next(hdr, &n);
00734         }
00735         
00736         nlmsg_free(msg);
00737         free(buf);
00738         free(creds);
00739         buf = NULL;
00740         msg = NULL;
00741         creds = NULL;
00742 
00743         if (multipart) {
00744                 /* Multipart message not yet complete, continue reading */
00745                 goto continue_reading;
00746         }
00747 stop:
00748         err = 0;
00749 out:
00750         nlmsg_free(msg);
00751         free(buf);
00752         free(creds);
00753 
00754         if (interrupted)
00755                 err = -NLE_DUMP_INTR;
00756 
00757         return err;
00758 }
00759 
00760 /**
00761  * Receive a set of messages from a netlink socket.
00762  * @arg sk              Netlink socket.
00763  * @arg cb              set of callbacks to control behaviour.
00764  *
00765  * Repeatedly calls nl_recv() or the respective replacement if provided
00766  * by the application (see nl_cb_overwrite_recv()) and parses the
00767  * received data as netlink messages. Stops reading if one of the
00768  * callbacks returns NL_STOP or nl_recv returns either 0 or a negative error code.
00769  *
00770  * A non-blocking sockets causes the function to return immediately if
00771  * no data is available.
00772  *
00773  * @return 0 on success or a negative error code from nl_recv().
00774  */
00775 int nl_recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
00776 {
00777         if (cb->cb_recvmsgs_ow)
00778                 return cb->cb_recvmsgs_ow(sk, cb);
00779         else
00780                 return recvmsgs(sk, cb);
00781 }
00782 
00783 /**
00784  * Receive a set of message from a netlink socket using handlers in nl_sock.
00785  * @arg sk              Netlink socket.
00786  *
00787  * Calls nl_recvmsgs() with the handlers configured in the netlink socket.
00788  */
00789 int nl_recvmsgs_default(struct nl_sock *sk)
00790 {
00791         return nl_recvmsgs(sk, sk->s_cb);
00792 
00793 }
00794 
00795 static int ack_wait_handler(struct nl_msg *msg, void *arg)
00796 {
00797         return NL_STOP;
00798 }
00799 
00800 /**
00801  * Wait for ACK.
00802  * @arg sk              Netlink socket.
00803  * @pre The netlink socket must be in blocking state.
00804  *
00805  * Waits until an ACK is received for the latest not yet acknowledged
00806  * netlink message.
00807  */
00808 int nl_wait_for_ack(struct nl_sock *sk)
00809 {
00810         int err;
00811         struct nl_cb *cb;
00812 
00813         cb = nl_cb_clone(sk->s_cb);
00814         if (cb == NULL)
00815                 return -NLE_NOMEM;
00816 
00817         nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, NULL);
00818         err = nl_recvmsgs(sk, cb);
00819         nl_cb_put(cb);
00820 
00821         return err;
00822 }
00823 
00824 /** @cond SKIP */
00825 struct pickup_param
00826 {
00827         int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *,
00828                       struct nlmsghdr *, struct nl_parser_param *);
00829         struct nl_object *result;
00830 };
00831 
00832 static int __store_answer(struct nl_object *obj, struct nl_parser_param *p)
00833 {
00834         struct pickup_param *pp = p->pp_arg;
00835         /*
00836          * the parser will put() the object at the end, expecting the cache
00837          * to take the reference.
00838          */
00839         nl_object_get(obj);
00840         pp->result =  obj;
00841 
00842         return 0;
00843 }
00844 
00845 static int __pickup_answer(struct nl_msg *msg, void *arg)
00846 {
00847         struct pickup_param *pp = arg;
00848         struct nl_parser_param parse_arg = {
00849                 .pp_cb = __store_answer,
00850                 .pp_arg = pp,
00851         };
00852 
00853         return pp->parser(NULL, &msg->nm_src, msg->nm_nlh, &parse_arg);
00854 }
00855 
00856 /** @endcond */
00857 
00858 /**
00859  * Pickup netlink answer, parse is and return object
00860  * @arg sk              Netlink socket
00861  * @arg parser          Parser function to parse answer
00862  * @arg result          Result pointer to return parsed object
00863  *
00864  * @return 0 on success or a negative error code.
00865  */
00866 int nl_pickup(struct nl_sock *sk,
00867               int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *,
00868                             struct nlmsghdr *, struct nl_parser_param *),
00869               struct nl_object **result)
00870 {
00871         struct nl_cb *cb;
00872         int err;
00873         struct pickup_param pp = {
00874                 .parser = parser,
00875         };
00876 
00877         cb = nl_cb_clone(sk->s_cb);
00878         if (cb == NULL)
00879                 return -NLE_NOMEM;
00880 
00881         nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, __pickup_answer, &pp);
00882 
00883         err = nl_recvmsgs(sk, cb);
00884         if (err < 0)
00885                 goto errout;
00886 
00887         *result = pp.result;
00888 errout:
00889         nl_cb_put(cb);
00890 
00891         return err;
00892 }
00893 
00894 /** @} */
00895 
00896 /** @} */