]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Provide a better getifaddrs(3).
authorRoy Marples <roy@marples.name>
Thu, 19 May 2016 15:10:26 +0000 (15:10 +0000)
committerRoy Marples <roy@marples.name>
Thu, 19 May 2016 15:10:26 +0000 (15:10 +0000)
if-sun.c
if.c
if.h

index 33ce9ab7213d5153dc96ffe401b9c904829d40b4..7b49bde90aebf9e7d7f034f3062ae6b005251880 100644 (file)
--- a/if-sun.c
+++ b/if-sun.c
 
 #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;
 }
diff --git a/if.c b/if.c
index 99ac3ca526c4e0fe1dfc2e1b5b869b97e1367a7d..67f040430366d35c8493dc035b9392d0bb1a30d9 100644 (file)
--- 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 078cc8adca98efe20caaf08be381392686ab643d..ab4bb3c1229bbb62ecab7011750d939e2c232809 100644 (file)
--- a/if.h
+++ b/if.h
 #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