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