diff options
Diffstat (limited to 'lib/lwres/getipnode.c')
-rw-r--r-- | lib/lwres/getipnode.c | 100 |
1 files changed, 55 insertions, 45 deletions
diff --git a/lib/lwres/getipnode.c b/lib/lwres/getipnode.c index a6c50c2..4331638 100644 --- a/lib/lwres/getipnode.c +++ b/lib/lwres/getipnode.c @@ -1,5 +1,5 @@ /* - * 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 @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: getipnode.c,v 1.42 2007/06/18 23:47:51 tbox Exp $ */ +/* $Id: getipnode.c,v 1.42.332.5 2009/09/01 23:47:05 tbox Exp $ */ /*! \file */ @@ -23,7 +23,7 @@ * 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 @@ -34,90 +34,90 @@ * }; * #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> @@ -146,21 +146,21 @@ LIBLWRES_EXTERNAL_DATA const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; #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 }; /*** @@ -202,7 +202,7 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) { 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; @@ -275,7 +275,6 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) { (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); @@ -285,7 +284,12 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) { 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; + } } } @@ -437,9 +441,15 @@ lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num) { 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) @@ -492,7 +502,7 @@ lwres_freehostent(struct hostent *he) { */ #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \ - !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF) + !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF) #ifdef __hpux #define lifc_len iflc_len @@ -504,7 +514,7 @@ lwres_freehostent(struct hostent *he) { #define ISC_HAVE_LIFC_FLAGS 1 #define LIFCONF lifconf #endif - + #ifdef __hpux #define lifr_addr iflr_addr #define lifr_name iflr_name @@ -557,7 +567,7 @@ scan_interfaces6(int *have_v4, int *have_v6) { /* * 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. @@ -619,13 +629,13 @@ scan_interfaces6(int *have_v4, int *have_v6) { 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) @@ -675,7 +685,7 @@ scan_interfaces(int *have_v4, int *have_v6) { 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(). */ @@ -721,7 +731,7 @@ scan_interfaces(int *have_v4, int *have_v6) { /* * 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. @@ -786,7 +796,7 @@ scan_interfaces(int *have_v4, int *have_v6) { if ((u.ifreq.ifr_flags & IFF_UP) == 0) break; *have_v4 = 1; - } + } break; case AF_INET6: if (*have_v6 == 0) { |