/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* 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.
*/
#if !defined(LINT) && !defined(CODECENTER)
#endif
/* Imports */
#include "port_before.h"
#if !defined(__BIND_NOSTATIC)
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <netdb.h>
#include <resolv.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <irs.h>
#include <isc/memcluster.h>
#include "port_after.h"
#include "irs_p.h"
#include "irs_data.h"
/* Definitions */
struct pvt {
};
/* Forward */
#ifdef SUNW_OVERRIDE_RETRY
extern int __res_retry(int);
extern int __res_retry_reset(void);
#endif /* SUNW_OVERRIDE_RETRY */
/* Public */
struct hostent *
}
struct hostent *
}
struct hostent *
}
struct hostent *
gethostent() {
return (gethostent_p(net_data));
}
void
}
void
endhostent() {
}
/* Shared private. */
struct hostent *
if (!net_data)
return (NULL);
if (hp)
return (hp);
}
}
struct hostent *
const char *cp;
char **hap;
return (NULL);
}
return (hp);
#ifdef SUNW_OVERRIDE_RETRY
#endif /* SUNW_OVERRIDE_RETRY */
#ifdef SUNW_OVERRIDE_RETRY
#endif /* SUNW_OVERRIDE_RETRY */
if (!net_data->ho_stayopen)
endhostent();
}
struct hostent *
char **hap;
return (NULL);
hap++)
if (!net_data->ho_stayopen)
endhostent();
}
struct hostent *
return (NULL);
continue;
}
void
return;
if (stayopen == 0)
}
void
}
#ifndef IN6_IS_ADDR_V4COMPAT
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
((x)->s6_addr[12] != 0 || \
(x)->s6_addr[13] != 0 || \
(x)->s6_addr[14] != 0 || \
((x)->s6_addr[15] != 0 && \
#endif
#ifndef IN6_IS_ADDR_V4MAPPED
#endif
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
static int scan_interfaces(int *, int *);
/*%
* Public functions
*/
/*%
* AI_V4MAPPED + AF_INET6
* If no IPv6 address then a query for IPv4 and map returned values.
*
* AI_ALL + AI_V4MAPPED + AF_INET6
* Return IPv6 and IPv4 mapped.
*
* AI_ADDRCONFIG
* Only return IPv6 / IPv4 address if there is an interface of that
* type active.
*/
struct hostent *
int tmp_err;
*error_num = NO_RECOVERY;
return (NULL);
}
/* If we care about active interfaces then check. */
if ((flags & AI_ADDRCONFIG) != 0)
*error_num = NO_RECOVERY;
return (NULL);
}
/* Check for literal address. */
/* Impossible combination? */
return (NULL);
}
/* Literal address? */
}
return (NULL);
} else {
}
}
if (have_v4 &&
return (NULL);
}
} else
return (he3);
}
struct hostent *
/* Sanity Checks. */
#ifdef ORIGINAL_ISC_CODE
#else
/* this change was added circa May 2009, but not in ISC libbind 6.0 */
#endif /* ORIGINAL_ISC_CODE */
*error_num = NO_RECOVERY;
return (NULL);
}
switch (af) {
case AF_INET:
*error_num = NO_RECOVERY;
return (NULL);
}
break;
case AF_INET6:
*error_num = NO_RECOVERY;
return (NULL);
}
break;
default:
*error_num = NO_RECOVERY;
return (NULL);
}
/*
* Lookup IPv4 and IPv4 mapped/compatible addresses
*/
cp += 12;
return (NULL);
}
return (NULL);
/*
* Restore original address if mapped/compatible.
*/
return (he2);
}
/*
* Lookup IPv6 address.
*/
return (NULL);
}
return (NULL);
}
}
void
char **cpp;
cpp++;
addresses++;
}
cpp++;
names++;
}
}
/*%
* Private
*/
/*%
* Scan the interface table and set have_v4 and have_v6 depending
* upon whether there are IPv4 and IPv6 interface addresses.
*
* Returns:
* 0 on success
* -1 on failure.
*/
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \
!defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
#ifdef __hpux
#else
#define SETFAMILYFLAGS
#endif
#ifdef __hpux
#else
#endif
static void
int s, cpsize, n;
/* Get interface list from system. */
goto cleanup;
/*
* Grow buffer until large enough to contain all interface
* descriptions.
*/
for (;;) {
goto cleanup;
#ifdef SETFAMILYFLAGS
lifc.lifc_flags = 0;
#endif
/*
* Some OS's just return what will fit rather
* than set EINVAL if the buffer is too small
* to fit all the interfaces in. If
* lifc.lifc_len is too near to the end of the
* buffer we will grow it just in case and
* retry.
*/
break;
}
goto cleanup;
if (bufsiz > 1000000)
goto cleanup;
bufsiz += 4096;
}
/* Parse system's interface list. */
#ifdef HAVE_SA_LEN
#ifdef FIX_ZERO_SA_LEN
#endif
#ifdef HAVE_MINIMUM_IFREQ
(int)(sizeof (struct sockaddr));
#else
#endif /* HAVE_MINIMUM_IFREQ */
#elif defined SIOCGIFCONF_ADDR
#else
/* XXX maybe this should be a hard error? */
continue;
#endif
case AF_INET:
if (*have_v4 == 0) {
&((struct sockaddr_in *)
sizeof in4);
break;
if (n < 0)
break;
break;
*have_v4 = 1;
}
break;
case AF_INET6:
if (*have_v6 == 0) {
&((struct sockaddr_in6 *)
break;
if (n < 0)
break;
break;
*have_v6 = 1;
}
break;
}
}
close(s);
/* printf("scan interface -> 4=%d 6=%d\n", *have_v4, *have_v6); */
return;
if (s != -1)
close(s);
/* printf("scan interface -> 4=%d 6=%d\n", *have_v4, *have_v6); */
return;
}
#endif
#ifndef IF_NAMESIZE
# ifdef IFNAMSIZ
# else
# endif
#endif
static void
return;
*have_v6 = 1;
return;
}
#endif
static int
union {
} u;
int s, n;
/* Set to zero. Used as loop terminators below. */
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \
!defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
/*
* Try to scan the interfaces using IPv6 ioctls().
*/
return (0);
#endif
#ifdef __linux
#endif
/* Get interface list from system. */
goto err_ret;
/*
* Grow buffer until large enough to contain all interface
* descriptions.
*/
for (;;) {
goto err_ret;
#ifdef IRIX_EMUL_IOCTL_SIOCGIFCONF
/*
* This is a fix for IRIX OS in which the call to ioctl with
* the flag SIOCGIFCONF may not return an entry for all the
* interfaces like most flavors of Unix.
*/
if (emul_ioctl(&ifc) >= 0)
break;
#else
/*
* Some OS's just return what will fit rather
* than set EINVAL if the buffer is too small
* to fit all the interfaces in. If
* ifc.ifc_len is too near to the end of the
* buffer we will grow it just in case and
* retry.
*/
break;
}
#endif
goto err_ret;
if (bufsiz > 1000000)
goto err_ret;
bufsiz += 4096;
}
/* Parse system's interface list. */
#ifdef HAVE_SA_LEN
#ifdef FIX_ZERO_SA_LEN
#endif
#ifdef HAVE_MINIMUM_IFREQ
(int)(sizeof (struct sockaddr));
#else
#endif /* HAVE_MINIMUM_IFREQ */
#elif defined SIOCGIFCONF_ADDR
#else
/* XXX maybe this should be a hard error? */
continue;
#endif
case AF_INET:
if (*have_v4 == 0) {
&((struct sockaddr_in *)
sizeof in4);
break;
if (n < 0)
break;
break;
*have_v4 = 1;
}
break;
case AF_INET6:
if (*have_v6 == 0) {
&((struct sockaddr_in6 *)
sizeof in6);
break;
if (n < 0)
break;
break;
*have_v6 = 1;
}
break;
}
}
close(s);
/* printf("scan interface -> 4=%d 6=%d\n", *have_v4, *have_v6); */
return (0);
if (s != -1)
close(s);
/* printf("scan interface -> 4=%d 6=%d\n", *have_v4, *have_v6); */
return (-1);
}
static struct hostent *
int len = 0;
/*
* Work out array sizes;
*/
addresses++;
cpp++;
}
names++;
cpp++;
}
}
addresses++;
cpp++;
}
names++;
cpp++;
}
}
}
if (addresses == 1) {
*error_num = NO_ADDRESS;
return (NULL);
}
goto no_recovery;
goto cleanup0;
/* copy addresses */
goto cleanup1;
/* convert to mapped if required */
sizeof in6addr_mapped);
INADDRSZ);
} else {
}
cpp++;
npp++;
}
}
goto cleanup1;
/* convert to mapped if required */
sizeof in6addr_mapped);
INADDRSZ);
} else {
}
cpp++;
npp++;
}
}
goto cleanup1;
/* copy aliases */
goto cleanup2;
npp++;
cpp++;
}
/* copy hostname */
goto cleanup2;
/* set address type and length */
return(he);
cpp++;
}
cpp++;
}
*error_num = NO_RECOVERY;
return (NULL);
}
static struct net_data *
init() {
goto error;
#ifdef SUNW_SETHERRNO
#endif /* SUNW_SETHERRNO */
return (NULL);
}
}
return (net_data);
}
static void
}
}
static struct hostent *
return (NULL);
}
#ifndef __bsdi__
/*
* Unlike its forebear(inet_aton), our friendly inet_pton() is strict
* in its interpretation of its input, and it will only return "1" if
* the input string is a formally valid(and thus unambiguous with
* respect to host names) internet address specification for this AF.
*
* This means "telnet 0xdeadbeef" and "telnet 127.1" are dead now.
*/
#else
/* BSDI XXX
* We put this back to inet_aton -- we really want the old behavior
* Long live 127.1...
*/
#endif
return (NULL);
}
}
switch(af) {
case AF_INET:
break;
case AF_INET6:
break;
default:
return (NULL);
}
}
#ifdef grot /*%< for future use in gethostbyaddr(), for "SUNSECURITY" */
char **haddr;
/*
* turn off search as the name should be absolute,
* 'localhost' should be matched by defnames
*/
return (NULL);
}
break;
if (!*haddr) {
return (NULL);
}
}
#endif /* grot */
#endif /*__BIND_NOSTATIC*/
/*! \file */