dhcpv4: detect noarp interfaces
[project/odhcpd.git] / src / odhcpd.c
index bb7aba64f1a9b2d6a88a386138336e4ac03e42a3..554e5f1c0b880b3da4bd0eeb56c2949522b55d13 100644 (file)
@@ -43,9 +43,7 @@
 #include <libubox/uloop.h>
 #include "odhcpd.h"
 
-
-
-static int ioctl_sock;
+static int ioctl_sock = -1;
 static int urandom_fd = -1;
 
 static void sighandler(_unused int signal)
@@ -141,8 +139,8 @@ int main(int argc, char **argv)
 int odhcpd_get_interface_config(const char *ifname, const char *what)
 {
        char buf[64];
-       const char *sysctl_pattern = "/proc/sys/net/ipv6/conf/%s/%s";
-       snprintf(buf, sizeof(buf), sysctl_pattern, ifname, what);
+       
+       snprintf(buf, sizeof(buf), "/proc/sys/net/ipv6/conf/%s/%s", ifname, what);
 
        int fd = open(buf, O_RDONLY);
        if (fd < 0)
@@ -173,6 +171,18 @@ int odhcpd_get_mac(const struct interface *iface, uint8_t mac[6])
        return 0;
 }
 
+int odhcpd_get_flags(const struct interface *iface)
+{
+       struct ifreq ifr;
+
+       memset(&ifr, 0, sizeof(ifr));
+       strncpy(ifr.ifr_name, iface->ifname, sizeof(ifr.ifr_name) - 1);
+       if (ioctl(ioctl_sock, SIOCGIFFLAGS, &ifr) < 0)
+               return -1;
+
+       return ifr.ifr_flags;
+}
+
 
 /* Forwards a packet on a specific interface */
 ssize_t odhcpd_send(int socket, struct sockaddr_in6 *dest,
@@ -209,11 +219,11 @@ ssize_t odhcpd_send(int socket, struct sockaddr_in6 *dest,
 
        ssize_t sent = sendmsg(socket, &msg, MSG_DONTWAIT);
        if (sent < 0)
-               syslog(LOG_NOTICE, "Failed to send to %s%%%s (%m)",
-                               ipbuf, iface->ifname);
+               syslog(LOG_ERR, "Failed to send to %s%%%s@%s (%m)",
+                               ipbuf, iface->name, iface->ifname);
        else
-               syslog(LOG_DEBUG, "Sent %li bytes to %s%%%s",
-                               (long)sent, ipbuf, iface->ifname);
+               syslog(LOG_DEBUG, "Sent %zd bytes to %s%%%s@%s",
+                               sent, ipbuf, iface->name, iface->ifname);
        return sent;
 }
 
@@ -255,6 +265,9 @@ int odhcpd_get_interface_dns_addr(const struct interface *iface, struct in6_addr
        time_t now = odhcpd_time();
        ssize_t m = -1;
 
+       if (!iface->dns_service)
+               return -1;
+
        for (size_t i = 0; i < iface->addr6_len; ++i) {
                if (iface->addr6[i].valid <= (uint32_t)now)
                        continue;
@@ -291,36 +304,15 @@ int odhcpd_get_interface_dns_addr(const struct interface *iface, struct in6_addr
 struct interface* odhcpd_get_interface_by_index(int ifindex)
 {
        struct interface *iface;
-       list_for_each_entry(iface, &interfaces, head)
-               if (iface->ifindex == ifindex)
-                       return iface;
 
-       return NULL;
-}
-
-
-struct interface* odhcpd_get_interface_by_name(const char *name)
-{
-       struct interface *iface;
-       list_for_each_entry(iface, &interfaces, head)
-               if (!strcmp(iface->ifname, name))
-                       return iface;
-
-       return NULL;
-}
-
-
-struct interface* odhcpd_get_master_interface(void)
-{
-       struct interface *iface;
-       list_for_each_entry(iface, &interfaces, head)
-               if (iface->master)
+       avl_for_each_element(&interfaces, iface, avl) {
+               if (iface->ifindex == ifindex)
                        return iface;
+       }
 
        return NULL;
 }
 
-
 /* Convenience function to receive and do basic validation of packets */
 static void odhcpd_receive_packets(struct uloop_fd *u, _unused unsigned int events)
 {
@@ -411,18 +403,19 @@ static void odhcpd_receive_packets(struct uloop_fd *u, _unused unsigned int even
 
                /* From netlink */
                if (addr.nl.nl_family == AF_NETLINK) {
-                       syslog(LOG_DEBUG, "Received %li Bytes from %s%%%s", (long)len,
-                                       ipbuf, "netlink");
+                       syslog(LOG_DEBUG, "Received %zd Bytes from %s%%netlink", len,
+                                       ipbuf);
                        e->handle_dgram(&addr, data_buf, len, NULL, dest);
                        return;
                } else if (destiface != 0) {
                        struct interface *iface;
-                       list_for_each_entry(iface, &interfaces, head) {
+
+                       avl_for_each_element(&interfaces, iface, avl) {
                                if (iface->ifindex != destiface)
                                        continue;
 
-                               syslog(LOG_DEBUG, "Received %li Bytes from %s%%%s", (long)len,
-                                               ipbuf, iface->ifname);
+                               syslog(LOG_DEBUG, "Received %zd Bytes from %s%%%s@%s", len,
+                                               ipbuf, iface->name, iface->ifname);
 
                                e->handle_dgram(&addr, data_buf, len, iface, dest);
                        }
@@ -460,7 +453,7 @@ int odhcpd_urandom(void *data, size_t len)
 time_t odhcpd_time(void)
 {
        struct timespec ts;
-       syscall(SYS_clock_gettime, CLOCK_MONOTONIC, &ts);
+       clock_gettime(CLOCK_MONOTONIC, &ts);
        return ts.tv_sec;
 }