1*00b67f09SDavid van Moolenbroek /* $NetBSD: dns64.c,v 1.6 2014/12/10 04:37:58 christos Exp $ */
2*00b67f09SDavid van Moolenbroek
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek * Copyright (C) 2010, 2011, 2014 Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek *
6*00b67f09SDavid van Moolenbroek * Permission to use, copy, modify, and/or distribute this software for any
7*00b67f09SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
8*00b67f09SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
9*00b67f09SDavid van Moolenbroek *
10*00b67f09SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11*00b67f09SDavid van Moolenbroek * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12*00b67f09SDavid van Moolenbroek * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13*00b67f09SDavid van Moolenbroek * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14*00b67f09SDavid van Moolenbroek * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15*00b67f09SDavid van Moolenbroek * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16*00b67f09SDavid van Moolenbroek * PERFORMANCE OF THIS SOFTWARE.
17*00b67f09SDavid van Moolenbroek */
18*00b67f09SDavid van Moolenbroek
19*00b67f09SDavid van Moolenbroek /* Id: dns64.c,v 1.8 2011/03/12 04:59:47 tbox Exp */
20*00b67f09SDavid van Moolenbroek
21*00b67f09SDavid van Moolenbroek #include <config.h>
22*00b67f09SDavid van Moolenbroek
23*00b67f09SDavid van Moolenbroek #include <isc/list.h>
24*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
25*00b67f09SDavid van Moolenbroek #include <isc/netaddr.h>
26*00b67f09SDavid van Moolenbroek #include <isc/string.h>
27*00b67f09SDavid van Moolenbroek #include <isc/util.h>
28*00b67f09SDavid van Moolenbroek
29*00b67f09SDavid van Moolenbroek #include <dns/acl.h>
30*00b67f09SDavid van Moolenbroek #include <dns/dns64.h>
31*00b67f09SDavid van Moolenbroek #include <dns/rdata.h>
32*00b67f09SDavid van Moolenbroek #include <dns/rdataset.h>
33*00b67f09SDavid van Moolenbroek #include <dns/result.h>
34*00b67f09SDavid van Moolenbroek
35*00b67f09SDavid van Moolenbroek struct dns_dns64 {
36*00b67f09SDavid van Moolenbroek unsigned char bits[16]; /*
37*00b67f09SDavid van Moolenbroek * Prefix + suffix bits.
38*00b67f09SDavid van Moolenbroek */
39*00b67f09SDavid van Moolenbroek dns_acl_t * clients; /*
40*00b67f09SDavid van Moolenbroek * Which clients get mapped
41*00b67f09SDavid van Moolenbroek * addresses.
42*00b67f09SDavid van Moolenbroek */
43*00b67f09SDavid van Moolenbroek dns_acl_t * mapped; /*
44*00b67f09SDavid van Moolenbroek * IPv4 addresses to be mapped.
45*00b67f09SDavid van Moolenbroek */
46*00b67f09SDavid van Moolenbroek dns_acl_t * excluded; /*
47*00b67f09SDavid van Moolenbroek * IPv6 addresses that are
48*00b67f09SDavid van Moolenbroek * treated as not existing.
49*00b67f09SDavid van Moolenbroek */
50*00b67f09SDavid van Moolenbroek unsigned int prefixlen; /*
51*00b67f09SDavid van Moolenbroek * Start of mapped address.
52*00b67f09SDavid van Moolenbroek */
53*00b67f09SDavid van Moolenbroek unsigned int flags;
54*00b67f09SDavid van Moolenbroek isc_mem_t * mctx;
55*00b67f09SDavid van Moolenbroek ISC_LINK(dns_dns64_t) link;
56*00b67f09SDavid van Moolenbroek };
57*00b67f09SDavid van Moolenbroek
58*00b67f09SDavid van Moolenbroek isc_result_t
dns_dns64_create(isc_mem_t * mctx,isc_netaddr_t * prefix,unsigned int prefixlen,isc_netaddr_t * suffix,dns_acl_t * clients,dns_acl_t * mapped,dns_acl_t * excluded,unsigned int flags,dns_dns64_t ** dns64)59*00b67f09SDavid van Moolenbroek dns_dns64_create(isc_mem_t *mctx, isc_netaddr_t *prefix,
60*00b67f09SDavid van Moolenbroek unsigned int prefixlen, isc_netaddr_t *suffix,
61*00b67f09SDavid van Moolenbroek dns_acl_t *clients, dns_acl_t *mapped, dns_acl_t *excluded,
62*00b67f09SDavid van Moolenbroek unsigned int flags, dns_dns64_t **dns64)
63*00b67f09SDavid van Moolenbroek {
64*00b67f09SDavid van Moolenbroek dns_dns64_t *new;
65*00b67f09SDavid van Moolenbroek unsigned int nbytes = 16;
66*00b67f09SDavid van Moolenbroek
67*00b67f09SDavid van Moolenbroek REQUIRE(prefix != NULL && prefix->family == AF_INET6);
68*00b67f09SDavid van Moolenbroek /* Legal prefix lengths from rfc6052.txt. */
69*00b67f09SDavid van Moolenbroek REQUIRE(prefixlen == 32 || prefixlen == 40 || prefixlen == 48 ||
70*00b67f09SDavid van Moolenbroek prefixlen == 56 || prefixlen == 64 || prefixlen == 96);
71*00b67f09SDavid van Moolenbroek REQUIRE(isc_netaddr_prefixok(prefix, prefixlen) == ISC_R_SUCCESS);
72*00b67f09SDavid van Moolenbroek REQUIRE(dns64 != NULL && *dns64 == NULL);
73*00b67f09SDavid van Moolenbroek
74*00b67f09SDavid van Moolenbroek if (suffix != NULL) {
75*00b67f09SDavid van Moolenbroek static const unsigned char zeros[16];
76*00b67f09SDavid van Moolenbroek REQUIRE(prefix->family == AF_INET6);
77*00b67f09SDavid van Moolenbroek nbytes = prefixlen / 8 + 4;
78*00b67f09SDavid van Moolenbroek /* Bits 64-71 are zeros. rfc6052.txt */
79*00b67f09SDavid van Moolenbroek if (prefixlen >= 32 && prefixlen <= 64)
80*00b67f09SDavid van Moolenbroek nbytes++;
81*00b67f09SDavid van Moolenbroek REQUIRE(memcmp(suffix->type.in6.s6_addr, zeros, nbytes) == 0);
82*00b67f09SDavid van Moolenbroek }
83*00b67f09SDavid van Moolenbroek
84*00b67f09SDavid van Moolenbroek new = isc_mem_get(mctx, sizeof(dns_dns64_t));
85*00b67f09SDavid van Moolenbroek if (new == NULL)
86*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
87*00b67f09SDavid van Moolenbroek memset(new->bits, 0, sizeof(new->bits));
88*00b67f09SDavid van Moolenbroek memmove(new->bits, prefix->type.in6.s6_addr, prefixlen / 8);
89*00b67f09SDavid van Moolenbroek if (suffix != NULL)
90*00b67f09SDavid van Moolenbroek memmove(new->bits + nbytes, suffix->type.in6.s6_addr + nbytes,
91*00b67f09SDavid van Moolenbroek 16 - nbytes);
92*00b67f09SDavid van Moolenbroek new->clients = NULL;
93*00b67f09SDavid van Moolenbroek if (clients != NULL)
94*00b67f09SDavid van Moolenbroek dns_acl_attach(clients, &new->clients);
95*00b67f09SDavid van Moolenbroek new->mapped = NULL;
96*00b67f09SDavid van Moolenbroek if (mapped != NULL)
97*00b67f09SDavid van Moolenbroek dns_acl_attach(mapped, &new->mapped);
98*00b67f09SDavid van Moolenbroek new->excluded = NULL;
99*00b67f09SDavid van Moolenbroek if (excluded != NULL)
100*00b67f09SDavid van Moolenbroek dns_acl_attach(excluded, &new->excluded);
101*00b67f09SDavid van Moolenbroek new->prefixlen = prefixlen;
102*00b67f09SDavid van Moolenbroek new->flags = flags;
103*00b67f09SDavid van Moolenbroek ISC_LINK_INIT(new, link);
104*00b67f09SDavid van Moolenbroek new->mctx = NULL;
105*00b67f09SDavid van Moolenbroek isc_mem_attach(mctx, &new->mctx);
106*00b67f09SDavid van Moolenbroek *dns64 = new;
107*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
108*00b67f09SDavid van Moolenbroek }
109*00b67f09SDavid van Moolenbroek
110*00b67f09SDavid van Moolenbroek void
dns_dns64_destroy(dns_dns64_t ** dns64p)111*00b67f09SDavid van Moolenbroek dns_dns64_destroy(dns_dns64_t **dns64p) {
112*00b67f09SDavid van Moolenbroek dns_dns64_t *dns64;
113*00b67f09SDavid van Moolenbroek
114*00b67f09SDavid van Moolenbroek REQUIRE(dns64p != NULL && *dns64p != NULL);
115*00b67f09SDavid van Moolenbroek
116*00b67f09SDavid van Moolenbroek dns64 = *dns64p;
117*00b67f09SDavid van Moolenbroek *dns64p = NULL;
118*00b67f09SDavid van Moolenbroek
119*00b67f09SDavid van Moolenbroek REQUIRE(!ISC_LINK_LINKED(dns64, link));
120*00b67f09SDavid van Moolenbroek
121*00b67f09SDavid van Moolenbroek if (dns64->clients != NULL)
122*00b67f09SDavid van Moolenbroek dns_acl_detach(&dns64->clients);
123*00b67f09SDavid van Moolenbroek if (dns64->mapped != NULL)
124*00b67f09SDavid van Moolenbroek dns_acl_detach(&dns64->mapped);
125*00b67f09SDavid van Moolenbroek if (dns64->excluded != NULL)
126*00b67f09SDavid van Moolenbroek dns_acl_detach(&dns64->excluded);
127*00b67f09SDavid van Moolenbroek isc_mem_putanddetach(&dns64->mctx, dns64, sizeof(*dns64));
128*00b67f09SDavid van Moolenbroek }
129*00b67f09SDavid van Moolenbroek
130*00b67f09SDavid van Moolenbroek isc_result_t
dns_dns64_aaaafroma(const dns_dns64_t * dns64,const isc_netaddr_t * reqaddr,const dns_name_t * reqsigner,const dns_aclenv_t * env,unsigned int flags,unsigned char * a,unsigned char * aaaa)131*00b67f09SDavid van Moolenbroek dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
132*00b67f09SDavid van Moolenbroek const dns_name_t *reqsigner, const dns_aclenv_t *env,
133*00b67f09SDavid van Moolenbroek unsigned int flags, unsigned char *a, unsigned char *aaaa)
134*00b67f09SDavid van Moolenbroek {
135*00b67f09SDavid van Moolenbroek unsigned int nbytes, i;
136*00b67f09SDavid van Moolenbroek isc_result_t result;
137*00b67f09SDavid van Moolenbroek int match;
138*00b67f09SDavid van Moolenbroek
139*00b67f09SDavid van Moolenbroek if ((dns64->flags & DNS_DNS64_RECURSIVE_ONLY) != 0 &&
140*00b67f09SDavid van Moolenbroek (flags & DNS_DNS64_RECURSIVE) == 0)
141*00b67f09SDavid van Moolenbroek return (DNS_R_DISALLOWED);
142*00b67f09SDavid van Moolenbroek
143*00b67f09SDavid van Moolenbroek if ((dns64->flags & DNS_DNS64_BREAK_DNSSEC) == 0 &&
144*00b67f09SDavid van Moolenbroek (flags & DNS_DNS64_DNSSEC) != 0)
145*00b67f09SDavid van Moolenbroek return (DNS_R_DISALLOWED);
146*00b67f09SDavid van Moolenbroek
147*00b67f09SDavid van Moolenbroek if (dns64->clients != NULL) {
148*00b67f09SDavid van Moolenbroek result = dns_acl_match(reqaddr, reqsigner, dns64->clients, env,
149*00b67f09SDavid van Moolenbroek &match, NULL);
150*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
151*00b67f09SDavid van Moolenbroek return (result);
152*00b67f09SDavid van Moolenbroek if (match <= 0)
153*00b67f09SDavid van Moolenbroek return (DNS_R_DISALLOWED);
154*00b67f09SDavid van Moolenbroek }
155*00b67f09SDavid van Moolenbroek
156*00b67f09SDavid van Moolenbroek if (dns64->mapped != NULL) {
157*00b67f09SDavid van Moolenbroek struct in_addr ina;
158*00b67f09SDavid van Moolenbroek isc_netaddr_t netaddr;
159*00b67f09SDavid van Moolenbroek
160*00b67f09SDavid van Moolenbroek memmove(&ina.s_addr, a, 4);
161*00b67f09SDavid van Moolenbroek isc_netaddr_fromin(&netaddr, &ina);
162*00b67f09SDavid van Moolenbroek result = dns_acl_match(&netaddr, NULL, dns64->mapped, env,
163*00b67f09SDavid van Moolenbroek &match, NULL);
164*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
165*00b67f09SDavid van Moolenbroek return (result);
166*00b67f09SDavid van Moolenbroek if (match <= 0)
167*00b67f09SDavid van Moolenbroek return (DNS_R_DISALLOWED);
168*00b67f09SDavid van Moolenbroek }
169*00b67f09SDavid van Moolenbroek
170*00b67f09SDavid van Moolenbroek nbytes = dns64->prefixlen / 8;
171*00b67f09SDavid van Moolenbroek INSIST(nbytes <= 12);
172*00b67f09SDavid van Moolenbroek /* Copy prefix. */
173*00b67f09SDavid van Moolenbroek memmove(aaaa, dns64->bits, nbytes);
174*00b67f09SDavid van Moolenbroek /* Bits 64-71 are zeros. rfc6052.txt */
175*00b67f09SDavid van Moolenbroek if (nbytes == 8)
176*00b67f09SDavid van Moolenbroek aaaa[nbytes++] = 0;
177*00b67f09SDavid van Moolenbroek /* Copy mapped address. */
178*00b67f09SDavid van Moolenbroek for (i = 0; i < 4U; i++) {
179*00b67f09SDavid van Moolenbroek aaaa[nbytes++] = a[i];
180*00b67f09SDavid van Moolenbroek /* Bits 64-71 are zeros. rfc6052.txt */
181*00b67f09SDavid van Moolenbroek if (nbytes == 8)
182*00b67f09SDavid van Moolenbroek aaaa[nbytes++] = 0;
183*00b67f09SDavid van Moolenbroek }
184*00b67f09SDavid van Moolenbroek /* Copy suffix. */
185*00b67f09SDavid van Moolenbroek memmove(aaaa + nbytes, dns64->bits + nbytes, 16 - nbytes);
186*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
187*00b67f09SDavid van Moolenbroek }
188*00b67f09SDavid van Moolenbroek
189*00b67f09SDavid van Moolenbroek dns_dns64_t *
dns_dns64_next(dns_dns64_t * dns64)190*00b67f09SDavid van Moolenbroek dns_dns64_next(dns_dns64_t *dns64) {
191*00b67f09SDavid van Moolenbroek dns64 = ISC_LIST_NEXT(dns64, link);
192*00b67f09SDavid van Moolenbroek return (dns64);
193*00b67f09SDavid van Moolenbroek }
194*00b67f09SDavid van Moolenbroek
195*00b67f09SDavid van Moolenbroek void
dns_dns64_append(dns_dns64list_t * list,dns_dns64_t * dns64)196*00b67f09SDavid van Moolenbroek dns_dns64_append(dns_dns64list_t *list, dns_dns64_t *dns64) {
197*00b67f09SDavid van Moolenbroek ISC_LIST_APPEND(*list, dns64, link);
198*00b67f09SDavid van Moolenbroek }
199*00b67f09SDavid van Moolenbroek
200*00b67f09SDavid van Moolenbroek void
dns_dns64_unlink(dns_dns64list_t * list,dns_dns64_t * dns64)201*00b67f09SDavid van Moolenbroek dns_dns64_unlink(dns_dns64list_t *list, dns_dns64_t *dns64) {
202*00b67f09SDavid van Moolenbroek ISC_LIST_UNLINK(*list, dns64, link);
203*00b67f09SDavid van Moolenbroek }
204*00b67f09SDavid van Moolenbroek
205*00b67f09SDavid van Moolenbroek isc_boolean_t
dns_dns64_aaaaok(const dns_dns64_t * dns64,const isc_netaddr_t * reqaddr,const dns_name_t * reqsigner,const dns_aclenv_t * env,unsigned int flags,dns_rdataset_t * rdataset,isc_boolean_t * aaaaok,size_t aaaaoklen)206*00b67f09SDavid van Moolenbroek dns_dns64_aaaaok(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
207*00b67f09SDavid van Moolenbroek const dns_name_t *reqsigner, const dns_aclenv_t *env,
208*00b67f09SDavid van Moolenbroek unsigned int flags, dns_rdataset_t *rdataset,
209*00b67f09SDavid van Moolenbroek isc_boolean_t *aaaaok, size_t aaaaoklen)
210*00b67f09SDavid van Moolenbroek {
211*00b67f09SDavid van Moolenbroek struct in6_addr in6;
212*00b67f09SDavid van Moolenbroek isc_netaddr_t netaddr;
213*00b67f09SDavid van Moolenbroek isc_result_t result;
214*00b67f09SDavid van Moolenbroek int match;
215*00b67f09SDavid van Moolenbroek isc_boolean_t answer = ISC_FALSE;
216*00b67f09SDavid van Moolenbroek isc_boolean_t found = ISC_FALSE;
217*00b67f09SDavid van Moolenbroek unsigned int i, ok;
218*00b67f09SDavid van Moolenbroek
219*00b67f09SDavid van Moolenbroek REQUIRE(rdataset != NULL);
220*00b67f09SDavid van Moolenbroek REQUIRE(rdataset->type == dns_rdatatype_aaaa);
221*00b67f09SDavid van Moolenbroek REQUIRE(rdataset->rdclass == dns_rdataclass_in);
222*00b67f09SDavid van Moolenbroek if (aaaaok != NULL)
223*00b67f09SDavid van Moolenbroek REQUIRE(aaaaoklen == dns_rdataset_count(rdataset));
224*00b67f09SDavid van Moolenbroek
225*00b67f09SDavid van Moolenbroek for (;dns64 != NULL; dns64 = ISC_LIST_NEXT(dns64, link)) {
226*00b67f09SDavid van Moolenbroek if ((dns64->flags & DNS_DNS64_RECURSIVE_ONLY) != 0 &&
227*00b67f09SDavid van Moolenbroek (flags & DNS_DNS64_RECURSIVE) == 0)
228*00b67f09SDavid van Moolenbroek continue;
229*00b67f09SDavid van Moolenbroek
230*00b67f09SDavid van Moolenbroek if ((dns64->flags & DNS_DNS64_BREAK_DNSSEC) == 0 &&
231*00b67f09SDavid van Moolenbroek (flags & DNS_DNS64_DNSSEC) != 0)
232*00b67f09SDavid van Moolenbroek continue;
233*00b67f09SDavid van Moolenbroek /*
234*00b67f09SDavid van Moolenbroek * Work out if this dns64 structure applies to this client.
235*00b67f09SDavid van Moolenbroek */
236*00b67f09SDavid van Moolenbroek if (dns64->clients != NULL) {
237*00b67f09SDavid van Moolenbroek result = dns_acl_match(reqaddr, reqsigner,
238*00b67f09SDavid van Moolenbroek dns64->clients, env,
239*00b67f09SDavid van Moolenbroek &match, NULL);
240*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
241*00b67f09SDavid van Moolenbroek continue;
242*00b67f09SDavid van Moolenbroek if (match <= 0)
243*00b67f09SDavid van Moolenbroek continue;
244*00b67f09SDavid van Moolenbroek }
245*00b67f09SDavid van Moolenbroek
246*00b67f09SDavid van Moolenbroek if (!found && aaaaok != NULL) {
247*00b67f09SDavid van Moolenbroek for (i = 0; i < aaaaoklen; i++)
248*00b67f09SDavid van Moolenbroek aaaaok[i] = ISC_FALSE;
249*00b67f09SDavid van Moolenbroek }
250*00b67f09SDavid van Moolenbroek found = ISC_TRUE;
251*00b67f09SDavid van Moolenbroek
252*00b67f09SDavid van Moolenbroek /*
253*00b67f09SDavid van Moolenbroek * If we are not excluding any addresses then any AAAA
254*00b67f09SDavid van Moolenbroek * will do.
255*00b67f09SDavid van Moolenbroek */
256*00b67f09SDavid van Moolenbroek if (dns64->excluded == NULL) {
257*00b67f09SDavid van Moolenbroek answer = ISC_TRUE;
258*00b67f09SDavid van Moolenbroek if (aaaaok == NULL)
259*00b67f09SDavid van Moolenbroek goto done;
260*00b67f09SDavid van Moolenbroek for (i = 0; i < aaaaoklen; i++)
261*00b67f09SDavid van Moolenbroek aaaaok[i] = ISC_TRUE;
262*00b67f09SDavid van Moolenbroek goto done;
263*00b67f09SDavid van Moolenbroek }
264*00b67f09SDavid van Moolenbroek
265*00b67f09SDavid van Moolenbroek i = 0; ok = 0;
266*00b67f09SDavid van Moolenbroek for (result = dns_rdataset_first(rdataset);
267*00b67f09SDavid van Moolenbroek result == ISC_R_SUCCESS;
268*00b67f09SDavid van Moolenbroek result = dns_rdataset_next(rdataset)) {
269*00b67f09SDavid van Moolenbroek dns_rdata_t rdata = DNS_RDATA_INIT;
270*00b67f09SDavid van Moolenbroek if (aaaaok == NULL || !aaaaok[i]) {
271*00b67f09SDavid van Moolenbroek
272*00b67f09SDavid van Moolenbroek dns_rdataset_current(rdataset, &rdata);
273*00b67f09SDavid van Moolenbroek memmove(&in6.s6_addr, rdata.data, 16);
274*00b67f09SDavid van Moolenbroek isc_netaddr_fromin6(&netaddr, &in6);
275*00b67f09SDavid van Moolenbroek
276*00b67f09SDavid van Moolenbroek result = dns_acl_match(&netaddr, NULL,
277*00b67f09SDavid van Moolenbroek dns64->excluded,
278*00b67f09SDavid van Moolenbroek env, &match, NULL);
279*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS && match <= 0) {
280*00b67f09SDavid van Moolenbroek answer = ISC_TRUE;
281*00b67f09SDavid van Moolenbroek if (aaaaok == NULL)
282*00b67f09SDavid van Moolenbroek goto done;
283*00b67f09SDavid van Moolenbroek aaaaok[i] = ISC_TRUE;
284*00b67f09SDavid van Moolenbroek ok++;
285*00b67f09SDavid van Moolenbroek }
286*00b67f09SDavid van Moolenbroek } else
287*00b67f09SDavid van Moolenbroek ok++;
288*00b67f09SDavid van Moolenbroek i++;
289*00b67f09SDavid van Moolenbroek }
290*00b67f09SDavid van Moolenbroek /*
291*00b67f09SDavid van Moolenbroek * Are all addresses ok?
292*00b67f09SDavid van Moolenbroek */
293*00b67f09SDavid van Moolenbroek if (aaaaok != NULL && ok == aaaaoklen)
294*00b67f09SDavid van Moolenbroek goto done;
295*00b67f09SDavid van Moolenbroek }
296*00b67f09SDavid van Moolenbroek
297*00b67f09SDavid van Moolenbroek done:
298*00b67f09SDavid van Moolenbroek if (!found && aaaaok != NULL) {
299*00b67f09SDavid van Moolenbroek for (i = 0; i < aaaaoklen; i++)
300*00b67f09SDavid van Moolenbroek aaaaok[i] = ISC_TRUE;
301*00b67f09SDavid van Moolenbroek }
302*00b67f09SDavid van Moolenbroek return (found ? answer : ISC_TRUE);
303*00b67f09SDavid van Moolenbroek }
304