libnl  3.2.21
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 <netlink-private/netlink.h>
33 #include <netlink/netlink.h>
34 #include <netlink/utils.h>
35 #include <netlink/handlers.h>
36 #include <netlink/msg.h>
37 #include <netlink/attr.h>
38 
39 static int default_cb = NL_CB_DEFAULT;
40 
41 static void __init init_default_cb(void)
42 {
43  char *nlcb;
44 
45  if ((nlcb = getenv("NLCB"))) {
46  if (!strcasecmp(nlcb, "default"))
47  default_cb = NL_CB_DEFAULT;
48  else if (!strcasecmp(nlcb, "verbose"))
49  default_cb = NL_CB_VERBOSE;
50  else if (!strcasecmp(nlcb, "debug"))
51  default_cb = NL_CB_DEBUG;
52  else {
53  fprintf(stderr, "Unknown value for NLCB, valid values: "
54  "{default | verbose | debug}\n");
55  }
56  }
57 }
58 
59 static uint32_t used_ports_map[32];
60 static NL_RW_LOCK(port_map_lock);
61 
62 static uint32_t generate_local_port(void)
63 {
64  int i, n;
65  uint32_t pid = getpid() & 0x3FFFFF;
66 
67  nl_write_lock(&port_map_lock);
68 
69  for (i = 0; i < 32; i++) {
70  if (used_ports_map[i] == 0xFFFFFFFF)
71  continue;
72 
73  for (n = 0; n < 32; n++) {
74  if (1UL & (used_ports_map[i] >> n))
75  continue;
76 
77  used_ports_map[i] |= (1UL << n);
78  n += (i * 32);
79 
80  /* PID_MAX_LIMIT is currently at 2^22, leaving 10 bit
81  * to, i.e. 1024 unique ports per application. */
82 
83  nl_write_unlock(&port_map_lock);
84 
85  return pid + (n << 22);
86  }
87  }
88 
89  nl_write_unlock(&port_map_lock);
90 
91  /* Out of sockets in our own PID namespace, what to do? FIXME */
92  return UINT_MAX;
93 }
94 
95 static void release_local_port(uint32_t port)
96 {
97  int nr;
98 
99  if (port == UINT_MAX)
100  return;
101 
102  nr = port >> 22;
103 
104  nl_write_lock(&port_map_lock);
105  used_ports_map[nr / 32] &= ~(1 << (nr % 32));
106  nl_write_unlock(&port_map_lock);
107 }
108 
109 /**
110  * @name Allocation
111  * @{
112  */
113 
114 static struct nl_sock *__alloc_socket(struct nl_cb *cb)
115 {
116  struct nl_sock *sk;
117 
118  sk = calloc(1, sizeof(*sk));
119  if (!sk)
120  return NULL;
121 
122  sk->s_fd = -1;
123  sk->s_cb = cb;
124  sk->s_local.nl_family = AF_NETLINK;
125  sk->s_peer.nl_family = AF_NETLINK;
126  sk->s_seq_expect = sk->s_seq_next = time(0);
127  sk->s_local.nl_pid = generate_local_port();
128  if (sk->s_local.nl_pid == UINT_MAX) {
129  nl_socket_free(sk);
130  return NULL;
131  }
132 
133  return sk;
134 }
135 
136 /**
137  * Allocate new netlink socket
138  *
139  * @return Newly allocated netlink socket or NULL.
140  */
141 struct nl_sock *nl_socket_alloc(void)
142 {
143  struct nl_cb *cb;
144 
145  cb = nl_cb_alloc(default_cb);
146  if (!cb)
147  return NULL;
148 
149  return __alloc_socket(cb);
150 }
151 
152 /**
153  * Allocate new socket with custom callbacks
154  * @arg cb Callback handler
155  *
156  * The reference to the callback handler is taken into account
157  * automatically, it is released again upon calling nl_socket_free().
158  *
159  *@return Newly allocted socket handle or NULL.
160  */
161 struct nl_sock *nl_socket_alloc_cb(struct nl_cb *cb)
162 {
163  if (cb == NULL)
164  BUG();
165 
166  return __alloc_socket(nl_cb_get(cb));
167 }
168 
169 /**
170  * Free a netlink socket.
171  * @arg sk Netlink socket.
172  */
173 void nl_socket_free(struct nl_sock *sk)
174 {
175  if (!sk)
176  return;
177 
178  if (sk->s_fd >= 0)
179  close(sk->s_fd);
180 
181  if (!(sk->s_flags & NL_OWN_PORT))
182  release_local_port(sk->s_local.nl_pid);
183 
184  nl_cb_put(sk->s_cb);
185  free(sk);
186 }
187 
188 /** @} */
189 
190 /**
191  * @name Sequence Numbers
192  * @{
193  */
194 
195 static int noop_seq_check(struct nl_msg *msg, void *arg)
196 {
197  return NL_OK;
198 }
199 
200 
201 /**
202  * Disable sequence number checking.
203  * @arg sk Netlink socket.
204  *
205  * Disables checking of sequence numbers on the netlink socket This is
206  * required to allow messages to be processed which were not requested by
207  * a preceding request message, e.g. netlink events.
208  *
209  * @note This function modifies the NL_CB_SEQ_CHECK configuration in
210  * the callback handle associated with the socket.
211  */
212 void nl_socket_disable_seq_check(struct nl_sock *sk)
213 {
214  nl_cb_set(sk->s_cb, NL_CB_SEQ_CHECK,
215  NL_CB_CUSTOM, noop_seq_check, NULL);
216 }
217 
218 /**
219  * Use next sequence number
220  * @arg sk Netlink socket.
221  *
222  * Uses the next available sequence number and increases the counter
223  * by one for subsequent calls.
224  *
225  * @return Unique serial sequence number
226  */
227 unsigned int nl_socket_use_seq(struct nl_sock *sk)
228 {
229  return sk->s_seq_next++;
230 }
231 
232 /**
233  * Disable automatic request for ACK
234  * @arg sk Netlink socket.
235  *
236  * The default behaviour of a socket is to request an ACK for
237  * each message sent to allow for the caller to synchronize to
238  * the completion of the netlink operation. This function
239  * disables this behaviour and will result in requests being
240  * sent which will not have the NLM_F_ACK flag set automatically.
241  * However, it is still possible for the caller to set the
242  * NLM_F_ACK flag explicitely.
243  */
244 void nl_socket_disable_auto_ack(struct nl_sock *sk)
245 {
246  sk->s_flags |= NL_NO_AUTO_ACK;
247 }
248 
249 /**
250  * Enable automatic request for ACK (default)
251  * @arg sk Netlink socket.
252  * @see nl_socket_disable_auto_ack
253  */
254 void nl_socket_enable_auto_ack(struct nl_sock *sk)
255 {
256  sk->s_flags &= ~NL_NO_AUTO_ACK;
257 }
258 
259 /** @} */
260 
261 /**
262  * @name Source Idenficiation
263  * @{
264  */
265 
266 uint32_t nl_socket_get_local_port(const struct nl_sock *sk)
267 {
268  return sk->s_local.nl_pid;
269 }
270 
271 /**
272  * Set local port of socket
273  * @arg sk Netlink socket.
274  * @arg port Local port identifier
275  *
276  * Assigns a local port identifier to the socket. If port is 0
277  * a unique port identifier will be generated automatically.
278  */
279 void nl_socket_set_local_port(struct nl_sock *sk, uint32_t port)
280 {
281  if (port == 0) {
282  port = generate_local_port();
283  /*
284  * Release local port after generation of a new one to be
285  * able to change local port using nl_socket_set_local_port(, 0)
286  */
287  if (!(sk->s_flags & NL_OWN_PORT))
288  release_local_port(sk->s_local.nl_pid);
289  else
290  sk->s_flags &= ~NL_OWN_PORT;
291  } else {
292  if (!(sk->s_flags & NL_OWN_PORT))
293  release_local_port(sk->s_local.nl_pid);
294  sk->s_flags |= NL_OWN_PORT;
295  }
296 
297  sk->s_local.nl_pid = port;
298 }
299 
300 /** @} */
301 
302 /**
303  * @name Group Subscriptions
304  * @{
305  */
306 
307 /**
308  * Join groups
309  * @arg sk Netlink socket
310  * @arg group Group identifier
311  *
312  * Joins the specified groups using the modern socket option which
313  * is available since kernel version 2.6.14. It allows joining an
314  * almost arbitary number of groups without limitation. The list
315  * of groups has to be terminated by 0 (%NFNLGRP_NONE).
316  *
317  * Make sure to use the correct group definitions as the older
318  * bitmask definitions for nl_join_groups() are likely to still
319  * be present for backward compatibility reasons.
320  *
321  * @return 0 on sucess or a negative error code.
322  */
323 int nl_socket_add_memberships(struct nl_sock *sk, int group, ...)
324 {
325  int err;
326  va_list ap;
327 
328  if (sk->s_fd == -1)
329  return -NLE_BAD_SOCK;
330 
331  va_start(ap, group);
332 
333  while (group != 0) {
334  if (group < 0) {
335  va_end(ap);
336  return -NLE_INVAL;
337  }
338 
339  err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
340  &group, sizeof(group));
341  if (err < 0) {
342  va_end(ap);
343  return -nl_syserr2nlerr(errno);
344  }
345 
346  group = va_arg(ap, int);
347  }
348 
349  va_end(ap);
350 
351  return 0;
352 }
353 
354 int nl_socket_add_membership(struct nl_sock *sk, int group)
355 {
356  return nl_socket_add_memberships(sk, group, 0);
357 }
358 
359 /**
360  * Leave groups
361  * @arg sk Netlink socket
362  * @arg group Group identifier
363  *
364  * Leaves the specified groups using the modern socket option
365  * which is available since kernel version 2.6.14. The list of groups
366  * has to terminated by 0 (%NFNLGRP_NONE).
367  *
368  * @see nl_socket_add_membership
369  * @return 0 on success or a negative error code.
370  */
371 int nl_socket_drop_memberships(struct nl_sock *sk, int group, ...)
372 {
373  int err;
374  va_list ap;
375 
376  if (sk->s_fd == -1)
377  return -NLE_BAD_SOCK;
378 
379  va_start(ap, group);
380 
381  while (group != 0) {
382  if (group < 0) {
383  va_end(ap);
384  return -NLE_INVAL;
385  }
386 
387  err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP,
388  &group, sizeof(group));
389  if (err < 0) {
390  va_end(ap);
391  return -nl_syserr2nlerr(errno);
392  }
393 
394  group = va_arg(ap, int);
395  }
396 
397  va_end(ap);
398 
399  return 0;
400 }
401 
402 int nl_socket_drop_membership(struct nl_sock *sk, int group)
403 {
404  return nl_socket_drop_memberships(sk, group, 0);
405 }
406 
407 
408 /**
409  * Join multicast groups (deprecated)
410  * @arg sk Netlink socket.
411  * @arg groups Bitmask of groups to join.
412  *
413  * This function defines the old way of joining multicast group which
414  * has to be done prior to calling nl_connect(). It works on any kernel
415  * version but is very limited as only 32 groups can be joined.
416  */
417 void nl_join_groups(struct nl_sock *sk, int groups)
418 {
419  sk->s_local.nl_groups |= groups;
420 }
421 
422 
423 /** @} */
424 
425 /**
426  * @name Peer Identfication
427  * @{
428  */
429 
430 uint32_t nl_socket_get_peer_port(const struct nl_sock *sk)
431 {
432  return sk->s_peer.nl_pid;
433 }
434 
435 void nl_socket_set_peer_port(struct nl_sock *sk, uint32_t port)
436 {
437  sk->s_peer.nl_pid = port;
438 }
439 
440 uint32_t nl_socket_get_peer_groups(const struct nl_sock *sk)
441 {
442  return sk->s_peer.nl_groups;
443 }
444 
445 void nl_socket_set_peer_groups(struct nl_sock *sk, uint32_t groups)
446 {
447  sk->s_peer.nl_groups = groups;
448 }
449 
450 
451 
452 /** @} */
453 
454 /**
455  * @name File Descriptor
456  * @{
457  */
458 
459 /**
460  * Return the file descriptor of the backing socket
461  * @arg sk Netlink socket
462  *
463  * Only valid after calling nl_connect() to create and bind the respective
464  * socket.
465  *
466  * @return File descriptor or -1 if not available.
467  */
468 int nl_socket_get_fd(const struct nl_sock *sk)
469 {
470  return sk->s_fd;
471 }
472 
473 /**
474  * Set file descriptor of socket to non-blocking state
475  * @arg sk Netlink socket.
476  *
477  * @return 0 on success or a negative error code.
478  */
479 int nl_socket_set_nonblocking(const struct nl_sock *sk)
480 {
481  if (sk->s_fd == -1)
482  return -NLE_BAD_SOCK;
483 
484  if (fcntl(sk->s_fd, F_SETFL, O_NONBLOCK) < 0)
485  return -nl_syserr2nlerr(errno);
486 
487  return 0;
488 }
489 
490 /**
491  * Enable use of MSG_PEEK when reading from socket
492  * @arg sk Netlink socket.
493  */
494 void nl_socket_enable_msg_peek(struct nl_sock *sk)
495 {
496  sk->s_flags |= NL_MSG_PEEK;
497 }
498 
499 /**
500  * Disable use of MSG_PEEK when reading from socket
501  * @arg sk Netlink socket.
502  */
503 void nl_socket_disable_msg_peek(struct nl_sock *sk)
504 {
505  sk->s_flags &= ~NL_MSG_PEEK;
506 }
507 
508 /** @} */
509 
510 /**
511  * @name Callback Handler
512  * @{
513  */
514 
515 struct nl_cb *nl_socket_get_cb(const struct nl_sock *sk)
516 {
517  return nl_cb_get(sk->s_cb);
518 }
519 
520 void nl_socket_set_cb(struct nl_sock *sk, struct nl_cb *cb)
521 {
522  nl_cb_put(sk->s_cb);
523  sk->s_cb = nl_cb_get(cb);
524 }
525 
526 /**
527  * Modify the callback handler associated with the socket
528  * @arg sk Netlink socket.
529  * @arg type which type callback to set
530  * @arg kind kind of callback
531  * @arg func callback function
532  * @arg arg argument to be passed to callback function
533  *
534  * @see nl_cb_set
535  */
536 int nl_socket_modify_cb(struct nl_sock *sk, enum nl_cb_type type,
537  enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func,
538  void *arg)
539 {
540  return nl_cb_set(sk->s_cb, type, kind, func, arg);
541 }
542 
543 /**
544  * Modify the error callback handler associated with the socket
545  * @arg sk Netlink socket.
546  * @arg kind kind of callback
547  * @arg func callback function
548  * @arg arg argument to be passed to callback function
549  *
550  * @see nl_cb_err
551  */
552 int nl_socket_modify_err_cb(struct nl_sock *sk, enum nl_cb_kind kind,
553  nl_recvmsg_err_cb_t func, void *arg)
554 {
555  return nl_cb_err(sk->s_cb, kind, func, arg);
556 }
557 
558 /** @} */
559 
560 /**
561  * @name Utilities
562  * @{
563  */
564 
565 /**
566  * Set socket buffer size of netlink socket.
567  * @arg sk Netlink socket.
568  * @arg rxbuf New receive socket buffer size in bytes.
569  * @arg txbuf New transmit socket buffer size in bytes.
570  *
571  * Sets the socket buffer size of a netlink socket to the specified
572  * values \c rxbuf and \c txbuf. Providing a value of \c 0 assumes a
573  * good default value.
574  *
575  * @note It is not required to call this function prior to nl_connect().
576  * @return 0 on sucess or a negative error code.
577  */
578 int nl_socket_set_buffer_size(struct nl_sock *sk, int rxbuf, int txbuf)
579 {
580  int err;
581 
582  if (rxbuf <= 0)
583  rxbuf = 32768;
584 
585  if (txbuf <= 0)
586  txbuf = 32768;
587 
588  if (sk->s_fd == -1)
589  return -NLE_BAD_SOCK;
590 
591  err = setsockopt(sk->s_fd, SOL_SOCKET, SO_SNDBUF,
592  &txbuf, sizeof(txbuf));
593  if (err < 0)
594  return -nl_syserr2nlerr(errno);
595 
596  err = setsockopt(sk->s_fd, SOL_SOCKET, SO_RCVBUF,
597  &rxbuf, sizeof(rxbuf));
598  if (err < 0)
599  return -nl_syserr2nlerr(errno);
600 
601  sk->s_flags |= NL_SOCK_BUFSIZE_SET;
602 
603  return 0;
604 }
605 
606 /**
607  * Set default message buffer size of netlink socket.
608  * @arg sk Netlink socket.
609  * @arg bufsize Default message buffer size in bytes.
610  *
611  * Sets the default message buffer size to the specified length in bytes.
612  * The default message buffer size limits the maximum message size the
613  * socket will be able to receive. It is generally recommneded to specify
614  * a buffer size no less than the size of a memory page.
615  *
616  * @return 0 on success or a negative error code.
617  */
618 int nl_socket_set_msg_buf_size(struct nl_sock *sk, size_t bufsize)
619 {
620  sk->s_bufsize = bufsize;
621 
622  return 0;
623 }
624 
625 /**
626  * Get default message buffer size of netlink socket.
627  * @arg sk Netlink socket.
628  *
629  * @return Size of default message buffer.
630  */
631 size_t nl_socket_get_msg_buf_size(struct nl_sock *sk)
632 {
633  return sk->s_bufsize;
634 }
635 
636 /**
637  * Enable/disable credential passing on netlink socket.
638  * @arg sk Netlink socket.
639  * @arg state New state (0 - disabled, 1 - enabled)
640  *
641  * @return 0 on success or a negative error code
642  */
643 int nl_socket_set_passcred(struct nl_sock *sk, int state)
644 {
645  int err;
646 
647  if (sk->s_fd == -1)
648  return -NLE_BAD_SOCK;
649 
650  err = setsockopt(sk->s_fd, SOL_SOCKET, SO_PASSCRED,
651  &state, sizeof(state));
652  if (err < 0)
653  return -nl_syserr2nlerr(errno);
654 
655  if (state)
656  sk->s_flags |= NL_SOCK_PASSCRED;
657  else
658  sk->s_flags &= ~NL_SOCK_PASSCRED;
659 
660  return 0;
661 }
662 
663 /**
664  * Enable/disable receival of additional packet information
665  * @arg sk Netlink socket.
666  * @arg state New state (0 - disabled, 1 - enabled)
667  *
668  * @return 0 on success or a negative error code
669  */
670 int nl_socket_recv_pktinfo(struct nl_sock *sk, int state)
671 {
672  int err;
673 
674  if (sk->s_fd == -1)
675  return -NLE_BAD_SOCK;
676 
677  err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_PKTINFO,
678  &state, sizeof(state));
679  if (err < 0)
680  return -nl_syserr2nlerr(errno);
681 
682  return 0;
683 }
684 
685 /** @} */
686 
687 /** @} */