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(const 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(const 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(const 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(const 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(const 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(const 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);