net/ToString: move UnmapV4() to class IPv6Address

This commit is contained in:
Max Kellermann 2019-07-03 21:39:34 +02:00
parent 08552f3938
commit 77b5b4158c
5 changed files with 40 additions and 24 deletions

View File

@ -28,6 +28,7 @@
*/
#include "IPv6Address.hxx"
#include "IPv4Address.hxx"
#include <assert.h>
#include <string.h>
@ -54,6 +55,20 @@ IPv6Address::IsAny() const noexcept
&in6addr_any, sizeof(in6addr_any)) == 0;
}
IPv4Address
IPv6Address::UnmapV4() const noexcept
{
assert(IsV4Mapped());
struct sockaddr_in buffer{};
buffer.sin_family = AF_INET;
memcpy(&buffer.sin_addr, ((const char *)&address.sin6_addr) + 12,
sizeof(buffer.sin_addr));
buffer.sin_port = address.sin6_port;
return buffer;
}
template<typename T>
static void
BitwiseAndT(T *dest, const T *a, const T *b, size_t n)

View File

@ -43,6 +43,8 @@
#include <netinet/in.h>
#endif
class IPv4Address;
/**
* An OO wrapper for struct sockaddr_in.
*/
@ -183,6 +185,12 @@ public:
return IN6_IS_ADDR_V4MAPPED(&address.sin6_addr);
}
/**
* Convert "::ffff:127.0.0.1" to "127.0.0.1".
*/
gcc_pure
IPv4Address UnmapV4() const noexcept;
/**
* Bit-wise AND of two addresses. This is useful for netmask
* calculations.

View File

@ -33,6 +33,7 @@
#include "IPv6Address.hxx"
#include "util/StringView.hxx"
#include <assert.h>
#include <string.h>
#ifdef HAVE_UN
@ -104,6 +105,14 @@ SocketAddress::IsV4Mapped() const noexcept
return GetFamily() == AF_INET6 && IPv6Address::Cast(*this).IsV4Mapped();
}
IPv4Address
SocketAddress::UnmapV4() const noexcept
{
assert(IsV4Mapped());
return IPv6Address::Cast(*this).UnmapV4();
}
unsigned
SocketAddress::GetPort() const noexcept
{

View File

@ -43,6 +43,7 @@
template<typename T> struct ConstBuffer;
struct StringView;
class IPv4Address;
/**
* An OO wrapper for struct sockaddr.
@ -128,6 +129,12 @@ public:
gcc_pure
bool IsV4Mapped() const noexcept;
/**
* Convert "::ffff:127.0.0.1" to "127.0.0.1".
*/
gcc_pure
IPv4Address UnmapV4() const noexcept;
/**
* Extract the port number. Returns 0 if not applicable.
*/

View File

@ -80,29 +80,6 @@ LocalAddressToString(const struct sockaddr_un &s_un, size_t size) noexcept
#endif
#if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED)
/**
* Convert "::ffff:127.0.0.1" to "127.0.0.1".
*/
static IPv4Address
UnmapV4(SocketAddress src) noexcept
{
assert(src.IsV4Mapped());
const auto &src6 = *(const struct sockaddr_in6 *)src.GetAddress();
struct sockaddr_in buffer{};
buffer.sin_family = AF_INET;
memcpy(&buffer.sin_addr, ((const char *)&src6.sin6_addr) + 12,
sizeof(buffer.sin_addr));
buffer.sin_port = src6.sin6_port;
return buffer;
}
#endif
std::string
ToString(SocketAddress address) noexcept
{
@ -116,7 +93,7 @@ ToString(SocketAddress address) noexcept
#if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED)
IPv4Address ipv4_buffer;
if (address.IsV4Mapped())
address = ipv4_buffer = UnmapV4(address);
address = ipv4_buffer = address.UnmapV4();
#endif
char host[NI_MAXHOST], serv[NI_MAXSERV];