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