#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>
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:
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) {
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;
}
}
int
-if_address(unsigned char cmd, struct ipv4_addr *ia)
+if_address(unsigned char cmd, const struct ipv4_addr *ia)
{
UNUSED(cmd);
{
UNUSED(cmd);
- UNUSED(action);
+ UNUSED(ia);
errno = ENOTSUP;
return -1;
}
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;
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;
}
#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