Created
April 25, 2022 08:06
-
-
Save dougvj/5918a826be845d91bfb8fed79770409d to your computer and use it in GitHub Desktop.
Getting IPv4 or IPv6 address string from IPv6 sockaddr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This function returns the string representation of an IP address in an IPv6 | |
// stack. Connections from IPv4 addresses are mapped to IPv6 addresses under | |
// the ::FFFF prefix. This checks for that mapping and if it exists returns the | |
// conversion as though the addresss were a native IPv4 Address. | |
// | |
// addr is a pointer to a valid sockaddr_in6 struct. | |
// | |
// dest must be a buffer of at least size INET6_ADDRSTRLEN | |
// | |
// The return is a pointer to dest, otherwise if NULL then errno is set, see | |
// man inet_ntop(3) | |
const char* get_addr_string(struct sockaddr_in6* addr, char* dest) { | |
assert(addr->sin6_family == AF_INET6); | |
uint32_t *addr_words = (uint32_t *)&(addr->sin6_addr); | |
// Check for ipv6 mapped ipv4 address. This means that the top 80 bits are | |
// 0 and the next 16 bits are 1 | |
if (addr_words[0] == 0 && addr_words[1] == 0 && | |
ntohl(addr_words[2]) == 0x0000FFFF) { | |
return inet_ntop(AF_INET, &(addr_words[3]), dest, INET6_ADDRSTRLEN); | |
} | |
return inet_ntop(AF_INET6, &(addr->sin6_addr), dest, INET6_ADDRSTRLEN); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment