]> git.decadent.org.uk Git - odhcp6c.git/blobdiff - src/dhcpv6.c
Fix DNS-server parsing with more than one server
[odhcp6c.git] / src / dhcpv6.c
index 9cb55adc28b935de24d254e8014481558c6ba183..93433d4d59ce5e4b945fec9904e6d4d3feba5057 100644 (file)
@@ -110,6 +110,27 @@ int init_dhcpv6(const char *ifname, int request_pd)
                uint8_t duid[14] = {0, DHCPV6_OPT_CLIENTID, 0, 10, 0,
                                DHCPV6_DUID_LLADDR, 0, 1};
                memcpy(&duid[8], ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
+
+               uint8_t zero[ETHER_ADDR_LEN] = {0, 0, 0, 0, 0, 0};
+               struct ifreq ifs[100], *ifp, *ifend;
+               struct ifconf ifc;
+               ifc.ifc_req = ifs;
+               ifc.ifc_len = sizeof(ifs);
+
+               if (!memcmp(&duid[8], zero, ETHER_ADDR_LEN) &&
+                               ioctl(sock, SIOCGIFCONF, &ifc) >= 0) {
+                       // If our interface doesn't have an address...
+                       ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
+                       for (ifp = ifc.ifc_req; ifp < ifend &&
+                                       !memcmp(&duid[8], zero, 6); ifp++) {
+                               memcpy(ifr.ifr_name, ifp->ifr_name,
+                                               sizeof(ifr.ifr_name));
+                               ioctl(sock, SIOCGIFHWADDR, &ifr);
+                               memcpy(&duid[8], ifr.ifr_hwaddr.sa_data,
+                                               ETHER_ADDR_LEN);
+                       }
+               }
+
                odhcp6c_add_state(STATE_CLIENT_ID, duid, sizeof(duid));
        }
 
@@ -654,7 +675,7 @@ static int dhcpv6_handle_reply(_unused enum dhcpv6_msg orig,
                                t3 = n;
 
                } else if (otype == DHCPV6_OPT_DNS_SERVERS) {
-                       if (olen == 16)
+                       if (olen % 16 == 0)
                                odhcp6c_add_state(STATE_DNS, odata, olen);
                } else if (otype == DHCPV6_OPT_DNS_DOMAIN) {
                        odhcp6c_add_state(STATE_SEARCH, odata, olen);