xref: /freebsd/lib/libc/tests/nss/gethostby_test.c (revision 22cf89c938886d14f5796fc49f9f020c23ea8eaf)
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 #include <sys/param.h>
30 #include <sys/socket.h>
31 #include <arpa/inet.h>
32 #include <netinet/in.h>
33 #include <errno.h>
34 #include <netdb.h>
35 #include <resolv.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <stringlist.h>
40 #include <unistd.h>
41 
42 #include <atf-c.h>
43 
44 #include "freebsd_test_suite/macros.h"
45 #include "testutil.h"
46 
47 enum test_methods {
48 	TEST_GETHOSTBYNAME2,
49 	TEST_GETHOSTBYADDR,
50 	TEST_GETHOSTBYNAME2_GETADDRINFO,
51 	TEST_GETHOSTBYADDR_GETNAMEINFO,
52 	TEST_BUILD_SNAPSHOT,
53 	TEST_BUILD_ADDR_SNAPSHOT
54 };
55 
56 static int ipnode_flags = 0;
57 static int af_type = AF_INET;
58 static bool use_ipnode_functions;
59 
60 DECLARE_TEST_DATA(hostent)
61 DECLARE_TEST_FILE_SNAPSHOT(hostent)
62 DECLARE_1PASS_TEST(hostent)
63 DECLARE_2PASS_TEST(hostent)
64 
65 /* These stubs will use gethostby***() or getipnodeby***() functions,
66  * depending on the use_ipnode_functions global variable value */
67 static struct hostent *__gethostbyname2(const char *, int);
68 static struct hostent *__gethostbyaddr(const void *, socklen_t, int);
69 static void __freehostent(struct hostent *);
70 
71 static void clone_hostent(struct hostent *, struct hostent const *);
72 static int compare_hostent(struct hostent *, struct hostent *, void *);
73 static void dump_hostent(struct hostent *);
74 static void free_hostent(struct hostent *);
75 
76 static int is_hostent_equal(struct hostent *, struct addrinfo *);
77 
78 static void sdump_hostent(struct hostent *, char *, size_t);
79 static int hostent_read_hostlist_func(struct hostent *, char *);
80 static int hostent_read_snapshot_addr(char *, unsigned char *, size_t);
81 static int hostent_read_snapshot_func(struct hostent *, char *);
82 
83 static int hostent_test_correctness(struct hostent *, void *);
84 static int hostent_test_gethostbyaddr(struct hostent *, void *);
85 static int hostent_test_getaddrinfo_eq(struct hostent *, void *);
86 static int hostent_test_getnameinfo_eq(struct hostent *, void *);
87 
88 IMPLEMENT_TEST_DATA(hostent)
89 IMPLEMENT_TEST_FILE_SNAPSHOT(hostent)
90 IMPLEMENT_1PASS_TEST(hostent)
91 IMPLEMENT_2PASS_TEST(hostent)
92 
93 static struct hostent *
94 __gethostbyname2(const char *name, int af)
95 {
96 	struct hostent *he;
97 	int error;
98 
99 	if (use_ipnode_functions) {
100 		error = 0;
101 		he = getipnodebyname(name, af, ipnode_flags, &error);
102 		if (he == NULL)
103 			errno = error;
104 	} else
105 		he = gethostbyname2(name, af);
106 
107 	return (he);
108 }
109 
110 static struct hostent *
111 __gethostbyaddr(const void *addr, socklen_t len, int af)
112 {
113 	struct hostent *he;
114 	int error;
115 
116 	if (use_ipnode_functions) {
117 		error = 0;
118 		he = getipnodebyaddr(addr, len, af, &error);
119 		if (he == NULL)
120 			errno = error;
121 	} else
122 		he = gethostbyaddr(addr, len, af);
123 
124 	return (he);
125 }
126 
127 static void
128 __freehostent(struct hostent *he)
129 {
130 
131 	/* NOTE: checking for he != NULL - just in case */
132 	if (use_ipnode_functions && he != NULL)
133 		freehostent(he);
134 }
135 
136 static void
137 clone_hostent(struct hostent *dest, struct hostent const *src)
138 {
139 	ATF_REQUIRE(dest != NULL);
140 	ATF_REQUIRE(src != NULL);
141 
142 	char **cp;
143 	int aliases_num;
144 	int addrs_num;
145 	size_t offset;
146 
147 	memset(dest, 0, sizeof(struct hostent));
148 
149 	if (src->h_name != NULL) {
150 		dest->h_name = strdup(src->h_name);
151 		ATF_REQUIRE(dest->h_name != NULL);
152 	}
153 
154 	dest->h_addrtype = src->h_addrtype;
155 	dest->h_length = src->h_length;
156 
157 	if (src->h_aliases != NULL) {
158 		aliases_num = 0;
159 		for (cp = src->h_aliases; *cp; ++cp)
160 			++aliases_num;
161 
162 		dest->h_aliases = calloc(aliases_num + 1, sizeof(char *));
163 		ATF_REQUIRE(dest->h_aliases != NULL);
164 
165 		for (cp = src->h_aliases; *cp; ++cp) {
166 			dest->h_aliases[cp - src->h_aliases] = strdup(*cp);
167 			ATF_REQUIRE(dest->h_aliases[cp - src->h_aliases] != NULL);
168 		}
169 	}
170 
171 	if (src->h_addr_list != NULL) {
172 		addrs_num = 0;
173 		for (cp = src->h_addr_list; *cp; ++cp)
174 			++addrs_num;
175 
176 		dest->h_addr_list = calloc(addrs_num + 1, sizeof(char *));
177 		ATF_REQUIRE(dest->h_addr_list != NULL);
178 
179 		for (cp = src->h_addr_list; *cp; ++cp) {
180 			offset = cp - src->h_addr_list;
181 			dest->h_addr_list[offset] = malloc(src->h_length);
182 			ATF_REQUIRE(dest->h_addr_list[offset] != NULL);
183 			memcpy(dest->h_addr_list[offset],
184 			    src->h_addr_list[offset], src->h_length);
185 		}
186 	}
187 }
188 
189 static void
190 free_hostent(struct hostent *ht)
191 {
192 	char **cp;
193 
194 	ATF_REQUIRE(ht != NULL);
195 
196 	free(ht->h_name);
197 
198 	if (ht->h_aliases != NULL) {
199 		for (cp = ht->h_aliases; *cp; ++cp)
200 			free(*cp);
201 		free(ht->h_aliases);
202 	}
203 
204 	if  (ht->h_addr_list != NULL) {
205 		for (cp = ht->h_addr_list; *cp; ++cp)
206 			free(*cp);
207 		free(ht->h_addr_list);
208 	}
209 }
210 
211 static  int
212 compare_hostent(struct hostent *ht1, struct hostent *ht2, void *mdata)
213 {
214 	char **c1, **c2, **ct, **cb;
215 	int b;
216 
217 	if (ht1 == ht2)
218 		return 0;
219 
220 	if (ht1 == NULL || ht2 == NULL)
221 		goto errfin;
222 
223 	if (ht1->h_name == NULL || ht2->h_name == NULL)
224 		goto errfin;
225 
226 	if (ht1->h_addrtype != ht2->h_addrtype ||
227 	    ht1->h_length != ht2->h_length ||
228 	    strcmp(ht1->h_name, ht2->h_name) != 0)
229 		goto errfin;
230 
231 	c1 = ht1->h_aliases;
232 	c2 = ht2->h_aliases;
233 
234 	if ((ht1->h_aliases == NULL || ht2->h_aliases == NULL) &&
235 	    ht1->h_aliases != ht2->h_aliases)
236 		goto errfin;
237 
238 	if (c1 != NULL && c2 != NULL) {
239 		cb = c1;
240 		for (;*c1; ++c1) {
241 			b = 0;
242 			for (ct = c2; *ct; ++ct) {
243 				if (strcmp(*c1, *ct) == 0) {
244 					b = 1;
245 					break;
246 				}
247 			}
248 			if (b == 0) {
249 				printf("h1 aliases item can't be found in h2 "
250 				    "aliases\n");
251 				goto errfin;
252 			}
253 		}
254 
255 		c1 = cb;
256 		for (;*c2; ++c2) {
257 			b = 0;
258 			for (ct = c1; *ct; ++ct) {
259 				if (strcmp(*c2, *ct) == 0) {
260 					b = 1;
261 					break;
262 				}
263 			}
264 			if (b == 0) {
265 				printf("h2 aliases item can't be found in h1 "
266 				    "aliases\n");
267 				goto errfin;
268 			}
269 		}
270 	}
271 
272 	c1 = ht1->h_addr_list;
273 	c2 = ht2->h_addr_list;
274 
275 	if ((ht1->h_addr_list == NULL || ht2->h_addr_list== NULL) &&
276 	    ht1->h_addr_list != ht2->h_addr_list)
277 		goto errfin;
278 
279 	if (c1 != NULL && c2 != NULL) {
280 		cb = c1;
281 		for (; *c1; ++c1) {
282 			b = 0;
283 			for (ct = c2; *ct; ++ct) {
284 				if (memcmp(*c1, *ct, ht1->h_length) == 0) {
285 					b = 1;
286 					break;
287 				}
288 			}
289 			if (b == 0) {
290 				printf("h1 addresses item can't be found in "
291 				    "h2 addresses\n");
292 				goto errfin;
293 			}
294 		}
295 
296 		c1 = cb;
297 		for (; *c2; ++c2) {
298 			b = 0;
299 			for (ct = c1; *ct; ++ct) {
300 				if (memcmp(*c2, *ct, ht1->h_length) == 0) {
301 					b = 1;
302 					break;
303 				}
304 			}
305 			if (b == 0) {
306 				printf("h2 addresses item can't be found in "
307 				    "h1 addresses\n");
308 				goto errfin;
309 			}
310 		}
311 	}
312 
313 	return 0;
314 
315 errfin:
316 	if (mdata == NULL) {
317 		printf("following structures are not equal:\n");
318 		dump_hostent(ht1);
319 		dump_hostent(ht2);
320 	}
321 
322 	return (-1);
323 }
324 
325 static int
326 check_addrinfo_for_name(struct addrinfo *ai, char const *name)
327 {
328 	struct addrinfo *ai2;
329 
330 	for (ai2 = ai; ai2 != NULL; ai2 = ai2->ai_next) {
331 		if (strcmp(ai2->ai_canonname, name) == 0)
332 			return (0);
333 	}
334 
335 	return (-1);
336 }
337 
338 static int
339 check_addrinfo_for_addr(struct addrinfo *ai, char const *addr,
340 	socklen_t addrlen, int af)
341 {
342 	struct addrinfo *ai2;
343 
344 	for (ai2 = ai; ai2 != NULL; ai2 = ai2->ai_next) {
345 		if (af != ai2->ai_family)
346 			continue;
347 
348 		switch (af) {
349 		case AF_INET:
350 			if (memcmp(addr,
351 			    (void *)&((struct sockaddr_in *)ai2->ai_addr)->sin_addr,
352 			    MIN(addrlen, ai2->ai_addrlen)) == 0)
353 				return (0);
354 			break;
355 		case AF_INET6:
356 			if (memcmp(addr,
357 			    (void *)&((struct sockaddr_in6 *)ai2->ai_addr)->sin6_addr,
358 			    MIN(addrlen, ai2->ai_addrlen)) == 0)
359 				return (0);
360 			break;
361 		default:
362 			break;
363 		}
364 	}
365 
366 	return (-1);
367 }
368 
369 static int
370 is_hostent_equal(struct hostent *he, struct addrinfo *ai)
371 {
372 	char **cp;
373 	int rv;
374 
375 #ifdef DEBUG
376 	printf("checking equality of he and ai\n");
377 #endif
378 
379 	rv = check_addrinfo_for_name(ai, he->h_name);
380 	if (rv != 0) {
381 		printf("not equal - he->h_name couldn't be found\n");
382 		return (rv);
383 	}
384 
385 	for (cp = he->h_addr_list; *cp; ++cp) {
386 		rv = check_addrinfo_for_addr(ai, *cp, he->h_length,
387 			he->h_addrtype);
388 		if (rv != 0) {
389 			printf("not equal - one of he->h_addr_list couldn't be found\n");
390 			return (rv);
391 		}
392 	}
393 
394 #ifdef DEBUG
395 	printf("equal\n");
396 #endif
397 
398 	return (0);
399 }
400 
401 static void
402 sdump_hostent(struct hostent *ht, char *buffer, size_t buflen)
403 {
404 	char **cp;
405 	size_t i;
406 	int written;
407 
408 	written = snprintf(buffer, buflen, "%s %d %d",
409 		ht->h_name, ht->h_addrtype, ht->h_length);
410 	buffer += written;
411 	if (written > (int)buflen)
412 		return;
413 	buflen -= written;
414 
415 	if (ht->h_aliases != NULL) {
416 		if (*(ht->h_aliases) != NULL) {
417 			for (cp = ht->h_aliases; *cp; ++cp) {
418 				written = snprintf(buffer, buflen, " %s",*cp);
419 				buffer += written;
420 				if (written > (int)buflen)
421 					return;
422 				buflen -= written;
423 
424 				if (buflen == 0)
425 					return;
426 			}
427 		} else {
428 			written = snprintf(buffer, buflen, " noaliases");
429 			buffer += written;
430 			if (written > (int)buflen)
431 				return;
432 			buflen -= written;
433 		}
434 	} else {
435 		written = snprintf(buffer, buflen, " (null)");
436 		buffer += written;
437 		if (written > (int)buflen)
438 			return;
439 		buflen -= written;
440 	}
441 
442 	written = snprintf(buffer, buflen, " : ");
443 	buffer += written;
444 	if (written > (int)buflen)
445 		return;
446 	buflen -= written;
447 
448 	if (ht->h_addr_list != NULL) {
449 		if (*(ht->h_addr_list) != NULL) {
450 			for (cp = ht->h_addr_list; *cp; ++cp) {
451 				for (i = 0; i < (size_t)ht->h_length; ++i) {
452 					written = snprintf(buffer, buflen,
453 					    i + 1 != (size_t)ht->h_length ?
454 					        "%d." : "%d",
455 					    (unsigned char)(*cp)[i]);
456 					buffer += written;
457 					if (written > (int)buflen)
458 						return;
459 					buflen -= written;
460 
461 					if (buflen == 0)
462 						return;
463 				}
464 
465 				if (*(cp + 1)) {
466 					written = snprintf(buffer, buflen,
467 					    " ");
468 					buffer += written;
469 					if (written > (int)buflen)
470 						return;
471 					buflen -= written;
472 				}
473 			}
474 		} else {
475 			written = snprintf(buffer, buflen, " noaddrs");
476 			buffer += written;
477 			if (written > (int)buflen)
478 				return;
479 			buflen -= written;
480 		}
481 	} else {
482 		written = snprintf(buffer, buflen, " (null)");
483 		buffer += written;
484 		if (written > (int)buflen)
485 			return;
486 		buflen -= written;
487 	}
488 }
489 
490 static int
491 hostent_read_hostlist_func(struct hostent *he, char *line)
492 {
493 	struct hostent *result;
494 	int rv;
495 
496 #ifdef DEBUG
497 	printf("resolving %s: ", line);
498 #endif
499 	result = __gethostbyname2(line, af_type);
500 	if (result != NULL) {
501 #ifdef DEBUG
502 		printf("found\n");
503 #endif
504 
505 		rv = hostent_test_correctness(result, NULL);
506 		if (rv != 0) {
507 			__freehostent(result);
508 			return (rv);
509 		}
510 
511 		clone_hostent(he, result);
512 		__freehostent(result);
513 	} else {
514 #ifdef DEBUG
515 		printf("not found\n");
516 #endif
517  		memset(he, 0, sizeof(struct hostent));
518 		he->h_name = strdup(line);
519 		ATF_REQUIRE(he->h_name != NULL);
520 	}
521 	return (0);
522 }
523 
524 static int
525 hostent_read_snapshot_addr(char *addr, unsigned char *result, size_t len)
526 {
527 	char *s, *ps, *ts;
528 
529 	ps = addr;
530 	while ( (s = strsep(&ps, ".")) != NULL) {
531 		if (len == 0)
532 			return (-1);
533 
534 		*result = (unsigned char)strtol(s, &ts, 10);
535 		++result;
536 		if (*ts != '\0')
537 			return (-1);
538 
539 		--len;
540 	}
541 	if (len != 0)
542 		return (-1);
543 	else
544 		return (0);
545 }
546 
547 static int
548 hostent_read_snapshot_func(struct hostent *ht, char *line)
549 {
550 	StringList *sl1, *sl2;
551 	char *s, *ps, *ts;
552 	int i, rv;
553 
554 #ifdef DEBUG
555 	printf("1 line read from snapshot:\n%s\n", line);
556 #endif
557 
558 	rv = 0;
559 	i = 0;
560 	sl1 = sl2 = NULL;
561 	ps = line;
562 	memset(ht, 0, sizeof(struct hostent));
563 	while ((s = strsep(&ps, " ")) != NULL) {
564 		switch (i) {
565 		case 0:
566 			ht->h_name = strdup(s);
567 			ATF_REQUIRE(ht->h_name != NULL);
568 			break;
569 
570 		case 1:
571 			ht->h_addrtype = (int)strtol(s, &ts, 10);
572 			if (*ts != '\0')
573 				goto fin;
574 			break;
575 
576 		case 2:
577 			ht->h_length = (int)strtol(s, &ts, 10);
578 			if (*ts != '\0')
579 				goto fin;
580 			break;
581 
582 		case 3:
583 			if (sl1 == NULL) {
584 				if (strcmp(s, "(null)") == 0)
585 					return (0);
586 
587 				sl1 = sl_init();
588 				ATF_REQUIRE(sl1 != NULL);
589 
590 				if (strcmp(s, "noaliases") != 0) {
591 					ts = strdup(s);
592 					ATF_REQUIRE(ts != NULL);
593 					sl_add(sl1, ts);
594 				}
595 			} else {
596 				if (strcmp(s, ":") == 0)
597 					++i;
598 				else {
599 					ts = strdup(s);
600 					ATF_REQUIRE(ts != NULL);
601 					sl_add(sl1, ts);
602 				}
603 			}
604 			break;
605 
606 		case 4:
607 			if (sl2 == NULL) {
608 				if (strcmp(s, "(null)") == 0)
609 					return (0);
610 
611 				sl2 = sl_init();
612 				ATF_REQUIRE(sl2 != NULL);
613 
614 				if (strcmp(s, "noaddrs") != 0) {
615 					ts = calloc(1, ht->h_length);
616 					ATF_REQUIRE(ts != NULL);
617 					rv = hostent_read_snapshot_addr(s,
618 					    (unsigned char *)ts,
619 					    ht->h_length);
620 					sl_add(sl2, ts);
621 					if (rv != 0)
622 						goto fin;
623 				}
624 			} else {
625 				ts = calloc(1, ht->h_length);
626 				ATF_REQUIRE(ts != NULL);
627 				rv = hostent_read_snapshot_addr(s,
628 				    (unsigned char *)ts, ht->h_length);
629 				sl_add(sl2, ts);
630 				if (rv != 0)
631 					goto fin;
632 			}
633 			break;
634 		default:
635 			break;
636 		}
637 
638 		if (i != 3 && i != 4)
639 			++i;
640 	}
641 
642 fin:
643 	if (sl1 != NULL) {
644 		sl_add(sl1, NULL);
645 		ht->h_aliases = sl1->sl_str;
646 	}
647 	if (sl2 != NULL) {
648 		sl_add(sl2, NULL);
649 		ht->h_addr_list = sl2->sl_str;
650 	}
651 
652 	if ((i != 4) || (rv != 0)) {
653 		free_hostent(ht);
654 		memset(ht, 0, sizeof(struct hostent));
655 		return (-1);
656 	}
657 
658 	/* NOTE: is it a dirty hack or not? */
659 	free(sl1);
660 	free(sl2);
661 	return (0);
662 }
663 
664 static void
665 dump_hostent(struct hostent *result)
666 {
667 	if (result != NULL) {
668 		char buffer[1024];
669 		sdump_hostent(result, buffer, sizeof(buffer));
670 		printf("%s\n", buffer);
671 	} else
672 		printf("(null)\n");
673 }
674 
675 static int
676 hostent_test_correctness(struct hostent *ht, void *mdata __unused)
677 {
678 
679 #ifdef DEBUG
680 	printf("testing correctness with the following data:\n");
681 	dump_hostent(ht);
682 #endif
683 
684 	if (ht == NULL)
685 		goto errfin;
686 
687 	if (ht->h_name == NULL)
688 		goto errfin;
689 
690 	if (!((ht->h_addrtype >= 0) && (ht->h_addrtype < AF_MAX)))
691 		goto errfin;
692 
693 	if ((ht->h_length != sizeof(struct in_addr)) &&
694 		(ht->h_length != sizeof(struct in6_addr)))
695 		goto errfin;
696 
697 	if (ht->h_aliases == NULL)
698 		goto errfin;
699 
700 	if (ht->h_addr_list == NULL)
701 		goto errfin;
702 
703 #ifdef DEBUG
704 	printf("correct\n");
705 #endif
706 
707 	return (0);
708 errfin:
709 	printf("incorrect\n");
710 
711 	return (-1);
712 }
713 
714 static int
715 hostent_test_gethostbyaddr(struct hostent *he, void *mdata)
716 {
717 	struct hostent *result;
718 	struct hostent_test_data *addr_test_data;
719 	int rv;
720 
721 	addr_test_data = (struct hostent_test_data *)mdata;
722 
723 	/* We should omit unresolved hostents */
724 	if (he->h_addr_list != NULL) {
725 		char **cp;
726 		for (cp = he->h_addr_list; *cp; ++cp) {
727 #ifdef DEBUG
728 			printf("doing reverse lookup for %s\n", he->h_name);
729 #endif
730 
731 			result = __gethostbyaddr(*cp, he->h_length,
732 			    he->h_addrtype);
733 			if (result == NULL) {
734 #ifdef DEBUG
735 				printf("%s: warning: reverse lookup failed "
736 				    "for %s: %s\n", __func__, he->h_name,
737 				    strerror(errno));
738 #endif
739 				continue;
740 			}
741 			rv = hostent_test_correctness(result, NULL);
742 			if (rv != 0) {
743 				__freehostent(result);
744 				return (rv);
745 			}
746 
747 			if (addr_test_data != NULL)
748 				TEST_DATA_APPEND(hostent, addr_test_data,
749 				    result);
750 
751 			__freehostent(result);
752 		}
753 	}
754 
755 	return (0);
756 }
757 
758 static int
759 hostent_test_getaddrinfo_eq(struct hostent *he, void *mdata __unused)
760 {
761 	struct addrinfo *ai, hints;
762 	int rv;
763 
764 	ai = NULL;
765 	memset(&hints, 0, sizeof(struct addrinfo));
766 	hints.ai_family = af_type;
767 	hints.ai_flags = AI_CANONNAME;
768 
769 	printf("using getaddrinfo() to resolve %s\n", he->h_name);
770 
771 	/* struct hostent *he was not resolved */
772 	if (he->h_addr_list == NULL) {
773 		/* We can be sure that he->h_name is not NULL */
774 		rv = getaddrinfo(he->h_name, NULL, &hints, &ai);
775 		if (rv == 0) {
776 			printf("not ok - shouldn't have been resolved\n");
777 			rv = -1;
778 		} else
779 			rv = 0;
780 	} else {
781 		rv = getaddrinfo(he->h_name, NULL, &hints, &ai);
782 		if (rv != 0) {
783 			printf("not ok - should have been resolved\n");
784 			rv = -1;
785 			goto done;
786 		}
787 		rv = is_hostent_equal(he, ai);
788 		if (rv != 0) {
789 			printf("not ok - addrinfo and hostent are not equal\n");
790 			rv = -1;
791 		}
792 	}
793 done:
794 	if (ai != NULL)
795 		freeaddrinfo(ai);
796 	return (rv);
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