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