libmnl 1.0.5
socket.c
1/*
2 * (C) 2008-2010 by Pablo Neira Ayuso <pablo@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2.1 of the License, or
7 * (at your option) any later version.
8 */
9
10#include <libmnl/libmnl.h>
11#include <sys/types.h>
12#include <sys/socket.h>
13#include <stdlib.h>
14#include <unistd.h>
15#include <time.h>
16#include <errno.h>
17#include "internal.h"
18
69struct mnl_socket {
70 int fd;
71 struct sockaddr_nl addr;
72};
73
85EXPORT_SYMBOL int mnl_socket_get_fd(const struct mnl_socket *nl)
86{
87 return nl->fd;
88}
89
99EXPORT_SYMBOL unsigned int mnl_socket_get_portid(const struct mnl_socket *nl)
100{
101 return nl->addr.nl_pid;
102}
103
104static struct mnl_socket *__mnl_socket_open(int bus, int flags)
105{
106 struct mnl_socket *nl;
107
108 nl = calloc(1, sizeof(struct mnl_socket));
109 if (nl == NULL)
110 return NULL;
111
112 nl->fd = socket(AF_NETLINK, SOCK_RAW | flags, bus);
113 if (nl->fd == -1) {
114 free(nl);
115 return NULL;
116 }
117
118 return nl;
119}
120
128EXPORT_SYMBOL struct mnl_socket *mnl_socket_open(int bus)
129{
130 return __mnl_socket_open(bus, 0);
131}
132
145EXPORT_SYMBOL struct mnl_socket *mnl_socket_open2(int bus, int flags)
146{
147 return __mnl_socket_open(bus, flags);
148}
149
161EXPORT_SYMBOL struct mnl_socket *mnl_socket_fdopen(int fd)
162{
163 int ret;
164 struct mnl_socket *nl;
165 struct sockaddr_nl addr;
166 socklen_t addr_len = sizeof(struct sockaddr_nl);
167
168 ret = getsockname(fd, (struct sockaddr *) &addr, &addr_len);
169 if (ret == -1)
170 return NULL;
171
172 nl = calloc(1, sizeof(struct mnl_socket));
173 if (nl == NULL)
174 return NULL;
175
176 nl->fd = fd;
177 if (addr.nl_family == AF_NETLINK)
178 nl->addr = addr;
179
180 return nl;
181}
182
193EXPORT_SYMBOL int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups,
194 pid_t pid)
195{
196 int ret;
197 socklen_t addr_len;
198
199 nl->addr.nl_family = AF_NETLINK;
200 nl->addr.nl_groups = groups;
201 nl->addr.nl_pid = pid;
202
203 ret = bind(nl->fd, (struct sockaddr *) &nl->addr, sizeof (nl->addr));
204 if (ret < 0)
205 return ret;
206
207 addr_len = sizeof(nl->addr);
208 ret = getsockname(nl->fd, (struct sockaddr *) &nl->addr, &addr_len);
209 if (ret < 0)
210 return ret;
211
212 if (addr_len != sizeof(nl->addr)) {
213 errno = EINVAL;
214 return -1;
215 }
216 if (nl->addr.nl_family != AF_NETLINK) {
217 errno = EINVAL;
218 return -1;
219 }
220 return 0;
221}
222
232EXPORT_SYMBOL ssize_t mnl_socket_sendto(const struct mnl_socket *nl,
233 const void *buf, size_t len)
234{
235 static const struct sockaddr_nl snl = {
236 .nl_family = AF_NETLINK
237 };
238 return sendto(nl->fd, buf, len, 0,
239 (struct sockaddr *) &snl, sizeof(snl));
240}
241
256EXPORT_SYMBOL ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl,
257 void *buf, size_t bufsiz)
258{
259 ssize_t ret;
260 struct sockaddr_nl addr;
261 struct iovec iov = {
262 .iov_base = buf,
263 .iov_len = bufsiz,
264 };
265 struct msghdr msg = {
266 .msg_name = &addr,
267 .msg_namelen = sizeof(struct sockaddr_nl),
268 .msg_iov = &iov,
269 .msg_iovlen = 1,
270 .msg_control = NULL,
271 .msg_controllen = 0,
272 .msg_flags = 0,
273 };
274 ret = recvmsg(nl->fd, &msg, 0);
275 if (ret == -1)
276 return ret;
277
278 if (msg.msg_flags & MSG_TRUNC) {
279 errno = ENOSPC;
280 return -1;
281 }
282 if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
283 errno = EINVAL;
284 return -1;
285 }
286 return ret;
287}
288
296EXPORT_SYMBOL int mnl_socket_close(struct mnl_socket *nl)
297{
298 int ret = close(nl->fd);
299 free(nl);
300 return ret;
301}
302
328EXPORT_SYMBOL int mnl_socket_setsockopt(const struct mnl_socket *nl, int type,
329 void *buf, socklen_t len)
330{
331 return setsockopt(nl->fd, SOL_NETLINK, type, buf, len);
332}
333
343EXPORT_SYMBOL int mnl_socket_getsockopt(const struct mnl_socket *nl, int type,
344 void *buf, socklen_t *len)
345{
346 return getsockopt(nl->fd, SOL_NETLINK, type, buf, len);
347}
348
int mnl_socket_getsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t *len)
Definition: socket.c:343
int mnl_socket_get_fd(const struct mnl_socket *nl)
Definition: socket.c:85
int mnl_socket_close(struct mnl_socket *nl)
Definition: socket.c:296
int mnl_socket_setsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t len)
Definition: socket.c:328
unsigned int mnl_socket_get_portid(const struct mnl_socket *nl)
Definition: socket.c:99
struct mnl_socket * mnl_socket_open(int bus)
Definition: socket.c:128
struct mnl_socket * mnl_socket_open2(int bus, int flags)
Definition: socket.c:145
ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t bufsiz)
Definition: socket.c:256
int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid)
Definition: socket.c:193
ssize_t mnl_socket_sendto(const struct mnl_socket *nl, const void *buf, size_t len)
Definition: socket.c:232
struct mnl_socket * mnl_socket_fdopen(int fd)
Definition: socket.c:161