Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -1444,12 +1444,21 @@ ]) AC_CHECK_HEADER(netinet/tcp.h, [ AC_DEFINE(OF_HAVE_NETINET_TCP_H, 1, [Whether we have netinet/tcp.h]) ]) - AC_CHECK_HEADERS([arpa/inet.h netdb.h net/if.h]) + AC_CHECK_HEADERS([arpa/inet.h netdb.h]) + AC_CHECK_HEADERS([net/if.h net/if_arp.h net/if_dl.h net/if_types.h]) AC_CHECK_FUNCS([if_indextoname if_nametoindex]) + AC_CHECK_TYPES([struct sockaddr_dl], [], [], [ + #ifdef HAVAE_SYS_TYPES_H + # include + #endif + #ifdef HAVE_NET_IF_DL_H + # include + #endif + ]) AC_CHECK_HEADER(sys/un.h, [ AC_DEFINE(OF_HAVE_SYS_UN_H, 1, [Whether we have sys/un.h]) ]) AC_CHECK_MEMBER([struct sockaddr_in6.sin6_addr], [ AC_EGREP_CPP(egrep_cpp_yes, [ Index: src/platform/POSIX/OFSystemInfo+NetworkInterfaces.m ================================================================== --- src/platform/POSIX/OFSystemInfo+NetworkInterfaces.m +++ src/platform/POSIX/OFSystemInfo+NetworkInterfaces.m @@ -22,10 +22,19 @@ # include #endif #ifdef HAVE_NET_IF_H # include #endif +#ifdef HAVE_NET_IF_ARP_H +# include +#endif +#ifdef HAVE_NET_IF_DL_H +# include +#endif +#ifdef HAVE_NET_IF_TYPES_H +# include +#endif #import "OFSystemInfo.h" #import "OFSystemInfo+NetworkInterfaces.h" #import "OFArray.h" #import "OFData.h" @@ -316,19 +325,85 @@ nameLength); if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) continue; - if (ifr.ifr_hwaddr.sa_family != 1) + if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) continue; hardwareAddress = [OFData dataWithItems: ifr.ifr_hwaddr.sa_data count: 6]; [[ret objectForKey: name] setObject: hardwareAddress forKey: OFNetworkInterfaceHardwareAddress]; } + + return true; +#elif defined(HAVE_IOCTL) && defined(HAVE_NET_IF_H) && \ + defined(HAVE_STRUCT_SOCKADDR_DL) + OFStringEncoding encoding = [OFLocale encoding]; + int sock = socket(AF_INET, SOCK_DGRAM, 0); + struct ifconf ifc; + struct ifreq *ifrs; + + if (sock < 0) + return false; + + ifrs = malloc(128 * sizeof(struct ifreq)); + if (ifrs == NULL) { + closesocket(sock); + return false; + } + + @try { + char *buffer; + + memset(&ifc, 0, sizeof(ifc)); + ifc.ifc_buf = (void *)ifrs; + ifc.ifc_len = 128 * sizeof(struct ifreq); + if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) + return false; + + buffer = ifc.ifc_buf; + while (buffer < (char *)ifc.ifc_buf + ifc.ifc_len) { + struct ifreq *current = (struct ifreq *)(void *)buffer; + struct sockaddr_dl *sdl; + OFString *name; + OFMutableDictionary *interface; + OFData *hardwareAddress; + + if (current->ifr_addr.sa_family != AF_LINK) + goto next; + + sdl = (struct sockaddr_dl *)(void *)¤t->ifr_addr; + if (sdl->sdl_type != IFT_ETHER) + goto next; + + name = [OFString stringWithCString: current->ifr_name + encoding: encoding]; + if ((interface = [ret objectForKey: name]) == nil) { + interface = [OFMutableDictionary dictionary]; + [ret setObject: interface forKey: name]; + } + + hardwareAddress = [OFData dataWithItems: LLADDR(sdl) + count: sdl->sdl_alen]; + [interface + setObject: hardwareAddress + forKey: OFNetworkInterfaceHardwareAddress]; + +next: +# ifdef _SIZEOF_ADDR_IFREQ + buffer += _SIZEOF_ADDR_IFREQ(*current); +# else + buffer += sizeof(struct ifreq); +# endif + } + } @finally { + free(ifrs); + closesocket(sock); + } return true; #else return false; #endif