getaddresses.c revision c110d61b173a68420d19858abb80285be0dc1120
/*
* Copyright (C) 2004, 2005, 2007, 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2001, 2002 Internet Software Consortium.
*
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: getaddresses.c,v 1.22 2007/06/19 23:47:16 tbox Exp $ */
/*! \file */
#include <config.h>
#include <string.h>
#include <isc/netscope.h>
#include <isc/sockaddr.h>
#include <bind9/getaddresses.h>
#ifdef HAVE_ADDRINFO
#ifdef HAVE_GETADDRINFO
#ifdef HAVE_GAISTRERROR
#define USE_GETADDRINFO
#endif
#endif
#endif
#ifndef USE_GETADDRINFO
#ifndef ISC_PLATFORM_NONSTDHERRNO
extern int h_errno;
#endif
#endif
{
int i;
#ifdef USE_GETADDRINFO
int result;
#else
#endif
/*
* Try IPv4, then IPv6. In order to handle the extended format
* for IPv6 scoped addresses (address%scope_ID), we'll use a local
* working buffer of 128 bytes. The length is an ad-hoc value, but
* should be enough for this purpose; the buffer can contain a string
* of at least 80 bytes for scope_ID in addition to any IPv6 numeric
* addresses (up to 46 bytes), the delimiter character and the
* terminating NULL character.
*/
if (have_ipv4)
else
*addrcount = 1;
return (ISC_R_SUCCESS);
char tmpbuf[128], *d;
isc_uint32_t zone = 0;
if (d != NULL)
*d = '\0';
if (!have_ipv6)
return (ISC_R_FAMILYNOSUPPORT);
if (d != NULL) {
#ifdef ISC_PLATFORM_HAVESCOPEID
if (iresult != ISC_R_SUCCESS)
return (iresult);
#else
/*
* The extended format is specified while the
* system does not provide the ability to use
* it. Throw an explicit error instead of
* ignoring the specified value.
*/
return (ISC_R_BADADDRESSFORM);
#endif
}
(const isc_netaddr_t *)&na,
port);
*addrcount = 1;
return (ISC_R_SUCCESS);
}
}
#ifdef USE_GETADDRINFO
if (!have_ipv6)
else if (!have_ipv4)
else {
#ifdef AI_ADDRCONFIG
#endif
}
#ifdef AI_ADDRCONFIG
#endif
switch (result) {
case 0:
break;
case EAI_NONAME:
case EAI_NODATA:
#endif
return (ISC_R_NOTFOUND);
#ifdef AI_ADDRCONFIG
case EAI_BADFLAGS:
goto again;
}
#endif
default:
return (ISC_R_FAILURE);
}
{
continue;
struct sockaddr_in *sin;
} else {
struct sockaddr_in6 *sin6;
port);
}
i++;
}
*addrcount = i;
#else
switch (h_errno) {
case HOST_NOT_FOUND:
#ifdef NO_DATA
case NO_DATA:
#endif
case NO_ADDRESS:
#endif
return (ISC_R_NOTFOUND);
default:
return (ISC_R_FAILURE);
}
}
return (ISC_R_NOTFOUND);
for (i = 0; i < addrsize; i++) {
break;
} else {
break;
}
}
*addrcount = i;
#endif
if (*addrcount == 0)
return (ISC_R_NOTFOUND);
else
return (ISC_R_SUCCESS);
}