diff --git a/Userland/Libraries/LibC/arpa/inet.cpp b/Userland/Libraries/LibC/arpa/inet.cpp index a3be63ac948..ca669086af0 100644 --- a/Userland/Libraries/LibC/arpa/inet.cpp +++ b/Userland/Libraries/LibC/arpa/inet.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -13,49 +14,68 @@ extern "C" { const char* inet_ntop(int af, const void* src, char* dst, socklen_t len) { - if (af != AF_INET) { - errno = EAFNOSUPPORT; - return nullptr; + if (af == AF_INET) { + if (len < INET_ADDRSTRLEN) { + errno = ENOSPC; + return nullptr; + } + auto* bytes = (const unsigned char*)src; + snprintf(dst, len, "%u.%u.%u.%u", bytes[0], bytes[1], bytes[2], bytes[3]); + return (const char*)dst; + } else if (af == AF_INET6) { + if (len < INET6_ADDRSTRLEN) { + errno = ENOSPC; + return nullptr; + } + auto str = IPv6Address(((in6_addr const*)src)->s6_addr).to_string(); + if (!str.copy_characters_to_buffer(dst, len)) { + errno = ENOSPC; + return nullptr; + } + return (const char*)dst; } - if (len < 4) { - errno = ENOSPC; - return nullptr; - } - auto* bytes = (const unsigned char*)src; - snprintf(dst, len, "%u.%u.%u.%u", bytes[0], bytes[1], bytes[2], bytes[3]); - return (const char*)dst; + + errno = EAFNOSUPPORT; + return nullptr; } int inet_pton(int af, const char* src, void* dst) { - if (af != AF_INET) { - errno = EAFNOSUPPORT; - return -1; + if (af == AF_INET) { + unsigned a, b, c, d; + int count = sscanf(src, "%u.%u.%u.%u", &a, &b, &c, &d); + if (count != 4) { + errno = EINVAL; + return 0; + } + union { + struct { + uint8_t a; + uint8_t b; + uint8_t c; + uint8_t d; + }; + uint32_t l; + } u; + u.a = a; + u.b = b; + u.c = c; + u.d = d; + *(uint32_t*)dst = u.l; + return 1; + } else if (af == AF_INET6) { + auto addr = IPv6Address::from_string(src); + if (!addr.has_value()) { + errno = EINVAL; + return 0; + } + + memcpy(dst, addr->to_in6_addr_t(), sizeof(in6_addr)); + return 1; } - unsigned a; - unsigned b; - unsigned c; - unsigned d; - int count = sscanf(src, "%u.%u.%u.%u", &a, &b, &c, &d); - if (count != 4) { - errno = EINVAL; - return 0; - } - union { - struct { - uint8_t a; - uint8_t b; - uint8_t c; - uint8_t d; - }; - uint32_t l; - } u; - u.a = a; - u.b = b; - u.c = c; - u.d = d; - *(uint32_t*)dst = u.l; - return 1; + + errno = EAFNOSUPPORT; + return -1; } in_addr_t inet_addr(const char* str)