2 * Acess2 POSIX Sockets Library
3 * - By John Hodge (thePowersGang)
6 * - getaddrinfo/freeaddrinfo/getnameinfo/gai_strerror
9 #include <netinet/in.h>
10 #include <net.h> // Net_ParseAddress
11 #include <stdlib.h> // malloc
12 #include <string.h> // memcpy
13 #include <acess/sys.h>
16 int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res)
18 static const struct addrinfo defhints = {.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG};
19 struct addrinfo *ret = NULL;
22 if( !node && !service ) return EAI_NONAME;
29 if( !(hints->ai_flags & AI_PASSIVE) )
36 // 1. Check if the node is an IP address
37 // TODO: Break this function out into inet_pton?
41 type = Net_ParseAddress(node, addrdata);
47 ret = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
48 ret->ai_family = AF_INET;
51 ret->ai_addrlen = sizeof(struct in_addr);
52 ret->ai_addr = (void*)( ret + 1 );
53 ret->ai_canonname = 0;
55 ((struct sockaddr_in*)ret->ai_addr)->sin_family = AF_INET;
56 ((struct sockaddr_in*)ret->ai_addr)->sin_port = 0;
57 memcpy( &((struct sockaddr_in*)ret->ai_addr)->sin_addr, addrdata, 4 );
60 _SysDebug("getaddrinfo: Unknown address family %i", type);
65 // 2. Check for a DNS name
66 // - No luck with above, and hints->ai_flags doesn't have AI_NUMERICHOST set
67 if( !ret && !(hints->ai_flags & AI_NUMERICHOST) )
70 // ? /Acess/Conf/Nameservers
71 // ? /Acess/Conf/Hosts
74 // 3. No Match, chuck sad
81 int default_socktype = 0;
82 int default_protocol = 0;
85 // Convert `node` into types
88 // TODO: Read something like /Acess/Conf/services
92 for( ai = ret; ai; ai = ai->ai_next)
94 struct sockaddr_in *in = (void*)ai->ai_addr;
95 struct sockaddr_in6 *in6 = (void*)ai->ai_addr;
97 // Check ai_socktype/ai_protocol
98 // TODO: Do both of these need to be zero for defaults to apply?
99 if( ai->ai_socktype == 0 )
100 ai->ai_socktype = default_socktype;
101 if( ai->ai_protocol == 0 )
102 ai->ai_protocol = default_protocol;
104 switch(ai->ai_family)
107 if( in->sin_port == 0 )
108 in->sin_port = default_port;
111 if( in6->sin6_port == 0 )
112 in6->sin6_port = default_port;
115 _SysDebug("getaddrinfo: Unknown address family %i (setting port)", ai->ai_family);
124 void freeaddrinfo(struct addrinfo *res)
129 const char *gai_strerror(int errnum)
133 case EAI_SUCCESS: return "No error";
134 case EAI_FAIL: return "Permanent resolution failure";
135 default: return "UNKNOWN";