diff --git a/src/bpf.c b/src/bpf.c index 789c718..2cd9ada 100644 --- a/src/bpf.c +++ b/src/bpf.c @@ -108,6 +108,10 @@ int iface_enumerate(int family, void *parm, int (*callback)()) return 0; /* need code for Solaris and MacOS*/ #endif + /* AF_LINK doesn't exist in Linux, so we can't use it in our API */ + if (family == AF_LOCAL) + family = AF_LINK; + if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1) return 0; @@ -154,24 +158,6 @@ int iface_enumerate(int family, void *parm, int (*callback)()) ifr = (struct ifreq *)ifreq.iov_base; memcpy(ifr, ptr, len); -#ifdef HAVE_DHCP6 - if (family == AF_LOCAL) - { - unsigned int flags; - if (ioctl(fd, SIOCGIFFLAGS, ifr) != -1) - { - flags = ifr->ifr_flags; - ifr->ifr_addr.sa_family = AF_LINK; - if (ioctl(fd, SIOCGIFADDR, ifr) != -1 && - !((*callback)((unsigned int)htons(ETHERTYPE_IP), - flags, - LLADDR((struct sockaddr_dl *)&ifr->ifr_addr), ETHER_ADDR_LEN, parm))) - goto err; - } - continue; - } -#endif - if (ifr->ifr_addr.sa_family == family) { if (family == AF_INET) @@ -208,6 +194,15 @@ int iface_enumerate(int family, void *parm, int (*callback)()) goto err; } #endif +#ifdef HAVE_DHCP6 + else if (family == AF_LINK) + { + /* Assume ethernet again here */ + struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr; + if (sdl->sdl_alen != 0 && !((*callback)(ARPHRD_ETHER, LLADDR(sdl), sdl->sdl_alen, parm))) + goto err; + } +#endif } } diff --git a/src/dhcp6.c b/src/dhcp6.c index 27f22b1..c8fe2ef 100644 --- a/src/dhcp6.c +++ b/src/dhcp6.c @@ -34,8 +34,7 @@ static int join_multicast(struct in6_addr *local, int prefix, static int complete_context6(struct in6_addr *local, int prefix, int scope, int if_index, int dad, void *vparam); -static int make_duid1(unsigned int type, unsigned int flags, char *mac, - size_t maclen, void *parm); +static int make_duid1(unsigned int type, char *mac, size_t maclen, void *parm); void dhcp6_init(void) { @@ -477,26 +476,23 @@ void make_duid(time_t now) { /* rebase epoch to 1/1/2000 */ time_t newnow = now - 946684800; + iface_enumerate(AF_LOCAL, &newnow, make_duid1); - - if (!daemon->duid) - die("Cannot create DHCPv6 server DUID", NULL, EC_MISC); + + if(!daemon->duid) + die("Cannot create DHCPv6 server DUID: %s", NULL, EC_MISC); } -static int make_duid1(unsigned int type, unsigned int flags, char *mac, - size_t maclen, void *parm) +static int make_duid1(unsigned int type, char *mac, size_t maclen, void *parm) { /* create DUID as specified in RFC3315. We use the MAC of the first interface we find that isn't loopback or P-to-P */ unsigned char *p; - if (flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) - return 1; - daemon->duid = p = safe_malloc(maclen + 8); daemon->duid_len = maclen + 8; - + #ifdef HAVE_BROKEN_RTC PUTSHORT(3, p); /* DUID_LL */ #else diff --git a/src/lease.c b/src/lease.c index b5f9926..4fdf226 100644 --- a/src/lease.c +++ b/src/lease.c @@ -147,12 +147,6 @@ void lease_init(time_t now) the startup synthesised SIGHUP. */ lease->flags &= ~(LEASE_NEW | LEASE_CHANGED); } - -#ifdef HAVE_DHCP6 - /* If we're not doing DHCPv6, and there are not v6 leases, don't add the DUID to the database */ - if (!daemon->duid && daemon->dhcp6) - make_duid(now); -#endif #ifdef HAVE_SCRIPT if (!daemon->lease_stream) @@ -181,6 +175,16 @@ void lease_init(time_t now) file_dirty = 0; lease_prune(NULL, now); dns_dirty = 1; + +#ifdef HAVE_DHCP6 + /* If we're not doing DHCPv6, and there are not v6 leases, don't add the DUID to the database */ + if (!daemon->duid && daemon->dhcp6) + { + file_dirty = 1; + make_duid(now); + } +#endif + } void lease_update_from_configs(void) diff --git a/src/netlink.c b/src/netlink.c index d6515d4..f4e9402 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -282,9 +282,8 @@ int iface_enumerate(int family, void *parm, int (*callback)()) rta = RTA_NEXT(rta, len1); } - if (mac && !((*callback)((unsigned int)link->ifi_type, - (unsigned int)link->ifi_flags, - mac, maclen, parm))) + if (mac && !((link->ifi_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) && + !((*callback)((unsigned int)link->ifi_type, mac, maclen, parm))) return 0; } #endif