@@ -147,10 +147,20 @@ memset(&address, 0, sizeof(address)); address.family = addressFamily; memcpy(&address.sockaddr.in, ¤t->ifr_addr, sockaddrSize); + +# if defined(OF_HAVE_IPV6) && defined(HAVE_IF_NAMETOINDEX) + if (address.sockaddr.in6.sin6_family == AF_INET6 && + address.sockaddr.in6.sin6_addr.s6_addr[0] == 0xFE && + (address.sockaddr.in6.sin6_addr.s6_addr[1] & 0xC0) + == 0x80) + address.sockaddr.in6.sin6_scope_id = + if_nametoindex( + [name cStringWithEncoding: encoding]); +# endif [addresses addItem: &address]; next: # ifdef _SIZEOF_ADDR_IFREQ @@ -187,10 +197,13 @@ #ifdef OF_HAVE_IPV6 static bool queryNetworkInterfaceIPv6Addresses(OFMutableDictionary *ret) { # if defined(OF_LINUX) && defined(OF_HAVE_FILES) +# ifdef HAVE_IF_NAMETOINDEX + OFStringEncoding encoding = [OFLocale encoding]; +# endif OFFile *file; OFString *line; OFMutableDictionary *interface; OFEnumerator *enumerator; @@ -222,10 +235,11 @@ [ret setObject: interface forKey: name]; } memset(&address, 0, sizeof(address)); address.family = OFSocketAddressFamilyIPv6; + address.sockaddr.in6.sin6_family = AF_INET6; for (size_t i = 0; i < 32; i += 2) { unsigned long long byte; @try { @@ -240,10 +254,17 @@ goto next_line; address.sockaddr.in6.sin6_addr.s6_addr[i / 2] = (unsigned char)byte; } + +# ifdef HAVE_IF_NAMETOINDEX + if (address.sockaddr.in6.sin6_addr.s6_addr[0] == 0xFE && + (address.sockaddr.in6.sin6_addr.s6_addr[1] & 0xC0) == 0x80) + address.sockaddr.in6.sin6_scope_id = if_nametoindex( + [name cStringWithEncoding: encoding]); +# endif if ((addresses = [interface objectForKey: OFNetworkInterfaceIPv6Addresses]) == nil) { addresses = [OFMutableData dataWithItemSize: sizeof(OFSocketAddress)];