• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-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 
init_default_cb(void)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 
generate_local_port(void)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 
release_local_port(uint32_t port)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 */
_nl_socket_used_ports_release_all(const uint32_t * used_ports)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 
_nl_socket_used_ports_set(uint32_t * used_ports,uint32_t port)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 
__alloc_socket(struct nl_cb * cb)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  */
nl_socket_alloc(void)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  */
nl_socket_alloc_cb(struct nl_cb * cb)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  */
nl_socket_free(struct nl_sock * sk)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 
noop_seq_check(struct nl_msg * msg,void * arg)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  */
nl_socket_disable_seq_check(struct nl_sock * sk)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  */
nl_socket_use_seq(struct nl_sock * sk)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  */
nl_socket_disable_auto_ack(struct nl_sock * sk)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  */
nl_socket_enable_auto_ack(struct nl_sock * sk)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 */
_nl_socket_is_local_port_unspecified(struct nl_sock * sk)333 int _nl_socket_is_local_port_unspecified(struct nl_sock *sk)
334 {
335 	return (sk->s_local.nl_pid == 0);
336 }
337 
_nl_socket_generate_local_port_no_release(struct nl_sock * sk)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 
nl_socket_get_local_port(const struct nl_sock * sk)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  */
nl_socket_set_local_port(struct nl_sock * sk,uint32_t port)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  */
nl_socket_add_memberships(struct nl_sock * sk,int group,...)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 
nl_socket_add_membership(struct nl_sock * sk,int group)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  */
nl_socket_drop_memberships(struct nl_sock * sk,int group,...)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 
nl_socket_drop_membership(struct nl_sock * sk,int group)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  */
nl_join_groups(struct nl_sock * sk,int groups)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 
nl_socket_get_peer_port(const struct nl_sock * sk)524 uint32_t nl_socket_get_peer_port(const struct nl_sock *sk)
525 {
526 	return sk->s_peer.nl_pid;
527 }
528 
nl_socket_set_peer_port(struct nl_sock * sk,uint32_t port)529 void nl_socket_set_peer_port(struct nl_sock *sk, uint32_t port)
530 {
531 	sk->s_peer.nl_pid = port;
532 }
533 
nl_socket_get_peer_groups(const struct nl_sock * sk)534 uint32_t nl_socket_get_peer_groups(const struct nl_sock *sk)
535 {
536 	return sk->s_peer.nl_groups;
537 }
538 
nl_socket_set_peer_groups(struct nl_sock * sk,uint32_t groups)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  */
nl_socket_get_fd(const struct nl_sock * sk)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  */
nl_socket_set_nonblocking(const struct nl_sock * sk)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  */
nl_socket_enable_msg_peek(struct nl_sock * sk)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  */
nl_socket_disable_msg_peek(struct nl_sock * sk)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 
nl_socket_get_cb(const struct nl_sock * sk)609 struct nl_cb *nl_socket_get_cb(const struct nl_sock *sk)
610 {
611 	return nl_cb_get(sk->s_cb);
612 }
613 
nl_socket_set_cb(struct nl_sock * sk,struct nl_cb * cb)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  */
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)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  */
nl_socket_modify_err_cb(struct nl_sock * sk,enum nl_cb_kind kind,nl_recvmsg_err_cb_t func,void * arg)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  */
nl_socket_set_buffer_size(struct nl_sock * sk,int rxbuf,int txbuf)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  */
nl_socket_set_msg_buf_size(struct nl_sock * sk,size_t bufsize)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  */
nl_socket_get_msg_buf_size(struct nl_sock * sk)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  */
nl_socket_set_passcred(struct nl_sock * sk,int state)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  */
nl_socket_recv_pktinfo(struct nl_sock * sk,int state)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