2 * lib/socket.c Netlink Socket
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
9 * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
14 * @defgroup socket Socket
18 #include <netlink-local.h>
19 #include <netlink/netlink.h>
20 #include <netlink/utils.h>
21 #include <netlink/handlers.h>
22 #include <netlink/msg.h>
23 #include <netlink/attr.h>
25 static int default_cb = NL_CB_DEFAULT;
27 static void __init init_default_cb(void)
31 if ((nlcb = getenv("NLCB"))) {
32 if (!strcasecmp(nlcb, "default"))
33 default_cb = NL_CB_DEFAULT;
34 else if (!strcasecmp(nlcb, "verbose"))
35 default_cb = NL_CB_VERBOSE;
36 else if (!strcasecmp(nlcb, "debug"))
37 default_cb = NL_CB_DEBUG;
39 fprintf(stderr, "Unknown value for NLCB, valid values: "
40 "{default | verbose | debug}\n");
45 static uint32_t used_ports_map[32];
47 static uint32_t generate_local_port(void)
50 uint32_t pid = getpid() & 0x3FFFFF;
52 for (i = 0; i < 32; i++) {
53 if (used_ports_map[i] == 0xFFFFFFFF)
56 for (n = 0; n < 32; n++) {
57 if (1UL & (used_ports_map[i] >> n))
60 used_ports_map[i] |= (1UL << n);
63 /* PID_MAX_LIMIT is currently at 2^22, leaving 10 bit
64 * to, i.e. 1024 unique ports per application. */
65 return pid + (n << 22);
70 /* Out of sockets in our own PID namespace, what to do? FIXME */
74 static void release_local_port(uint32_t port)
82 used_ports_map[nr / 32] &= ~(1 << nr % 32);
90 static struct nl_sock *__alloc_socket(struct nl_cb *cb)
94 sk = calloc(1, sizeof(*sk));
100 sk->s_local.nl_family = AF_NETLINK;
101 sk->s_peer.nl_family = AF_NETLINK;
102 sk->s_seq_expect = sk->s_seq_next = time(0);
103 sk->s_local.nl_pid = generate_local_port();
104 if (sk->s_local.nl_pid == UINT_MAX) {
113 * Allocate new netlink socket
115 * @return Newly allocated netlink socket or NULL.
117 struct nl_sock *nl_socket_alloc(void)
121 cb = nl_cb_alloc(default_cb);
125 return __alloc_socket(cb);
129 * Allocate new socket with custom callbacks
130 * @arg cb Callback handler
132 * The reference to the callback handler is taken into account
133 * automatically, it is released again upon calling nl_socket_free().
135 *@return Newly allocted socket handle or NULL.
137 struct nl_sock *nl_socket_alloc_cb(struct nl_cb *cb)
142 return __alloc_socket(nl_cb_get(cb));
146 * Free a netlink socket.
147 * @arg sk Netlink socket.
149 void nl_socket_free(struct nl_sock *sk)
157 if (!(sk->s_flags & NL_OWN_PORT))
158 release_local_port(sk->s_local.nl_pid);
167 * @name Sequence Numbers
171 static int noop_seq_check(struct nl_msg *msg, void *arg)
178 * Disable sequence number checking.
179 * @arg sk Netlink socket.
181 * Disables checking of sequence numbers on the netlink socket This is
182 * required to allow messages to be processed which were not requested by
183 * a preceding request message, e.g. netlink events.
185 * @note This function modifies the NL_CB_SEQ_CHECK configuration in
186 * the callback handle associated with the socket.
188 void nl_socket_disable_seq_check(struct nl_sock *sk)
190 nl_cb_set(sk->s_cb, NL_CB_SEQ_CHECK,
191 NL_CB_CUSTOM, noop_seq_check, NULL);
195 * Use next sequence number
196 * @arg sk Netlink socket.
198 * Uses the next available sequence number and increases the counter
199 * by one for subsequent calls.
201 * @return Unique serial sequence number
203 unsigned int nl_socket_use_seq(struct nl_sock *sk)
205 return sk->s_seq_next++;
209 * Disable automatic request for ACK
210 * @arg sk Netlink socket.
212 * The default behaviour of a socket is to request an ACK for
213 * each message sent to allow for the caller to synchronize to
214 * the completion of the netlink operation. This function
215 * disables this behaviour and will result in requests being
216 * sent which will not have the NLM_F_ACK flag set automatically.
217 * However, it is still possible for the caller to set the
218 * NLM_F_ACK flag explicitely.
220 void nl_socket_disable_auto_ack(struct nl_sock *sk)
222 sk->s_flags |= NL_NO_AUTO_ACK;
226 * Enable automatic request for ACK (default)
227 * @arg sk Netlink socket.
228 * @see nl_socket_disable_auto_ack
230 void nl_socket_enable_auto_ack(struct nl_sock *sk)
232 sk->s_flags &= ~NL_NO_AUTO_ACK;
238 * @name Source Idenficiation
242 uint32_t nl_socket_get_local_port(struct nl_sock *sk)
244 return sk->s_local.nl_pid;
248 * Set local port of socket
249 * @arg sk Netlink socket.
250 * @arg port Local port identifier
252 * Assigns a local port identifier to the socket. If port is 0
253 * a unique port identifier will be generated automatically.
255 void nl_socket_set_local_port(struct nl_sock *sk, uint32_t port)
258 port = generate_local_port();
259 sk->s_flags &= ~NL_OWN_PORT;
261 if (!(sk->s_flags & NL_OWN_PORT))
262 release_local_port(sk->s_local.nl_pid);
263 sk->s_flags |= NL_OWN_PORT;
266 sk->s_local.nl_pid = port;
272 * @name Group Subscriptions
278 * @arg sk Netlink socket
279 * @arg group Group identifier
281 * Joins the specified groups using the modern socket option which
282 * is available since kernel version 2.6.14. It allows joining an
283 * almost arbitary number of groups without limitation. The list
284 * of groups has to be terminated by 0 (%NFNLGRP_NONE).
286 * Make sure to use the correct group definitions as the older
287 * bitmask definitions for nl_join_groups() are likely to still
288 * be present for backward compatibility reasons.
290 * @return 0 on sucess or a negative error code.
292 int nl_socket_add_memberships(struct nl_sock *sk, int group, ...)
298 return -NLE_BAD_SOCK;
306 err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
307 &group, sizeof(group));
309 return -nl_syserr2nlerr(errno);
311 group = va_arg(ap, int);
319 int nl_socket_add_membership(struct nl_sock *sk, int group)
321 return nl_socket_add_memberships(sk, group, 0);
326 * @arg sk Netlink socket
327 * @arg group Group identifier
329 * Leaves the specified groups using the modern socket option
330 * which is available since kernel version 2.6.14. The list of groups
331 * has to terminated by 0 (%NFNLGRP_NONE).
333 * @see nl_socket_add_membership
334 * @return 0 on success or a negative error code.
336 int nl_socket_drop_memberships(struct nl_sock *sk, int group, ...)
342 return -NLE_BAD_SOCK;
350 err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP,
351 &group, sizeof(group));
353 return -nl_syserr2nlerr(errno);
355 group = va_arg(ap, int);
363 int nl_socket_drop_membership(struct nl_sock *sk, int group)
365 return nl_socket_drop_memberships(sk, group, 0);
370 * Join multicast groups (deprecated)
371 * @arg sk Netlink socket.
372 * @arg groups Bitmask of groups to join.
374 * This function defines the old way of joining multicast group which
375 * has to be done prior to calling nl_connect(). It works on any kernel
376 * version but is very limited as only 32 groups can be joined.
378 void nl_join_groups(struct nl_sock *sk, int groups)
380 sk->s_local.nl_groups |= groups;
387 * @name Peer Identfication
391 uint32_t nl_socket_get_peer_port(struct nl_sock *sk)
393 return sk->s_peer.nl_pid;
396 void nl_socket_set_peer_port(struct nl_sock *sk, uint32_t port)
398 sk->s_peer.nl_pid = port;
401 uint32_t nl_socket_get_peer_groups(struct nl_sock *sk)
403 return sk->s_peer.nl_groups;
406 void nl_socket_set_peer_groups(struct nl_sock *sk, uint32_t groups)
408 sk->s_peer.nl_groups = groups;
416 * @name File Descriptor
420 int nl_socket_get_fd(struct nl_sock *sk)
426 * Set file descriptor of socket to non-blocking state
427 * @arg sk Netlink socket.
429 * @return 0 on success or a negative error code.
431 int nl_socket_set_nonblocking(struct nl_sock *sk)
434 return -NLE_BAD_SOCK;
436 if (fcntl(sk->s_fd, F_SETFL, O_NONBLOCK) < 0)
437 return -nl_syserr2nlerr(errno);
443 * Enable use of MSG_PEEK when reading from socket
444 * @arg sk Netlink socket.
446 void nl_socket_enable_msg_peek(struct nl_sock *sk)
448 sk->s_flags |= NL_MSG_PEEK;
452 * Disable use of MSG_PEEK when reading from socket
453 * @arg sk Netlink socket.
455 void nl_socket_disable_msg_peek(struct nl_sock *sk)
457 sk->s_flags &= ~NL_MSG_PEEK;
463 * @name Callback Handler
467 struct nl_cb *nl_socket_get_cb(struct nl_sock *sk)
469 return nl_cb_get(sk->s_cb);
472 void nl_socket_set_cb(struct nl_sock *sk, struct nl_cb *cb)
475 sk->s_cb = nl_cb_get(cb);
479 * Modify the callback handler associated to the socket
480 * @arg sk Netlink socket.
481 * @arg type which type callback to set
482 * @arg kind kind of callback
483 * @arg func callback function
484 * @arg arg argument to be passwd to callback function
488 int nl_socket_modify_cb(struct nl_sock *sk, enum nl_cb_type type,
489 enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func,
492 return nl_cb_set(sk->s_cb, type, kind, func, arg);
503 * Set socket buffer size of netlink socket.
504 * @arg sk Netlink socket.
505 * @arg rxbuf New receive socket buffer size in bytes.
506 * @arg txbuf New transmit socket buffer size in bytes.
508 * Sets the socket buffer size of a netlink socket to the specified
509 * values \c rxbuf and \c txbuf. Providing a value of \c 0 assumes a
510 * good default value.
512 * @note It is not required to call this function prior to nl_connect().
513 * @return 0 on sucess or a negative error code.
515 int nl_socket_set_buffer_size(struct nl_sock *sk, int rxbuf, int txbuf)
526 return -NLE_BAD_SOCK;
528 err = setsockopt(sk->s_fd, SOL_SOCKET, SO_SNDBUF,
529 &txbuf, sizeof(txbuf));
531 return -nl_syserr2nlerr(errno);
533 err = setsockopt(sk->s_fd, SOL_SOCKET, SO_RCVBUF,
534 &rxbuf, sizeof(rxbuf));
536 return -nl_syserr2nlerr(errno);
538 sk->s_flags |= NL_SOCK_BUFSIZE_SET;
544 * Enable/disable credential passing on netlink socket.
545 * @arg sk Netlink socket.
546 * @arg state New state (0 - disabled, 1 - enabled)
548 * @return 0 on success or a negative error code
550 int nl_socket_set_passcred(struct nl_sock *sk, int state)
555 return -NLE_BAD_SOCK;
557 err = setsockopt(sk->s_fd, SOL_SOCKET, SO_PASSCRED,
558 &state, sizeof(state));
560 return -nl_syserr2nlerr(errno);
563 sk->s_flags |= NL_SOCK_PASSCRED;
565 sk->s_flags &= ~NL_SOCK_PASSCRED;
571 * Enable/disable receival of additional packet information
572 * @arg sk Netlink socket.
573 * @arg state New state (0 - disabled, 1 - enabled)
575 * @return 0 on success or a negative error code
577 int nl_socket_recv_pktinfo(struct nl_sock *sk, int state)
582 return -NLE_BAD_SOCK;
584 err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_PKTINFO,
585 &state, sizeof(state));
587 return -nl_syserr2nlerr(errno);