From 6ca5a4e867e564926b5d64667f9c63078fb63ccf Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Thu, 19 May 2016 15:10:26 +0000 Subject: [PATCH] Provide a better getifaddrs(3). --- if-sun.c | 30 ++++++++++++++++++++++++------ if.c | 15 ++------------- if.h | 4 +++- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/if-sun.c b/if-sun.c index 33ce9ab7..7b49bde9 100644 --- a/if-sun.c +++ b/if-sun.c @@ -37,6 +37,10 @@ #include +/* private interface we can hook into to get + * a better getifaddrs(3). */ +#include + #include #include @@ -192,6 +196,7 @@ if_newaddr(const char *ifname, void *arg) goto failed; ifa->ifa_addr = (struct sockaddr *)sdl; + sdl->sdl_index = if_nametoindex(ifname); sdl->sdl_family = AF_LINK; switch (dlinfo.di_mactype) { case DL_ETHER: @@ -247,20 +252,26 @@ if_ifa_lo0(void) ifa->ifa_addr = (struct sockaddr *)sdl; ifa->ifa_flags = IFF_LOOPBACK; sdl->sdl_family = AF_LINK; + sdl->sdl_index = if_nametoindex("lo0"); return ifa; } -/* all getifaddrs(3) should support AF_LINK, but hey ho */ +/* getifaddrs(3) does not support AF_LINK, strips aliases and won't + * report addresses that are not UP. + * As such it's just totally useless, so we need to roll our own. */ int if_getifaddrs(struct ifaddrs **ifap) { struct linkwalk lw; + struct ifaddrs *ifa; - /* lo0 doesn't appear in dlpi_walk, so fudge it. */ - if ((lw.lw_ifa = if_ifa_lo0()) == NULL) + /* Private libc function which we should not have to call + * to get non UP addresses. */ + if (getallifaddrs(AF_UNSPEC, &lw.lw_ifa, 0) == -1) return -1; + /* Start with some AF_LINK addresses. */ lw.lw_error = 0; dlpi_walk(if_newaddr, &lw, 0); if (lw.lw_error != 0) { @@ -269,7 +280,14 @@ if_getifaddrs(struct ifaddrs **ifap) return -1; } - *ifap = lw.lw_ifa; + /* lo0 doesn't appear in dlpi_walk, so fudge it. */ + if ((ifa = if_ifa_lo0()) == NULL) { + freeifaddrs(lw.lw_ifa); + return -1; + } + ifa->ifa_next = lw.lw_ifa; + + *ifap = ifa; return 0; } @@ -546,7 +564,7 @@ if_readraw(struct interface *ifp, int fd, } int -if_address(unsigned char cmd, struct ipv4_addr *ia) +if_address(unsigned char cmd, const struct ipv4_addr *ia) { UNUSED(cmd); @@ -645,7 +663,7 @@ if_address6(unsigned char cmd, const struct ipv6_addr *ia) { UNUSED(cmd); - UNUSED(action); + UNUSED(ia); errno = ENOTSUP; return -1; } diff --git a/if.c b/if.c index 99ac3ca5..67f04043 100644 --- a/if.c +++ b/if.c @@ -270,13 +270,9 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv) const struct sockaddr_ll *sll; #endif -#ifdef GETIFADDRS_AFLINK - if (getifaddrs(&ifaddrs) == -1) - return NULL; -#else if (if_getifaddrs(&ifaddrs) == -1) return NULL; -#endif + ifs = malloc(sizeof(*ifs)); if (ifs == NULL) return NULL; @@ -553,15 +549,8 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv) TAILQ_INSERT_TAIL(ifs, ifp, next); } -#ifdef GETIFADDRS_AFLINK - { -#else + if_learnaddrs(ctx, ifs, ifaddrs); freeifaddrs(ifaddrs); - if (getifaddrs(&ifaddrs) != -1) { -#endif - if_learnaddrs(ctx, ifs, ifaddrs); - freeifaddrs(ifaddrs); - } return ifs; } diff --git a/if.h b/if.h index 078cc8ad..ab4bb3c1 100644 --- a/if.h +++ b/if.h @@ -83,9 +83,11 @@ #define RAW_PARTIALCSUM 1 << 0 #ifdef __sun -/* platform does not supply AF_LINK with getifaddrs. */ +/* Solaris getifaddrs is very un-suitable for dhcpcd. + * See if-sun.c for details why. */ struct ifaddrs; int if_getifaddrs(struct ifaddrs **); +#define getifaddrs if_getaddrs #else #define GETIFADDRS_AFLINK #endif -- 2.47.3