libnl 3.0
|
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 /** @} */