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