forked from mirrors/tftp-hpa-google
IPv6 infrastructure support
Add autoconf rules to detect IPv6 availability and some of the neeeded support functions. Add stubs for getaddrinfo and inet_ntop. You can disable IPv6 at compile time with ./configure --without-ipv6 Signed-off-by: Karsten Keil <kkeil@suse.de> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
parent
57ca281980
commit
7fe0fb941c
5 changed files with 355 additions and 6 deletions
121
lib/getaddrinfo.c
Normal file
121
lib/getaddrinfo.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* getaddrinfo.c
|
||||
*
|
||||
* Simple version of getaddrinfo()
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
extern int errno;
|
||||
extern int h_errno;
|
||||
|
||||
void freeaddrinfo(struct addrinfo *res)
|
||||
{
|
||||
if (!res)
|
||||
return;
|
||||
if (res->ai_next)
|
||||
freeaddrinfo(res->ai_next);
|
||||
if (res->ai_addr)
|
||||
free(res->ai_addr);
|
||||
if (res->ai_canonname)
|
||||
free(res->ai_canonname);
|
||||
free(res);
|
||||
}
|
||||
|
||||
int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints,
|
||||
struct addrinfo **res)
|
||||
{
|
||||
struct hostent *host;
|
||||
struct sockaddr *sa;
|
||||
int err, size = 0;
|
||||
|
||||
if ((!node) || (!res)) {
|
||||
errno = EINVAL;
|
||||
return EAI_SYSTEM;
|
||||
}
|
||||
*res = NULL;
|
||||
/* we do not support service in this version */
|
||||
if (service) {
|
||||
errno = EINVAL;
|
||||
return EAI_SYSTEM;
|
||||
}
|
||||
host = gethostbyname(node);
|
||||
if (!host)
|
||||
return EAI_NONAME;
|
||||
if (hints) {
|
||||
if (hints->ai_family != AF_UNSPEC) {
|
||||
if (hints->ai_family != host->h_addrtype)
|
||||
return EAI_ADDRFAMILY;
|
||||
}
|
||||
}
|
||||
*res = malloc(sizeof(struct addrinfo));
|
||||
if (!*res) {
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
memset(*res, 0, sizeof(struct addrinfo));
|
||||
(*res)->ai_family = host->h_addrtype;
|
||||
if (host->h_length) {
|
||||
if (host->h_addrtype == AF_INET)
|
||||
size = sizeof(struct sockaddr_in);
|
||||
#ifdef HAVE_IPV6
|
||||
else if (host->h_addrtype == AF_INET6)
|
||||
size = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
else {
|
||||
free(*res);
|
||||
*res = NULL;
|
||||
return EAI_ADDRFAMILY;
|
||||
}
|
||||
sa = malloc(size);
|
||||
if (!sa) {
|
||||
free(*res);
|
||||
*res = NULL;
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
memset(sa, 0, size);
|
||||
(*res)->ai_addr = sa;
|
||||
(*res)->ai_addrlen = size;
|
||||
sa->sa_family = host->h_addrtype;
|
||||
if (host->h_addrtype == AF_INET)
|
||||
memcpy(&((struct sockaddr_in *)sa)->sin_addr, host->h_addr, host->h_length);
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
memcpy(&((struct sockaddr_in6 *)sa)->sin6_addr, host->h_addr, host->h_length);
|
||||
#endif
|
||||
}
|
||||
if (host->h_name)
|
||||
(*res)->ai_canonname = strdup(host->h_name);
|
||||
|
||||
/* we only handle the first address entry and do not build a list now */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *gai_strerror(int errcode)
|
||||
{
|
||||
const char *s = NULL;
|
||||
|
||||
switch(errcode) {
|
||||
case 0:
|
||||
s = "no error";
|
||||
break;
|
||||
case EAI_MEMORY:
|
||||
s = "no memory";
|
||||
break;
|
||||
case EAI_SYSTEM:
|
||||
s = strerror(errno);
|
||||
break;
|
||||
case EAI_NONAME:
|
||||
s = hstrerror(h_errno);
|
||||
break;
|
||||
case EAI_ADDRFAMILY:
|
||||
s = "address does not match address family";
|
||||
break;
|
||||
default:
|
||||
s = "unknown error code";
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue