xref: /aosp_15_r20/external/ethtool/libmnl/src/socket.c (revision 1b481fc3bb1b45d4cf28d1ec12969dc1055f555d)
1*1b481fc3SMaciej Żenczykowski /*
2*1b481fc3SMaciej Żenczykowski  * (C) 2008-2010 by Pablo Neira Ayuso <[email protected]>
3*1b481fc3SMaciej Żenczykowski  *
4*1b481fc3SMaciej Żenczykowski  * This program is free software; you can redistribute it and/or modify
5*1b481fc3SMaciej Żenczykowski  * it under the terms of the GNU Lesser General Public License as published
6*1b481fc3SMaciej Żenczykowski  * by the Free Software Foundation; either version 2.1 of the License, or
7*1b481fc3SMaciej Żenczykowski  * (at your option) any later version.
8*1b481fc3SMaciej Żenczykowski  */
9*1b481fc3SMaciej Żenczykowski 
10*1b481fc3SMaciej Żenczykowski #include <libmnl/libmnl.h>
11*1b481fc3SMaciej Żenczykowski #include <sys/types.h>
12*1b481fc3SMaciej Żenczykowski #include <sys/socket.h>
13*1b481fc3SMaciej Żenczykowski #include <stdlib.h>
14*1b481fc3SMaciej Żenczykowski #include <unistd.h>
15*1b481fc3SMaciej Żenczykowski #include <time.h>
16*1b481fc3SMaciej Żenczykowski #include <errno.h>
17*1b481fc3SMaciej Żenczykowski #include "internal.h"
18*1b481fc3SMaciej Żenczykowski 
19*1b481fc3SMaciej Żenczykowski /**
20*1b481fc3SMaciej Żenczykowski  * \mainpage
21*1b481fc3SMaciej Żenczykowski  *
22*1b481fc3SMaciej Żenczykowski  * libmnl is a minimalistic user-space library oriented to Netlink developers.
23*1b481fc3SMaciej Żenczykowski  * There are a lot of common tasks in parsing, validating, constructing of
24*1b481fc3SMaciej Żenczykowski  * both the Netlink header and TLVs that are repetitive and easy to get wrong.
25*1b481fc3SMaciej Żenczykowski  * This library aims to provide simple helpers that allows you to avoid
26*1b481fc3SMaciej Żenczykowski  * re-inventing the wheel in common Netlink tasks.
27*1b481fc3SMaciej Żenczykowski  *
28*1b481fc3SMaciej Żenczykowski  * \verbatim
29*1b481fc3SMaciej Żenczykowski "Simplify, simplify" -- Henry David Thoureau. Walden (1854)
30*1b481fc3SMaciej Żenczykowski \endverbatim
31*1b481fc3SMaciej Żenczykowski  *
32*1b481fc3SMaciej Żenczykowski  * The acronym libmnl stands for LIBrary Minimalistic NetLink.
33*1b481fc3SMaciej Żenczykowski  *
34*1b481fc3SMaciej Żenczykowski  * libmnl homepage is:
35*1b481fc3SMaciej Żenczykowski  *      http://www.netfilter.org/projects/libmnl/
36*1b481fc3SMaciej Żenczykowski  *
37*1b481fc3SMaciej Żenczykowski  * \section features Main Features
38*1b481fc3SMaciej Żenczykowski  * - Small: the shared library requires around 30KB for an x86-based computer.
39*1b481fc3SMaciej Żenczykowski  * - Simple: this library avoids complex abstractions that tend to hide Netlink
40*1b481fc3SMaciej Żenczykowski  *   details. It avoids elaborated object-oriented infrastructure and complex
41*1b481fc3SMaciej Żenczykowski  *   callback-based workflow.
42*1b481fc3SMaciej Żenczykowski  * - Easy to use: the library simplifies the work for Netlink-wise developers.
43*1b481fc3SMaciej Żenczykowski  *   It provides functions to make socket handling, message building,
44*1b481fc3SMaciej Żenczykowski  *   validating, parsing and sequence tracking, easier.
45*1b481fc3SMaciej Żenczykowski  * - Easy to re-use: you can use this library to build your own abstraction
46*1b481fc3SMaciej Żenczykowski  *   layer upon this library, if you want to provide another library that
47*1b481fc3SMaciej Żenczykowski  *   hides Netlink details to your users.
48*1b481fc3SMaciej Żenczykowski  * - Decoupling: the interdependency of the main bricks that compose this
49*1b481fc3SMaciej Żenczykowski  *   library is reduced, i.e. the library provides many helpers, but the
50*1b481fc3SMaciej Żenczykowski  *   programmer is not forced to use them.
51*1b481fc3SMaciej Żenczykowski  *
52*1b481fc3SMaciej Żenczykowski  * \section licensing Licensing terms
53*1b481fc3SMaciej Żenczykowski  * This library is released under the LGPLv2.1 or any later (at your option).
54*1b481fc3SMaciej Żenczykowski  *
55*1b481fc3SMaciej Żenczykowski  * \section Dependencies
56*1b481fc3SMaciej Żenczykowski  * You have to install the Linux kernel headers that you want to use to develop
57*1b481fc3SMaciej Żenczykowski  * your application. Moreover, this library requires that you have some basics
58*1b481fc3SMaciej Żenczykowski  * on Netlink.
59*1b481fc3SMaciej Żenczykowski  *
60*1b481fc3SMaciej Żenczykowski  * \section scm Git Tree
61*1b481fc3SMaciej Żenczykowski  * The current development version of libmnl can be accessed at:
62*1b481fc3SMaciej Żenczykowski  * https://git.netfilter.org/libmnl/
63*1b481fc3SMaciej Żenczykowski  *
64*1b481fc3SMaciej Żenczykowski  * \section using Using libmnl
65*1b481fc3SMaciej Żenczykowski  * You can access several example files under examples/ in the libmnl source
66*1b481fc3SMaciej Żenczykowski  * code tree.
67*1b481fc3SMaciej Żenczykowski  */
68*1b481fc3SMaciej Żenczykowski 
69*1b481fc3SMaciej Żenczykowski struct mnl_socket {
70*1b481fc3SMaciej Żenczykowski 	int 			fd;
71*1b481fc3SMaciej Żenczykowski 	struct sockaddr_nl	addr;
72*1b481fc3SMaciej Żenczykowski };
73*1b481fc3SMaciej Żenczykowski 
74*1b481fc3SMaciej Żenczykowski /**
75*1b481fc3SMaciej Żenczykowski  * \defgroup socket Netlink socket helpers
76*1b481fc3SMaciej Żenczykowski  * @{
77*1b481fc3SMaciej Żenczykowski  */
78*1b481fc3SMaciej Żenczykowski 
79*1b481fc3SMaciej Żenczykowski /**
80*1b481fc3SMaciej Żenczykowski  * mnl_socket_get_fd - obtain file descriptor from netlink socket
81*1b481fc3SMaciej Żenczykowski  * \param nl netlink socket obtained via mnl_socket_open()
82*1b481fc3SMaciej Żenczykowski  *
83*1b481fc3SMaciej Żenczykowski  * This function returns the file descriptor of a given netlink socket.
84*1b481fc3SMaciej Żenczykowski  */
mnl_socket_get_fd(const struct mnl_socket * nl)85*1b481fc3SMaciej Żenczykowski EXPORT_SYMBOL int mnl_socket_get_fd(const struct mnl_socket *nl)
86*1b481fc3SMaciej Żenczykowski {
87*1b481fc3SMaciej Żenczykowski 	return nl->fd;
88*1b481fc3SMaciej Żenczykowski }
89*1b481fc3SMaciej Żenczykowski 
90*1b481fc3SMaciej Żenczykowski /**
91*1b481fc3SMaciej Żenczykowski  * mnl_socket_get_portid - obtain Netlink PortID from netlink socket
92*1b481fc3SMaciej Żenczykowski  * \param nl netlink socket obtained via mnl_socket_open()
93*1b481fc3SMaciej Żenczykowski  *
94*1b481fc3SMaciej Żenczykowski  * This function returns the Netlink PortID of a given netlink socket.
95*1b481fc3SMaciej Żenczykowski  * It's a common mistake to assume that this PortID equals the process ID
96*1b481fc3SMaciej Żenczykowski  * which is not always true. This is the case if you open more than one
97*1b481fc3SMaciej Żenczykowski  * socket that is binded to the same Netlink subsystem from the same process.
98*1b481fc3SMaciej Żenczykowski  */
mnl_socket_get_portid(const struct mnl_socket * nl)99*1b481fc3SMaciej Żenczykowski EXPORT_SYMBOL unsigned int mnl_socket_get_portid(const struct mnl_socket *nl)
100*1b481fc3SMaciej Żenczykowski {
101*1b481fc3SMaciej Żenczykowski 	return nl->addr.nl_pid;
102*1b481fc3SMaciej Żenczykowski }
103*1b481fc3SMaciej Żenczykowski 
__mnl_socket_open(int bus,int flags)104*1b481fc3SMaciej Żenczykowski static struct mnl_socket *__mnl_socket_open(int bus, int flags)
105*1b481fc3SMaciej Żenczykowski {
106*1b481fc3SMaciej Żenczykowski 	struct mnl_socket *nl;
107*1b481fc3SMaciej Żenczykowski 
108*1b481fc3SMaciej Żenczykowski 	nl = calloc(1, sizeof(struct mnl_socket));
109*1b481fc3SMaciej Żenczykowski 	if (nl == NULL)
110*1b481fc3SMaciej Żenczykowski 		return NULL;
111*1b481fc3SMaciej Żenczykowski 
112*1b481fc3SMaciej Żenczykowski 	nl->fd = socket(AF_NETLINK, SOCK_RAW | flags, bus);
113*1b481fc3SMaciej Żenczykowski 	if (nl->fd == -1) {
114*1b481fc3SMaciej Żenczykowski 		free(nl);
115*1b481fc3SMaciej Żenczykowski 		return NULL;
116*1b481fc3SMaciej Żenczykowski 	}
117*1b481fc3SMaciej Żenczykowski 
118*1b481fc3SMaciej Żenczykowski 	return nl;
119*1b481fc3SMaciej Żenczykowski }
120*1b481fc3SMaciej Żenczykowski 
121*1b481fc3SMaciej Żenczykowski /**
122*1b481fc3SMaciej Żenczykowski  * mnl_socket_open - open a netlink socket
123*1b481fc3SMaciej Żenczykowski  * \param bus the netlink socket bus ID (see NETLINK_* constants)
124*1b481fc3SMaciej Żenczykowski  *
125*1b481fc3SMaciej Żenczykowski  * On error, it returns NULL and errno is appropriately set. Otherwise, it
126*1b481fc3SMaciej Żenczykowski  * returns a valid pointer to the mnl_socket structure.
127*1b481fc3SMaciej Żenczykowski  */
mnl_socket_open(int bus)128*1b481fc3SMaciej Żenczykowski EXPORT_SYMBOL struct mnl_socket *mnl_socket_open(int bus)
129*1b481fc3SMaciej Żenczykowski {
130*1b481fc3SMaciej Żenczykowski 	return __mnl_socket_open(bus, 0);
131*1b481fc3SMaciej Żenczykowski }
132*1b481fc3SMaciej Żenczykowski 
133*1b481fc3SMaciej Żenczykowski /**
134*1b481fc3SMaciej Żenczykowski  * mnl_socket_open2 - open a netlink socket with appropriate flags
135*1b481fc3SMaciej Żenczykowski  * \param bus the netlink socket bus ID (see NETLINK_* constants)
136*1b481fc3SMaciej Żenczykowski  * \param flags the netlink socket flags (see SOCK_* constants in socket(2))
137*1b481fc3SMaciej Żenczykowski  *
138*1b481fc3SMaciej Żenczykowski  * This is similar to mnl_socket_open(), but allows one to set flags like
139*1b481fc3SMaciej Żenczykowski  * SOCK_CLOEXEC at socket creation time (useful for multi-threaded programs
140*1b481fc3SMaciej Żenczykowski  * performing exec calls).
141*1b481fc3SMaciej Żenczykowski  *
142*1b481fc3SMaciej Żenczykowski  * On error, it returns NULL and errno is appropriately set. Otherwise, it
143*1b481fc3SMaciej Żenczykowski  * returns a valid pointer to the mnl_socket structure.
144*1b481fc3SMaciej Żenczykowski  */
mnl_socket_open2(int bus,int flags)145*1b481fc3SMaciej Żenczykowski EXPORT_SYMBOL struct mnl_socket *mnl_socket_open2(int bus, int flags)
146*1b481fc3SMaciej Żenczykowski {
147*1b481fc3SMaciej Żenczykowski 	return __mnl_socket_open(bus, flags);
148*1b481fc3SMaciej Żenczykowski }
149*1b481fc3SMaciej Żenczykowski 
150*1b481fc3SMaciej Żenczykowski /**
151*1b481fc3SMaciej Żenczykowski  * mnl_socket_fdopen - associates a mnl_socket object with pre-existing socket.
152*1b481fc3SMaciej Żenczykowski  * \param fd pre-existing socket descriptor.
153*1b481fc3SMaciej Żenczykowski  *
154*1b481fc3SMaciej Żenczykowski  * On error, it returns NULL and errno is appropriately set. Otherwise, it
155*1b481fc3SMaciej Żenczykowski  * returns a valid pointer to the mnl_socket structure. It also sets the portID
156*1b481fc3SMaciej Żenczykowski  * if the socket fd is already bound and it is AF_NETLINK.
157*1b481fc3SMaciej Żenczykowski  *
158*1b481fc3SMaciej Żenczykowski  * Note that mnl_socket_get_portid() returns 0 if this function is used with
159*1b481fc3SMaciej Żenczykowski  * non-netlink socket.
160*1b481fc3SMaciej Żenczykowski  */
mnl_socket_fdopen(int fd)161*1b481fc3SMaciej Żenczykowski EXPORT_SYMBOL struct mnl_socket *mnl_socket_fdopen(int fd)
162*1b481fc3SMaciej Żenczykowski {
163*1b481fc3SMaciej Żenczykowski 	int ret;
164*1b481fc3SMaciej Żenczykowski 	struct mnl_socket *nl;
165*1b481fc3SMaciej Żenczykowski 	struct sockaddr_nl addr;
166*1b481fc3SMaciej Żenczykowski 	socklen_t addr_len = sizeof(struct sockaddr_nl);
167*1b481fc3SMaciej Żenczykowski 
168*1b481fc3SMaciej Żenczykowski 	ret = getsockname(fd, (struct sockaddr *) &addr, &addr_len);
169*1b481fc3SMaciej Żenczykowski 	if (ret == -1)
170*1b481fc3SMaciej Żenczykowski 		return NULL;
171*1b481fc3SMaciej Żenczykowski 
172*1b481fc3SMaciej Żenczykowski 	nl = calloc(1, sizeof(struct mnl_socket));
173*1b481fc3SMaciej Żenczykowski 	if (nl == NULL)
174*1b481fc3SMaciej Żenczykowski 		return NULL;
175*1b481fc3SMaciej Żenczykowski 
176*1b481fc3SMaciej Żenczykowski 	nl->fd = fd;
177*1b481fc3SMaciej Żenczykowski 	if (addr.nl_family == AF_NETLINK)
178*1b481fc3SMaciej Żenczykowski 		nl->addr = addr;
179*1b481fc3SMaciej Żenczykowski 
180*1b481fc3SMaciej Żenczykowski 	return nl;
181*1b481fc3SMaciej Żenczykowski }
182*1b481fc3SMaciej Żenczykowski 
183*1b481fc3SMaciej Żenczykowski /**
184*1b481fc3SMaciej Żenczykowski  * mnl_socket_bind - bind netlink socket
185*1b481fc3SMaciej Żenczykowski  * \param nl netlink socket obtained via mnl_socket_open()
186*1b481fc3SMaciej Żenczykowski  * \param groups the group of message you're interested in
187*1b481fc3SMaciej Żenczykowski  * \param pid the port ID you want to use (use zero for automatic selection)
188*1b481fc3SMaciej Żenczykowski  *
189*1b481fc3SMaciej Żenczykowski  * On error, this function returns -1 and errno is appropriately set. On
190*1b481fc3SMaciej Żenczykowski  * success, 0 is returned. You can use MNL_SOCKET_AUTOPID which is 0 for
191*1b481fc3SMaciej Żenczykowski  * automatic port ID selection.
192*1b481fc3SMaciej Żenczykowski  */
mnl_socket_bind(struct mnl_socket * nl,unsigned int groups,pid_t pid)193*1b481fc3SMaciej Żenczykowski EXPORT_SYMBOL int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups,
194*1b481fc3SMaciej Żenczykowski 				  pid_t pid)
195*1b481fc3SMaciej Żenczykowski {
196*1b481fc3SMaciej Żenczykowski 	int ret;
197*1b481fc3SMaciej Żenczykowski 	socklen_t addr_len;
198*1b481fc3SMaciej Żenczykowski 
199*1b481fc3SMaciej Żenczykowski 	nl->addr.nl_family = AF_NETLINK;
200*1b481fc3SMaciej Żenczykowski 	nl->addr.nl_groups = groups;
201*1b481fc3SMaciej Żenczykowski 	nl->addr.nl_pid = pid;
202*1b481fc3SMaciej Żenczykowski 
203*1b481fc3SMaciej Żenczykowski 	ret = bind(nl->fd, (struct sockaddr *) &nl->addr, sizeof (nl->addr));
204*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
205*1b481fc3SMaciej Żenczykowski 		return ret;
206*1b481fc3SMaciej Żenczykowski 
207*1b481fc3SMaciej Żenczykowski 	addr_len = sizeof(nl->addr);
208*1b481fc3SMaciej Żenczykowski 	ret = getsockname(nl->fd, (struct sockaddr *) &nl->addr, &addr_len);
209*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
210*1b481fc3SMaciej Żenczykowski 		return ret;
211*1b481fc3SMaciej Żenczykowski 
212*1b481fc3SMaciej Żenczykowski 	if (addr_len != sizeof(nl->addr)) {
213*1b481fc3SMaciej Żenczykowski 		errno = EINVAL;
214*1b481fc3SMaciej Żenczykowski 		return -1;
215*1b481fc3SMaciej Żenczykowski 	}
216*1b481fc3SMaciej Żenczykowski 	if (nl->addr.nl_family != AF_NETLINK) {
217*1b481fc3SMaciej Żenczykowski 		errno = EINVAL;
218*1b481fc3SMaciej Żenczykowski 		return -1;
219*1b481fc3SMaciej Żenczykowski 	}
220*1b481fc3SMaciej Żenczykowski 	return 0;
221*1b481fc3SMaciej Żenczykowski }
222*1b481fc3SMaciej Żenczykowski 
223*1b481fc3SMaciej Żenczykowski /**
224*1b481fc3SMaciej Żenczykowski  * mnl_socket_sendto - send a netlink message of a certain size
225*1b481fc3SMaciej Żenczykowski  * \param nl netlink socket obtained via mnl_socket_open()
226*1b481fc3SMaciej Żenczykowski  * \param buf buffer containing the netlink message to be sent
227*1b481fc3SMaciej Żenczykowski  * \param len number of bytes in the buffer that you want to send
228*1b481fc3SMaciej Żenczykowski  *
229*1b481fc3SMaciej Żenczykowski  * On error, it returns -1 and errno is appropriately set. Otherwise, it
230*1b481fc3SMaciej Żenczykowski  * returns the number of bytes sent.
231*1b481fc3SMaciej Żenczykowski  */
mnl_socket_sendto(const struct mnl_socket * nl,const void * buf,size_t len)232*1b481fc3SMaciej Żenczykowski EXPORT_SYMBOL ssize_t mnl_socket_sendto(const struct mnl_socket *nl,
233*1b481fc3SMaciej Żenczykowski 					const void *buf, size_t len)
234*1b481fc3SMaciej Żenczykowski {
235*1b481fc3SMaciej Żenczykowski 	static const struct sockaddr_nl snl = {
236*1b481fc3SMaciej Żenczykowski 		.nl_family = AF_NETLINK
237*1b481fc3SMaciej Żenczykowski 	};
238*1b481fc3SMaciej Żenczykowski 	return sendto(nl->fd, buf, len, 0,
239*1b481fc3SMaciej Żenczykowski 		      (struct sockaddr *) &snl, sizeof(snl));
240*1b481fc3SMaciej Żenczykowski }
241*1b481fc3SMaciej Żenczykowski 
242*1b481fc3SMaciej Żenczykowski /**
243*1b481fc3SMaciej Żenczykowski  * mnl_socket_recvfrom - receive a netlink message
244*1b481fc3SMaciej Żenczykowski  * \param nl netlink socket obtained via mnl_socket_open()
245*1b481fc3SMaciej Żenczykowski  * \param buf buffer that you want to use to store the netlink message
246*1b481fc3SMaciej Żenczykowski  * \param bufsiz size of the buffer passed to store the netlink message
247*1b481fc3SMaciej Żenczykowski  *
248*1b481fc3SMaciej Żenczykowski  * On error, it returns -1 and errno is appropriately set. If errno is set
249*1b481fc3SMaciej Żenczykowski  * to ENOSPC, it means that the buffer that you have passed to store the
250*1b481fc3SMaciej Żenczykowski  * netlink message is too small, so you have received a truncated message.
251*1b481fc3SMaciej Żenczykowski  * To avoid this, you have to allocate a buffer of MNL_SOCKET_BUFFER_SIZE
252*1b481fc3SMaciej Żenczykowski  * (which is 8KB, see linux/netlink.h for more information). Using this
253*1b481fc3SMaciej Żenczykowski  * buffer size ensures that your buffer is big enough to store the netlink
254*1b481fc3SMaciej Żenczykowski  * message without truncating it.
255*1b481fc3SMaciej Żenczykowski  */
mnl_socket_recvfrom(const struct mnl_socket * nl,void * buf,size_t bufsiz)256*1b481fc3SMaciej Żenczykowski EXPORT_SYMBOL ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl,
257*1b481fc3SMaciej Żenczykowski 					  void *buf, size_t bufsiz)
258*1b481fc3SMaciej Żenczykowski {
259*1b481fc3SMaciej Żenczykowski 	ssize_t ret;
260*1b481fc3SMaciej Żenczykowski 	struct sockaddr_nl addr;
261*1b481fc3SMaciej Żenczykowski 	struct iovec iov = {
262*1b481fc3SMaciej Żenczykowski 		.iov_base	= buf,
263*1b481fc3SMaciej Żenczykowski 		.iov_len	= bufsiz,
264*1b481fc3SMaciej Żenczykowski 	};
265*1b481fc3SMaciej Żenczykowski 	struct msghdr msg = {
266*1b481fc3SMaciej Żenczykowski 		.msg_name	= &addr,
267*1b481fc3SMaciej Żenczykowski 		.msg_namelen	= sizeof(struct sockaddr_nl),
268*1b481fc3SMaciej Żenczykowski 		.msg_iov	= &iov,
269*1b481fc3SMaciej Żenczykowski 		.msg_iovlen	= 1,
270*1b481fc3SMaciej Żenczykowski 		.msg_control	= NULL,
271*1b481fc3SMaciej Żenczykowski 		.msg_controllen	= 0,
272*1b481fc3SMaciej Żenczykowski 		.msg_flags	= 0,
273*1b481fc3SMaciej Żenczykowski 	};
274*1b481fc3SMaciej Żenczykowski 	ret = recvmsg(nl->fd, &msg, 0);
275*1b481fc3SMaciej Żenczykowski 	if (ret == -1)
276*1b481fc3SMaciej Żenczykowski 		return ret;
277*1b481fc3SMaciej Żenczykowski 
278*1b481fc3SMaciej Żenczykowski 	if (msg.msg_flags & MSG_TRUNC) {
279*1b481fc3SMaciej Żenczykowski 		errno = ENOSPC;
280*1b481fc3SMaciej Żenczykowski 		return -1;
281*1b481fc3SMaciej Żenczykowski 	}
282*1b481fc3SMaciej Żenczykowski 	if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
283*1b481fc3SMaciej Żenczykowski 		errno = EINVAL;
284*1b481fc3SMaciej Żenczykowski 		return -1;
285*1b481fc3SMaciej Żenczykowski 	}
286*1b481fc3SMaciej Żenczykowski 	return ret;
287*1b481fc3SMaciej Żenczykowski }
288*1b481fc3SMaciej Żenczykowski 
289*1b481fc3SMaciej Żenczykowski /**
290*1b481fc3SMaciej Żenczykowski  * mnl_socket_close - close a given netlink socket
291*1b481fc3SMaciej Żenczykowski  * \param nl netlink socket obtained via mnl_socket_open()
292*1b481fc3SMaciej Żenczykowski  *
293*1b481fc3SMaciej Żenczykowski  * On error, this function returns -1 and errno is appropriately set.
294*1b481fc3SMaciej Żenczykowski  * On success, it returns 0.
295*1b481fc3SMaciej Żenczykowski  */
mnl_socket_close(struct mnl_socket * nl)296*1b481fc3SMaciej Żenczykowski EXPORT_SYMBOL int mnl_socket_close(struct mnl_socket *nl)
297*1b481fc3SMaciej Żenczykowski {
298*1b481fc3SMaciej Żenczykowski 	int ret = close(nl->fd);
299*1b481fc3SMaciej Żenczykowski 	free(nl);
300*1b481fc3SMaciej Żenczykowski 	return ret;
301*1b481fc3SMaciej Żenczykowski }
302*1b481fc3SMaciej Żenczykowski 
303*1b481fc3SMaciej Żenczykowski /**
304*1b481fc3SMaciej Żenczykowski  * mnl_socket_setsockopt - set Netlink socket option
305*1b481fc3SMaciej Żenczykowski  * \param nl netlink socket obtained via mnl_socket_open()
306*1b481fc3SMaciej Żenczykowski  * \param type type of Netlink socket options
307*1b481fc3SMaciej Żenczykowski  * \param buf the buffer that contains the data about this option
308*1b481fc3SMaciej Żenczykowski  * \param len the size of the buffer passed
309*1b481fc3SMaciej Żenczykowski  *
310*1b481fc3SMaciej Żenczykowski  * This function allows you to set some Netlink socket option. As of writing
311*1b481fc3SMaciej Żenczykowski  * this (see linux/netlink.h), the existing options are:
312*1b481fc3SMaciej Żenczykowski  *
313*1b481fc3SMaciej Żenczykowski  *	- \#define NETLINK_ADD_MEMBERSHIP  1
314*1b481fc3SMaciej Żenczykowski  *	- \#define NETLINK_DROP_MEMBERSHIP 2
315*1b481fc3SMaciej Żenczykowski  *	- \#define NETLINK_PKTINFO         3
316*1b481fc3SMaciej Żenczykowski  *	- \#define NETLINK_BROADCAST_ERROR 4
317*1b481fc3SMaciej Żenczykowski  *	- \#define NETLINK_NO_ENOBUFS      5
318*1b481fc3SMaciej Żenczykowski  *
319*1b481fc3SMaciej Żenczykowski  * In the early days, Netlink only supported 32 groups expressed in a
320*1b481fc3SMaciej Żenczykowski  * 32-bits mask. However, since 2.6.14, Netlink may have up to 2^32 multicast
321*1b481fc3SMaciej Żenczykowski  * groups but you have to use setsockopt() with NETLINK_ADD_MEMBERSHIP to
322*1b481fc3SMaciej Żenczykowski  * join a given multicast group. This function internally calls setsockopt()
323*1b481fc3SMaciej Żenczykowski  * to join a given netlink multicast group. You can still use mnl_bind()
324*1b481fc3SMaciej Żenczykowski  * and the 32-bit mask to join a set of Netlink multicast groups.
325*1b481fc3SMaciej Żenczykowski  *
326*1b481fc3SMaciej Żenczykowski  * On error, this function returns -1 and errno is appropriately set.
327*1b481fc3SMaciej Żenczykowski  */
mnl_socket_setsockopt(const struct mnl_socket * nl,int type,void * buf,socklen_t len)328*1b481fc3SMaciej Żenczykowski EXPORT_SYMBOL int mnl_socket_setsockopt(const struct mnl_socket *nl, int type,
329*1b481fc3SMaciej Żenczykowski 					void *buf, socklen_t len)
330*1b481fc3SMaciej Żenczykowski {
331*1b481fc3SMaciej Żenczykowski 	return setsockopt(nl->fd, SOL_NETLINK, type, buf, len);
332*1b481fc3SMaciej Żenczykowski }
333*1b481fc3SMaciej Żenczykowski 
334*1b481fc3SMaciej Żenczykowski /**
335*1b481fc3SMaciej Żenczykowski  * mnl_socket_getsockopt - get a Netlink socket option
336*1b481fc3SMaciej Żenczykowski  * \param nl netlink socket obtained via mnl_socket_open()
337*1b481fc3SMaciej Żenczykowski  * \param type type of Netlink socket options
338*1b481fc3SMaciej Żenczykowski  * \param buf pointer to the buffer to store the value of this option
339*1b481fc3SMaciej Żenczykowski  * \param len size of the information written in the buffer
340*1b481fc3SMaciej Żenczykowski  *
341*1b481fc3SMaciej Żenczykowski  * On error, this function returns -1 and errno is appropriately set.
342*1b481fc3SMaciej Żenczykowski  */
mnl_socket_getsockopt(const struct mnl_socket * nl,int type,void * buf,socklen_t * len)343*1b481fc3SMaciej Żenczykowski EXPORT_SYMBOL int mnl_socket_getsockopt(const struct mnl_socket *nl, int type,
344*1b481fc3SMaciej Żenczykowski 					void *buf, socklen_t *len)
345*1b481fc3SMaciej Żenczykowski {
346*1b481fc3SMaciej Żenczykowski 	return getsockopt(nl->fd, SOL_NETLINK, type, buf, len);
347*1b481fc3SMaciej Żenczykowski }
348*1b481fc3SMaciej Żenczykowski 
349*1b481fc3SMaciej Żenczykowski /**
350*1b481fc3SMaciej Żenczykowski  * @}
351*1b481fc3SMaciej Żenczykowski  */
352