libnl 3.5.0

nl.c
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3 * lib/nl.c Core Netlink Interface
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation version 2.1
8 * of the License.
9 *
10 * Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
11 */
12
13 /**
14 * @defgroup core Core Library (libnl)
15 *
16 * Socket handling, connection management, sending and receiving of data,
17 * message construction and parsing, object caching system, ...
18 *
19 * This is the API reference of the core library. It is not meant as a guide
20 * but as a reference. Please refer to the core library guide for detailed
21 * documentation on the library architecture and examples:
22 *
23 * * @ref_asciidoc{core,_,Netlink Core Library Development Guide}
24 *
25 *
26 * @{
27 */
28
29 #include <netlink-private/netlink.h>
30 #include <netlink-private/socket.h>
31 #include <netlink-private/utils.h>
32 #include <netlink/netlink.h>
33 #include <netlink/utils.h>
34 #include <netlink/handlers.h>
35 #include <netlink/msg.h>
36 #include <netlink/attr.h>
37 #include <linux/socket.h>
38
39 /**
40 * @defgroup core_types Data Types
41 *
42 * Core library data types
43 * @{
44 * @}
45 *
46 * @defgroup send_recv Send & Receive Data
47 *
48 * Connection management, sending & receiving of data
49 *
50 * Related sections in the development guide:
51 * - @core_doc{core_send_recv, Sending & Receiving}
52 * - @core_doc{core_sockets, Sockets}
53 *
54 * @{
55 *
56 * Header
57 * ------
58 * ~~~~{.c}
59 * #include <netlink/netlink.h>
60 * ~~~~
61 */
62
63 /**
64 * @name Connection Management
65 * @{
66 */
67
68 /**
69 * Create file descriptor and bind socket.
70 * @arg sk Netlink socket (required)
71 * @arg protocol Netlink protocol to use (required)
72 *
73 * Creates a new Netlink socket using `socket()` and binds the socket to the
74 * protocol and local port specified in the `sk` socket object. Fails if
75 * the socket is already connected.
76 *
77 * @note If available, the `close-on-exec` (`SOCK_CLOEXEC`) feature is enabled
78 * automatically on the new file descriptor. This causes the socket to
79 * be closed automatically if any of the `exec` family functions succeed.
80 * This is essential for multi threaded programs.
81 *
82 * @note The local port (`nl_socket_get_local_port()`) is unspecified after
83 * creating a new socket. It only gets determined when accessing the
84 * port the first time or during `nl_connect()`. When nl_connect()
85 * fails during `bind()` due to `ADDRINUSE`, it will retry with
86 * different ports if the port is unspecified. Unless you want to enforce
87 * the use of a specific local port, don't access the local port (or
88 * reset it to `unspecified` by calling `nl_socket_set_local_port(sk, 0)`).
89 * This capability is indicated by
90 * `%NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE`.
91 *
92 * @note nl_connect() creates and sets the file descriptor. You can setup the file
93 * descriptor yourself by creating and binding it, and then calling
94 * nl_socket_set_fd(). The result will be the same.
95 *
96 * @see nl_socket_alloc()
97 * @see nl_close()
98 * @see nl_socket_set_fd()
99 *
100 * @return 0 on success or a negative error code.
101 *
102 * @retval -NLE_BAD_SOCK Socket is already connected
103 */
104 int nl_connect(struct nl_sock *sk, int protocol)
105 {
106 int err, flags = 0;
107 int errsv;
108 socklen_t addrlen;
109 struct sockaddr_nl local = { 0 };
110 int try_bind = 1;
111
112 #ifdef SOCK_CLOEXEC
113 flags |= SOCK_CLOEXEC;
114 #endif
115
116 if (sk->s_fd != -1)
117 return -NLE_BAD_SOCK;
118
119 sk->s_fd = socket(AF_NETLINK, SOCK_RAW | flags, protocol);
120 if (sk->s_fd < 0) {
121 errsv = errno;
122 NL_DBG(4, "nl_connect(%p): socket() failed with %d (%s)\n", sk, errsv,
123 nl_strerror_l(errsv));
124 err = -nl_syserr2nlerr(errsv);
125 goto errout;
126 }
127
128 err = nl_socket_set_buffer_size(sk, 0, 0);
129 if (err < 0)
130 goto errout;
131
132 if (_nl_socket_is_local_port_unspecified (sk)) {
133 uint32_t port;
134 uint32_t used_ports[32] = { 0 };
135 int ntries = 0;
136
137 while (1) {
138 if (ntries++ > 5) {
139 /* try only a few times. We hit this only if many ports are already in
140 * use but allocated *outside* libnl/generate_local_port(). */
141 _nl_socket_set_local_port_no_release (sk, 0);
142 break;
143 }
144
145 port = _nl_socket_set_local_port_no_release(sk, 1);
146 if (port == 0)
147 break;
148
149 err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local,
150 sizeof(sk->s_local));
151 if (err == 0) {
152 try_bind = 0;
153 break;
154 }
155
156 errsv = errno;
157 if (errsv == EADDRINUSE) {
158 NL_DBG(4, "nl_connect(%p): local port %u already in use. Retry.\n", sk, (unsigned) port);
159 _nl_socket_used_ports_set(used_ports, port);
160 } else {
161 NL_DBG(4, "nl_connect(%p): bind() for port %u failed with %d (%s)\n",
162 sk, (unsigned) port, errsv, nl_strerror_l(errsv));
163 _nl_socket_used_ports_release_all(used_ports);
164 err = -nl_syserr2nlerr(errsv);
165 goto errout;
166 }
167 }
168 _nl_socket_used_ports_release_all(used_ports);
169 }
170 if (try_bind) {
171 err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local,
172 sizeof(sk->s_local));
173 if (err != 0) {
174 errsv = errno;
175 NL_DBG(4, "nl_connect(%p): bind() failed with %d (%s)\n",
176 sk, errsv, nl_strerror_l(errsv));
177 err = -nl_syserr2nlerr(errsv);
178 goto errout;
179 }
180 }
181
182 addrlen = sizeof(local);
183 err = getsockname(sk->s_fd, (struct sockaddr *) &local,
184 &addrlen);
185 if (err < 0) {
186 NL_DBG(4, "nl_connect(%p): getsockname() failed with %d (%s)\n",
187 sk, errno, nl_strerror_l(errno));
188 err = -nl_syserr2nlerr(errno);
189 goto errout;
190 }
191
192 if (addrlen != sizeof(local)) {
193 err = -NLE_NOADDR;
194 goto errout;
195 }
196
197 if (local.nl_family != AF_NETLINK) {
198 err = -NLE_AF_NOSUPPORT;
199 goto errout;
200 }
201
202 if (sk->s_local.nl_pid != local.nl_pid) {
203 /* The port id is different. That can happen if the port id was zero
204 * and kernel assigned a local port. */
205 nl_socket_set_local_port (sk, local.nl_pid);
206 }
207 sk->s_local = local;
208 sk->s_proto = protocol;
209
210 return 0;
211 errout:
212 if (sk->s_fd != -1) {
213 close(sk->s_fd);
214 sk->s_fd = -1;
215 }
216
217 return err;
218 }
219
220 /**
221 * Close Netlink socket
222 * @arg sk Netlink socket (required)
223 *
224 * Closes the Netlink socket using `close()`.
225 *
226 * @note The socket is closed automatically if a `struct nl_sock` object is
227 * freed using `nl_socket_free()`.
228 *
229 * @see nl_connect()
230 */
231 void nl_close(struct nl_sock *sk)
232 {
233 if (sk->s_fd >= 0) {
234 close(sk->s_fd);
235 sk->s_fd = -1;
236 }
237
238 sk->s_proto = 0;
239 }
240
241 /** @} */
242
243 /**
244 * @name Send
245 * @{
246 */
247
248 /**
249 * Transmit raw data over Netlink socket.
250 * @arg sk Netlink socket (required)
251 * @arg buf Buffer carrying data to send (required)
252 * @arg size Size of buffer (required)
253 *
254 * Transmits "raw" data over the specified Netlink socket. Unlike the other
255 * transmit functions it does not modify the data in any way. It directly
256 * passes the buffer \c buf of \c size to sendto().
257 *
258 * The message is addressed to the peer as specified in the socket by either
259 * the nl_socket_set_peer_port() or nl_socket_set_peer_groups() function.
260 *
261 * @note Because there is no indication on the message boundaries of the data
262 * being sent, the \c NL_CB_MSG_OUT callback handler will not be invoked
263 * for data that is being sent using this function.
264 *
265 * @see nl_socket_set_peer_port()
266 * @see nl_socket_set_peer_groups()
267 * @see nl_sendmsg()
268 *
269 * @return Number of bytes sent or a negative error code.
270 */
271 int nl_sendto(struct nl_sock *sk, void *buf, size_t size)
272 {
273 int ret;
274
275 if (!buf)
276 return -NLE_INVAL;
277
278 if (sk->s_fd < 0)
279 return -NLE_BAD_SOCK;
280
281 ret = sendto(sk->s_fd, buf, size, 0, (struct sockaddr *)
282 &sk->s_peer, sizeof(sk->s_peer));
283 if (ret < 0) {
284 NL_DBG(4, "nl_sendto(%p): sendto() failed with %d (%s)\n",
285 sk, errno, nl_strerror_l(errno));
286 return -nl_syserr2nlerr(errno);
287 }
288
289 return ret;
290 }
291
292 /**
293 * Transmit Netlink message using sendmsg()
294 * @arg sk Netlink socket (required)
295 * @arg msg Netlink message to be sent (required)
296 * @arg hdr sendmsg() message header (required)
297 *
298 * Transmits the message specified in \c hdr over the Netlink socket using the
299 * sendmsg() system call.
300 *
301 * @attention
302 * The `msg` argument will *not* be used to derive the message payload that
303 * is being sent out. The `msg` argument is *only* passed on to the
304 * `NL_CB_MSG_OUT` callback. The caller is responsible to initialize the
305 * `hdr` struct properly and have it point to the message payload and
306 * socket address.
307 *
308 * @note
309 * This function uses `nlmsg_set_src()` to modify the `msg` argument prior to
310 * invoking the `NL_CB_MSG_OUT` callback to provide the local port number.
311 *
312 * @callback This function triggers the `NL_CB_MSG_OUT` callback.
313 *
314 * @attention
315 * Think twice before using this function. It provides a low level access to
316 * the Netlink socket. Among other limitations, it does not add credentials
317 * even if enabled or respect the destination address specified in the `msg`
318 * object.
319 *
320 * @see nl_socket_set_local_port()
321 * @see nl_send_auto()
322 * @see nl_send_iovec()
323 *
324 * @return Number of bytes sent on success or a negative error code.
325 *
326 * @lowlevel
327 */
328 int nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr)
329 {
330 struct nl_cb *cb;
331 int ret;
332
333 if (sk->s_fd < 0)
334 return -NLE_BAD_SOCK;
335
336 nlmsg_set_src(msg, &sk->s_local);
337
338 cb = sk->s_cb;
339 if (cb->cb_set[NL_CB_MSG_OUT])
340 if ((ret = nl_cb_call(cb, NL_CB_MSG_OUT, msg)) != NL_OK)
341 return ret;
342
343 ret = sendmsg(sk->s_fd, hdr, 0);
344 if (ret < 0) {
345 NL_DBG(4, "nl_sendmsg(%p): sendmsg() failed with %d (%s)\n",
346 sk, errno, nl_strerror_l(errno));
347 return -nl_syserr2nlerr(errno);
348 }
349
350 NL_DBG(4, "sent %d bytes\n", ret);
351 return ret;
352 }
353
354
355 /**
356 * Transmit Netlink message (taking IO vector)
357 * @arg sk Netlink socket (required)
358 * @arg msg Netlink message to be sent (required)
359 * @arg iov IO vector to be sent (required)
360 * @arg iovlen Number of struct iovec to be sent (required)
361 *
362 * This function is identical to nl_send() except that instead of taking a
363 * `struct nl_msg` object it takes an IO vector. Please see the description
364 * of `nl_send()`.
365 *
366 * @callback This function triggers the `NL_CB_MSG_OUT` callback.
367 *
368 * @see nl_send()
369 *
370 * @return Number of bytes sent on success or a negative error code.
371 *
372 * @lowlevel
373 */
374 int nl_send_iovec(struct nl_sock *sk, struct nl_msg *msg, struct iovec *iov, unsigned iovlen)
375 {
376 struct sockaddr_nl *dst;
377 struct ucred *creds;
378 struct msghdr hdr = {
379 .msg_name = (void *) &sk->s_peer,
380 .msg_namelen = sizeof(struct sockaddr_nl),
381 .msg_iov = iov,
382 .msg_iovlen = iovlen,
383 };
384 char buf[CMSG_SPACE(sizeof(struct ucred))];
385
386 /* Overwrite destination if specified in the message itself, defaults
387 * to the peer address of the socket.
388 */
389 dst = nlmsg_get_dst(msg);
390 if (dst->nl_family == AF_NETLINK)
391 hdr.msg_name = dst;
392
393 /* Add credentials if present. */
394 creds = nlmsg_get_creds(msg);
395 if (creds != NULL) {
396 struct cmsghdr *cmsg;
397
398 hdr.msg_control = buf;
399 hdr.msg_controllen = sizeof(buf);
400
401 cmsg = CMSG_FIRSTHDR(&hdr);
402 cmsg->cmsg_level = SOL_SOCKET;
403 cmsg->cmsg_type = SCM_CREDENTIALS;
404 cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
405 memcpy(CMSG_DATA(cmsg), creds, sizeof(struct ucred));
406 }
407
408 return nl_sendmsg(sk, msg, &hdr);
409 }
410
411 /**
412 * Transmit Netlink message
413 * @arg sk Netlink socket (required)
414 * @arg msg Netlink message (required)
415 *
416 * Transmits the Netlink message `msg` over the Netlink socket using the
417 * `sendmsg()` system call. This function is based on `nl_send_iovec()` but
418 * takes care of initializing a `struct iovec` based on the `msg` object.
419 *
420 * The message is addressed to the peer as specified in the socket by either
421 * the nl_socket_set_peer_port() or nl_socket_set_peer_groups() function.
422 * The peer address can be overwritten by specifying an address in the `msg`
423 * object using nlmsg_set_dst().
424 *
425 * If present in the `msg`, credentials set by the nlmsg_set_creds() function
426 * are added to the control buffer of the message.
427 *
428 * @par Overwriting Capability:
429 * Calls to this function can be overwritten by providing an alternative using
430 * the nl_cb_overwrite_send() function.
431 *
432 * @callback This function triggers the `NL_CB_MSG_OUT` callback.
433 *
434 * @attention
435 * Unlike `nl_send_auto()`, this function does *not* finalize the message in
436 * terms of automatically adding needed flags or filling out port numbers.
437 *
438 * @see nl_send_auto()
439 * @see nl_send_iovec()
440 * @see nl_socket_set_peer_port()
441 * @see nl_socket_set_peer_groups()
442 * @see nlmsg_set_dst()
443 * @see nlmsg_set_creds()
444 * @see nl_cb_overwrite_send()
445 *
446 * @return Number of bytes sent on success or a negative error code.
447 */
448 int nl_send(struct nl_sock *sk, struct nl_msg *msg)
449 {
450 struct nl_cb *cb = sk->s_cb;
451
452 if (cb->cb_send_ow)
453 return cb->cb_send_ow(sk, msg);
454 else {
455 struct iovec iov = {
456 .iov_base = (void *) nlmsg_hdr(msg),
457 .iov_len = nlmsg_hdr(msg)->nlmsg_len,
458 };
459
460 return nl_send_iovec(sk, msg, &iov, 1);
461 }
462 }
463
464 /**
465 * Finalize Netlink message
466 * @arg sk Netlink socket (required)
467 * @arg msg Netlink message (required)
468 *
469 * This function finalizes a Netlink message by completing the message with
470 * desirable flags and values depending on the socket configuration.
471 *
472 * - If not yet filled out, the source address of the message (`nlmsg_pid`)
473 * will be set to the local port number of the socket.
474 * - If not yet specified, the next available sequence number is assigned
475 * to the message (`nlmsg_seq`).
476 * - If not yet specified, the protocol field of the message will be set to
477 * the protocol field of the socket.
478 * - The `NLM_F_REQUEST` Netlink message flag will be set.
479 * - The `NLM_F_ACK` flag will be set if Auto-ACK mode is enabled on the
480 * socket.
481 */
482 void nl_complete_msg(struct nl_sock *sk, struct nl_msg *msg)
483 {
484 struct nlmsghdr *nlh;
485
486 nlh = nlmsg_hdr(msg);
487 if (nlh->nlmsg_pid == NL_AUTO_PORT)
488 nlh->nlmsg_pid = nl_socket_get_local_port(sk);
489
490 if (nlh->nlmsg_seq == NL_AUTO_SEQ)
491 nlh->nlmsg_seq = sk->s_seq_next++;
492
493 if (msg->nm_protocol == -1)
494 msg->nm_protocol = sk->s_proto;
495
496 nlh->nlmsg_flags |= NLM_F_REQUEST;
497
498 if (!(sk->s_flags & NL_NO_AUTO_ACK))
499 nlh->nlmsg_flags |= NLM_F_ACK;
500 }
501
502 /**
503 * Finalize and transmit Netlink message
504 * @arg sk Netlink socket (required)
505 * @arg msg Netlink message (required)
506 *
507 * Finalizes the message by passing it to `nl_complete_msg()` and transmits it
508 * by passing it to `nl_send()`.
509 *
510 * @callback This function triggers the `NL_CB_MSG_OUT` callback.
511 *
512 * @see nl_complete_msg()
513 * @see nl_send()
514 *
515 * @return Number of bytes sent or a negative error code.
516 */
517 int nl_send_auto(struct nl_sock *sk, struct nl_msg *msg)
518 {
519 nl_complete_msg(sk, msg);
520
521 return nl_send(sk, msg);
522 }
523
524 /**
525 * Finalize and transmit Netlink message and wait for ACK or error message
526 * @arg sk Netlink socket (required)
527 * @arg msg Netlink message (required)
528 *
529 * Passes the `msg` to `nl_send_auto()` to finalize and transmit it. Frees the
530 * message and waits (sleeps) for the ACK or error message to be received.
531 *
532 * @attention
533 * Disabling Auto-ACK (nl_socket_disable_auto_ack()) will cause this function
534 * to return immediately after transmitting the message. However, the peer may
535 * still be returning an error message in response to the request. It is the
536 * responsibility of the caller to handle such messages.
537 *
538 * @callback This function triggers the `NL_CB_MSG_OUT` callback.
539 *
540 * @attention
541 * This function frees the `msg` object after transmitting it by calling
542 * `nlmsg_free()`.
543 *
544 * @see nl_send_auto().
545 * @see nl_wait_for_ack()
546 *
547 * @return 0 on success or a negative error code.
548 */
549 int nl_send_sync(struct nl_sock *sk, struct nl_msg *msg)
550 {
551 int err;
552
553 err = nl_send_auto(sk, msg);
554 nlmsg_free(msg);
555 if (err < 0)
556 return err;
557
558 return wait_for_ack(sk);
559 }
560
561 /**
562 * Construct and transmit a Netlink message
563 * @arg sk Netlink socket (required)
564 * @arg type Netlink message type (required)
565 * @arg flags Netlink message flags (optional)
566 * @arg buf Data buffer (optional)
567 * @arg size Size of data buffer (optional)
568 *
569 * Allocates a new Netlink message based on `type` and `flags`. If `buf`
570 * points to payload of length `size` that payload will be appended to the
571 * message.
572 *
573 * Sends out the message using `nl_send_auto()` and frees the message
574 * afterwards.
575 *
576 * @see nl_send_auto()
577 *
578 * @return Number of characters sent on success or a negative error code.
579 * @retval -NLE_NOMEM Unable to allocate Netlink message
580 */
581 int nl_send_simple(struct nl_sock *sk, int type, int flags, void *buf,
582 size_t size)
583 {
584 int err;
585 struct nl_msg *msg;
586
587 msg = nlmsg_alloc_simple(type, flags);
588 if (!msg)
589 return -NLE_NOMEM;
590
591 if (buf && size) {
592 err = nlmsg_append(msg, buf, size, NLMSG_ALIGNTO);
593 if (err < 0)
594 goto errout;
595 }
596
597 err = nl_send_auto(sk, msg);
598 errout:
599 nlmsg_free(msg);
600
601 return err;
602 }
603
604 /** @} */
605
606 /**
607 * @name Receive
608 * @{
609 */
610
611 /**
612 * Receive data from netlink socket
613 * @arg sk Netlink socket (required)
614 * @arg nla Netlink socket structure to hold address of peer (required)
615 * @arg buf Destination pointer for message content (required)
616 * @arg creds Destination pointer for credentials (optional)
617 *
618 * Receives data from a connected netlink socket using recvmsg() and returns
619 * the number of bytes read. The read data is stored in a newly allocated
620 * buffer that is assigned to \c *buf. The peer's netlink address will be
621 * stored in \c *nla.
622 *
623 * This function blocks until data is available to be read unless the socket
624 * has been put into non-blocking mode using nl_socket_set_nonblocking() in
625 * which case this function will return immediately with a return value of
626 * -NLA_AGAIN (versions before 3.2.22 returned instead 0, in which case you
627 * should check first clear errno and then check for errno EAGAIN).
628 *
629 * The buffer size used when reading from the netlink socket and thus limiting
630 * the maximum size of a netlink message that can be read defaults to the size
631 * of a memory page (getpagesize()). The buffer size can be modified on a per
632 * socket level using the function nl_socket_set_msg_buf_size().
633 *
634 * If message peeking is enabled using nl_socket_enable_msg_peek() the size of
635 * the message to be read will be determined using the MSG_PEEK flag prior to
636 * performing the actual read. This leads to an additional recvmsg() call for
637 * every read operation which has performance implications and is not
638 * recommended for high throughput protocols.
639 *
640 * An eventual interruption of the recvmsg() system call is automatically
641 * handled by retrying the operation.
642 *
643 * If receiving of credentials has been enabled using the function
644 * nl_socket_set_passcred(), this function will allocate a new struct ucred
645 * filled with the received credentials and assign it to \c *creds. The caller
646 * is responsible for freeing the buffer.
647 *
648 * @note The caller is responsible to free the returned data buffer and if
649 * enabled, the credentials buffer.
650 *
651 * @see nl_socket_set_nonblocking()
652 * @see nl_socket_set_msg_buf_size()
653 * @see nl_socket_enable_msg_peek()
654 * @see nl_socket_set_passcred()
655 *
656 * @return Number of bytes read, 0 on EOF, 0 on no data event (non-blocking
657 * mode), or a negative error code.
658 */
659 int nl_recv(struct nl_sock *sk, struct sockaddr_nl *nla,
660 unsigned char **buf, struct ucred **creds)
661 {
662 ssize_t n;
663 int flags = 0;
664 static int page_size = 0;
665 struct iovec iov;
666 struct msghdr msg = {
667 .msg_name = (void *) nla,
668 .msg_namelen = sizeof(struct sockaddr_nl),
669 .msg_iov = &iov,
670 .msg_iovlen = 1,
671 };
672 struct ucred* tmpcreds = NULL;
673 int retval = 0;
674
675 if (!buf || !nla)
676 return -NLE_INVAL;
677
678 if ( (sk->s_flags & NL_MSG_PEEK)
679 || (!(sk->s_flags & NL_MSG_PEEK_EXPLICIT) && sk->s_bufsize == 0))
680 flags |= MSG_PEEK | MSG_TRUNC;
681
682 if (page_size == 0)
683 page_size = getpagesize() * 4;
684
685 iov.iov_len = sk->s_bufsize ? sk->s_bufsize : page_size;
686 iov.iov_base = malloc(iov.iov_len);
687
688 if (!iov.iov_base) {
689 retval = -NLE_NOMEM;
690 goto abort;
691 }
692
693 if (creds && (sk->s_flags & NL_SOCK_PASSCRED)) {
694 msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred));
695 msg.msg_control = malloc(msg.msg_controllen);
696 if (!msg.msg_control) {
697 retval = -NLE_NOMEM;
698 goto abort;
699 }
700 }
701 retry:
702
703 n = recvmsg(sk->s_fd, &msg, flags);
704 if (!n) {
705 retval = 0;
706 goto abort;
707 }
708 if (n < 0) {
709 if (errno == EINTR) {
710 NL_DBG(3, "recvmsg() returned EINTR, retrying\n");
711 goto retry;
712 }
713
714 NL_DBG(4, "recvmsg(%p): nl_recv() failed with %d (%s)\n",
715 sk, errno, nl_strerror_l(errno));
716 retval = -nl_syserr2nlerr(errno);
717 goto abort;
718 }
719
720 if (msg.msg_flags & MSG_CTRUNC) {
721 void *tmp;
722
723 if (msg.msg_controllen == 0) {
724 retval = -NLE_MSG_TRUNC;
725 NL_DBG(4, "recvmsg(%p): Received unexpected control data", sk);
726 goto abort;
727 }
728
729 msg.msg_controllen *= 2;
730 tmp = realloc(msg.msg_control, msg.msg_controllen);
731 if (!tmp) {
732 retval = -NLE_NOMEM;
733 goto abort;
734 }
735 msg.msg_control = tmp;
736 goto retry;
737 }
738
739 if (iov.iov_len < n || (msg.msg_flags & MSG_TRUNC)) {
740 void *tmp;
741
742 /* respond with error to an incomplete message */
743 if (flags == 0) {
744 retval = -NLE_MSG_TRUNC;
745 goto abort;
746 }
747
748 /* Provided buffer is not long enough, enlarge it
749 * to size of n (which should be total length of the message)
750 * and try again. */
751 iov.iov_len = n;
752 tmp = realloc(iov.iov_base, iov.iov_len);
753 if (!tmp) {
754 retval = -NLE_NOMEM;
755 goto abort;
756 }
757 iov.iov_base = tmp;
758 flags = 0;
759 goto retry;
760 }
761
762 if (flags != 0) {
763 /* Buffer is big enough, do the actual reading */
764 flags = 0;
765 goto retry;
766 }
767
768 if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
769 retval = -NLE_NOADDR;
770 goto abort;
771 }
772
773 if (creds && (sk->s_flags & NL_SOCK_PASSCRED)) {
774 struct cmsghdr *cmsg;
775
776 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
777 if (cmsg->cmsg_level != SOL_SOCKET)
778 continue;
779 if (cmsg->cmsg_type != SCM_CREDENTIALS)
780 continue;
781 tmpcreds = malloc(sizeof(*tmpcreds));
782 if (!tmpcreds) {
783 retval = -NLE_NOMEM;
784 goto abort;
785 }
786 memcpy(tmpcreds, CMSG_DATA(cmsg), sizeof(*tmpcreds));
787 break;
788 }
789 }
790
791 retval = n;
792 abort:
793 free(msg.msg_control);
794
795 if (retval <= 0) {
796 free(iov.iov_base);
797 iov.iov_base = NULL;
798 free(tmpcreds);
799 tmpcreds = NULL;
800 } else
801 *buf = iov.iov_base;
802
803 if (creds)
804 *creds = tmpcreds;
805
806 return retval;
807 }
808
809 /** @cond SKIP */
810 #define NL_CB_CALL(cb, type, msg) \
811 do { \
812 err = nl_cb_call(cb, type, msg); \
813 switch (err) { \
814 case NL_OK: \
815 err = 0; \
816 break; \
817 case NL_SKIP: \
818 goto skip; \
819 case NL_STOP: \
820 goto stop; \
821 default: \
822 goto out; \
823 } \
824 } while (0)
825 /** @endcond */
826
827 static int recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
828 {
829 int n, err = 0, multipart = 0, interrupted = 0, nrecv = 0;
830 unsigned char *buf = NULL;
831 struct nlmsghdr *hdr;
832
833 /*
834 nla is passed on to not only to nl_recv() but may also be passed
835 to a function pointer provided by the caller which may or may not
836 initialize the variable. Thomas Graf.
837 */
838 struct sockaddr_nl nla = {0};
839 struct nl_msg *msg = NULL;
840 struct ucred *creds = NULL;
841
842 continue_reading:
843 NL_DBG(3, "Attempting to read from %p\n", sk);
844 if (cb->cb_recv_ow)
845 n = cb->cb_recv_ow(sk, &nla, &buf, &creds);
846 else
847 n = nl_recv(sk, &nla, &buf, &creds);
848
849 if (n <= 0)
850 return n;
851
852 NL_DBG(3, "recvmsgs(%p): Read %d bytes\n", sk, n);
853
854 hdr = (struct nlmsghdr *) buf;
855 while (nlmsg_ok(hdr, n)) {
856 NL_DBG(3, "recvmsgs(%p): Processing valid message...\n", sk);
857
858 nlmsg_free(msg);
859 msg = nlmsg_convert(hdr);
860 if (!msg) {
861 err = -NLE_NOMEM;
862 goto out;
863 }
864
865 nlmsg_set_proto(msg, sk->s_proto);
866 nlmsg_set_src(msg, &nla);
867 if (creds)
868 nlmsg_set_creds(msg, creds);
869
870 nrecv++;
871
872 /* Raw callback is the first, it gives the most control
873 * to the user and he can do his very own parsing. */
874 if (cb->cb_set[NL_CB_MSG_IN])
875 NL_CB_CALL(cb, NL_CB_MSG_IN, msg);
876
877 /* Sequence number checking. The check may be done by
878 * the user, otherwise a very simple check is applied
879 * enforcing strict ordering */
880 if (cb->cb_set[NL_CB_SEQ_CHECK]) {
881 NL_CB_CALL(cb, NL_CB_SEQ_CHECK, msg);
882
883 /* Only do sequence checking if auto-ack mode is enabled */
884 } else if (!(sk->s_flags & NL_NO_AUTO_ACK)) {
885 if (hdr->nlmsg_seq != sk->s_seq_expect) {
886 if (cb->cb_set[NL_CB_INVALID])
887 NL_CB_CALL(cb, NL_CB_INVALID, msg);
888 else {
889 err = -NLE_SEQ_MISMATCH;
890 goto out;
891 }
892 }
893 }
894
895 if (hdr->nlmsg_type == NLMSG_DONE ||
896 hdr->nlmsg_type == NLMSG_ERROR ||
897 hdr->nlmsg_type == NLMSG_NOOP ||
898 hdr->nlmsg_type == NLMSG_OVERRUN) {
899 /* We can't check for !NLM_F_MULTI since some netlink
900 * users in the kernel are broken. */
901 sk->s_seq_expect++;
902 NL_DBG(3, "recvmsgs(%p): Increased expected " \
903 "sequence number to %d\n",
904 sk, sk->s_seq_expect);
905 }
906
907 if (hdr->nlmsg_flags & NLM_F_MULTI)
908 multipart = 1;
909
910 if (hdr->nlmsg_flags & NLM_F_DUMP_INTR) {
911 if (cb->cb_set[NL_CB_DUMP_INTR])
912 NL_CB_CALL(cb, NL_CB_DUMP_INTR, msg);
913 else {
914 /*
915 * We have to continue reading to clear
916 * all messages until a NLMSG_DONE is
917 * received and report the inconsistency.
918 */
919 interrupted = 1;
920 }
921 }
922
923 /* Other side wishes to see an ack for this message */
924 if (hdr->nlmsg_flags & NLM_F_ACK) {
925 if (cb->cb_set[NL_CB_SEND_ACK])
926 NL_CB_CALL(cb, NL_CB_SEND_ACK, msg);
927 else {
928 /* FIXME: implement */
929 }
930 }
931
932 /* messages terminates a multipart message, this is
933 * usually the end of a message and therefore we slip
934 * out of the loop by default. the user may overrule
935 * this action by skipping this packet. */
936 if (hdr->nlmsg_type == NLMSG_DONE) {
937 multipart = 0;
938 if (cb->cb_set[NL_CB_FINISH])
939 NL_CB_CALL(cb, NL_CB_FINISH, msg);
940 }
941
942 /* Message to be ignored, the default action is to
943 * skip this message if no callback is specified. The
944 * user may overrule this action by returning
945 * NL_PROCEED. */
946 else if (hdr->nlmsg_type == NLMSG_NOOP) {
947 if (cb->cb_set[NL_CB_SKIPPED])
948 NL_CB_CALL(cb, NL_CB_SKIPPED, msg);
949 else
950 goto skip;
951 }
952
953 /* Data got lost, report back to user. The default action is to
954 * quit parsing. The user may overrule this action by retuning
955 * NL_SKIP or NL_PROCEED (dangerous) */
956 else if (hdr->nlmsg_type == NLMSG_OVERRUN) {
957 if (cb->cb_set[NL_CB_OVERRUN])
958 NL_CB_CALL(cb, NL_CB_OVERRUN, msg);
959 else {
960 err = -NLE_MSG_OVERFLOW;
961 goto out;
962 }
963 }
964
965 /* Message carries a nlmsgerr */
966 else if (hdr->nlmsg_type == NLMSG_ERROR) {
967 struct nlmsgerr *e = nlmsg_data(hdr);
968
969 if (hdr->nlmsg_len < nlmsg_size(sizeof(*e))) {
970 /* Truncated error message, the default action
971 * is to stop parsing. The user may overrule
972 * this action by returning NL_SKIP or
973 * NL_PROCEED (dangerous) */
974 if (cb->cb_set[NL_CB_INVALID])
975 NL_CB_CALL(cb, NL_CB_INVALID, msg);
976 else {
977 err = -NLE_MSG_TRUNC;
978 goto out;
979 }
980 } else if (e->error) {
981 NL_DBG(4, "recvmsgs(%p): RTNETLINK responded with %d (%s)\n",
982 sk, -e->error, nl_strerror_l(-e->error));
983
984 /* Error message reported back from kernel. */
985 if (cb->cb_err) {
986 err = cb->cb_err(&nla, e,
987 cb->cb_err_arg);
988 if (err < 0)
989 goto out;
990 else if (err == NL_SKIP)
991 goto skip;
992 else if (err == NL_STOP) {
993 err = -nl_syserr2nlerr(e->error);
994 goto out;
995 }
996 } else {
997 err = -nl_syserr2nlerr(e->error);
998 goto out;
999 }
1000 } else if (cb->cb_set[NL_CB_ACK])
1001 NL_CB_CALL(cb, NL_CB_ACK, msg);
1002 } else {
1003 /* Valid message (not checking for MULTIPART bit to
1004 * get along with broken kernels. NL_SKIP has no
1005 * effect on this. */
1006 if (cb->cb_set[NL_CB_VALID])
1007 NL_CB_CALL(cb, NL_CB_VALID, msg);
1008 }
1009 skip:
1010 err = 0;
1011 hdr = nlmsg_next(hdr, &n);
1012 }
1013
1014 nlmsg_free(msg);
1015 free(buf);
1016 free(creds);
1017 buf = NULL;
1018 msg = NULL;
1019 creds = NULL;
1020
1021 if (multipart) {
1022 /* Multipart message not yet complete, continue reading */
1023 goto continue_reading;
1024 }
1025 stop:
1026 err = 0;
1027 out:
1028 nlmsg_free(msg);
1029 free(buf);
1030 free(creds);
1031
1032 if (interrupted)
1033 err = -NLE_DUMP_INTR;
1034
1035 if (!err)
1036 err = nrecv;
1037
1038 return err;
1039 }
1040
1041 /**
1042 * Receive a set of messages from a netlink socket and report parsed messages
1043 * @arg sk Netlink socket.
1044 * @arg cb set of callbacks to control behaviour.
1045 *
1046 * This function is identical to nl_recvmsgs() to the point that it will
1047 * return the number of parsed messages instead of 0 on success.
1048 *
1049 * @see nl_recvmsgs()
1050 *
1051 * @return Number of received messages or a negative error code from nl_recv().
1052 */
1053 int nl_recvmsgs_report(struct nl_sock *sk, struct nl_cb *cb)
1054 {
1055 if (cb->cb_recvmsgs_ow)
1056 return cb->cb_recvmsgs_ow(sk, cb);
1057 else
1058 return recvmsgs(sk, cb);
1059 }
1060
1061 /**
1062 * Receive a set of messages from a netlink socket.
1063 * @arg sk Netlink socket.
1064 * @arg cb set of callbacks to control behaviour.
1065 *
1066 * Repeatedly calls nl_recv() or the respective replacement if provided
1067 * by the application (see nl_cb_overwrite_recv()) and parses the
1068 * received data as netlink messages. Stops reading if one of the
1069 * callbacks returns NL_STOP or nl_recv returns either 0 or a negative error code.
1070 *
1071 * A non-blocking sockets causes the function to return immediately if
1072 * no data is available.
1073 *
1074 * @see nl_recvmsgs_report()
1075 *
1076 * @return 0 on success or a negative error code from nl_recv().
1077 */
1078 int nl_recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
1079 {
1080 int err;
1081
1082 if ((err = nl_recvmsgs_report(sk, cb)) > 0)
1083 err = 0;
1084
1085 return err;
1086 }
1087
1088 /**
1089 * Receive a set of message from a netlink socket using handlers in nl_sock.
1090 * @arg sk Netlink socket.
1091 *
1092 * Calls nl_recvmsgs() with the handlers configured in the netlink socket.
1093 */
1094 int nl_recvmsgs_default(struct nl_sock *sk)
1095 {
1096 return nl_recvmsgs(sk, sk->s_cb);
1097
1098 }
1099
1100 static int ack_wait_handler(struct nl_msg *msg, void *arg)
1101 {
1102 return NL_STOP;
1103 }
1104
1105 /**
1106 * Wait for ACK.
1107 * @arg sk Netlink socket.
1108 * @pre The netlink socket must be in blocking state.
1109 *
1110 * Waits until an ACK is received for the latest not yet acknowledged
1111 * netlink message.
1112 */
1113 int nl_wait_for_ack(struct nl_sock *sk)
1114 {
1115 int err;
1116 struct nl_cb *cb;
1117
1118 cb = nl_cb_clone(sk->s_cb);
1119 if (cb == NULL)
1120 return -NLE_NOMEM;
1121
1122 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, NULL);
1123 err = nl_recvmsgs(sk, cb);
1124 nl_cb_put(cb);
1125
1126 return err;
1127 }
1128
1129 /** @cond SKIP */
1130 struct pickup_param
1131 {
1132 int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *,
1133 struct nlmsghdr *, struct nl_parser_param *);
1134 struct nl_object *result;
1135 int *syserror;
1136 };
1137
1138 static int __store_answer(struct nl_object *obj, struct nl_parser_param *p)
1139 {
1140 struct pickup_param *pp = p->pp_arg;
1141 /*
1142 * the parser will put() the object at the end, expecting the cache
1143 * to take the reference.
1144 */
1145 nl_object_get(obj);
1146 pp->result = obj;
1147
1148 return 0;
1149 }
1150
1151 static int __pickup_answer(struct nl_msg *msg, void *arg)
1152 {
1153 struct pickup_param *pp = arg;
1154 struct nl_parser_param parse_arg = {
1155 .pp_cb = __store_answer,
1156 .pp_arg = pp,
1157 };
1158
1159 return pp->parser(NULL, &msg->nm_src, msg->nm_nlh, &parse_arg);
1160 }
1161
1162 static int __pickup_answer_syserr(struct sockaddr_nl *nla, struct nlmsgerr *nlerr, void *arg)
1163 {
1164 *(((struct pickup_param *) arg)->syserror) = nlerr->error;
1165
1166 return -nl_syserr2nlerr(nlerr->error);
1167 }
1168
1169 /** @endcond */
1170
1171 /**
1172 * Pickup netlink answer, parse is and return object
1173 * @arg sk Netlink socket
1174 * @arg parser Parser function to parse answer
1175 * @arg result Result pointer to return parsed object
1176 *
1177 * @return 0 on success or a negative error code.
1178 */
1179 int nl_pickup(struct nl_sock *sk,
1180 int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *,
1181 struct nlmsghdr *, struct nl_parser_param *),
1182 struct nl_object **result)
1183 {
1184 return nl_pickup_keep_syserr(sk, parser, result, NULL);
1185 }
1186
1187 /**
1188 * Pickup netlink answer, parse is and return object with preserving system error
1189 * @arg sk Netlink socket
1190 * @arg parser Parser function to parse answer
1191 * @arg result Result pointer to return parsed object
1192 * @arg syserr Result pointer for the system error in case of failure
1193 *
1194 * @return 0 on success or a negative error code.
1195 */
1196 int nl_pickup_keep_syserr(struct nl_sock *sk,
1197 int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *,
1198 struct nlmsghdr *, struct nl_parser_param *),
1199 struct nl_object **result,
1200 int *syserror)
1201 {
1202 struct nl_cb *cb;
1203 int err;
1204 struct pickup_param pp = {
1205 .parser = parser,
1206 };
1207
1208 cb = nl_cb_clone(sk->s_cb);
1209 if (cb == NULL)
1210 return -NLE_NOMEM;
1211
1212 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, __pickup_answer, &pp);
1213 if (syserror) {
1214 *syserror = 0;
1215 pp.syserror = syserror;
1216 nl_cb_err(cb, NL_CB_CUSTOM, __pickup_answer_syserr, &pp);
1217 }
1218
1219 err = nl_recvmsgs(sk, cb);
1220 if (err < 0)
1221 goto errout;
1222
1223 *result = pp.result;
1224 errout:
1225 nl_cb_put(cb);
1226
1227 return err;
1228 }
1229
1230 /** @} */
1231
1232 /**
1233 * @name Deprecated
1234 * @{
1235 */
1236
1237 /**
1238 * @deprecated Please use nl_complete_msg()
1239 */
1240 void nl_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
1241 {
1242 nl_complete_msg(sk, msg);
1243 }
1244
1245 /**
1246 * @deprecated Please use nl_send_auto()
1247 */
1248 int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
1249 {
1250 return nl_send_auto(sk, msg);
1251 }
1252
1253
1254 /** @} */
1255
1256 /** @} */
1257
1258 /** @} */
NL_CB_OVERRUN
Report received that data was lost.
Definition: handlers.h:99
nl_send_auto_complete
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
Definition: nl.c:1248
NL_CB_MSG_OUT
Called for every message sent out except for nl_sendto()
Definition: handlers.h:107
NL_CB_ACK
Message is an acknowledge.
Definition: handlers.h:103
nlmsg_free
void nlmsg_free(struct nl_msg *msg)
Release a reference from an netlink message.
Definition: msg.c:565
nlmsg_data
void * nlmsg_data(const struct nlmsghdr *nlh)
Return pointer to message payload.
Definition: msg.c:107
NL_CB_SEND_ACK
Sending of an acknowledge message has been requested.
Definition: handlers.h:113
nl_complete_msg
void nl_complete_msg(struct nl_sock *sk, struct nl_msg *msg)
Finalize Netlink message.
Definition: nl.c:482
NL_AUTO_PORT
#define NL_AUTO_PORT
Will cause the netlink port to be set to the port assigned to the netlink icoket ust before sending t...
Definition: msg.h:35
nlmsg_size
int nlmsg_size(int payload)
Calculates size of netlink message based on payload length.
Definition: msg.c:56
NL_CB_CUSTOM
Customized handler specified by the user.
Definition: handlers.h:83
NL_AUTO_SEQ
#define NL_AUTO_SEQ
May be used to refer to a sequence number which should be automatically set just before sending the m...
Definition: msg.h:46
nl_object_get
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
Definition: object.c:205
nl_send_sync
int nl_send_sync(struct nl_sock *sk, struct nl_msg *msg)
Finalize and transmit Netlink message and wait for ACK or error message.
Definition: nl.c:549
NL_CB_SKIPPED
Message wants to be skipped.
Definition: handlers.h:101
nl_pickup
int nl_pickup(struct nl_sock *sk, int(*parser)(struct nl_cache_ops *, struct sockaddr_nl *, struct nlmsghdr *, struct nl_parser_param *), struct nl_object **result)
Pickup netlink answer, parse is and return object.
Definition: nl.c:1179
nl_pickup_keep_syserr
int nl_pickup_keep_syserr(struct nl_sock *sk, int(*parser)(struct nl_cache_ops *, struct sockaddr_nl *, struct nlmsghdr *, struct nl_parser_param *), struct nl_object **result, int *syserror)
Pickup netlink answer, parse is and return object with preserving system error.
Definition: nl.c:1196
nlmsg_ok
int nlmsg_ok(const struct nlmsghdr *nlh, int remaining)
check if the netlink message fits into the remaining bytes
Definition: msg.c:181
NL_STOP
Stop parsing altogether and discard remaining messages.
Definition: handlers.h:68
nl_socket_set_local_port
void nl_socket_set_local_port(struct nl_sock *sk, uint32_t port)
Set local port of socket.
Definition: socket.c:404
NL_CB_MSG_IN
Called for every message received.
Definition: handlers.h:105
nl_cb_clone
struct nl_cb * nl_cb_clone(struct nl_cb *orig)
Clone an existing callback handle.
Definition: handlers.c:231
nl_cb_set
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:294
nl_recvmsgs
int nl_recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
Receive a set of messages from a netlink socket.
Definition: nl.c:1078
nl_connect
int nl_connect(struct nl_sock *sk, int protocol)
Create file descriptor and bind socket.
Definition: nl.c:104
nlmsg_next
struct nlmsghdr * nlmsg_next(struct nlmsghdr *nlh, int *remaining)
next netlink message in message stream
Definition: msg.c:196
NL_CB_INVALID
Message is malformed and invalid.
Definition: handlers.h:109
NL_CB_DUMP_INTR
Flag NLM_F_DUMP_INTR is set in message.
Definition: handlers.h:115
NL_SKIP
Skip this message.
Definition: handlers.h:66
NL_CB_FINISH
Last message in a series of multi part messages received.
Definition: handlers.h:97
nlmsg_hdr
struct nlmsghdr * nlmsg_hdr(struct nl_msg *n)
Return actual netlink message.
Definition: msg.c:543
nl_send_iovec
int nl_send_iovec(struct nl_sock *sk, struct nl_msg *msg, struct iovec *iov, unsigned iovlen)
Transmit Netlink message (taking IO vector)
Definition: nl.c:374
nl_recvmsgs_default
int nl_recvmsgs_default(struct nl_sock *sk)
Receive a set of message from a netlink socket using handlers in nl_sock.
Definition: nl.c:1094
nl_send
int nl_send(struct nl_sock *sk, struct nl_msg *msg)
Transmit Netlink message.
Definition: nl.c:448
nl_send_simple
int nl_send_simple(struct nl_sock *sk, int type, int flags, void *buf, size_t size)
Construct and transmit a Netlink message.
Definition: nl.c:581
NL_CB_VALID
Message is valid.
Definition: handlers.h:95
NL_CB_SEQ_CHECK
Called instead of internal sequence number checking.
Definition: handlers.h:111
nlmsg_append
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:449
nl_wait_for_ack
int nl_wait_for_ack(struct nl_sock *sk)
Wait for ACK.
Definition: nl.c:1113
NL_OK
Proceed with wathever would come next.
Definition: handlers.h:64
nlmsg_alloc_simple
struct nl_msg * nlmsg_alloc_simple(int nlmsgtype, int flags)
Allocate a new netlink message.
Definition: msg.c:348
nl_close
void nl_close(struct nl_sock *sk)
Close Netlink socket.
Definition: nl.c:231
nl_auto_complete
void nl_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
Definition: nl.c:1240
nl_socket_set_buffer_size
int nl_socket_set_buffer_size(struct nl_sock *sk, int rxbuf, int txbuf)
Set socket buffer size of netlink socket.
Definition: socket.c:813
nl_recvmsgs_report
int nl_recvmsgs_report(struct nl_sock *sk, struct nl_cb *cb)
Receive a set of messages from a netlink socket and report parsed messages.
Definition: nl.c:1053
nl_sendto
int nl_sendto(struct nl_sock *sk, void *buf, size_t size)
Transmit raw data over Netlink socket.
Definition: nl.c:271
nlmsg_convert
struct nl_msg * nlmsg_convert(struct nlmsghdr *hdr)
Convert a netlink message received from a netlink socket to a nl_msg.
Definition: msg.c:386
nl_send_auto
int nl_send_auto(struct nl_sock *sk, struct nl_msg *msg)
Finalize and transmit Netlink message.
Definition: nl.c:517
nl_recv
int nl_recv(struct nl_sock *sk, struct sockaddr_nl *nla, unsigned char **buf, struct ucred **creds)
Receive data from netlink socket.
Definition: nl.c:659
nl_cb_err
int nl_cb_err(struct nl_cb *cb, enum nl_cb_kind kind, nl_recvmsg_err_cb_t func, void *arg)
Set up an error callback.
Definition: handlers.c:344
nl_sendmsg
int nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr)
Transmit Netlink message using sendmsg()
Definition: nl.c:328