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); }
/*% Prints the config data structure to the FILE. */ lwres_result_t lwres_conf_print(lwres_context_t *ctx, FILE *fp) { int i; int af; char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; const char *p; lwres_conf_t *confdata; lwres_addr_t tmpaddr; REQUIRE(ctx != NULL); confdata = &ctx->confdata; REQUIRE(confdata->nsnext <= LWRES_CONFMAXNAMESERVERS); for (i = 0; i < confdata->nsnext; i++) { af = lwresaddr2af(confdata->nameservers[i].family); p = lwres_net_ntop(af, confdata->nameservers[i].address, tmp, sizeof(tmp)); if (p != tmp) return (LWRES_R_FAILURE); fprintf(fp, "nameserver %s\n", tmp); } for (i = 0; i < confdata->lwnext; i++) { af = lwresaddr2af(confdata->lwservers[i].family); p = lwres_net_ntop(af, confdata->lwservers[i].address, tmp, sizeof(tmp)); if (p != tmp) return (LWRES_R_FAILURE); fprintf(fp, "lwserver %s\n", tmp); } if (confdata->domainname != NULL) { fprintf(fp, "domain %s\n", confdata->domainname); } else if (confdata->searchnxt > 0) { REQUIRE(confdata->searchnxt <= LWRES_CONFMAXSEARCH); fprintf(fp, "search"); for (i = 0; i < confdata->searchnxt; i++) fprintf(fp, " %s", confdata->search[i]); fputc('\n', fp); } REQUIRE(confdata->sortlistnxt <= LWRES_CONFMAXSORTLIST); if (confdata->sortlistnxt > 0) { fputs("sortlist", fp); for (i = 0; i < confdata->sortlistnxt; i++) { af = lwresaddr2af(confdata->sortlist[i].addr.family); p = lwres_net_ntop(af, confdata->sortlist[i].addr.address, tmp, sizeof(tmp)); if (p != tmp) return (LWRES_R_FAILURE); fprintf(fp, " %s", tmp); tmpaddr = confdata->sortlist[i].mask; memset(&tmpaddr.address, 0xff, tmpaddr.length); if (memcmp(&tmpaddr.address, confdata->sortlist[i].mask.address, confdata->sortlist[i].mask.length) != 0) { af = lwresaddr2af( confdata->sortlist[i].mask.family); p = lwres_net_ntop (af, confdata->sortlist[i].mask.address, tmp, sizeof(tmp)); if (p != tmp) return (LWRES_R_FAILURE); fprintf(fp, "/%s", tmp); } } fputc('\n', fp); } if (confdata->resdebug) fprintf(fp, "options debug\n"); if (confdata->ndots > 0) fprintf(fp, "options ndots:%d\n", confdata->ndots); if (confdata->no_tld_query) fprintf(fp, "options no_tld_query\n"); return (LWRES_R_SUCCESS); }