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 uint32_t used_ports_map
[32];
27 static uint32_t generate_local_port(void)
30 uint32_t pid
= getpid() & 0x3FFFFF;
32 for (i
= 0; i
< 32; i
++) {
33 if (used_ports_map
[i
] == 0xFFFFFFFF)
36 for (n
= 0; n
< 32; n
++) {
37 if (1UL & (used_ports_map
[i
] >> n
))
40 used_ports_map
[i
] |= (1UL << n
);
43 /* PID_MAX_LIMIT is currently at 2^22, leaving 10 bit
44 * to, i.e. 1024 unique ports per application. */
45 return pid
+ (n
<< 22);
50 /* Out of sockets in our own PID namespace, what to do? FIXME */
54 static void release_local_port(uint32_t port
)
62 used_ports_map
[nr
/ 32] &= ~(1 << nr
% 32);
70 static struct nl_sock
*__alloc_socket(struct nl_cb
*cb
)
74 sk
= calloc(1, sizeof(*sk
));
80 sk
->s_local
.nl_family
= AF_NETLINK
;
81 sk
->s_peer
.nl_family
= AF_NETLINK
;
82 sk
->s_seq_expect
= sk
->s_seq_next
= time(0);
83 sk
->s_local
.nl_pid
= generate_local_port();
84 if (sk
->s_local
.nl_pid
== UINT_MAX
) {
93 * Allocate new netlink socket
95 * @return Newly allocated netlink socket or NULL.
97 struct nl_sock
*nl_socket_alloc(void)
101 cb
= nl_cb_alloc(NL_CB_DEFAULT
);
105 return __alloc_socket(cb
);
109 * Allocate new socket with custom callbacks
110 * @arg cb Callback handler
112 * The reference to the callback handler is taken into account
113 * automatically, it is released again upon calling nl_socket_free().
115 *@return Newly allocted socket handle or NULL.
117 struct nl_sock
*nl_socket_alloc_cb(struct nl_cb
*cb
)
122 return __alloc_socket(nl_cb_get(cb
));
126 * Free a netlink socket.
127 * @arg sk Netlink socket.
129 void nl_socket_free(struct nl_sock
*sk
)
137 if (!(sk
->s_flags
& NL_OWN_PORT
))
138 release_local_port(sk
->s_local
.nl_pid
);
147 * @name Sequence Numbers
151 static int noop_seq_check(struct nl_msg
*msg
, void *arg
)
158 * Disable sequence number checking.
159 * @arg sk Netlink socket.
161 * Disables checking of sequence numbers on the netlink socket This is
162 * required to allow messages to be processed which were not requested by
163 * a preceding request message, e.g. netlink events.
165 * @note This function modifies the NL_CB_SEQ_CHECK configuration in
166 * the callback handle associated with the socket.
168 void nl_socket_disable_seq_check(struct nl_sock
*sk
)
170 nl_cb_set(sk
->s_cb
, NL_CB_SEQ_CHECK
,
171 NL_CB_CUSTOM
, noop_seq_check
, NULL
);
177 * Set local port of socket
178 * @arg sk Netlink socket.
179 * @arg port Local port identifier
181 * Assigns a local port identifier to the socket. If port is 0
182 * a unique port identifier will be generated automatically.
184 void nl_socket_set_local_port(struct nl_sock
*sk
, uint32_t port
)
187 port
= generate_local_port();
188 sk
->s_flags
&= ~NL_OWN_PORT
;
190 if (!(sk
->s_flags
& NL_OWN_PORT
))
191 release_local_port(sk
->s_local
.nl_pid
);
192 sk
->s_flags
|= NL_OWN_PORT
;
195 sk
->s_local
.nl_pid
= port
;
201 * @name Group Subscriptions
207 * @arg sk Netlink socket
208 * @arg group Group identifier
210 * Joins the specified groups using the modern socket option which
211 * is available since kernel version 2.6.14. It allows joining an
212 * almost arbitary number of groups without limitation. The list
213 * of groups has to be terminated by 0 (%NFNLGRP_NONE).
215 * Make sure to use the correct group definitions as the older
216 * bitmask definitions for nl_join_groups() are likely to still
217 * be present for backward compatibility reasons.
219 * @return 0 on sucess or a negative error code.
221 int nl_socket_add_memberships(struct nl_sock
*sk
, int group
, ...)
227 return -NLE_BAD_SOCK
;
235 err
= setsockopt(sk
->s_fd
, SOL_NETLINK
, NETLINK_ADD_MEMBERSHIP
,
236 &group
, sizeof(group
));
238 return -nl_syserr2nlerr(errno
);
240 group
= va_arg(ap
, int);
250 * @arg sk Netlink socket
251 * @arg group Group identifier
253 * Leaves the specified groups using the modern socket option
254 * which is available since kernel version 2.6.14. The list of groups
255 * has to terminated by 0 (%NFNLGRP_NONE).
257 * @see nl_socket_add_membership
258 * @return 0 on success or a negative error code.
260 int nl_socket_drop_memberships(struct nl_sock
*sk
, int group
, ...)
266 return -NLE_BAD_SOCK
;
274 err
= setsockopt(sk
->s_fd
, SOL_NETLINK
, NETLINK_DROP_MEMBERSHIP
,
275 &group
, sizeof(group
));
277 return -nl_syserr2nlerr(errno
);
279 group
= va_arg(ap
, int);
291 * Set file descriptor of socket to non-blocking state
292 * @arg sk Netlink socket.
294 * @return 0 on success or a negative error code.
296 int nl_socket_set_nonblocking(struct nl_sock
*sk
)
299 return -NLE_BAD_SOCK
;
301 if (fcntl(sk
->s_fd
, F_SETFL
, O_NONBLOCK
) < 0)
302 return -nl_syserr2nlerr(errno
);
315 * Set socket buffer size of netlink socket.
316 * @arg sk Netlink socket.
317 * @arg rxbuf New receive socket buffer size in bytes.
318 * @arg txbuf New transmit socket buffer size in bytes.
320 * Sets the socket buffer size of a netlink socket to the specified
321 * values \c rxbuf and \c txbuf. Providing a value of \c 0 assumes a
322 * good default value.
324 * @note It is not required to call this function prior to nl_connect().
325 * @return 0 on sucess or a negative error code.
327 int nl_socket_set_buffer_size(struct nl_sock
*sk
, int rxbuf
, int txbuf
)
338 return -NLE_BAD_SOCK
;
340 err
= setsockopt(sk
->s_fd
, SOL_SOCKET
, SO_SNDBUF
,
341 &txbuf
, sizeof(txbuf
));
343 return -nl_syserr2nlerr(errno
);
345 err
= setsockopt(sk
->s_fd
, SOL_SOCKET
, SO_RCVBUF
,
346 &rxbuf
, sizeof(rxbuf
));
348 return -nl_syserr2nlerr(errno
);
350 sk
->s_flags
|= NL_SOCK_BUFSIZE_SET
;
356 * Enable/disable credential passing on netlink socket.
357 * @arg sk Netlink socket.
358 * @arg state New state (0 - disabled, 1 - enabled)
360 * @return 0 on success or a negative error code
362 int nl_socket_set_passcred(struct nl_sock
*sk
, int state
)
367 return -NLE_BAD_SOCK
;
369 err
= setsockopt(sk
->s_fd
, SOL_SOCKET
, SO_PASSCRED
,
370 &state
, sizeof(state
));
372 return -nl_syserr2nlerr(errno
);
375 sk
->s_flags
|= NL_SOCK_PASSCRED
;
377 sk
->s_flags
&= ~NL_SOCK_PASSCRED
;
383 * Enable/disable receival of additional packet information
384 * @arg sk Netlink socket.
385 * @arg state New state (0 - disabled, 1 - enabled)
387 * @return 0 on success or a negative error code
389 int nl_socket_recv_pktinfo(struct nl_sock
*sk
, int state
)
394 return -NLE_BAD_SOCK
;
396 err
= setsockopt(sk
->s_fd
, SOL_NETLINK
, NETLINK_PKTINFO
,
397 &state
, sizeof(state
));
399 return -nl_syserr2nlerr(errno
);
This page took 0.072331 seconds and 5 git commands to generate.