1 /*	$NetBSD: doa_259.c,v 1.7 2022/09/23 12:15:31 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 #ifndef RDATA_GENERIC_DOA_259_C
17 #define RDATA_GENERIC_DOA_259_C
18 
19 #define RRTYPE_DOA_ATTRIBUTES (0)
20 
21 static isc_result_t
fromtext_doa(ARGS_FROMTEXT)22 fromtext_doa(ARGS_FROMTEXT) {
23 	isc_token_t token;
24 
25 	REQUIRE(type == dns_rdatatype_doa);
26 
27 	UNUSED(rdclass);
28 	UNUSED(origin);
29 	UNUSED(options);
30 	UNUSED(callbacks);
31 
32 	/*
33 	 * DOA-ENTERPRISE
34 	 */
35 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
36 				      false));
37 	RETERR(uint32_tobuffer(token.value.as_ulong, target));
38 
39 	/*
40 	 * DOA-TYPE
41 	 */
42 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
43 				      false));
44 	RETERR(uint32_tobuffer(token.value.as_ulong, target));
45 
46 	/*
47 	 * DOA-LOCATION
48 	 */
49 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
50 				      false));
51 	if (token.value.as_ulong > 0xffU) {
52 		RETTOK(ISC_R_RANGE);
53 	}
54 	RETERR(uint8_tobuffer(token.value.as_ulong, target));
55 
56 	/*
57 	 * DOA-MEDIA-TYPE
58 	 */
59 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
60 				      false));
61 	RETTOK(txt_fromtext(&token.value.as_textregion, target));
62 
63 	/*
64 	 * DOA-DATA
65 	 */
66 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
67 				      false));
68 	if (strcmp(DNS_AS_STR(token), "-") == 0) {
69 		return (ISC_R_SUCCESS);
70 	} else {
71 		isc_lex_ungettoken(lexer, &token);
72 		return (isc_base64_tobuffer(lexer, target, -1));
73 	}
74 }
75 
76 static isc_result_t
totext_doa(ARGS_TOTEXT)77 totext_doa(ARGS_TOTEXT) {
78 	char buf[sizeof("4294967295 ")];
79 	isc_region_t region;
80 	uint32_t n;
81 
82 	REQUIRE(rdata != NULL);
83 	REQUIRE(rdata->type == dns_rdatatype_doa);
84 	REQUIRE(rdata->length != 0);
85 
86 	UNUSED(tctx);
87 
88 	dns_rdata_toregion(rdata, &region);
89 
90 	/*
91 	 * DOA-ENTERPRISE
92 	 */
93 	n = uint32_fromregion(&region);
94 	isc_region_consume(&region, 4);
95 	snprintf(buf, sizeof(buf), "%u ", n);
96 	RETERR(str_totext(buf, target));
97 
98 	/*
99 	 * DOA-TYPE
100 	 */
101 	n = uint32_fromregion(&region);
102 	isc_region_consume(&region, 4);
103 	snprintf(buf, sizeof(buf), "%u ", n);
104 	RETERR(str_totext(buf, target));
105 
106 	/*
107 	 * DOA-LOCATION
108 	 */
109 	n = uint8_fromregion(&region);
110 	isc_region_consume(&region, 1);
111 	snprintf(buf, sizeof(buf), "%u ", n);
112 	RETERR(str_totext(buf, target));
113 
114 	/*
115 	 * DOA-MEDIA-TYPE
116 	 */
117 	RETERR(txt_totext(&region, true, target));
118 	RETERR(str_totext(" ", target));
119 
120 	/*
121 	 * DOA-DATA
122 	 */
123 	if (region.length == 0) {
124 		return (str_totext("-", target));
125 	} else {
126 		return (isc_base64_totext(&region, 60, "", target));
127 	}
128 }
129 
130 static isc_result_t
fromwire_doa(ARGS_FROMWIRE)131 fromwire_doa(ARGS_FROMWIRE) {
132 	isc_region_t region;
133 
134 	UNUSED(rdclass);
135 	UNUSED(dctx);
136 	UNUSED(options);
137 
138 	REQUIRE(type == dns_rdatatype_doa);
139 
140 	isc_buffer_activeregion(source, &region);
141 	/*
142 	 * DOA-MEDIA-TYPE may be an empty <character-string> (i.e.,
143 	 * comprising of just the length octet) and DOA-DATA can have
144 	 * zero length.
145 	 */
146 	if (region.length < 4 + 4 + 1 + 1) {
147 		return (ISC_R_UNEXPECTEDEND);
148 	}
149 
150 	/*
151 	 * Check whether DOA-MEDIA-TYPE length is not malformed.
152 	 */
153 	if (region.base[9] > region.length - 10) {
154 		return (ISC_R_UNEXPECTEDEND);
155 	}
156 
157 	isc_buffer_forward(source, region.length);
158 	return (mem_tobuffer(target, region.base, region.length));
159 }
160 
161 static isc_result_t
towire_doa(ARGS_TOWIRE)162 towire_doa(ARGS_TOWIRE) {
163 	isc_region_t region;
164 
165 	UNUSED(cctx);
166 
167 	REQUIRE(rdata != NULL);
168 	REQUIRE(rdata->type == dns_rdatatype_doa);
169 	REQUIRE(rdata->length != 0);
170 
171 	dns_rdata_toregion(rdata, &region);
172 	return (mem_tobuffer(target, region.base, region.length));
173 }
174 
175 static int
compare_doa(ARGS_COMPARE)176 compare_doa(ARGS_COMPARE) {
177 	isc_region_t r1;
178 	isc_region_t r2;
179 
180 	REQUIRE(rdata1 != NULL);
181 	REQUIRE(rdata2 != NULL);
182 	REQUIRE(rdata1->type == rdata2->type);
183 	REQUIRE(rdata1->type == dns_rdatatype_doa);
184 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
185 	REQUIRE(rdata1->length != 0);
186 	REQUIRE(rdata2->length != 0);
187 
188 	dns_rdata_toregion(rdata1, &r1);
189 	dns_rdata_toregion(rdata2, &r2);
190 	return (isc_region_compare(&r1, &r2));
191 }
192 
193 static isc_result_t
fromstruct_doa(ARGS_FROMSTRUCT)194 fromstruct_doa(ARGS_FROMSTRUCT) {
195 	dns_rdata_doa_t *doa = source;
196 
197 	REQUIRE(type == dns_rdatatype_doa);
198 	REQUIRE(doa != NULL);
199 	REQUIRE(doa->common.rdtype == dns_rdatatype_doa);
200 	REQUIRE(doa->common.rdclass == rdclass);
201 
202 	RETERR(uint32_tobuffer(doa->enterprise, target));
203 	RETERR(uint32_tobuffer(doa->type, target));
204 	RETERR(uint8_tobuffer(doa->location, target));
205 	RETERR(uint8_tobuffer(doa->mediatype_len, target));
206 	RETERR(mem_tobuffer(target, doa->mediatype, doa->mediatype_len));
207 	return (mem_tobuffer(target, doa->data, doa->data_len));
208 }
209 
210 static isc_result_t
tostruct_doa(ARGS_TOSTRUCT)211 tostruct_doa(ARGS_TOSTRUCT) {
212 	dns_rdata_doa_t *doa = target;
213 	isc_region_t region;
214 
215 	REQUIRE(rdata != NULL);
216 	REQUIRE(rdata->type == dns_rdatatype_doa);
217 	REQUIRE(doa != NULL);
218 	REQUIRE(rdata->length != 0);
219 
220 	doa->common.rdclass = rdata->rdclass;
221 	doa->common.rdtype = rdata->type;
222 	ISC_LINK_INIT(&doa->common, link);
223 
224 	dns_rdata_toregion(rdata, &region);
225 
226 	/*
227 	 * DOA-ENTERPRISE
228 	 */
229 	if (region.length < 4) {
230 		return (ISC_R_UNEXPECTEDEND);
231 	}
232 	doa->enterprise = uint32_fromregion(&region);
233 	isc_region_consume(&region, 4);
234 
235 	/*
236 	 * DOA-TYPE
237 	 */
238 	if (region.length < 4) {
239 		return (ISC_R_UNEXPECTEDEND);
240 	}
241 	doa->type = uint32_fromregion(&region);
242 	isc_region_consume(&region, 4);
243 
244 	/*
245 	 * DOA-LOCATION
246 	 */
247 	if (region.length < 1) {
248 		return (ISC_R_UNEXPECTEDEND);
249 	}
250 	doa->location = uint8_fromregion(&region);
251 	isc_region_consume(&region, 1);
252 
253 	/*
254 	 * DOA-MEDIA-TYPE
255 	 */
256 	if (region.length < 1) {
257 		return (ISC_R_UNEXPECTEDEND);
258 	}
259 	doa->mediatype_len = uint8_fromregion(&region);
260 	isc_region_consume(&region, 1);
261 	INSIST(doa->mediatype_len <= region.length);
262 	doa->mediatype = mem_maybedup(mctx, region.base, doa->mediatype_len);
263 	if (doa->mediatype == NULL) {
264 		goto cleanup;
265 	}
266 	isc_region_consume(&region, doa->mediatype_len);
267 
268 	/*
269 	 * DOA-DATA
270 	 */
271 	doa->data_len = region.length;
272 	doa->data = NULL;
273 	if (doa->data_len > 0) {
274 		doa->data = mem_maybedup(mctx, region.base, doa->data_len);
275 		if (doa->data == NULL) {
276 			goto cleanup;
277 		}
278 		isc_region_consume(&region, doa->data_len);
279 	}
280 
281 	doa->mctx = mctx;
282 
283 	return (ISC_R_SUCCESS);
284 
285 cleanup:
286 	if (mctx != NULL && doa->mediatype != NULL) {
287 		isc_mem_free(mctx, doa->mediatype);
288 	}
289 	return (ISC_R_NOMEMORY);
290 }
291 
292 static void
freestruct_doa(ARGS_FREESTRUCT)293 freestruct_doa(ARGS_FREESTRUCT) {
294 	dns_rdata_doa_t *doa = source;
295 
296 	REQUIRE(doa != NULL);
297 	REQUIRE(doa->common.rdtype == dns_rdatatype_doa);
298 
299 	if (doa->mctx == NULL) {
300 		return;
301 	}
302 
303 	if (doa->mediatype != NULL) {
304 		isc_mem_free(doa->mctx, doa->mediatype);
305 	}
306 	if (doa->data != NULL) {
307 		isc_mem_free(doa->mctx, doa->data);
308 	}
309 
310 	doa->mctx = NULL;
311 }
312 
313 static isc_result_t
additionaldata_doa(ARGS_ADDLDATA)314 additionaldata_doa(ARGS_ADDLDATA) {
315 	UNUSED(rdata);
316 	UNUSED(add);
317 	UNUSED(arg);
318 
319 	REQUIRE(rdata->type == dns_rdatatype_doa);
320 
321 	return (ISC_R_SUCCESS);
322 }
323 
324 static isc_result_t
digest_doa(ARGS_DIGEST)325 digest_doa(ARGS_DIGEST) {
326 	isc_region_t r;
327 
328 	REQUIRE(rdata->type == dns_rdatatype_doa);
329 
330 	dns_rdata_toregion(rdata, &r);
331 
332 	return ((digest)(arg, &r));
333 }
334 
335 static bool
checkowner_doa(ARGS_CHECKOWNER)336 checkowner_doa(ARGS_CHECKOWNER) {
337 	UNUSED(name);
338 	UNUSED(type);
339 	UNUSED(rdclass);
340 	UNUSED(wildcard);
341 
342 	REQUIRE(type == dns_rdatatype_doa);
343 
344 	return (true);
345 }
346 
347 static bool
checknames_doa(ARGS_CHECKNAMES)348 checknames_doa(ARGS_CHECKNAMES) {
349 	UNUSED(rdata);
350 	UNUSED(owner);
351 	UNUSED(bad);
352 
353 	REQUIRE(rdata->type == dns_rdatatype_doa);
354 
355 	return (true);
356 }
357 
358 static int
casecompare_doa(ARGS_COMPARE)359 casecompare_doa(ARGS_COMPARE) {
360 	return (compare_doa(rdata1, rdata2));
361 }
362 
363 #endif /* RDATA_GENERIC_DOA_259_C */
364