1 /* $NetBSD: doa_259.c,v 1.9 2025/01/26 16:25: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 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 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 131 fromwire_doa(ARGS_FROMWIRE) { 132 isc_region_t region; 133 134 UNUSED(rdclass); 135 UNUSED(dctx); 136 137 REQUIRE(type == dns_rdatatype_doa); 138 139 isc_buffer_activeregion(source, ®ion); 140 /* 141 * DOA-MEDIA-TYPE may be an empty <character-string> (i.e., 142 * comprising of just the length octet) and DOA-DATA can have 143 * zero length. 144 */ 145 if (region.length < 4 + 4 + 1 + 1) { 146 return ISC_R_UNEXPECTEDEND; 147 } 148 149 /* 150 * Check whether DOA-MEDIA-TYPE length is not malformed. 151 */ 152 if (region.base[9] > region.length - 10) { 153 return ISC_R_UNEXPECTEDEND; 154 } 155 156 isc_buffer_forward(source, region.length); 157 return mem_tobuffer(target, region.base, region.length); 158 } 159 160 static isc_result_t 161 towire_doa(ARGS_TOWIRE) { 162 isc_region_t region; 163 164 UNUSED(cctx); 165 166 REQUIRE(rdata != NULL); 167 REQUIRE(rdata->type == dns_rdatatype_doa); 168 REQUIRE(rdata->length != 0); 169 170 dns_rdata_toregion(rdata, ®ion); 171 return mem_tobuffer(target, region.base, region.length); 172 } 173 174 static int 175 compare_doa(ARGS_COMPARE) { 176 isc_region_t r1; 177 isc_region_t r2; 178 179 REQUIRE(rdata1 != NULL); 180 REQUIRE(rdata2 != NULL); 181 REQUIRE(rdata1->type == rdata2->type); 182 REQUIRE(rdata1->type == dns_rdatatype_doa); 183 REQUIRE(rdata1->rdclass == rdata2->rdclass); 184 REQUIRE(rdata1->length != 0); 185 REQUIRE(rdata2->length != 0); 186 187 dns_rdata_toregion(rdata1, &r1); 188 dns_rdata_toregion(rdata2, &r2); 189 return isc_region_compare(&r1, &r2); 190 } 191 192 static isc_result_t 193 fromstruct_doa(ARGS_FROMSTRUCT) { 194 dns_rdata_doa_t *doa = source; 195 196 REQUIRE(type == dns_rdatatype_doa); 197 REQUIRE(doa != NULL); 198 REQUIRE(doa->common.rdtype == dns_rdatatype_doa); 199 REQUIRE(doa->common.rdclass == rdclass); 200 201 RETERR(uint32_tobuffer(doa->enterprise, target)); 202 RETERR(uint32_tobuffer(doa->type, target)); 203 RETERR(uint8_tobuffer(doa->location, target)); 204 RETERR(uint8_tobuffer(doa->mediatype_len, target)); 205 RETERR(mem_tobuffer(target, doa->mediatype, doa->mediatype_len)); 206 return mem_tobuffer(target, doa->data, doa->data_len); 207 } 208 209 static isc_result_t 210 tostruct_doa(ARGS_TOSTRUCT) { 211 dns_rdata_doa_t *doa = target; 212 isc_region_t region; 213 214 REQUIRE(rdata != NULL); 215 REQUIRE(rdata->type == dns_rdatatype_doa); 216 REQUIRE(doa != NULL); 217 REQUIRE(rdata->length >= 10); 218 219 doa->common.rdclass = rdata->rdclass; 220 doa->common.rdtype = rdata->type; 221 ISC_LINK_INIT(&doa->common, link); 222 223 dns_rdata_toregion(rdata, ®ion); 224 225 /* 226 * DOA-ENTERPRISE 227 */ 228 doa->enterprise = uint32_fromregion(®ion); 229 isc_region_consume(®ion, 4); 230 231 /* 232 * DOA-TYPE 233 */ 234 doa->type = uint32_fromregion(®ion); 235 isc_region_consume(®ion, 4); 236 237 /* 238 * DOA-LOCATION 239 */ 240 doa->location = uint8_fromregion(®ion); 241 isc_region_consume(®ion, 1); 242 243 /* 244 * DOA-MEDIA-TYPE 245 */ 246 doa->mediatype_len = uint8_fromregion(®ion); 247 isc_region_consume(®ion, 1); 248 INSIST(doa->mediatype_len <= region.length); 249 doa->mediatype = mem_maybedup(mctx, region.base, doa->mediatype_len); 250 isc_region_consume(®ion, doa->mediatype_len); 251 252 /* 253 * DOA-DATA 254 */ 255 doa->data_len = region.length; 256 doa->data = NULL; 257 if (doa->data_len > 0) { 258 doa->data = mem_maybedup(mctx, region.base, doa->data_len); 259 isc_region_consume(®ion, doa->data_len); 260 } 261 262 doa->mctx = mctx; 263 264 return ISC_R_SUCCESS; 265 } 266 267 static void 268 freestruct_doa(ARGS_FREESTRUCT) { 269 dns_rdata_doa_t *doa = source; 270 271 REQUIRE(doa != NULL); 272 REQUIRE(doa->common.rdtype == dns_rdatatype_doa); 273 274 if (doa->mctx == NULL) { 275 return; 276 } 277 278 if (doa->mediatype != NULL) { 279 isc_mem_free(doa->mctx, doa->mediatype); 280 } 281 if (doa->data != NULL) { 282 isc_mem_free(doa->mctx, doa->data); 283 } 284 285 doa->mctx = NULL; 286 } 287 288 static isc_result_t 289 additionaldata_doa(ARGS_ADDLDATA) { 290 REQUIRE(rdata->type == dns_rdatatype_doa); 291 292 UNUSED(rdata); 293 UNUSED(owner); 294 UNUSED(add); 295 UNUSED(arg); 296 297 return ISC_R_SUCCESS; 298 } 299 300 static isc_result_t 301 digest_doa(ARGS_DIGEST) { 302 isc_region_t r; 303 304 REQUIRE(rdata->type == dns_rdatatype_doa); 305 306 dns_rdata_toregion(rdata, &r); 307 308 return (digest)(arg, &r); 309 } 310 311 static bool 312 checkowner_doa(ARGS_CHECKOWNER) { 313 UNUSED(name); 314 UNUSED(type); 315 UNUSED(rdclass); 316 UNUSED(wildcard); 317 318 REQUIRE(type == dns_rdatatype_doa); 319 320 return true; 321 } 322 323 static bool 324 checknames_doa(ARGS_CHECKNAMES) { 325 UNUSED(rdata); 326 UNUSED(owner); 327 UNUSED(bad); 328 329 REQUIRE(rdata->type == dns_rdatatype_doa); 330 331 return true; 332 } 333 334 static int 335 casecompare_doa(ARGS_COMPARE) { 336 return compare_doa(rdata1, rdata2); 337 } 338 339 #endif /* RDATA_GENERIC_DOA_259_C */ 340