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