From f0e0d767f3b472cfb7294bd290d918f980ef8c2d Mon Sep 17 00:00:00 2001 From: Daniel Adolfsson Date: Thu, 12 Dec 2019 00:01:46 +0100 Subject: [PATCH] Refactor how the AF_PACKET socket is used --- src/iface.c | 122 ++++++++++++++++++++------------------- src/iface.h | 3 +- src/{sio.c => io.c} | 135 +++++++++++++++++++++++++++++--------------- src/{sio.h => io.h} | 31 +++++----- src/ndppd.c | 10 ++-- src/ndppd.h | 2 +- src/rtnl.c | 28 ++++----- 7 files changed, 189 insertions(+), 142 deletions(-) rename src/{sio.c => io.c} (63%) rename src/{sio.h => io.h} (54%) diff --git a/src/iface.c b/src/iface.c index 91be2ad..653a3b6 100644 --- a/src/iface.c +++ b/src/iface.c @@ -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); } diff --git a/src/iface.h b/src/iface.h index 006449e..1d6e18d 100644 --- a/src/iface.h +++ b/src/iface.h @@ -20,6 +20,7 @@ #define NDPPD_IFACE_H #include "ndppd.h" + #include 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 */ diff --git a/src/sio.c b/src/io.c similarity index 63% rename from src/sio.c rename to src/io.c index ce58fbd..f790ced 100644 --- a/src/sio.c +++ b/src/io.c @@ -24,6 +24,7 @@ #include #ifndef NDPPD_NO_USE_EPOLL +# include # include #else # include @@ -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) + io->fd = fd; + io->data = 0; + io->handler = NULL; + + return io; +} + +static nd_io_t *ndL_create(int fd) +{ + int flags = fcntl(fd, F_GETFL, 0); + + if (flags == -1) { + nd_log_error("Could not read flags: %s", strerror(errno)); close(fd); - return NULL; + return false; } - /* Allocate the nd_sio_t object. */ + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) + { + nd_log_error("Could not set flags: %s", strerror(errno)); + close(fd); + return false; + } - nd_sio_t *sio = ndL_first_free_sio; + nd_io_t *io = ndL_first_free_io; - if (sio) - ND_LL_DELETE(ndL_first_free_sio, sio, next); + 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 } diff --git a/src/sio.h b/src/io.h similarity index 54% rename from src/sio.h rename to src/io.h index 6d14c73..27e4c8d 100644 --- a/src/sio.h +++ b/src/io.h @@ -16,27 +16,30 @@ * You should have received a copy of the GNU General Public License * along with ndppd. If not, see . */ -#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*/ diff --git a/src/ndppd.c b/src/ndppd.c index 1a6e06d..7f70942 100644 --- a/src/ndppd.c +++ b/src/ndppd.c @@ -28,14 +28,12 @@ #include #include -#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; diff --git a/src/ndppd.h b/src/ndppd.h index ea61d0c..3815ee1 100644 --- a/src/ndppd.h +++ b/src/ndppd.h @@ -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; diff --git a/src/rtnl.c b/src/rtnl.c index d58f869..5227735 100644 --- a/src/rtnl.c +++ b/src/rtnl.c @@ -22,11 +22,11 @@ #include #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; }