Reputation: 2018
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
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
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, <h);
return sa[0]; // In any case (IPv4 or IPv6) family is the first halfword of
// address structure
}
Upvotes: 0
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