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