1/*-
2 * Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: stable/11/lib/libc/tests/nss/gethostby_test.c 321143 2017-07-18 18:09:16Z ngie $");
30
31#include <sys/param.h>
32#include <sys/socket.h>
33#include <arpa/inet.h>
34#include <netinet/in.h>
35#include <errno.h>
36#include <netdb.h>
37#include <resolv.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <stringlist.h>
42#include <unistd.h>
43
44#include <atf-c.h>
45
46#include "freebsd_test_suite/macros.h"
47#include "testutil.h"
48
49enum test_methods {
50	TEST_GETHOSTBYNAME2,
51	TEST_GETHOSTBYADDR,
52	TEST_GETHOSTBYNAME2_GETADDRINFO,
53	TEST_GETHOSTBYADDR_GETNAMEINFO,
54	TEST_BUILD_SNAPSHOT,
55	TEST_BUILD_ADDR_SNAPSHOT
56};
57
58static int ipnode_flags = 0;
59static int af_type = AF_INET;
60static bool use_ipnode_functions;
61
62DECLARE_TEST_DATA(hostent)
63DECLARE_TEST_FILE_SNAPSHOT(hostent)
64DECLARE_1PASS_TEST(hostent)
65DECLARE_2PASS_TEST(hostent)
66
67/* These stubs will use gethostby***() or getipnodeby***() functions,
68 * depending on the use_ipnode_functions global variable value */
69static struct hostent *__gethostbyname2(const char *, int);
70static struct hostent *__gethostbyaddr(const void *, socklen_t, int);
71static void __freehostent(struct hostent *);
72
73static void clone_hostent(struct hostent *, struct hostent const *);
74static int compare_hostent(struct hostent *, struct hostent *, void *);
75static void dump_hostent(struct hostent *);
76static void free_hostent(struct hostent *);
77
78static int is_hostent_equal(struct hostent *, struct addrinfo *);
79
80static void sdump_hostent(struct hostent *, char *, size_t);
81static int hostent_read_hostlist_func(struct hostent *, char *);
82static int hostent_read_snapshot_addr(char *, unsigned char *, size_t);
83static int hostent_read_snapshot_func(struct hostent *, char *);
84
85static int hostent_test_correctness(struct hostent *, void *);
86static int hostent_test_gethostbyaddr(struct hostent *, void *);
87static int hostent_test_getaddrinfo_eq(struct hostent *, void *);
88static int hostent_test_getnameinfo_eq(struct hostent *, void *);
89
90IMPLEMENT_TEST_DATA(hostent)
91IMPLEMENT_TEST_FILE_SNAPSHOT(hostent)
92IMPLEMENT_1PASS_TEST(hostent)
93IMPLEMENT_2PASS_TEST(hostent)
94
95static struct hostent *
96__gethostbyname2(const char *name, int af)
97{
98	struct hostent *he;
99	int error;
100
101	if (use_ipnode_functions) {
102		error = 0;
103		he = getipnodebyname(name, af, ipnode_flags, &error);
104		if (he == NULL)
105			errno = error;
106	} else
107		he = gethostbyname2(name, af);
108
109	return (he);
110}
111
112static struct hostent *
113__gethostbyaddr(const void *addr, socklen_t len, int af)
114{
115	struct hostent *he;
116	int error;
117
118	if (use_ipnode_functions) {
119		error = 0;
120		he = getipnodebyaddr(addr, len, af, &error);
121		if (he == NULL)
122			errno = error;
123	} else
124		he = gethostbyaddr(addr, len, af);
125
126	return (he);
127}
128
129static void
130__freehostent(struct hostent *he)
131{
132
133	/* NOTE: checking for he != NULL - just in case */
134	if (use_ipnode_functions && he != NULL)
135		freehostent(he);
136}
137
138static void
139clone_hostent(struct hostent *dest, struct hostent const *src)
140{
141	ATF_REQUIRE(dest != NULL);
142	ATF_REQUIRE(src != NULL);
143
144	char **cp;
145	int aliases_num;
146	int addrs_num;
147	size_t offset;
148
149	memset(dest, 0, sizeof(struct hostent));
150
151	if (src->h_name != NULL) {
152		dest->h_name = strdup(src->h_name);
153		ATF_REQUIRE(dest->h_name != NULL);
154	}
155
156	dest->h_addrtype = src->h_addrtype;
157	dest->h_length = src->h_length;
158
159	if (src->h_aliases != NULL) {
160		aliases_num = 0;
161		for (cp = src->h_aliases; *cp; ++cp)
162			++aliases_num;
163
164		dest->h_aliases = calloc(aliases_num + 1, sizeof(char *));
165		ATF_REQUIRE(dest->h_aliases != NULL);
166
167		for (cp = src->h_aliases; *cp; ++cp) {
168			dest->h_aliases[cp - src->h_aliases] = strdup(*cp);
169			ATF_REQUIRE(dest->h_aliases[cp - src->h_aliases] != NULL);
170		}
171	}
172
173	if (src->h_addr_list != NULL) {
174		addrs_num = 0;
175		for (cp = src->h_addr_list; *cp; ++cp)
176			++addrs_num;
177
178		dest->h_addr_list = calloc(addrs_num + 1, sizeof(char *));
179		ATF_REQUIRE(dest->h_addr_list != NULL);
180
181		for (cp = src->h_addr_list; *cp; ++cp) {
182			offset = cp - src->h_addr_list;
183			dest->h_addr_list[offset] = malloc(src->h_length);
184			ATF_REQUIRE(dest->h_addr_list[offset] != NULL);
185			memcpy(dest->h_addr_list[offset],
186			    src->h_addr_list[offset], src->h_length);
187		}
188	}
189}
190
191static void
192free_hostent(struct hostent *ht)
193{
194	char **cp;
195
196	ATF_REQUIRE(ht != NULL);
197
198	free(ht->h_name);
199
200	if (ht->h_aliases != NULL) {
201		for (cp = ht->h_aliases; *cp; ++cp)
202			free(*cp);
203		free(ht->h_aliases);
204	}
205
206	if  (ht->h_addr_list != NULL) {
207		for (cp = ht->h_addr_list; *cp; ++cp)
208			free(*cp);
209		free(ht->h_addr_list);
210	}
211}
212
213static  int
214compare_hostent(struct hostent *ht1, struct hostent *ht2, void *mdata)
215{
216	char **c1, **c2, **ct, **cb;
217	int b;
218
219	if (ht1 == ht2)
220		return 0;
221
222	if (ht1 == NULL || ht2 == NULL)
223		goto errfin;
224
225	if (ht1->h_name == NULL || ht2->h_name == NULL)
226		goto errfin;
227
228	if (ht1->h_addrtype != ht2->h_addrtype ||
229	    ht1->h_length != ht2->h_length ||
230	    strcmp(ht1->h_name, ht2->h_name) != 0)
231		goto errfin;
232
233	c1 = ht1->h_aliases;
234	c2 = ht2->h_aliases;
235
236	if ((ht1->h_aliases == NULL || ht2->h_aliases == NULL) &&
237	    ht1->h_aliases != ht2->h_aliases)
238		goto errfin;
239
240	if (c1 != NULL && c2 != NULL) {
241		cb = c1;
242		for (;*c1; ++c1) {
243			b = 0;
244			for (ct = c2; *ct; ++ct) {
245				if (strcmp(*c1, *ct) == 0) {
246					b = 1;
247					break;
248				}
249			}
250			if (b == 0) {
251				printf("h1 aliases item can't be found in h2 "
252				    "aliases\n");
253				goto errfin;
254			}
255		}
256
257		c1 = cb;
258		for (;*c2; ++c2) {
259			b = 0;
260			for (ct = c1; *ct; ++ct) {
261				if (strcmp(*c2, *ct) == 0) {
262					b = 1;
263					break;
264				}
265			}
266			if (b == 0) {
267				printf("h2 aliases item can't be found in h1 "
268				    "aliases\n");
269				goto errfin;
270			}
271		}
272	}
273
274	c1 = ht1->h_addr_list;
275	c2 = ht2->h_addr_list;
276
277	if ((ht1->h_addr_list == NULL || ht2->h_addr_list== NULL) &&
278	    ht1->h_addr_list != ht2->h_addr_list)
279		goto errfin;
280
281	if (c1 != NULL && c2 != NULL) {
282		cb = c1;
283		for (; *c1; ++c1) {
284			b = 0;
285			for (ct = c2; *ct; ++ct) {
286				if (memcmp(*c1, *ct, ht1->h_length) == 0) {
287					b = 1;
288					break;
289				}
290			}
291			if (b == 0) {
292				printf("h1 addresses item can't be found in "
293				    "h2 addresses\n");
294				goto errfin;
295			}
296		}
297
298		c1 = cb;
299		for (; *c2; ++c2) {
300			b = 0;
301			for (ct = c1; *ct; ++ct) {
302				if (memcmp(*c2, *ct, ht1->h_length) == 0) {
303					b = 1;
304					break;
305				}
306			}
307			if (b == 0) {
308				printf("h2 addresses item can't be found in "
309				    "h1 addresses\n");
310				goto errfin;
311			}
312		}
313	}
314
315	return 0;
316
317errfin:
318	if (mdata == NULL) {
319		printf("following structures are not equal:\n");
320		dump_hostent(ht1);
321		dump_hostent(ht2);
322	}
323
324	return (-1);
325}
326
327static int
328check_addrinfo_for_name(struct addrinfo *ai, char const *name)
329{
330	struct addrinfo *ai2;
331
332	for (ai2 = ai; ai2 != NULL; ai2 = ai2->ai_next) {
333		if (strcmp(ai2->ai_canonname, name) == 0)
334			return (0);
335	}
336
337	return (-1);
338}
339
340static int
341check_addrinfo_for_addr(struct addrinfo *ai, char const *addr,
342	socklen_t addrlen, int af)
343{
344	struct addrinfo *ai2;
345
346	for (ai2 = ai; ai2 != NULL; ai2 = ai2->ai_next) {
347		if (af != ai2->ai_family)
348			continue;
349
350		switch (af) {
351		case AF_INET:
352			if (memcmp(addr,
353			    (void *)&((struct sockaddr_in *)ai2->ai_addr)->sin_addr,
354			    MIN(addrlen, ai2->ai_addrlen)) == 0)
355				return (0);
356			break;
357		case AF_INET6:
358			if (memcmp(addr,
359			    (void *)&((struct sockaddr_in6 *)ai2->ai_addr)->sin6_addr,
360			    MIN(addrlen, ai2->ai_addrlen)) == 0)
361				return (0);
362			break;
363		default:
364			break;
365		}
366	}
367
368	return (-1);
369}
370
371static int
372is_hostent_equal(struct hostent *he, struct addrinfo *ai)
373{
374	char **cp;
375	int rv;
376
377#ifdef DEBUG
378	printf("checking equality of he and ai\n");
379#endif
380
381	rv = check_addrinfo_for_name(ai, he->h_name);
382	if (rv != 0) {
383		printf("not equal - he->h_name couldn't be found\n");
384		return (rv);
385	}
386
387	for (cp = he->h_addr_list; *cp; ++cp) {
388		rv = check_addrinfo_for_addr(ai, *cp, he->h_length,
389			he->h_addrtype);
390		if (rv != 0) {
391			printf("not equal - one of he->h_addr_list couldn't be found\n");
392			return (rv);
393		}
394	}
395
396#ifdef DEBUG
397	printf("equal\n");
398#endif
399
400	return (0);
401}
402
403static void
404sdump_hostent(struct hostent *ht, char *buffer, size_t buflen)
405{
406	char **cp;
407	size_t i;
408	int written;
409
410	written = snprintf(buffer, buflen, "%s %d %d",
411		ht->h_name, ht->h_addrtype, ht->h_length);
412	buffer += written;
413	if (written > (int)buflen)
414		return;
415	buflen -= written;
416
417	if (ht->h_aliases != NULL) {
418		if (*(ht->h_aliases) != NULL) {
419			for (cp = ht->h_aliases; *cp; ++cp) {
420				written = snprintf(buffer, buflen, " %s",*cp);
421				buffer += written;
422				if (written > (int)buflen)
423					return;
424				buflen -= written;
425
426				if (buflen == 0)
427					return;
428			}
429		} else {
430			written = snprintf(buffer, buflen, " noaliases");
431			buffer += written;
432			if (written > (int)buflen)
433				return;
434			buflen -= written;
435		}
436	} else {
437		written = snprintf(buffer, buflen, " (null)");
438		buffer += written;
439		if (written > (int)buflen)
440			return;
441		buflen -= written;
442	}
443
444	written = snprintf(buffer, buflen, " : ");
445	buffer += written;
446	if (written > (int)buflen)
447		return;
448	buflen -= written;
449
450	if (ht->h_addr_list != NULL) {
451		if (*(ht->h_addr_list) != NULL) {
452			for (cp = ht->h_addr_list; *cp; ++cp) {
453				for (i = 0; i < (size_t)ht->h_length; ++i) {
454					written = snprintf(buffer, buflen,
455					    i + 1 != (size_t)ht->h_length ?
456					        "%d." : "%d",
457					    (unsigned char)(*cp)[i]);
458					buffer += written;
459					if (written > (int)buflen)
460						return;
461					buflen -= written;
462
463					if (buflen == 0)
464						return;
465				}
466
467				if (*(cp + 1)) {
468					written = snprintf(buffer, buflen,
469					    " ");
470					buffer += written;
471					if (written > (int)buflen)
472						return;
473					buflen -= written;
474				}
475			}
476		} else {
477			written = snprintf(buffer, buflen, " noaddrs");
478			buffer += written;
479			if (written > (int)buflen)
480				return;
481			buflen -= written;
482		}
483	} else {
484		written = snprintf(buffer, buflen, " (null)");
485		buffer += written;
486		if (written > (int)buflen)
487			return;
488		buflen -= written;
489	}
490}
491
492static int
493hostent_read_hostlist_func(struct hostent *he, char *line)
494{
495	struct hostent *result;
496	int rv;
497
498#ifdef DEBUG
499	printf("resolving %s: ", line);
500#endif
501	result = __gethostbyname2(line, af_type);
502	if (result != NULL) {
503#ifdef DEBUG
504		printf("found\n");
505#endif
506
507		rv = hostent_test_correctness(result, NULL);
508		if (rv != 0) {
509			__freehostent(result);
510			return (rv);
511		}
512
513		clone_hostent(he, result);
514		__freehostent(result);
515	} else {
516#ifdef DEBUG
517		printf("not found\n");
518#endif
519 		memset(he, 0, sizeof(struct hostent));
520		he->h_name = strdup(line);
521		ATF_REQUIRE(he->h_name != NULL);
522	}
523	return (0);
524}
525
526static int
527hostent_read_snapshot_addr(char *addr, unsigned char *result, size_t len)
528{
529	char *s, *ps, *ts;
530
531	ps = addr;
532	while ( (s = strsep(&ps, ".")) != NULL) {
533		if (len == 0)
534			return (-1);
535
536		*result = (unsigned char)strtol(s, &ts, 10);
537		++result;
538		if (*ts != '\0')
539			return (-1);
540
541		--len;
542	}
543	if (len != 0)
544		return (-1);
545	else
546		return (0);
547}
548
549static int
550hostent_read_snapshot_func(struct hostent *ht, char *line)
551{
552	StringList *sl1, *sl2;
553	char *s, *ps, *ts;
554	int i, rv;
555
556#ifdef DEBUG
557	printf("1 line read from snapshot:\n%s\n", line);
558#endif
559
560	rv = 0;
561	i = 0;
562	sl1 = sl2 = NULL;
563	ps = line;
564	memset(ht, 0, sizeof(struct hostent));
565	while ((s = strsep(&ps, " ")) != NULL) {
566		switch (i) {
567		case 0:
568			ht->h_name = strdup(s);
569			ATF_REQUIRE(ht->h_name != NULL);
570			break;
571
572		case 1:
573			ht->h_addrtype = (int)strtol(s, &ts, 10);
574			if (*ts != '\0')
575				goto fin;
576			break;
577
578		case 2:
579			ht->h_length = (int)strtol(s, &ts, 10);
580			if (*ts != '\0')
581				goto fin;
582			break;
583
584		case 3:
585			if (sl1 == NULL) {
586				if (strcmp(s, "(null)") == 0)
587					return (0);
588
589				sl1 = sl_init();
590				ATF_REQUIRE(sl1 != NULL);
591
592				if (strcmp(s, "noaliases") != 0) {
593					ts = strdup(s);
594					ATF_REQUIRE(ts != NULL);
595					sl_add(sl1, ts);
596				}
597			} else {
598				if (strcmp(s, ":") == 0)
599					++i;
600				else {
601					ts = strdup(s);
602					ATF_REQUIRE(ts != NULL);
603					sl_add(sl1, ts);
604				}
605			}
606			break;
607
608		case 4:
609			if (sl2 == NULL) {
610				if (strcmp(s, "(null)") == 0)
611					return (0);
612
613				sl2 = sl_init();
614				ATF_REQUIRE(sl2 != NULL);
615
616				if (strcmp(s, "noaddrs") != 0) {
617					ts = calloc(1, ht->h_length);
618					ATF_REQUIRE(ts != NULL);
619					rv = hostent_read_snapshot_addr(s,
620					    (unsigned char *)ts,
621					    ht->h_length);
622					sl_add(sl2, ts);
623					if (rv != 0)
624						goto fin;
625				}
626			} else {
627				ts = calloc(1, ht->h_length);
628				ATF_REQUIRE(ts != NULL);
629				rv = hostent_read_snapshot_addr(s,
630				    (unsigned char *)ts, ht->h_length);
631				sl_add(sl2, ts);
632				if (rv != 0)
633					goto fin;
634			}
635			break;
636		default:
637			break;
638		}
639
640		if (i != 3 && i != 4)
641			++i;
642	}
643
644fin:
645	if (sl1 != NULL) {
646		sl_add(sl1, NULL);
647		ht->h_aliases = sl1->sl_str;
648	}
649	if (sl2 != NULL) {
650		sl_add(sl2, NULL);
651		ht->h_addr_list = sl2->sl_str;
652	}
653
654	if ((i != 4) || (rv != 0)) {
655		free_hostent(ht);
656		memset(ht, 0, sizeof(struct hostent));
657		return (-1);
658	}
659
660	/* NOTE: is it a dirty hack or not? */
661	free(sl1);
662	free(sl2);
663	return (0);
664}
665
666static void
667dump_hostent(struct hostent *result)
668{
669	if (result != NULL) {
670		char buffer[1024];
671		sdump_hostent(result, buffer, sizeof(buffer));
672		printf("%s\n", buffer);
673	} else
674		printf("(null)\n");
675}
676
677static int
678hostent_test_correctness(struct hostent *ht, void *mdata __unused)
679{
680
681#ifdef DEBUG
682	printf("testing correctness with the following data:\n");
683	dump_hostent(ht);
684#endif
685
686	if (ht == NULL)
687		goto errfin;
688
689	if (ht->h_name == NULL)
690		goto errfin;
691
692	if (!((ht->h_addrtype >= 0) && (ht->h_addrtype < AF_MAX)))
693		goto errfin;
694
695	if ((ht->h_length != sizeof(struct in_addr)) &&
696		(ht->h_length != sizeof(struct in6_addr)))
697		goto errfin;
698
699	if (ht->h_aliases == NULL)
700		goto errfin;
701
702	if (ht->h_addr_list == NULL)
703		goto errfin;
704
705#ifdef DEBUG
706	printf("correct\n");
707#endif
708
709	return (0);
710errfin:
711	printf("incorrect\n");
712
713	return (-1);
714}
715
716static int
717hostent_test_gethostbyaddr(struct hostent *he, void *mdata)
718{
719	struct hostent *result;
720	struct hostent_test_data *addr_test_data;
721	int rv;
722
723	addr_test_data = (struct hostent_test_data *)mdata;
724
725	/* We should omit unresolved hostents */
726	if (he->h_addr_list != NULL) {
727		char **cp;
728		for (cp = he->h_addr_list; *cp; ++cp) {
729#ifdef DEBUG
730			printf("doing reverse lookup for %s\n", he->h_name);
731#endif
732
733			result = __gethostbyaddr(*cp, he->h_length,
734			    he->h_addrtype);
735			if (result == NULL) {
736#ifdef DEBUG
737				printf("%s: warning: reverse lookup failed "
738				    "for %s: %s\n", __func__, he->h_name,
739				    strerror(errno));
740#endif
741				continue;
742			}
743			rv = hostent_test_correctness(result, NULL);
744			if (rv != 0) {
745				__freehostent(result);
746				return (rv);
747			}
748
749			if (addr_test_data != NULL)
750				TEST_DATA_APPEND(hostent, addr_test_data,
751				    result);
752
753			__freehostent(result);
754		}
755	}
756
757	return (0);
758}
759
760static int
761hostent_test_getaddrinfo_eq(struct hostent *he, void *mdata __unused)
762{
763	struct addrinfo *ai, hints;
764	int rv;
765
766	ai = NULL;
767	memset(&hints, 0, sizeof(struct addrinfo));
768	hints.ai_family = af_type;
769	hints.ai_flags = AI_CANONNAME;
770
771	printf("using getaddrinfo() to resolve %s\n", he->h_name);
772
773	/* struct hostent *he was not resolved */
774	if (he->h_addr_list == NULL) {
775		/* We can be sure that he->h_name is not NULL */
776		rv = getaddrinfo(he->h_name, NULL, &hints, &ai);
777		if (rv == 0) {
778			printf("not ok - shouldn't have been resolved\n");
779			rv = -1;
780		} else
781			rv = 0;
782	} else {
783		rv = getaddrinfo(he->h_name, NULL, &hints, &ai);
784		if (rv != 0) {
785			printf("not ok - should have been resolved\n");
786			rv = -1;
787			goto done;
788		}
789		rv = is_hostent_equal(he, ai);
790		if (rv != 0) {
791			printf("not ok - addrinfo and hostent are not equal\n");
792			rv = -1;
793		}
794	}
795done:
796	if (ai != NULL)
797		freeaddrinfo(ai);
798	return (rv);
799}
800
801static int
802hostent_test_getnameinfo_eq(struct hostent *he, void *mdata __unused)
803{
804	char **cp;
805	char buffer[NI_MAXHOST];
806	struct sockaddr_in sin;
807	struct sockaddr_in6 sin6;
808	struct sockaddr *saddr;
809	struct hostent *result;
810	int i, rv;
811
812	if (he->h_addr_list == NULL)
813		return (0);
814
815	for (cp = he->h_addr_list; *cp; ++cp) {
816#ifdef DEBUG
817		printf("doing reverse lookup for %s\n", he->h_name);
818#endif
819		result = __gethostbyaddr(*cp, he->h_length,
820		    he->h_addrtype);
821		if (result != NULL) {
822			rv = hostent_test_correctness(result, NULL);
823			if (rv != 0) {
824				__freehostent(result);
825				return (rv);
826			}
827		} else
828			printf("%s: warning: reverse lookup failed "
829			    "for %s: %s\n", __func__, he->h_name,
830			    strerror(errno));
831
832		switch (he->h_addrtype) {
833		case AF_INET:
834			memset(&sin, 0, sizeof(struct sockaddr_in));
835			sin.sin_len = sizeof(struct sockaddr_in);
836			sin.sin_family = AF_INET;
837			memcpy(&sin.sin_addr, *cp, he->h_length);
838
839			saddr = (struct sockaddr *)&sin;
840			break;
841		case AF_INET6:
842			memset(&sin6, 0, sizeof(struct sockaddr_in6));
843			sin6.sin6_len = sizeof(struct sockaddr_in6);
844			sin6.sin6_family = AF_INET6;
845			memcpy(&sin6.sin6_addr, *cp, he->h_length);
846
847			saddr = (struct sockaddr *)&sin6;
848			break;
849		default:
850			printf("warning: %d family is unsupported\n",
851			    he->h_addrtype);
852			continue;
853		}
854
855		ATF_REQUIRE(saddr != NULL);
856		rv = getnameinfo(saddr, saddr->sa_len, buffer,
857			sizeof(buffer), NULL, 0, NI_NAMEREQD);
858
859		if (rv != 0 && result != NULL) {
860			printf("getnameinfo() didn't make the reverse "
861			    "lookup, when it should have (%s)\n",
862			    gai_strerror(rv));
863			return (rv);
864		}
865
866		if (rv == 0 && result == NULL) {
867			printf("getnameinfo() made the "
868			    "reverse lookup, when it shouldn't have\n");
869			return (rv);
870		}
871
872		if (rv != 0 && result == NULL) {
873#ifdef DEBUG
874			printf("both getnameinfo() and ***byaddr() failed as "
875			    "expected\n");
876#endif
877			continue;
878		}
879
880#ifdef DEBUG
881		printf("comparing %s with %s\n", result->h_name,
882		    buffer);
883#endif
884
885		/*
886		 * An address might reverse resolve to hostname alias or the
887		 * official hostname, e.g. moon.vub.ac.be.
888		 */
889		bool found_a_match = false;
890
891		if (strcmp(result->h_name, buffer) == 0) {
892			found_a_match = true;
893#ifdef DEBUG
894			printf("matched official hostname\n");
895#endif
896		} else {
897			for (i = 0; result->h_aliases[i] != NULL; i++) {
898				printf("[%d] resolved: %s\n", i,
899				    result->h_aliases[i]);
900				if (strcmp(result->h_aliases[i],
901				    buffer) == 0) {
902					printf("matched hostname alias\n");
903					found_a_match = true;
904					break;
905				}
906			}
907		}
908		__freehostent(result);
909
910		if (found_a_match) {
911#ifdef DEBUG
912			printf("getnameinfo() and ***byaddr() results are "
913			    "equal\n");
914#endif
915		} else {
916			printf("getnameinfo() and ***byaddr() results are not "
917			    "equal for %s\n", he->h_name);
918			return (-1);
919		}
920	}
921
922	return (0);
923}
924
925static int
926run_tests(const char *hostlist_file, const char *snapshot_file, int _af_type,
927    enum test_methods method, bool use_ipv6_mapping)
928{
929	char *snapshot_file_copy;
930	struct hostent_test_data td, td_addr, td_snap;
931	res_state statp;
932	int rv = -2;
933
934	if (snapshot_file == NULL)
935		snapshot_file_copy = NULL;
936	else {
937		snapshot_file_copy = strdup(snapshot_file);
938		ATF_REQUIRE(snapshot_file_copy != NULL);
939	}
940	snapshot_file = snapshot_file_copy;
941
942	switch (_af_type) {
943	case AF_INET:
944		ATF_REQUIRE_FEATURE("inet");
945		ATF_REQUIRE(!use_ipv6_mapping);
946		break;
947	case AF_INET6:
948		ATF_REQUIRE_FEATURE("inet6");
949		break;
950	default:
951		atf_tc_fail("unhandled address family: %d", _af_type);
952		break;
953	}
954
955	if (!use_ipnode_functions) {
956		statp = __res_state();
957		if (statp == NULL || ((statp->options & RES_INIT) == 0 &&
958		    res_ninit(statp) == -1)) {
959			printf("error: can't init res_state\n");
960			rv = -1;
961			goto fin2;
962		}
963
964		if (use_ipv6_mapping)
965			statp->options |= RES_USE_INET6;
966		else
967			statp->options &= ~RES_USE_INET6;
968	}
969
970	TEST_DATA_INIT(hostent, &td, clone_hostent, free_hostent);
971	TEST_DATA_INIT(hostent, &td_addr, clone_hostent, free_hostent);
972	TEST_DATA_INIT(hostent, &td_snap, clone_hostent, free_hostent);
973
974	if (access(hostlist_file, R_OK) != 0) {
975		printf("can't access the hostlist file %s\n", hostlist_file);
976		rv = -1;
977		goto fin;
978	}
979
980#ifdef DEBUG
981	printf("building host lists from %s\n", hostlist_file);
982#endif
983
984	rv = TEST_SNAPSHOT_FILE_READ(hostent, hostlist_file, &td,
985		hostent_read_hostlist_func);
986	if (rv != 0) {
987		printf("failed to read the host list file: %s\n",
988		    hostlist_file);
989		goto fin;
990	}
991
992	if (snapshot_file != NULL) {
993		if (access(snapshot_file, W_OK | R_OK) != 0) {
994			if (errno == ENOENT) {
995				if (method != TEST_GETHOSTBYADDR)
996					method = TEST_BUILD_SNAPSHOT;
997				else
998					method = TEST_BUILD_ADDR_SNAPSHOT;
999			} else {
1000				printf("can't access the snapshot file %s\n",
1001				    snapshot_file);
1002				rv = -1;
1003				goto fin;
1004			}
1005		} else {
1006			rv = TEST_SNAPSHOT_FILE_READ(hostent, snapshot_file,
1007				&td_snap, hostent_read_snapshot_func);
1008			if (rv != 0) {
1009				printf("error reading snapshot file\n");
1010				goto fin;
1011			}
1012		}
1013	}
1014
1015	switch (method) {
1016	case TEST_GETHOSTBYNAME2:
1017		if (snapshot_file != NULL)
1018			rv = DO_2PASS_TEST(hostent, &td, &td_snap,
1019			    compare_hostent, NULL);
1020		break;
1021	case TEST_GETHOSTBYADDR:
1022		rv = DO_1PASS_TEST(hostent, &td,
1023			hostent_test_gethostbyaddr, (void *)&td_addr);
1024		if (rv != 0)
1025			goto fin;
1026
1027		if (snapshot_file != NULL)
1028			rv = DO_2PASS_TEST(hostent, &td_addr, &td_snap,
1029			    compare_hostent, NULL);
1030		break;
1031	case TEST_GETHOSTBYNAME2_GETADDRINFO:
1032		rv = DO_1PASS_TEST(hostent, &td,
1033			hostent_test_getaddrinfo_eq, NULL);
1034		break;
1035	case TEST_GETHOSTBYADDR_GETNAMEINFO:
1036		rv = DO_1PASS_TEST(hostent, &td,
1037			hostent_test_getnameinfo_eq, NULL);
1038		break;
1039	case TEST_BUILD_SNAPSHOT:
1040		if (snapshot_file != NULL) {
1041			rv = TEST_SNAPSHOT_FILE_WRITE(hostent, snapshot_file,
1042			    &td, sdump_hostent);
1043		}
1044		break;
1045	case TEST_BUILD_ADDR_SNAPSHOT:
1046		if (snapshot_file != NULL) {
1047			rv = DO_1PASS_TEST(hostent, &td,
1048			    hostent_test_gethostbyaddr, (void *)&td_addr);
1049			if (rv != 0)
1050				goto fin;
1051			rv = TEST_SNAPSHOT_FILE_WRITE(hostent, snapshot_file,
1052			    &td_addr, sdump_hostent);
1053		}
1054		break;
1055	default:
1056		rv = 0;
1057		break;
1058	}
1059
1060fin:
1061	TEST_DATA_DESTROY(hostent, &td_snap);
1062	TEST_DATA_DESTROY(hostent, &td_addr);
1063	TEST_DATA_DESTROY(hostent, &td);
1064
1065fin2:
1066	free(snapshot_file_copy);
1067
1068	return (rv);
1069}
1070
1071#define	HOSTLIST_FILE	"mach"
1072
1073#define	_RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \
1074do {									\
1075	char *_hostlist_file;						\
1076	ATF_REQUIRE(0 < asprintf(&_hostlist_file, "%s/%s",		\
1077	    atf_tc_get_config_var(tc, "srcdir"), HOSTLIST_FILE));	\
1078	ATF_REQUIRE(run_tests(_hostlist_file, snapshot_file, af_type,	\
1079	    method, use_ipv6_mapping) == 0);				\
1080	free(_hostlist_file);						\
1081} while (0)
1082
1083#define	RUN_HOST_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \
1084do {									\
1085	use_ipnode_functions = false; 					\
1086	_RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping); \
1087} while (0)
1088
1089#define	RUN_IPNODE_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \
1090do {									\
1091	use_ipnode_functions = true; 					\
1092	_RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping); \
1093} while (0)
1094
1095ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv4);
1096ATF_TC_BODY(gethostbyaddr_ipv4, tc)
1097{
1098
1099	RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR, false);
1100}
1101
1102ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv4_with_snapshot);
1103ATF_TC_BODY(gethostbyaddr_ipv4_with_snapshot, tc)
1104{
1105
1106	RUN_HOST_TESTS(tc, "snapshot_htaddr4", AF_INET, TEST_GETHOSTBYADDR, false);
1107}
1108
1109ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6);
1110ATF_TC_BODY(gethostbyaddr_ipv6, tc)
1111{
1112
1113	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, false);
1114}
1115
1116ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_AI_V4MAPPED);
1117ATF_TC_BODY(gethostbyaddr_ipv6_AI_V4MAPPED, tc)
1118{
1119
1120	ipnode_flags = AI_V4MAPPED;
1121	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true);
1122}
1123
1124ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_with_snapshot);
1125ATF_TC_BODY(gethostbyaddr_ipv6_with_snapshot, tc)
1126{
1127
1128	RUN_HOST_TESTS(tc, "snapshot_htaddr6", AF_INET6, TEST_GETHOSTBYADDR, false);
1129}
1130
1131ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_with_snapshot_AI_V4MAPPED);
1132ATF_TC_BODY(gethostbyaddr_ipv6_with_snapshot_AI_V4MAPPED, tc)
1133{
1134
1135	ipnode_flags = AI_V4MAPPED;
1136	RUN_HOST_TESTS(tc, "snapshot_htaddr6map", AF_INET6, TEST_GETHOSTBYADDR, true);
1137}
1138
1139ATF_TC_WITHOUT_HEAD(gethostbyname2_getaddrinfo_ipv4);
1140ATF_TC_BODY(gethostbyname2_getaddrinfo_ipv4, tc)
1141{
1142
1143	RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2_GETADDRINFO, false);
1144}
1145
1146ATF_TC_WITHOUT_HEAD(gethostbyname2_getaddrinfo_ipv6);
1147ATF_TC_BODY(gethostbyname2_getaddrinfo_ipv6, tc)
1148{
1149
1150	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2_GETADDRINFO, false);
1151}
1152
1153ATF_TC_WITHOUT_HEAD(gethostbyaddr_getnameinfo_ipv4);
1154ATF_TC_BODY(gethostbyaddr_getnameinfo_ipv4, tc)
1155{
1156
1157	RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR_GETNAMEINFO, false);
1158}
1159
1160ATF_TC_WITHOUT_HEAD(gethostbyaddr_getnameinfo_ipv6);
1161ATF_TC_BODY(gethostbyaddr_getnameinfo_ipv6, tc)
1162{
1163
1164	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR_GETNAMEINFO, false);
1165}
1166
1167ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv4);
1168ATF_TC_BODY(gethostbyname2_ipv4, tc)
1169{
1170
1171	RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false);
1172}
1173
1174ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv4_with_snapshot);
1175ATF_TC_BODY(gethostbyname2_ipv4_with_snapshot, tc)
1176{
1177
1178	RUN_HOST_TESTS(tc, "snapshot_htname4", AF_INET, TEST_GETHOSTBYNAME2, false);
1179}
1180
1181ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6);
1182ATF_TC_BODY(gethostbyname2_ipv6, tc)
1183{
1184
1185	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false);
1186}
1187
1188ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_AI_V4MAPPED);
1189ATF_TC_BODY(gethostbyname2_ipv6_AI_V4MAPPED, tc)
1190{
1191
1192	ipnode_flags = AI_V4MAPPED;
1193	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true);
1194}
1195
1196ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_with_snapshot);
1197ATF_TC_BODY(gethostbyname2_ipv6_with_snapshot, tc)
1198{
1199
1200	RUN_HOST_TESTS(tc, "snapshot_htname6", AF_INET6, TEST_GETHOSTBYNAME2, false);
1201}
1202
1203ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_with_snapshot_AI_V4MAPPED);
1204ATF_TC_BODY(gethostbyname2_ipv6_with_snapshot_AI_V4MAPPED, tc)
1205{
1206
1207	ipnode_flags = AI_V4MAPPED;
1208	RUN_HOST_TESTS(tc, "snapshot_htname6map", AF_INET6, TEST_GETHOSTBYNAME2, true);
1209}
1210
1211ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv4);
1212ATF_TC_BODY(getipnodebyaddr_ipv4, tc)
1213{
1214
1215	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR, false);
1216}
1217
1218ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv4_with_snapshot);
1219ATF_TC_BODY(getipnodebyaddr_ipv4_with_snapshot, tc)
1220{
1221
1222	RUN_IPNODE_TESTS(tc, "snapshot_ipnodeaddr4", AF_INET, TEST_GETHOSTBYADDR, false);
1223}
1224
1225ATF_TC_WITHOUT_HEAD(getipnodebyaddr_getnameinfo_ipv4);
1226ATF_TC_BODY(getipnodebyaddr_getnameinfo_ipv4, tc)
1227{
1228
1229	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR_GETNAMEINFO, false);
1230}
1231
1232ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6);
1233ATF_TC_BODY(getipnodebyaddr_ipv6, tc)
1234{
1235
1236	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, false);
1237}
1238
1239ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED);
1240ATF_TC_BODY(getipnodebyaddr_ipv6_AI_V4MAPPED, tc)
1241{
1242
1243	ipnode_flags = AI_V4MAPPED;
1244	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true);
1245}
1246
1247ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG);
1248ATF_TC_BODY(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG, tc)
1249{
1250
1251	ipnode_flags = AI_V4MAPPED_CFG;
1252	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true);
1253}
1254
1255ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG_AI_ALL);
1256ATF_TC_BODY(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG_AI_ALL, tc)
1257{
1258
1259	ipnode_flags = AI_V4MAPPED_CFG | AI_ALL;
1260	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true);
1261}
1262
1263ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot);
1264ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot, tc)
1265{
1266
1267	RUN_IPNODE_TESTS(tc, "snapshot_ipnodeaddr6", AF_INET6, TEST_GETHOSTBYADDR, false);
1268}
1269
1270ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED);
1271ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED, tc)
1272{
1273
1274	ipnode_flags = AI_V4MAPPED;
1275	RUN_IPNODE_TESTS(tc,
1276	    "snapshot_ipnodeaddr6_AI_V4MAPPED", AF_INET6,
1277	    TEST_GETHOSTBYADDR, true);
1278}
1279
1280ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG);
1281ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG, tc)
1282{
1283
1284	ipnode_flags = AI_V4MAPPED_CFG;
1285	RUN_IPNODE_TESTS(tc,
1286	    "snapshot_ipnodeaddr6_AI_V4MAPPED_CFG", AF_INET6,
1287	    TEST_GETHOSTBYADDR, true);
1288}
1289
1290ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL);
1291ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL, tc)
1292{
1293
1294	ipnode_flags = AI_V4MAPPED_CFG | AI_ALL;
1295	RUN_IPNODE_TESTS(tc,
1296	    "snapshot_ipnodeaddr6_AI_V4MAPPED_CFG_AI_ALL", AF_INET6,
1297	    TEST_GETHOSTBYADDR, true);
1298}
1299
1300ATF_TC_WITHOUT_HEAD(getipnodebyaddr_getnameinfo_ipv6);
1301ATF_TC_BODY(getipnodebyaddr_getnameinfo_ipv6, tc)
1302{
1303
1304	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR_GETNAMEINFO, false);
1305}
1306
1307ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4);
1308ATF_TC_BODY(getipnodebyname_ipv4, tc)
1309{
1310
1311	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false);
1312}
1313
1314ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_with_snapshot);
1315ATF_TC_BODY(getipnodebyname_ipv4_with_snapshot, tc)
1316{
1317
1318	RUN_IPNODE_TESTS(tc, "snapshot_ipnodename4", AF_INET, TEST_GETHOSTBYNAME2, false);
1319}
1320
1321ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_AI_ADDRCONFIG);
1322ATF_TC_BODY(getipnodebyname_ipv4_AI_ADDRCONFIG, tc)
1323{
1324
1325	ipnode_flags = AI_ADDRCONFIG;
1326	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false);
1327}
1328
1329ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_with_snapshot_AI_ADDRCONFIG);
1330ATF_TC_BODY(getipnodebyname_ipv4_with_snapshot_AI_ADDRCONFIG, tc)
1331{
1332
1333	ipnode_flags = AI_ADDRCONFIG;
1334	RUN_IPNODE_TESTS(tc, "snapshot_ipnodename4_AI_ADDRCONFIG", AF_INET,
1335	    TEST_GETHOSTBYNAME2, false);
1336}
1337
1338ATF_TC_WITHOUT_HEAD(getipnodebyname_getaddrinfo_ipv4);
1339ATF_TC_BODY(getipnodebyname_getaddrinfo_ipv4, tc)
1340{
1341
1342	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2_GETADDRINFO, false);
1343}
1344
1345ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6);
1346ATF_TC_BODY(getipnodebyname_ipv6, tc)
1347{
1348
1349	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false);
1350}
1351
1352ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot);
1353ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot, tc)
1354{
1355
1356	RUN_IPNODE_TESTS(tc, "snapshot_ipnodename6", AF_INET6, TEST_GETHOSTBYNAME2, false);
1357}
1358
1359ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_ADDRCONFIG);
1360ATF_TC_BODY(getipnodebyname_ipv6_AI_ADDRCONFIG, tc)
1361{
1362
1363	ipnode_flags = AI_ADDRCONFIG;
1364	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false);
1365}
1366
1367ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED);
1368ATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED, tc)
1369{
1370
1371	ipnode_flags = AI_V4MAPPED;
1372	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true);
1373}
1374
1375ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG);
1376ATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED_CFG, tc)
1377{
1378
1379	ipnode_flags = AI_V4MAPPED_CFG;
1380	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true);
1381}
1382
1383ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ADDRCONFIG);
1384ATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ADDRCONFIG, tc)
1385{
1386
1387	ipnode_flags = AI_V4MAPPED_CFG | AI_ADDRCONFIG;
1388	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false);
1389}
1390
1391ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ALL);
1392ATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ALL, tc)
1393{
1394
1395	ipnode_flags = AI_V4MAPPED_CFG | AI_ALL;
1396	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true);
1397}
1398
1399ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED);
1400ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED, tc)
1401{
1402
1403	ipnode_flags = AI_V4MAPPED;
1404	RUN_IPNODE_TESTS(tc,
1405	    "snapshot_ipnodename6_AI_V4MAPPED", AF_INET6,
1406	    TEST_GETHOSTBYNAME2, true);
1407}
1408
1409ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG);
1410ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG, tc)
1411{
1412
1413	ipnode_flags = AI_V4MAPPED_CFG;
1414	RUN_IPNODE_TESTS(tc,
1415	    "snapshot_ipnodename6_AI_V4MAPPED_CFG", AF_INET6,
1416	    TEST_GETHOSTBYNAME2, true);
1417}
1418
1419ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ADDRCONFIG);
1420ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ADDRCONFIG, tc)
1421{
1422
1423	ipnode_flags = AI_V4MAPPED_CFG | AI_ADDRCONFIG;
1424	RUN_IPNODE_TESTS(tc,
1425	    "snapshot_ipnodename6_AI_V4MAPPED_CFG_AI_ADDRCONFIG", AF_INET6,
1426	    TEST_GETHOSTBYNAME2, false);
1427}
1428
1429ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL);
1430ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL, tc)
1431{
1432
1433	ipnode_flags = AI_V4MAPPED_CFG | AI_ALL;
1434	RUN_IPNODE_TESTS(tc,
1435	    "snapshot_ipnodename6_AI_V4MAPPED_CFG_AI_ALL", AF_INET6,
1436	    TEST_GETHOSTBYNAME2, true);
1437}
1438
1439ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_ADDRCONFIG);
1440ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_ADDRCONFIG, tc)
1441{
1442
1443	ipnode_flags = AI_ADDRCONFIG;
1444	RUN_IPNODE_TESTS(tc, "snapshot_ipnodename6_AI_ADDRCONFIG", AF_INET6,
1445	    TEST_GETHOSTBYNAME2, false);
1446}
1447
1448ATF_TC_WITHOUT_HEAD(getipnodebyname_getaddrinfo_ipv6);
1449ATF_TC_BODY(getipnodebyname_getaddrinfo_ipv6, tc)
1450{
1451
1452	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2_GETADDRINFO, false);
1453}
1454
1455ATF_TP_ADD_TCS(tp)
1456{
1457
1458	/* gethostbyaddr */
1459	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv4);
1460	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv4_with_snapshot);
1461	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6);
1462	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6_AI_V4MAPPED); /* XXX */
1463	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6_with_snapshot);
1464	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6_with_snapshot_AI_V4MAPPED);
1465	ATF_TP_ADD_TC(tp, gethostbyaddr_getnameinfo_ipv4);
1466	ATF_TP_ADD_TC(tp, gethostbyaddr_getnameinfo_ipv6);
1467
1468	/* gethostbyname2 */
1469	ATF_TP_ADD_TC(tp, gethostbyname2_getaddrinfo_ipv4);
1470	ATF_TP_ADD_TC(tp, gethostbyname2_getaddrinfo_ipv6);
1471	ATF_TP_ADD_TC(tp, gethostbyname2_ipv4);
1472	ATF_TP_ADD_TC(tp, gethostbyname2_ipv4_with_snapshot);
1473	ATF_TP_ADD_TC(tp, gethostbyname2_ipv6);
1474	ATF_TP_ADD_TC(tp, gethostbyname2_ipv6_AI_V4MAPPED);
1475	ATF_TP_ADD_TC(tp, gethostbyname2_ipv6_with_snapshot);
1476	ATF_TP_ADD_TC(tp, gethostbyname2_ipv6_with_snapshot_AI_V4MAPPED);
1477
1478	/* getipnodebyaddr */
1479	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv4);
1480	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv4_with_snapshot);
1481	ATF_TP_ADD_TC(tp, getipnodebyaddr_getnameinfo_ipv4);
1482	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6);
1483	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_AI_V4MAPPED);
1484	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_AI_V4MAPPED_CFG);
1485	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_AI_V4MAPPED_CFG_AI_ALL);
1486	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot);
1487	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED);
1488	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG);
1489	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL);
1490	ATF_TP_ADD_TC(tp, getipnodebyaddr_getnameinfo_ipv6);
1491
1492	/* getipnodebyname */
1493	ATF_TP_ADD_TC(tp, getipnodebyname_ipv4);
1494	ATF_TP_ADD_TC(tp, getipnodebyname_ipv4_with_snapshot);
1495	ATF_TP_ADD_TC(tp, getipnodebyname_ipv4_AI_ADDRCONFIG);
1496	ATF_TP_ADD_TC(tp, getipnodebyname_ipv4_with_snapshot_AI_ADDRCONFIG);
1497	ATF_TP_ADD_TC(tp, getipnodebyname_getaddrinfo_ipv4);
1498	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6);
1499	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot);
1500	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_ADDRCONFIG);
1501	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED);
1502	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED_CFG);
1503	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ADDRCONFIG);
1504	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ALL);
1505	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED);
1506	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG);
1507	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ADDRCONFIG);
1508	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL);
1509	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_ADDRCONFIG);
1510	ATF_TP_ADD_TC(tp, getipnodebyname_getaddrinfo_ipv6);
1511
1512	return (atf_no_error());
1513}
1514