xref: /netbsd-src/external/mpl/dhcp/bind/dist/lib/dns/rdata/generic/nsec_47.c (revision 4afad4b7fa6d4a0d3dedf41d1587a7250710ae54)
1 /*	$NetBSD: nsec_47.c,v 1.1 2024/02/18 20:57:43 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * SPDX-License-Identifier: MPL-2.0
7  *
8  * This Source Code Form is subject to the terms of the Mozilla Public
9  * License, v. 2.0. If a copy of the MPL was not distributed with this
10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11  *
12  * See the COPYRIGHT file distributed with this work for additional
13  * information regarding copyright ownership.
14  */
15 
16 /* RFC 3845 */
17 
18 #ifndef RDATA_GENERIC_NSEC_47_C
19 #define RDATA_GENERIC_NSEC_47_C
20 
21 /*
22  * The attributes do not include DNS_RDATATYPEATTR_SINGLETON
23  * because we must be able to handle a parent/child NSEC pair.
24  */
25 #define RRTYPE_NSEC_ATTRIBUTES                                      \
26 	(DNS_RDATATYPEATTR_DNSSEC | DNS_RDATATYPEATTR_ZONECUTAUTH | \
27 	 DNS_RDATATYPEATTR_ATCNAME)
28 
29 static isc_result_t
fromtext_nsec(ARGS_FROMTEXT)30 fromtext_nsec(ARGS_FROMTEXT) {
31 	isc_token_t token;
32 	dns_name_t name;
33 	isc_buffer_t buffer;
34 
35 	REQUIRE(type == dns_rdatatype_nsec);
36 
37 	UNUSED(type);
38 	UNUSED(rdclass);
39 	UNUSED(callbacks);
40 
41 	/*
42 	 * Next domain.
43 	 */
44 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
45 				      false));
46 	dns_name_init(&name, NULL);
47 	buffer_fromregion(&buffer, &token.value.as_region);
48 	if (origin == NULL) {
49 		origin = dns_rootname;
50 	}
51 	RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
52 
53 	return (typemap_fromtext(lexer, target, false));
54 }
55 
56 static isc_result_t
totext_nsec(ARGS_TOTEXT)57 totext_nsec(ARGS_TOTEXT) {
58 	isc_region_t sr;
59 	dns_name_t name;
60 
61 	REQUIRE(rdata->type == dns_rdatatype_nsec);
62 	REQUIRE(rdata->length != 0);
63 
64 	UNUSED(tctx);
65 
66 	dns_name_init(&name, NULL);
67 	dns_rdata_toregion(rdata, &sr);
68 	dns_name_fromregion(&name, &sr);
69 	isc_region_consume(&sr, name_length(&name));
70 	RETERR(dns_name_totext(&name, false, target));
71 	/*
72 	 * Don't leave a trailing space when there's no typemap present.
73 	 */
74 	if (sr.length > 0) {
75 		RETERR(str_totext(" ", target));
76 	}
77 	return (typemap_totext(&sr, NULL, target));
78 }
79 
80 static isc_result_t
fromwire_nsec(ARGS_FROMWIRE)81 fromwire_nsec(ARGS_FROMWIRE) {
82 	isc_region_t sr;
83 	dns_name_t name;
84 
85 	REQUIRE(type == dns_rdatatype_nsec);
86 
87 	UNUSED(type);
88 	UNUSED(rdclass);
89 
90 	dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
91 
92 	dns_name_init(&name, NULL);
93 	RETERR(dns_name_fromwire(&name, source, dctx, options, target));
94 
95 	isc_buffer_activeregion(source, &sr);
96 	RETERR(typemap_test(&sr, false));
97 	RETERR(mem_tobuffer(target, sr.base, sr.length));
98 	isc_buffer_forward(source, sr.length);
99 	return (ISC_R_SUCCESS);
100 }
101 
102 static isc_result_t
towire_nsec(ARGS_TOWIRE)103 towire_nsec(ARGS_TOWIRE) {
104 	isc_region_t sr;
105 	dns_name_t name;
106 	dns_offsets_t offsets;
107 
108 	REQUIRE(rdata->type == dns_rdatatype_nsec);
109 	REQUIRE(rdata->length != 0);
110 
111 	dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
112 	dns_name_init(&name, offsets);
113 	dns_rdata_toregion(rdata, &sr);
114 	dns_name_fromregion(&name, &sr);
115 	isc_region_consume(&sr, name_length(&name));
116 	RETERR(dns_name_towire(&name, cctx, target));
117 
118 	return (mem_tobuffer(target, sr.base, sr.length));
119 }
120 
121 static int
compare_nsec(ARGS_COMPARE)122 compare_nsec(ARGS_COMPARE) {
123 	isc_region_t r1;
124 	isc_region_t r2;
125 
126 	REQUIRE(rdata1->type == rdata2->type);
127 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
128 	REQUIRE(rdata1->type == dns_rdatatype_nsec);
129 	REQUIRE(rdata1->length != 0);
130 	REQUIRE(rdata2->length != 0);
131 
132 	dns_rdata_toregion(rdata1, &r1);
133 	dns_rdata_toregion(rdata2, &r2);
134 	return (isc_region_compare(&r1, &r2));
135 }
136 
137 static isc_result_t
fromstruct_nsec(ARGS_FROMSTRUCT)138 fromstruct_nsec(ARGS_FROMSTRUCT) {
139 	dns_rdata_nsec_t *nsec = source;
140 	isc_region_t region;
141 
142 	REQUIRE(type == dns_rdatatype_nsec);
143 	REQUIRE(nsec != NULL);
144 	REQUIRE(nsec->common.rdtype == type);
145 	REQUIRE(nsec->common.rdclass == rdclass);
146 	REQUIRE(nsec->typebits != NULL || nsec->len == 0);
147 
148 	UNUSED(type);
149 	UNUSED(rdclass);
150 
151 	dns_name_toregion(&nsec->next, &region);
152 	RETERR(isc_buffer_copyregion(target, &region));
153 
154 	region.base = nsec->typebits;
155 	region.length = nsec->len;
156 	RETERR(typemap_test(&region, false));
157 	return (mem_tobuffer(target, nsec->typebits, nsec->len));
158 }
159 
160 static isc_result_t
tostruct_nsec(ARGS_TOSTRUCT)161 tostruct_nsec(ARGS_TOSTRUCT) {
162 	isc_region_t region;
163 	dns_rdata_nsec_t *nsec = target;
164 	dns_name_t name;
165 
166 	REQUIRE(rdata->type == dns_rdatatype_nsec);
167 	REQUIRE(nsec != NULL);
168 	REQUIRE(rdata->length != 0);
169 
170 	nsec->common.rdclass = rdata->rdclass;
171 	nsec->common.rdtype = rdata->type;
172 	ISC_LINK_INIT(&nsec->common, link);
173 
174 	dns_name_init(&name, NULL);
175 	dns_rdata_toregion(rdata, &region);
176 	dns_name_fromregion(&name, &region);
177 	isc_region_consume(&region, name_length(&name));
178 	dns_name_init(&nsec->next, NULL);
179 	RETERR(name_duporclone(&name, mctx, &nsec->next));
180 
181 	nsec->len = region.length;
182 	nsec->typebits = mem_maybedup(mctx, region.base, region.length);
183 	if (nsec->typebits == NULL) {
184 		goto cleanup;
185 	}
186 
187 	nsec->mctx = mctx;
188 	return (ISC_R_SUCCESS);
189 
190 cleanup:
191 	if (mctx != NULL) {
192 		dns_name_free(&nsec->next, mctx);
193 	}
194 	return (ISC_R_NOMEMORY);
195 }
196 
197 static void
freestruct_nsec(ARGS_FREESTRUCT)198 freestruct_nsec(ARGS_FREESTRUCT) {
199 	dns_rdata_nsec_t *nsec = source;
200 
201 	REQUIRE(nsec != NULL);
202 	REQUIRE(nsec->common.rdtype == dns_rdatatype_nsec);
203 
204 	if (nsec->mctx == NULL) {
205 		return;
206 	}
207 
208 	dns_name_free(&nsec->next, nsec->mctx);
209 	if (nsec->typebits != NULL) {
210 		isc_mem_free(nsec->mctx, nsec->typebits);
211 	}
212 	nsec->mctx = NULL;
213 }
214 
215 static isc_result_t
additionaldata_nsec(ARGS_ADDLDATA)216 additionaldata_nsec(ARGS_ADDLDATA) {
217 	REQUIRE(rdata->type == dns_rdatatype_nsec);
218 
219 	UNUSED(rdata);
220 	UNUSED(add);
221 	UNUSED(arg);
222 
223 	return (ISC_R_SUCCESS);
224 }
225 
226 static isc_result_t
digest_nsec(ARGS_DIGEST)227 digest_nsec(ARGS_DIGEST) {
228 	isc_region_t r;
229 
230 	REQUIRE(rdata->type == dns_rdatatype_nsec);
231 
232 	dns_rdata_toregion(rdata, &r);
233 	return ((digest)(arg, &r));
234 }
235 
236 static bool
checkowner_nsec(ARGS_CHECKOWNER)237 checkowner_nsec(ARGS_CHECKOWNER) {
238 	REQUIRE(type == dns_rdatatype_nsec);
239 
240 	UNUSED(name);
241 	UNUSED(type);
242 	UNUSED(rdclass);
243 	UNUSED(wildcard);
244 
245 	return (true);
246 }
247 
248 static bool
checknames_nsec(ARGS_CHECKNAMES)249 checknames_nsec(ARGS_CHECKNAMES) {
250 	REQUIRE(rdata->type == dns_rdatatype_nsec);
251 
252 	UNUSED(rdata);
253 	UNUSED(owner);
254 	UNUSED(bad);
255 
256 	return (true);
257 }
258 
259 static int
casecompare_nsec(ARGS_COMPARE)260 casecompare_nsec(ARGS_COMPARE) {
261 	isc_region_t region1;
262 	isc_region_t region2;
263 	dns_name_t name1;
264 	dns_name_t name2;
265 	int order;
266 
267 	REQUIRE(rdata1->type == rdata2->type);
268 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
269 	REQUIRE(rdata1->type == dns_rdatatype_nsec);
270 	REQUIRE(rdata1->length != 0);
271 	REQUIRE(rdata2->length != 0);
272 
273 	dns_name_init(&name1, NULL);
274 	dns_name_init(&name2, NULL);
275 
276 	dns_rdata_toregion(rdata1, &region1);
277 	dns_rdata_toregion(rdata2, &region2);
278 
279 	dns_name_fromregion(&name1, &region1);
280 	dns_name_fromregion(&name2, &region2);
281 
282 	order = dns_name_rdatacompare(&name1, &name2);
283 	if (order != 0) {
284 		return (order);
285 	}
286 
287 	isc_region_consume(&region1, name_length(&name1));
288 	isc_region_consume(&region2, name_length(&name2));
289 
290 	return (isc_region_compare(&region1, &region2));
291 }
292 #endif /* RDATA_GENERIC_NSEC_47_C */
293