unresolved_external
unresolved_external

Reputation: 2018

How to determine IP version in C++?

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.

Upvotes: 2

Views: 739

Answers (3)

KillianDS
KillianDS

Reputation: 17176

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.

Upvotes: 6

Sunil Bojanapally
Sunil Bojanapally

Reputation: 12658

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
}

Upvotes: 0

Alnitak
Alnitak

Reputation: 339786

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.

Upvotes: 2

Related Questions