net/SocketAddress: add IsV4Mapped()

This commit is contained in:
Max Kellermann 2018-08-21 10:43:36 +02:00
parent 94092f1f90
commit dfc1f6342a
3 changed files with 14 additions and 13 deletions

View File

@ -82,6 +82,12 @@ SocketAddress::IsV6Any() const noexcept
return GetFamily() == AF_INET6 && IPv6Address(*this).IsAny(); return GetFamily() == AF_INET6 && IPv6Address(*this).IsAny();
} }
bool
SocketAddress::IsV4Mapped() const noexcept
{
return GetFamily() == AF_INET6 && IPv6Address(*this).IsV4Mapped();
}
unsigned unsigned
SocketAddress::GetPort() const noexcept SocketAddress::GetPort() const noexcept
{ {

View File

@ -114,6 +114,12 @@ public:
gcc_pure gcc_pure
bool IsV6Any() const noexcept; bool IsV6Any() const noexcept;
/**
* Is this an IPv4 address mapped inside struct sockaddr_in6?
*/
gcc_pure
bool IsV4Mapped() const noexcept;
/** /**
* Extract the port number. Returns 0 if not applicable. * Extract the port number. Returns 0 if not applicable.
*/ */

View File

@ -81,24 +81,13 @@ LocalAddressToString(const struct sockaddr_un &s_un, size_t size) noexcept
#if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED) #if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED)
gcc_pure
static bool
IsV4Mapped(SocketAddress address) noexcept
{
if (address.GetFamily() != AF_INET6)
return false;
const auto &a6 = *(const struct sockaddr_in6 *)address.GetAddress();
return IN6_IS_ADDR_V4MAPPED(&a6.sin6_addr);
}
/** /**
* Convert "::ffff:127.0.0.1" to "127.0.0.1". * Convert "::ffff:127.0.0.1" to "127.0.0.1".
*/ */
static SocketAddress static SocketAddress
UnmapV4(SocketAddress src, struct sockaddr_in &buffer) noexcept UnmapV4(SocketAddress src, struct sockaddr_in &buffer) noexcept
{ {
assert(IsV4Mapped(src)); assert(src.IsV4Mapped());
const auto &src6 = *(const struct sockaddr_in6 *)src.GetAddress(); const auto &src6 = *(const struct sockaddr_in6 *)src.GetAddress();
memset(&buffer, 0, sizeof(buffer)); memset(&buffer, 0, sizeof(buffer));
@ -124,7 +113,7 @@ ToString(SocketAddress address) noexcept
#if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED) #if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED)
struct sockaddr_in in_buffer; struct sockaddr_in in_buffer;
if (IsV4Mapped(address)) if (address.IsV4Mapped())
address = UnmapV4(address, in_buffer); address = UnmapV4(address, in_buffer);
#endif #endif