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