#include "netdb.h"
#include "syscall.h"
#include "errno.h"
#include "stdlib.h"
#include "string.h"
int getaddrinfo(const char* node, const char* service,
const struct addrinfo* hints, struct addrinfo** res) {
(void)service;
if (!res) return EAI_FAIL;
/* Use kernel getaddrinfo syscall for DNS resolution */
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
int ret = _syscall3(SYS_GETADDRINFO, (int)node, (int)&addr.sin_addr, 0);
if (ret < 0) return EAI_NONAME;
struct addrinfo* ai = (struct addrinfo*)calloc(1, sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
if (!ai) return EAI_MEMORY;
struct sockaddr_in* sa = (struct sockaddr_in*)(ai + 1);
memcpy(sa, &addr, sizeof(struct sockaddr_in));
ai->ai_family = AF_INET;
ai->ai_socktype = hints ? hints->ai_socktype : SOCK_STREAM;
ai->ai_protocol = hints ? hints->ai_protocol : 0;
ai->ai_addrlen = sizeof(struct sockaddr_in);
ai->ai_addr = (struct sockaddr*)sa;
ai->ai_next = (void*)0;
*res = ai;
return 0;
}
void freeaddrinfo(struct addrinfo* res) {
while (res) {
struct addrinfo* next = res->ai_next;
free(res);
res = next;
}
}
const char* gai_strerror(int errcode) {
switch (errcode) {
case 0: return "Success";
case EAI_NONAME: return "Name does not resolve";
case EAI_AGAIN: return "Temporary failure in name resolution";
case EAI_FAIL: return "Non-recoverable failure in name resolution";
case EAI_MEMORY: return "Memory allocation failure";
case EAI_FAMILY: return "Address family not supported";
case EAI_SOCKTYPE: return "Socket type not supported";
case EAI_SERVICE: return "Service not supported";
case EAI_SYSTEM: return "System error";
default: return "Unknown error";
}
}