1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * SPDX-License-Identifier: MPL-2.0
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9  *
10  * See the COPYRIGHT file distributed with this work for additional
11  * information regarding copyright ownership.
12  */
13 
14 #ifndef DNS_DNS64_H
15 #define DNS_DNS64_H 1
16 
17 #include <stdbool.h>
18 
19 #include <isc/lang.h>
20 
21 #include <dns/types.h>
22 
23 ISC_LANG_BEGINDECLS
24 
25 /*
26  * dns_dns64_create() flags.
27  */
28 #define DNS_DNS64_RECURSIVE_ONLY          \
29 	0x01 /* If set then this record   \
30 	      * only applies to recursive \
31 	      * queries.                  \
32 	      */
33 #define DNS_DNS64_BREAK_DNSSEC            \
34 	0x02 /* If set then still perform \
35 	      * DNSSEC synthesis even     \
36 	      * though the result would   \
37 	      * fail validation.          \
38 	      */
39 
40 /*
41  * dns_dns64_aaaaok() and dns_dns64_aaaafroma() flags.
42  */
43 #define DNS_DNS64_RECURSIVE 0x01 /* Recursive query. */
44 #define DNS_DNS64_DNSSEC    0x02 /* DNSSEC sensitive query. */
45 
46 isc_result_t
47 dns_dns64_create(isc_mem_t *mctx, const isc_netaddr_t *prefix,
48 		 unsigned int prefixlen, const isc_netaddr_t *suffix,
49 		 dns_acl_t *client, dns_acl_t *mapped, dns_acl_t *excluded,
50 		 unsigned int flags, dns_dns64_t **dns64);
51 /*
52  * Create a dns64 record which is used to identify the set of clients
53  * it applies to and how to perform the DNS64 synthesis.
54  *
55  * 'prefix' and 'prefixlen' defined the leading bits of the AAAA records
56  * to be synthesised.  'suffix' defines the bits after the A records bits.
57  * If suffix is NULL zeros will be used for these bits.  'client' defines
58  * for which clients this record applies.  If 'client' is NULL then all
59  * clients apply.  'mapped' defines which A records are candidated for
60  * mapping.  If 'mapped' is NULL then all A records will be mapped.
61  * 'excluded' defines which AAAA are to be treated as non-existent for the
62  * purposed of determining whether to perform synthesis.  If 'excluded' is
63  * NULL then no AAAA records prevent synthesis.
64  *
65  * If DNS_DNS64_RECURSIVE_ONLY is set then the record will only match if
66  * DNS_DNS64_RECURSIVE is set when calling  dns_dns64_aaaaok() and
67  * dns_dns64_aaaafroma().
68  *
69  * If DNS_DNS64_BREAK_DNSSEC is set then the record will still apply if
70  * DNS_DNS64_DNSSEC is set when calling  dns_dns64_aaaaok() and
71  * dns_dns64_aaaafroma() otherwise the record will be ignored.
72  *
73  * Requires:
74  *      'mctx'          to be valid.
75  *      'prefix'        to be valid and the address family to AF_INET6.
76  *      'prefixlen'     to be one of 32, 40, 48, 56, 72 and 96.
77  *                      the bits not covered by prefixlen in prefix to
78  *                      be zero.
79  *      'suffix'        to be NULL or the address family be set to AF_INET6
80  *                      and the leading 'prefixlen' + 32 bits of the 'suffix'
81  *                      to be zero.  If 'prefixlen' is 40, 48 or 56 then the
82  *                      the leading 'prefixlen' + 40 bits of 'suffix' must be
83  *                      zero.
84  *	'client'	to be NULL or a valid acl.
85  *	'mapped'	to be NULL or a valid acl.
86  *	'excluded'	to be NULL or a valid acl.
87  *
88  * Returns:
89  *	ISC_R_SUCCESS
90  *	ISC_R_NOMEMORY
91  */
92 
93 void
94 dns_dns64_destroy(dns_dns64_t **dns64p);
95 /*
96  * Destroys a dns64 record.
97  *
98  * Requires the record to not be linked.
99  */
100 
101 isc_result_t
102 dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
103 		    const dns_name_t *reqsigner, const dns_aclenv_t *env,
104 		    unsigned int flags, unsigned char *a, unsigned char *aaaa);
105 /*
106  * dns_dns64_aaaafroma() determines whether to perform a DNS64 address
107  * synthesis from 'a' based on 'dns64', 'reqaddr', 'reqsigner', 'env',
108  * 'flags' and 'aaaa'.  If synthesis is performed then the result is
109  * written to '*aaaa'.
110  *
111  * The synthesised address will be of the form:
112  *
113  *	 <prefix bits><a bits><suffix bits>
114  *
115  * If <a bits> straddle bits 64-71 of the AAAA record, then 8 zero bits will
116  * be inserted at bits 64-71.
117  *
118  * Requires:
119  *	'dns64'		to be valid.
120  *	'reqaddr'	to be valid.
121  *	'reqsigner'	to be NULL or valid.
122  *	'env'		to be valid.
123  *	'a'		to point to a IPv4 address in network order.
124  *	'aaaa'		to point to a IPv6 address buffer in network order.
125  *
126  * Returns:
127  *	ISC_R_SUCCESS		if synthesis was performed.
128  *	DNS_R_DISALLOWED	if there is no match.
129  */
130 
131 dns_dns64_t *
132 dns_dns64_next(dns_dns64_t *dns64);
133 /*
134  * Return the next dns64 record in the list.
135  */
136 
137 void
138 dns_dns64_append(dns_dns64list_t *list, dns_dns64_t *dns64);
139 /*
140  * Append the dns64 record to the list.
141  */
142 
143 void
144 dns_dns64_unlink(dns_dns64list_t *list, dns_dns64_t *dns64);
145 /*
146  * Unlink the dns64 record from the list.
147  */
148 
149 bool
150 dns_dns64_aaaaok(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
151 		 const dns_name_t *reqsigner, const dns_aclenv_t *env,
152 		 unsigned int flags, dns_rdataset_t *rdataset, bool *aaaaok,
153 		 size_t aaaaoklen);
154 /*
155  * Determine if there are any non-excluded AAAA records in from the
156  * matching dns64 records in the list starting at 'dns64'.  If there
157  * is a non-excluded address return true.  If all addresses are
158  * excluded in the matched records return false.   If no records
159  * match then return true.
160  *
161  * If aaaaok is defined then dns_dns64_aaaaok() return a array of which
162  * addresses in 'rdataset' were deemed to not be exclude by any matching
163  * record.  If there are no matching records then all entries are set
164  * to true.
165  *
166  * Requires
167  * 	'rdataset'	to be valid and to be for type AAAA and class IN.
168  *	'aaaaoklen'	must match the number of records in 'rdataset'
169  *			if 'aaaaok' in non NULL.
170  */
171 
172 ISC_LANG_ENDDECLS
173 
174 #endif /* DNS_DNS64_H */
175