summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2016-05-19 15:10:26 +0000
committerRoy Marples <roy@marples.name>2016-05-19 15:10:26 +0000
commit6ca5a4e867e564926b5d64667f9c63078fb63ccf (patch)
treed783f1ff3b2cbb58baf7a019294754af4870746c
parent58153b6af284231c148f428521f9283575e5ac9a (diff)
downloaddhcpcd-6ca5a4e867e564926b5d64667f9c63078fb63ccf.tar.xz
Provide a better getifaddrs(3).
-rw-r--r--if-sun.c30
-rw-r--r--if.c15
-rw-r--r--if.h4
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 <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 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