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);
}
Beispiel #2
0
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);
}
Beispiel #3
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);
}
Beispiel #4
0
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);
}