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