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