libnl  3.7.0
socket.c
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
4  */
5 
6 /**
7  * @ingroup core_types
8  * @defgroup socket Socket
9  *
10  * Representation of a netlink socket
11  *
12  * Related sections in the development guide:
13  * - @core_doc{core_sockets, Netlink Sockets}
14  *
15  * @{
16  *
17  * Header
18  * ------
19  * ~~~~{.c}
20  * #include <netlink/socket.h>
21  * ~~~~
22  */
23 
24 #include "defs.h"
25 
26 #include "sys/socket.h"
27 
28 #include <netlink-private/netlink.h>
29 #include <netlink-private/socket.h>
30 #include <netlink-private/utils.h>
31 #include <netlink/netlink.h>
32 #include <netlink/utils.h>
33 #include <netlink/handlers.h>
34 #include <netlink/msg.h>
35 #include <netlink/attr.h>
36 
37 static int default_cb = NL_CB_DEFAULT;
38 
39 static void __init init_default_cb(void)
40 {
41  char *nlcb;
42 
43  if ((nlcb = getenv("NLCB"))) {
44  if (!strcasecmp(nlcb, "default"))
45  default_cb = NL_CB_DEFAULT;
46  else if (!strcasecmp(nlcb, "verbose"))
47  default_cb = NL_CB_VERBOSE;
48  else if (!strcasecmp(nlcb, "debug"))
49  default_cb = NL_CB_DEBUG;
50  else {
51  fprintf(stderr, "Unknown value for NLCB, valid values: "
52  "{default | verbose | debug}\n");
53  }
54  }
55 }
56 
57 static uint32_t used_ports_map[32];
58 static NL_RW_LOCK(port_map_lock);
59 
60 static uint32_t generate_local_port(void)
61 {
62  int i, j, m;
63  uint16_t n;
64  static uint16_t idx_state = 0;
65  uint32_t pid = getpid() & 0x3FFFFF;
66 
67  nl_write_lock(&port_map_lock);
68 
69  if (idx_state == 0) {
70  uint32_t t = time(NULL);
71 
72  /* from time to time (on average each 2^15 calls), the idx_state will
73  * be zero again. No problem, just "seed" anew with time(). */
74  idx_state = t ^ (t >> 16) ^ 0x3047;
75  } else
76  idx_state = idx_state + 20011; /* add prime number */
77 
78  i = idx_state >> 5;
79  n = idx_state;
80  for (j = 0; j < 32; j++) {
81  /* walk the index somewhat randomized, with always leaving the block
82  * #0 as last. The reason is that libnl-1 will start at block #0,
83  * so just leave the first 32 ports preferably for libnl-1 owned sockets
84  * (this is relevant only if the applications ends up using both versions
85  * of the library and doesn't hurt otherwise). */
86  if (j == 31)
87  i = 0;
88  else
89  i = (((i-1) + 7) % 31) + 1;
90 
91  if (used_ports_map[i] == 0xFFFFFFFF)
92  continue;
93 
94  for (m = 0; m < 32; m++) {
95  n = (n + 13u) % 32u;
96  if (1UL & (used_ports_map[i] >> n))
97  continue;
98 
99  used_ports_map[i] |= (1UL << n);
100  n += (i * 32);
101 
102  /* PID_MAX_LIMIT is currently at 2^22, leaving 10 bit
103  * to, i.e. 1024 unique ports per application. */
104 
105  nl_write_unlock(&port_map_lock);
106 
107  /* ensure we don't return zero. */
108  pid = pid + (n << 22);
109  return pid ? pid : 1024;
110  }
111  }
112 
113  nl_write_unlock(&port_map_lock);
114  return 0;
115 }
116 
117 static void release_local_port(uint32_t port)
118 {
119  int nr;
120  uint32_t mask;
121 
122  BUG_ON(port == 0);
123 
124  nr = port >> 22;
125  mask = 1UL << (nr % 32);
126  nr /= 32;
127 
128  nl_write_lock(&port_map_lock);
129  BUG_ON((used_ports_map[nr] & mask) != mask);
130  used_ports_map[nr] &= ~mask;
131  nl_write_unlock(&port_map_lock);
132 }
133 
134 /** \cond skip */
135 void _nl_socket_used_ports_release_all(const uint32_t *used_ports)
136 {
137  int i;
138 
139  for (i = 0; i < 32; i++) {
140  if (used_ports[i] != 0) {
141  nl_write_lock(&port_map_lock);
142  for (; i < 32; i++) {
143  BUG_ON((used_ports_map[i] & used_ports[i]) != used_ports[i]);
144  used_ports_map[i] &= ~(used_ports[i]);
145  }
146  nl_write_unlock(&port_map_lock);
147  return;
148  }
149  }
150 }
151 
152 void _nl_socket_used_ports_set(uint32_t *used_ports, uint32_t port)
153 {
154  int nr;
155  int32_t mask;
156 
157  nr = port >> 22;
158  mask = 1UL << (nr % 32);
159  nr /= 32;
160 
161  /*
162  BUG_ON(port == 0 || (getpid() & 0x3FFFFF) != (port & 0x3FFFFF));
163  BUG_ON(used_ports[nr] & mask);
164  */
165 
166  used_ports[nr] |= mask;
167 }
168 /** \endcond */
169 
170 /**
171  * @name Allocation
172  * @{
173  */
174 
175 static struct nl_sock *__alloc_socket(struct nl_cb *cb)
176 {
177  struct nl_sock *sk;
178 
179  sk = calloc(1, sizeof(*sk));
180  if (!sk)
181  return NULL;
182 
183  sk->s_fd = -1;
184  sk->s_cb = nl_cb_get(cb);
185  sk->s_local.nl_family = AF_NETLINK;
186  sk->s_peer.nl_family = AF_NETLINK;
187  sk->s_seq_expect = sk->s_seq_next = time(NULL);
188 
189  /* the port is 0 (unspecified), meaning NL_OWN_PORT */
190  sk->s_flags = NL_OWN_PORT;
191 
192  return sk;
193 }
194 
195 /**
196  * Allocate new netlink socket
197  *
198  * @return Newly allocated netlink socket or NULL.
199  */
200 struct nl_sock *nl_socket_alloc(void)
201 {
202  struct nl_cb *cb;
203  struct nl_sock *sk;
204 
205  cb = nl_cb_alloc(default_cb);
206  if (!cb)
207  return NULL;
208 
209  /* will increment cb reference count on success */
210  sk = __alloc_socket(cb);
211 
212  nl_cb_put(cb);
213 
214  return sk;
215 }
216 
217 /**
218  * Allocate new socket with custom callbacks
219  * @arg cb Callback handler
220  *
221  * The reference to the callback handler is taken into account
222  * automatically, it is released again upon calling nl_socket_free().
223  *
224  *@return Newly allocted socket handle or NULL.
225  */
226 struct nl_sock *nl_socket_alloc_cb(struct nl_cb *cb)
227 {
228  if (cb == NULL)
229  BUG();
230 
231  return __alloc_socket(cb);
232 }
233 
234 /**
235  * Free a netlink socket.
236  * @arg sk Netlink socket.
237  */
238 void nl_socket_free(struct nl_sock *sk)
239 {
240  if (!sk)
241  return;
242 
243  if (sk->s_fd >= 0)
244  close(sk->s_fd);
245 
246  if (!(sk->s_flags & NL_OWN_PORT))
247  release_local_port(sk->s_local.nl_pid);
248 
249  nl_cb_put(sk->s_cb);
250  free(sk);
251 }
252 
253 /** @} */
254 
255 /**
256  * @name Sequence Numbers
257  * @{
258  */
259 
260 static int noop_seq_check(struct nl_msg *msg, void *arg)
261 {
262  return NL_OK;
263 }
264 
265 
266 /**
267  * Disable sequence number checking.
268  * @arg sk Netlink socket.
269  *
270  * Disables checking of sequence numbers on the netlink socket This is
271  * required to allow messages to be processed which were not requested by
272  * a preceding request message, e.g. netlink events.
273  *
274  * @note This function modifies the NL_CB_SEQ_CHECK configuration in
275  * the callback handle associated with the socket.
276  */
277 void nl_socket_disable_seq_check(struct nl_sock *sk)
278 {
279  nl_cb_set(sk->s_cb, NL_CB_SEQ_CHECK,
280  NL_CB_CUSTOM, noop_seq_check, NULL);
281 }
282 
283 /**
284  * Use next sequence number
285  * @arg sk Netlink socket.
286  *
287  * Uses the next available sequence number and increases the counter
288  * by one for subsequent calls.
289  *
290  * @return Unique serial sequence number
291  */
292 unsigned int nl_socket_use_seq(struct nl_sock *sk)
293 {
294  return sk->s_seq_next++;
295 }
296 
297 /**
298  * Disable automatic request for ACK
299  * @arg sk Netlink socket.
300  *
301  * The default behaviour of a socket is to request an ACK for
302  * each message sent to allow for the caller to synchronize to
303  * the completion of the netlink operation. This function
304  * disables this behaviour and will result in requests being
305  * sent which will not have the NLM_F_ACK flag set automatically.
306  * However, it is still possible for the caller to set the
307  * NLM_F_ACK flag explicitely.
308  */
309 void nl_socket_disable_auto_ack(struct nl_sock *sk)
310 {
311  sk->s_flags |= NL_NO_AUTO_ACK;
312 }
313 
314 /**
315  * Enable automatic request for ACK (default)
316  * @arg sk Netlink socket.
317  * @see nl_socket_disable_auto_ack
318  */
319 void nl_socket_enable_auto_ack(struct nl_sock *sk)
320 {
321  sk->s_flags &= ~NL_NO_AUTO_ACK;
322 }
323 
324 /** @} */
325 
326 /** \cond skip */
327 int _nl_socket_is_local_port_unspecified(struct nl_sock *sk)
328 {
329  return (sk->s_local.nl_pid == 0);
330 }
331 
332 uint32_t _nl_socket_set_local_port_no_release(struct nl_sock *sk, int generate_other)
333 {
334  uint32_t port;
335 
336  /* reset the port to generate_local_port(), but do not release
337  * the previously generated port. */
338 
339  if (generate_other)
340  port = generate_local_port();
341  else
342  port = 0;
343  sk->s_local.nl_pid = port;
344  if (port == 0) {
345  /* failed to find an unsed port. Restore the socket to have an
346  * unspecified port. */
347  sk->s_flags |= NL_OWN_PORT;
348  } else
349  sk->s_flags &= ~NL_OWN_PORT;
350  return port;
351 }
352 /** \endcond */
353 
354 /**
355  * @name Source Idenficiation
356  * @{
357  */
358 
359 uint32_t nl_socket_get_local_port(const struct nl_sock *sk)
360 {
361  if (sk->s_local.nl_pid == 0) {
362  struct nl_sock *sk_mutable = (struct nl_sock *) sk;
363 
364  /* modify the const argument sk. This is justified, because
365  * nobody ever saw the local_port from externally. So, we
366  * initilize it on first use.
367  *
368  * Note that this also means that you cannot call this function
369  * from multiple threads without synchronization. But nl_sock
370  * is not automatically threadsafe anyway, so the user is not
371  * allowed to do that.
372  */
373  sk_mutable->s_local.nl_pid = generate_local_port();
374  if (sk_mutable->s_local.nl_pid == 0) {
375  /* could not generate a local port. Assign UINT32_MAX to preserve
376  * backward compatibility. A user who cares can clear that anyway
377  * with nl_socket_set_local_port(). */
378  sk_mutable->s_local.nl_pid = UINT32_MAX;
379  sk_mutable->s_flags |= NL_OWN_PORT;
380  } else
381  sk_mutable->s_flags &= ~NL_OWN_PORT;
382  }
383  return sk->s_local.nl_pid;
384 }
385 
386 /**
387  * Set local port of socket
388  * @arg sk Netlink socket.
389  * @arg port Local port identifier
390  *
391  * Assigns a local port identifier to the socket.
392  *
393  * If port is 0, the port is reset to 'unspecified' as it is after newly
394  * calling nl_socket_alloc().
395  * Unspecified means, that the port will be generated automatically later
396  * on first use (either on nl_socket_get_local_port() or nl_connect()).
397  */
398 void nl_socket_set_local_port(struct nl_sock *sk, uint32_t port)
399 {
400  if (!(sk->s_flags & NL_OWN_PORT))
401  release_local_port(sk->s_local.nl_pid);
402  sk->s_flags |= NL_OWN_PORT;
403  sk->s_local.nl_pid = port;
404 }
405 
406 /** @} */
407 
408 /**
409  * @name Group Subscriptions
410  * @{
411  */
412 
413 /**
414  * Join groups
415  * @arg sk Netlink socket
416  * @arg group Group identifier
417  *
418  * Joins the specified groups using the modern socket option which
419  * is available since kernel version 2.6.14. It allows joining an
420  * almost arbitary number of groups without limitation. The list
421  * of groups has to be terminated by 0 (%NFNLGRP_NONE).
422  *
423  * Make sure to use the correct group definitions as the older
424  * bitmask definitions for nl_join_groups() are likely to still
425  * be present for backward compatibility reasons.
426  *
427  * @return 0 on sucess or a negative error code.
428  */
429 int nl_socket_add_memberships(struct nl_sock *sk, int group, ...)
430 {
431  int err;
432  va_list ap;
433 
434  if (sk->s_fd == -1)
435  return -NLE_BAD_SOCK;
436 
437  va_start(ap, group);
438 
439  while (group != 0) {
440  if (group < 0) {
441  va_end(ap);
442  return -NLE_INVAL;
443  }
444 
445  err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
446  &group, sizeof(group));
447  if (err < 0) {
448  va_end(ap);
449  NL_DBG(4, "nl_socket_add_memberships(%p): setsockopt() failed with %d (%s)\n",
450  sk, errno, nl_strerror_l(errno));
451  return -nl_syserr2nlerr(errno);
452  }
453 
454  group = va_arg(ap, int);
455  }
456 
457  va_end(ap);
458 
459  return 0;
460 }
461 
462 int nl_socket_add_membership(struct nl_sock *sk, int group)
463 {
464  return nl_socket_add_memberships(sk, group, 0);
465 }
466 
467 /**
468  * Leave groups
469  * @arg sk Netlink socket
470  * @arg group Group identifier
471  *
472  * Leaves the specified groups using the modern socket option
473  * which is available since kernel version 2.6.14. The list of groups
474  * has to terminated by 0 (%NFNLGRP_NONE).
475  *
476  * @see nl_socket_add_membership
477  * @return 0 on success or a negative error code.
478  */
479 int nl_socket_drop_memberships(struct nl_sock *sk, int group, ...)
480 {
481  int err;
482  va_list ap;
483 
484  if (sk->s_fd == -1)
485  return -NLE_BAD_SOCK;
486 
487  va_start(ap, group);
488 
489  while (group != 0) {
490  if (group < 0) {
491  va_end(ap);
492  return -NLE_INVAL;
493  }
494 
495  err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP,
496  &group, sizeof(group));
497  if (err < 0) {
498  va_end(ap);
499  NL_DBG(4, "nl_socket_drop_memberships(%p): setsockopt() failed with %d (%s)\n",
500  sk, errno, nl_strerror_l(errno));
501  return -nl_syserr2nlerr(errno);
502  }
503 
504  group = va_arg(ap, int);
505  }
506 
507  va_end(ap);
508 
509  return 0;
510 }
511 
512 int nl_socket_drop_membership(struct nl_sock *sk, int group)
513 {
514  return nl_socket_drop_memberships(sk, group, 0);
515 }
516 
517 
518 /**
519  * Join multicast groups (deprecated)
520  * @arg sk Netlink socket.
521  * @arg groups Bitmask of groups to join.
522  *
523  * This function defines the old way of joining multicast group which
524  * has to be done prior to calling nl_connect(). It works on any kernel
525  * version but is very limited as only 32 groups can be joined.
526  */
527 void nl_join_groups(struct nl_sock *sk, int groups)
528 {
529  sk->s_local.nl_groups |= groups;
530 }
531 
532 
533 /** @} */
534 
535 /**
536  * @name Peer Identfication
537  * @{
538  */
539 
540 uint32_t nl_socket_get_peer_port(const struct nl_sock *sk)
541 {
542  return sk->s_peer.nl_pid;
543 }
544 
545 void nl_socket_set_peer_port(struct nl_sock *sk, uint32_t port)
546 {
547  sk->s_peer.nl_pid = port;
548 }
549 
550 uint32_t nl_socket_get_peer_groups(const struct nl_sock *sk)
551 {
552  return sk->s_peer.nl_groups;
553 }
554 
555 void nl_socket_set_peer_groups(struct nl_sock *sk, uint32_t groups)
556 {
557  sk->s_peer.nl_groups = groups;
558 }
559 
560 
561 
562 /** @} */
563 
564 /**
565  * @name File Descriptor
566  * @{
567  */
568 
569 /**
570  * Return the file descriptor of the backing socket
571  * @arg sk Netlink socket
572  *
573  * Only valid after calling nl_connect() to create and bind the respective
574  * socket.
575  *
576  * @return File descriptor or -1 if not available.
577  */
578 int nl_socket_get_fd(const struct nl_sock *sk)
579 {
580  return sk->s_fd;
581 }
582 
583 /**
584  * Set the socket file descriptor externally which initializes the
585  * socket similar to nl_connect().
586  *
587  * @arg sk Netlink socket (required)
588  * @arg protocol The socket protocol (optional). Linux 2.6.32 supports
589  * the socket option SO_PROTOCOL. In this case, you can set
590  * protocol to a negative value and let it autodetect.
591  * If you set it to a non-negative value, the detected protocol
592  * must match the one provided.
593  * To support older kernels, you must specify the protocol.
594  * @arg fd Socket file descriptor to use (required)
595  *
596  * Set the socket file descriptor. @fd must be valid and bind'ed.
597  *
598  * This is an alternative to nl_connect(). nl_connect() creates, binds and
599  * sets the socket. With this function you can set the socket to an externally
600  * created file descriptor.
601  *
602  * @see nl_connect()
603  *
604  * @return 0 on success or a negative error code. On error, @fd is not closed but
605  * possibly unusable.
606  *
607  * @retval -NLE_BAD_SOCK Netlink socket is already connected
608  * @retval -NLE_INVAL Socket is of unexpected type
609  */
610 int nl_socket_set_fd(struct nl_sock *sk, int protocol, int fd)
611 {
612  int err = 0;
613  socklen_t addrlen;
614  struct sockaddr_nl local = { 0 };
615  int so_type = -1, so_protocol = -1;
616 
617  if (sk->s_fd != -1)
618  return -NLE_BAD_SOCK;
619  if (fd < 0)
620  return -NLE_INVAL;
621 
622  addrlen = sizeof(local);
623  err = getsockname(fd, (struct sockaddr *) &local,
624  &addrlen);
625  if (err < 0) {
626  NL_DBG(4, "nl_socket_set_fd(%p,%d): getsockname() failed with %d (%s)\n",
627  sk, fd, errno, nl_strerror_l(errno));
628  return -nl_syserr2nlerr(errno);
629  }
630  if (addrlen != sizeof(local))
631  return -NLE_INVAL;
632  if (local.nl_family != AF_NETLINK) {
633  NL_DBG(4, "nl_socket_set_fd(%p,%d): getsockname() returned family %d instead of %d (AF_NETLINK)\n",
634  sk, fd, local.nl_family, AF_NETLINK);
635  return -NLE_INVAL;
636  }
637 
638  addrlen = sizeof(so_type);
639  err = getsockopt(fd, SOL_SOCKET, SO_TYPE, &so_type, &addrlen);
640  if (err < 0) {
641  NL_DBG(4, "nl_socket_set_fd(%p,%d): getsockopt() for SO_TYPE failed with %d (%s)\n",
642  sk, fd, errno, nl_strerror_l(errno));
643  return -nl_syserr2nlerr(errno);
644  }
645  if (addrlen != sizeof(so_type))
646  return -NLE_INVAL;
647  if (so_type != SOCK_RAW) {
648  NL_DBG(4, "nl_socket_set_fd(%p,%d): getsockopt() returned SO_TYPE %d instead of %d (SOCK_RAW)\n",
649  sk, fd, so_type, SOCK_RAW);
650  return -NLE_INVAL;
651  }
652 
653 #if SO_PROTOCOL
654  addrlen = sizeof(so_protocol);
655  err = getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &so_protocol, &addrlen);
656  if (err < 0) {
657  if (errno == ENOPROTOOPT)
658  goto no_so_protocol;
659  NL_DBG(4, "nl_socket_set_fd(%p,%d): getsockopt() for SO_PROTOCOL failed with %d (%s)\n",
660  sk, fd, errno, nl_strerror_l(errno));
661  return -nl_syserr2nlerr(errno);
662  }
663  if (addrlen != sizeof(so_protocol))
664  return -NLE_INVAL;
665  if (protocol >= 0 && protocol != so_protocol) {
666  NL_DBG(4, "nl_socket_set_fd(%p,%d): getsockopt() for SO_PROTOCOL returned %d instead of %d\n",
667  sk, fd, so_protocol, protocol);
668  return -NLE_INVAL;
669  }
670 
671  if (0)
672 #endif
673  {
674 no_so_protocol:
675  if (protocol < 0) {
676  NL_DBG(4, "nl_socket_set_fd(%p,%d): unknown protocol and unable to detect it via SO_PROTOCOL socket option\n",
677  sk, fd);
678  return -NLE_INVAL;
679  }
680  so_protocol = protocol;
681  }
682 
683  nl_socket_set_local_port (sk, local.nl_pid);
684  sk->s_local = local;
685  sk->s_fd = fd;
686  sk->s_proto = so_protocol;
687 
688  return 0;
689 }
690 
691 /**
692  * Set file descriptor of socket to non-blocking state
693  * @arg sk Netlink socket.
694  *
695  * @return 0 on success or a negative error code.
696  */
697 int nl_socket_set_nonblocking(const struct nl_sock *sk)
698 {
699  if (sk->s_fd == -1)
700  return -NLE_BAD_SOCK;
701 
702  if (fcntl(sk->s_fd, F_SETFL, O_NONBLOCK) < 0) {
703  NL_DBG(4, "nl_socket_set_nonblocking(%p): fcntl() failed with %d (%s)\n",
704  sk, errno, nl_strerror_l(errno));
705  return -nl_syserr2nlerr(errno);
706  }
707 
708  return 0;
709 }
710 
711 /**
712  * Enable use of MSG_PEEK when reading from socket
713  * @arg sk Netlink socket.
714  *
715  * See also NL_CAPABILITY_NL_RECVMSGS_PEEK_BY_DEFAULT capability
716  */
717 void nl_socket_enable_msg_peek(struct nl_sock *sk)
718 {
719  sk->s_flags |= (NL_MSG_PEEK | NL_MSG_PEEK_EXPLICIT);
720 }
721 
722 /**
723  * Disable use of MSG_PEEK when reading from socket
724  * @arg sk Netlink socket.
725  *
726  * See also NL_CAPABILITY_NL_RECVMSGS_PEEK_BY_DEFAULT capability
727  */
728 void nl_socket_disable_msg_peek(struct nl_sock *sk)
729 {
730  sk->s_flags |= NL_MSG_PEEK_EXPLICIT;
731  sk->s_flags &= ~NL_MSG_PEEK;
732 }
733 
734 /** @} */
735 
736 /**
737  * @name Callback Handler
738  * @{
739  */
740 
741 struct nl_cb *nl_socket_get_cb(const struct nl_sock *sk)
742 {
743  return nl_cb_get(sk->s_cb);
744 }
745 
746 void nl_socket_set_cb(struct nl_sock *sk, struct nl_cb *cb)
747 {
748  if (cb == NULL)
749  BUG();
750 
751  nl_cb_put(sk->s_cb);
752  sk->s_cb = nl_cb_get(cb);
753 }
754 
755 /**
756  * Modify the callback handler associated with the socket
757  * @arg sk Netlink socket.
758  * @arg type which type callback to set
759  * @arg kind kind of callback
760  * @arg func callback function
761  * @arg arg argument to be passed to callback function
762  *
763  * @see nl_cb_set
764  */
765 int nl_socket_modify_cb(struct nl_sock *sk, enum nl_cb_type type,
766  enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func,
767  void *arg)
768 {
769  return nl_cb_set(sk->s_cb, type, kind, func, arg);
770 }
771 
772 /**
773  * Modify the error callback handler associated with the socket
774  * @arg sk Netlink socket.
775  * @arg kind kind of callback
776  * @arg func callback function
777  * @arg arg argument to be passed to callback function
778  *
779  * @see nl_cb_err
780  */
781 int nl_socket_modify_err_cb(struct nl_sock *sk, enum nl_cb_kind kind,
782  nl_recvmsg_err_cb_t func, void *arg)
783 {
784  return nl_cb_err(sk->s_cb, kind, func, arg);
785 }
786 
787 /** @} */
788 
789 /**
790  * @name Utilities
791  * @{
792  */
793 
794 /**
795  * Set socket buffer size of netlink socket.
796  * @arg sk Netlink socket.
797  * @arg rxbuf New receive socket buffer size in bytes.
798  * @arg txbuf New transmit socket buffer size in bytes.
799  *
800  * Sets the socket buffer size of a netlink socket to the specified
801  * values \c rxbuf and \c txbuf. Providing a value of \c 0 assumes a
802  * good default value.
803  *
804  * @note It is not required to call this function prior to nl_connect().
805  * @return 0 on sucess or a negative error code.
806  */
807 int nl_socket_set_buffer_size(struct nl_sock *sk, int rxbuf, int txbuf)
808 {
809  int err;
810 
811  if (rxbuf <= 0)
812  rxbuf = 32768;
813 
814  if (txbuf <= 0)
815  txbuf = 32768;
816 
817  if (sk->s_fd == -1)
818  return -NLE_BAD_SOCK;
819 
820  err = setsockopt(sk->s_fd, SOL_SOCKET, SO_SNDBUF,
821  &txbuf, sizeof(txbuf));
822  if (err < 0) {
823  NL_DBG(4, "nl_socket_set_buffer_size(%p): setsockopt() failed with %d (%s)\n",
824  sk, errno, nl_strerror_l(errno));
825  return -nl_syserr2nlerr(errno);
826  }
827 
828  err = setsockopt(sk->s_fd, SOL_SOCKET, SO_RCVBUF,
829  &rxbuf, sizeof(rxbuf));
830  if (err < 0) {
831  NL_DBG(4, "nl_socket_set_buffer_size(%p): setsockopt() failed with %d (%s)\n",
832  sk, errno, nl_strerror_l(errno));
833  return -nl_syserr2nlerr(errno);
834  }
835 
836  return 0;
837 }
838 
839 /**
840  * Set default message buffer size of netlink socket.
841  * @arg sk Netlink socket.
842  * @arg bufsize Default message buffer size in bytes.
843  *
844  * Sets the default message buffer size to the specified length in bytes.
845  * The default message buffer size limits the maximum message size the
846  * socket will be able to receive. It is generally recommneded to specify
847  * a buffer size no less than the size of a memory page.
848  *
849  * Setting the @bufsize to zero means to use a default of 4 times getpagesize().
850  *
851  * When MSG_PEEK is enabled, the buffer size is used for the initial choice
852  * of the buffer while peeking. It still makes sense to choose an optimal value
853  * to avoid realloc().
854  *
855  * When MSG_PEEK is disabled, the buffer size is important because a too small
856  * size will lead to failure of receiving the message via nl_recvmsgs().
857  *
858  * By default, MSG_PEEK is enabled unless the user calls either nl_socket_disable_msg_peek()/
859  * nl_socket_enable_msg_peek() or sets the message buffer size to a positive value.
860  * See capability NL_CAPABILITY_NL_RECVMSGS_PEEK_BY_DEFAULT for that.
861  *
862  * @return 0 on success or a negative error code.
863  */
864 int nl_socket_set_msg_buf_size(struct nl_sock *sk, size_t bufsize)
865 {
866  sk->s_bufsize = bufsize;
867 
868  return 0;
869 }
870 
871 /**
872  * Get default message buffer size of netlink socket.
873  * @arg sk Netlink socket.
874  *
875  * @return Size of default message buffer.
876  */
877 size_t nl_socket_get_msg_buf_size(struct nl_sock *sk)
878 {
879  return sk->s_bufsize;
880 }
881 
882 /**
883  * Enable/disable credential passing on netlink socket.
884  * @arg sk Netlink socket.
885  * @arg state New state (0 - disabled, 1 - enabled)
886  *
887  * @return 0 on success or a negative error code
888  */
889 int nl_socket_set_passcred(struct nl_sock *sk, int state)
890 {
891  int err;
892 
893  if (sk->s_fd == -1)
894  return -NLE_BAD_SOCK;
895 
896  err = setsockopt(sk->s_fd, SOL_SOCKET, SO_PASSCRED,
897  &state, sizeof(state));
898  if (err < 0) {
899  NL_DBG(4, "nl_socket_set_passcred(%p): setsockopt() failed with %d (%s)\n",
900  sk, errno, nl_strerror_l(errno));
901  return -nl_syserr2nlerr(errno);
902  }
903 
904  if (state)
905  sk->s_flags |= NL_SOCK_PASSCRED;
906  else
907  sk->s_flags &= ~NL_SOCK_PASSCRED;
908 
909  return 0;
910 }
911 
912 /**
913  * Enable/disable receival of additional packet information
914  * @arg sk Netlink socket.
915  * @arg state New state (0 - disabled, 1 - enabled)
916  *
917  * @return 0 on success or a negative error code
918  */
919 int nl_socket_recv_pktinfo(struct nl_sock *sk, int state)
920 {
921  int err;
922 
923  if (sk->s_fd == -1)
924  return -NLE_BAD_SOCK;
925 
926  err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_PKTINFO,
927  &state, sizeof(state));
928  if (err < 0) {
929  NL_DBG(4, "nl_socket_recv_pktinfo(%p): setsockopt() failed with %d (%s)\n",
930  sk, errno, nl_strerror_l(errno));
931  return -nl_syserr2nlerr(errno);
932  }
933 
934  return 0;
935 }
936 
937 /** @} */
938 
939 /** @} */
int(* nl_recvmsg_err_cb_t)(struct sockaddr_nl *nla, struct nlmsgerr *nlerr, void *arg)
nl_recvmsgs() callback for error message processing customization
Definition: handlers.h:47
nl_cb_type
Callback types.
Definition: handlers.h:87
int(* nl_recvmsg_msg_cb_t)(struct nl_msg *msg, void *arg)
nl_recvmsgs() callback for message processing customization
Definition: handlers.h:38
nl_cb_kind
Callback kinds.
Definition: handlers.h:69
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:287
struct nl_cb * nl_cb_alloc(enum nl_cb_kind kind)
Allocate a new callback handle.
Definition: handlers.c:195
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:337
@ NL_OK
Proceed with whatever would come next.
Definition: handlers.h:58
@ NL_CB_SEQ_CHECK
Called instead of internal sequence number checking.
Definition: handlers.h:105
@ NL_CB_DEFAULT
Default handlers (quiet)
Definition: handlers.h:71
@ NL_CB_CUSTOM
Customized handler specified by the user.
Definition: handlers.h:77
@ NL_CB_VERBOSE
Verbose default handlers (error messages printed)
Definition: handlers.h:73
@ NL_CB_DEBUG
Debug handlers for debugging.
Definition: handlers.h:75
int nl_socket_get_fd(const struct nl_sock *sk)
Return the file descriptor of the backing socket.
Definition: socket.c:578
void nl_socket_set_local_port(struct nl_sock *sk, uint32_t port)
Set local port of socket.
Definition: socket.c:398
void nl_socket_disable_auto_ack(struct nl_sock *sk)
Disable automatic request for ACK.
Definition: socket.c:309
struct nl_sock * nl_socket_alloc_cb(struct nl_cb *cb)
Allocate new socket with custom callbacks.
Definition: socket.c:226
size_t nl_socket_get_msg_buf_size(struct nl_sock *sk)
Get default message buffer size of netlink socket.
Definition: socket.c:877
int nl_socket_recv_pktinfo(struct nl_sock *sk, int state)
Enable/disable receival of additional packet information.
Definition: socket.c:919
int nl_socket_modify_err_cb(struct nl_sock *sk, enum nl_cb_kind kind, nl_recvmsg_err_cb_t func, void *arg)
Modify the error callback handler associated with the socket.
Definition: socket.c:781
void nl_join_groups(struct nl_sock *sk, int groups)
Join multicast groups (deprecated)
Definition: socket.c:527
int nl_socket_set_passcred(struct nl_sock *sk, int state)
Enable/disable credential passing on netlink socket.
Definition: socket.c:889
int nl_socket_add_memberships(struct nl_sock *sk, int group,...)
Join groups.
Definition: socket.c:429
void nl_socket_disable_msg_peek(struct nl_sock *sk)
Disable use of MSG_PEEK when reading from socket.
Definition: socket.c:728
int nl_socket_set_msg_buf_size(struct nl_sock *sk, size_t bufsize)
Set default message buffer size of netlink socket.
Definition: socket.c:864
int nl_socket_set_nonblocking(const struct nl_sock *sk)
Set file descriptor of socket to non-blocking state.
Definition: socket.c:697
void nl_socket_enable_auto_ack(struct nl_sock *sk)
Enable automatic request for ACK (default)
Definition: socket.c:319
void nl_socket_enable_msg_peek(struct nl_sock *sk)
Enable use of MSG_PEEK when reading from socket.
Definition: socket.c:717
int nl_socket_set_fd(struct nl_sock *sk, int protocol, int fd)
Set the socket file descriptor externally which initializes the socket similar to nl_connect().
Definition: socket.c:610
unsigned int nl_socket_use_seq(struct nl_sock *sk)
Use next sequence number.
Definition: socket.c:292
void nl_socket_disable_seq_check(struct nl_sock *sk)
Disable sequence number checking.
Definition: socket.c:277
int nl_socket_set_buffer_size(struct nl_sock *sk, int rxbuf, int txbuf)
Set socket buffer size of netlink socket.
Definition: socket.c:807
void nl_socket_free(struct nl_sock *sk)
Free a netlink socket.
Definition: socket.c:238
int nl_socket_drop_memberships(struct nl_sock *sk, int group,...)
Leave groups.
Definition: socket.c:479
int nl_socket_modify_cb(struct nl_sock *sk, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func, void *arg)
Modify the callback handler associated with the socket.
Definition: socket.c:765
struct nl_sock * nl_socket_alloc(void)
Allocate new netlink socket.
Definition: socket.c:200