Index: Doxyfile ================================================================== --- Doxyfile +++ Doxyfile @@ -35,14 +35,13 @@ OF_RETURNS_INNER_POINTER= \ OF_RETURNS_NOT_RETAINED= \ OF_RETURNS_RETAINED= \ OF_ROOT_CLASS= \ OF_SENTINEL= \ - OF_SYSTEM_INFO_HAS_NETWORK_INTERFACES \ OF_WARN_UNUSED_RESULT= \ OF_WEAK_UNAVAILABLE= \ SIGHUP \ SIGUSR1 \ SIGUSR2 MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = YES IGNORE_PREFIX = OF of_ Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -1767,16 +1767,13 @@ "OFSelectKernelEventObserver.m") ]) ;; esac - AC_CHECK_HEADERS(ifaddrs.h net/if_types.h net/if_dl.h) + AC_CHECK_HEADERS(net/if.h net/if_types.h net/if_dl.h) AC_CHECK_HEADERS(netpacket/packet.h) - AC_CHECK_FUNC(getifaddrs, [ - AC_DEFINE(OF_SYSTEM_INFO_HAS_NETWORK_INTERFACES, 1, - [Whether OFSystemInfo has network interfaces]) - ]) + AC_CHECK_FUNCS(if_nameindex) AC_CHECK_TYPES([struct sockaddr_dl], [], [], [ #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_NET_IF_DL_H Index: src/OFSystemInfo.h ================================================================== --- src/OFSystemInfo.h +++ src/OFSystemInfo.h @@ -19,37 +19,10 @@ OF_ASSUME_NONNULL_BEGIN @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFIRI; -#ifdef OF_SYSTEM_INFO_HAS_NETWORK_INTERFACES -/** - * @brief A key in the per-interface dictionary returned by - * @ref networkInterfaces. - * - * Possible keys are: - * - * * @ref OFNetworkInterfaceAddresses - * * @ref OFNetworkInterfaceEthernetAddress - */ -typedef OFConstantString *OFNetworkInterfaceInfoKey; - -/** - * @brief The addresses of a network interface. - * - * This maps to an @ref OFData of @ref OFSocketAddress. - */ -extern OFConstantString *const OFNetworkInterfaceAddresses; - -/** - * @brief The Ethernet address of a network interface. - * - * This maps to an @ref OFData. - */ -extern OFConstantString *const OFNetworkInterfaceEthernetAddress; -#endif - /** * @class OFSystemInfo OFSystemInfo.h ObjFW/OFSystemInfo.h * * @brief A class for querying information about the system. */ @@ -88,14 +61,13 @@ @property (class, readonly, nonatomic) bool supportsAltiVec; # endif # ifdef OF_WINDOWS @property (class, readonly, nonatomic, getter=isWindowsNT) bool windowsNT; # endif -# ifdef OF_SYSTEM_INFO_HAS_NETWORK_INTERFACES -@property (class, readonly, nonatomic) OFDictionary OF_GENERIC(OFString *, - OFDictionary OF_GENERIC(OFNetworkInterfaceInfoKey, id) *) - *networkInterfaces; +# ifdef OF_HAVE_SOCKETS +@property (class, readonly, nullable, nonatomic) + OFArray OF_GENERIC(OFString *) *networkInterfaces; # endif #endif /** * @brief Returns the size of a page. @@ -369,21 +341,20 @@ * @return Whether the application is running on Windows NT */ + (bool)isWindowsNT; #endif -#ifdef OF_SYSTEM_INFO_HAS_NETWORK_INTERFACES +#ifdef OF_HAVE_SOCKETS /** * @brief Returns the available (though not necessarily configured) network - * interfaces and information about them. + * interfaces. * - * @return The available network interfaces and information about them + * @return The available network interfaces */ -+ (OFDictionary OF_GENERIC(OFString *, OFDictionary - OF_GENERIC(OFNetworkInterfaceInfoKey, id) *) *)networkInterfaces; ++ (nullable OFArray OF_GENERIC(OFString *) *)networkInterfaces; #endif + (instancetype)alloc OF_UNAVAILABLE; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END Index: src/OFSystemInfo.m ================================================================== --- src/OFSystemInfo.m +++ src/OFSystemInfo.m @@ -28,12 +28,12 @@ #endif #if defined(OF_MACOS) || defined(OF_IOS) || defined(OF_NETBSD) # include #endif -#ifdef HAVE_IFADDRS_H -# include +#ifdef HAVE_NET_IF_H +# include #endif #ifdef HAVE_NET_IF_TYPES_H # include #endif #ifdef HAVE_NET_IF_DL_H @@ -71,10 +71,11 @@ #import "OFArray.h" #import "OFData.h" #import "OFDictionary.h" #import "OFIRI.h" #import "OFLocale.h" +#import "OFNumber.h" #import "OFOnce.h" #ifdef OF_HAVE_SOCKETS # import "OFSocket.h" #endif #import "OFString.h" @@ -128,17 +129,10 @@ struct X86Regs { uint32_t eax, ebx, ecx, edx; }; #endif -#ifdef OF_SYSTEM_INFO_HAS_NETWORK_INTERFACES -OFConstantString *const OFNetworkInterfaceAddresses = - @"OFNetworkInterfaceAddresses"; -OFConstantString *const OFNetworkInterfaceEthernetAddress = - @"OFNetworkInterfaceEthernetAddress"; -#endif - static size_t pageSize = 4096; static size_t numberOfCPUs = 1; static OFString *operatingSystemName = nil; static OFString *operatingSystemVersion = nil; @@ -842,141 +836,44 @@ { return !(GetVersion() & 0x80000000); } #endif -#ifdef OF_SYSTEM_INFO_HAS_NETWORK_INTERFACES -static OFSocketAddress -wrapSockaddr(struct sockaddr *sa) -{ - OFSocketAddress address; - - switch (sa->sa_family) { - case AF_INET: - address.family = OFSocketAddressFamilyIPv4; - memcpy(&address.sockaddr.ipx, sa, sizeof(struct sockaddr_in)); - address.length = (socklen_t)sizeof(struct sockaddr_in); - break; -# ifdef AF_INET6 - case AF_INET6: - address.family = OFSocketAddressFamilyIPv6; - memcpy(&address.sockaddr.ipx, sa, sizeof(struct sockaddr_in6)); - address.length = (socklen_t)sizeof(struct sockaddr_in6); - break; -# endif -# ifdef AF_IPX - case AF_IPX: - address.family = OFSocketAddressFamilyIPX; - memcpy(&address.sockaddr.ipx, sa, sizeof(struct sockaddr_ipx)); - address.length = (socklen_t)sizeof(struct sockaddr_ipx); - break; -# endif -# ifdef AF_APPLETALK - case AF_APPLETALK: - address.family = OFSocketAddressFamilyAppleTalk; - memcpy(&address.sockaddr.at, sa, sizeof(struct sockaddr_at)); - address.length = (socklen_t)sizeof(struct sockaddr_at); - break; -# endif - default: - address.family = OFSocketAddressFamilyUnknown; - memcpy(&address.sockaddr, sa, sizeof(struct sockaddr)); - address.length = sizeof(struct sockaddr); - break; - } - - return address; -} - -+ (OFDictionary OF_GENERIC(OFString *, OFDictionary - OF_GENERIC(OFNetworkInterfaceInfoKey, id) *) *)networkInterfaces -{ - OFMutableDictionary *interfaces = [OFMutableDictionary dictionary]; - OFStringEncoding encoding = [OFLocale encoding]; - struct ifaddrs *ifaddrs; - - if (getifaddrs(&ifaddrs) != 0) - return nil; - - @try { - for (struct ifaddrs *iter = ifaddrs; iter != NULL; - iter = iter->ifa_next) { - OFString *interfaceName = - [OFString stringWithCString: iter->ifa_name - encoding: encoding]; - OFMutableDictionary *interface; - OFMutableData *addresses; - OFSocketAddress address; - - interface = [interfaces objectForKey: interfaceName]; - if (interface == nil) { - interface = [OFMutableDictionary dictionary]; - [interfaces setObject: interface - forKey: interfaceName]; - } - - if (iter->ifa_addr == NULL) - continue; - -# if defined(HAVE_STRUCT_SOCKADDR_LL) && defined(AF_PACKET) - if (iter->ifa_addr->sa_family == AF_PACKET) { - const OFNetworkInterfaceInfoKey key = - OFNetworkInterfaceEthernetAddress; - struct sockaddr_ll *sll = (struct sockaddr_ll *) - (void *)iter->ifa_addr; - OFData *addr; - - /* ARP hardware address type 1 is Ethernet. */ - if (sll->sll_hatype != 1) - continue; - - addr = [OFData dataWithItems: sll->sll_addr - count: sll->sll_halen]; - [interface setObject: addr forKey: key]; - continue; - } -# endif -# if defined(HAVE_STRUCT_SOCKADDR_DL) && defined(AF_LINK) && \ - defined(IFT_ETHER) && defined(LLADDR) - if (iter->ifa_addr->sa_family == AF_LINK) { - const OFNetworkInterfaceInfoKey key = - OFNetworkInterfaceEthernetAddress; - struct sockaddr_dl *sdl = (struct sockaddr_dl *) - (void *)iter->ifa_addr; - OFData *addr; - - if (sdl->sdl_type != IFT_ETHER) - continue; - - addr = [OFData dataWithItems: LLADDR(sdl) - count: sdl->sdl_alen]; - [interface setObject: addr forKey: key]; - continue; - } -# endif - - addresses = [interface - objectForKey: OFNetworkInterfaceAddresses]; - if (addresses == nil) { - addresses = [OFMutableData - dataWithItemSize: sizeof(OFSocketAddress)]; - [interface - setObject: addresses - forKey: OFNetworkInterfaceAddresses]; - } - - address = wrapSockaddr(iter->ifa_addr); - [addresses addItem: &address]; - } - } @finally { - freeifaddrs(ifaddrs); - } - - return interfaces; +#ifdef OF_HAVE_SOCKETS ++ (OFArray OF_GENERIC(OFString *) *)networkInterfaces +{ +# ifdef HAVE_IF_NAMEINDEX + OFMutableArray *ret = [OFMutableArray array]; + void *pool = objc_autoreleasePoolPush(); + OFStringEncoding encoding = [OFLocale encoding]; + struct if_nameindex *nameindex = if_nameindex(); + + if (nameindex == NULL) { + objc_autoreleasePoolPop(pool); + return nil; + } + + @try { + for (size_t i = 0; nameindex[i].if_index != 0; i++) + [ret addObject: [OFString + stringWithCString: nameindex[i].if_name + encoding: encoding]]; + } @finally { + if_freenameindex(nameindex); + } + + [ret makeImmutable]; + + objc_autoreleasePoolPop(pool); + + return ret; +# else + return nil; +# endif } #endif - (instancetype)init { OF_INVALID_INIT_METHOD } @end Index: src/objfw-defs.h.in ================================================================== --- src/objfw-defs.h.in +++ src/objfw-defs.h.in @@ -49,9 +49,8 @@ #undef OF_NINTENDO_3DS #undef OF_NINTENDO_DS #undef OF_NINTENDO_SWITCH #undef OF_NO_SHARED #undef OF_OBJFW_RUNTIME -#undef OF_SYSTEM_INFO_HAS_NETWORK_INTERFACES #undef OF_UNIVERSAL #undef OF_WII #undef OF_WII_U Index: tests/OFSystemInfoTests.m ================================================================== --- tests/OFSystemInfoTests.m +++ tests/OFSystemInfoTests.m @@ -19,14 +19,10 @@ @implementation TestsAppDelegate (OFSystemInfoTests) - (void)systemInfoTests { void *pool = objc_autoreleasePoolPush(); -#ifdef OF_SYSTEM_INFO_HAS_NETWORK_INTERFACES - OFDictionary *networkInterfaces; - bool firstInterface = true; -#endif [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeFormat: @"[OFSystemInfo] Page size: %zd\n", [OFSystemInfo pageSize]]; @@ -109,74 +105,13 @@ #ifdef OF_POWERPC [OFStdOut writeFormat: @"[OFSystemInfo] Supports AltiVec: %d\n", [OFSystemInfo supportsAltiVec]]; #endif -#ifdef OF_SYSTEM_INFO_HAS_NETWORK_INTERFACES - [OFStdOut writeString: @"[OFSystemInfo] Network interfaces: "]; - networkInterfaces = [OFSystemInfo networkInterfaces]; - for (OFString *name in networkInterfaces) { - OFDictionary *interface = [networkInterfaces - objectForKey: name]; - OFData *etherAddr = [interface - objectForKey: OFNetworkInterfaceEthernetAddress]; - bool firstAddress = true; - OFData *addrs; - - if (!firstInterface) - [OFStdOut writeString: @"; "]; - firstInterface = false; - - [OFStdOut writeFormat: @"%@(", name]; - - if (etherAddr.itemSize == 1 && etherAddr.count == 6) { - const unsigned char *addr = etherAddr.items; - [OFStdOut writeFormat: - @"MAC=%02X:%02X:%02X:%02X:%02X:%02X", - addr[0], addr[1], addr[2], addr[3], addr[4], - addr[5]]; - firstAddress = false; - } - - addrs = [interface objectForKey: OFNetworkInterfaceAddresses]; - for (size_t i = 0; i < addrs.count; i++) { - const OFSocketAddress *addr = [addrs itemAtIndex: i]; - OFString *string; - - @try { - string = OFSocketAddressString(addr); - } @catch (OFInvalidArgumentException *e) { - continue; - } - - if (!firstAddress) - [OFStdOut writeString: @", "]; - firstAddress = nil; - - switch (addr->family) { - case OFSocketAddressFamilyIPv4: - [OFStdOut writeString: @"IPv4="]; - break; - case OFSocketAddressFamilyIPv6: - [OFStdOut writeString: @"IPv6="]; - break; - case OFSocketAddressFamilyIPX: - [OFStdOut writeString: @"IPX="]; - break; - case OFSocketAddressFamilyAppleTalk: - [OFStdOut writeString: @"AppleTalk="]; - break; - default: - [OFStdOut writeString: @"unknown="]; - } - - [OFStdOut writeString: string]; - } - - [OFStdOut writeString: @")"]; - } - [OFStdOut writeString: @"\n"]; +#ifdef OF_HAVE_SOCKETS + [OFStdOut writeFormat: @"[OFSystemInfo] Network interfaces: %@\n", + [[OFSystemInfo networkInterfaces] componentsJoinedByString: @", "]]; #endif objc_autoreleasePoolPop(pool); } @end