LibC: Implement gethostbyaddr

This commit is contained in:
Bananymous 2025-06-26 02:43:03 +03:00
parent 9de27110e2
commit bc06926702
2 changed files with 72 additions and 0 deletions

View File

@ -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);

View File

@ -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<socklen_t>(sizeof(in_addr)))
return nullptr;
hostent.h_name = static_cast<char*>(malloc(INET_ADDRSTRLEN));
if (hostent.h_name == nullptr)
return nullptr;
const auto* in_addr = static_cast<const ::in_addr*>(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<socklen_t>(sizeof(in6_addr)))
return nullptr;
hostent.h_name = static_cast<char*>(malloc(INET6_ADDRSTRLEN));
if (hostent.h_name == nullptr)
return nullptr;
const auto* in6_addr = static_cast<const ::in6_addr*>(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];