github.com/afumu/libc@v0.0.6/musl/src/network/gethostbyaddr_r.c (about) 1 #define _GNU_SOURCE 2 3 #include <sys/socket.h> 4 #include <netdb.h> 5 #include <string.h> 6 #include <netinet/in.h> 7 #include <errno.h> 8 #include <inttypes.h> 9 10 int gethostbyaddr_r(const void *a, socklen_t l, int af, 11 struct hostent *h, char *buf, size_t buflen, 12 struct hostent **res, int *err) 13 { 14 //TODO union { 15 //TODO struct sockaddr_in sin; 16 //TODO struct sockaddr_in6 sin6; 17 //TODO } sa = { .sin.sin_family = af }; 18 union { //TODO- 19 struct sockaddr_in sin; //TODO- 20 struct sockaddr_in6 sin6; //TODO- 21 } sa = {}; //TODO- 22 sa.sin.sin_family = af; //TODO- 23 socklen_t sl = af==AF_INET6 ? sizeof sa.sin6 : sizeof sa.sin; 24 int i; 25 26 *res = 0; 27 28 /* Load address argument into sockaddr structure */ 29 if (af==AF_INET6 && l==16) memcpy(&sa.sin6.sin6_addr, a, 16); 30 else if (af==AF_INET && l==4) memcpy(&sa.sin.sin_addr, a, 4); 31 else { 32 *err = NO_RECOVERY; 33 return EINVAL; 34 } 35 36 /* Align buffer and check for space for pointers and ip address */ 37 i = (uintptr_t)buf & sizeof(char *)-1; 38 if (!i) i = sizeof(char *); 39 if (buflen <= 5*sizeof(char *)-i + l) return ERANGE; 40 buf += sizeof(char *)-i; 41 buflen -= 5*sizeof(char *)-i + l; 42 43 h->h_addr_list = (void *)buf; 44 buf += 2*sizeof(char *); 45 h->h_aliases = (void *)buf; 46 buf += 2*sizeof(char *); 47 48 h->h_addr_list[0] = buf; 49 memcpy(h->h_addr_list[0], a, l); 50 buf += l; 51 h->h_addr_list[1] = 0; 52 h->h_aliases[0] = buf; 53 h->h_aliases[1] = 0; 54 55 switch (getnameinfo((void *)&sa, sl, buf, buflen, 0, 0, 0)) { 56 case EAI_AGAIN: 57 *err = TRY_AGAIN; 58 return EAGAIN; 59 case EAI_OVERFLOW: 60 return ERANGE; 61 default: 62 case EAI_MEMORY: 63 case EAI_SYSTEM: 64 case EAI_FAIL: 65 *err = NO_RECOVERY; 66 return errno; 67 case 0: 68 break; 69 } 70 71 h->h_addrtype = af; 72 h->h_length = l; 73 h->h_name = h->h_aliases[0]; 74 *res = h; 75 return 0; 76 }