From 73275cc872669d4c6702bfe7dcf674d3f4d1b1c8 Mon Sep 17 00:00:00 2001 From: dmiller Date: Tue, 9 Sep 2014 21:19:08 +0000 Subject: [PATCH] dnet: Fix hw address getting on AIX --- libdnet-stripped/src/intf.c | 43 ++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/libdnet-stripped/src/intf.c b/libdnet-stripped/src/intf.c index 184c077af..2df6a4da4 100644 --- a/libdnet-stripped/src/intf.c +++ b/libdnet-stripped/src/intf.c @@ -20,6 +20,10 @@ # include #endif /* XXX - AIX */ +#ifdef HAVE_GETKERNINFO +#include +#include +#endif #ifndef IP_MULTICAST # define IP_MULTICAST #endif @@ -477,6 +481,11 @@ static int _intf_get_noalias(intf_t *intf, struct intf_entry *entry) { struct ifreq ifr; +#ifdef HAVE_GETKERNINFO + int size; + struct kinfo_ndd *nddp; + void *end; +#endif /* Get interface index. */ entry->intf_index = if_nametoindex(entry->intf_name); @@ -517,7 +526,39 @@ _intf_get_noalias(intf_t *intf, struct intf_entry *entry) return (-1); } } else if (entry->intf_type == INTF_TYPE_ETH) { -#if defined(SIOCGIFHWADDR) +#if defined(HAVE_GETKERNINFO) + /* AIX also defines SIOCGIFHWADDR, but it fails silently? + * This is the method IBM recommends here: + * http://www-01.ibm.com/support/knowledgecenter/ssw_aix_53/com.ibm.aix.progcomm/doc/progcomc/skt_sndother_ex.htm%23ssqinc2joyc?lang=en + */ + /* How many bytes will be returned? */ + size = getkerninfo(KINFO_NDD, 0, 0, 0); + if (size <= 0) { + return -1; + } + nddp = (struct kinfo_ndd *)malloc(size); + + if (!nddp) { + return -1; + } + /* Get all Network Device Driver (NDD) info */ + if (getkerninfo(KINFO_NDD, nddp, &size, 0) < 0) { + free(nddp); + return -1; + } + /* Loop over the returned values until we find a match */ + end = (void *)nddp + size; + while ((void *)nddp < end) { + if (!strcmp(nddp->ndd_alias, entry->intf_name) || + !strcmp(nddp->ndd_name, entry->intf_name)) { + addr_pack(&entry->intf_link_addr, ADDR_TYPE_ETH, ETH_ADDR_BITS, + nddp->ndd_addr, ETH_ADDR_LEN); + break; + } else + nddp++; + } + free(nddp); +#elif defined(SIOCGIFHWADDR) if (ioctl(intf->fd, SIOCGIFHWADDR, &ifr) < 0) return (-1); if (addr_ston(&ifr.ifr_addr, &entry->intf_link_addr) < 0)