// List all useful IPv4/IPv6 addresses (excluding localhost). /* static */ Strings Address::ListAll(void) { Strings result; #ifdef _POSIX /* POSIX doesn't provide a way to enumerate network interfaces, so use Linux getifaddrs(3). */ ifaddrs* p_list; int const error = ::getifaddrs(&p_list); ASSERT(error == 0); for (ifaddrs* p_current = p_list; p_current != NULL; p_current = p_current->ifa_next) { unsigned flags = p_current->ifa_flags; ADDRESS_FAMILY const family = p_current->ifa_addr->sa_family; if ((flags & IFF_UP) && !(flags & IFF_LOOPBACK) && (family == AF_INET || family == AF_INET6)) { Address const address(*(p_current->ifa_addr)); if (!address.IsLocalHost()) { // not localhost String const address_text = address; result.Append(address_text); } } } ::freeifaddrs(p_list); #elif defined(_QT) QList<QHostAddress> const list = QNetworkInterface::allAddresses(); QList<QHostAddress>::const_iterator i_address; for (i_address = list.constBegin(); i_address != list.constEnd(); i_address++) { QHostAddress const q_address = *i_address; Address const address(q_address); if (!address.IsLocalHost()) { // not localhost String const address_text = address; result.Append(address_text); } } #elif defined(_WINSOCK2) ULONG const flags = (GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST); PIP_ADAPTER_ADDRESSES p_list = NULL; ULONG list_bytes = 16000; // initial size estimate while (p_list == NULL) { p_list = PIP_ADAPTER_ADDRESSES(new char[list_bytes]); ASSERT(p_list != NULL); ULONG const error_code = Win::GetAdaptersAddresses( AF_UNSPEC, flags, NULL, p_list, &list_bytes); if (error_code != NO_ERROR) { if (error_code == ERROR_NO_DATA) { return result; } ASSERT(error_code == ERROR_BUFFER_OVERFLOW); delete p_list; p_list = NULL; } } // Go through the list and append useful IP addresses to the result. PIP_ADAPTER_ADDRESSES p_current = p_list; while (p_current != NULL) { // Only interested in unicast addresses. PIP_ADAPTER_UNICAST_ADDRESS p_unicast = p_current->FirstUnicastAddress; while (p_unicast != NULL) { if ((p_unicast->Flags & IP_ADAPTER_ADDRESS_TRANSIENT) == 0x0) { // not transient Win::PSOCKADDR const p_address = p_unicast->Address.lpSockaddr; Address const address(*p_address); if (!address.IsLocalHost()) { // not localhost String const address_text = address; result.Append(address_text); } } p_unicast = p_unicast->Next; } p_current = p_current->Next; } delete p_list; #endif // defined(_WINSOCK2) return result; }