diff options
| author | Roy Marples <roy@marples.name> | 2016-05-19 15:10:26 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2016-05-19 15:10:26 +0000 |
| commit | 6ca5a4e867e564926b5d64667f9c63078fb63ccf (patch) | |
| tree | d783f1ff3b2cbb58baf7a019294754af4870746c | |
| parent | 58153b6af284231c148f428521f9283575e5ac9a (diff) | |
| download | dhcpcd-6ca5a4e867e564926b5d64667f9c63078fb63ccf.tar.xz | |
Provide a better getifaddrs(3).
| -rw-r--r-- | if-sun.c | 30 | ||||
| -rw-r--r-- | if.c | 15 | ||||
| -rw-r--r-- | if.h | 4 |
3 files changed, 29 insertions, 20 deletions
@@ -37,6 +37,10 @@ #include <inet/ip.h> +/* private interface we can hook into to get + * a better getifaddrs(3). */ +#include <libsocket_priv.h> + #include <net/if_dl.h> #include <net/if_types.h> @@ -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; } @@ -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; } @@ -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 |
