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