Index: src/OFSystemInfo.h ================================================================== --- src/OFSystemInfo.h +++ src/OFSystemInfo.h @@ -19,10 +19,36 @@ OF_ASSUME_NONNULL_BEGIN @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFIRI; +#ifdef OF_HAVE_SOCKETS +/** + * @brief A dictionary describing a network interface, as returned by + * @ref networkInterfaces. + * + * Keys are of type @ref OFNetworkInterfaceKey. + */ +typedef OFDictionary OF_GENERIC(OFString *, id) *OFNetworkInterface; + +/** + * @brief A key of an @ref OFNetworkInterface. + * + * Possible values are: + * + * * @ref OFNetworkInterfaceIndex + */ +typedef OFConstantString *OFNetworkInterfaceKey; + +/** + * @brief The index of a network interface. + * + * This maps to a @ref OFNumber. + */ +extern OFNetworkInterfaceKey OFNetworkInterfaceIndex; +#endif + /** * @class OFSystemInfo OFSystemInfo.h ObjFW/OFSystemInfo.h * * @brief A class for querying information about the system. */ @@ -63,11 +89,11 @@ # ifdef OF_WINDOWS @property (class, readonly, nonatomic, getter=isWindowsNT) bool windowsNT; # endif # ifdef OF_HAVE_SOCKETS @property (class, readonly, nullable, nonatomic) - OFArray OF_GENERIC(OFString *) *networkInterfaces; + OFDictionary OF_GENERIC(OFString *, OFNetworkInterface) *networkInterfaces; # endif #endif /** * @brief Returns the size of a page. @@ -348,13 +374,14 @@ * @brief Returns the available (though not necessarily configured) network * interfaces. * * @return The available network interfaces */ -+ (nullable OFArray OF_GENERIC(OFString *) *)networkInterfaces; ++ (nullable OFDictionary OF_GENERIC(OFString *, OFNetworkInterface) *) + 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 @@ -122,10 +122,14 @@ extern NSSearchPathEnumerationState NSStartSearchPathEnumeration( NSSearchPathDirectory, NSSearchPathDomainMask); extern NSSearchPathEnumerationState NSGetNextSearchPathEnumeration( NSSearchPathEnumerationState, char *); #endif + +#ifdef OF_HAVE_SOCKETS +OFNetworkInterfaceKey OFNetworkInterfaceIndex = @"OFNetworkInterfaceIndex"; +#endif #if defined(OF_AMD64) || defined(OF_X86) struct X86Regs { uint32_t eax, ebx, ecx, edx; }; @@ -837,14 +841,14 @@ return !(GetVersion() & 0x80000000); } #endif #ifdef OF_HAVE_SOCKETS -+ (OFArray OF_GENERIC(OFString *) *)networkInterfaces ++ (OFDictionary OF_GENERIC(OFString *, OFNetworkInterface) *)networkInterfaces { # ifdef HAVE_IF_NAMEINDEX - OFMutableArray *ret = [OFMutableArray array]; + OFMutableDictionary *ret = [OFMutableDictionary dictionary]; void *pool = objc_autoreleasePoolPush(); OFStringEncoding encoding = [OFLocale encoding]; struct if_nameindex *nameindex = if_nameindex(); if (nameindex == NULL) { @@ -851,14 +855,22 @@ objc_autoreleasePoolPop(pool); return nil; } @try { - for (size_t i = 0; nameindex[i].if_index != 0; i++) - [ret addObject: [OFString + for (size_t i = 0; nameindex[i].if_index != 0; i++) { + OFString *name = [OFString stringWithCString: nameindex[i].if_name - encoding: encoding]]; + encoding: encoding]; + OFNumber *index = [OFNumber + numberWithUnsignedInt: nameindex[i].if_index]; + OFDictionary *interface = [OFDictionary + dictionaryWithObject: index + forKey: OFNetworkInterfaceIndex]; + + [ret setObject: interface forKey: name]; + } } @finally { if_freenameindex(nameindex); } [ret makeImmutable]; Index: tests/OFSystemInfoTests.m ================================================================== --- tests/OFSystemInfoTests.m +++ tests/OFSystemInfoTests.m @@ -19,10 +19,14 @@ @implementation TestsAppDelegate (OFSystemInfoTests) - (void)systemInfoTests { void *pool = objc_autoreleasePoolPush(); +#ifdef OF_HAVE_SOCKETS + OFDictionary *networkInterfaces; + bool firstInterface = true; +#endif [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeFormat: @"[OFSystemInfo] Page size: %zd\n", [OFSystemInfo pageSize]]; @@ -106,12 +110,21 @@ [OFStdOut writeFormat: @"[OFSystemInfo] Supports AltiVec: %d\n", [OFSystemInfo supportsAltiVec]]; #endif #ifdef OF_HAVE_SOCKETS - [OFStdOut writeFormat: @"[OFSystemInfo] Network interfaces: %@\n", - [[OFSystemInfo networkInterfaces] componentsJoinedByString: @", "]]; + networkInterfaces = [OFSystemInfo networkInterfaces]; + [OFStdOut writeString: @"[OFSystemInfo] Network interfaces: "]; + for (OFString *name in networkInterfaces) { + if (!firstInterface) + [OFStdOut writeString: @"; "]; + + firstInterface = false; + + [OFStdOut writeString: name]; + } + [OFStdOut writeString: @"\n"]; #endif objc_autoreleasePoolPop(pool); } @end