libnl  1.1
nl.c
1 /*
2  * lib/nl.c Core Netlink Interface
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation version 2.1
7  * of the License.
8  *
9  * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
10  */
11 
12 /**
13  * @defgroup nl Core Netlink API
14  * @brief
15  *
16  * @par Receiving Semantics
17  * @code
18  * nl_recvmsgs_default(socket)
19  * |
20  * | cb = nl_socket_get_cb(socket)
21  * v
22  * nl_recvmsgs(socket, cb)
23  * | [Application provides nl_recvmsgs() replacement]
24  * |- - - - - - - - - - - - - - - v
25  * | cb->cb_recvmsgs_ow()
26  * |
27  * | [Application provides nl_recv() replacement]
28  * +-------------->|- - - - - - - - - - - - - - - v
29  * | nl_recv() cb->cb_recv_ow()
30  * | +----------->|<- - - - - - - - - - - - - - -+
31  * | | v
32  * | | Parse Message
33  * | | |- - - - - - - - - - - - - - - v
34  * | | | NL_CB_MSG_IN()
35  * | | |<- - - - - - - - - - - - - - -+
36  * | | |
37  * | | |- - - - - - - - - - - - - - - v
38  * | | Sequence Check NL_CB_SEQ_CHECK()
39  * | | |<- - - - - - - - - - - - - - -+
40  * | | |
41  * | | |- - - - - - - - - - - - - - - v [ NLM_F_ACK is set ]
42  * | | | NL_CB_SEND_ACK()
43  * | | |<- - - - - - - - - - - - - - -+
44  * | | |
45  * | | +-----+------+--------------+----------------+--------------+
46  * | | v v v v v
47  * | | Valid Message ACK NOOP Message End of Multipart Error Message
48  * | | | | | | |
49  * | | v v v v v
50  * | |NL_CB_VALID() NL_CB_ACK() NL_CB_SKIPPED() NL_CB_FINISH() cb->cb_err()
51  * | | | | | | |
52  * | | +------------+--------------+----------------+ v
53  * | | | (FAILURE)
54  * | | | [Callback returned NL_SKIP]
55  * | | [More messages to be parsed] |<-----------
56  * | +----------------------------------|
57  * | |
58  * | [Multipart message] |
59  * +-------------------------------------| [Callback returned NL_STOP]
60  * |<-----------
61  * v
62  * (SUCCESS)
63  *
64  * At any time:
65  * Message Format Error
66  * |- - - - - - - - - - - - v
67  * v NL_CB_INVALID()
68  * (FAILURE)
69  *
70  * Message Overrun (Kernel Lost Data)
71  * |- - - - - - - - - - - - v
72  * v NL_CB_OVERRUN()
73  * (FAILURE)
74  *
75  * Callback returned negative error code
76  * (FAILURE)
77  * @endcode
78  *
79  * @par Sending Semantics
80  * @code
81  * nl_send_auto_complete()
82  * |
83  * | Automatically fill in PID and/or sequence number
84  * |
85  * | [Application provides nl_send() replacement]
86  * |- - - - - - - - - - - - - - - - - - - - v
87  * v cb->cb_send_ow()
88  * nl_send()
89  * | Add destination address and credentials
90  * v
91  * nl_sendmsg()
92  * | Set source address
93  * |
94  * |- - - - - - - - - - - - - - - - - - - - v
95  * | NL_CB_MSG_OUT()
96  * |<- - - - - - - - - - - - - - - - - - - -+
97  * v
98  * sendmsg()
99  * @endcode
100  *
101  * @par 1) Connecting the socket
102  * @code
103  * // Bind and connect the socket to a protocol, NETLINK_ROUTE in this example.
104  * nl_connect(handle, NETLINK_ROUTE);
105  * @endcode
106  *
107  * @par 2) Sending data
108  * @code
109  * // The most rudimentary method is to use nl_sendto() simply pushing
110  * // a piece of data to the other netlink peer. This method is not
111  * // recommended.
112  * const char buf[] = { 0x01, 0x02, 0x03, 0x04 };
113  * nl_sendto(handle, buf, sizeof(buf));
114  *
115  * // A more comfortable interface is nl_send() taking a pointer to
116  * // a netlink message.
117  * struct nl_msg *msg = my_msg_builder();
118  * nl_send(handle, nlmsg_hdr(msg));
119  *
120  * // nl_sendmsg() provides additional control over the sendmsg() message
121  * // header in order to allow more specific addressing of multiple peers etc.
122  * struct msghdr hdr = { ... };
123  * nl_sendmsg(handle, nlmsg_hdr(msg), &hdr);
124  *
125  * // You're probably too lazy to fill out the netlink pid, sequence number
126  * // and message flags all the time. nl_send_auto_complete() automatically
127  * // extends your message header as needed with an appropriate sequence
128  * // number, the netlink pid stored in the netlink handle and the message
129  * // flags NLM_F_REQUEST and NLM_F_ACK
130  * nl_send_auto_complete(handle, nlmsg_hdr(msg));
131  *
132  * // Simple protocols don't require the complex message construction interface
133  * // and may favour nl_send_simple() to easly send a bunch of payload
134  * // encapsulated in a netlink message header.
135  * nl_send_simple(handle, MY_MSG_TYPE, 0, buf, sizeof(buf));
136  * @endcode
137  *
138  * @par 3) Receiving data
139  * @code
140  * // nl_recv() receives a single message allocating a buffer for the message
141  * // content and gives back the pointer to you.
142  * struct sockaddr_nl peer;
143  * unsigned char *msg;
144  * nl_recv(handle, &peer, &msg);
145  *
146  * // nl_recvmsgs() receives a bunch of messages until the callback system
147  * // orders it to state, usually after receving a compolete multi part
148  * // message series.
149  * nl_recvmsgs(handle, my_callback_configuration);
150  *
151  * // nl_recvmsgs_default() acts just like nl_recvmsg() but uses the callback
152  * // configuration stored in the handle.
153  * nl_recvmsgs_default(handle);
154  *
155  * // In case you want to wait for the ACK to be recieved that you requested
156  * // with your latest message, you can call nl_wait_for_ack()
157  * nl_wait_for_ack(handle);
158  * @endcode
159  *
160  * @par 4) Closing
161  * @code
162  * // Close the socket first to release kernel memory
163  * nl_close(handle);
164  * @endcode
165  *
166  * @{
167  */
168 
169 #include <netlink-local.h>
170 #include <netlink/netlink.h>
171 #include <netlink/utils.h>
172 #include <netlink/handlers.h>
173 #include <netlink/msg.h>
174 #include <netlink/attr.h>
175 
176 /**
177  * @name Connection Management
178  * @{
179  */
180 
181 /**
182  * Create and connect netlink socket.
183  * @arg handle Netlink handle.
184  * @arg protocol Netlink protocol to use.
185  *
186  * Creates a netlink socket using the specified protocol, binds the socket
187  * and issues a connection attempt.
188  *
189  * @return 0 on success or a negative error code.
190  */
191 int nl_connect(struct nl_handle *handle, int protocol)
192 {
193  int err;
194  socklen_t addrlen;
195 
196  handle->h_fd = socket(AF_NETLINK, SOCK_RAW, protocol);
197  if (handle->h_fd < 0) {
198  err = nl_error(1, "socket(AF_NETLINK, ...) failed");
199  goto errout;
200  }
201 
202  if (!(handle->h_flags & NL_SOCK_BUFSIZE_SET)) {
203  err = nl_set_buffer_size(handle, 0, 0);
204  if (err < 0)
205  goto errout;
206  }
207 
208  err = bind(handle->h_fd, (struct sockaddr*) &handle->h_local,
209  sizeof(handle->h_local));
210  if (err < 0) {
211  err = nl_error(1, "bind() failed");
212  goto errout;
213  }
214 
215  addrlen = sizeof(handle->h_local);
216  err = getsockname(handle->h_fd, (struct sockaddr *) &handle->h_local,
217  &addrlen);
218  if (err < 0) {
219  err = nl_error(1, "getsockname failed");
220  goto errout;
221  }
222 
223  if (addrlen != sizeof(handle->h_local)) {
224  err = nl_error(EADDRNOTAVAIL, "Invalid address length");
225  goto errout;
226  }
227 
228  if (handle->h_local.nl_family != AF_NETLINK) {
229  err = nl_error(EPFNOSUPPORT, "Address format not supported");
230  goto errout;
231  }
232 
233  handle->h_proto = protocol;
234 
235  return 0;
236 errout:
237  close(handle->h_fd);
238  handle->h_fd = -1;
239 
240  return err;
241 }
242 
243 /**
244  * Close/Disconnect netlink socket.
245  * @arg handle Netlink handle
246  */
247 void nl_close(struct nl_handle *handle)
248 {
249  if (handle->h_fd >= 0) {
250  close(handle->h_fd);
251  handle->h_fd = -1;
252  }
253 
254  handle->h_proto = 0;
255 }
256 
257 /** @} */
258 
259 /**
260  * @name Send
261  * @{
262  */
263 
264 /**
265  * Send raw data over netlink socket.
266  * @arg handle Netlink handle.
267  * @arg buf Data buffer.
268  * @arg size Size of data buffer.
269  * @return Number of characters written on success or a negative error code.
270  */
271 int nl_sendto(struct nl_handle *handle, void *buf, size_t size)
272 {
273  int ret;
274 
275  ret = sendto(handle->h_fd, buf, size, 0, (struct sockaddr *)
276  &handle->h_peer, sizeof(handle->h_peer));
277  if (ret < 0)
278  return nl_errno(errno);
279 
280  return ret;
281 }
282 
283 /**
284  * Send netlink message with control over sendmsg() message header.
285  * @arg handle Netlink handle.
286  * @arg msg Netlink message to be sent.
287  * @arg hdr Sendmsg() message header.
288  * @return Number of characters sent on sucess or a negative error code.
289  */
290 int nl_sendmsg(struct nl_handle *handle, struct nl_msg *msg, struct msghdr *hdr)
291 {
292  struct nl_cb *cb;
293  int ret;
294 
295  struct iovec iov = {
296  .iov_base = (void *) nlmsg_hdr(msg),
297  .iov_len = nlmsg_hdr(msg)->nlmsg_len,
298  };
299 
300  hdr->msg_iov = &iov;
301  hdr->msg_iovlen = 1;
302 
303  nlmsg_set_src(msg, &handle->h_local);
304 
305  cb = handle->h_cb;
306  if (cb->cb_set[NL_CB_MSG_OUT])
307  if (nl_cb_call(cb, NL_CB_MSG_OUT, msg) != NL_OK)
308  return 0;
309 
310  ret = sendmsg(handle->h_fd, hdr, 0);
311  if (ret < 0)
312  return nl_errno(errno);
313 
314  return ret;
315 }
316 
317 
318 /**
319  * Send netlink message.
320  * @arg handle Netlink handle
321  * @arg msg Netlink message to be sent.
322  * @see nl_sendmsg()
323  * @return Number of characters sent on success or a negative error code.
324  */
325 int nl_send(struct nl_handle *handle, struct nl_msg *msg)
326 {
327  struct sockaddr_nl *dst;
328  struct ucred *creds;
329 
330  struct msghdr hdr = {
331  .msg_name = (void *) &handle->h_peer,
332  .msg_namelen = sizeof(struct sockaddr_nl),
333  };
334 
335  /* Overwrite destination if specified in the message itself, defaults
336  * to the peer address of the handle.
337  */
338  dst = nlmsg_get_dst(msg);
339  if (dst->nl_family == AF_NETLINK)
340  hdr.msg_name = dst;
341 
342  /* Add credentials if present. */
343  creds = nlmsg_get_creds(msg);
344  if (creds != NULL) {
345  char buf[CMSG_SPACE(sizeof(struct ucred))];
346  struct cmsghdr *cmsg;
347 
348  hdr.msg_control = buf;
349  hdr.msg_controllen = sizeof(buf);
350 
351  cmsg = CMSG_FIRSTHDR(&hdr);
352  cmsg->cmsg_level = SOL_SOCKET;
353  cmsg->cmsg_type = SCM_CREDENTIALS;
354  cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
355  memcpy(CMSG_DATA(cmsg), creds, sizeof(struct ucred));
356  }
357 
358  return nl_sendmsg(handle, msg, &hdr);
359 }
360 
361 /**
362  * Send netlink message and check & extend header values as needed.
363  * @arg handle Netlink handle.
364  * @arg msg Netlink message to be sent.
365  *
366  * Checks the netlink message \c nlh for completness and extends it
367  * as required before sending it out. Checked fields include pid,
368  * sequence nr, and flags.
369  *
370  * @see nl_send()
371  * @return Number of characters sent or a negative error code.
372  */
373 int nl_send_auto_complete(struct nl_handle *handle, struct nl_msg *msg)
374 {
375  struct nlmsghdr *nlh;
376  struct nl_cb *cb = handle->h_cb;
377 
378  nlh = nlmsg_hdr(msg);
379  if (nlh->nlmsg_pid == 0)
380  nlh->nlmsg_pid = handle->h_local.nl_pid;
381 
382  if (nlh->nlmsg_seq == 0)
383  nlh->nlmsg_seq = handle->h_seq_next++;
384 
385  if (msg->nm_protocol == -1)
386  msg->nm_protocol = handle->h_proto;
387 
388  nlh->nlmsg_flags |= (NLM_F_REQUEST | NLM_F_ACK);
389 
390  if (cb->cb_send_ow)
391  return cb->cb_send_ow(handle, msg);
392  else
393  return nl_send(handle, msg);
394 }
395 
396 /**
397  * Send simple netlink message using nl_send_auto_complete()
398  * @arg handle Netlink handle.
399  * @arg type Netlink message type.
400  * @arg flags Netlink message flags.
401  * @arg buf Data buffer.
402  * @arg size Size of data buffer.
403  *
404  * Builds a netlink message with the specified type and flags and
405  * appends the specified data as payload to the message.
406  *
407  * @see nl_send_auto_complete()
408  * @return Number of characters sent on success or a negative error code.
409  */
410 int nl_send_simple(struct nl_handle *handle, int type, int flags, void *buf,
411  size_t size)
412 {
413  int err;
414  struct nl_msg *msg;
415 
416  msg = nlmsg_alloc_simple(type, flags);
417  if (!msg)
418  return nl_errno(ENOMEM);
419 
420  if (buf && size) {
421  err = nlmsg_append(msg, buf, size, NLMSG_ALIGNTO);
422  if (err < 0)
423  goto errout;
424  }
425 
426 
427  err = nl_send_auto_complete(handle, msg);
428 errout:
429  nlmsg_free(msg);
430 
431  return err;
432 }
433 
434 /** @} */
435 
436 /**
437  * @name Receive
438  * @{
439  */
440 
441 /**
442  * Receive data from netlink socket
443  * @arg handle Netlink handle.
444  * @arg nla Destination pointer for peer's netlink address.
445  * @arg buf Destination pointer for message content.
446  * @arg creds Destination pointer for credentials.
447  *
448  * Receives a netlink message, allocates a buffer in \c *buf and
449  * stores the message content. The peer's netlink address is stored
450  * in \c *nla. The caller is responsible for freeing the buffer allocated
451  * in \c *buf if a positive value is returned. Interruped system calls
452  * are handled by repeating the read. The input buffer size is determined
453  * by peeking before the actual read is done.
454  *
455  * A non-blocking sockets causes the function to return immediately with
456  * a return value of 0 if no data is available.
457  *
458  * @return Number of octets read, 0 on EOF or a negative error code.
459  */
460 int nl_recv(struct nl_handle *handle, struct sockaddr_nl *nla,
461  unsigned char **buf, struct ucred **creds)
462 {
463  int n;
464  int flags = 0;
465  static int page_size = 0;
466  struct iovec iov;
467  struct msghdr msg = {
468  .msg_name = (void *) nla,
469  .msg_namelen = sizeof(struct sockaddr_nl),
470  .msg_iov = &iov,
471  .msg_iovlen = 1,
472  .msg_control = NULL,
473  .msg_controllen = 0,
474  .msg_flags = 0,
475  };
476  struct cmsghdr *cmsg;
477 
478  if (handle->h_flags & NL_MSG_PEEK)
479  flags |= MSG_PEEK;
480 
481  if (page_size == 0)
482  page_size = getpagesize();
483 
484  iov.iov_len = page_size;
485  iov.iov_base = *buf = calloc(1, iov.iov_len);
486 
487  if (handle->h_flags & NL_SOCK_PASSCRED) {
488  msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred));
489  msg.msg_control = calloc(1, msg.msg_controllen);
490  }
491 retry:
492 
493  n = recvmsg(handle->h_fd, &msg, flags);
494  if (!n)
495  goto abort;
496  else if (n < 0) {
497  if (errno == EINTR) {
498  NL_DBG(3, "recvmsg() returned EINTR, retrying\n");
499  goto retry;
500  } else if (errno == EAGAIN) {
501  NL_DBG(3, "recvmsg() returned EAGAIN, aborting\n");
502  goto abort;
503  } else {
504  free(msg.msg_control);
505  free(*buf);
506  return nl_error(errno, "recvmsg failed");
507  }
508  }
509 
510  if (iov.iov_len < n ||
511  msg.msg_flags & MSG_TRUNC) {
512  /* Provided buffer is not long enough, enlarge it
513  * and try again. */
514  iov.iov_len *= 2;
515  iov.iov_base = *buf = realloc(*buf, iov.iov_len);
516  goto retry;
517  } else if (msg.msg_flags & MSG_CTRUNC) {
518  msg.msg_controllen *= 2;
519  msg.msg_control = realloc(msg.msg_control, msg.msg_controllen);
520  goto retry;
521  } else if (flags != 0) {
522  /* Buffer is big enough, do the actual reading */
523  flags = 0;
524  goto retry;
525  }
526 
527  if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
528  free(msg.msg_control);
529  free(*buf);
530  return nl_error(EADDRNOTAVAIL, "socket address size mismatch");
531  }
532 
533  for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
534  if (cmsg->cmsg_level == SOL_SOCKET &&
535  cmsg->cmsg_type == SCM_CREDENTIALS) {
536  *creds = calloc(1, sizeof(struct ucred));
537  memcpy(*creds, CMSG_DATA(cmsg), sizeof(struct ucred));
538  break;
539  }
540  }
541 
542  free(msg.msg_control);
543  return n;
544 
545 abort:
546  free(msg.msg_control);
547  free(*buf);
548  return 0;
549 }
550 
551 #define NL_CB_CALL(cb, type, msg) \
552 do { \
553  err = nl_cb_call(cb, type, msg); \
554  switch (err) { \
555  case NL_OK: \
556  err = 0; \
557  break; \
558  case NL_SKIP: \
559  goto skip; \
560  case NL_STOP: \
561  goto stop; \
562  default: \
563  goto out; \
564  } \
565 } while (0)
566 
567 static int recvmsgs(struct nl_handle *handle, struct nl_cb *cb)
568 {
569  int n, err = 0, multipart = 0;
570  unsigned char *buf = NULL;
571  struct nlmsghdr *hdr;
572  struct sockaddr_nl nla = {0};
573  struct nl_msg *msg = NULL;
574  struct ucred *creds = NULL;
575 
576 continue_reading:
577  NL_DBG(3, "Attempting to read from %p\n", handle);
578  if (cb->cb_recv_ow)
579  n = cb->cb_recv_ow(handle, &nla, &buf, &creds);
580  else
581  n = nl_recv(handle, &nla, &buf, &creds);
582 
583  if (n <= 0)
584  return n;
585 
586  NL_DBG(3, "recvmsgs(%p): Read %d bytes\n", handle, n);
587 
588  hdr = (struct nlmsghdr *) buf;
589  while (nlmsg_ok(hdr, n)) {
590  NL_DBG(3, "recgmsgs(%p): Processing valid message...\n",
591  handle);
592 
593  nlmsg_free(msg);
594  msg = nlmsg_convert(hdr);
595  if (!msg) {
596  err = nl_errno(ENOMEM);
597  goto out;
598  }
599 
600  nlmsg_set_proto(msg, handle->h_proto);
601  nlmsg_set_src(msg, &nla);
602  if (creds)
603  nlmsg_set_creds(msg, creds);
604 
605  /* Raw callback is the first, it gives the most control
606  * to the user and he can do his very own parsing. */
607  if (cb->cb_set[NL_CB_MSG_IN])
608  NL_CB_CALL(cb, NL_CB_MSG_IN, msg);
609 
610  /* Sequence number checking. The check may be done by
611  * the user, otherwise a very simple check is applied
612  * enforcing strict ordering */
613  if (cb->cb_set[NL_CB_SEQ_CHECK])
614  NL_CB_CALL(cb, NL_CB_SEQ_CHECK, msg);
615  else if (hdr->nlmsg_seq != handle->h_seq_expect) {
616  if (cb->cb_set[NL_CB_INVALID])
617  NL_CB_CALL(cb, NL_CB_INVALID, msg);
618  else {
619  err = nl_error(EINVAL,
620  "Sequence number mismatch");
621  goto out;
622  }
623  }
624 
625  if (hdr->nlmsg_type == NLMSG_DONE ||
626  hdr->nlmsg_type == NLMSG_ERROR ||
627  hdr->nlmsg_type == NLMSG_NOOP ||
628  hdr->nlmsg_type == NLMSG_OVERRUN) {
629  /* We can't check for !NLM_F_MULTI since some netlink
630  * users in the kernel are broken. */
631  handle->h_seq_expect++;
632  NL_DBG(3, "recvmsgs(%p): Increased expected " \
633  "sequence number to %d\n",
634  handle, handle->h_seq_expect);
635  }
636 
637  if (hdr->nlmsg_flags & NLM_F_MULTI)
638  multipart = 1;
639 
640  /* Other side wishes to see an ack for this message */
641  if (hdr->nlmsg_flags & NLM_F_ACK) {
642  if (cb->cb_set[NL_CB_SEND_ACK])
643  NL_CB_CALL(cb, NL_CB_SEND_ACK, msg);
644  else {
645  /* FIXME: implement */
646  }
647  }
648 
649  /* messages terminates a multpart message, this is
650  * usually the end of a message and therefore we slip
651  * out of the loop by default. the user may overrule
652  * this action by skipping this packet. */
653  if (hdr->nlmsg_type == NLMSG_DONE) {
654  multipart = 0;
655  if (cb->cb_set[NL_CB_FINISH])
656  NL_CB_CALL(cb, NL_CB_FINISH, msg);
657  }
658 
659  /* Message to be ignored, the default action is to
660  * skip this message if no callback is specified. The
661  * user may overrule this action by returning
662  * NL_PROCEED. */
663  else if (hdr->nlmsg_type == NLMSG_NOOP) {
664  if (cb->cb_set[NL_CB_SKIPPED])
665  NL_CB_CALL(cb, NL_CB_SKIPPED, msg);
666  else
667  goto skip;
668  }
669 
670  /* Data got lost, report back to user. The default action is to
671  * quit parsing. The user may overrule this action by retuning
672  * NL_SKIP or NL_PROCEED (dangerous) */
673  else if (hdr->nlmsg_type == NLMSG_OVERRUN) {
674  if (cb->cb_set[NL_CB_OVERRUN])
675  NL_CB_CALL(cb, NL_CB_OVERRUN, msg);
676  else {
677  err = nl_error(EOVERFLOW, "Overrun");
678  goto out;
679  }
680  }
681 
682  /* Message carries a nlmsgerr */
683  else if (hdr->nlmsg_type == NLMSG_ERROR) {
684  struct nlmsgerr *e = nlmsg_data(hdr);
685 
686  if (hdr->nlmsg_len < nlmsg_msg_size(sizeof(*e))) {
687  /* Truncated error message, the default action
688  * is to stop parsing. The user may overrule
689  * this action by returning NL_SKIP or
690  * NL_PROCEED (dangerous) */
691  if (cb->cb_set[NL_CB_INVALID])
692  NL_CB_CALL(cb, NL_CB_INVALID, msg);
693  else {
694  err = nl_error(EINVAL,
695  "Truncated error message");
696  goto out;
697  }
698  } else if (e->error) {
699  /* Error message reported back from kernel. */
700  if (cb->cb_err) {
701  err = cb->cb_err(&nla, e,
702  cb->cb_err_arg);
703  if (err < 0)
704  goto out;
705  else if (err == NL_SKIP)
706  goto skip;
707  else if (err == NL_STOP) {
708  err = nl_error(-e->error,
709  "Netlink Error");
710  goto out;
711  }
712  } else {
713  err = nl_error(-e->error,
714  "Netlink Error");
715  goto out;
716  }
717  } else if (cb->cb_set[NL_CB_ACK])
718  NL_CB_CALL(cb, NL_CB_ACK, msg);
719  } else {
720  /* Valid message (not checking for MULTIPART bit to
721  * get along with broken kernels. NL_SKIP has no
722  * effect on this. */
723  if (cb->cb_set[NL_CB_VALID])
724  NL_CB_CALL(cb, NL_CB_VALID, msg);
725  }
726 skip:
727  err = 0;
728  hdr = nlmsg_next(hdr, &n);
729  }
730 
731  nlmsg_free(msg);
732  free(buf);
733  free(creds);
734  buf = NULL;
735  msg = NULL;
736  creds = NULL;
737 
738  if (multipart) {
739  /* Multipart message not yet complete, continue reading */
740  goto continue_reading;
741  }
742 stop:
743  err = 0;
744 out:
745  nlmsg_free(msg);
746  free(buf);
747  free(creds);
748 
749  return err;
750 }
751 
752 /**
753  * Receive a set of messages from a netlink socket.
754  * @arg handle netlink handle
755  * @arg cb set of callbacks to control behaviour.
756  *
757  * Repeatedly calls nl_recv() or the respective replacement if provided
758  * by the application (see nl_cb_overwrite_recv()) and parses the
759  * received data as netlink messages. Stops reading if one of the
760  * callbacks returns NL_STOP or nl_recv returns either 0 or a negative error code.
761  *
762  * A non-blocking sockets causes the function to return immediately if
763  * no data is available.
764  *
765  * @return 0 on success or a negative error code from nl_recv().
766  */
767 int nl_recvmsgs(struct nl_handle *handle, struct nl_cb *cb)
768 {
769  if (cb->cb_recvmsgs_ow)
770  return cb->cb_recvmsgs_ow(handle, cb);
771  else
772  return recvmsgs(handle, cb);
773 }
774 
775 /**
776  * Receive a set of message from a netlink socket using handlers in nl_handle.
777  * @arg handle netlink handle
778  *
779  * Calls nl_recvmsgs() with the handlers configured in the netlink handle.
780  */
781 int nl_recvmsgs_default(struct nl_handle *handle)
782 {
783  return nl_recvmsgs(handle, handle->h_cb);
784 
785 }
786 
787 static int ack_wait_handler(struct nl_msg *msg, void *arg)
788 {
789  return NL_STOP;
790 }
791 
792 /**
793  * Wait for ACK.
794  * @arg handle netlink handle
795  * @pre The netlink socket must be in blocking state.
796  *
797  * Waits until an ACK is received for the latest not yet acknowledged
798  * netlink message.
799  */
800 int nl_wait_for_ack(struct nl_handle *handle)
801 {
802  int err;
803  struct nl_cb *cb;
804 
805  cb = nl_cb_clone(handle->h_cb);
806  if (cb == NULL)
807  return nl_get_errno();
808 
809  nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, NULL);
810  err = nl_recvmsgs(handle, cb);
811  nl_cb_put(cb);
812 
813  return err;
814 }
815 
816 /** @} */
817 
818 /** @} */