static void test_gabn(const char *target) { lwres_gabnresponse_t *res; lwres_addr_t *addr; int ret; unsigned int i; char outbuf[64]; res = NULL; ret = lwres_getaddrsbyname(ctx, target, LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6, &res); printf("gabn %s ret == %d\n", target, ret); if (ret != 0) { printf("FAILURE!\n"); if (res != NULL) lwres_gabnresponse_free(ctx, &res); return; } printf("Returned real name: (%u, %s)\n", res->realnamelen, res->realname); printf("%u aliases:\n", res->naliases); for (i = 0; i < res->naliases; i++) printf("\t(%u, %s)\n", res->aliaslen[i], res->aliases[i]); printf("%u addresses:\n", res->naddrs); addr = LWRES_LIST_HEAD(res->addrs); for (i = 0; i < res->naddrs; i++) { INSIST(addr != NULL); if (addr->family == LWRES_ADDRTYPE_V4) (void)inet_ntop(AF_INET, addr->address, outbuf, sizeof(outbuf)); else (void)inet_ntop(AF_INET6, addr->address, outbuf, sizeof(outbuf)); printf("\tAddr len %u family %08x %s\n", addr->length, addr->family, outbuf); addr = LWRES_LIST_NEXT(addr, link); } lwres_gabnresponse_free(ctx, &res); }
static void test_gabn(const char *target, lwres_result_t expected, const char *address, lwres_uint32_t af) { lwres_gabnresponse_t *res; unsigned char addrbuf[16]; lwres_addr_t *addr; char outbuf[64]; unsigned int len; lwres_result_t ret; res = NULL; ret = lwres_getaddrsbyname(ctx, target, LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6, &res); if (ret != expected) { printf("I:gabn(%s) failed: %d\n", target, ret); if (res != NULL) lwres_gabnresponse_free(ctx, &res); fails++; return; } if (ret == LWRES_R_SUCCESS) { if (af == LWRES_ADDRTYPE_V4) { len = 4; ret = inet_pton(AF_INET, address, addrbuf); assert(ret == 1); } else { len = 16; ret = inet_pton(AF_INET6, address, addrbuf); assert(ret == 1); } addr = LWRES_LIST_HEAD(res->addrs); if (addr == NULL) { printf("I:gabn(%s) returned empty list\n", target); fails++; return; } while (addr != NULL) { if (addr->family != af || addr->length != len || memcmp(addr->address, addrbuf, len) == 0) break; addr = LWRES_LIST_NEXT(addr, link); } if (addr == NULL) { addr = LWRES_LIST_HEAD(res->addrs); if (addr->family == LWRES_ADDRTYPE_V4) (void)inet_ntop(AF_INET, addr->address, outbuf, sizeof(outbuf)); else (void)inet_ntop(AF_INET6, addr->address, outbuf, sizeof(outbuf)); printf("I:gabn(%s) returned %s, expected %s\n", target, outbuf, address); fails++; return; } } if (res != NULL) lwres_gabnresponse_free(ctx, &res); }
struct hostent * lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) { int have_v4 = 1, have_v6 = 1; struct in_addr in4; struct in6_addr in6; struct hostent he, *he1 = NULL, *he2 = NULL, *he3 = NULL; int v4 = 0, v6 = 0; int tmp_err = 0; lwres_context_t *lwrctx = NULL; lwres_gabnresponse_t *by = NULL; int n; /* * If we care about active interfaces then check. */ if ((flags & AI_ADDRCONFIG) != 0) if (scan_interfaces(&have_v4, &have_v6) == -1) { *error_num = NO_RECOVERY; return (NULL); } /* Check for literal address. */ if ((v4 = lwres_net_pton(AF_INET, name, &in4)) != 1) v6 = lwres_net_pton(AF_INET6, name, &in6); /* * Impossible combination? */ if ((af == AF_INET6 && (flags & AI_V4MAPPED) == 0 && v4 == 1) || (af == AF_INET && v6 == 1) || (have_v4 == 0 && v4 == 1) || (have_v6 == 0 && v6 == 1) || (have_v4 == 0 && af == AF_INET) || (have_v6 == 0 && af == AF_INET6 && (((flags & AI_V4MAPPED) != 0 && have_v4) || (flags & AI_V4MAPPED) == 0))) { *error_num = HOST_NOT_FOUND; return (NULL); } /* * Literal address? */ if (v4 == 1 || v6 == 1) { char *addr_list[2]; char *aliases[1]; char mappedname[sizeof("::ffff:123.123.123.123")]; union { const char *const_name; char *deconst_name; } u; u.const_name = name; if (v4 == 1 && af == AF_INET6) { strcpy(mappedname, "::ffff:"); lwres_net_ntop(AF_INET, (char *)&in4, mappedname + sizeof("::ffff:") - 1, sizeof(mappedname) - sizeof("::ffff:") + 1); he.h_name = mappedname; } else he.h_name = u.deconst_name; he.h_addr_list = addr_list; he.h_addr_list[0] = (v4 == 1) ? (char *)&in4 : (char *)&in6; he.h_addr_list[1] = NULL; he.h_aliases = aliases; he.h_aliases[0] = NULL; he.h_length = (v4 == 1) ? INADDRSZ : IN6ADDRSZ; he.h_addrtype = (v4 == 1) ? AF_INET : AF_INET6; return (copyandmerge(&he, NULL, af, error_num)); } n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0); if (n != 0) { *error_num = NO_RECOVERY; goto cleanup; } (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); lwres_gabnresponse_free(lwrctx, &by); if (he1 == NULL) { *error_num = NO_RECOVERY; goto cleanup; } } else { if (n == LWRES_R_NOTFOUND) tmp_err = HOST_NOT_FOUND; else { *error_num = NO_RECOVERY; goto cleanup; } } } if (have_v4 && ((af == AF_INET) || (af == AF_INET6 && (flags & AI_V4MAPPED) != 0 && (he1 == NULL || (flags & AI_ALL) != 0)))) { n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V4, &by); if (n == 0) { he2 = hostfromname(by, AF_INET); lwres_gabnresponse_free(lwrctx, &by); if (he2 == NULL) { *error_num = NO_RECOVERY; goto cleanup; } } else if (he1 == NULL) { if (n == LWRES_R_NOTFOUND) *error_num = HOST_NOT_FOUND; else *error_num = NO_RECOVERY; goto cleanup; } } else *error_num = tmp_err; he3 = copyandmerge(he1, he2, af, error_num); cleanup: if (he1 != NULL) lwres_freehostent(he1); if (he2 != NULL) lwres_freehostent(he2); if (lwrctx != NULL) { lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); } return (he3); }
static int add_ipv6(const char *hostname, int flags, struct addrinfo **aip, int socktype, int port) { struct addrinfo *ai; lwres_context_t *lwrctx = NULL; lwres_gabnresponse_t *by = NULL; lwres_addr_t *addr; lwres_result_t lwres; int result = 0; lwres = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0); if (lwres != LWRES_R_SUCCESS) ERR(EAI_FAIL); (void) lwres_conf_parse(lwrctx, lwres_resolv_conf); if (hostname == NULL && (flags & AI_PASSIVE) == 0) { ai = ai_clone(*aip, AF_INET6); if (ai == NULL) { lwres_freeaddrinfo(*aip); ERR(EAI_MEMORY); } *aip = ai; ai->ai_socktype = socktype; SIN6(ai->ai_addr)->sin6_port = port; memcpy(&SIN6(ai->ai_addr)->sin6_addr, v6_loop, 16); } else { lwres = lwres_getaddrsbyname(lwrctx, hostname, LWRES_ADDRTYPE_V6, &by); if (lwres != LWRES_R_SUCCESS) { if (lwres == LWRES_R_NOTFOUND) goto cleanup; else ERR(EAI_FAIL); } addr = LWRES_LIST_HEAD(by->addrs); while (addr != NULL) { ai = ai_clone(*aip, AF_INET6); if (ai == NULL) { lwres_freeaddrinfo(*aip); ERR(EAI_MEMORY); } *aip = ai; ai->ai_socktype = socktype; SIN6(ai->ai_addr)->sin6_port = port; memcpy(&SIN6(ai->ai_addr)->sin6_addr, addr->address, 16); if (flags & AI_CANONNAME) { ai->ai_canonname = strdup(by->realname); if (ai->ai_canonname == NULL) ERR(EAI_MEMORY); } addr = LWRES_LIST_NEXT(addr, link); } } cleanup: if (by != NULL) lwres_gabnresponse_free(lwrctx, &by); if (lwrctx != NULL) { lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); } return (result); }