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, ®ion);
89
90 /*
91 * DOA-ENTERPRISE
92 */
93 n = uint32_fromregion(®ion);
94 isc_region_consume(®ion, 4);
95 snprintf(buf, sizeof(buf), "%u ", n);
96 RETERR(str_totext(buf, target));
97
98 /*
99 * DOA-TYPE
100 */
101 n = uint32_fromregion(®ion);
102 isc_region_consume(®ion, 4);
103 snprintf(buf, sizeof(buf), "%u ", n);
104 RETERR(str_totext(buf, target));
105
106 /*
107 * DOA-LOCATION
108 */
109 n = uint8_fromregion(®ion);
110 isc_region_consume(®ion, 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(®ion, 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(®ion, 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, ®ion);
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, ®ion);
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, ®ion);
225
226 /*
227 * DOA-ENTERPRISE
228 */
229 if (region.length < 4) {
230 return (ISC_R_UNEXPECTEDEND);
231 }
232 doa->enterprise = uint32_fromregion(®ion);
233 isc_region_consume(®ion, 4);
234
235 /*
236 * DOA-TYPE
237 */
238 if (region.length < 4) {
239 return (ISC_R_UNEXPECTEDEND);
240 }
241 doa->type = uint32_fromregion(®ion);
242 isc_region_consume(®ion, 4);
243
244 /*
245 * DOA-LOCATION
246 */
247 if (region.length < 1) {
248 return (ISC_R_UNEXPECTEDEND);
249 }
250 doa->location = uint8_fromregion(®ion);
251 isc_region_consume(®ion, 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(®ion);
260 isc_region_consume(®ion, 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(®ion, 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(®ion, 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