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