xref: /freebsd/lib/libcasper/services/cap_dns/tests/dns_test.c (revision 87b759f0fa1f7554d50ce640c40138512bbded44)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2013 The FreeBSD Foundation
5  *
6  * This software was developed by Pawel Jakub Dawidek under sponsorship from
7  * the FreeBSD Foundation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/capsicum.h>
32 #include <sys/nv.h>
33 
34 #include <arpa/inet.h>
35 #include <netinet/in.h>
36 
37 #include <assert.h>
38 #include <err.h>
39 #include <errno.h>
40 #include <netdb.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <unistd.h>
45 
46 #include <libcasper.h>
47 #include <casper/cap_dns.h>
48 
49 #include <atf-c.h>
50 
51 #define	GETHOSTBYNAME			0x01
52 #define	GETHOSTBYNAME2_AF_INET		0x02
53 #define	GETHOSTBYNAME2_AF_INET6		0x04
54 #define	GETHOSTBYADDR_AF_INET		0x08
55 #define	GETHOSTBYADDR_AF_INET6		0x10
56 #define	GETADDRINFO_AF_UNSPEC		0x20
57 #define	GETADDRINFO_AF_INET		0x40
58 #define	GETADDRINFO_AF_INET6		0x80
59 
60 static bool
61 addrinfo_compare(struct addrinfo *ai0, struct addrinfo *ai1)
62 {
63 	struct addrinfo *at0, *at1;
64 
65 	if (ai0 == NULL && ai1 == NULL)
66 		return (true);
67 	if (ai0 == NULL || ai1 == NULL)
68 		return (false);
69 
70 	at0 = ai0;
71 	at1 = ai1;
72 	while (true) {
73 		if ((at0->ai_flags == at1->ai_flags) &&
74 		    (at0->ai_family == at1->ai_family) &&
75 		    (at0->ai_socktype == at1->ai_socktype) &&
76 		    (at0->ai_protocol == at1->ai_protocol) &&
77 		    (at0->ai_addrlen == at1->ai_addrlen) &&
78 		    (memcmp(at0->ai_addr, at1->ai_addr,
79 			at0->ai_addrlen) == 0)) {
80 			if (at0->ai_canonname != NULL &&
81 			    at1->ai_canonname != NULL) {
82 				if (strcmp(at0->ai_canonname,
83 				    at1->ai_canonname) != 0) {
84 					return (false);
85 				}
86 			}
87 
88 			if (at0->ai_canonname == NULL &&
89 			    at1->ai_canonname != NULL) {
90 				return (false);
91 			}
92 			if (at0->ai_canonname != NULL &&
93 			    at1->ai_canonname == NULL) {
94 				return (false);
95 			}
96 
97 			if (at0->ai_next == NULL && at1->ai_next == NULL)
98 				return (true);
99 			if (at0->ai_next == NULL || at1->ai_next == NULL)
100 				return (false);
101 
102 			at0 = at0->ai_next;
103 			at1 = at1->ai_next;
104 		} else {
105 			return (false);
106 		}
107 	}
108 
109 	/* NOTREACHED */
110 	fprintf(stderr, "Dead code reached in addrinfo_compare()\n");
111 	exit(1);
112 }
113 
114 static bool
115 hostent_aliases_compare(char **aliases0, char **aliases1)
116 {
117 	int i0, i1;
118 
119 	if (aliases0 == NULL && aliases1 == NULL)
120 		return (true);
121 	if (aliases0 == NULL || aliases1 == NULL)
122 		return (false);
123 
124 	for (i0 = 0; aliases0[i0] != NULL; i0++) {
125 		for (i1 = 0; aliases1[i1] != NULL; i1++) {
126 			if (strcmp(aliases0[i0], aliases1[i1]) == 0)
127 				break;
128 		}
129 		if (aliases1[i1] == NULL)
130 			return (false);
131 	}
132 
133 	return (true);
134 }
135 
136 static bool
137 hostent_addr_list_compare(char **addr_list0, char **addr_list1, int length)
138 {
139 	int i0, i1;
140 
141 	if (addr_list0 == NULL && addr_list1 == NULL)
142 		return (true);
143 	if (addr_list0 == NULL || addr_list1 == NULL)
144 		return (false);
145 
146 	for (i0 = 0; addr_list0[i0] != NULL; i0++) {
147 		for (i1 = 0; addr_list1[i1] != NULL; i1++) {
148 			if (memcmp(addr_list0[i0], addr_list1[i1], length) == 0)
149 				break;
150 		}
151 		if (addr_list1[i1] == NULL)
152 			return (false);
153 	}
154 
155 	return (true);
156 }
157 
158 static bool
159 hostent_compare(const struct hostent *hp0, const struct hostent *hp1)
160 {
161 
162 	if (hp0 == NULL && hp1 != NULL)
163 		return (true);
164 
165 	if (hp0 == NULL || hp1 == NULL)
166 		return (false);
167 
168 	if (hp0->h_name != NULL || hp1->h_name != NULL) {
169 		if (hp0->h_name == NULL || hp1->h_name == NULL)
170 			return (false);
171 		if (strcmp(hp0->h_name, hp1->h_name) != 0)
172 			return (false);
173 	}
174 
175 	if (!hostent_aliases_compare(hp0->h_aliases, hp1->h_aliases))
176 		return (false);
177 	if (!hostent_aliases_compare(hp1->h_aliases, hp0->h_aliases))
178 		return (false);
179 
180 	if (hp0->h_addrtype != hp1->h_addrtype)
181 		return (false);
182 
183 	if (hp0->h_length != hp1->h_length)
184 		return (false);
185 
186 	if (!hostent_addr_list_compare(hp0->h_addr_list, hp1->h_addr_list,
187 	    hp0->h_length)) {
188 		return (false);
189 	}
190 	if (!hostent_addr_list_compare(hp1->h_addr_list, hp0->h_addr_list,
191 	    hp0->h_length)) {
192 		return (false);
193 	}
194 
195 	return (true);
196 }
197 
198 static void
199 runtest(cap_channel_t *capdns, unsigned int expected)
200 {
201 	unsigned int result, failure;
202 	struct addrinfo *ais, *aic, hints, *hintsp;
203 	struct hostent *hps, *hpc;
204 	struct in_addr ip4;
205 	struct in6_addr ip6;
206 	int caperr, syserr;
207 
208 	failure = result = 0;
209 
210 	hps = gethostbyname("example.com");
211 	if (hps == NULL) {
212 		failure |= GETHOSTBYNAME;
213 		fprintf(stderr, "Unable to resolve %s IPv4.\n", "example.com");
214 	} else {
215 		hpc = cap_gethostbyname(capdns, "example.com");
216 		if (hostent_compare(hps, hpc))
217 			result |= GETHOSTBYNAME;
218 	}
219 
220 	hps = gethostbyname2("example.com", AF_INET);
221 	if (hps == NULL) {
222 		failure |= GETHOSTBYNAME2_AF_INET;
223 		fprintf(stderr, "Unable to resolve %s IPv4.\n", "example.com");
224 	} else {
225 		hpc = cap_gethostbyname2(capdns, "example.com", AF_INET);
226 		if (hostent_compare(hps, hpc))
227 			result |= GETHOSTBYNAME2_AF_INET;
228 	}
229 
230 	hps = gethostbyname2("example.com", AF_INET6);
231 	if (hps == NULL) {
232 		failure |= GETHOSTBYNAME2_AF_INET6;
233 		fprintf(stderr, "Unable to resolve %s IPv6.\n", "example.com");
234 	} else {
235 		hpc = cap_gethostbyname2(capdns, "example.com", AF_INET6);
236 		if (hostent_compare(hps, hpc))
237 			result |= GETHOSTBYNAME2_AF_INET6;
238 	}
239 
240 	hints.ai_flags = 0;
241 	hints.ai_family = AF_UNSPEC;
242 	hints.ai_socktype = 0;
243 	hints.ai_protocol = 0;
244 	hints.ai_addrlen = 0;
245 	hints.ai_addr = NULL;
246 	hints.ai_canonname = NULL;
247 	hints.ai_next = NULL;
248 
249 	hintsp = &hints;
250 
251 	syserr = getaddrinfo("freebsd.org", "25", hintsp, &ais);
252 	if (syserr != 0) {
253 		failure |= GETADDRINFO_AF_UNSPEC;
254 		fprintf(stderr,
255 		    "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n",
256 		    gai_strerror(syserr));
257 	} else {
258 		caperr = cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp,
259 		    &aic);
260 		if (caperr == 0) {
261 			if (addrinfo_compare(ais, aic))
262 				result |= GETADDRINFO_AF_UNSPEC;
263 			freeaddrinfo(ais);
264 			freeaddrinfo(aic);
265 		}
266 	}
267 
268 	hints.ai_family = AF_INET;
269 	syserr = getaddrinfo("freebsd.org", "25", hintsp, &ais);
270 	if (syserr != 0) {
271 		failure |= GETADDRINFO_AF_INET;
272 		fprintf(stderr,
273 		    "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n",
274 		    gai_strerror(syserr));
275 	} else {
276 		caperr = cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp,
277 		    &aic);
278 		if (caperr == 0) {
279 			if (addrinfo_compare(ais, aic))
280 				result |= GETADDRINFO_AF_INET;
281 			freeaddrinfo(ais);
282 			freeaddrinfo(aic);
283 		}
284 	}
285 
286 	hints.ai_family = AF_INET6;
287 	syserr = getaddrinfo("freebsd.org", "25", hintsp, &ais);
288 	if (syserr != 0) {
289 		failure |= GETADDRINFO_AF_INET6;
290 		fprintf(stderr,
291 		    "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n",
292 		    gai_strerror(syserr));
293 	} else {
294 		caperr = cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp,
295 		    &aic);
296 		if (caperr == 0) {
297 			if (addrinfo_compare(ais, aic))
298 				result |= GETADDRINFO_AF_INET6;
299 			freeaddrinfo(ais);
300 			freeaddrinfo(aic);
301 		}
302 	}
303 
304 	/* XXX: hardcoded addresses for "google-public-dns-a.google.com". */
305 #define	GOOGLE_DNS_IPV4	"8.8.8.8"
306 #define	GOOGLE_DNS_IPV6	"2001:4860:4860::8888"
307 
308 	inet_pton(AF_INET, GOOGLE_DNS_IPV4, &ip4);
309 	hps = gethostbyaddr(&ip4, sizeof(ip4), AF_INET);
310 	if (hps == NULL) {
311 		failure |= GETHOSTBYADDR_AF_INET;
312 		fprintf(stderr, "Unable to resolve %s.\n", GOOGLE_DNS_IPV4);
313 	} else {
314 		hpc = cap_gethostbyaddr(capdns, &ip4, sizeof(ip4), AF_INET);
315 		if (hostent_compare(hps, hpc))
316 			result |= GETHOSTBYADDR_AF_INET;
317 	}
318 
319 	inet_pton(AF_INET6, GOOGLE_DNS_IPV6, &ip6);
320 	hps = gethostbyaddr(&ip6, sizeof(ip6), AF_INET6);
321 	if (hps == NULL) {
322 		failure |= GETHOSTBYADDR_AF_INET6;
323 		fprintf(stderr, "Unable to resolve %s.\n", GOOGLE_DNS_IPV6);
324 	} else {
325 		hpc = cap_gethostbyaddr(capdns, &ip6, sizeof(ip6), AF_INET6);
326 		if (hostent_compare(hps, hpc)) {
327 			caperr = h_errno;
328 			result |= GETHOSTBYADDR_AF_INET6;
329 		}
330 	}
331 
332 	/*
333 	 * If we had any failures, make sure that all lookups failed.  If some
334 	 * succeeded and some failed, there's a problem with the test or the DNS
335 	 * and we should not fail silently.
336 	 */
337 	if (failure != 0) {
338 		ATF_REQUIRE_MSG(failure == (GETHOSTBYNAME |
339 		    GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
340 		    GETADDRINFO_AF_UNSPEC | GETADDRINFO_AF_INET |
341 		    GETADDRINFO_AF_INET6 |
342 		    GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6),
343 		    "expected all tests to fail, got 0x%x", failure);
344 		atf_tc_skip(
345 		    "no name lookups succeeded, tests require Internet access");
346 	}
347 	ATF_REQUIRE_MSG(result == expected,
348 	    "expected 0x%x, got 0x%x", expected, result);
349 }
350 
351 static cap_channel_t *
352 cap_dns_init(void)
353 {
354 	cap_channel_t *capcas, *capdns;
355 
356 	capcas = cap_init();
357 	ATF_REQUIRE(capcas != NULL);
358 
359 	capdns = cap_service_open(capcas, "system.dns");
360 	ATF_REQUIRE(capdns != NULL);
361 
362 	cap_close(capcas);
363 
364 	return (capdns);
365 }
366 
367 ATF_TC(dns_no_limits);
368 ATF_TC_HEAD(dns_no_limits, tc)
369 {
370 }
371 ATF_TC_BODY(dns_no_limits, tc)
372 {
373 	cap_channel_t *capdns;
374 
375 	capdns = cap_dns_init();
376 
377 	runtest(capdns,
378 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
379 	     GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 |
380 	     GETADDRINFO_AF_UNSPEC | GETADDRINFO_AF_INET |
381 	     GETADDRINFO_AF_INET6));
382 
383 	cap_close(capdns);
384 }
385 
386 ATF_TC(dns_all_limits);
387 ATF_TC_HEAD(dns_all_limits, tc)
388 {
389 }
390 ATF_TC_BODY(dns_all_limits, tc)
391 {
392 	cap_channel_t *capdns;
393 	const char *types[2];
394 	int families[2];
395 
396 	capdns = cap_dns_init();
397 
398 	types[0] = "NAME2ADDR";
399 	types[1] = "ADDR2NAME";
400 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
401 	families[0] = AF_INET;
402 	families[1] = AF_INET6;
403 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
404 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
405 	    cap_dns_family_limit(capdns, NULL, 0) == -1);
406 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
407 	    cap_dns_type_limit(capdns, NULL, 0) == -1);
408 
409 	runtest(capdns,
410 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
411 	     GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 |
412 	     GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6));
413 
414 	cap_close(capdns);
415 }
416 
417 ATF_TC(dns_name_limit);
418 ATF_TC_HEAD(dns_name_limit, tc)
419 {
420 }
421 ATF_TC_BODY(dns_name_limit, tc)
422 {
423 	cap_channel_t *capdns;
424 	const char *types[2];
425 	int families[2];
426 
427 	capdns = cap_dns_init();
428 
429 	types[0] = "NAME2ADDR";
430 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
431 	types[1] = "ADDR2NAME";
432 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
433 	    cap_dns_type_limit(capdns, types, 2) == -1);
434 	types[0] = "ADDR2NAME";
435 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
436 	    cap_dns_type_limit(capdns, types, 1) == -1);
437 	families[0] = AF_INET;
438 	families[1] = AF_INET6;
439 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
440 
441 	runtest(capdns,
442 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
443 	    GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6));
444 
445 	cap_close(capdns);
446 }
447 
448 ATF_TC(dns_addr_limit);
449 ATF_TC_HEAD(dns_addr_limit, tc)
450 {
451 }
452 ATF_TC_BODY(dns_addr_limit, tc)
453 {
454 	cap_channel_t *capdns;
455 	const char *types[2];
456 	int families[2];
457 
458 	capdns = cap_dns_init();
459 
460 	types[0] = "ADDR2NAME";
461 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
462 	types[1] = "NAME2ADDR";
463 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
464 	    cap_dns_type_limit(capdns, types, 2) == -1);
465 	types[0] = "NAME2ADDR";
466 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
467 	    cap_dns_type_limit(capdns, types, 1) == -1);
468 	families[0] = AF_INET;
469 	families[1] = AF_INET6;
470 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
471 
472 	runtest(capdns,
473 	    (GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6));
474 
475 	cap_close(capdns);
476 }
477 
478 ATF_TC(dns_inet_limit);
479 ATF_TC_HEAD(dns_inet_limit, tc)
480 {
481 }
482 ATF_TC_BODY(dns_inet_limit, tc)
483 {
484 	cap_channel_t *capdns;
485 	const char *types[2];
486 	int families[2];
487 
488 	capdns = cap_dns_init();
489 
490 	types[0] = "NAME2ADDR";
491 	types[1] = "ADDR2NAME";
492 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
493 	families[0] = AF_INET;
494 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
495 	families[1] = AF_INET6;
496 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
497 	    cap_dns_family_limit(capdns, families, 2) == -1);
498 	families[0] = AF_INET6;
499 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
500 	    cap_dns_family_limit(capdns, families, 1) == -1);
501 
502 	runtest(capdns,
503 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYADDR_AF_INET |
504 	    GETADDRINFO_AF_INET));
505 
506 	cap_close(capdns);
507 }
508 
509 ATF_TC(dns_inet6_limit);
510 ATF_TC_HEAD(dns_inet6_limit, tc)
511 {
512 }
513 ATF_TC_BODY(dns_inet6_limit, tc)
514 {
515 	cap_channel_t *capdns;
516 	const char *types[2];
517 	int families[2];
518 
519 	capdns = cap_dns_init();
520 
521 	types[0] = "NAME2ADDR";
522 	types[1] = "ADDR2NAME";
523 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
524 	families[0] = AF_INET6;
525 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
526 	families[1] = AF_INET;
527 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
528 	    cap_dns_family_limit(capdns, families, 2) == -1);
529 	families[0] = AF_INET;
530 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
531 	    cap_dns_family_limit(capdns, families, 1) == -1);
532 
533 	runtest(capdns,
534 	    (GETHOSTBYNAME2_AF_INET6 | GETHOSTBYADDR_AF_INET6 |
535 	    GETADDRINFO_AF_INET6));
536 
537 	cap_close(capdns);
538 }
539 
540 ATF_TC(dns_name_inet_limit);
541 ATF_TC_HEAD(dns_name_inet_limit, tc)
542 {
543 }
544 ATF_TC_BODY(dns_name_inet_limit, tc)
545 {
546 	cap_channel_t *capdns;
547 	const char *types[2];
548 	int families[2];
549 
550 	capdns = cap_dns_init();
551 
552 	types[0] = "NAME2ADDR";
553 	types[1] = "ADDR2NAME";
554 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
555 	families[0] = AF_INET;
556 	families[1] = AF_INET6;
557 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
558 	types[0] = "NAME2ADDR";
559 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
560 	types[1] = "ADDR2NAME";
561 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
562 	    cap_dns_type_limit(capdns, types, 2) == -1);
563 	types[0] = "ADDR2NAME";
564 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
565 	    cap_dns_type_limit(capdns, types, 1) == -1);
566 	families[0] = AF_INET;
567 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
568 	families[1] = AF_INET6;
569 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
570 	    cap_dns_family_limit(capdns, families, 2) == -1);
571 	families[0] = AF_INET6;
572 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
573 	    cap_dns_family_limit(capdns, families, 1) == -1);
574 
575 	runtest(capdns,
576 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETADDRINFO_AF_INET));
577 
578 	cap_close(capdns);
579 }
580 
581 ATF_TC(dns_name_inet6_limit);
582 ATF_TC_HEAD(dns_name_inet6_limit, tc)
583 {
584 }
585 ATF_TC_BODY(dns_name_inet6_limit, tc)
586 {
587 	cap_channel_t *capdns;
588 	const char *types[2];
589 	int families[2];
590 
591 	capdns = cap_dns_init();
592 
593 	types[0] = "NAME2ADDR";
594 	types[1] = "ADDR2NAME";
595 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
596 	families[0] = AF_INET6;
597 	families[1] = AF_INET;
598 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
599 	types[0] = "NAME2ADDR";
600 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
601 	types[1] = "ADDR2NAME";
602 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
603 	    cap_dns_type_limit(capdns, types, 2) == -1);
604 	types[0] = "ADDR2NAME";
605 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
606 	    cap_dns_type_limit(capdns, types, 1) == -1);
607 	families[0] = AF_INET6;
608 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
609 	families[1] = AF_INET;
610 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
611 	    cap_dns_family_limit(capdns, families, 2) == -1);
612 	families[0] = AF_INET;
613 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
614 	    cap_dns_family_limit(capdns, families, 1) == -1);
615 
616 	runtest(capdns,
617 	    (GETHOSTBYNAME2_AF_INET6 | GETADDRINFO_AF_INET6));
618 
619 	cap_close(capdns);
620 }
621 
622 ATF_TC(dns_addr_inet_limit);
623 ATF_TC_HEAD(dns_addr_inet_limit, tc)
624 {
625 }
626 ATF_TC_BODY(dns_addr_inet_limit, tc)
627 {
628 	cap_channel_t *capdns;
629 	const char *types[2];
630 	int families[2];
631 
632 	capdns = cap_dns_init();
633 
634 	types[0] = "NAME2ADDR";
635 	types[1] = "ADDR2NAME";
636 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
637 	families[0] = AF_INET;
638 	families[1] = AF_INET6;
639 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
640 	types[0] = "ADDR2NAME";
641 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
642 	types[1] = "NAME2ADDR";
643 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
644 	    cap_dns_type_limit(capdns, types, 2) == -1);
645 	types[0] = "NAME2ADDR";
646 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
647 	    cap_dns_type_limit(capdns, types, 1) == -1);
648 	families[0] = AF_INET;
649 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
650 	families[1] = AF_INET6;
651 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
652 	    cap_dns_family_limit(capdns, families, 2) == -1);
653 	families[0] = AF_INET6;
654 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
655 	    cap_dns_family_limit(capdns, families, 1) == -1);
656 
657 	runtest(capdns, GETHOSTBYADDR_AF_INET);
658 
659 	cap_close(capdns);
660 }
661 
662 ATF_TC(dns_addr_inet6_limit);
663 ATF_TC_HEAD(dns_addr_inet6_limit, tc)
664 {
665 }
666 ATF_TC_BODY(dns_addr_inet6_limit, tc)
667 {
668 	cap_channel_t *capdns;
669 	const char *types[2];
670 	int families[2];
671 
672 	capdns = cap_dns_init();
673 
674 	types[0] = "NAME2ADDR";
675 	types[1] = "ADDR2NAME";
676 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
677 	families[0] = AF_INET6;
678 	families[1] = AF_INET;
679 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
680 	types[0] = "ADDR2NAME";
681 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
682 	types[1] = "NAME2ADDR";
683 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
684 	    cap_dns_type_limit(capdns, types, 2) == -1);
685 	types[0] = "NAME2ADDR";
686 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
687 	    cap_dns_type_limit(capdns, types, 1) == -1);
688 	families[0] = AF_INET6;
689 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
690 	families[1] = AF_INET;
691 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
692 	    cap_dns_family_limit(capdns, families, 2) == -1);
693 	families[0] = AF_INET;
694 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
695 	    cap_dns_family_limit(capdns, families, 1) == -1);
696 
697 	runtest(capdns, GETHOSTBYADDR_AF_INET6);
698 
699 	cap_close(capdns);
700 }
701 
702 ATF_TP_ADD_TCS(tp)
703 {
704 	ATF_TP_ADD_TC(tp, dns_no_limits);
705 	ATF_TP_ADD_TC(tp, dns_all_limits);
706 	ATF_TP_ADD_TC(tp, dns_name_limit);
707 	ATF_TP_ADD_TC(tp, dns_addr_limit);
708 	ATF_TP_ADD_TC(tp, dns_inet_limit);
709 	ATF_TP_ADD_TC(tp, dns_inet6_limit);
710 	ATF_TP_ADD_TC(tp, dns_name_inet_limit);
711 	ATF_TP_ADD_TC(tp, dns_name_inet6_limit);
712 	ATF_TP_ADD_TC(tp, dns_addr_inet_limit);
713 	ATF_TP_ADD_TC(tp, dns_addr_inet6_limit);
714 
715 	return atf_no_error();
716 }
717