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

net/ToString: move UnmapV4() to class IPv6Address

parent 08552f39
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
*/ */
#include "IPv6Address.hxx" #include "IPv6Address.hxx"
#include "IPv4Address.hxx"
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
...@@ -54,6 +55,20 @@ IPv6Address::IsAny() const noexcept ...@@ -54,6 +55,20 @@ IPv6Address::IsAny() const noexcept
&in6addr_any, sizeof(in6addr_any)) == 0; &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> template<typename T>
static void static void
BitwiseAndT(T *dest, const T *a, const T *b, size_t n) BitwiseAndT(T *dest, const T *a, const T *b, size_t n)
......
...@@ -43,6 +43,8 @@ ...@@ -43,6 +43,8 @@
#include <netinet/in.h> #include <netinet/in.h>
#endif #endif
class IPv4Address;
/** /**
* An OO wrapper for struct sockaddr_in. * An OO wrapper for struct sockaddr_in.
*/ */
...@@ -184,6 +186,12 @@ public: ...@@ -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 * Bit-wise AND of two addresses. This is useful for netmask
* calculations. * calculations.
*/ */
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "IPv6Address.hxx" #include "IPv6Address.hxx"
#include "util/StringView.hxx" #include "util/StringView.hxx"
#include <assert.h>
#include <string.h> #include <string.h>
#ifdef HAVE_UN #ifdef HAVE_UN
...@@ -104,6 +105,14 @@ SocketAddress::IsV4Mapped() const noexcept ...@@ -104,6 +105,14 @@ SocketAddress::IsV4Mapped() const noexcept
return GetFamily() == AF_INET6 && IPv6Address::Cast(*this).IsV4Mapped(); return GetFamily() == AF_INET6 && IPv6Address::Cast(*this).IsV4Mapped();
} }
IPv4Address
SocketAddress::UnmapV4() const noexcept
{
assert(IsV4Mapped());
return IPv6Address::Cast(*this).UnmapV4();
}
unsigned unsigned
SocketAddress::GetPort() const noexcept SocketAddress::GetPort() const noexcept
{ {
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
template<typename T> struct ConstBuffer; template<typename T> struct ConstBuffer;
struct StringView; struct StringView;
class IPv4Address;
/** /**
* An OO wrapper for struct sockaddr. * An OO wrapper for struct sockaddr.
...@@ -129,6 +130,12 @@ public: ...@@ -129,6 +130,12 @@ public:
bool IsV4Mapped() const noexcept; 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. * Extract the port number. Returns 0 if not applicable.
*/ */
gcc_pure gcc_pure
......
...@@ -80,29 +80,6 @@ LocalAddressToString(const struct sockaddr_un &s_un, size_t size) noexcept ...@@ -80,29 +80,6 @@ LocalAddressToString(const struct sockaddr_un &s_un, size_t size) noexcept
#endif #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 std::string
ToString(SocketAddress address) noexcept ToString(SocketAddress address) noexcept
{ {
...@@ -116,7 +93,7 @@ ToString(SocketAddress address) noexcept ...@@ -116,7 +93,7 @@ ToString(SocketAddress address) noexcept
#if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED) #if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED)
IPv4Address ipv4_buffer; IPv4Address ipv4_buffer;
if (address.IsV4Mapped()) if (address.IsV4Mapped())
address = ipv4_buffer = UnmapV4(address); address = ipv4_buffer = address.UnmapV4();
#endif #endif
char host[NI_MAXHOST], serv[NI_MAXSERV]; 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