socket.c
/*
* (C) 2008-2010 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*/
#include <libmnl/libmnl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include "internal.h"
struct mnl_socket {
int fd;
struct sockaddr_nl addr;
};
EXPORT_SYMBOL int mnl_socket_get_fd(const struct mnl_socket *nl)
{
return nl->fd;
}
EXPORT_SYMBOL unsigned int mnl_socket_get_portid(const struct mnl_socket *nl)
{
return nl->addr.nl_pid;
}
static struct mnl_socket *__mnl_socket_open(int bus, int flags)
{
struct mnl_socket *nl;
nl = calloc(1, sizeof(struct mnl_socket));
if (nl == NULL)
return NULL;
nl->fd = socket(AF_NETLINK, SOCK_RAW | flags, bus);
if (nl->fd == -1) {
free(nl);
return NULL;
}
return nl;
}
EXPORT_SYMBOL struct mnl_socket *mnl_socket_open(int bus)
{
return __mnl_socket_open(bus, 0);
}
EXPORT_SYMBOL struct mnl_socket *mnl_socket_open2(int bus, int flags)
{
return __mnl_socket_open(bus, flags);
}
EXPORT_SYMBOL struct mnl_socket *mnl_socket_fdopen(int fd)
{
int ret;
struct mnl_socket *nl;
struct sockaddr_nl addr;
socklen_t addr_len = sizeof(struct sockaddr_nl);
ret = getsockname(fd, (struct sockaddr *) &addr, &addr_len);
if (ret == -1)
return NULL;
nl = calloc(1, sizeof(struct mnl_socket));
if (nl == NULL)
return NULL;
nl->fd = fd;
if (addr.nl_family == AF_NETLINK)
nl->addr = addr;
return nl;
}
EXPORT_SYMBOL int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups,
pid_t pid)
{
int ret;
socklen_t addr_len;
nl->addr.nl_family = AF_NETLINK;
nl->addr.nl_groups = groups;
nl->addr.nl_pid = pid;
ret = bind(nl->fd, (struct sockaddr *) &nl->addr, sizeof (nl->addr));
if (ret < 0)
return ret;
addr_len = sizeof(nl->addr);
ret = getsockname(nl->fd, (struct sockaddr *) &nl->addr, &addr_len);
if (ret < 0)
return ret;
if (addr_len != sizeof(nl->addr)) {
errno = EINVAL;
return -1;
}
if (nl->addr.nl_family != AF_NETLINK) {
errno = EINVAL;
return -1;
}
return 0;
}
EXPORT_SYMBOL ssize_t mnl_socket_sendto(const struct mnl_socket *nl,
const void *buf, size_t len)
{
static const struct sockaddr_nl snl = {
.nl_family = AF_NETLINK
};
return sendto(nl->fd, buf, len, 0,
(struct sockaddr *) &snl, sizeof(snl));
}
EXPORT_SYMBOL ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl,
void *buf, size_t bufsiz)
{
ssize_t ret;
struct sockaddr_nl addr;
struct iovec iov = {
.iov_base = buf,
.iov_len = bufsiz,
};
struct msghdr msg = {
.msg_name = &addr,
.msg_namelen = sizeof(struct sockaddr_nl),
.msg_iov = &iov,
.msg_iovlen = 1,
.msg_control = NULL,
.msg_controllen = 0,
.msg_flags = 0,
};
ret = recvmsg(nl->fd, &msg, 0);
if (ret == -1)
return ret;
if (msg.msg_flags & MSG_TRUNC) {
errno = ENOSPC;
return -1;
}
if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
errno = EINVAL;
return -1;
}
return ret;
}
EXPORT_SYMBOL int mnl_socket_close(struct mnl_socket *nl)
{
int ret = close(nl->fd);
free(nl);
return ret;
}
EXPORT_SYMBOL int mnl_socket_setsockopt(const struct mnl_socket *nl, int type,
void *buf, socklen_t len)
{
return setsockopt(nl->fd, SOL_NETLINK, type, buf, len);
}
EXPORT_SYMBOL int mnl_socket_getsockopt(const struct mnl_socket *nl, int type,
void *buf, socklen_t *len)
{
return getsockopt(nl->fd, SOL_NETLINK, type, buf, len);
}
mnl_socket_getsockopt
int mnl_socket_getsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t *len)
Definition socket.c:343
mnl_socket_get_fd
int mnl_socket_get_fd(const struct mnl_socket *nl)
Definition socket.c:85
mnl_socket_close
int mnl_socket_close(struct mnl_socket *nl)
Definition socket.c:296
mnl_socket_setsockopt
int mnl_socket_setsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t len)
Definition socket.c:328
mnl_socket_get_portid
unsigned int mnl_socket_get_portid(const struct mnl_socket *nl)
Definition socket.c:99
mnl_socket_open
struct mnl_socket * mnl_socket_open(int bus)
Definition socket.c:128
mnl_socket_open2
struct mnl_socket * mnl_socket_open2(int bus, int flags)
Definition socket.c:145
mnl_socket_recvfrom
ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t bufsiz)
Definition socket.c:256
mnl_socket_bind
int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid)
Definition socket.c:193
mnl_socket_sendto
ssize_t mnl_socket_sendto(const struct mnl_socket *nl, const void *buf, size_t len)
Definition socket.c:232
mnl_socket_fdopen
struct mnl_socket * mnl_socket_fdopen(int fd)
Definition socket.c:161