libnl  1.1.4
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 | MSG_TRUNC;
480 
481  if (page_size == 0)
482  page_size = getpagesize() * 4;
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 (msg.msg_flags & MSG_CTRUNC) {
511  msg.msg_controllen *= 2;
512  msg.msg_control = realloc(msg.msg_control, msg.msg_controllen);
513  goto retry;
514  } else if (iov.iov_len < n || msg.msg_flags & MSG_TRUNC) {
515  /* Provided buffer is not long enough, enlarge it
516  * to size of n (which should be total length of the message)
517  * and try again. */
518  iov.iov_len = n;
519  iov.iov_base = *buf = realloc(*buf, iov.iov_len);
520  flags = 0;
521  goto retry;
522  } else if (flags != 0) {
523  /* Buffer is big enough, do the actual reading */
524  flags = 0;
525  goto retry;
526  }
527 
528  if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
529  free(msg.msg_control);
530  free(*buf);
531  return nl_error(EADDRNOTAVAIL, "socket address size mismatch");
532  }
533 
534  for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
535  if (cmsg->cmsg_level == SOL_SOCKET &&
536  cmsg->cmsg_type == SCM_CREDENTIALS) {
537  *creds = calloc(1, sizeof(struct ucred));
538  memcpy(*creds, CMSG_DATA(cmsg), sizeof(struct ucred));
539  break;
540  }
541  }
542 
543  free(msg.msg_control);
544  return n;
545 
546 abort:
547  free(msg.msg_control);
548  free(*buf);
549  return 0;
550 }
551 
552 #define NL_CB_CALL(cb, type, msg) \
553 do { \
554  err = nl_cb_call(cb, type, msg); \
555  switch (err) { \
556  case NL_OK: \
557  err = 0; \
558  break; \
559  case NL_SKIP: \
560  goto skip; \
561  case NL_STOP: \
562  goto stop; \
563  default: \
564  goto out; \
565  } \
566 } while (0)
567 
568 static int recvmsgs(struct nl_handle *handle, struct nl_cb *cb)
569 {
570  int n, err = 0, multipart = 0;
571  unsigned char *buf = NULL;
572  struct nlmsghdr *hdr;
573  struct sockaddr_nl nla = {0};
574  struct nl_msg *msg = NULL;
575  struct ucred *creds = NULL;
576 
577 continue_reading:
578  NL_DBG(3, "Attempting to read from %p\n", handle);
579  if (cb->cb_recv_ow)
580  n = cb->cb_recv_ow(handle, &nla, &buf, &creds);
581  else
582  n = nl_recv(handle, &nla, &buf, &creds);
583 
584  if (n <= 0)
585  return n;
586 
587  NL_DBG(3, "recvmsgs(%p): Read %d bytes\n", handle, n);
588 
589  hdr = (struct nlmsghdr *) buf;
590  while (nlmsg_ok(hdr, n)) {
591  NL_DBG(3, "recgmsgs(%p): Processing valid message...\n",
592  handle);
593 
594  nlmsg_free(msg);
595  msg = nlmsg_convert(hdr);
596  if (!msg) {
597  err = nl_errno(ENOMEM);
598  goto out;
599  }
600 
601  nlmsg_set_proto(msg, handle->h_proto);
602  nlmsg_set_src(msg, &nla);
603  if (creds)
604  nlmsg_set_creds(msg, creds);
605 
606  /* Raw callback is the first, it gives the most control
607  * to the user and he can do his very own parsing. */
608  if (cb->cb_set[NL_CB_MSG_IN])
609  NL_CB_CALL(cb, NL_CB_MSG_IN, msg);
610 
611  /* Sequence number checking. The check may be done by
612  * the user, otherwise a very simple check is applied
613  * enforcing strict ordering */
614  if (cb->cb_set[NL_CB_SEQ_CHECK])
615  NL_CB_CALL(cb, NL_CB_SEQ_CHECK, msg);
616  else if (hdr->nlmsg_seq != handle->h_seq_expect) {
617  if (cb->cb_set[NL_CB_INVALID])
618  NL_CB_CALL(cb, NL_CB_INVALID, msg);
619  else {
620  err = nl_error(EINVAL,
621  "Sequence number mismatch");
622  goto out;
623  }
624  }
625 
626  if (hdr->nlmsg_type == NLMSG_DONE ||
627  hdr->nlmsg_type == NLMSG_ERROR ||
628  hdr->nlmsg_type == NLMSG_NOOP ||
629  hdr->nlmsg_type == NLMSG_OVERRUN) {
630  /* We can't check for !NLM_F_MULTI since some netlink
631  * users in the kernel are broken. */
632  handle->h_seq_expect++;
633  NL_DBG(3, "recvmsgs(%p): Increased expected " \
634  "sequence number to %d\n",
635  handle, handle->h_seq_expect);
636  }
637 
638  if (hdr->nlmsg_flags & NLM_F_MULTI)
639  multipart = 1;
640 
641  /* Other side wishes to see an ack for this message */
642  if (hdr->nlmsg_flags & NLM_F_ACK) {
643  if (cb->cb_set[NL_CB_SEND_ACK])
644  NL_CB_CALL(cb, NL_CB_SEND_ACK, msg);
645  else {
646  /* FIXME: implement */
647  }
648  }
649 
650  /* messages terminates a multpart message, this is
651  * usually the end of a message and therefore we slip
652  * out of the loop by default. the user may overrule
653  * this action by skipping this packet. */
654  if (hdr->nlmsg_type == NLMSG_DONE) {
655  multipart = 0;
656  if (cb->cb_set[NL_CB_FINISH])
657  NL_CB_CALL(cb, NL_CB_FINISH, msg);
658  }
659 
660  /* Message to be ignored, the default action is to
661  * skip this message if no callback is specified. The
662  * user may overrule this action by returning
663  * NL_PROCEED. */
664  else if (hdr->nlmsg_type == NLMSG_NOOP) {
665  if (cb->cb_set[NL_CB_SKIPPED])
666  NL_CB_CALL(cb, NL_CB_SKIPPED, msg);
667  else
668  goto skip;
669  }
670 
671  /* Data got lost, report back to user. The default action is to
672  * quit parsing. The user may overrule this action by retuning
673  * NL_SKIP or NL_PROCEED (dangerous) */
674  else if (hdr->nlmsg_type == NLMSG_OVERRUN) {
675  if (cb->cb_set[NL_CB_OVERRUN])
676  NL_CB_CALL(cb, NL_CB_OVERRUN, msg);
677  else {
678  err = nl_error(EOVERFLOW, "Overrun");
679  goto out;
680  }
681  }
682 
683  /* Message carries a nlmsgerr */
684  else if (hdr->nlmsg_type == NLMSG_ERROR) {
685  struct nlmsgerr *e = nlmsg_data(hdr);
686 
687  if (hdr->nlmsg_len < nlmsg_msg_size(sizeof(*e))) {
688  /* Truncated error message, the default action
689  * is to stop parsing. The user may overrule
690  * this action by returning NL_SKIP or
691  * NL_PROCEED (dangerous) */
692  if (cb->cb_set[NL_CB_INVALID])
693  NL_CB_CALL(cb, NL_CB_INVALID, msg);
694  else {
695  err = nl_error(EINVAL,
696  "Truncated error message");
697  goto out;
698  }
699  } else if (e->error) {
700  /* Error message reported back from kernel. */
701  if (cb->cb_err) {
702  err = cb->cb_err(&nla, e,
703  cb->cb_err_arg);
704  if (err < 0)
705  goto out;
706  else if (err == NL_SKIP)
707  goto skip;
708  else if (err == NL_STOP) {
709  err = nl_error(-e->error,
710  "Netlink Error");
711  goto out;
712  }
713  } else {
714  err = nl_error(-e->error,
715  "Netlink Error");
716  goto out;
717  }
718  } else if (cb->cb_set[NL_CB_ACK])
719  NL_CB_CALL(cb, NL_CB_ACK, msg);
720  } else {
721  /* Valid message (not checking for MULTIPART bit to
722  * get along with broken kernels. NL_SKIP has no
723  * effect on this. */
724  if (cb->cb_set[NL_CB_VALID])
725  NL_CB_CALL(cb, NL_CB_VALID, msg);
726  }
727 skip:
728  err = 0;
729  hdr = nlmsg_next(hdr, &n);
730  }
731 
732  nlmsg_free(msg);
733  free(buf);
734  free(creds);
735  buf = NULL;
736  msg = NULL;
737  creds = NULL;
738 
739  if (multipart) {
740  /* Multipart message not yet complete, continue reading */
741  goto continue_reading;
742  }
743 stop:
744  err = 0;
745 out:
746  nlmsg_free(msg);
747  free(buf);
748  free(creds);
749 
750  return err;
751 }
752 
753 /**
754  * Receive a set of messages from a netlink socket.
755  * @arg handle netlink handle
756  * @arg cb set of callbacks to control behaviour.
757  *
758  * Repeatedly calls nl_recv() or the respective replacement if provided
759  * by the application (see nl_cb_overwrite_recv()) and parses the
760  * received data as netlink messages. Stops reading if one of the
761  * callbacks returns NL_STOP or nl_recv returns either 0 or a negative error code.
762  *
763  * A non-blocking sockets causes the function to return immediately if
764  * no data is available.
765  *
766  * @return 0 on success or a negative error code from nl_recv().
767  */
768 int nl_recvmsgs(struct nl_handle *handle, struct nl_cb *cb)
769 {
770  if (cb->cb_recvmsgs_ow)
771  return cb->cb_recvmsgs_ow(handle, cb);
772  else
773  return recvmsgs(handle, cb);
774 }
775 
776 /**
777  * Receive a set of message from a netlink socket using handlers in nl_handle.
778  * @arg handle netlink handle
779  *
780  * Calls nl_recvmsgs() with the handlers configured in the netlink handle.
781  */
782 int nl_recvmsgs_default(struct nl_handle *handle)
783 {
784  return nl_recvmsgs(handle, handle->h_cb);
785 
786 }
787 
788 static int ack_wait_handler(struct nl_msg *msg, void *arg)
789 {
790  return NL_STOP;
791 }
792 
793 /**
794  * Wait for ACK.
795  * @arg handle netlink handle
796  * @pre The netlink socket must be in blocking state.
797  *
798  * Waits until an ACK is received for the latest not yet acknowledged
799  * netlink message.
800  */
801 int nl_wait_for_ack(struct nl_handle *handle)
802 {
803  int err;
804  struct nl_cb *cb;
805 
806  cb = nl_cb_clone(handle->h_cb);
807  if (cb == NULL)
808  return nl_get_errno();
809 
810  nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, NULL);
811  err = nl_recvmsgs(handle, cb);
812  nl_cb_put(cb);
813 
814  return err;
815 }
816 
817 /** @} */
818 
819 /** @} */
Report received that data was lost.
Definition: handlers.h:100
Called for every message sent out except for nl_sendto()
Definition: handlers.h:108
Message is an acknowledge.
Definition: handlers.h:104
int nl_recvmsgs(struct nl_handle *handle, struct nl_cb *cb)
Receive a set of messages from a netlink socket.
Definition: nl.c:768
int nl_sendto(struct nl_handle *handle, void *buf, size_t size)
Send raw data over netlink socket.
Definition: nl.c:271
void * nlmsg_data(const struct nlmsghdr *nlh)
head of message payload
Definition: msg.c:218
Sending of an acknowledge message has been requested.
Definition: handlers.h:114
uint16_t nlmsg_type
Message type (content type)
int nl_sendmsg(struct nl_handle *handle, struct nl_msg *msg, struct msghdr *hdr)
Send netlink message with control over sendmsg() message header.
Definition: nl.c:290
#define NLM_F_ACK
Request for an acknowledgment on success.
Customized handler specified by the user.
Definition: handlers.h:84
int nl_wait_for_ack(struct nl_handle *handle)
Wait for ACK.
Definition: nl.c:801
int nl_send(struct nl_handle *handle, struct nl_msg *msg)
Send netlink message.
Definition: nl.c:325
uint32_t nlmsg_seq
Sequence number.
Message wants to be skipped.
Definition: handlers.h:102
void nlmsg_free(struct nl_msg *n)
Free a netlink message.
Definition: msg.c:656
int error
Error code (errno number)
int nl_recvmsgs_default(struct nl_handle *handle)
Receive a set of message from a netlink socket using handlers in nl_handle.
Definition: nl.c:782
int nlmsg_ok(const struct nlmsghdr *nlh, int remaining)
check if the netlink message fits into the remaining bytes
Definition: msg.c:285
Stop parsing altogether and discard remaining messages.
Definition: handlers.h:65
Netlink message header.
Called for every message received.
Definition: handlers.h:106
#define NLMSG_OVERRUN
The message signals that data got lost.
uint32_t nlmsg_len
Length of message including header.
Netlink error message.
#define NLM_F_REQUEST
Must be set on all request messages (typically from user space to kernel space).
#define NLMSG_ERROR
The message signals an error and the payload contains a nlmsgerr structure.
struct nl_cb * nl_cb_clone(struct nl_cb *orig)
Clone an existing callback handle.
Definition: handlers.c:286
int nl_cb_set(struct nl_cb *cb, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func, void *arg)
Set up a callback.
Definition: handlers.c:338
int nl_send_auto_complete(struct nl_handle *handle, struct nl_msg *msg)
Send netlink message and check & extend header values as needed.
Definition: nl.c:373
struct nlmsghdr * nlmsg_next(struct nlmsghdr *nlh, int *remaining)
next netlink message in message stream
Definition: msg.c:300
int nl_send_simple(struct nl_handle *handle, int type, int flags, void *buf, size_t size)
Send simple netlink message using nl_send_auto_complete()
Definition: nl.c:410
uint32_t nlmsg_pid
Netlink PID of the proccess sending the message.
Message is malformed and invalid.
Definition: handlers.h:110
Skip this message.
Definition: handlers.h:63
Last message in a series of multi part messages received.
Definition: handlers.h:98
struct nlmsghdr * nlmsg_hdr(struct nl_msg *n)
Return actual netlink message.
Definition: msg.c:643
int nl_set_buffer_size(struct nl_handle *handle, int rxbuf, int txbuf)
Set socket buffer size of netlink handle.
Definition: socket.c:541
Netlink socket address.
Definition: netlink-kernel.h:8
Message is valid.
Definition: handlers.h:96
Called instead of internal sequence number checking.
Definition: handlers.h:112
#define NLM_F_MULTI
Indicates the message is part of a multipart message terminated by NLMSG_DONE.
uint16_t nlmsg_flags
Message flags.
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
Definition: msg.c:549
int nl_connect(struct nl_handle *handle, int protocol)
Create and connect netlink socket.
Definition: nl.c:191
Proceed with wathever would come next.
Definition: handlers.h:61
#define NLMSG_DONE
Message terminates a multipart message.
struct nl_msg * nlmsg_alloc_simple(int nlmsgtype, int flags)
Allocate a new netlink message.
Definition: msg.c:448
#define NLMSG_NOOP
No operation, message must be ignored.
struct nl_msg * nlmsg_convert(struct nlmsghdr *hdr)
Convert a netlink message received from a netlink socket to a nl_msg.
Definition: msg.c:484
int nlmsg_msg_size(int payload)
length of netlink message not including padding
Definition: msg.c:184
int nl_recv(struct nl_handle *handle, struct sockaddr_nl *nla, unsigned char **buf, struct ucred **creds)
Receive data from netlink socket.
Definition: nl.c:460
sa_family_t nl_family
socket family (AF_NETLINK)
void nl_close(struct nl_handle *handle)
Close/Disconnect netlink socket.
Definition: nl.c:247