Explorar o código

LibC: Add IPv6 support to inet_ntop and inet_pton

Tom %!s(int64=3) %!d(string=hai) anos
pai
achega
d124889698
Modificáronse 1 ficheiros con 57 adicións e 37 borrados
  1. 57 37
      Userland/Libraries/LibC/arpa/inet.cpp

+ 57 - 37
Userland/Libraries/LibC/arpa/inet.cpp

@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
 
 
+#include <AK/IPv6Address.h>
 #include <arpa/inet.h>
 #include <arpa/inet.h>
 #include <errno.h>
 #include <errno.h>
 #include <netinet/in.h>
 #include <netinet/in.h>
@@ -13,49 +14,68 @@ extern "C" {
 
 
 const char* inet_ntop(int af, const void* src, char* dst, socklen_t len)
 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)
 int inet_pton(int af, const char* src, void* dst)
 {
 {
-    if (af != AF_INET) {
-        errno = EAFNOSUPPORT;
-        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;
+    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;
     }
     }
-    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)
 in_addr_t inet_addr(const char* str)