152419Sjulian/*-
252419Sjulian * Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org>
3139823Simp * All rights reserved.
4139823Simp *
5139823Simp * Redistribution and use in source and binary forms, with or without
652419Sjulian * modification, are permitted provided that the following conditions
752419Sjulian * are met:
852419Sjulian * 1. Redistributions of source code must retain the above copyright
952419Sjulian *    notice, this list of conditions and the following disclaimer.
1052419Sjulian * 2. Redistributions in binary form must reproduce the above copyright
1152419Sjulian *    notice, this list of conditions and the following disclaimer in the
1252419Sjulian *    documentation and/or other materials provided with the distribution.
1352419Sjulian *
1452419Sjulian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1552419Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1652419Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1752419Sjulian * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1852419Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1952419Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2052419Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2152419Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2252419Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2352419Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2452419Sjulian * SUCH DAMAGE.
2552419Sjulian *
2652419Sjulian */
2752419Sjulian
2852419Sjulian#include <sys/param.h>
2952419Sjulian#include <sys/socket.h>
3052419Sjulian#include <arpa/inet.h>
3152419Sjulian#include <netinet/in.h>
3252419Sjulian#include <errno.h>
3352419Sjulian#include <netdb.h>
3452419Sjulian#include <resolv.h>
3552419Sjulian#include <stdio.h>
3652419Sjulian#include <stdlib.h>
3752419Sjulian#include <string.h>
3867506Sjulian#include <stringlist.h>
3952419Sjulian#include <unistd.h>
4052419Sjulian
4152752Sjulian#include <atf-c.h>
4252419Sjulian
4352419Sjulian#include "freebsd_test_suite/macros.h"
4452419Sjulian#include "testutil.h"
4552419Sjulian
4652419Sjulianenum test_methods {
47154604Sglebius	TEST_GETHOSTBYNAME2,
4852419Sjulian	TEST_GETHOSTBYADDR,
4952419Sjulian	TEST_GETHOSTBYNAME2_GETADDRINFO,
5052419Sjulian	TEST_GETHOSTBYADDR_GETNAMEINFO,
51161034Sglebius	TEST_BUILD_SNAPSHOT,
5252419Sjulian	TEST_BUILD_ADDR_SNAPSHOT
5352419Sjulian};
5452419Sjulian
5552419Sjulianstatic int ipnode_flags = 0;
5668031Sbrianstatic int af_type = AF_INET;
5752419Sjulianstatic bool use_ipnode_functions;
58161117Sglebius
5952419SjulianDECLARE_TEST_DATA(hostent)
6070870SjulianDECLARE_TEST_FILE_SNAPSHOT(hostent)
61227293SedDECLARE_1PASS_TEST(hostent)
6270870SjulianDECLARE_2PASS_TEST(hostent)
6370870Sjulian
6470870Sjulian/* These stubs will use gethostby***() or getipnodeby***() functions,
6570870Sjulian * depending on the use_ipnode_functions global variable value */
6653405Sarchiestatic struct hostent *__gethostbyname2(const char *, int);
6753405Sarchiestatic struct hostent *__gethostbyaddr(const void *, socklen_t, int);
6852419Sjulianstatic void __freehostent(struct hostent *);
6952419Sjulian
7072946Sjulianstatic void clone_hostent(struct hostent *, struct hostent const *);
7152419Sjulianstatic int compare_hostent(struct hostent *, struct hostent *, void *);
7252419Sjulianstatic void dump_hostent(struct hostent *);
7352752Sjulianstatic void free_hostent(struct hostent *);
7452752Sjulian
7570700Sjulianstatic int is_hostent_equal(struct hostent *, struct addrinfo *);
7652752Sjulian
77161117Sglebiusstatic void sdump_hostent(struct hostent *, char *, size_t);
7852752Sjulianstatic int hostent_read_hostlist_func(struct hostent *, char *);
79172629Smavstatic int hostent_read_snapshot_addr(char *, unsigned char *, size_t);
80172629Smavstatic int hostent_read_snapshot_func(struct hostent *, char *);
8152752Sjulian
8252419Sjulianstatic int hostent_test_correctness(struct hostent *, void *);
8368031Sbrianstatic int hostent_test_gethostbyaddr(struct hostent *, void *);
8497685Sarchiestatic int hostent_test_getaddrinfo_eq(struct hostent *, void *);
8568031Sbrianstatic int hostent_test_getnameinfo_eq(struct hostent *, void *);
8668845Sbrian
8768031SbrianIMPLEMENT_TEST_DATA(hostent)
8897685SarchieIMPLEMENT_TEST_FILE_SNAPSHOT(hostent)
8968031SbrianIMPLEMENT_1PASS_TEST(hostent)
9068031SbrianIMPLEMENT_2PASS_TEST(hostent)
9168031Sbrian
9297685Sarchiestatic struct hostent *
9368031Sbrian__gethostbyname2(const char *name, int af)
9468031Sbrian{
9568031Sbrian	struct hostent *he;
9697685Sarchie	int error;
9768031Sbrian
9868031Sbrian	if (use_ipnode_functions) {
9968031Sbrian		error = 0;
10068031Sbrian		he = getipnodebyname(name, af, ipnode_flags, &error);
10168031Sbrian		if (he == NULL)
10268031Sbrian			errno = error;
10368031Sbrian	} else
10468031Sbrian		he = gethostbyname2(name, af);
10568845Sbrian
10668031Sbrian	return (he);
10768031Sbrian}
10868031Sbrian
10968031Sbrianstatic struct hostent *
11068031Sbrian__gethostbyaddr(const void *addr, socklen_t len, int af)
11168031Sbrian{
11268845Sbrian	struct hostent *he;
11368031Sbrian	int error;
11468031Sbrian
11568031Sbrian	if (use_ipnode_functions) {
11668031Sbrian		error = 0;
11768031Sbrian		he = getipnodebyaddr(addr, len, af, &error);
11868031Sbrian		if (he == NULL)
11968845Sbrian			errno = error;
12068031Sbrian	} else
12168031Sbrian		he = gethostbyaddr(addr, len, af);
12268031Sbrian
12368031Sbrian	return (he);
12469922Sjulian}
12569922Sjulian
12669922Sjulianstatic void
12769922Sjulian__freehostent(struct hostent *he)
12869922Sjulian{
12969922Sjulian
13069922Sjulian	/* NOTE: checking for he != NULL - just in case */
13168031Sbrian	if (use_ipnode_functions && he != NULL)
13268031Sbrian		freehostent(he);
13368031Sbrian}
13468031Sbrian
13568031Sbrianstatic void
13668031Sbrianclone_hostent(struct hostent *dest, struct hostent const *src)
13768031Sbrian{
13868031Sbrian	ATF_REQUIRE(dest != NULL);
13968031Sbrian	ATF_REQUIRE(src != NULL);
14068031Sbrian
14168031Sbrian	char **cp;
14268031Sbrian	int aliases_num;
14368031Sbrian	int addrs_num;
14468031Sbrian	size_t offset;
14568031Sbrian
14668031Sbrian	memset(dest, 0, sizeof(struct hostent));
14768031Sbrian
14868031Sbrian	if (src->h_name != NULL) {
14968031Sbrian		dest->h_name = strdup(src->h_name);
150132703Sglebius		ATF_REQUIRE(dest->h_name != NULL);
151132703Sglebius	}
152132703Sglebius
153132703Sglebius	dest->h_addrtype = src->h_addrtype;
154132703Sglebius	dest->h_length = src->h_length;
155132703Sglebius
156132703Sglebius	if (src->h_aliases != NULL) {
157132703Sglebius		aliases_num = 0;
158132703Sglebius		for (cp = src->h_aliases; *cp; ++cp)
159132703Sglebius			++aliases_num;
160132703Sglebius
161132703Sglebius		dest->h_aliases = calloc(aliases_num + 1, sizeof(char *));
162132703Sglebius		ATF_REQUIRE(dest->h_aliases != NULL);
163132703Sglebius
164161117Sglebius		for (cp = src->h_aliases; *cp; ++cp) {
165161117Sglebius			dest->h_aliases[cp - src->h_aliases] = strdup(*cp);
166161117Sglebius			ATF_REQUIRE(dest->h_aliases[cp - src->h_aliases] != NULL);
167161117Sglebius		}
168161117Sglebius	}
169161117Sglebius
170161117Sglebius	if (src->h_addr_list != NULL) {
171288918Smav		addrs_num = 0;
172288918Smav		for (cp = src->h_addr_list; *cp; ++cp)
173288918Smav			++addrs_num;
174288918Smav
175288918Smav		dest->h_addr_list = calloc(addrs_num + 1, sizeof(char *));
176288918Smav		ATF_REQUIRE(dest->h_addr_list != NULL);
177288918Smav
17868031Sbrian		for (cp = src->h_addr_list; *cp; ++cp) {
17968031Sbrian			offset = cp - src->h_addr_list;
18068031Sbrian			dest->h_addr_list[offset] = malloc(src->h_length);
18152419Sjulian			ATF_REQUIRE(dest->h_addr_list[offset] != NULL);
18252419Sjulian			memcpy(dest->h_addr_list[offset],
183129823Sjulian			    src->h_addr_list[offset], src->h_length);
184129823Sjulian		}
185129823Sjulian	}
186129823Sjulian}
187129823Sjulian
188129823Sjulianstatic void
189161117Sglebiusfree_hostent(struct hostent *ht)
190129823Sjulian{
191129823Sjulian	char **cp;
192129823Sjulian
19352419Sjulian	ATF_REQUIRE(ht != NULL);
19452562Sjulian
19552419Sjulian	free(ht->h_name);
19652419Sjulian
19752419Sjulian	if (ht->h_aliases != NULL) {
19852419Sjulian		for (cp = ht->h_aliases; *cp; ++cp)
19952419Sjulian			free(*cp);
20052419Sjulian		free(ht->h_aliases);
20152419Sjulian	}
20253498Sjulian
20352419Sjulian	if  (ht->h_addr_list != NULL) {
20453498Sjulian		for (cp = ht->h_addr_list; *cp; ++cp)
20553498Sjulian			free(*cp);
20652419Sjulian		free(ht->h_addr_list);
20753498Sjulian	}
20852419Sjulian}
20952419Sjulian
21052419Sjulianstatic  int
21152419Sjuliancompare_hostent(struct hostent *ht1, struct hostent *ht2, void *mdata)
21252419Sjulian{
21352419Sjulian	char **c1, **c2, **ct, **cb;
21452419Sjulian	int b;
215154604Sglebius
21652419Sjulian	if (ht1 == ht2)
21752419Sjulian		return 0;
21852419Sjulian
21952419Sjulian	if (ht1 == NULL || ht2 == NULL)
22052419Sjulian		goto errfin;
22152419Sjulian
22252419Sjulian	if (ht1->h_name == NULL || ht2->h_name == NULL)
223138562Sglebius		goto errfin;
22452419Sjulian
22552419Sjulian	if (ht1->h_addrtype != ht2->h_addrtype ||
22697897Sarchie	    ht1->h_length != ht2->h_length ||
22752419Sjulian	    strcmp(ht1->h_name, ht2->h_name) != 0)
22852419Sjulian		goto errfin;
22952419Sjulian
23052419Sjulian	c1 = ht1->h_aliases;
23152419Sjulian	c2 = ht2->h_aliases;
23252419Sjulian
23352419Sjulian	if ((ht1->h_aliases == NULL || ht2->h_aliases == NULL) &&
23452419Sjulian	    ht1->h_aliases != ht2->h_aliases)
23552419Sjulian		goto errfin;
23652419Sjulian
23752419Sjulian	if (c1 != NULL && c2 != NULL) {
23866052Sarchie		cb = c1;
23952419Sjulian		for (;*c1; ++c1) {
240154604Sglebius			b = 0;
24152419Sjulian			for (ct = c2; *ct; ++ct) {
242154604Sglebius				if (strcmp(*c1, *ct) == 0) {
24352419Sjulian					b = 1;
24452419Sjulian					break;
245176775Smav				}
24652419Sjulian			}
24766052Sarchie			if (b == 0) {
24852419Sjulian				printf("h1 aliases item can't be found in h2 "
249175865Smav				    "aliases\n");
250175865Smav				goto errfin;
251175865Smav			}
252175865Smav		}
253175865Smav
254176775Smav		c1 = cb;
255175865Smav		for (;*c2; ++c2) {
256175865Smav			b = 0;
25752419Sjulian			for (ct = c1; *ct; ++ct) {
25852419Sjulian				if (strcmp(*c2, *ct) == 0) {
25952419Sjulian					b = 1;
260154604Sglebius					break;
26152419Sjulian				}
26252419Sjulian			}
26352419Sjulian			if (b == 0) {
26452419Sjulian				printf("h2 aliases item can't be found in h1 "
26552419Sjulian				    "aliases\n");
266154604Sglebius				goto errfin;
267154901Sglebius			}
268154901Sglebius		}
269161117Sglebius	}
270176775Smav
271175865Smav	c1 = ht1->h_addr_list;
272288918Smav	c2 = ht2->h_addr_list;
27352419Sjulian
274154604Sglebius	if ((ht1->h_addr_list == NULL || ht2->h_addr_list== NULL) &&
27552419Sjulian	    ht1->h_addr_list != ht2->h_addr_list)
27652419Sjulian		goto errfin;
27752419Sjulian
278154604Sglebius	if (c1 != NULL && c2 != NULL) {
279154604Sglebius		cb = c1;
28052419Sjulian		for (; *c1; ++c1) {
28152419Sjulian			b = 0;
28252419Sjulian			for (ct = c2; *ct; ++ct) {
283138562Sglebius				if (memcmp(*c1, *ct, ht1->h_length) == 0) {
28497897Sarchie					b = 1;
28597897Sarchie					break;
28652441Sjulian				}
28752419Sjulian			}
28852419Sjulian			if (b == 0) {
28952419Sjulian				printf("h1 addresses item can't be found in "
29052419Sjulian				    "h2 addresses\n");
29152419Sjulian				goto errfin;
29252419Sjulian			}
29352419Sjulian		}
29452419Sjulian
29552419Sjulian		c1 = cb;
296154604Sglebius		for (; *c2; ++c2) {
29752419Sjulian			b = 0;
29897897Sarchie			for (ct = c1; *ct; ++ct) {
29997897Sarchie				if (memcmp(*c2, *ct, ht1->h_length) == 0) {
30052419Sjulian					b = 1;
301189315Sed					break;
30297897Sarchie				}
30352419Sjulian			}
30452419Sjulian			if (b == 0) {
30552419Sjulian				printf("h2 addresses item can't be found in "
306154604Sglebius				    "h1 addresses\n");
307154604Sglebius				goto errfin;
30852419Sjulian			}
30952419Sjulian		}
31097897Sarchie	}
311154604Sglebius
31252419Sjulian	return 0;
31397897Sarchie
314189315Sederrfin:
31597897Sarchie	if (mdata == NULL) {
316154604Sglebius		printf("following structures are not equal:\n");
31752419Sjulian		dump_hostent(ht1);
31852419Sjulian		dump_hostent(ht2);
31952419Sjulian	}
32097897Sarchie
321154604Sglebius	return (-1);
322154604Sglebius}
323154604Sglebius
324154604Sglebiusstatic int
325154604Sglebiuscheck_addrinfo_for_name(struct addrinfo *ai, char const *name)
326154604Sglebius{
327154604Sglebius	struct addrinfo *ai2;
328154604Sglebius
329154604Sglebius	for (ai2 = ai; ai2 != NULL; ai2 = ai2->ai_next) {
330154604Sglebius		if (strcmp(ai2->ai_canonname, name) == 0)
331154604Sglebius			return (0);
332154604Sglebius	}
333154604Sglebius
33452419Sjulian	return (-1);
335154604Sglebius}
336154604Sglebius
33752419Sjulianstatic int
338154604Sglebiuscheck_addrinfo_for_addr(struct addrinfo *ai, char const *addr,
339154604Sglebius	socklen_t addrlen, int af)
34052419Sjulian{
34152419Sjulian	struct addrinfo *ai2;
34252419Sjulian
343154604Sglebius	for (ai2 = ai; ai2 != NULL; ai2 = ai2->ai_next) {
34452419Sjulian		if (af != ai2->ai_family)
34552419Sjulian			continue;
346154604Sglebius
34752419Sjulian		switch (af) {
34852419Sjulian		case AF_INET:
34952419Sjulian			if (memcmp(addr,
35052419Sjulian			    (void *)&((struct sockaddr_in *)ai2->ai_addr)->sin_addr,
351154604Sglebius			    MIN(addrlen, ai2->ai_addrlen)) == 0)
35252419Sjulian				return (0);
35352419Sjulian			break;
35452419Sjulian		case AF_INET6:
35552419Sjulian			if (memcmp(addr,
35697897Sarchie			    (void *)&((struct sockaddr_in6 *)ai2->ai_addr)->sin6_addr,
35752419Sjulian			    MIN(addrlen, ai2->ai_addrlen)) == 0)
358154604Sglebius				return (0);
359154604Sglebius			break;
36052419Sjulian		default:
361154604Sglebius			break;
36252419Sjulian		}
36352419Sjulian	}
36452419Sjulian
365161034Sglebius	return (-1);
366161034Sglebius}
36753042Sjulian
36852419Sjulianstatic int
36952419Sjulianis_hostent_equal(struct hostent *he, struct addrinfo *ai)
37052419Sjulian{
37152419Sjulian	char **cp;
37252419Sjulian	int rv;
37352419Sjulian
374154604Sglebius#ifdef DEBUG
37552419Sjulian	printf("checking equality of he and ai\n");
376154604Sglebius#endif
37752419Sjulian
37852419Sjulian	rv = check_addrinfo_for_name(ai, he->h_name);
37952419Sjulian	if (rv != 0) {
38052419Sjulian		printf("not equal - he->h_name couldn't be found\n");
38152419Sjulian		return (rv);
38297897Sarchie	}
38352419Sjulian
38452419Sjulian	for (cp = he->h_addr_list; *cp; ++cp) {
38552419Sjulian		rv = check_addrinfo_for_addr(ai, *cp, he->h_length,
386154604Sglebius			he->h_addrtype);
38752419Sjulian		if (rv != 0) {
388154604Sglebius			printf("not equal - one of he->h_addr_list couldn't be found\n");
389161034Sglebius			return (rv);
390154604Sglebius		}
391154604Sglebius	}
392189315Sed
39352419Sjulian#ifdef DEBUG
394154604Sglebius	printf("equal\n");
39552419Sjulian#endif
39652419Sjulian
39752419Sjulian	return (0);
398161034Sglebius}
39952419Sjulian
40052419Sjulianstatic void
40152419Sjuliansdump_hostent(struct hostent *ht, char *buffer, size_t buflen)
40297897Sarchie{
40352419Sjulian	char **cp;
40452419Sjulian	size_t i;
40552419Sjulian	int written;
40652419Sjulian
40752419Sjulian	written = snprintf(buffer, buflen, "%s %d %d",
40852419Sjulian		ht->h_name, ht->h_addrtype, ht->h_length);
40952419Sjulian	buffer += written;
41052419Sjulian	if (written > (int)buflen)
41152419Sjulian		return;
412154862Sglebius	buflen -= written;
41352419Sjulian
414154862Sglebius	if (ht->h_aliases != NULL) {
415154604Sglebius		if (*(ht->h_aliases) != NULL) {
41652419Sjulian			for (cp = ht->h_aliases; *cp; ++cp) {
417154862Sglebius				written = snprintf(buffer, buflen, " %s",*cp);
41852419Sjulian				buffer += written;
419154862Sglebius				if (written > (int)buflen)
420154862Sglebius					return;
421154862Sglebius				buflen -= written;
42252419Sjulian
42380311Sbrian				if (buflen == 0)
42452419Sjulian					return;
425154862Sglebius			}
42652419Sjulian		} else {
427176775Smav			written = snprintf(buffer, buflen, " noaliases");
428176775Smav			buffer += written;
42952419Sjulian			if (written > (int)buflen)
430176775Smav				return;
431176775Smav			buflen -= written;
43252419Sjulian		}
433154862Sglebius	} else {
434154862Sglebius		written = snprintf(buffer, buflen, " (null)");
435154862Sglebius		buffer += written;
43652419Sjulian		if (written > (int)buflen)
437154862Sglebius			return;
438154862Sglebius		buflen -= written;
439154862Sglebius	}
440154862Sglebius
44152419Sjulian	written = snprintf(buffer, buflen, " : ");
442154862Sglebius	buffer += written;
44352419Sjulian	if (written > (int)buflen)
44452419Sjulian		return;
445189315Sed	buflen -= written;
446154862Sglebius
44780311Sbrian	if (ht->h_addr_list != NULL) {
448154862Sglebius		if (*(ht->h_addr_list) != NULL) {
449176775Smav			for (cp = ht->h_addr_list; *cp; ++cp) {
450189315Sed				for (i = 0; i < (size_t)ht->h_length; ++i) {
45180311Sbrian					written = snprintf(buffer, buflen,
452176775Smav					    i + 1 != (size_t)ht->h_length ?
453154862Sglebius					        "%d." : "%d",
454154862Sglebius					    (unsigned char)(*cp)[i]);
455154862Sglebius					buffer += written;
456154862Sglebius					if (written > (int)buflen)
457154862Sglebius						return;
458154862Sglebius					buflen -= written;
459154862Sglebius
460154862Sglebius					if (buflen == 0)
461154862Sglebius						return;
462154862Sglebius				}
463154862Sglebius
464176775Smav				if (*(cp + 1)) {
465176775Smav					written = snprintf(buffer, buflen,
466154862Sglebius					    " ");
467154862Sglebius					buffer += written;
468176775Smav					if (written > (int)buflen)
469154862Sglebius						return;
470154862Sglebius					buflen -= written;
471243882Sglebius				}
472154862Sglebius			}
473154862Sglebius		} else {
474176775Smav			written = snprintf(buffer, buflen, " noaddrs");
475154862Sglebius			buffer += written;
476154862Sglebius			if (written > (int)buflen)
47752419Sjulian				return;
478154604Sglebius			buflen -= written;
479154862Sglebius		}
48052419Sjulian	} else {
481154604Sglebius		written = snprintf(buffer, buflen, " (null)");
482154862Sglebius		buffer += written;
483154862Sglebius		if (written > (int)buflen)
484154862Sglebius			return;
485154862Sglebius		buflen -= written;
486154862Sglebius	}
487154862Sglebius}
488176775Smav
489176775Smavstatic int
490154862Sglebiushostent_read_hostlist_func(struct hostent *he, char *line)
491176775Smav{
492176775Smav	struct hostent *result;
493154862Sglebius	int rv;
494154862Sglebius
495174931Smav#ifdef DEBUG
496176775Smav	printf("resolving %s: ", line);
497154862Sglebius#endif
498154862Sglebius	result = __gethostbyname2(line, af_type);
499154862Sglebius	if (result != NULL) {
500154862Sglebius#ifdef DEBUG
501154862Sglebius		printf("found\n");
50252419Sjulian#endif
503175865Smav
50452419Sjulian		rv = hostent_test_correctness(result, NULL);
505176753Smav		if (rv != 0) {
506176753Smav			__freehostent(result);
507176753Smav			return (rv);
508176753Smav		}
509176753Smav
510176753Smav		clone_hostent(he, result);
511176753Smav		__freehostent(result);
512176753Smav	} else {
513176753Smav#ifdef DEBUG
514176753Smav		printf("not found\n");
515176753Smav#endif
516176753Smav 		memset(he, 0, sizeof(struct hostent));
517176753Smav		he->h_name = strdup(line);
518176753Smav		ATF_REQUIRE(he->h_name != NULL);
519176753Smav	}
520176753Smav	return (0);
521176753Smav}
522176753Smav
523176753Smavstatic int
524176775Smavhostent_read_snapshot_addr(char *addr, unsigned char *result, size_t len)
525176753Smav{
526176753Smav	char *s, *ps, *ts;
527176753Smav
528176753Smav	ps = addr;
529176753Smav	while ( (s = strsep(&ps, ".")) != NULL) {
530176775Smav		if (len == 0)
531176753Smav			return (-1);
532176753Smav
533176753Smav		*result = (unsigned char)strtol(s, &ts, 10);
534176753Smav		++result;
535176753Smav		if (*ts != '\0')
536176753Smav			return (-1);
537176753Smav
538176753Smav		--len;
539176753Smav	}
540176753Smav	if (len != 0)
541175865Smav		return (-1);
542175865Smav	else
543175865Smav		return (0);
54452419Sjulian}
545175865Smav
546175865Smavstatic int
54752419Sjulianhostent_read_snapshot_func(struct hostent *ht, char *line)
548175865Smav{
549176775Smav	StringList *sl1, *sl2;
550175865Smav	char *s, *ps, *ts;
551175865Smav	int i, rv;
552172270Smav
553175865Smav#ifdef DEBUG
554175865Smav	printf("1 line read from snapshot:\n%s\n", line);
555175865Smav#endif
556175865Smav
557175865Smav	rv = 0;
558175865Smav	i = 0;
559175865Smav	sl1 = sl2 = NULL;
560175865Smav	ps = line;
561176775Smav	memset(ht, 0, sizeof(struct hostent));
562175865Smav	while ((s = strsep(&ps, " ")) != NULL) {
563175865Smav		switch (i) {
564175865Smav		case 0:
565175865Smav			ht->h_name = strdup(s);
566175865Smav			ATF_REQUIRE(ht->h_name != NULL);
567175865Smav			break;
568175865Smav
569175865Smav		case 1:
570175865Smav			ht->h_addrtype = (int)strtol(s, &ts, 10);
571175865Smav			if (*ts != '\0')
572175865Smav				goto fin;
573175865Smav			break;
574176775Smav
575172270Smav		case 2:
576172270Smav			ht->h_length = (int)strtol(s, &ts, 10);
577172270Smav			if (*ts != '\0')
57852419Sjulian				goto fin;
57952419Sjulian			break;
58052419Sjulian
581175865Smav		case 3:
582175867Smav			if (sl1 == NULL) {
583175867Smav				if (strcmp(s, "(null)") == 0)
584154604Sglebius					return (0);
585175865Smav
58652419Sjulian				sl1 = sl_init();
58752419Sjulian				ATF_REQUIRE(sl1 != NULL);
58852419Sjulian
58997897Sarchie				if (strcmp(s, "noaliases") != 0) {
59052419Sjulian					ts = strdup(s);
591154604Sglebius					ATF_REQUIRE(ts != NULL);
592154604Sglebius					sl_add(sl1, ts);
59352419Sjulian				}
594189315Sed			} else {
595154604Sglebius				if (strcmp(s, ":") == 0)
59670784Sjulian					++i;
597172270Smav				else {
598172270Smav					ts = strdup(s);
59952419Sjulian					ATF_REQUIRE(ts != NULL);
60070784Sjulian					sl_add(sl1, ts);
60152419Sjulian				}
60252419Sjulian			}
603154604Sglebius			break;
604154604Sglebius
60552419Sjulian		case 4:
60652419Sjulian			if (sl2 == NULL) {
60752419Sjulian				if (strcmp(s, "(null)") == 0)
60852419Sjulian					return (0);
609154604Sglebius
61052419Sjulian				sl2 = sl_init();
61152419Sjulian				ATF_REQUIRE(sl2 != NULL);
61252419Sjulian
613154604Sglebius				if (strcmp(s, "noaddrs") != 0) {
61452419Sjulian					ts = calloc(1, ht->h_length);
61552419Sjulian					ATF_REQUIRE(ts != NULL);
61670700Sjulian					rv = hostent_read_snapshot_addr(s,
61752419Sjulian					    (unsigned char *)ts,
618175865Smav					    ht->h_length);
619175865Smav					sl_add(sl2, ts);
62052419Sjulian					if (rv != 0)
621154604Sglebius						goto fin;
622220768Sglebius				}
62352419Sjulian			} else {
624154604Sglebius				ts = calloc(1, ht->h_length);
625154604Sglebius				ATF_REQUIRE(ts != NULL);
626154604Sglebius				rv = hostent_read_snapshot_addr(s,
627132703Sglebius				    (unsigned char *)ts, ht->h_length);
628154901Sglebius				sl_add(sl2, ts);
629161117Sglebius				if (rv != 0)
630161117Sglebius					goto fin;
631154604Sglebius			}
632176775Smav			break;
633175865Smav		default:
634175865Smav			break;
635176775Smav		}
636175865Smav
637175865Smav		if (i != 3 && i != 4)
638154604Sglebius			++i;
639154604Sglebius	}
640154604Sglebius
64152419Sjulianfin:
64252419Sjulian	if (sl1 != NULL) {
64352419Sjulian		sl_add(sl1, NULL);
64452419Sjulian		ht->h_aliases = sl1->sl_str;
64552419Sjulian	}
64652419Sjulian	if (sl2 != NULL) {
64752419Sjulian		sl_add(sl2, NULL);
64852419Sjulian		ht->h_addr_list = sl2->sl_str;
649154604Sglebius	}
650154604Sglebius
65169922Sjulian	if ((i != 4) || (rv != 0)) {
65252419Sjulian		free_hostent(ht);
65352419Sjulian		memset(ht, 0, sizeof(struct hostent));
65452562Sjulian		return (-1);
65552419Sjulian	}
65670784Sjulian
65752419Sjulian	/* NOTE: is it a dirty hack or not? */
65852419Sjulian	free(sl1);
65952419Sjulian	free(sl2);
66052419Sjulian	return (0);
661172629Smav}
66252419Sjulian
66352419Sjulianstatic void
664172629Smavdump_hostent(struct hostent *result)
66552419Sjulian{
66652419Sjulian	if (result != NULL) {
66752419Sjulian		char buffer[1024];
66852419Sjulian		sdump_hostent(result, buffer, sizeof(buffer));
66952419Sjulian		printf("%s\n", buffer);
67052419Sjulian	} else
671154604Sglebius		printf("(null)\n");
672154604Sglebius}
673154604Sglebius
67452419Sjulianstatic int
67570784Sjulianhostent_test_correctness(struct hostent *ht, void *mdata __unused)
67652419Sjulian{
67752419Sjulian
678154604Sglebius#ifdef DEBUG
679154604Sglebius	printf("testing correctness with the following data:\n");
680154604Sglebius	dump_hostent(ht);
68152419Sjulian#endif
68252419Sjulian
68352419Sjulian	if (ht == NULL)
68452419Sjulian		goto errfin;
685161117Sglebius
686161117Sglebius	if (ht->h_name == NULL)
687161117Sglebius		goto errfin;
688161117Sglebius
689161117Sglebius	if (!((ht->h_addrtype >= 0) && (ht->h_addrtype < AF_MAX)))
690161117Sglebius		goto errfin;
691161117Sglebius
692161117Sglebius	if ((ht->h_length != sizeof(struct in_addr)) &&
693161181Sglebius		(ht->h_length != sizeof(struct in6_addr)))
694161117Sglebius		goto errfin;
695161117Sglebius
696161117Sglebius	if (ht->h_aliases == NULL)
697161117Sglebius		goto errfin;
698161117Sglebius
699161117Sglebius	if (ht->h_addr_list == NULL)
700161117Sglebius		goto errfin;
701161117Sglebius
702161117Sglebius#ifdef DEBUG
703161117Sglebius	printf("correct\n");
704161117Sglebius#endif
705161117Sglebius
706161117Sglebius	return (0);
707161117Sglebiuserrfin:
708161117Sglebius	printf("incorrect\n");
709161117Sglebius
710161117Sglebius	return (-1);
711161117Sglebius}
712161117Sglebius
713161117Sglebiusstatic int
714161117Sglebiushostent_test_gethostbyaddr(struct hostent *he, void *mdata)
715161117Sglebius{
716161117Sglebius	struct hostent *result;
71752419Sjulian	struct hostent_test_data *addr_test_data;
71852419Sjulian	int rv;
71952419Sjulian
72052419Sjulian	addr_test_data = (struct hostent_test_data *)mdata;
72152419Sjulian
72252419Sjulian	/* We should omit unresolved hostents */
72370700Sjulian	if (he->h_addr_list != NULL) {
72452419Sjulian		char **cp;
72570784Sjulian		for (cp = he->h_addr_list; *cp; ++cp) {
72652562Sjulian#ifdef DEBUG
72752419Sjulian			printf("doing reverse lookup for %s\n", he->h_name);
72852419Sjulian#endif
72952419Sjulian
73052419Sjulian			result = __gethostbyaddr(*cp, he->h_length,
73152419Sjulian			    he->h_addrtype);
73270700Sjulian			if (result == NULL) {
73352419Sjulian#ifdef DEBUG
73470700Sjulian				printf("%s: warning: reverse lookup failed "
735154604Sglebius				    "for %s: %s\n", __func__, he->h_name,
736154604Sglebius				    strerror(errno));
737154604Sglebius#endif
738154604Sglebius				continue;
739154604Sglebius			}
74052419Sjulian			rv = hostent_test_correctness(result, NULL);
741154604Sglebius			if (rv != 0) {
74252419Sjulian				__freehostent(result);
74352419Sjulian				return (rv);
744154604Sglebius			}
745154604Sglebius
746154604Sglebius			if (addr_test_data != NULL)
74768845Sbrian				TEST_DATA_APPEND(hostent, addr_test_data,
74868845Sbrian				    result);
749161034Sglebius
750161034Sglebius			__freehostent(result);
75168845Sbrian		}
75268031Sbrian	}
753154604Sglebius
75468031Sbrian	return (0);
755161034Sglebius}
756161034Sglebius
75752419Sjulianstatic int
75852419Sjulianhostent_test_getaddrinfo_eq(struct hostent *he, void *mdata __unused)
75968845Sbrian{
76068845Sbrian	struct addrinfo *ai, hints;
761161034Sglebius	int rv;
762161034Sglebius
763161034Sglebius	ai = NULL;
76468845Sbrian	memset(&hints, 0, sizeof(struct addrinfo));
76552419Sjulian	hints.ai_family = af_type;
76652419Sjulian	hints.ai_flags = AI_CANONNAME;
76768031Sbrian
768154604Sglebius	printf("using getaddrinfo() to resolve %s\n", he->h_name);
76952419Sjulian
77052419Sjulian	/* struct hostent *he was not resolved */
771176775Smav	if (he->h_addr_list == NULL) {
772176775Smav		/* We can be sure that he->h_name is not NULL */
773154604Sglebius		rv = getaddrinfo(he->h_name, NULL, &hints, &ai);
77452419Sjulian		if (rv == 0) {
775154604Sglebius			printf("not ok - shouldn't have been resolved\n");
776172270Smav			rv = -1;
777172270Smav		} else
77852419Sjulian			rv = 0;
779154604Sglebius	} else {
78080311Sbrian		rv = getaddrinfo(he->h_name, NULL, &hints, &ai);
78180311Sbrian		if (rv != 0) {
78280311Sbrian			printf("not ok - should have been resolved\n");
78380311Sbrian			rv = -1;
78480311Sbrian			goto done;
785154862Sglebius		}
786154862Sglebius		rv = is_hostent_equal(he, ai);
78780311Sbrian		if (rv != 0) {
78880311Sbrian			printf("not ok - addrinfo and hostent are not equal\n");
78980311Sbrian			rv = -1;
79069922Sjulian		}
79169922Sjulian	}
79269922Sjuliandone:
79369922Sjulian	if (ai != NULL)
794154604Sglebius		freeaddrinfo(ai);
79569922Sjulian	return (rv);
796154604Sglebius}
797150319Sglebius
798161034Sglebiusstatic int
799161034Sglebiushostent_test_getnameinfo_eq(struct hostent *he, void *mdata __unused)
80052419Sjulian{
80152419Sjulian	char **cp;
80252443Sjulian	char buffer[NI_MAXHOST];
80352419Sjulian	struct sockaddr_in sin;
804154604Sglebius	struct sockaddr_in6 sin6;
80552419Sjulian	struct sockaddr *saddr;
806154604Sglebius	struct hostent *result;
80768876Sdwmalone	int i, rv;
80852419Sjulian
809154604Sglebius	if (he->h_addr_list == NULL)
81052419Sjulian		return (0);
811154604Sglebius
812243882Sglebius	for (cp = he->h_addr_list; *cp; ++cp) {
813154604Sglebius#ifdef DEBUG
814154604Sglebius		printf("doing reverse lookup for %s\n", he->h_name);
81552419Sjulian#endif
81652419Sjulian		result = __gethostbyaddr(*cp, he->h_length,
81752419Sjulian		    he->h_addrtype);
81852419Sjulian		if (result != NULL) {
819138562Sglebius			rv = hostent_test_correctness(result, NULL);
82052419Sjulian			if (rv != 0) {
82152419Sjulian				__freehostent(result);
822132703Sglebius				return (rv);
823161117Sglebius			}
82452419Sjulian		} else
82552419Sjulian			printf("%s: warning: reverse lookup failed "
82652419Sjulian			    "for %s: %s\n", __func__, he->h_name,
82752419Sjulian			    strerror(errno));
82852419Sjulian
82970700Sjulian		switch (he->h_addrtype) {
83052419Sjulian		case AF_INET:
83152419Sjulian			memset(&sin, 0, sizeof(struct sockaddr_in));
83252419Sjulian			sin.sin_len = sizeof(struct sockaddr_in);
83352419Sjulian			sin.sin_family = AF_INET;
83452562Sjulian			memcpy(&sin.sin_addr, *cp, he->h_length);
83552419Sjulian
83652419Sjulian			saddr = (struct sockaddr *)&sin;
837154604Sglebius			break;
83852419Sjulian		case AF_INET6:
839154604Sglebius			memset(&sin6, 0, sizeof(struct sockaddr_in6));
84052562Sjulian			sin6.sin6_len = sizeof(struct sockaddr_in6);
84152419Sjulian			sin6.sin6_family = AF_INET6;
84252419Sjulian			memcpy(&sin6.sin6_addr, *cp, he->h_length);
84352419Sjulian
84452419Sjulian			saddr = (struct sockaddr *)&sin6;
84552419Sjulian			break;
846174981Smav		default:
84752419Sjulian			printf("warning: %d family is unsupported\n",
84852419Sjulian			    he->h_addrtype);
84952419Sjulian			continue;
85052419Sjulian		}
85152419Sjulian
852154604Sglebius		ATF_REQUIRE(saddr != NULL);
85352419Sjulian		rv = getnameinfo(saddr, saddr->sa_len, buffer,
85452419Sjulian			sizeof(buffer), NULL, 0, NI_NAMEREQD);
85552419Sjulian
856174981Smav		if (rv != 0 && result != NULL) {
857174981Smav			printf("getnameinfo() didn't make the reverse "
858174981Smav			    "lookup, when it should have (%s)\n",
859174981Smav			    gai_strerror(rv));
860174981Smav			return (rv);
861174981Smav		}
862174981Smav
863174981Smav		if (rv == 0 && result == NULL) {
864174981Smav			printf("getnameinfo() made the "
865174981Smav			    "reverse lookup, when it shouldn't have\n");
866174981Smav			return (rv);
867174981Smav		}
868174981Smav
86952419Sjulian		if (rv != 0 && result == NULL) {
870174981Smav#ifdef DEBUG
871174981Smav			printf("both getnameinfo() and ***byaddr() failed as "
872174981Smav			    "expected\n");
873174981Smav#endif
87452419Sjulian			continue;
87552419Sjulian		}
876174981Smav
87752419Sjulian#ifdef DEBUG
87852419Sjulian		printf("comparing %s with %s\n", result->h_name,
87952419Sjulian		    buffer);
88052419Sjulian#endif
88152419Sjulian
88252419Sjulian		/*
88352419Sjulian		 * An address might reverse resolve to hostname alias or the
88452419Sjulian		 * official hostname, e.g. moon.vub.ac.be.
88552419Sjulian		 */
88668845Sbrian		bool found_a_match = false;
887154604Sglebius
88852443Sjulian		if (strcmp(result->h_name, buffer) == 0) {
88968845Sbrian			found_a_match = true;
89068845Sbrian#ifdef DEBUG
89168845Sbrian			printf("matched official hostname\n");
89268845Sbrian#endif
89352419Sjulian		} else {
89452419Sjulian			for (i = 0; result->h_aliases[i] != NULL; i++) {
895154604Sglebius				printf("[%d] resolved: %s\n", i,
89652419Sjulian				    result->h_aliases[i]);
89752419Sjulian				if (strcmp(result->h_aliases[i],
898176775Smav				    buffer) == 0) {
89952419Sjulian					printf("matched hostname alias\n");
90052419Sjulian					found_a_match = true;
90152419Sjulian					break;
90252419Sjulian				}
90352419Sjulian			}
90452419Sjulian		}
90552419Sjulian		__freehostent(result);
90652419Sjulian
90752419Sjulian		if (found_a_match) {
90868845Sbrian#ifdef DEBUG
909154604Sglebius			printf("getnameinfo() and ***byaddr() results are "
91068845Sbrian			    "equal\n");
91168845Sbrian#endif
91268845Sbrian		} else {
91368845Sbrian			printf("getnameinfo() and ***byaddr() results are not "
91452419Sjulian			    "equal for %s\n", he->h_name);
91552419Sjulian			return (-1);
916154604Sglebius		}
91752419Sjulian	}
91852419Sjulian
91952419Sjulian	return (0);
920154604Sglebius}
921154604Sglebius
92269922Sjulianstatic int
92369922Sjulianrun_tests(const char *hostlist_file, const char *snapshot_file, int _af_type,
92469922Sjulian    enum test_methods method, bool use_ipv6_mapping)
92569922Sjulian{
92670148Sjulian	char *snapshot_file_copy;
927161034Sglebius	struct hostent_test_data td, td_addr, td_snap;
928161034Sglebius	res_state statp;
92969922Sjulian	int rv = -2;
93069922Sjulian
93170931Sjulian	if (snapshot_file == NULL)
93269922Sjulian		snapshot_file_copy = NULL;
93369922Sjulian	else {
934154604Sglebius		snapshot_file_copy = strdup(snapshot_file);
93569922Sjulian		ATF_REQUIRE(snapshot_file_copy != NULL);
93669922Sjulian	}
93769922Sjulian	snapshot_file = snapshot_file_copy;
93869922Sjulian
93969922Sjulian	switch (_af_type) {
94069922Sjulian	case AF_INET:
941132703Sglebius		ATF_REQUIRE_FEATURE("inet");
942132703Sglebius		ATF_REQUIRE(!use_ipv6_mapping);
943132703Sglebius		break;
944132703Sglebius	case AF_INET6:
945132703Sglebius		ATF_REQUIRE_FEATURE("inet6");
946132703Sglebius		break;
947132703Sglebius	default:
948132703Sglebius		atf_tc_fail("unhandled address family: %d", _af_type);
949132703Sglebius		break;
950132703Sglebius	}
951132703Sglebius
952154604Sglebius	if (!use_ipnode_functions) {
953154901Sglebius		statp = __res_state();
954154901Sglebius		if (statp == NULL || ((statp->options & RES_INIT) == 0 &&
955154901Sglebius		    res_ninit(statp) == -1)) {
956161117Sglebius			printf("error: can't init res_state\n");
957154901Sglebius			rv = -1;
958154901Sglebius			goto fin2;
959154901Sglebius		}
960154901Sglebius
961154901Sglebius		if (use_ipv6_mapping)
962161117Sglebius			statp->options |= RES_USE_INET6;
963161117Sglebius		else
964154901Sglebius			statp->options &= ~RES_USE_INET6;
965154901Sglebius	}
966154901Sglebius
967154901Sglebius	TEST_DATA_INIT(hostent, &td, clone_hostent, free_hostent);
968154901Sglebius	TEST_DATA_INIT(hostent, &td_addr, clone_hostent, free_hostent);
969154901Sglebius	TEST_DATA_INIT(hostent, &td_snap, clone_hostent, free_hostent);
970154901Sglebius
971154901Sglebius	if (access(hostlist_file, R_OK) != 0) {
972132703Sglebius		printf("can't access the hostlist file %s\n", hostlist_file);
973132703Sglebius		rv = -1;
974132703Sglebius		goto fin;
975154901Sglebius	}
976154901Sglebius
977154901Sglebius#ifdef DEBUG
978154901Sglebius	printf("building host lists from %s\n", hostlist_file);
979154901Sglebius#endif
980154901Sglebius
981154901Sglebius	rv = TEST_SNAPSHOT_FILE_READ(hostent, hostlist_file, &td,
982154901Sglebius		hostent_read_hostlist_func);
983154901Sglebius	if (rv != 0) {
984154901Sglebius		printf("failed to read the host list file: %s\n",
985154901Sglebius		    hostlist_file);
986154901Sglebius		goto fin;
987132703Sglebius	}
988132703Sglebius
989154901Sglebius	if (snapshot_file != NULL) {
990154901Sglebius		if (access(snapshot_file, W_OK | R_OK) != 0) {
991154901Sglebius			if (errno == ENOENT) {
992154901Sglebius				if (method != TEST_GETHOSTBYADDR)
993154901Sglebius					method = TEST_BUILD_SNAPSHOT;
994154901Sglebius				else
995154901Sglebius					method = TEST_BUILD_ADDR_SNAPSHOT;
996154901Sglebius			} else {
997154901Sglebius				printf("can't access the snapshot file %s\n",
998154901Sglebius				    snapshot_file);
999154901Sglebius				rv = -1;
1000154901Sglebius				goto fin;
1001154901Sglebius			}
1002154901Sglebius		} else {
1003154901Sglebius			rv = TEST_SNAPSHOT_FILE_READ(hostent, snapshot_file,
1004154901Sglebius				&td_snap, hostent_read_snapshot_func);
1005154901Sglebius			if (rv != 0) {
1006154901Sglebius				printf("error reading snapshot file\n");
1007132703Sglebius				goto fin;
1008154901Sglebius			}
1009161117Sglebius		}
1010161117Sglebius	}
1011161117Sglebius
1012161117Sglebius	switch (method) {
1013161117Sglebius	case TEST_GETHOSTBYNAME2:
1014161117Sglebius		if (snapshot_file != NULL)
1015288918Smav			rv = DO_2PASS_TEST(hostent, &td, &td_snap,
1016288918Smav			    compare_hostent, NULL);
1017288918Smav		break;
1018288918Smav	case TEST_GETHOSTBYADDR:
1019288918Smav		rv = DO_1PASS_TEST(hostent, &td,
1020288918Smav			hostent_test_gethostbyaddr, (void *)&td_addr);
1021288918Smav		if (rv != 0)
102252419Sjulian			goto fin;
102352419Sjulian
102452419Sjulian		if (snapshot_file != NULL)
102552419Sjulian			rv = DO_2PASS_TEST(hostent, &td_addr, &td_snap,
1026161117Sglebius			    compare_hostent, NULL);
1027161117Sglebius		break;
1028161117Sglebius	case TEST_GETHOSTBYNAME2_GETADDRINFO:
1029161117Sglebius		rv = DO_1PASS_TEST(hostent, &td,
1030161117Sglebius			hostent_test_getaddrinfo_eq, NULL);
1031161117Sglebius		break;
1032161117Sglebius	case TEST_GETHOSTBYADDR_GETNAMEINFO:
1033161117Sglebius		rv = DO_1PASS_TEST(hostent, &td,
1034161117Sglebius			hostent_test_getnameinfo_eq, NULL);
1035161117Sglebius		break;
1036161117Sglebius	case TEST_BUILD_SNAPSHOT:
1037161181Sglebius		if (snapshot_file != NULL) {
1038161117Sglebius			rv = TEST_SNAPSHOT_FILE_WRITE(hostent, snapshot_file,
1039161117Sglebius			    &td, sdump_hostent);
104052419Sjulian		}
104152419Sjulian		break;
104252419Sjulian	case TEST_BUILD_ADDR_SNAPSHOT:
104352419Sjulian		if (snapshot_file != NULL) {
1044154604Sglebius			rv = DO_1PASS_TEST(hostent, &td,
104570700Sjulian			    hostent_test_gethostbyaddr, (void *)&td_addr);
1046154901Sglebius			if (rv != 0)
104770700Sjulian				goto fin;
1048154604Sglebius			rv = TEST_SNAPSHOT_FILE_WRITE(hostent, snapshot_file,
104970700Sjulian			    &td_addr, sdump_hostent);
105052419Sjulian		}
105152419Sjulian		break;
105252419Sjulian	default:
105352443Sjulian		rv = 0;
105452443Sjulian		break;
105552443Sjulian	}
105652443Sjulian
105752419Sjulianfin:
105852419Sjulian	TEST_DATA_DESTROY(hostent, &td_snap);
105952419Sjulian	TEST_DATA_DESTROY(hostent, &td_addr);
1060172628Smav	TEST_DATA_DESTROY(hostent, &td);
1061172628Smav
1062172628Smavfin2:
1063172628Smav	free(snapshot_file_copy);
106452419Sjulian
106552419Sjulian	return (rv);
106652419Sjulian}
1067103870Salfred
1068172628Smav#define	HOSTLIST_FILE	"mach"
1069172628Smav
107052419Sjulian#define	_RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \
1071154604Sglebiusdo {									\
1072154604Sglebius	char *_hostlist_file;						\
107352419Sjulian	ATF_REQUIRE(0 < asprintf(&_hostlist_file, "%s/%s",		\
1074154604Sglebius	    atf_tc_get_config_var(tc, "srcdir"), HOSTLIST_FILE));	\
107552419Sjulian	ATF_REQUIRE(run_tests(_hostlist_file, snapshot_file, af_type,	\
1076154604Sglebius	    method, use_ipv6_mapping) == 0);				\
1077154604Sglebius	free(_hostlist_file);						\
1078161117Sglebius} while (0)
1079154604Sglebius
1080172628Smav#define	RUN_HOST_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \
1081161117Sglebiusdo {									\
1082172628Smav	use_ipnode_functions = false; 					\
108352419Sjulian	_RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping); \
108452419Sjulian} while (0)
108552419Sjulian
108652419Sjulian#define	RUN_IPNODE_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \
108768079Sjuliando {									\
1088172628Smav	use_ipnode_functions = true; 					\
1089288918Smav	_RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping); \
1090288918Smav} while (0)
109152419Sjulian
1092172628SmavATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv4);
1093172628SmavATF_TC_BODY(gethostbyaddr_ipv4, tc)
1094172628Smav{
1095172628Smav
1096172628Smav	RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR, false);
1097172628Smav}
1098243882Sglebius
1099172628SmavATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv4_with_snapshot);
110052419SjulianATF_TC_BODY(gethostbyaddr_ipv4_with_snapshot, tc)
110152419Sjulian{
110290973Sbrian
110397897Sarchie	RUN_HOST_TESTS(tc, "snapshot_htaddr4", AF_INET, TEST_GETHOSTBYADDR, false);
110490973Sbrian}
110598636Sbrian
110690973SbrianATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6);
110790973SbrianATF_TC_BODY(gethostbyaddr_ipv6, tc)
110890973Sbrian{
1109154604Sglebius
1110154604Sglebius	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, false);
111190973Sbrian}
111290973Sbrian
111390973SbrianATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_AI_V4MAPPED);
111490973SbrianATF_TC_BODY(gethostbyaddr_ipv6_AI_V4MAPPED, tc)
111590973Sbrian{
111690973Sbrian
1117125028Sharti	ipnode_flags = AI_V4MAPPED;
1118189315Sed	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true);
111998636Sbrian}
1120102244Sarchie
112190973SbrianATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_with_snapshot);
112290973SbrianATF_TC_BODY(gethostbyaddr_ipv6_with_snapshot, tc)
112390973Sbrian{
112490973Sbrian
112596578Sbrian	RUN_HOST_TESTS(tc, "snapshot_htaddr6", AF_INET6, TEST_GETHOSTBYADDR, false);
112696578Sbrian}
112796578Sbrian
112896578SbrianATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_with_snapshot_AI_V4MAPPED);
112996578SbrianATF_TC_BODY(gethostbyaddr_ipv6_with_snapshot_AI_V4MAPPED, tc)
113096578Sbrian{
1131154604Sglebius
1132154604Sglebius	ipnode_flags = AI_V4MAPPED;
113396578Sbrian	RUN_HOST_TESTS(tc, "snapshot_htaddr6map", AF_INET6, TEST_GETHOSTBYADDR, true);
1134154604Sglebius}
113596578Sbrian
113696578SbrianATF_TC_WITHOUT_HEAD(gethostbyname2_getaddrinfo_ipv4);
113796578SbrianATF_TC_BODY(gethostbyname2_getaddrinfo_ipv4, tc)
1138154604Sglebius{
1139102244Sarchie
114096578Sbrian	RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2_GETADDRINFO, false);
114196578Sbrian}
114296578Sbrian
114396578SbrianATF_TC_WITHOUT_HEAD(gethostbyname2_getaddrinfo_ipv6);
1144288918SmavATF_TC_BODY(gethostbyname2_getaddrinfo_ipv6, tc)
1145288918Smav{
1146288918Smav
1147288918Smav	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2_GETADDRINFO, false);
1148288918Smav}
1149288918Smav
1150288918SmavATF_TC_WITHOUT_HEAD(gethostbyaddr_getnameinfo_ipv4);
1151288918SmavATF_TC_BODY(gethostbyaddr_getnameinfo_ipv4, tc)
1152288918Smav{
1153288918Smav
1154288918Smav	RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR_GETNAMEINFO, false);
1155288918Smav}
1156288918Smav
1157288918SmavATF_TC_WITHOUT_HEAD(gethostbyaddr_getnameinfo_ipv6);
1158288918SmavATF_TC_BODY(gethostbyaddr_getnameinfo_ipv6, tc)
1159288918Smav{
1160288918Smav
1161288918Smav	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR_GETNAMEINFO, false);
1162288918Smav}
1163288918Smav
1164288918SmavATF_TC_WITHOUT_HEAD(gethostbyname2_ipv4);
1165288918SmavATF_TC_BODY(gethostbyname2_ipv4, tc)
116652419Sjulian{
1167172629Smav
116852419Sjulian	RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false);
116952419Sjulian}
117070700Sjulian
117152419SjulianATF_TC_WITHOUT_HEAD(gethostbyname2_ipv4_with_snapshot);
117270784SjulianATF_TC_BODY(gethostbyname2_ipv4_with_snapshot, tc)
117370784Sjulian{
117470784Sjulian
1175172629Smav	RUN_HOST_TESTS(tc, "snapshot_htname4", AF_INET, TEST_GETHOSTBYNAME2, false);
1176154604Sglebius}
1177172629Smav
117852419SjulianATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6);
1179154604SglebiusATF_TC_BODY(gethostbyname2_ipv6, tc)
1180154604Sglebius{
1181154604Sglebius
118270700Sjulian	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false);
1183172629Smav}
1184172629Smav
1185172629SmavATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_AI_V4MAPPED);
118652419SjulianATF_TC_BODY(gethostbyname2_ipv6_AI_V4MAPPED, tc)
1187172629Smav{
1188172629Smav
1189172629Smav	ipnode_flags = AI_V4MAPPED;
1190172629Smav	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true);
119152419Sjulian}
1192172629Smav
1193172629SmavATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_with_snapshot);
1194172629SmavATF_TC_BODY(gethostbyname2_ipv6_with_snapshot, tc)
1195176057Smav{
1196176057Smav
1197172629Smav	RUN_HOST_TESTS(tc, "snapshot_htname6", AF_INET6, TEST_GETHOSTBYNAME2, false);
1198172629Smav}
119952419Sjulian
1200172629SmavATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_with_snapshot_AI_V4MAPPED);
1201172629SmavATF_TC_BODY(gethostbyname2_ipv6_with_snapshot_AI_V4MAPPED, tc)
120252419Sjulian{
1203243882Sglebius
1204172629Smav	ipnode_flags = AI_V4MAPPED;
1205172629Smav	RUN_HOST_TESTS(tc, "snapshot_htname6map", AF_INET6, TEST_GETHOSTBYNAME2, true);
1206172629Smav}
1207172629Smav
1208172629SmavATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv4);
1209172629SmavATF_TC_BODY(getipnodebyaddr_ipv4, tc)
1210172629Smav{
1211172629Smav
1212172629Smav	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR, false);
1213172629Smav}
1214172629Smav
1215172629SmavATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv4_with_snapshot);
1216172629SmavATF_TC_BODY(getipnodebyaddr_ipv4_with_snapshot, tc)
1217172629Smav{
1218172629Smav
1219172629Smav	RUN_IPNODE_TESTS(tc, "snapshot_ipnodeaddr4", AF_INET, TEST_GETHOSTBYADDR, false);
1220172629Smav}
1221172629Smav
1222172629SmavATF_TC_WITHOUT_HEAD(getipnodebyaddr_getnameinfo_ipv4);
1223172629SmavATF_TC_BODY(getipnodebyaddr_getnameinfo_ipv4, tc)
1224172629Smav{
1225172629Smav
1226172629Smav	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR_GETNAMEINFO, false);
1227172629Smav}
1228172629Smav
1229172629SmavATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6);
1230172629SmavATF_TC_BODY(getipnodebyaddr_ipv6, tc)
1231172629Smav{
1232172629Smav
1233172629Smav	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, false);
1234172629Smav}
123552510Sjulian
123652419SjulianATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED);
123752419SjulianATF_TC_BODY(getipnodebyaddr_ipv6_AI_V4MAPPED, tc)
1238172629Smav{
1239172629Smav
124052419Sjulian	ipnode_flags = AI_V4MAPPED;
1241172629Smav	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true);
1242172629Smav}
1243172629Smav
1244172629SmavATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG);
1245172629SmavATF_TC_BODY(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG, tc)
1246172629Smav{
124752419Sjulian
1248172629Smav	ipnode_flags = AI_V4MAPPED_CFG;
1249172629Smav	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true);
1250172629Smav}
1251172629Smav
1252172629SmavATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG_AI_ALL);
1253172629SmavATF_TC_BODY(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG_AI_ALL, tc)
1254172629Smav{
1255172629Smav
1256172629Smav	ipnode_flags = AI_V4MAPPED_CFG | AI_ALL;
1257172629Smav	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true);
1258172629Smav}
1259172629Smav
1260154862SglebiusATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot);
1261172629SmavATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot, tc)
1262172629Smav{
1263172629Smav
1264172629Smav	RUN_IPNODE_TESTS(tc, "snapshot_ipnodeaddr6", AF_INET6, TEST_GETHOSTBYADDR, false);
1265172629Smav}
1266172629Smav
1267172629SmavATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED);
1268172629SmavATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED, tc)
1269172629Smav{
1270172629Smav
1271172629Smav	ipnode_flags = AI_V4MAPPED;
1272172629Smav	RUN_IPNODE_TESTS(tc,
1273172629Smav	    "snapshot_ipnodeaddr6_AI_V4MAPPED", AF_INET6,
1274172629Smav	    TEST_GETHOSTBYADDR, true);
1275172629Smav}
1276172629Smav
1277172629SmavATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG);
1278172629SmavATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG, tc)
1279172629Smav{
1280172629Smav
1281172629Smav	ipnode_flags = AI_V4MAPPED_CFG;
1282172629Smav	RUN_IPNODE_TESTS(tc,
1283172629Smav	    "snapshot_ipnodeaddr6_AI_V4MAPPED_CFG", AF_INET6,
1284172629Smav	    TEST_GETHOSTBYADDR, true);
1285172629Smav}
1286172629Smav
1287172629SmavATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL);
1288172629SmavATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL, tc)
1289172629Smav{
1290172629Smav
1291172629Smav	ipnode_flags = AI_V4MAPPED_CFG | AI_ALL;
1292172629Smav	RUN_IPNODE_TESTS(tc,
1293243882Sglebius	    "snapshot_ipnodeaddr6_AI_V4MAPPED_CFG_AI_ALL", AF_INET6,
1294172629Smav	    TEST_GETHOSTBYADDR, true);
1295172629Smav}
1296172629Smav
1297172629SmavATF_TC_WITHOUT_HEAD(getipnodebyaddr_getnameinfo_ipv6);
129852419SjulianATF_TC_BODY(getipnodebyaddr_getnameinfo_ipv6, tc)
1299172629Smav{
1300172629Smav
1301172629Smav	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR_GETNAMEINFO, false);
1302172629Smav}
1303172629Smav
1304172629SmavATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4);
1305172629SmavATF_TC_BODY(getipnodebyname_ipv4, tc)
1306172629Smav{
1307172629Smav
1308172629Smav	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false);
1309172629Smav}
1310172629Smav
1311172629SmavATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_with_snapshot);
131252419SjulianATF_TC_BODY(getipnodebyname_ipv4_with_snapshot, tc)
1313172629Smav{
1314172629Smav
1315172629Smav	RUN_IPNODE_TESTS(tc, "snapshot_ipnodename4", AF_INET, TEST_GETHOSTBYNAME2, false);
1316172629Smav}
1317172629Smav
1318172629SmavATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_AI_ADDRCONFIG);
1319172629SmavATF_TC_BODY(getipnodebyname_ipv4_AI_ADDRCONFIG, tc)
1320172629Smav{
1321208824Smav
1322172629Smav	ipnode_flags = AI_ADDRCONFIG;
1323172629Smav	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false);
1324172629Smav}
1325172629Smav
1326172629SmavATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_with_snapshot_AI_ADDRCONFIG);
1327172629SmavATF_TC_BODY(getipnodebyname_ipv4_with_snapshot_AI_ADDRCONFIG, tc)
1328172629Smav{
1329172629Smav
1330172629Smav	ipnode_flags = AI_ADDRCONFIG;
1331172629Smav	RUN_IPNODE_TESTS(tc, "snapshot_ipnodename4_AI_ADDRCONFIG", AF_INET,
1332172629Smav	    TEST_GETHOSTBYNAME2, false);
133352419Sjulian}
1334172629Smav
1335172629SmavATF_TC_WITHOUT_HEAD(getipnodebyname_getaddrinfo_ipv4);
133652419SjulianATF_TC_BODY(getipnodebyname_getaddrinfo_ipv4, tc)
1337172629Smav{
1338172629Smav
1339172629Smav	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2_GETADDRINFO, false);
1340172629Smav}
1341172629Smav
1342172629SmavATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6);
1343172629SmavATF_TC_BODY(getipnodebyname_ipv6, tc)
1344172629Smav{
1345172629Smav
1346172629Smav	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false);
1347172629Smav}
1348172629Smav
1349172629SmavATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot);
1350172629SmavATF_TC_BODY(getipnodebyname_ipv6_with_snapshot, tc)
1351172629Smav{
1352172629Smav
1353172629Smav	RUN_IPNODE_TESTS(tc, "snapshot_ipnodename6", AF_INET6, TEST_GETHOSTBYNAME2, false);
1354172629Smav}
1355172629Smav
1356172629SmavATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_ADDRCONFIG);
1357172629SmavATF_TC_BODY(getipnodebyname_ipv6_AI_ADDRCONFIG, tc)
1358172629Smav{
1359172629Smav
1360172629Smav	ipnode_flags = AI_ADDRCONFIG;
1361172629Smav	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false);
1362172629Smav}
1363172629Smav
1364172629SmavATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED);
1365172629SmavATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED, tc)
1366172629Smav{
1367172629Smav
1368172629Smav	ipnode_flags = AI_V4MAPPED;
1369172629Smav	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true);
137052419Sjulian}
137152419Sjulian
1372172629SmavATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG);
1373172629SmavATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED_CFG, tc)
137452419Sjulian{
1375172629Smav
1376172629Smav	ipnode_flags = AI_V4MAPPED_CFG;
1377172629Smav	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true);
137852419Sjulian}
1379172629Smav
1380243882SglebiusATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ADDRCONFIG);
1381172629SmavATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ADDRCONFIG, tc)
1382172629Smav{
1383172629Smav
1384172629Smav	ipnode_flags = AI_V4MAPPED_CFG | AI_ADDRCONFIG;
1385172629Smav	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false);
1386172629Smav}
1387172629Smav
1388172629SmavATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ALL);
138952419SjulianATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ALL, tc)
1390172629Smav{
1391172629Smav
1392172629Smav	ipnode_flags = AI_V4MAPPED_CFG | AI_ALL;
139352419Sjulian	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true);
139452419Sjulian}
139552419Sjulian
1396172629SmavATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED);
1397172629SmavATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED, tc)
1398172629Smav{
1399172629Smav
1400172629Smav	ipnode_flags = AI_V4MAPPED;
140164502Sarchie	RUN_IPNODE_TESTS(tc,
1402172629Smav	    "snapshot_ipnodename6_AI_V4MAPPED", AF_INET6,
1403172629Smav	    TEST_GETHOSTBYNAME2, true);
140452419Sjulian}
1405172629Smav
1406172629SmavATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG);
1407172629SmavATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG, tc)
1408172629Smav{
1409172629Smav
141064502Sarchie	ipnode_flags = AI_V4MAPPED_CFG;
1411172629Smav	RUN_IPNODE_TESTS(tc,
1412172629Smav	    "snapshot_ipnodename6_AI_V4MAPPED_CFG", AF_INET6,
1413172629Smav	    TEST_GETHOSTBYNAME2, true);
1414172629Smav}
1415172629Smav
141664502SarchieATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ADDRCONFIG);
1417172629SmavATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ADDRCONFIG, tc)
141864502Sarchie{
1419172629Smav
1420172629Smav	ipnode_flags = AI_V4MAPPED_CFG | AI_ADDRCONFIG;
1421172629Smav	RUN_IPNODE_TESTS(tc,
1422172629Smav	    "snapshot_ipnodename6_AI_V4MAPPED_CFG_AI_ADDRCONFIG", AF_INET6,
142352419Sjulian	    TEST_GETHOSTBYNAME2, false);
1424172629Smav}
1425172629Smav
1426172629SmavATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL);
1427172629SmavATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL, tc)
1428172629Smav{
1429172629Smav
1430172629Smav	ipnode_flags = AI_V4MAPPED_CFG | AI_ALL;
1431172629Smav	RUN_IPNODE_TESTS(tc,
143252419Sjulian	    "snapshot_ipnodename6_AI_V4MAPPED_CFG_AI_ALL", AF_INET6,
1433172629Smav	    TEST_GETHOSTBYNAME2, true);
1434172629Smav}
1435172629Smav
1436172629SmavATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_ADDRCONFIG);
1437172629SmavATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_ADDRCONFIG, tc)
1438172629Smav{
1439172629Smav
1440172629Smav	ipnode_flags = AI_ADDRCONFIG;
1441172629Smav	RUN_IPNODE_TESTS(tc, "snapshot_ipnodename6_AI_ADDRCONFIG", AF_INET6,
1442172629Smav	    TEST_GETHOSTBYNAME2, false);
1443172629Smav}
1444172629Smav
1445172629SmavATF_TC_WITHOUT_HEAD(getipnodebyname_getaddrinfo_ipv6);
144652419SjulianATF_TC_BODY(getipnodebyname_getaddrinfo_ipv6, tc)
1447172629Smav{
1448172629Smav
1449172629Smav	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2_GETADDRINFO, false);
1450172629Smav}
1451172629Smav
1452172629SmavATF_TP_ADD_TCS(tp)
1453172629Smav{
1454172629Smav
145552419Sjulian	/* gethostbyaddr */
1456172629Smav	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv4);
1457172629Smav	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv4_with_snapshot);
145852419Sjulian	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6);
1459172629Smav	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6_AI_V4MAPPED); /* XXX */
1460174981Smav	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6_with_snapshot);
1461174981Smav	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6_with_snapshot_AI_V4MAPPED);
1462174981Smav	ATF_TP_ADD_TC(tp, gethostbyaddr_getnameinfo_ipv4);
1463174981Smav	ATF_TP_ADD_TC(tp, gethostbyaddr_getnameinfo_ipv6);
1464172629Smav
1465172629Smav	/* gethostbyname2 */
1466172629Smav	ATF_TP_ADD_TC(tp, gethostbyname2_getaddrinfo_ipv4);
1467172629Smav	ATF_TP_ADD_TC(tp, gethostbyname2_getaddrinfo_ipv6);
1468172629Smav	ATF_TP_ADD_TC(tp, gethostbyname2_ipv4);
146952419Sjulian	ATF_TP_ADD_TC(tp, gethostbyname2_ipv4_with_snapshot);
1470174981Smav	ATF_TP_ADD_TC(tp, gethostbyname2_ipv6);
1471174981Smav	ATF_TP_ADD_TC(tp, gethostbyname2_ipv6_AI_V4MAPPED);
1472174981Smav	ATF_TP_ADD_TC(tp, gethostbyname2_ipv6_with_snapshot);
1473174981Smav	ATF_TP_ADD_TC(tp, gethostbyname2_ipv6_with_snapshot_AI_V4MAPPED);
1474174981Smav
1475174981Smav	/* getipnodebyaddr */
1476174981Smav	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv4);
1477174981Smav	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv4_with_snapshot);
1478189315Sed	ATF_TP_ADD_TC(tp, getipnodebyaddr_getnameinfo_ipv4);
1479189315Sed	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6);
1480174981Smav	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_AI_V4MAPPED);
1481174981Smav	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_AI_V4MAPPED_CFG);
1482174981Smav	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_AI_V4MAPPED_CFG_AI_ALL);
1483174981Smav	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot);
1484174981Smav	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED);
1485138562Sglebius	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG);
148652419Sjulian	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL);
148752419Sjulian	ATF_TP_ADD_TC(tp, getipnodebyaddr_getnameinfo_ipv6);
148852419Sjulian
1489172629Smav	/* getipnodebyname */
149052419Sjulian	ATF_TP_ADD_TC(tp, getipnodebyname_ipv4);
1491172629Smav	ATF_TP_ADD_TC(tp, getipnodebyname_ipv4_with_snapshot);
149252419Sjulian	ATF_TP_ADD_TC(tp, getipnodebyname_ipv4_AI_ADDRCONFIG);
149352419Sjulian	ATF_TP_ADD_TC(tp, getipnodebyname_ipv4_with_snapshot_AI_ADDRCONFIG);
149452419Sjulian	ATF_TP_ADD_TC(tp, getipnodebyname_getaddrinfo_ipv4);
149552419Sjulian	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6);
149652419Sjulian	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot);
1497172629Smav	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_ADDRCONFIG);
1498172629Smav	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED);
1499172629Smav	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED_CFG);
1500172629Smav	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ADDRCONFIG);
1501172629Smav	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ALL);
1502172629Smav	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED);
1503172629Smav	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG);
1504172629Smav	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ADDRCONFIG);
1505172629Smav	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL);
1506288918Smav	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_ADDRCONFIG);
1507288918Smav	ATF_TP_ADD_TC(tp, getipnodebyname_getaddrinfo_ipv6);
1508288918Smav
1509172629Smav	return (atf_no_error());
1510172629Smav}
1511172629Smav