Exemple #1
0
// 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;
}