Commit 77b5b415 authored by Max Kellermann's avatar Max Kellermann

net/ToString: move UnmapV4() to class IPv6Address

parent 08552f39
......@@ -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)
......
......@@ -43,6 +43,8 @@
#include <netinet/in.h>
#endif
class IPv4Address;
/**
* An OO wrapper for struct sockaddr_in.
*/
......@@ -184,6 +186,12 @@ public:
}
/**
* 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.
*/
......
......@@ -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
{
......
......@@ -43,6 +43,7 @@
template<typename T> struct ConstBuffer;
struct StringView;
class IPv4Address;
/**
* An OO wrapper for struct sockaddr.
......@@ -129,6 +130,12 @@ public:
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.
*/
gcc_pure
......
......@@ -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];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment