Refactor how the AF_PACKET socket is used

This commit is contained in:
Daniel Adolfsson 2019-12-12 00:01:46 +01:00
parent be97afdf83
commit f0e0d767f3
7 changed files with 189 additions and 142 deletions

View File

@ -33,10 +33,10 @@
#include "addr.h"
#include "iface.h"
#include "io.h"
#include "ndppd.h"
#include "proxy.h"
#include "session.h"
#include "sio.h"
extern int nd_conf_invalid_ttl;
extern int nd_conf_valid_ttl;
@ -46,6 +46,7 @@ extern int nd_conf_retrans_time;
extern bool nd_conf_keepalive;
static nd_iface_t *ndL_first_iface, *ndL_first_free_iface;
static nd_io_t *ndL_io;
/* Used when daemonizing to make sure the parent process does not restore these flags upon exit. */
bool nd_iface_no_restore_flags;
@ -150,7 +151,7 @@ static uint16_t ndL_calculate_icmp6_checksum(ndL_icmp6_msg_t *msg, size_t size)
return htons(~sum);
}
static void ndL_handle_packet(nd_iface_t *iface, uint8_t *buf, size_t buflen)
static __attribute__((unused)) void ndL_handle_packet(nd_iface_t *iface, uint8_t *buf, size_t buflen)
{
ndL_icmp6_msg_t *msg = (ndL_icmp6_msg_t *)buf;
@ -172,21 +173,18 @@ static void ndL_handle_packet(nd_iface_t *iface, uint8_t *buf, size_t buflen)
ndL_handle_na(iface, msg);
}
static void ndL_sio_handler(nd_sio_t *sio, __attribute__((unused)) int events)
static void ndL_io_handler(nd_io_t *io, __attribute__((unused)) int events)
{
nd_iface_t *ifa = (nd_iface_t *)sio->data;
struct sockaddr_ll lladdr;
memset(&lladdr, 0, sizeof(struct sockaddr_ll));
lladdr.sll_family = AF_PACKET;
lladdr.sll_protocol = htons(ETH_P_IPV6);
lladdr.sll_ifindex = (int)ifa->index;
uint8_t buf[1024];
for (;;)
{
ssize_t len = nd_sio_recv(sio, (struct sockaddr *)&lladdr, sizeof(lladdr), buf, sizeof(buf));
ssize_t len = nd_io_recv(io, (struct sockaddr *)&lladdr, sizeof(lladdr), buf, sizeof(buf));
if (len == 0)
return;
@ -194,7 +192,12 @@ static void ndL_sio_handler(nd_sio_t *sio, __attribute__((unused)) int events)
if (len < 0)
return;
ndL_handle_packet(ifa, buf, len);
nd_iface_t *iface;
ND_LL_SEARCH(ndL_first_iface, iface, next, iface->index == (unsigned int)lladdr.sll_ifindex);
if (iface)
ndL_handle_packet(iface, buf, len);
}
}
@ -232,57 +235,18 @@ nd_iface_t *nd_iface_open(const char *name, unsigned int index)
return iface;
}
/* No such interface. */
nd_sio_t *sio = nd_sio_open(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6));
if (!sio)
{
nd_log_error("Failed to create socket: %s", strerror(errno));
return NULL;
}
/* Determine link-layer address. */
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, name);
if (ioctl(sio->fd, SIOCGIFHWADDR, &ifr) < 0)
if (ioctl(ndL_io->fd, SIOCGIFHWADDR, &ifr) < 0)
{
nd_sio_close(sio);
nd_log_error("Failed to determine link-layer address: %s", strerror(errno));
return NULL;
}
/* Set up filter, so we only get NS and NA messages. */
static struct sock_filter filter[] = {
/* Load next header field. */
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, offsetof(struct ip6_hdr, ip6_nxt)),
/* Bail if it's not IPPROTO_ICMPV6. */
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, IPPROTO_ICMPV6, 0, 3),
/* Load the ICMPv6 type. */
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, sizeof(struct ip6_hdr) + offsetof(struct icmp6_hdr, icmp6_type)),
/* Keep if ND_NEIGHBOR_SOLICIT. */
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ND_NEIGHBOR_SOLICIT, 2, 0),
/* Keep if ND_NEIGHBOR_SOLICIT. */
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ND_NEIGHBOR_ADVERT, 1, 0),
/* Drop packet. */
BPF_STMT(BPF_RET | BPF_K, 0),
/* Keep packet. */
BPF_STMT(BPF_RET | BPF_K, (u_int32_t)-1)
};
static struct sock_fprog fprog = { 7, filter };
if (setsockopt(sio->fd, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)) < 0)
{
nd_sio_close(sio);
nd_log_error("Failed to configure netfilter: %s", strerror(errno));
return NULL;
}
/* Allocate the nd_ifa_t object. */
iface = ndL_first_free_iface;
@ -296,7 +260,6 @@ nd_iface_t *nd_iface_open(const char *name, unsigned int index)
ND_LL_PREPEND(ndL_first_iface, iface, next);
iface->sio = sio;
iface->index = index;
iface->refcount = 1;
iface->old_allmulti = -1;
@ -304,9 +267,6 @@ nd_iface_t *nd_iface_open(const char *name, unsigned int index)
strcpy(iface->name, name);
memcpy(iface->lladdr, ifr.ifr_hwaddr.sa_data, 6);
sio->data = (intptr_t)iface;
sio->handler = ndL_sio_handler;
nd_log_info("New interface %s (%d)", iface->name, iface->index);
return iface;
@ -325,8 +285,6 @@ void nd_iface_close(nd_iface_t *iface)
nd_iface_set_allmulti(iface, iface->old_allmulti);
}
nd_sio_close(iface->sio);
ND_LL_DELETE(ndL_first_iface, iface, next);
ND_LL_PREPEND(ndL_first_free_iface, iface, next);
}
@ -363,7 +321,7 @@ static ssize_t ndL_send_icmp6(nd_iface_t *ifa, ndL_icmp6_msg_t *msg, size_t size
addr.sll_ifindex = (int)ifa->index;
memcpy(addr.sll_addr, hwaddr, 6);
return nd_sio_send(ifa->sio, (struct sockaddr *)&addr, sizeof(addr), msg, size);
return nd_io_send(ndL_io, (struct sockaddr *)&addr, sizeof(addr), msg, size);
}
ssize_t nd_iface_write_na(nd_iface_t *iface, nd_addr_t *dst, uint8_t *dst_ll, nd_addr_t *tgt, bool router)
@ -395,8 +353,8 @@ ssize_t nd_iface_write_na(nd_iface_t *iface, nd_addr_t *dst, uint8_t *dst_ll, nd
memcpy(msg.lladdr, iface->lladdr, sizeof(msg.lladdr));
nd_log_info("Write NA tgt=%s, dst=%s [%x:%x:%x:%x:%x:%x dev %s]", nd_aton(tgt), nd_aton(dst),
dst_ll[0], dst_ll[1], dst_ll[2], dst_ll[3], dst_ll[4], dst_ll[5], iface->name);
nd_log_info("Write NA tgt=%s, dst=%s [%x:%x:%x:%x:%x:%x dev %s]", nd_aton(tgt), nd_aton(dst), dst_ll[0], dst_ll[1],
dst_ll[2], dst_ll[3], dst_ll[4], dst_ll[5], iface->name);
return ndL_send_icmp6(iface, (ndL_icmp6_msg_t *)&msg, sizeof(msg), dst_ll);
}
@ -437,6 +395,45 @@ ssize_t nd_iface_write_ns(nd_iface_t *ifa, nd_addr_t *tgt)
return ndL_send_icmp6(ifa, (ndL_icmp6_msg_t *)&msg, sizeof(msg), ll_mcast);
}
bool nd_iface_startup()
{
if (!(ndL_io = nd_io_socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6))))
return false;
/* Set up filter, so we only get NS and NA messages. */
static struct sock_filter filter[] = {
/* Load next header field. */
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, offsetof(struct ip6_hdr, ip6_nxt)),
/* Bail if it's not IPPROTO_ICMPV6. */
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, IPPROTO_ICMPV6, 0, 3),
/* Load the ICMPv6 type. */
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, sizeof(struct ip6_hdr) + offsetof(struct icmp6_hdr, icmp6_type)),
/* Keep if ND_NEIGHBOR_SOLICIT. */
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ND_NEIGHBOR_SOLICIT, 2, 0),
/* Keep if ND_NEIGHBOR_SOLICIT. */
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ND_NEIGHBOR_ADVERT, 1, 0),
/* Drop packet. */
BPF_STMT(BPF_RET | BPF_K, 0),
/* Keep packet. */
BPF_STMT(BPF_RET | BPF_K, (u_int32_t)-1)
};
static struct sock_fprog fprog = { 7, filter };
if (setsockopt(ndL_io->fd, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)) < 0)
{
nd_io_close(ndL_io);
ndL_io = NULL;
nd_log_error("Failed to configure netfilter: %s", strerror(errno));
return NULL;
}
ndL_io->handler = ndL_io_handler;
return true;
}
bool nd_iface_set_allmulti(nd_iface_t *iface, bool on)
{
nd_log_debug("%s all multicast mode for interface %s", on ? "Enabling" : "Disabling", iface->name);
@ -444,7 +441,7 @@ bool nd_iface_set_allmulti(nd_iface_t *iface, bool on)
struct ifreq ifr;
memcpy(ifr.ifr_name, iface->name, IFNAMSIZ);
if (ioctl(iface->sio->fd, SIOCGIFFLAGS, &ifr) < 0)
if (ioctl(ndL_io->fd, SIOCGIFFLAGS, &ifr) < 0)
{
nd_log_error("Failed to get interface flags: %s", strerror(errno));
return false;
@ -461,7 +458,7 @@ bool nd_iface_set_allmulti(nd_iface_t *iface, bool on)
else
ifr.ifr_flags &= ~IFF_ALLMULTI;
if (ioctl(iface->sio->fd, SIOCSIFFLAGS, &ifr) < 0)
if (ioctl(ndL_io->fd, SIOCSIFFLAGS, &ifr) < 0)
{
nd_log_error("Failed to set interface flags: %s", strerror(errno));
return false;
@ -477,7 +474,7 @@ bool nd_iface_set_promisc(nd_iface_t *iface, bool on)
struct ifreq ifr;
memcpy(ifr.ifr_name, iface->name, IFNAMSIZ);
if (ioctl(iface->sio->fd, SIOCGIFFLAGS, &ifr) < 0)
if (ioctl(ndL_io->fd, SIOCGIFFLAGS, &ifr) < 0)
{
nd_log_error("Failed to get interface flags: %s", strerror(errno));
return false;
@ -494,7 +491,7 @@ bool nd_iface_set_promisc(nd_iface_t *iface, bool on)
else
ifr.ifr_flags &= ~IFF_PROMISC;
if (ioctl(iface->sio->fd, SIOCSIFFLAGS, &ifr) < 0)
if (ioctl(ndL_io->fd, SIOCSIFFLAGS, &ifr) < 0)
{
nd_log_error("Failed to set interface flags: %s", strerror(errno));
return false;
@ -507,8 +504,9 @@ void nd_iface_cleanup()
{
ND_LL_FOREACH_S(ndL_first_iface, iface, tmp, next)
{
/* We're gonna be bad and just ignore refs here as all memory will soon be invalid anyway. */
iface->refcount = 1;
nd_iface_close(iface);
}
nd_io_close(ndL_io);
}

View File

@ -20,6 +20,7 @@
#define NDPPD_IFACE_H
#include "ndppd.h"
#include <net/if.h>
struct nd_iface
@ -37,7 +38,6 @@ struct nd_iface
nd_proxy_t *proxy;
nd_session_t *sessions; /* All sessions expecting NA messages to arrive here. */
nd_sio_t *sio;
};
extern bool nd_iface_no_restore_flags;
@ -49,6 +49,7 @@ ssize_t nd_iface_write_na(nd_iface_t *iface, nd_addr_t *dst, uint8_t *dst_ll, nd
void nd_iface_get_local_addr(nd_iface_t *iface, nd_addr_t *addr);
bool nd_iface_set_allmulti(nd_iface_t *iface, bool on);
bool nd_iface_set_promisc(nd_iface_t *iface, bool on);
bool nd_iface_startup();
void nd_iface_cleanup();
#endif /* NDPPD_IFACE_H */

View File

@ -24,6 +24,7 @@
#include <unistd.h>
#ifndef NDPPD_NO_USE_EPOLL
# include <fcntl.h>
# include <sys/epoll.h>
#else
# include <poll.h>
@ -34,16 +35,16 @@
# define EPOLLIN POLLIN
#endif
#include "io.h"
#include "ndppd.h"
#include "sio.h"
static nd_sio_t *ndL_first_sio, *ndL_first_free_sio;
static nd_io_t *ndL_first_io, *ndL_first_free_io;
#ifndef NDPPD_NO_USE_EPOLL
static int ndL_epoll_fd;
#else
# ifndef NDPPD_STATIC_POLLFDS_SIZE
# define NDPPD_STATIC_POLLFDS_SIZE 32
# define NDPPD_STATIC_POLLFDS_SIZE 8
# endif
static struct pollfd static_pollfds[NDPPD_STATIC_POLLFDS_SIZE];
@ -74,7 +75,7 @@ static void ndL_refresh_pollfds()
ND_LL_FOREACH(ndL_first_sio, sio, next)
{
pollfds[index].fd = sio->fd;
pollfds[index].fd = io->fd;
pollfds[index].revents = 0;
pollfds[index].events = POLLIN;
index++;
@ -84,73 +85,113 @@ static void ndL_refresh_pollfds()
}
#endif
nd_sio_t *nd_sio_open(int domain, int type, int protocol)
nd_io_t *nd_sio_create(int fd)
{
int fd = socket(domain, type, protocol);
nd_io_t *io = ndL_first_free_io;
if (fd < 0)
return NULL;
if (io)
ND_LL_DELETE(ndL_first_free_io, io, next);
else
io = ND_ALLOC(nd_io_t);
/* Non-blocking. */
ND_LL_PREPEND(ndL_first_io, io, next);
int on = 1;
if (ioctl(fd, FIONBIO, (char *)&on) < 0)
{
close(fd);
return NULL;
io->fd = fd;
io->data = 0;
io->handler = NULL;
return io;
}
/* Allocate the nd_sio_t object. */
static nd_io_t *ndL_create(int fd)
{
int flags = fcntl(fd, F_GETFL, 0);
nd_sio_t *sio = ndL_first_free_sio;
if (flags == -1)
{
nd_log_error("Could not read flags: %s", strerror(errno));
close(fd);
return false;
}
if (sio)
ND_LL_DELETE(ndL_first_free_sio, sio, next);
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
{
nd_log_error("Could not set flags: %s", strerror(errno));
close(fd);
return false;
}
nd_io_t *io = ndL_first_free_io;
if (io)
ND_LL_DELETE(ndL_first_free_io, io, next);
else
sio = ND_ALLOC(nd_sio_t);
io = ND_ALLOC(nd_io_t);
ND_LL_PREPEND(ndL_first_sio, sio, next);
ND_LL_PREPEND(ndL_first_io, io, next);
sio->fd = fd;
io->fd = fd;
io->data = 0;
io->handler = NULL;
#ifndef NDPPD_NO_USE_EPOLL
if (ndL_epoll_fd <= 0 && (ndL_epoll_fd = epoll_create(1)) < 0)
{
nd_log_error("epoll_create() failed: %s", strerror(errno));
nd_sio_close(sio);
return NULL;
}
struct epoll_event event = { .events = EPOLLIN, .data.ptr = sio };
struct epoll_event event = { .events = EPOLLIN, .data.ptr = io };
if (epoll_ctl(ndL_epoll_fd, EPOLL_CTL_ADD, fd, &event) < 0)
if (epoll_ctl(ndL_epoll_fd, EPOLL_CTL_ADD, io->fd, &event) < 0)
{
nd_log_error("epoll_ctl() failed: %s", strerror(errno));
nd_sio_close(sio);
return NULL;
}
#else
/* Make sure our pollfd array is updated. */
ndL_dirty = true;
#endif
return sio;
return io;
}
void nd_sio_close(nd_sio_t *sio)
nd_io_t *nd_io_socket(int domain, int type, int protocol)
{
close(sio->fd);
int fd = socket(domain, type, protocol);
if (fd == -1)
{
nd_log_error("nd_io_socket(): Could not create socket: %s", strerror(errno));
return NULL;
}
return ndL_create(fd);
}
nd_io_t *nd_io_open(const char *file, int oflag)
{
int fd = open(file, oflag);
if (fd == -1)
return NULL;
return ndL_create(fd);
}
void nd_io_close(nd_io_t *io)
{
close(io->fd);
#ifdef NDPPD_NO_USE_EPOLL
ndL_dirty = true;
#endif
ND_LL_DELETE(ndL_first_sio, sio, next);
ND_LL_PREPEND(ndL_first_free_sio, sio, next);
ND_LL_DELETE(ndL_first_io, io, next);
ND_LL_PREPEND(ndL_first_free_io, io, next);
}
ssize_t nd_sio_send(nd_sio_t *sio, const struct sockaddr *addr, size_t addrlen, const void *msg, size_t msglen)
ssize_t nd_io_send(nd_io_t *io, const struct sockaddr *addr, size_t addrlen, const void *msg, size_t msglen)
{
struct iovec iov;
iov.iov_len = msglen;
@ -164,7 +205,7 @@ ssize_t nd_sio_send(nd_sio_t *sio, const struct sockaddr *addr, size_t addrlen,
ssize_t len;
if ((len = sendmsg(sio->fd, &mhdr, 0)) < 0)
if ((len = sendmsg(io->fd, &mhdr, 0)) < 0)
{
printf("send err %s\n", strerror(errno));
return -1;
@ -173,7 +214,7 @@ ssize_t nd_sio_send(nd_sio_t *sio, const struct sockaddr *addr, size_t addrlen,
return len;
}
ssize_t nd_sio_recv(nd_sio_t *sio, struct sockaddr *addr, size_t addrlen, void *msg, size_t msglen)
ssize_t nd_io_recv(nd_io_t *io, struct sockaddr *addr, size_t addrlen, void *msg, size_t msglen)
{
struct iovec iov;
iov.iov_len = msglen;
@ -188,7 +229,7 @@ ssize_t nd_sio_recv(nd_sio_t *sio, struct sockaddr *addr, size_t addrlen, void *
int len;
if ((len = recvmsg(sio->fd, &mhdr, 0)) < 0)
if ((len = recvmsg(io->fd, &mhdr, 0)) < 0)
{
if (errno != EAGAIN)
nd_log_error("nd_sio_recv() failed: %s", strerror(errno));
@ -199,12 +240,12 @@ ssize_t nd_sio_recv(nd_sio_t *sio, struct sockaddr *addr, size_t addrlen, void *
return len;
}
bool nd_sio_bind(nd_sio_t *sio, const struct sockaddr *addr, size_t addrlen)
bool nd_io_bind(nd_io_t *io, const struct sockaddr *addr, size_t addrlen)
{
return bind(sio->fd, addr, addrlen) == 0;
return bind(io->fd, addr, addrlen) == 0;
}
bool nd_sio_poll()
bool nd_io_poll()
{
#ifndef NDPPD_NO_USE_EPOLL
struct epoll_event events[8];
@ -219,10 +260,10 @@ bool nd_sio_poll()
for (int i = 0; i < count; i++)
{
nd_sio_t *sio = (nd_sio_t *)events[i].data.ptr;
nd_io_t *io = (nd_io_t *)events[i].data.ptr;
if (sio->handler)
sio->handler(sio, events[i].events);
if (io->handler)
io->handler(io, events[i].events);
}
#else
@ -245,12 +286,12 @@ bool nd_sio_poll()
if (pollfds[i].revents == 0)
continue;
for (nd_sio_t *sio = ndL_first_sio; sio; sio = sio->next)
for (nd_sio_t *sio = ndL_first_sio; sio; sio = io->next)
{
if (sio->fd == pollfds[i].fd)
if (io->fd == pollfds[i].fd)
{
if (sio->handler != NULL)
sio->handler(sio, pollfds[i].revents);
if (io->handler != NULL)
io->handler(sio, pollfds[i].revents);
break;
}
@ -261,16 +302,18 @@ bool nd_sio_poll()
return true;
}
void nd_sio_cleanup()
void nd_io_cleanup()
{
ND_LL_FOREACH_S(ndL_first_sio, sio, tmp, next)
ND_LL_FOREACH_S(ndL_first_io, sio, tmp, next)
{
nd_sio_close(sio);
nd_io_close(sio);
}
#ifndef NDPPD_NO_USE_EPOLL
if (ndL_epoll_fd > 0)
{
close(ndL_epoll_fd);
ndL_epoll_fd = 0;
}
#endif
}

View File

@ -16,27 +16,30 @@
* You should have received a copy of the GNU General Public License
* along with ndppd. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef NDPPD_SIO_H
#define NDPPD_SIO_H
#ifndef NDPPD_IO_H
#define NDPPD_IO_H
#include "ndppd.h"
typedef void(nd_sio_handler_t)(nd_sio_t *sio, int events);
typedef void(nd_io_handler_t)(nd_io_t *io, int events);
struct nd_sio
struct nd_io
{
nd_sio_t *next;
nd_io_t *next;
int fd;
uintptr_t data;
nd_sio_handler_t *handler;
nd_io_handler_t *handler;
};
nd_sio_t *nd_sio_open(int domain, int type, int protocol);
void nd_sio_close(nd_sio_t *nio);
bool nd_sio_bind(nd_sio_t *sio, const struct sockaddr *addr, size_t addrlen);
ssize_t nd_sio_send(nd_sio_t *sio, const struct sockaddr *addr, size_t addrlen, const void *msg, size_t msglen);
ssize_t nd_sio_recv(nd_sio_t *sio, struct sockaddr *addr, size_t addrlen, void *msg, size_t msglen);
bool nd_sio_poll();
void nd_sio_cleanup();
nd_io_t *nd_sio_create(int fd);
bool nd_sio_set_nonblock(nd_io_t *io, bool value);
#endif /* NDPPD_SIO_H */
nd_io_t *nd_io_socket(int domain, int type, int protocol);
void nd_io_close(nd_io_t *io);
bool nd_io_bind(nd_io_t *io, const struct sockaddr *addr, size_t addrlen);
ssize_t nd_io_send(nd_io_t *io, const struct sockaddr *addr, size_t addrlen, const void *msg, size_t msglen);
ssize_t nd_io_recv(nd_io_t *io, struct sockaddr *addr, size_t addrlen, void *msg, size_t msglen);
bool nd_io_poll();
void nd_io_cleanup();
#endif /*NDPPD_IO_H*/

View File

@ -28,14 +28,12 @@
#include <sys/time.h>
#include <unistd.h>
#include "addr.h"
#include "conf.h"
#include "iface.h"
#include "io.h"
#include "ndppd.h"
#include "proxy.h"
#include "rtnl.h"
#include "rule.h"
#include "sio.h"
#ifndef NDPPD_CONFIG_PATH
# define NDPPD_CONFIG_PATH "../ndppd.conf"
@ -198,6 +196,9 @@ int main(int argc, char *argv[])
return -1;
}
if (!nd_iface_startup())
return -1;
if (!nd_proxy_startup())
return -1;
@ -211,6 +212,7 @@ int main(int argc, char *argv[])
bool query_addresses = false;
while (1)
{
if (nd_current_time >= nd_rtnl_dump_timeout)
@ -222,7 +224,7 @@ int main(int argc, char *argv[])
nd_rtnl_query_addresses();
}
if (!nd_sio_poll())
if (!nd_io_poll())
{
/* TODO: Error */
break;

View File

@ -27,7 +27,7 @@
#define NDPPD_VERSION "1.0-beta1"
typedef struct nd_iface nd_iface_t;
typedef struct nd_sio nd_sio_t;
typedef struct nd_io nd_io_t;
typedef struct nd_proxy nd_proxy_t;
typedef struct nd_conf nd_conf_t;
typedef struct in6_addr nd_addr_t;

View File

@ -22,11 +22,11 @@
#include <sys/socket.h>
#include "addr.h"
#include "io.h"
#include "ndppd.h"
#include "rtnl.h"
#include "sio.h"
static nd_sio_t *ndL_sio;
static nd_io_t *ndL_io;
static nd_rtnl_route_t *ndL_routes, *ndL_free_routes;
static nd_rtnl_addr_t *ndL_addrs, *ndL_free_addrs;
@ -189,13 +189,13 @@ static void ndL_handle_delroute(struct rtmsg *msg, int rtl)
}
}
static void ndL_sio_handler(__attribute__((unused)) nd_sio_t *unused1, __attribute__((unused)) int unused2)
static void ndL_io_handler(__attribute__((unused)) nd_io_t *unused1, __attribute__((unused)) int unused2)
{
uint8_t buf[4096];
for (;;)
{
ssize_t len = nd_sio_recv(ndL_sio, NULL, 0, buf, sizeof(buf));
ssize_t len = nd_io_recv(ndL_io, NULL, 0, buf, sizeof(buf));
if (len < 0)
/* Failed. */
@ -230,10 +230,10 @@ static void ndL_sio_handler(__attribute__((unused)) nd_sio_t *unused1, __attribu
bool nd_rtnl_open()
{
if (ndL_sio != NULL)
if (ndL_io != NULL)
return true;
if (!(ndL_sio = nd_sio_open(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)))
if (!(ndL_io = nd_io_socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)))
{
nd_log_error("Failed to open netlink socket: %s", strerror(errno));
return false;
@ -244,23 +244,23 @@ bool nd_rtnl_open()
addr.nl_family = AF_NETLINK;
addr.nl_groups = (1 << (RTNLGRP_IPV6_IFADDR - 1)) | (1 << (RTNLGRP_IPV6_ROUTE - 1));
if (!nd_sio_bind(ndL_sio, (struct sockaddr *)&addr, sizeof(addr)))
if (!nd_io_bind(ndL_io, (struct sockaddr *)&addr, sizeof(addr)))
{
nd_log_error("Failed to bind netlink socket: %s", strerror(errno));
nd_sio_close(ndL_sio);
ndL_sio = NULL;
nd_io_close(ndL_io);
ndL_io = NULL;
return false;
}
ndL_sio->handler = ndL_sio_handler;
ndL_io->handler = ndL_io_handler;
return true;
}
void nd_rtnl_cleanup()
{
if (ndL_sio)
nd_sio_close(ndL_sio);
if (ndL_io)
nd_io_close(ndL_io);
}
bool nd_rtnl_query_routes()
@ -290,7 +290,7 @@ bool nd_rtnl_query_routes()
nd_rtnl_dump_timeout = nd_current_time + 5000;
nd_sio_send(ndL_sio, (struct sockaddr *)&addr, sizeof(addr), &req, sizeof(req));
nd_io_send(ndL_io, (struct sockaddr *)&addr, sizeof(addr), &req, sizeof(req));
return false;
}
@ -320,7 +320,7 @@ bool nd_rtnl_query_addresses()
nd_rtnl_dump_timeout = nd_current_time + 5000;
nd_sio_send(ndL_sio, (struct sockaddr *)&addr, sizeof(addr), &req, sizeof(req));
nd_io_send(ndL_io, (struct sockaddr *)&addr, sizeof(addr), &req, sizeof(req));
return false;
}