xref: /freebsd/lib/libc/tests/nss/gethostby_test.c (revision dedafe6447cc1bee6f6dbe04ce4fe84af1c21780)
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 
49 enum 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 
58 static int ipnode_flags = 0;
59 static int af_type = AF_INET;
60 static bool use_ipnode_functions;
61 
62 DECLARE_TEST_DATA(hostent)
63 DECLARE_TEST_FILE_SNAPSHOT(hostent)
64 DECLARE_1PASS_TEST(hostent)
65 DECLARE_2PASS_TEST(hostent)
66 
67 /* These stubs will use gethostby***() or getipnodeby***() functions,
68  * depending on the use_ipnode_functions global variable value */
69 static struct hostent *__gethostbyname2(const char *, int);
70 static struct hostent *__gethostbyaddr(const void *, socklen_t, int);
71 static void __freehostent(struct hostent *);
72 
73 static void clone_hostent(struct hostent *, struct hostent const *);
74 static int compare_hostent(struct hostent *, struct hostent *, void *);
75 static void dump_hostent(struct hostent *);
76 static void free_hostent(struct hostent *);
77 
78 static int is_hostent_equal(struct hostent *, struct addrinfo *);
79 
80 static void sdump_hostent(struct hostent *, char *, size_t);
81 static int hostent_read_hostlist_func(struct hostent *, char *);
82 static int hostent_read_snapshot_addr(char *, unsigned char *, size_t);
83 static int hostent_read_snapshot_func(struct hostent *, char *);
84 
85 static int hostent_test_correctness(struct hostent *, void *);
86 static int hostent_test_gethostbyaddr(struct hostent *, void *);
87 static int hostent_test_getaddrinfo_eq(struct hostent *, void *);
88 static int hostent_test_getnameinfo_eq(struct hostent *, void *);
89 
90 IMPLEMENT_TEST_DATA(hostent)
91 IMPLEMENT_TEST_FILE_SNAPSHOT(hostent)
92 IMPLEMENT_1PASS_TEST(hostent)
93 IMPLEMENT_2PASS_TEST(hostent)
94 
95 static 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 
112 static 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 
129 static 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 
138 static void
139 clone_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 
191 static void
192 free_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 
213 static  int
214 compare_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 
317 errfin:
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 
327 static int
328 check_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 
340 static int
341 check_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 
371 static int
372 is_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 
403 static void
404 sdump_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 
492 static int
493 hostent_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 
526 static int
527 hostent_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 
549 static int
550 hostent_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 
644 fin:
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 
666 static void
667 dump_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 
677 static int
678 hostent_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);
710 errfin:
711 	printf("incorrect\n");
712 
713 	return (-1);
714 }
715 
716 static int
717 hostent_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 
760 static int
761 hostent_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 			return (-1);
780 		}
781 	} else {
782 		rv = getaddrinfo(he->h_name, NULL, &hints, &ai);
783 		if (rv != 0) {
784 			printf("not ok - should have been resolved\n");
785 			return (-1);
786 		}
787 
788 		rv = is_hostent_equal(he, ai);
789 		if (rv != 0) {
790 			printf("not ok - addrinfo and hostent are not equal\n");
791 			return (-1);
792 		}
793 
794 	}
795 
796 	return (0);
797 }
798 
799 static int
800 hostent_test_getnameinfo_eq(struct hostent *he, void *mdata __unused)
801 {
802 	char **cp;
803 	char buffer[NI_MAXHOST];
804 	struct sockaddr_in sin;
805 	struct sockaddr_in6 sin6;
806 	struct sockaddr *saddr;
807 	struct hostent *result;
808 	int i, rv;
809 
810 	if (he->h_addr_list == NULL)
811 		return (0);
812 
813 	for (cp = he->h_addr_list; *cp; ++cp) {
814 #ifdef DEBUG
815 		printf("doing reverse lookup for %s\n", he->h_name);
816 #endif
817 		result = __gethostbyaddr(*cp, he->h_length,
818 		    he->h_addrtype);
819 		if (result != NULL) {
820 			rv = hostent_test_correctness(result, NULL);
821 			if (rv != 0) {
822 				__freehostent(result);
823 				return (rv);
824 			}
825 		} else
826 			printf("%s: warning: reverse lookup failed "
827 			    "for %s: %s\n", __func__, he->h_name,
828 			    strerror(errno));
829 
830 		switch (he->h_addrtype) {
831 		case AF_INET:
832 			memset(&sin, 0, sizeof(struct sockaddr_in));
833 			sin.sin_len = sizeof(struct sockaddr_in);
834 			sin.sin_family = AF_INET;
835 			memcpy(&sin.sin_addr, *cp, he->h_length);
836 
837 			saddr = (struct sockaddr *)&sin;
838 			break;
839 		case AF_INET6:
840 			memset(&sin6, 0, sizeof(struct sockaddr_in6));
841 			sin6.sin6_len = sizeof(struct sockaddr_in6);
842 			sin6.sin6_family = AF_INET6;
843 			memcpy(&sin6.sin6_addr, *cp, he->h_length);
844 
845 			saddr = (struct sockaddr *)&sin6;
846 			break;
847 		default:
848 			printf("warning: %d family is unsupported\n",
849 			    he->h_addrtype);
850 			continue;
851 		}
852 
853 		ATF_REQUIRE(saddr != NULL);
854 		rv = getnameinfo(saddr, saddr->sa_len, buffer,
855 			sizeof(buffer), NULL, 0, NI_NAMEREQD);
856 
857 		if (rv != 0 && result != NULL) {
858 			printf("getnameinfo() didn't make the reverse "
859 			    "lookup, when it should have (%s)\n",
860 			    gai_strerror(rv));
861 			return (rv);
862 		}
863 
864 		if (rv == 0 && result == NULL) {
865 			printf("getnameinfo() made the "
866 			    "reverse lookup, when it shouldn't have\n");
867 			return (rv);
868 		}
869 
870 		if (rv != 0 && result == NULL) {
871 #ifdef DEBUG
872 			printf("both getnameinfo() and ***byaddr() failed as "
873 			    "expected\n");
874 #endif
875 			continue;
876 		}
877 
878 #ifdef DEBUG
879 		printf("comparing %s with %s\n", result->h_name,
880 		    buffer);
881 #endif
882 
883 		/*
884 		 * An address might reverse resolve to hostname alias or the
885 		 * official hostname, e.g. moon.vub.ac.be.
886 		 */
887 		bool found_a_match = false;
888 
889 		if (strcmp(result->h_name, buffer) == 0) {
890 			found_a_match = true;
891 #ifdef DEBUG
892 			printf("matched official hostname\n");
893 #endif
894 		} else {
895 			for (i = 0; result->h_aliases[i] != NULL; i++) {
896 				printf("[%d] resolved: %s\n", i,
897 				    result->h_aliases[i]);
898 				if (strcmp(result->h_aliases[i],
899 				    buffer) == 0) {
900 					printf("matched hostname alias\n");
901 					found_a_match = true;
902 					break;
903 				}
904 			}
905 		}
906 		__freehostent(result);
907 
908 		if (found_a_match) {
909 #ifdef DEBUG
910 			printf("getnameinfo() and ***byaddr() results are "
911 			    "equal\n");
912 #endif
913 		} else {
914 			printf("getnameinfo() and ***byaddr() results are not "
915 			    "equal for %s\n", he->h_name);
916 			return (-1);
917 		}
918 	}
919 
920 	return (0);
921 }
922 
923 static int
924 run_tests(const char *hostlist_file, const char *snapshot_file, int _af_type,
925     enum test_methods method, bool use_ipv6_mapping)
926 {
927 	char *snapshot_file_copy;
928 	struct hostent_test_data td, td_addr, td_snap;
929 	res_state statp;
930 	int rv = -2;
931 
932 	if (snapshot_file == NULL)
933 		snapshot_file_copy = NULL;
934 	else {
935 		snapshot_file_copy = strdup(snapshot_file);
936 		ATF_REQUIRE(snapshot_file_copy != NULL);
937 	}
938 	snapshot_file = snapshot_file_copy;
939 
940 	switch (_af_type) {
941 	case AF_INET:
942 		ATF_REQUIRE_FEATURE("inet");
943 		ATF_REQUIRE(!use_ipv6_mapping);
944 		break;
945 	case AF_INET6:
946 		ATF_REQUIRE_FEATURE("inet6");
947 		break;
948 	default:
949 		atf_tc_fail("unhandled address family: %d", _af_type);
950 		break;
951 	}
952 
953 	if (!use_ipnode_functions) {
954 		statp = __res_state();
955 		if (statp == NULL || ((statp->options & RES_INIT) == 0 &&
956 		    res_ninit(statp) == -1)) {
957 			printf("error: can't init res_state\n");
958 			rv = -1;
959 			goto fin2;
960 		}
961 
962 		if (use_ipv6_mapping)
963 			statp->options |= RES_USE_INET6;
964 		else
965 			statp->options &= ~RES_USE_INET6;
966 	}
967 
968 	TEST_DATA_INIT(hostent, &td, clone_hostent, free_hostent);
969 	TEST_DATA_INIT(hostent, &td_addr, clone_hostent, free_hostent);
970 	TEST_DATA_INIT(hostent, &td_snap, clone_hostent, free_hostent);
971 
972 	if (access(hostlist_file, R_OK) != 0) {
973 		printf("can't access the hostlist file %s\n", hostlist_file);
974 		rv = -1;
975 		goto fin;
976 	}
977 
978 #ifdef DEBUG
979 	printf("building host lists from %s\n", hostlist_file);
980 #endif
981 
982 	rv = TEST_SNAPSHOT_FILE_READ(hostent, hostlist_file, &td,
983 		hostent_read_hostlist_func);
984 	if (rv != 0) {
985 		printf("failed to read the host list file: %s\n",
986 		    hostlist_file);
987 		goto fin;
988 	}
989 
990 	if (snapshot_file != NULL) {
991 		if (access(snapshot_file, W_OK | R_OK) != 0) {
992 			if (errno == ENOENT) {
993 				if (method != TEST_GETHOSTBYADDR)
994 					method = TEST_BUILD_SNAPSHOT;
995 				else
996 					method = TEST_BUILD_ADDR_SNAPSHOT;
997 			} else {
998 				printf("can't access the snapshot file %s\n",
999 				    snapshot_file);
1000 				rv = -1;
1001 				goto fin;
1002 			}
1003 		} else {
1004 			rv = TEST_SNAPSHOT_FILE_READ(hostent, snapshot_file,
1005 				&td_snap, hostent_read_snapshot_func);
1006 			if (rv != 0) {
1007 				printf("error reading snapshot file\n");
1008 				goto fin;
1009 			}
1010 		}
1011 	}
1012 
1013 	switch (method) {
1014 	case TEST_GETHOSTBYNAME2:
1015 		if (snapshot_file != NULL)
1016 			rv = DO_2PASS_TEST(hostent, &td, &td_snap,
1017 			    compare_hostent, NULL);
1018 		break;
1019 	case TEST_GETHOSTBYADDR:
1020 		rv = DO_1PASS_TEST(hostent, &td,
1021 			hostent_test_gethostbyaddr, (void *)&td_addr);
1022 		if (rv != 0)
1023 			goto fin;
1024 
1025 		if (snapshot_file != NULL)
1026 			rv = DO_2PASS_TEST(hostent, &td_addr, &td_snap,
1027 			    compare_hostent, NULL);
1028 		break;
1029 	case TEST_GETHOSTBYNAME2_GETADDRINFO:
1030 		rv = DO_1PASS_TEST(hostent, &td,
1031 			hostent_test_getaddrinfo_eq, NULL);
1032 		break;
1033 	case TEST_GETHOSTBYADDR_GETNAMEINFO:
1034 		rv = DO_1PASS_TEST(hostent, &td,
1035 			hostent_test_getnameinfo_eq, NULL);
1036 		break;
1037 	case TEST_BUILD_SNAPSHOT:
1038 		if (snapshot_file != NULL) {
1039 			rv = TEST_SNAPSHOT_FILE_WRITE(hostent, snapshot_file,
1040 			    &td, sdump_hostent);
1041 		}
1042 		break;
1043 	case TEST_BUILD_ADDR_SNAPSHOT:
1044 		if (snapshot_file != NULL) {
1045 			rv = DO_1PASS_TEST(hostent, &td,
1046 			    hostent_test_gethostbyaddr, (void *)&td_addr);
1047 			if (rv != 0)
1048 				goto fin;
1049 			rv = TEST_SNAPSHOT_FILE_WRITE(hostent, snapshot_file,
1050 			    &td_addr, sdump_hostent);
1051 		}
1052 		break;
1053 	default:
1054 		rv = 0;
1055 		break;
1056 	}
1057 
1058 fin:
1059 	TEST_DATA_DESTROY(hostent, &td_snap);
1060 	TEST_DATA_DESTROY(hostent, &td_addr);
1061 	TEST_DATA_DESTROY(hostent, &td);
1062 
1063 fin2:
1064 	free(snapshot_file_copy);
1065 
1066 	return (rv);
1067 }
1068 
1069 #define	HOSTLIST_FILE	"mach"
1070 
1071 #define	_RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \
1072 do {									\
1073 	char *_hostlist_file;						\
1074 	ATF_REQUIRE(0 < asprintf(&_hostlist_file, "%s/%s",		\
1075 	    atf_tc_get_config_var(tc, "srcdir"), HOSTLIST_FILE));	\
1076 	ATF_REQUIRE(run_tests(_hostlist_file, snapshot_file, af_type,	\
1077 	    method, use_ipv6_mapping) == 0);				\
1078 	free(_hostlist_file);						\
1079 } while (0)
1080 
1081 #define	RUN_HOST_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \
1082 do {									\
1083 	use_ipnode_functions = false; 					\
1084 	_RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping); \
1085 } while (0)
1086 
1087 #define	RUN_IPNODE_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \
1088 do {									\
1089 	use_ipnode_functions = true; 					\
1090 	_RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping); \
1091 } while (0)
1092 
1093 ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv4);
1094 ATF_TC_BODY(gethostbyaddr_ipv4, tc)
1095 {
1096 
1097 	RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR, false);
1098 }
1099 
1100 ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv4_with_snapshot);
1101 ATF_TC_BODY(gethostbyaddr_ipv4_with_snapshot, tc)
1102 {
1103 
1104 	RUN_HOST_TESTS(tc, "snapshot_htaddr4", AF_INET, TEST_GETHOSTBYADDR, false);
1105 }
1106 
1107 ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6);
1108 ATF_TC_BODY(gethostbyaddr_ipv6, tc)
1109 {
1110 
1111 	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, false);
1112 }
1113 
1114 ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_AI_V4MAPPED);
1115 ATF_TC_BODY(gethostbyaddr_ipv6_AI_V4MAPPED, tc)
1116 {
1117 
1118 	ipnode_flags = AI_V4MAPPED;
1119 	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true);
1120 }
1121 
1122 ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_with_snapshot);
1123 ATF_TC_BODY(gethostbyaddr_ipv6_with_snapshot, tc)
1124 {
1125 
1126 	RUN_HOST_TESTS(tc, "snapshot_htaddr6", AF_INET6, TEST_GETHOSTBYADDR, false);
1127 }
1128 
1129 ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_with_snapshot_AI_V4MAPPED);
1130 ATF_TC_BODY(gethostbyaddr_ipv6_with_snapshot_AI_V4MAPPED, tc)
1131 {
1132 
1133 	ipnode_flags = AI_V4MAPPED;
1134 	RUN_HOST_TESTS(tc, "snapshot_htaddr6map", AF_INET6, TEST_GETHOSTBYADDR, true);
1135 }
1136 
1137 ATF_TC_WITHOUT_HEAD(gethostbyname2_getaddrinfo_ipv4);
1138 ATF_TC_BODY(gethostbyname2_getaddrinfo_ipv4, tc)
1139 {
1140 
1141 	RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2_GETADDRINFO, false);
1142 }
1143 
1144 ATF_TC_WITHOUT_HEAD(gethostbyname2_getaddrinfo_ipv6);
1145 ATF_TC_BODY(gethostbyname2_getaddrinfo_ipv6, tc)
1146 {
1147 
1148 	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2_GETADDRINFO, false);
1149 }
1150 
1151 ATF_TC_WITHOUT_HEAD(gethostbyaddr_getnameinfo_ipv4);
1152 ATF_TC_BODY(gethostbyaddr_getnameinfo_ipv4, tc)
1153 {
1154 
1155 	RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR_GETNAMEINFO, false);
1156 }
1157 
1158 ATF_TC_WITHOUT_HEAD(gethostbyaddr_getnameinfo_ipv6);
1159 ATF_TC_BODY(gethostbyaddr_getnameinfo_ipv6, tc)
1160 {
1161 
1162 	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR_GETNAMEINFO, false);
1163 }
1164 
1165 ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv4);
1166 ATF_TC_BODY(gethostbyname2_ipv4, tc)
1167 {
1168 
1169 	RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false);
1170 }
1171 
1172 ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv4_with_snapshot);
1173 ATF_TC_BODY(gethostbyname2_ipv4_with_snapshot, tc)
1174 {
1175 
1176 	RUN_HOST_TESTS(tc, "snapshot_htname4", AF_INET, TEST_GETHOSTBYNAME2, false);
1177 }
1178 
1179 ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6);
1180 ATF_TC_BODY(gethostbyname2_ipv6, tc)
1181 {
1182 
1183 	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false);
1184 }
1185 
1186 ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_AI_V4MAPPED);
1187 ATF_TC_BODY(gethostbyname2_ipv6_AI_V4MAPPED, tc)
1188 {
1189 
1190 	ipnode_flags = AI_V4MAPPED;
1191 	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true);
1192 }
1193 
1194 ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_with_snapshot);
1195 ATF_TC_BODY(gethostbyname2_ipv6_with_snapshot, tc)
1196 {
1197 
1198 	RUN_HOST_TESTS(tc, "snapshot_htname6", AF_INET6, TEST_GETHOSTBYNAME2, false);
1199 }
1200 
1201 ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_with_snapshot_AI_V4MAPPED);
1202 ATF_TC_BODY(gethostbyname2_ipv6_with_snapshot_AI_V4MAPPED, tc)
1203 {
1204 
1205 	ipnode_flags = AI_V4MAPPED;
1206 	RUN_HOST_TESTS(tc, "snapshot_htname6map", AF_INET6, TEST_GETHOSTBYNAME2, true);
1207 }
1208 
1209 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv4);
1210 ATF_TC_BODY(getipnodebyaddr_ipv4, tc)
1211 {
1212 
1213 	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR, false);
1214 }
1215 
1216 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv4_with_snapshot);
1217 ATF_TC_BODY(getipnodebyaddr_ipv4_with_snapshot, tc)
1218 {
1219 
1220 	RUN_IPNODE_TESTS(tc, "snapshot_ipnodeaddr4", AF_INET, TEST_GETHOSTBYADDR, false);
1221 }
1222 
1223 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_getnameinfo_ipv4);
1224 ATF_TC_BODY(getipnodebyaddr_getnameinfo_ipv4, tc)
1225 {
1226 
1227 	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR_GETNAMEINFO, false);
1228 }
1229 
1230 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6);
1231 ATF_TC_BODY(getipnodebyaddr_ipv6, tc)
1232 {
1233 
1234 	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, false);
1235 }
1236 
1237 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED);
1238 ATF_TC_BODY(getipnodebyaddr_ipv6_AI_V4MAPPED, tc)
1239 {
1240 
1241 	ipnode_flags = AI_V4MAPPED;
1242 	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true);
1243 }
1244 
1245 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG);
1246 ATF_TC_BODY(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG, tc)
1247 {
1248 
1249 	ipnode_flags = AI_V4MAPPED_CFG;
1250 	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true);
1251 }
1252 
1253 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG_AI_ALL);
1254 ATF_TC_BODY(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG_AI_ALL, tc)
1255 {
1256 
1257 	ipnode_flags = AI_V4MAPPED_CFG | AI_ALL;
1258 	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true);
1259 }
1260 
1261 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot);
1262 ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot, tc)
1263 {
1264 
1265 	RUN_IPNODE_TESTS(tc, "snapshot_ipnodeaddr6", AF_INET6, TEST_GETHOSTBYADDR, false);
1266 }
1267 
1268 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED);
1269 ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED, tc)
1270 {
1271 
1272 	ipnode_flags = AI_V4MAPPED;
1273 	RUN_IPNODE_TESTS(tc,
1274 	    "snapshot_ipnodeaddr6_AI_V4MAPPED", AF_INET6,
1275 	    TEST_GETHOSTBYADDR, true);
1276 }
1277 
1278 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG);
1279 ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG, tc)
1280 {
1281 
1282 	ipnode_flags = AI_V4MAPPED_CFG;
1283 	RUN_IPNODE_TESTS(tc,
1284 	    "snapshot_ipnodeaddr6_AI_V4MAPPED_CFG", AF_INET6,
1285 	    TEST_GETHOSTBYADDR, true);
1286 }
1287 
1288 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL);
1289 ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL, tc)
1290 {
1291 
1292 	ipnode_flags = AI_V4MAPPED_CFG | AI_ALL;
1293 	RUN_IPNODE_TESTS(tc,
1294 	    "snapshot_ipnodeaddr6_AI_V4MAPPED_CFG_AI_ALL", AF_INET6,
1295 	    TEST_GETHOSTBYADDR, true);
1296 }
1297 
1298 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_getnameinfo_ipv6);
1299 ATF_TC_BODY(getipnodebyaddr_getnameinfo_ipv6, tc)
1300 {
1301 
1302 	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR_GETNAMEINFO, false);
1303 }
1304 
1305 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4);
1306 ATF_TC_BODY(getipnodebyname_ipv4, tc)
1307 {
1308 
1309 	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false);
1310 }
1311 
1312 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_with_snapshot);
1313 ATF_TC_BODY(getipnodebyname_ipv4_with_snapshot, tc)
1314 {
1315 
1316 	RUN_IPNODE_TESTS(tc, "snapshot_ipnodename4", AF_INET, TEST_GETHOSTBYNAME2, false);
1317 }
1318 
1319 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_AI_ADDRCONFIG);
1320 ATF_TC_BODY(getipnodebyname_ipv4_AI_ADDRCONFIG, tc)
1321 {
1322 
1323 	ipnode_flags = AI_ADDRCONFIG;
1324 	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false);
1325 }
1326 
1327 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_with_snapshot_AI_ADDRCONFIG);
1328 ATF_TC_BODY(getipnodebyname_ipv4_with_snapshot_AI_ADDRCONFIG, tc)
1329 {
1330 
1331 	ipnode_flags = AI_ADDRCONFIG;
1332 	RUN_IPNODE_TESTS(tc, "snapshot_ipnodename4_AI_ADDRCONFIG", AF_INET,
1333 	    TEST_GETHOSTBYNAME2, false);
1334 }
1335 
1336 ATF_TC_WITHOUT_HEAD(getipnodebyname_getaddrinfo_ipv4);
1337 ATF_TC_BODY(getipnodebyname_getaddrinfo_ipv4, tc)
1338 {
1339 
1340 	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2_GETADDRINFO, false);
1341 }
1342 
1343 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6);
1344 ATF_TC_BODY(getipnodebyname_ipv6, tc)
1345 {
1346 
1347 	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false);
1348 }
1349 
1350 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot);
1351 ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot, tc)
1352 {
1353 
1354 	RUN_IPNODE_TESTS(tc, "snapshot_ipnodename6", AF_INET6, TEST_GETHOSTBYNAME2, false);
1355 }
1356 
1357 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_ADDRCONFIG);
1358 ATF_TC_BODY(getipnodebyname_ipv6_AI_ADDRCONFIG, tc)
1359 {
1360 
1361 	ipnode_flags = AI_ADDRCONFIG;
1362 	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false);
1363 }
1364 
1365 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED);
1366 ATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED, tc)
1367 {
1368 
1369 	ipnode_flags = AI_V4MAPPED;
1370 	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true);
1371 }
1372 
1373 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG);
1374 ATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED_CFG, tc)
1375 {
1376 
1377 	ipnode_flags = AI_V4MAPPED_CFG;
1378 	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true);
1379 }
1380 
1381 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ADDRCONFIG);
1382 ATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ADDRCONFIG, tc)
1383 {
1384 
1385 	ipnode_flags = AI_V4MAPPED_CFG | AI_ADDRCONFIG;
1386 	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false);
1387 }
1388 
1389 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ALL);
1390 ATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ALL, tc)
1391 {
1392 
1393 	ipnode_flags = AI_V4MAPPED_CFG | AI_ALL;
1394 	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true);
1395 }
1396 
1397 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED);
1398 ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED, tc)
1399 {
1400 
1401 	ipnode_flags = AI_V4MAPPED;
1402 	RUN_IPNODE_TESTS(tc,
1403 	    "snapshot_ipnodename6_AI_V4MAPPED", AF_INET6,
1404 	    TEST_GETHOSTBYNAME2, true);
1405 }
1406 
1407 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG);
1408 ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG, tc)
1409 {
1410 
1411 	ipnode_flags = AI_V4MAPPED_CFG;
1412 	RUN_IPNODE_TESTS(tc,
1413 	    "snapshot_ipnodename6_AI_V4MAPPED_CFG", AF_INET6,
1414 	    TEST_GETHOSTBYNAME2, true);
1415 }
1416 
1417 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ADDRCONFIG);
1418 ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ADDRCONFIG, tc)
1419 {
1420 
1421 	ipnode_flags = AI_V4MAPPED_CFG | AI_ADDRCONFIG;
1422 	RUN_IPNODE_TESTS(tc,
1423 	    "snapshot_ipnodename6_AI_V4MAPPED_CFG_AI_ADDRCONFIG", AF_INET6,
1424 	    TEST_GETHOSTBYNAME2, false);
1425 }
1426 
1427 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL);
1428 ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL, tc)
1429 {
1430 
1431 	ipnode_flags = AI_V4MAPPED_CFG | AI_ALL;
1432 	RUN_IPNODE_TESTS(tc,
1433 	    "snapshot_ipnodename6_AI_V4MAPPED_CFG_AI_ALL", AF_INET6,
1434 	    TEST_GETHOSTBYNAME2, true);
1435 }
1436 
1437 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_ADDRCONFIG);
1438 ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_ADDRCONFIG, tc)
1439 {
1440 
1441 	ipnode_flags = AI_ADDRCONFIG;
1442 	RUN_IPNODE_TESTS(tc, "snapshot_ipnodename6_AI_ADDRCONFIG", AF_INET6,
1443 	    TEST_GETHOSTBYNAME2, false);
1444 }
1445 
1446 ATF_TC_WITHOUT_HEAD(getipnodebyname_getaddrinfo_ipv6);
1447 ATF_TC_BODY(getipnodebyname_getaddrinfo_ipv6, tc)
1448 {
1449 
1450 	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2_GETADDRINFO, false);
1451 }
1452 
1453 ATF_TP_ADD_TCS(tp)
1454 {
1455 
1456 	/* gethostbyaddr */
1457 	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv4);
1458 	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv4_with_snapshot);
1459 	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6);
1460 	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6_AI_V4MAPPED); /* XXX */
1461 	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6_with_snapshot);
1462 	ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6_with_snapshot_AI_V4MAPPED);
1463 	ATF_TP_ADD_TC(tp, gethostbyaddr_getnameinfo_ipv4);
1464 	ATF_TP_ADD_TC(tp, gethostbyaddr_getnameinfo_ipv6);
1465 
1466 	/* gethostbyname2 */
1467 	ATF_TP_ADD_TC(tp, gethostbyname2_getaddrinfo_ipv4);
1468 	ATF_TP_ADD_TC(tp, gethostbyname2_getaddrinfo_ipv6);
1469 	ATF_TP_ADD_TC(tp, gethostbyname2_ipv4);
1470 	ATF_TP_ADD_TC(tp, gethostbyname2_ipv4_with_snapshot);
1471 	ATF_TP_ADD_TC(tp, gethostbyname2_ipv6);
1472 	ATF_TP_ADD_TC(tp, gethostbyname2_ipv6_AI_V4MAPPED);
1473 	ATF_TP_ADD_TC(tp, gethostbyname2_ipv6_with_snapshot);
1474 	ATF_TP_ADD_TC(tp, gethostbyname2_ipv6_with_snapshot_AI_V4MAPPED);
1475 
1476 	/* getipnodebyaddr */
1477 	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv4);
1478 	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv4_with_snapshot);
1479 	ATF_TP_ADD_TC(tp, getipnodebyaddr_getnameinfo_ipv4);
1480 	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6);
1481 	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_AI_V4MAPPED);
1482 	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_AI_V4MAPPED_CFG);
1483 	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_AI_V4MAPPED_CFG_AI_ALL);
1484 	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot);
1485 	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED);
1486 	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG);
1487 	ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL);
1488 	ATF_TP_ADD_TC(tp, getipnodebyaddr_getnameinfo_ipv6);
1489 
1490 	/* getipnodebyname */
1491 	ATF_TP_ADD_TC(tp, getipnodebyname_ipv4);
1492 	ATF_TP_ADD_TC(tp, getipnodebyname_ipv4_with_snapshot);
1493 	ATF_TP_ADD_TC(tp, getipnodebyname_ipv4_AI_ADDRCONFIG);
1494 	ATF_TP_ADD_TC(tp, getipnodebyname_ipv4_with_snapshot_AI_ADDRCONFIG);
1495 	ATF_TP_ADD_TC(tp, getipnodebyname_getaddrinfo_ipv4);
1496 	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6);
1497 	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot);
1498 	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_ADDRCONFIG);
1499 	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED);
1500 	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED_CFG);
1501 	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ADDRCONFIG);
1502 	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ALL);
1503 	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED);
1504 	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG);
1505 	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ADDRCONFIG);
1506 	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL);
1507 	ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_ADDRCONFIG);
1508 	ATF_TP_ADD_TC(tp, getipnodebyname_getaddrinfo_ipv6);
1509 
1510 	return (atf_no_error());
1511 }
1512