Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -1403,11 +1403,11 @@ ]) 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]) + AC_CHECK_HEADERS([arpa/inet.h netdb.h net/if.h]) 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/OFSocket.m ================================================================== --- src/OFSocket.m +++ src/OFSocket.m @@ -23,10 +23,14 @@ #ifdef OF_NINTENDO_3DS # include /* For memalign() */ #endif #include + +#ifdef HAVE_NET_IF_H +# include +#endif #import "OFArray.h" #import "OFCharacterSet.h" #import "OFLocale.h" #ifdef OF_HAVE_THREADS @@ -45,10 +49,16 @@ #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFLockFailedException.h" #import "OFOutOfRangeException.h" #import "OFUnlockFailedException.h" + +#ifdef OF_WINDOWS +# define interface struct +# include +# undef interface +#endif #ifdef OF_AMIGAOS # include #endif @@ -431,11 +441,11 @@ OFSocketAddressParseIPv6(OFString *IPv6, uint16_t port) { void *pool = objc_autoreleasePoolPush(); OFSocketAddress ret; struct sockaddr_in6 *addrIn6 = &ret.sockaddr.in6; - size_t doubleColon; + size_t doubleColon, percent; memset(&ret, '\0', sizeof(ret)); ret.family = OFSocketAddressFamilyIPv6; ret.length = sizeof(ret.sockaddr.in6); @@ -443,13 +453,20 @@ addrIn6->sin6_family = AF_INET6; #else addrIn6->sin6_family = AF_UNSPEC; #endif addrIn6->sin6_port = OFToBigEndian16(port); + + if ((percent = [IPv6 rangeOfString: @"%"].location) != OFNotFound) { + OFString *interface = [IPv6 substringFromIndex: percent + 1]; + IPv6 = [IPv6 substringToIndex: percent]; + + addrIn6->sin6_scope_id = if_nametoindex( + [interface cStringWithEncoding: [OFLocale encoding]]); + } doubleColon = [IPv6 rangeOfString: @"::"].location; - if (doubleColon != OFNotFound) { OFString *left = [IPv6 substringToIndex: doubleColon]; OFString *right = [IPv6 substringFromIndex: doubleColon + 2]; OFArray OF_GENERIC(OFString *) *leftComponents; OFArray OF_GENERIC(OFString *) *rightComponents; @@ -867,10 +884,19 @@ (addrIn6->sin6_addr.s6_addr[i] << 8) | addrIn6->sin6_addr.s6_addr[i + 1]]; first = false; } } + + if (addrIn6->sin6_scope_id != 0) { + char interface[IF_NAMESIZE]; + + if (if_indextoname(addrIn6->sin6_scope_id, interface) != NULL) + [string appendFormat: @"%%%s", interface]; + else + [string appendFormat: @"%%%u", addrIn6->sin6_scope_id]; + } [string makeImmutable]; return string; }