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