Detect a suitable MAC if the main interface doesn't have one (e.g. ppp)
authorSteven Barth <steven@midlink.org>
Thu, 17 Jan 2013 07:53:48 +0000 (08:53 +0100)
committerSteven Barth <steven@midlink.org>
Thu, 17 Jan 2013 07:53:48 +0000 (08:53 +0100)
src/dhcpv6.c

index 9cb55adc28b935de24d254e8014481558c6ba183..a3d4223404688dc9234be1753b7e3ccc2f4b9919 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));
        }