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  }