Merge pull request #20 from mehlis/implement-dhcp4-router-config
[project/odhcpd.git] / src / router.c
index ddec21e..a45a8cb 100644 (file)
@@ -30,7 +30,7 @@ static void forward_router_solicitation(const struct interface *iface);
 static void forward_router_advertisement(uint8_t *data, size_t len);
 
 static void handle_icmpv6(void *addr, void *data, size_t len,
-               struct interface *iface);
+               struct interface *iface, void *dest);
 static void send_router_advert(struct uloop_timeout *event);
 static void sigusr1_refresh(int signal);
 
@@ -88,6 +88,9 @@ int init_router(void)
 
 int setup_router_interface(struct interface *iface, bool enable)
 {
+       if (!fp_route || router_event.uloop.fd < 0)
+               return -1;
+
        struct ipv6_mreq all_nodes = {ALL_IPV6_NODES, iface->ifindex};
        struct ipv6_mreq all_routers = {ALL_IPV6_ROUTERS, iface->ifindex};
 
@@ -167,7 +170,7 @@ static bool router_icmpv6_valid(struct sockaddr_in6 *source, uint8_t *data, size
 
 // Event handler for incoming ICMPv6 packets
 static void handle_icmpv6(void *addr, void *data, size_t len,
-               struct interface *iface)
+               struct interface *iface, _unused void *dest)
 {
        struct icmp6_hdr *hdr = data;
 
@@ -276,7 +279,7 @@ static void send_router_advert(struct uloop_timeout *event)
        bool have_public = false;
        size_t cnt = 0;
 
-       struct in6_addr dns_pref, *dns_addr = &dns_pref;
+       struct in6_addr dns_pref = IN6ADDR_ANY_INIT, *dns_addr = &dns_pref;
        uint32_t dns_time = 0;
        size_t dns_cnt = 1;
 
@@ -344,7 +347,7 @@ static void send_router_advert(struct uloop_timeout *event)
                dns_time = 2 * MaxRtrAdvInterval;
        }
 
-       if (!dns_addr)
+       if (!dns_addr || IN6_IS_ADDR_UNSPECIFIED(dns_addr))
                dns_cnt = 0;
 
        struct {
@@ -407,7 +410,8 @@ static void send_router_advert(struct uloop_timeout *event)
 
        for (ssize_t i = 0; i < ipcnt; ++i) {
                struct odhcpd_ipaddr *addr = &addrs[i];
-               if (addr->dprefix > 64 || addr->dprefix == 0) {
+               if (addr->dprefix > 64 || addr->dprefix == 0 ||
+                               (addr->dprefix == 64 && addr->prefix == 64)) {
                        continue; // Address not suitable
                } else if (addr->dprefix > 32) {
                        addr->addr.s6_addr32[1] &= htonl(~((1U << (64 - addr->dprefix)) - 1));