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