示例#1
0
int ResolveUtil::getHostnameByAddress(bsl::string        *canonicalHostname,
                                      const IPv4Address&  address,
                                      int                *errorCode)
{
    BSLS_ASSERT(canonicalHostname);

    struct hostent *hp = NULL;
    unsigned int    addr = address.ipAddress();   // in network order

#if defined(BSLS_PLATFORM_OS_AIX)
    struct hostent      hent;
    struct hostent_data hdt;

    if (gethostbyaddr_r(reinterpret_cast<char *>(&addr),
                        sizeof (struct in_addr),
                        AF_INET,
                        &hent,
                        &hdt)) {
        if (errorCode) {
            *errorCode = h_errno;
        }
        return -1;                                                    // RETURN
    }

    *canonicalHostname = hent.h_name;

#elif defined(BSLS_PLATFORM_OS_SUNOS) || defined(BSLS_PLATFORM_OS_SOLARIS)
    struct hostent hent;
    char           hdt[2048];
    int            err;

    hp = gethostbyaddr_r(reinterpret_cast<char *>(&addr),
                         sizeof (struct in_addr),
                         AF_INET,
                         &hent,
                         hdt,
                         sizeof(hdt),
                         &err);

    if (0 == hp) {
        if (errorCode) {
            *errorCode = err;
        }
        return -1;                                                    // RETURN
    }

    *canonicalHostname = hp->h_name;

#elif defined(BSLS_PLATFORM_OS_LINUX) \
   || defined(BSLS_PLATFORM_OS_FREEBSD)
    struct hostent hent;
    char           hdt[2048];
    int            err;

    if (gethostbyaddr_r(reinterpret_cast<char *>(&addr),
                        sizeof (struct in_addr),
                        AF_INET,
                        &hent,
                        hdt,
                        sizeof(hdt),
                        &hp,
                        &err) || 0 == hp) {
        if (errorCode) {
            *errorCode = err;
        }
        return -1;                                                    // RETURN
    }

    *canonicalHostname = hp->h_name;

#elif defined(BSLS_PLATFORM_OS_UNIX)
    // Standard call cannot be assumed to be re-entrant (it often is not).
    {
        static bslmt::Mutex            mutex;
        bslmt::LockGuard<bslmt::Mutex> guard(&mutex);

        hp = gethostbyaddr(reinterpret_cast<char *>(&addr),
                           sizeof (struct in_addr),
                           AF_INET);

        if (0 == hp) {
            if (errorCode) {
#ifdef BSLS_PLATFORM_OS_HPUX
                *errorCode = h_errno;
#else
                *errorCode = errno;
#endif
            }
            return -1;                                                // RETURN
        }

        *canonicalHostname = hp->h_name;
    }

#elif defined(BSLS_PLATFORM_OS_WINDOWS)
    unsigned short port = address.portNumber();  // in host order

    struct sockaddr_in saGNI;
    char               hostName[NI_MAXHOST];
    char               servInfo[NI_MAXSERV];

    saGNI.sin_family = AF_INET;
    saGNI.sin_addr.s_addr = addr;
    saGNI.sin_port = htons(port);

    if (getnameinfo(reinterpret_cast<SOCKADDR *>(&saGNI),
                    sizeof(sockaddr),
                    hostName,
                    sizeof(hostName),
                    servInfo,
                    sizeof(servInfo),
                    NI_NUMERICSERV|NI_NAMEREQD)) {
        if (errorCode) {
            *errorCode = WSAGetLastError();
        }
        return -1;                                                    // RETURN
    }

    *canonicalHostname = hostName; // a Fully Qualified Domain Name (FQDN)

#else

#error getHostnameByAddress does not handle current platform type!

#endif

    return 0;
}