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