Question

I want to support both versions IPv4 and IPv6. Currently. I only support IPv4, but in order to set different behaviour for each version of IP I need to know, what version of IP I am working with.

Currenly I am using gethostbyname function, and depending on h_addrtype field of hostent struct I set whether it is IPv4 or IPv6, but I am wondering is that really correct? And if it is not, what are possible ways to get IP version ? And if it is correct, what should I do, if this function fails ?

Thanks on advance.

Was it helpful?

Solution 2

The h_addrtype field of an IPv6 address should be AF_INET6 (instead of AF_INET) and testing that field is the correct method when using gethostbyname.

You should however consider using getaddrinfo instead of gethostbyname in new applications.

OTHER TIPS

gethostbyname is deprecated, you should actually use getaddrinfo, one of the reasons it's being deprecated are IPv4/IPv6 issues.

That being said, yes, checking h_addrtype is correct.

You can use getsockname to determine IP version,

int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

Below method can be employed,

/* Function to detect family of a socket */
// Return AF_INET or AF_INET6
unsigned short GetSocketFamily(int sockfd)
{
    unsigned short sa[16];  // 32 bytes is enough for sockaddr version for any family
                            // 16 bytes for IPv4 and 28 bytes for IPv6
    socklen_t lth = sizeof(sa);
    getsockname(sockfd, (struct sockaddr *)&sa, &lth);
    return sa[0]; // In any case (IPv4 or IPv6) family is the first halfword of 
                  // address structure
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top