/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: getipnode.c,v 1.42 2007/06/18 23:47:51 tbox Exp $ */
+/* $Id: getipnode.c,v 1.47 2009/09/01 23:47:45 tbox Exp $ */
/*! \file */
* These functions perform thread safe, protocol independent
* nodename-to-address and address-to-nodename translation as defined in
* RFC2553. This use a struct hostent which is defined in namedb.h:
- *
+ *
* \code
* struct hostent {
* char *h_name; // official name of host
* };
* #define h_addr h_addr_list[0] // address, for backward compatibility
* \endcode
- *
+ *
* The members of this structure are:
- *
+ *
* \li h_name:
* The official (canonical) name of the host.
- *
+ *
* \li h_aliases:
* A NULL-terminated array of alternate names (nicknames) for the
* host.
- *
+ *
* \li h_addrtype:
* The type of address being returned - usually PF_INET or
* PF_INET6.
- *
+ *
* \li h_length:
* The length of the address in bytes.
- *
+ *
* \li h_addr_list:
* A NULL terminated array of network addresses for the host. Host
* addresses are returned in network byte order.
- *
+ *
* lwres_getipnodebyname() looks up addresses of protocol family af for
* the hostname name. The flags parameter contains ORed flag bits to
* specify the types of addresses that are searched for, and the types of
* addresses that are returned. The flag bits are:
- *
+ *
* \li #AI_V4MAPPED:
* This is used with an af of #AF_INET6, and causes IPv4 addresses
* to be returned as IPv4-mapped IPv6 addresses.
- *
+ *
* \li #AI_ALL:
* This is used with an af of #AF_INET6, and causes all known
* addresses (IPv6 and IPv4) to be returned. If #AI_V4MAPPED is
* also set, the IPv4 addresses are return as mapped IPv6
* addresses.
- *
+ *
* \li #AI_ADDRCONFIG:
* Only return an IPv6 or IPv4 address if here is an active
* network interface of that type. This is not currently
* implemented in the BIND 9 lightweight resolver, and the flag is
* ignored.
- *
+ *
* \li #AI_DEFAULT:
* This default sets the #AI_V4MAPPED and #AI_ADDRCONFIG flag bits.
- *
+ *
* lwres_getipnodebyaddr() performs a reverse lookup of address src which
* is len bytes long. af denotes the protocol family, typically PF_INET
* or PF_INET6.
- *
+ *
* lwres_freehostent() releases all the memory associated with the struct
* hostent pointer. Any memory allocated for the h_name, h_addr_list
* and h_aliases is freed, as is the memory for the hostent structure
* itself.
- *
+ *
* \section getipnode_return Return Values
- *
+ *
* If an error occurs, lwres_getipnodebyname() and
* lwres_getipnodebyaddr() set *error_num to an appropriate error code
* and the function returns a NULL pointer. The error codes and their
* meanings are defined in \link netdb.h <lwres/netdb.h>\endlink:
- *
+ *
* \li #HOST_NOT_FOUND:
* No such host is known.
- *
+ *
* \li #NO_ADDRESS:
* The server recognised the request and the name but no address
* is available. Another type of request to the name server for
* the domain might return an answer.
- *
+ *
* \li #TRY_AGAIN:
* A temporary and possibly transient error occurred, such as a
* failure of a server to respond. The request may succeed if
* retried.
- *
+ *
* \li #NO_RECOVERY:
* An unexpected failure occurred, and retrying the request is
* pointless.
- *
+ *
* lwres_hstrerror() translates these error codes to suitable error
* messages.
- *
+ *
* \section getipnode_see See Also
- *
- * getaddrinfo.c, gethost.c, getnameinfo.c, herror.c, RFC2553
+ *
+ * getaddrinfo.c, gethost.c, getnameinfo.c, herror.c, RFC2553
*/
#include <config.h>
#ifndef IN6_IS_ADDR_V4COMPAT
static const unsigned char in6addr_compat[12] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#define IN6_IS_ADDR_V4COMPAT(x) (!memcmp((x)->s6_addr, in6addr_compat, 12) && \
- ((x)->s6_addr[12] != 0 || \
- (x)->s6_addr[13] != 0 || \
- (x)->s6_addr[14] != 0 || \
- ((x)->s6_addr[15] != 0 && \
- (x)->s6_addr[15] != 1)))
+ ((x)->s6_addr[12] != 0 || \
+ (x)->s6_addr[13] != 0 || \
+ (x)->s6_addr[14] != 0 || \
+ ((x)->s6_addr[15] != 0 && \
+ (x)->s6_addr[15] != 1)))
#endif
#ifndef IN6_IS_ADDR_V4MAPPED
#define IN6_IS_ADDR_V4MAPPED(x) (!memcmp((x)->s6_addr, in6addr_mapped, 12))
#endif
static const unsigned char in6addr_mapped[12] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff
};
/***
struct in6_addr in6;
struct hostent he, *he1 = NULL, *he2 = NULL, *he3 = NULL;
int v4 = 0, v6 = 0;
- int tmp_err;
+ int tmp_err = 0;
lwres_context_t *lwrctx = NULL;
lwres_gabnresponse_t *by = NULL;
int n;
(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
tmp_err = NO_RECOVERY;
if (have_v6 && af == AF_INET6) {
-
n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V6, &by);
if (n == 0) {
he1 = hostfromname(by, AF_INET6);
goto cleanup;
}
} else {
- tmp_err = HOST_NOT_FOUND;
+ if (n == LWRES_R_NOTFOUND)
+ tmp_err = HOST_NOT_FOUND;
+ else {
+ *error_num = NO_RECOVERY;
+ goto cleanup;
+ }
}
}
if (n != 0) {
lwres_conf_clear(lwrctx);
lwres_context_destroy(&lwrctx);
- *error_num = HOST_NOT_FOUND;
+
+ if (n == LWRES_R_NOTFOUND)
+ *error_num = HOST_NOT_FOUND;
+ else
+ *error_num = NO_RECOVERY;
+
return (NULL);
}
+
he1 = hostfromaddr(by, AF_INET6, src);
lwres_gnbaresponse_free(lwrctx, &by);
if (he1 == NULL)
*/
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \
- !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
+ !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
#ifdef __hpux
#define lifc_len iflc_len
#define ISC_HAVE_LIFC_FLAGS 1
#define LIFCONF lifconf
#endif
-
+
#ifdef __hpux
#define lifr_addr iflr_addr
#define lifr_name iflr_name
/*
* 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
+ * 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.
if ((lifreq.lifr_flags & IFF_UP) == 0)
break;
*have_v4 = 1;
- }
+ }
break;
case AF_INET6:
if (*have_v6 == 0) {
memcpy(&in6,
&((struct sockaddr_in6 *)
- &lifreq.lifr_addr)->sin6_addr,
+ &lifreq.lifr_addr)->sin6_addr,
sizeof(in6));
if (memcmp(&in6, &in6addr_any,
sizeof(in6)) == 0)
InitSockets();
#endif
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \
- !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
+ !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
/*
* Try to scan the interfaces using IPv6 ioctls().
*/
/*
* 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
+ * 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.
if ((u.ifreq.ifr_flags & IFF_UP) == 0)
break;
*have_v4 = 1;
- }
+ }
break;
case AF_INET6:
if (*have_v6 == 0) {