xref: /freebsd/lib/libc/tests/nss/gethostby_test.c (revision 42249ef2)
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 			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 	}
795 done:
796 	if (ai != NULL)
797 		freeaddrinfo(ai);
798 	return (rv);
799 }
800 
801 static int
802 hostent_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 
925 static int
926 run_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 
1060 fin:
1061 	TEST_DATA_DESTROY(hostent, &td_snap);
1062 	TEST_DATA_DESTROY(hostent, &td_addr);
1063 	TEST_DATA_DESTROY(hostent, &td);
1064 
1065 fin2:
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) \
1074 do {									\
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) \
1084 do {									\
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) \
1090 do {									\
1091 	use_ipnode_functions = true; 					\
1092 	_RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping); \
1093 } while (0)
1094 
1095 ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv4);
1096 ATF_TC_BODY(gethostbyaddr_ipv4, tc)
1097 {
1098 
1099 	RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR, false);
1100 }
1101 
1102 ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv4_with_snapshot);
1103 ATF_TC_BODY(gethostbyaddr_ipv4_with_snapshot, tc)
1104 {
1105 
1106 	RUN_HOST_TESTS(tc, "snapshot_htaddr4", AF_INET, TEST_GETHOSTBYADDR, false);
1107 }
1108 
1109 ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6);
1110 ATF_TC_BODY(gethostbyaddr_ipv6, tc)
1111 {
1112 
1113 	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, false);
1114 }
1115 
1116 ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_AI_V4MAPPED);
1117 ATF_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 
1124 ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_with_snapshot);
1125 ATF_TC_BODY(gethostbyaddr_ipv6_with_snapshot, tc)
1126 {
1127 
1128 	RUN_HOST_TESTS(tc, "snapshot_htaddr6", AF_INET6, TEST_GETHOSTBYADDR, false);
1129 }
1130 
1131 ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_with_snapshot_AI_V4MAPPED);
1132 ATF_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 
1139 ATF_TC_WITHOUT_HEAD(gethostbyname2_getaddrinfo_ipv4);
1140 ATF_TC_BODY(gethostbyname2_getaddrinfo_ipv4, tc)
1141 {
1142 
1143 	RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2_GETADDRINFO, false);
1144 }
1145 
1146 ATF_TC_WITHOUT_HEAD(gethostbyname2_getaddrinfo_ipv6);
1147 ATF_TC_BODY(gethostbyname2_getaddrinfo_ipv6, tc)
1148 {
1149 
1150 	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2_GETADDRINFO, false);
1151 }
1152 
1153 ATF_TC_WITHOUT_HEAD(gethostbyaddr_getnameinfo_ipv4);
1154 ATF_TC_BODY(gethostbyaddr_getnameinfo_ipv4, tc)
1155 {
1156 
1157 	RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR_GETNAMEINFO, false);
1158 }
1159 
1160 ATF_TC_WITHOUT_HEAD(gethostbyaddr_getnameinfo_ipv6);
1161 ATF_TC_BODY(gethostbyaddr_getnameinfo_ipv6, tc)
1162 {
1163 
1164 	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR_GETNAMEINFO, false);
1165 }
1166 
1167 ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv4);
1168 ATF_TC_BODY(gethostbyname2_ipv4, tc)
1169 {
1170 
1171 	RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false);
1172 }
1173 
1174 ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv4_with_snapshot);
1175 ATF_TC_BODY(gethostbyname2_ipv4_with_snapshot, tc)
1176 {
1177 
1178 	RUN_HOST_TESTS(tc, "snapshot_htname4", AF_INET, TEST_GETHOSTBYNAME2, false);
1179 }
1180 
1181 ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6);
1182 ATF_TC_BODY(gethostbyname2_ipv6, tc)
1183 {
1184 
1185 	RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false);
1186 }
1187 
1188 ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_AI_V4MAPPED);
1189 ATF_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 
1196 ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_with_snapshot);
1197 ATF_TC_BODY(gethostbyname2_ipv6_with_snapshot, tc)
1198 {
1199 
1200 	RUN_HOST_TESTS(tc, "snapshot_htname6", AF_INET6, TEST_GETHOSTBYNAME2, false);
1201 }
1202 
1203 ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_with_snapshot_AI_V4MAPPED);
1204 ATF_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 
1211 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv4);
1212 ATF_TC_BODY(getipnodebyaddr_ipv4, tc)
1213 {
1214 
1215 	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR, false);
1216 }
1217 
1218 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv4_with_snapshot);
1219 ATF_TC_BODY(getipnodebyaddr_ipv4_with_snapshot, tc)
1220 {
1221 
1222 	RUN_IPNODE_TESTS(tc, "snapshot_ipnodeaddr4", AF_INET, TEST_GETHOSTBYADDR, false);
1223 }
1224 
1225 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_getnameinfo_ipv4);
1226 ATF_TC_BODY(getipnodebyaddr_getnameinfo_ipv4, tc)
1227 {
1228 
1229 	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR_GETNAMEINFO, false);
1230 }
1231 
1232 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6);
1233 ATF_TC_BODY(getipnodebyaddr_ipv6, tc)
1234 {
1235 
1236 	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, false);
1237 }
1238 
1239 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED);
1240 ATF_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 
1247 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG);
1248 ATF_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 
1255 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG_AI_ALL);
1256 ATF_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 
1263 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot);
1264 ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot, tc)
1265 {
1266 
1267 	RUN_IPNODE_TESTS(tc, "snapshot_ipnodeaddr6", AF_INET6, TEST_GETHOSTBYADDR, false);
1268 }
1269 
1270 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED);
1271 ATF_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 
1280 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG);
1281 ATF_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 
1290 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL);
1291 ATF_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 
1300 ATF_TC_WITHOUT_HEAD(getipnodebyaddr_getnameinfo_ipv6);
1301 ATF_TC_BODY(getipnodebyaddr_getnameinfo_ipv6, tc)
1302 {
1303 
1304 	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR_GETNAMEINFO, false);
1305 }
1306 
1307 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4);
1308 ATF_TC_BODY(getipnodebyname_ipv4, tc)
1309 {
1310 
1311 	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false);
1312 }
1313 
1314 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_with_snapshot);
1315 ATF_TC_BODY(getipnodebyname_ipv4_with_snapshot, tc)
1316 {
1317 
1318 	RUN_IPNODE_TESTS(tc, "snapshot_ipnodename4", AF_INET, TEST_GETHOSTBYNAME2, false);
1319 }
1320 
1321 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_AI_ADDRCONFIG);
1322 ATF_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 
1329 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_with_snapshot_AI_ADDRCONFIG);
1330 ATF_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 
1338 ATF_TC_WITHOUT_HEAD(getipnodebyname_getaddrinfo_ipv4);
1339 ATF_TC_BODY(getipnodebyname_getaddrinfo_ipv4, tc)
1340 {
1341 
1342 	RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2_GETADDRINFO, false);
1343 }
1344 
1345 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6);
1346 ATF_TC_BODY(getipnodebyname_ipv6, tc)
1347 {
1348 
1349 	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false);
1350 }
1351 
1352 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot);
1353 ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot, tc)
1354 {
1355 
1356 	RUN_IPNODE_TESTS(tc, "snapshot_ipnodename6", AF_INET6, TEST_GETHOSTBYNAME2, false);
1357 }
1358 
1359 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_ADDRCONFIG);
1360 ATF_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 
1367 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED);
1368 ATF_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 
1375 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG);
1376 ATF_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 
1383 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ADDRCONFIG);
1384 ATF_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 
1391 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ALL);
1392 ATF_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 
1399 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED);
1400 ATF_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 
1409 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG);
1410 ATF_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 
1419 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ADDRCONFIG);
1420 ATF_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 
1429 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL);
1430 ATF_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 
1439 ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_ADDRCONFIG);
1440 ATF_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 
1448 ATF_TC_WITHOUT_HEAD(getipnodebyname_getaddrinfo_ipv6);
1449 ATF_TC_BODY(getipnodebyname_getaddrinfo_ipv6, tc)
1450 {
1451 
1452 	RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2_GETADDRINFO, false);
1453 }
1454 
1455 ATF_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