From bc069267029cf57a43ba3c8210f2b7f9fa0baa76 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Thu, 26 Jun 2025 02:43:03 +0300 Subject: [PATCH] LibC: Implement gethostbyaddr --- userspace/libraries/LibC/include/netdb.h | 1 + userspace/libraries/LibC/netdb.cpp | 71 ++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/userspace/libraries/LibC/include/netdb.h b/userspace/libraries/LibC/include/netdb.h index e06474fe..6d4a084f 100644 --- a/userspace/libraries/LibC/include/netdb.h +++ b/userspace/libraries/LibC/include/netdb.h @@ -99,6 +99,7 @@ void endservent(void); void freeaddrinfo(struct addrinfo* ai); const char* gai_strerror(int ecode); int getaddrinfo(const char* __restrict nodename, const char* __restrict servname, const struct addrinfo* __restrict hints, struct addrinfo** __restrict res); +struct hostent* gethostbyaddr(const void* addr, socklen_t size, int type); struct hostent* gethostbyname(const char* name); struct hostent* gethostent(void); int getnameinfo(const struct sockaddr* __restrict sa, socklen_t salen, char* __restrict node, socklen_t nodelen, char* __restrict service, socklen_t servicelen, int flags); diff --git a/userspace/libraries/LibC/netdb.cpp b/userspace/libraries/LibC/netdb.cpp index aed2f8a0..50772961 100644 --- a/userspace/libraries/LibC/netdb.cpp +++ b/userspace/libraries/LibC/netdb.cpp @@ -182,6 +182,77 @@ int getnameinfo(const struct sockaddr* __restrict sa, socklen_t salen, char* __r return 0; } +struct hostent* gethostbyaddr(const void* addr, socklen_t size, int type) +{ + static char* addr_ptrs[2]; + static struct hostent hostent; + + if (hostent.h_name != nullptr) + free(hostent.h_name); + + switch (type) + { + case AF_INET: + { + if (size < static_cast(sizeof(in_addr))) + return nullptr; + + hostent.h_name = static_cast(malloc(INET_ADDRSTRLEN)); + if (hostent.h_name == nullptr) + return nullptr; + + const auto* in_addr = static_cast(addr); + if (!inet_ntop(AF_INET, &in_addr->s_addr, hostent.h_name, INET_ADDRSTRLEN)) + return nullptr; + + hostent.h_aliases = nullptr; + + hostent.h_addrtype = AF_INET; + hostent.h_length = sizeof(::in_addr); + + static char in_addr_buffer[sizeof(::in_addr::s_addr)]; + memcpy(in_addr_buffer, &in_addr->s_addr, sizeof(::in_addr::s_addr)); + + addr_ptrs[0] = in_addr_buffer; + addr_ptrs[1] = nullptr; + hostent.h_addr_list = addr_ptrs; + + break; + } + case AF_INET6: + { + if (size < static_cast(sizeof(in6_addr))) + return nullptr; + + hostent.h_name = static_cast(malloc(INET6_ADDRSTRLEN)); + if (hostent.h_name == nullptr) + return nullptr; + + const auto* in6_addr = static_cast(addr); + if (!inet_ntop(AF_INET6, &in6_addr->s6_addr, hostent.h_name, INET6_ADDRSTRLEN)) + return nullptr; + + hostent.h_aliases = nullptr; + + hostent.h_addrtype = AF_INET6; + hostent.h_length = sizeof(::in6_addr::s6_addr); + + static char in6_addr_buffer[sizeof(::in6_addr::s6_addr)]; + memcpy(in6_addr_buffer, &in6_addr->s6_addr, sizeof(::in6_addr::s6_addr)); + + addr_ptrs[0] = in6_addr_buffer; + addr_ptrs[1] = nullptr; + hostent.h_addr_list = addr_ptrs; + + break; + } + default: + return nullptr; + } + + return &hostent; +} + struct hostent* gethostbyname(const char* name) { static char name_buffer[HOST_NAME_MAX + 1];