Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
/*% 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);
}