ubus: fix invalid ipv6-prefix json
[project/odhcpd.git] / src / odhcpd.c
index 5f87151..8aa4571 100644 (file)
@@ -110,8 +110,10 @@ int main(int argc, char **argv)
        if (ndp_init())
                return 4;
 
+#ifdef DHCPV4_SUPPORT
        if (dhcpv4_init())
                return 4;
+#endif
 
        odhcpd_run();
        return 0;
@@ -141,10 +143,12 @@ int odhcpd_get_interface_config(const char *ifname, const char *what)
 int odhcpd_get_mac(const struct interface *iface, uint8_t mac[6])
 {
        struct ifreq ifr;
+
        memset(&ifr, 0, sizeof(ifr));
-       strncpy(ifr.ifr_name, iface->ifname, sizeof(ifr.ifr_name));
+       strncpy(ifr.ifr_name, iface->ifname, sizeof(ifr.ifr_name) - 1);
        if (ioctl(ioctl_sock, SIOCGIFHWADDR, &ifr) < 0)
                return -1;
+
        memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
        return 0;
 }
@@ -185,8 +189,8 @@ 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 (%s)",
-                               ipbuf, iface->ifname, strerror(errno));
+               syslog(LOG_NOTICE, "Failed to send to %s%%%s (%m)",
+                               ipbuf, iface->ifname);
        else
                syslog(LOG_DEBUG, "Sent %li bytes to %s%%%s",
                                (long)sent, ipbuf, iface->ifname);
@@ -224,8 +228,8 @@ int odhcpd_get_interface_dns_addr(const struct interface *iface, struct in6_addr
        time_t now = odhcpd_time();
        ssize_t m = -1;
 
-       for (size_t i = 0; i < iface->ia_addr_len; ++i) {
-               if (iface->ia_addr[i].valid <= (uint32_t)now)
+       for (size_t i = 0; i < iface->addr6_len; ++i) {
+               if (iface->addr6[i].valid <= (uint32_t)now)
                        continue;
 
                if (m < 0) {
@@ -233,24 +237,24 @@ int odhcpd_get_interface_dns_addr(const struct interface *iface, struct in6_addr
                        continue;
                }
 
-               if (iface->ia_addr[m].preferred >= (uint32_t)now &&
-                               iface->ia_addr[i].preferred < (uint32_t)now)
+               if (iface->addr6[m].preferred >= (uint32_t)now &&
+                               iface->addr6[i].preferred < (uint32_t)now)
                        continue;
 
-               if (IN6_IS_ADDR_ULA(&iface->ia_addr[i].addr.in6)) {
-                       if (!IN6_IS_ADDR_ULA(&iface->ia_addr[m].addr.in6)) {
+               if (IN6_IS_ADDR_ULA(&iface->addr6[i].addr.in6)) {
+                       if (!IN6_IS_ADDR_ULA(&iface->addr6[m].addr.in6)) {
                                m = i;
                                continue;
                        }
-               } else if (IN6_IS_ADDR_ULA(&iface->ia_addr[m].addr.in6))
+               } else if (IN6_IS_ADDR_ULA(&iface->addr6[m].addr.in6))
                        continue;
 
-               if (iface->ia_addr[i].preferred > iface->ia_addr[m].preferred)
+               if (iface->addr6[i].preferred > iface->addr6[m].preferred)
                        m = i;
        }
 
        if (m >= 0) {
-               *addr = iface->ia_addr[m].addr.in6;
+               *addr = iface->addr6[m].addr.in6;
                return 0;
        }
 
@@ -369,12 +373,6 @@ static void odhcpd_receive_packets(struct uloop_fd *u, _unused unsigned int even
                if (addr.ll.sll_family == AF_PACKET)
                        destiface = addr.ll.sll_ifindex;
 
-               struct interface *iface =
-                               odhcpd_get_interface_by_index(destiface);
-
-               if (!iface && addr.nl.nl_family != AF_NETLINK)
-                       continue;
-
                char ipbuf[INET6_ADDRSTRLEN] = "kernel";
                if (addr.ll.sll_family == AF_PACKET &&
                                len >= (ssize_t)sizeof(struct ip6_hdr))
@@ -384,10 +382,26 @@ static void odhcpd_receive_packets(struct uloop_fd *u, _unused unsigned int even
                else if (addr.in.sin_family == AF_INET)
                        inet_ntop(AF_INET, &addr.in.sin_addr, ipbuf, sizeof(ipbuf));
 
-               syslog(LOG_DEBUG, "Received %li Bytes from %s%%%s", (long)len,
-                               ipbuf, (iface) ? iface->ifname : "netlink");
+               // From netlink
+               if (addr.nl.nl_family == AF_NETLINK) {
+                       syslog(LOG_DEBUG, "Received %li Bytes from %s%%%s", (long)len,
+                                       ipbuf, "netlink");
+                       e->handle_dgram(&addr, data_buf, len, NULL, dest);
+                       return;
+               } else if (destiface != 0) {
+                       struct interface *iface;
+                       list_for_each_entry(iface, &interfaces, head) {
+                               if (iface->ifindex != destiface)
+                                       continue;
+
+                               syslog(LOG_DEBUG, "Received %li Bytes from %s%%%s", (long)len,
+                                               ipbuf, iface->ifname);
+
+                               e->handle_dgram(&addr, data_buf, len, iface, dest);
+                       }
+               }
+
 
-               e->handle_dgram(&addr, data_buf, len, iface, dest);
        }
 }
 
@@ -464,6 +478,16 @@ void odhcpd_hexlify(char *dst, const uint8_t *src, size_t len)
        *dst = 0;
 }
 
+const char *odhcpd_print_mac(const uint8_t *mac, const size_t len)
+{
+       static char buf[32];
+
+       snprintf(buf, sizeof(buf), "%02x", mac[0]);
+       for (size_t i = 1, j = 2; i < len && j < sizeof(buf); i++, j += 3)
+               snprintf(buf + j, sizeof(buf) - j, ":%02x", mac[i]);
+
+       return buf;
+}
 
 int odhcpd_bmemcmp(const void *av, const void *bv, size_t bits)
 {