libmnl  1.0.3
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 
69 struct mnl_socket {
70  int fd;
71  struct sockaddr_nl addr;
72 };
73 
85 int mnl_socket_get_fd(const struct mnl_socket *nl)
86 {
87  return nl->fd;
88 }
89 EXPORT_SYMBOL(mnl_socket_get_fd);
90 
100 unsigned int mnl_socket_get_portid(const struct mnl_socket *nl)
101 {
102  return nl->addr.nl_pid;
103 }
104 EXPORT_SYMBOL(mnl_socket_get_portid);
105 
113 struct mnl_socket *mnl_socket_open(int bus)
114 {
115  struct mnl_socket *nl;
116 
117  nl = calloc(sizeof(struct mnl_socket), 1);
118  if (nl == NULL)
119  return NULL;
120 
121  nl->fd = socket(AF_NETLINK, SOCK_RAW, bus);
122  if (nl->fd == -1) {
123  free(nl);
124  return NULL;
125  }
126 
127  return nl;
128 }
129 EXPORT_SYMBOL(mnl_socket_open);
130 
141 int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid)
142 {
143  int ret;
144  socklen_t addr_len;
145 
146  nl->addr.nl_family = AF_NETLINK;
147  nl->addr.nl_groups = groups;
148  nl->addr.nl_pid = pid;
149 
150  ret = bind(nl->fd, (struct sockaddr *) &nl->addr, sizeof (nl->addr));
151  if (ret < 0)
152  return ret;
153 
154  addr_len = sizeof(nl->addr);
155  ret = getsockname(nl->fd, (struct sockaddr *) &nl->addr, &addr_len);
156  if (ret < 0)
157  return ret;
158 
159  if (addr_len != sizeof(nl->addr)) {
160  errno = EINVAL;
161  return -1;
162  }
163  if (nl->addr.nl_family != AF_NETLINK) {
164  errno = EINVAL;
165  return -1;
166  }
167  return 0;
168 }
169 EXPORT_SYMBOL(mnl_socket_bind);
170 
180 ssize_t
181 mnl_socket_sendto(const struct mnl_socket *nl, const void *buf, size_t len)
182 {
183  static const struct sockaddr_nl snl = {
184  .nl_family = AF_NETLINK
185  };
186  return sendto(nl->fd, buf, len, 0,
187  (struct sockaddr *) &snl, sizeof(snl));
188 }
189 EXPORT_SYMBOL(mnl_socket_sendto);
190 
205 ssize_t
206 mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t bufsiz)
207 {
208  ssize_t ret;
209  struct sockaddr_nl addr;
210  struct iovec iov = {
211  .iov_base = buf,
212  .iov_len = bufsiz,
213  };
214  struct msghdr msg = {
215  .msg_name = &addr,
216  .msg_namelen = sizeof(struct sockaddr_nl),
217  .msg_iov = &iov,
218  .msg_iovlen = 1,
219  .msg_control = NULL,
220  .msg_controllen = 0,
221  .msg_flags = 0,
222  };
223  ret = recvmsg(nl->fd, &msg, 0);
224  if (ret == -1)
225  return ret;
226 
227  if (msg.msg_flags & MSG_TRUNC) {
228  errno = ENOSPC;
229  return -1;
230  }
231  if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
232  errno = EINVAL;
233  return -1;
234  }
235  return ret;
236 }
237 EXPORT_SYMBOL(mnl_socket_recvfrom);
238 
247 {
248  int ret = close(nl->fd);
249  free(nl);
250  return ret;
251 }
252 EXPORT_SYMBOL(mnl_socket_close);
253 
279 int mnl_socket_setsockopt(const struct mnl_socket *nl, int type,
280  void *buf, socklen_t len)
281 {
282  return setsockopt(nl->fd, SOL_NETLINK, type, buf, len);
283 }
284 EXPORT_SYMBOL(mnl_socket_setsockopt);
285 
295 int mnl_socket_getsockopt(const struct mnl_socket *nl, int type,
296  void *buf, socklen_t *len)
297 {
298  return getsockopt(nl->fd, SOL_NETLINK, type, buf, len);
299 }
300 EXPORT_SYMBOL(mnl_socket_getsockopt);
301 
struct mnl_socket * mnl_socket_open(int bus)
Definition: socket.c:113
unsigned int mnl_socket_get_portid(const struct mnl_socket *nl)
Definition: socket.c:100
ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t bufsiz)
Definition: socket.c:206
int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid)
Definition: socket.c:141
int mnl_socket_close(struct mnl_socket *nl)
Definition: socket.c:246
int mnl_socket_getsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t *len)
Definition: socket.c:295
ssize_t mnl_socket_sendto(const struct mnl_socket *nl, const void *buf, size_t len)
Definition: socket.c:181
int mnl_socket_get_fd(const struct mnl_socket *nl)
Definition: socket.c:85
int mnl_socket_setsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t len)
Definition: socket.c:279