1 /* 2 * types.h 3 * 4 * Copyright (c) 2023, NLnet Labs. All rights reserved. 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 * 8 */ 9 #ifndef TYPES_H 10 #define TYPES_H 11 12 nonnull_all 13 static really_inline int32_t scan_type_or_class( 14 const char *data, 15 size_t length, 16 uint16_t *code, 17 const mnemonic_t **mnemonic); 18 19 nonnull_all 20 static really_inline int32_t parse_type( 21 parser_t *parser, 22 const type_info_t *type, 23 const rdata_info_t *field, 24 rdata_t *rdata, 25 const token_t *token); 26 27 nonnull_all 28 static really_inline int32_t parse_name( 29 parser_t *parser, 30 const type_info_t *type, 31 const rdata_info_t *field, 32 rdata_t *rdata, 33 const token_t *token); 34 35 nonnull_all 36 static really_inline int32_t parse_string( 37 parser_t *parser, 38 const type_info_t *type, 39 const rdata_info_t *field, 40 rdata_t *rdata, 41 const token_t *token); 42 43 nonnull_all 44 static really_inline int32_t parse_text( 45 parser_t *parser, 46 const type_info_t *type, 47 const rdata_info_t *field, 48 rdata_t *rdata, 49 const token_t *token); 50 51 #define FIELDS(fields) \ 52 { (sizeof(fields)/sizeof(fields[0])), fields } 53 54 #define FIELD(name) \ 55 { { { name, sizeof(name) - 1 } } } 56 57 #define CLASS(name, code) \ 58 { { { name, sizeof(name) - 1 }, code } } 59 60 #define UNKNOWN_CLASS(code) \ 61 { { { "", 0 }, code } } 62 63 #define TYPE(name, code, _class, fields, check, parse) \ 64 { { { name, sizeof(name) - 1 }, code }, _class, false, false, fields, check, parse } 65 66 #define UNKNOWN_TYPE(code) \ 67 { { { "", 0 }, code }, 0, false, false, { 0, NULL }, check_generic_rr, parse_unknown_rdata } 68 69 nonnull((1,2,3,4)) 70 static really_inline int32_t check_bytes( 71 parser_t *parser, 72 const type_info_t *type, 73 const rdata_info_t *field, 74 const uint8_t *data, 75 const size_t length, 76 const size_t size) 77 { 78 (void)data; 79 if (length < size) 80 SYNTAX_ERROR(parser, "Missing %s in %s", NAME(field), NAME(type)); 81 return (int32_t)size; 82 } 83 84 #define check_int8(...) check_bytes(__VA_ARGS__, sizeof(uint8_t)) 85 86 #define check_int16(...) check_bytes(__VA_ARGS__, sizeof(uint16_t)) 87 88 #define check_int32(...) check_bytes(__VA_ARGS__, sizeof(uint32_t)) 89 90 #define check_int64(...) check_bytes(__VA_ARGS__, sizeof(uint64_t)) 91 92 #define check_ip4(...) check_bytes(__VA_ARGS__, 4) 93 94 #define check_ip6(...) check_bytes(__VA_ARGS__, 16) 95 96 #define check_ilnp64(...) check_bytes(__VA_ARGS__, sizeof(uint64_t)) 97 98 nonnull((1,2,3,4)) 99 static really_inline int32_t check_ttl( 100 parser_t *parser, 101 const type_info_t *type, 102 const rdata_info_t *field, 103 const uint8_t *data, 104 const size_t length) 105 { 106 uint32_t number; 107 108 if (length < sizeof(number)) 109 SYNTAX_ERROR(parser, "Missing %s in %s", NAME(field), NAME(type)); 110 111 memcpy(&number, data, sizeof(number)); 112 number = be32toh(number); 113 114 if (number > INT32_MAX) 115 SEMANTIC_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type)); 116 117 return 4; 118 } 119 120 zone_nonnull((1,2,3,4)) 121 static really_inline int32_t check_name( 122 parser_t *parser, 123 const type_info_t *type, 124 const rdata_info_t *field, 125 const uint8_t *data, 126 const size_t length) 127 { 128 int32_t label = 0, count = 0; 129 while (count < (int32_t)length) { 130 label = data[count]; 131 count += 1 + label; 132 if (!label) 133 break; 134 } 135 136 if (!count || count > (int32_t)length) 137 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type)); 138 139 return count; 140 } 141 142 zone_nonnull((1,2,3,4)) 143 static really_inline int32_t check_string( 144 parser_t *parser, 145 const type_info_t *type, 146 const rdata_info_t *field, 147 const uint8_t *data, 148 const size_t length) 149 { 150 int32_t count; 151 152 if (!length || (count = 1 + (int32_t)data[0]) > (int32_t)length) 153 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type)); 154 155 return count; 156 } 157 158 zone_nonnull((1,2,3,4)) 159 static really_inline int32_t check_nsec( 160 parser_t *parser, 161 const type_info_t *type, 162 const rdata_info_t *field, 163 const uint8_t *data, 164 const size_t length) 165 { 166 int32_t count = 0; 167 int32_t last_window = -1; 168 169 while ((count + 2) < (int32_t)length) { 170 const int32_t window = (int32_t)data[0]; 171 const int32_t blocks = (int32_t)data[1]; 172 if (window <= last_window) 173 SYNTAX_ERROR(parser, "Invalid %s in %s, windows are out-of-order", 174 NAME(field), NAME(type)); 175 if (!blocks || blocks > 32) 176 SYNTAX_ERROR(parser, "Invalid %s in %s, blocks are out-of-bounds", 177 NAME(field), NAME(type)); 178 count += 2 + blocks; 179 last_window = window; 180 } 181 182 if (count != (int32_t)length) 183 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type)); 184 185 return count; 186 } 187 188 zone_nonnull((1)) 189 static really_inline int32_t check(size_t *length, int32_t count) 190 { 191 if (count < 0) 192 return count; 193 *length += (size_t)count; 194 return 0; 195 } 196 197 nonnull_all 198 static really_inline void adjust_line_count(file_t *file) 199 { 200 file->line += file->span; 201 file->span = 0; 202 } 203 204 nonnull_all 205 static really_inline int32_t accept_rr( 206 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 207 { 208 (void)type; 209 210 assert(rdata->octets <= rdata->limit); 211 assert(rdata->octets >= parser->rdata->octets); 212 size_t length = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 213 214 assert(length <= UINT16_MAX); 215 assert(parser->owner->length <= UINT8_MAX); 216 int32_t code = parser->options.accept.callback( 217 parser, 218 &(zone_name_t){ (uint8_t)parser->owner->length, parser->owner->octets }, 219 parser->file->last_type, 220 parser->file->last_class, 221 *parser->file->ttl, 222 (uint16_t)length, 223 parser->rdata->octets, 224 parser->user_data); 225 226 adjust_line_count(parser->file); 227 return code; 228 } 229 230 nonnull_all 231 static int32_t check_a_rr( 232 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 233 { 234 assert(rdata->octets >= parser->rdata->octets); 235 if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets == 4) 236 return accept_rr(parser, type, rdata); 237 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 238 } 239 240 nonnull_all 241 static int32_t parse_a_rdata( 242 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 243 { 244 int32_t code; 245 const rdata_info_t *fields = type->rdata.fields; 246 247 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 248 return code; 249 if ((code = parse_ip4(parser, type, &fields[0], rdata, token)) < 0) 250 return code; 251 if ((code = take_delimiter(parser, type, token)) < 0) 252 return code; 253 return accept_rr(parser, type, rdata); 254 } 255 256 nonnull_all 257 static int32_t check_ns_rr( 258 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 259 { 260 int32_t r; 261 size_t c = 0; 262 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 263 const uint8_t *o = parser->rdata->octets; 264 const rdata_info_t *f = type->rdata.fields; 265 266 if ((r = check(&c, check_name(parser, type, &f[0], o, n))) < 0) 267 return r; 268 269 if (c != n) 270 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 271 return accept_rr(parser, type, rdata); 272 } 273 274 nonnull_all 275 static int32_t parse_ns_rdata( 276 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 277 { 278 int32_t code; 279 const rdata_info_t *fields = type->rdata.fields; 280 281 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 282 return code; 283 if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0) 284 return code; 285 if ((code = take_delimiter(parser, type, token)) < 0) 286 return code; 287 return accept_rr(parser, type, rdata); 288 } 289 290 nonnull_all 291 static int32_t check_soa_rr( 292 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 293 { 294 int32_t r; 295 size_t c = 0; 296 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 297 const uint8_t *o = parser->rdata->octets; 298 const rdata_info_t *f = type->rdata.fields; 299 300 if ((r = check(&c, check_name(parser, type, &f[0], o, n))) || 301 (r = check(&c, check_name(parser, type, &f[1], o+c, n-c))) || 302 (r = check(&c, check_int32(parser, type, &f[2], o+c, n-c))) || 303 (r = check(&c, check_ttl(parser, type, &f[3], o+c, n-c))) || 304 (r = check(&c, check_ttl(parser, type, &f[4], o+c, n-c))) || 305 (r = check(&c, check_ttl(parser, type, &f[5], o+c, n-c))) || 306 (r = check(&c, check_ttl(parser, type, &f[6], o+c, n-c)))) 307 return r; 308 309 if (c != n) 310 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 311 return accept_rr(parser, type, rdata); 312 } 313 314 nonnull_all 315 static int32_t parse_soa_rdata( 316 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 317 { 318 int32_t code; 319 const rdata_info_t *fields = type->rdata.fields; 320 321 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 322 return code; 323 if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0) 324 return code; 325 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 326 return code; 327 if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0) 328 return code; 329 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 330 return code; 331 if ((code = parse_int32(parser, type, &fields[2], rdata, token)) < 0) 332 return code; 333 if ((code = take_contiguous(parser, type, &fields[3], token)) < 0) 334 return code; 335 if ((code = parse_ttl(parser, type, &fields[3], rdata, token)) < 0) 336 return code; 337 if ((code = take_contiguous(parser, type, &fields[4], token)) < 0) 338 return code; 339 if ((code = parse_ttl(parser, type, &fields[4], rdata, token)) < 0) 340 return code; 341 if ((code = take_contiguous(parser, type, &fields[5], token)) < 0) 342 return code; 343 if ((code = parse_ttl(parser, type, &fields[5], rdata, token)) < 0) 344 return code; 345 if ((code = take_contiguous(parser, type, &fields[6], token)) < 0) 346 return code; 347 if ((code = parse_ttl(parser, type, &fields[6], rdata, token)) < 0) 348 return code; 349 if ((code = take_delimiter(parser, type, token)) < 0) 350 return code; 351 return accept_rr(parser, type, rdata); 352 } 353 354 nonnull_all 355 static int32_t check_wks_rr( 356 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 357 { 358 int32_t r; 359 size_t c = 0; 360 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 361 const uint8_t *o = parser->rdata->octets; 362 const rdata_info_t *f = type->rdata.fields; 363 364 if ((r = check(&c, check_ip4(parser, type, &f[0], o, n))) || 365 (r = check(&c, check_int8(parser, type, &f[0], o+c, n-c)))) 366 return r; 367 368 // any bit may, or may not, be set. confirm the bitmap does not exceed the 369 // maximum number of ports 370 if (n > 8192 + 5) 371 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 372 373 return accept_rr(parser, type, rdata); 374 } 375 376 nonnull_all 377 static int32_t parse_wks_rdata( 378 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 379 { 380 int32_t code; 381 const rdata_info_t *fields = type->rdata.fields; 382 383 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 384 return code; 385 if ((code = parse_ip4(parser, type, &fields[0], rdata, token) < 0)) 386 return code; 387 388 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 389 return code; 390 391 uint8_t protocol; 392 if (!scan_protocol(token->data, token->length, &protocol)) 393 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[1]), NAME(type)); 394 395 *rdata->octets++ = protocol; 396 uint8_t *bitmap = rdata->octets; 397 int32_t highest_port = -1; 398 399 take(parser, token); 400 while (is_contiguous(token)) { 401 uint16_t port; 402 if (!scan_service(token->data, token->length, protocol, &port)) 403 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&type->rdata.fields[2]), NAME(type)); 404 405 if (port > highest_port) { 406 // ensure newly used octets are zeroed out before use 407 size_t offset = highest_port < 0 ? 0 : (size_t)highest_port / 8 + 1; 408 size_t length = (size_t)port / 8 + 1; 409 memset(bitmap + offset, 0, length - offset); 410 highest_port = port; 411 } 412 413 // bits are counted from left to right, so bit 0 is the left most bit 414 bitmap[port / 8] |= (1 << (7 - port % 8)); 415 take(parser, token); 416 } 417 418 rdata->octets += (size_t)highest_port / 8 + 1; 419 420 if (have_delimiter(parser, type, token) < 0) 421 return token->code; 422 return accept_rr(parser, type, rdata); 423 } 424 425 nonnull_all 426 static int32_t check_hinfo_rr( 427 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 428 { 429 int32_t r; 430 size_t c = 0; 431 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 432 const uint8_t *o = parser->rdata->octets; 433 const rdata_info_t *f = type->rdata.fields; 434 435 if ((r = check(&c, check_string(parser, type, &f[0], o, n))) || 436 (r = check(&c, check_string(parser, type, &f[1], o+c, n-c)))) 437 return r; 438 439 if (c != n) 440 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 441 return accept_rr(parser, type, rdata); 442 } 443 444 nonnull_all 445 static int32_t parse_hinfo_rdata( 446 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 447 { 448 int32_t code; 449 const rdata_info_t *fields = type->rdata.fields; 450 451 if ((code = have_contiguous_or_quoted(parser, type, &fields[0], token)) < 0) 452 return code; 453 if ((code = parse_string(parser, type, &fields[0], rdata, token)) < 0) 454 return code; 455 if ((code = take_quoted_or_contiguous(parser, type, &fields[1], token)) < 0) 456 return code; 457 if ((code = parse_string(parser, type, &fields[1], rdata, token)) < 0) 458 return code; 459 if ((code = take_delimiter(parser, type, token)) < 0) 460 return code; 461 return accept_rr(parser, type, rdata); 462 } 463 464 nonnull_all 465 static int32_t check_minfo_rr( 466 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 467 { 468 int32_t r; 469 size_t c = 0; 470 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 471 const uint8_t *o = parser->rdata->octets; 472 const rdata_info_t *f = type->rdata.fields; 473 474 if ((r = check(&c, check_name(parser, type, &f[0], o, n))) || 475 (r = check(&c, check_name(parser, type, &f[1], o+c, n-c)))) 476 return r; 477 478 if (c != n) 479 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 480 return accept_rr(parser, type, rdata); 481 } 482 483 nonnull_all 484 static int32_t parse_minfo_rdata( 485 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 486 { 487 int32_t code; 488 const rdata_info_t *fields = type->rdata.fields; 489 490 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 491 return code; 492 if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0) 493 return code; 494 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 495 return code; 496 if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0) 497 return code; 498 if ((code = take_delimiter(parser, type, token)) < 0) 499 return code; 500 return accept_rr(parser, type, rdata); 501 } 502 503 nonnull_all 504 static int32_t check_mx_rr( 505 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 506 { 507 int32_t r; 508 size_t c = 0; 509 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 510 const uint8_t *o = parser->rdata->octets; 511 const rdata_info_t *f = type->rdata.fields; 512 513 if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) || 514 (r = check(&c, check_name(parser, type, &f[1], o+c, n-c)))) 515 return r; 516 517 if (c != n) 518 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 519 return accept_rr(parser, type, rdata); 520 } 521 522 nonnull_all 523 static int32_t parse_mx_rdata( 524 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 525 { 526 int32_t code; 527 const rdata_info_t *fields = type->rdata.fields; 528 529 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 530 return code; 531 if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0) 532 return code; 533 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 534 return code; 535 if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0) 536 return code; 537 if ((code = take_delimiter(parser, type, token)) < 0) 538 return code; 539 return accept_rr(parser, type, rdata); 540 } 541 542 nonnull_all 543 static int32_t check_txt_rr( 544 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 545 { 546 int32_t r; 547 size_t c = 0; 548 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 549 const uint8_t *o = parser->rdata->octets; 550 const rdata_info_t *f = type->rdata.fields; 551 552 if ((r = check(&c, check_string(parser, type, &f[0], o, n)))) 553 return r; 554 555 while (c < n) 556 if ((r = check(&c, check_string(parser, type, &f[0], o+c, n-c)))) 557 return r; 558 559 if (c != n) 560 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 561 return accept_rr(parser, type, rdata); 562 } 563 564 nonnull_all 565 static int32_t parse_txt_rdata( 566 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 567 { 568 int32_t code; 569 const rdata_info_t *fields = type->rdata.fields; 570 571 while (is_contiguous_or_quoted(token)) { 572 if ((code = parse_string(parser, type, &fields[0], rdata, token)) < 0) 573 return code; 574 take(parser, token); 575 } 576 577 if ((code = have_delimiter(parser, type, token)) < 0) 578 return code; 579 return accept_rr(parser, type, rdata); 580 } 581 582 nonnull_all 583 static int32_t check_x25_rr( 584 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 585 { 586 int32_t r; 587 size_t c = 0; 588 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 589 const uint8_t *o = parser->rdata->octets; 590 const rdata_info_t *f = type->rdata.fields; 591 592 if ((r = check(&c, check_string(parser, type, &f[0], o, n)))) 593 return r; 594 595 if (c != n) 596 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 597 return accept_rr(parser, type, rdata); 598 } 599 600 nonnull_all 601 static int32_t parse_x25_rdata( 602 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 603 { 604 int32_t code; 605 const rdata_info_t *fields = type->rdata.fields; 606 607 if ((code = have_contiguous_or_quoted(parser, type, &fields[0], token)) < 0) 608 return code; 609 if ((code = parse_string(parser, type, &fields[0], rdata, token)) < 0) 610 return code; 611 if ((code = take_delimiter(parser, type, token)) < 0) 612 return code; 613 return accept_rr(parser, type, rdata); 614 } 615 616 nonnull_all 617 static int32_t check_isdn_rr( 618 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 619 { 620 int32_t r; 621 size_t c = 0; 622 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 623 const uint8_t *o = parser->rdata->octets; 624 const rdata_info_t *f = type->rdata.fields; 625 626 if ((r = check(&c, check_string(parser, type, &f[0], o, n)))) 627 return r; 628 // subaddress is optional 629 if (c < n && (r = check(&c, check_string(parser, type, &f[1], o+c, n-c)))) 630 return r; 631 632 if (c != n) 633 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 634 return accept_rr(parser, type, rdata); 635 } 636 637 nonnull_all 638 static int32_t parse_isdn_rdata( 639 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 640 { 641 int32_t code; 642 const rdata_info_t *fields = type->rdata.fields; 643 644 if ((code = have_contiguous_or_quoted(parser, type, &fields[0], token)) < 0) 645 return code; 646 if ((code = parse_string(parser, type, &fields[0], rdata, token)) < 0) 647 return code; 648 649 // subaddress is optional 650 take(parser, token); 651 if (is_contiguous_or_quoted(token)) { 652 if ((code = parse_string(parser, type, &fields[1], rdata, token)) < 0) 653 return code; 654 take(parser, token); 655 } 656 657 if ((code = have_delimiter(parser, type, token)) < 0) 658 return code; 659 return accept_rr(parser, type, rdata); 660 } 661 662 nonnull_all 663 static int32_t check_rt_rr( 664 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 665 { 666 int32_t r; 667 size_t c = 0; 668 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 669 const uint8_t *o = parser->rdata->octets; 670 const rdata_info_t *f = type->rdata.fields; 671 672 if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) || 673 (r = check(&c, check_name(parser, type, &f[1], o+c, n-c)))) 674 return r; 675 676 if (c != n) 677 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 678 return accept_rr(parser, type, rdata); 679 } 680 681 nonnull_all 682 static int32_t parse_rt_rdata( 683 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 684 { 685 int32_t code; 686 const rdata_info_t *fields = type->rdata.fields; 687 688 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 689 return code; 690 if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0) 691 return code; 692 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 693 return code; 694 if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0) 695 return code; 696 if ((code = take_delimiter(parser, type, token)) < 0) 697 return code; 698 return accept_rr(parser, type, rdata); 699 } 700 701 nonnull_all 702 static int32_t check_nsap_rr( 703 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 704 { 705 if (rdata->octets == parser->rdata->octets) 706 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 707 return accept_rr(parser, type, rdata); 708 } 709 710 nonnull_all 711 static int32_t parse_nsap_rdata( 712 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 713 { 714 int32_t code; 715 const rdata_info_t *fields = type->rdata.fields; 716 717 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 718 return code; 719 if ((code = parse_nsap(parser, type, &fields[0], rdata, token)) < 0) 720 return code; 721 if ((code = take_delimiter(parser, type, token)) < 0) 722 return code; 723 return accept_rr(parser, type, rdata); 724 } 725 726 nonnull_all 727 static int32_t check_nsap_ptr_rr( 728 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 729 { 730 { 731 int32_t r; 732 size_t c = 0; 733 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 734 const uint8_t *o = parser->rdata->octets; 735 const rdata_info_t *f = type->rdata.fields; 736 737 if ((r = check(&c, check_string(parser, type, &f[0], o, n)))) 738 return r; 739 740 if (c != n) 741 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 742 } 743 744 { 745 // RFC1706 section 6 746 // A domain name is generated from an NSAP by reversing the hex nibbles of 747 // the NSAP, treating each nibble as a separate subdomain, and appending 748 // the top-level subdomain name "NSAP.INT" to it. For example, the domain 749 // name used in the reverse lookup for the NSAP 750 // 751 // 47.0005.80.005a00.0000.0001.e133.ffffff000162.00 752 // 753 // would appear as 754 // 755 // 0.0.2.6.1.0.0.0.f.f.f.f.f.f.3.3.1.e.1.0.0.0.0.0.0.0.0.0.a.5.0.0. 756 // 0.8.5.0.0.0.7.4.NSAP.INT. 757 size_t i = 0; 758 const size_t n = parser->file->owner.length; 759 const uint8_t *o = parser->file->owner.octets; 760 for (; i < n; i += 2) 761 if (o[i] != 1 || (base16_table_dec_32bit_d1[o[i+1]] > 0xff)) 762 break; 763 764 const uint8_t nsap_int[] = { 4, 'n', 's', 'a', 'p', 3, 'i', 'n', 't', 0 }; 765 if (strncasecmp((const char *)o + i, (const char *)nsap_int, 9) != 0 || !i || i + 10 != n) 766 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 767 } 768 769 return accept_rr(parser, type, rdata); 770 } 771 772 nonnull_all 773 static int32_t parse_nsap_ptr_rdata( 774 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 775 { 776 int32_t code; 777 const rdata_info_t *fields = type->rdata.fields; 778 779 if ((code = have_contiguous_or_quoted(parser, type, &fields[0], token)) < 0) 780 return code; 781 if ((code = parse_string(parser, type, &fields[0], rdata, token)) < 0) 782 return code; 783 if ((code = take_delimiter(parser, type, token)) < 0) 784 return code; 785 786 // RFC1706 section 6 states each nibble is treated as a separate subdomain 787 return check_nsap_ptr_rr(parser, type, rdata); 788 } 789 790 nonnull_all 791 static int32_t check_key_rr( 792 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 793 { 794 #if 0 795 int32_t r; 796 size_t c = 0; 797 const size_t n = parser->rdata->length; 798 const uint8_t *o = parser->rdata->octets; 799 const rdata_info_t *f = type->rdata.fields; 800 801 // 802 // FIXME: implement (RFC2065) 803 // 804 // FIXME: verify the flag, algorithm and protocol combination is valid 805 // FIXME: verify the key is valid for type(3)+algorithm(1) 806 // 807 // The combination is of course subject to secondary checks! 808 // 809 #endif 810 (void)type; 811 return accept_rr(parser, type, rdata); 812 } 813 814 nonnull_all 815 static int32_t parse_key_rdata( 816 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 817 { 818 int32_t code; 819 const rdata_info_t *fields = type->rdata.fields; 820 821 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 822 return code; 823 if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0) 824 return code; 825 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 826 return code; 827 if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0) 828 return code; 829 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 830 return code; 831 if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0) 832 return code; 833 take(parser, token); 834 if ((code = parse_base64_sequence(parser, type, &fields[3], rdata, token)) < 0) 835 return code; 836 837 return check_key_rr(parser, type, rdata); 838 } 839 840 nonnull_all 841 static int32_t check_px_rr( 842 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 843 { 844 int32_t r; 845 size_t c = 0; 846 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 847 const uint8_t *o = parser->rdata->octets; 848 const rdata_info_t *f = type->rdata.fields; 849 850 if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) || 851 (r = check(&c, check_name(parser, type, &f[1], o+c, n-c))) || 852 (r = check(&c, check_name(parser, type, &f[2], o+c, n-c)))) 853 return r; 854 855 if (c != n) 856 SYNTAX_ERROR(parser, "Invalid %s record", NAME(type)); 857 return accept_rr(parser, type, rdata); 858 } 859 860 nonnull_all 861 static int32_t parse_px_rdata( 862 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 863 { 864 int32_t code; 865 const rdata_info_t *fields = type->rdata.fields; 866 867 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 868 return code; 869 if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0) 870 return code; 871 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 872 return code; 873 if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0) 874 return code; 875 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 876 return code; 877 if ((code = parse_name(parser, type, &fields[2], rdata, token)) < 0) 878 return code; 879 if ((code = take_delimiter(parser, type, token)) < 0) 880 return code; 881 return accept_rr(parser, type, rdata); 882 } 883 884 nonnull_all 885 static int32_t check_gpos_rr( 886 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 887 { 888 int32_t r; 889 size_t c = 0; 890 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 891 const uint8_t *o = parser->rdata->octets; 892 const rdata_info_t *f = type->rdata.fields; 893 894 if ((r = check(&c, check_string(parser, type, &f[0], o, n))) || 895 (r = check(&c, check_string(parser, type, &f[1], o+c, n-c))) || 896 (r = check(&c, check_string(parser, type, &f[2], o+c, n-c)))) 897 return r; 898 899 if (c != n) 900 SYNTAX_ERROR(parser, "Invalid %s record", NAME(type)); 901 return accept_rr(parser, type, rdata); 902 } 903 904 static int32_t parse_gpos_rdata( 905 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 906 { 907 int32_t code; 908 const rdata_info_t *fields = type->rdata.fields; 909 910 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 911 return code; 912 if ((code = parse_latitude(parser, type, &fields[0], rdata, token)) < 0) 913 return code; 914 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 915 return code; 916 if ((code = parse_longitude(parser, type, &fields[1], rdata, token)) < 0) 917 return code; 918 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 919 return code; 920 if ((code = parse_altitude(parser, type, &fields[2], rdata, token)) < 0) 921 return code; 922 if ((code = take_delimiter(parser, type, token)) < 0) 923 return code; 924 return accept_rr(parser, type, rdata); 925 } 926 927 nonnull_all 928 static int32_t check_aaaa_rr( 929 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 930 { 931 int32_t r; 932 size_t c = 0; 933 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 934 const uint8_t *o = parser->rdata->octets; 935 const rdata_info_t *f = type->rdata.fields; 936 937 if ((r = check(&c, check_ip6(parser, type, &f[0], o, n)))) 938 return r; 939 940 if (c != n) 941 SYNTAX_ERROR(parser, "Invalid %s record", NAME(type)); 942 return accept_rr(parser, type, rdata); 943 } 944 945 nonnull_all 946 static int32_t parse_aaaa_rdata( 947 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 948 { 949 int32_t code; 950 const rdata_info_t *fields = type->rdata.fields; 951 952 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 953 return code; 954 if ((code = parse_ip6(parser, type, &fields[0], rdata, token)) < 0) 955 return code; 956 if ((code = take_delimiter(parser, type, token)) < 0) 957 return code; 958 return accept_rr(parser, type, rdata); 959 } 960 961 nonnull_all 962 static int32_t check_loc_rr( 963 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 964 { 965 if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets != 16) 966 SYNTAX_ERROR(parser, "Invalid %s record", NAME(type)); 967 return accept_rr(parser, type, rdata); 968 969 // FIXME: check validity of latitude, longitude and latitude? 970 } 971 972 nonnull_all 973 static int32_t parse_loc_rdata( 974 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 975 { 976 int32_t code; 977 uint32_t degrees, minutes, seconds; 978 uint32_t latitude, longitude, altitude; 979 const rdata_info_t *fields = type->rdata.fields; 980 static const uint8_t defaults[4] = { 0x00, 0x12, 0x16, 0x13 }; 981 982 // RFC1876 section 3: 983 // If omitted, minutes and seconds default to zero, size defaults to 1m, 984 // horizontal precision defaults to 10000m, and vertical precision defaults 985 // to 10m. 986 memcpy(rdata->octets, &defaults, sizeof(defaults)); 987 988 // latitude 989 if ((code = have_contiguous(parser, type, &fields[4], token)) < 0) 990 return code; 991 if (scan_degrees(token->data, token->length, °rees) == -1) 992 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[4]), NAME(type)); 993 if ((code = take_contiguous(parser, type, &fields[4], token)) < 0) 994 return code; 995 if (scan_minutes(token->data, token->length, &minutes) == -1) 996 goto north_south; // minutes default to zero 997 degrees += minutes; 998 if ((code = take_contiguous(parser, type, &fields[4], token)) < 0) 999 return code; 1000 if (scan_seconds(token->data, token->length, &seconds) == -1) 1001 goto north_south; // seconds default to zero 1002 degrees += seconds; 1003 1004 if ((code = take_contiguous(parser, type, &fields[4], token)) < 0) 1005 return code; 1006 north_south: 1007 if (token->data[0] == 'N') 1008 latitude = htobe32((1u<<31) + degrees); 1009 else if (token->data[0] == 'S') 1010 latitude = htobe32((1u<<31) - degrees); 1011 else 1012 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[4]), NAME(type)); 1013 1014 memcpy(&rdata->octets[4], &latitude, sizeof(latitude)); 1015 1016 // longitude 1017 if ((code = take_contiguous(parser, type, &fields[5], token)) < 0) 1018 return code; 1019 if (scan_degrees(token->data, token->length, °rees) == -1) 1020 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[5]), NAME(type)); 1021 if ((code = take_contiguous(parser, type, &fields[5], token)) < 0) 1022 return code; 1023 if (scan_minutes(token->data, token->length, &minutes) == -1) 1024 goto east_west; // minutes default to zero 1025 degrees += minutes; 1026 if ((code = take_contiguous(parser, type, &fields[5], token)) < 0) 1027 return code; 1028 if (scan_seconds(token->data, token->length, &seconds) == -1) 1029 goto east_west; // seconds default to zero 1030 degrees += seconds; 1031 1032 if ((code = take_contiguous(parser, type, &fields[5], token)) < 0) 1033 return code; 1034 east_west: 1035 if (token->data[0] == 'E') 1036 longitude = htobe32((1u<<31) + degrees); 1037 else if (token->data[0] == 'W') 1038 longitude = htobe32((1u<<31) - degrees); 1039 else 1040 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[5]), NAME(type)); 1041 1042 memcpy(&rdata->octets[8], &longitude, sizeof(longitude)); 1043 1044 // altitude 1045 if ((code = take_contiguous(parser, type, &fields[6], token)) < 0) 1046 return code; 1047 if (scan_altitude(token->data, token->length, &altitude) == -1) 1048 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[6]), NAME(type)); 1049 1050 altitude = htobe32(altitude); 1051 memcpy(&rdata->octets[12], &altitude, sizeof(altitude)); 1052 1053 // size 1054 take(parser, token); 1055 if (!is_contiguous(token)) 1056 goto skip_optional; 1057 if (scan_precision(token->data, token->length, &rdata->octets[1])) 1058 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[1]), NAME(type)); 1059 1060 // horizontal precision 1061 take(parser, token); 1062 if (!is_contiguous(token)) 1063 goto skip_optional; 1064 if (scan_precision(token->data, token->length, &rdata->octets[2])) 1065 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[2]), NAME(type)); 1066 1067 // vertical precision 1068 take(parser, token); 1069 if (!is_contiguous(token)) 1070 goto skip_optional; 1071 if (scan_precision(token->data, token->length, &rdata->octets[3])) 1072 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[3]), NAME(type)); 1073 1074 take(parser, token); 1075 skip_optional: 1076 if ((code = have_delimiter(parser, type, token)) < 0) 1077 return code; 1078 1079 rdata->octets += 16; 1080 return accept_rr(parser, type, rdata); 1081 } 1082 1083 nonnull_all 1084 static int32_t check_nxt_rr( 1085 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1086 { 1087 int32_t r; 1088 size_t c = 0; 1089 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 1090 const uint8_t *o = parser->rdata->octets; 1091 const rdata_info_t *f = type->rdata.fields; 1092 1093 if ((r = check(&c, check_name(parser, type, &f[0], o+c, n-c)))) 1094 return r; 1095 1096 return accept_rr(parser, type, rdata); 1097 } 1098 1099 nonnull_all 1100 static int32_t parse_nxt_rdata( 1101 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1102 { 1103 int32_t code; 1104 const rdata_info_t *fields = type->rdata.fields; 1105 1106 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 1107 return code; 1108 if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0) 1109 return code; 1110 take(parser, token); 1111 if ((code = parse_nxt(parser, type, &fields[1], rdata, token)) < 0) 1112 return code; 1113 1114 return accept_rr(parser, type, rdata); 1115 } 1116 1117 nonnull_all 1118 static int32_t check_eid_rr( 1119 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1120 { 1121 if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets <= 0) 1122 SYNTAX_ERROR(parser, "Invalid %s record", NAME(type)); 1123 return accept_rr(parser, type, rdata); 1124 } 1125 1126 nonnull_all 1127 static int32_t parse_eid_rdata( 1128 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1129 { 1130 int32_t code; 1131 const rdata_info_t *fields = type->rdata.fields; 1132 1133 if ((code = parse_base16_sequence(parser, type, &fields[1], rdata, token)) < 0) 1134 return code; 1135 return check_eid_rr(parser, type, rdata); 1136 } 1137 1138 nonnull_all 1139 static int32_t check_srv_rr( 1140 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1141 { 1142 int32_t r; 1143 size_t c = 0; 1144 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 1145 const uint8_t *o = parser->rdata->octets; 1146 const rdata_info_t *f = type->rdata.fields; 1147 1148 if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) || 1149 (r = check(&c, check_int16(parser, type, &f[1], o+c, n-c))) || 1150 (r = check(&c, check_int16(parser, type, &f[2], o+c, n-c))) || 1151 (r = check(&c, check_name(parser, type, &f[3], o+c, n-c)))) 1152 return r; 1153 1154 if (c != n) 1155 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 1156 return accept_rr(parser, type, rdata); 1157 } 1158 1159 nonnull_all 1160 static int32_t parse_srv_rdata( 1161 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1162 { 1163 int32_t code; 1164 const rdata_info_t *fields = type->rdata.fields; 1165 1166 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 1167 return code; 1168 if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0) 1169 return code; 1170 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 1171 return code; 1172 if ((code = parse_int16(parser, type, &fields[1], rdata, token)) < 0) 1173 return code; 1174 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 1175 return code; 1176 if ((code = parse_int16(parser, type, &fields[2], rdata, token)) < 0) 1177 return code; 1178 if ((code = take_contiguous(parser, type, &fields[3], token)) < 0) 1179 return code; 1180 if ((code = parse_name(parser, type, &fields[3], rdata, token)) < 0) 1181 return code; 1182 if ((code = take_delimiter(parser, type, token)) < 0) 1183 return code; 1184 return accept_rr(parser, type, rdata); 1185 } 1186 1187 nonnull_all 1188 static int32_t check_atma_rr( 1189 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1190 { 1191 assert(rdata->octets >= parser->rdata->octets); 1192 if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets > 2) 1193 return accept_rr(parser, type, rdata); 1194 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 1195 } 1196 1197 nonnull_all 1198 static int32_t parse_atma_rdata( 1199 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1200 { 1201 int32_t code; 1202 const rdata_info_t *fields = type->rdata.fields; 1203 1204 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 1205 return code; 1206 if ((code = parse_atma(parser, type, &fields[0], rdata, token)) < 0) 1207 return code; 1208 if ((code = take_delimiter(parser, type, token)) < 0) 1209 return code; 1210 return accept_rr(parser, type, rdata); 1211 } 1212 1213 nonnull_all 1214 static int32_t check_naptr_rr( 1215 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1216 { 1217 // FIXME: implement actual checks 1218 (void)type; 1219 return accept_rr(parser, type, rdata); 1220 } 1221 1222 nonnull_all 1223 static int32_t parse_naptr_rdata( 1224 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1225 { 1226 int32_t code; 1227 const rdata_info_t *fields = type->rdata.fields; 1228 1229 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 1230 return code; 1231 if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0) 1232 return code; 1233 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 1234 return code; 1235 if ((code = parse_int16(parser, type, &fields[1], rdata, token)) < 0) 1236 return code; 1237 if ((code = take_quoted_or_contiguous(parser, type, &fields[2], token)) < 0) 1238 return code; 1239 if ((code = parse_string(parser, type, &fields[2], rdata, token)) < 0) 1240 return code; 1241 if ((code = take_quoted_or_contiguous(parser, type, &fields[3], token)) < 0) 1242 return code; 1243 if ((code = parse_string(parser, type, &fields[3], rdata, token)) < 0) 1244 return code; 1245 if ((code = take_quoted_or_contiguous(parser, type, &fields[4], token)) < 0) 1246 return code; 1247 if ((code = parse_string(parser, type, &fields[4], rdata, token)) < 0) 1248 return code; 1249 if ((code = take_contiguous(parser, type, &fields[5], token)) < 0) 1250 return code; 1251 if ((code = parse_name(parser, type, &fields[5], rdata, token)) < 0) 1252 return code; 1253 if ((code = take_delimiter(parser, type, token)) < 0) 1254 return code; 1255 return accept_rr(parser, type, rdata); 1256 } 1257 1258 nonnull_all 1259 static int32_t check_cert_rr( 1260 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1261 { 1262 // FIXME: implement actual checks 1263 (void)type; 1264 1265 assert(rdata->octets >= parser->rdata->octets); 1266 if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets < 6) 1267 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 1268 return accept_rr(parser, type, rdata); 1269 } 1270 1271 nonnull_all 1272 static int32_t parse_cert_rdata( 1273 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1274 { 1275 int32_t code; 1276 const rdata_info_t *fields = type->rdata.fields; 1277 1278 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 1279 return code; 1280 if ((code = parse_certificate_type(parser, type, &fields[0], rdata, token)) < 0) 1281 return code; 1282 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 1283 return code; 1284 if ((code = parse_int16(parser, type, &fields[1], rdata, token)) < 0) 1285 return code; 1286 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 1287 return code; 1288 if ((code = parse_algorithm(parser, type, &fields[2], rdata, token)) < 0) 1289 return code; 1290 take(parser, token); 1291 if ((code = parse_base64_sequence(parser, type, &fields[3], rdata, token)) < 0) 1292 return code; 1293 1294 return accept_rr(parser, type, rdata); 1295 } 1296 1297 nonnull_all 1298 static int32_t check_sink_rr( 1299 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1300 { 1301 // FIXME: implement actual checks 1302 (void)type; 1303 1304 assert(rdata->octets >= parser->rdata->octets); 1305 if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets < 3) 1306 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 1307 return accept_rr(parser, type, rdata); 1308 } 1309 1310 nonnull_all 1311 static int32_t parse_sink_rdata( 1312 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1313 { 1314 int32_t code; 1315 const rdata_info_t *fields = type->rdata.fields; 1316 1317 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 1318 return code; 1319 if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0) 1320 return code; 1321 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 1322 return code; 1323 if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0) 1324 return code; 1325 take(parser, token); 1326 if ((code = parse_base64_sequence(parser, type, &fields[3], rdata, token)) < 0) 1327 return code; 1328 1329 return accept_rr(parser, type, rdata); 1330 } 1331 1332 nonnull_all 1333 static int32_t check_apl_rr( 1334 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1335 { 1336 // FIXME: check correctness of fields and total length 1337 return accept_rr(parser, type, rdata); 1338 } 1339 1340 nonnull_all 1341 static int32_t parse_apl_rdata( 1342 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1343 { 1344 int32_t code; 1345 const rdata_info_t *fields = type->rdata.fields; 1346 1347 // RDATA section for APL consists of zero or more fields 1348 while (is_contiguous(token)) { 1349 int32_t length; 1350 const size_t size = (uintptr_t)rdata->limit - (uintptr_t)rdata->octets; 1351 if ((length = scan_apl(token->data, token->length, rdata->octets, size)) < 0) 1352 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[0]), NAME(type)); 1353 assert(length == 8 /* ipv4 */ || length == 20 /* ipv6 */); 1354 rdata->octets += (size_t)length; 1355 take(parser, token); 1356 } 1357 1358 if ((code = have_delimiter(parser, type, token)) < 0) 1359 return code; 1360 return accept_rr(parser, type, rdata); 1361 } 1362 1363 nonnull_all 1364 static int32_t check_ds_rr( 1365 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1366 { 1367 int32_t r; 1368 size_t c = 0; 1369 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 1370 const uint8_t *o = parser->rdata->octets; 1371 const rdata_info_t *f = type->rdata.fields; 1372 1373 if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) || 1374 (r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) || 1375 (r = check(&c, check_int8(parser, type, &f[2], o+c, n-c)))) 1376 return r; 1377 1378 const uint8_t digest_algorithm = parser->rdata->octets[3]; 1379 1380 if ((digest_algorithm & 0x7) == digest_algorithm) { 1381 // https://www.iana.org/assignments/ds-rr-types 1382 static const uint8_t digest_sizes[8] = { 1383 0, // 0: Reserved 1384 20, // 1: SHA-1 1385 32, // 2: SHA-256 1386 32, // 3: GOST R 34.11-94 1387 48, // 4: SHA-384 1388 32, // 5: GOST R 34.10-2012 1389 32, // 6: SM3 1390 0 // 7: Unassigned 1391 }; 1392 1393 const uint8_t digest_size = digest_sizes[ digest_algorithm ]; 1394 1395 if (digest_size && n - 4 != digest_size) 1396 SEMANTIC_ERROR(parser, "Invalid digest in %s", NAME(type)); 1397 } 1398 1399 if (c > n) 1400 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 1401 return accept_rr(parser, type, rdata); 1402 } 1403 1404 nonnull_all 1405 static int32_t parse_ds_rdata( 1406 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1407 { 1408 int32_t code; 1409 const rdata_info_t *fields = type->rdata.fields; 1410 1411 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 1412 return code; 1413 if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0) 1414 return code; 1415 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 1416 return code; 1417 if ((code = parse_algorithm(parser, type, &fields[1], rdata, token)) < 0) 1418 return code; 1419 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 1420 return code; 1421 if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0) 1422 return code; 1423 take(parser, token); 1424 if (!(token->length == 1 && (char)*token->data == '0') 1425 && (code = parse_base16_sequence(parser, type, &fields[3], rdata, token)) < 0) 1426 return code; 1427 1428 const uint8_t digest_algorithm = parser->rdata->octets[3]; 1429 1430 if ((digest_algorithm & 0x7) == digest_algorithm) { 1431 // https://www.iana.org/assignments/ds-rr-types 1432 static const uint8_t digest_sizes[8] = { 1433 0, // 0: Reserved 1434 20, // 1: SHA-1 1435 32, // 2: SHA-256 1436 32, // 3: GOST R 34.11-94 1437 48, // 4: SHA-384 1438 32, // 5: GOST R 34.10-2012 1439 32, // 6: SM3 1440 0 // 7: Unassigned 1441 }; 1442 1443 const uint8_t digest_size = digest_sizes[ digest_algorithm ]; 1444 size_t length = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 1445 1446 if (digest_size && length - 4 != digest_size) 1447 SEMANTIC_ERROR(parser, "Invalid digest in %s", NAME(type)); 1448 } 1449 1450 return accept_rr(parser, type, rdata); 1451 } 1452 1453 nonnull_all 1454 static int32_t check_sshfp_rr( 1455 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1456 { 1457 int32_t r; 1458 size_t c = 0; 1459 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 1460 const uint8_t *o = parser->rdata->octets; 1461 const rdata_info_t *f = type->rdata.fields; 1462 1463 if ((r = check(&c, check_int8(parser, type, &f[0], o, n))) || 1464 (r = check(&c, check_int8(parser, type, &f[1], o+c, n-c)))) 1465 return r; 1466 1467 // https://www.iana.org/assignments/dns-sshfp-rr-parameters 1468 1469 if (c == n) 1470 SYNTAX_ERROR(parser, "Missing %s in %s", NAME((&f[n!=0])), NAME(type)); 1471 else if (o[1] == 1 && (n - c) != 20) 1472 SEMANTIC_ERROR(parser, "Wrong fingerprint size for type %s in %s", 1473 "SHA1", NAME(type)); 1474 else if (o[1] == 2 && (n - c) != 32) 1475 SEMANTIC_ERROR(parser, "Wrong fingerprint size for type %s in %s", 1476 "SHA256", NAME(type)); 1477 1478 return accept_rr(parser, type, rdata); 1479 } 1480 1481 nonnull_all 1482 static int32_t parse_sshfp_rdata( 1483 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1484 { 1485 int32_t code; 1486 const rdata_info_t *fields = type->rdata.fields; 1487 1488 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 1489 return code; 1490 if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0) 1491 return code; 1492 1493 const uint8_t *fingerprint_type = rdata->octets; 1494 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 1495 return code; 1496 if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0) 1497 return code; 1498 1499 const uint8_t *fingerprint = rdata->octets; 1500 take(parser, token); 1501 if ((code = parse_base16_sequence(parser, type, &fields[2], rdata, token)) < 0) 1502 return code; 1503 1504 // https://www.iana.org/assignments/dns-sshfp-rr-parameters 1505 size_t fingerprint_size = (uintptr_t)rdata->octets - (uintptr_t)fingerprint; 1506 if (unlikely(*fingerprint_type == 1 && fingerprint_size != 20)) 1507 SEMANTIC_ERROR(parser, "Wrong fingerprint size for type %s in %s", 1508 "SHA1", NAME(type)); 1509 if (unlikely(*fingerprint_type == 2 && fingerprint_size != 32)) 1510 SEMANTIC_ERROR(parser, "Wrong fingerprint size for type %s in %s", 1511 "SHA256", NAME(type)); 1512 1513 return accept_rr(parser, type, rdata); 1514 } 1515 1516 nonnull_all 1517 static int32_t check_ipseckey_rr( 1518 parser_t *parser, const type_info_t *type, const rdata_t *rdata); 1519 1520 nonnull_all 1521 static int32_t parse_ipseckey_rdata( 1522 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token); 1523 1524 diagnostic_push() 1525 gcc_diagnostic_ignored(missing-field-initializers) 1526 clang_diagnostic_ignored(missing-field-initializers) 1527 1528 static const rdata_info_t ipseckey_ipv4_rdata_fields[] = { 1529 FIELD("precedence"), 1530 FIELD("gateway type"), 1531 FIELD("algorithm"), 1532 FIELD("gateway"), 1533 FIELD("public key") 1534 }; 1535 1536 static const type_info_t ipseckey_ipv4[] = { 1537 TYPE("IPSECKEY", ZONE_TYPE_IPSECKEY, ZONE_CLASS_IN, FIELDS(ipseckey_ipv4_rdata_fields), 1538 check_ipseckey_rr, parse_ipseckey_rdata), 1539 }; 1540 1541 static const rdata_info_t ipseckey_ipv6_rdata_fields[] = { 1542 FIELD("precedence"), 1543 FIELD("gateway type"), 1544 FIELD("algorithm"), 1545 FIELD("gateway"), 1546 FIELD("public key") 1547 }; 1548 1549 static const type_info_t ipseckey_ipv6[] = { 1550 TYPE("IPSECKEY", ZONE_TYPE_IPSECKEY, ZONE_CLASS_IN, FIELDS(ipseckey_ipv6_rdata_fields), 1551 check_ipseckey_rr, parse_ipseckey_rdata), 1552 }; 1553 1554 diagnostic_pop() 1555 1556 nonnull_all 1557 static int32_t check_ipseckey_rr( 1558 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1559 { 1560 int32_t r; 1561 size_t c = 0; 1562 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 1563 const uint8_t *o = parser->rdata->octets; 1564 const type_info_t *t = type; 1565 const rdata_info_t *f = type->rdata.fields; 1566 1567 if ((r = check(&c, check_int8(parser, type, &f[0], o, n))) || 1568 (r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) || 1569 (r = check(&c, check_int8(parser, type, &f[2], o+c, n-c)))) 1570 return r; 1571 1572 switch (parser->rdata->octets[1]) { 1573 case 1: /* IPv4 address */ 1574 t = (const type_info_t *)ipseckey_ipv4; 1575 f = ipseckey_ipv4_rdata_fields; 1576 if ((r = check(&c, check_ip4(parser, t, &f[3], o+c, n-c))) < 0) 1577 return r; 1578 break; 1579 case 2: /* IPv6 address */ 1580 t = (const type_info_t *)ipseckey_ipv6; 1581 f = ipseckey_ipv6_rdata_fields; 1582 if ((r = check(&c, check_ip6(parser, t, &f[3], o+c, n-c))) < 0) 1583 return r; 1584 break; 1585 case 0: /* no gateway */ 1586 break; 1587 case 3: /* domain name */ 1588 if ((r = check(&c, check_name(parser, t, &f[3], o+c, n-c))) < 0) 1589 return r; 1590 break; 1591 default: 1592 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 1593 } 1594 1595 switch (parser->rdata->octets[2]) { 1596 case 0: 1597 if (c < n) 1598 SYNTAX_ERROR(parser, "Trailing data in %s", NAME(t)); 1599 break; 1600 default: 1601 if (c >= n) 1602 SYNTAX_ERROR(parser, "Missing %s in %s", NAME(&f[4]), NAME(t)); 1603 break; 1604 } 1605 1606 return accept_rr(parser, t, rdata); 1607 } 1608 1609 nonnull_all 1610 static int32_t parse_ipseckey_rdata( 1611 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1612 { 1613 int32_t code; 1614 const rdata_info_t *fields = type->rdata.fields; 1615 uint8_t *octets = rdata->octets; 1616 1617 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 1618 return code; 1619 if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0) 1620 return code; 1621 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 1622 return code; 1623 if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0) 1624 return code; 1625 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 1626 return code; 1627 if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0) 1628 return code; 1629 if ((code = take_contiguous(parser, type, &fields[3], token)) < 0) 1630 return code; 1631 1632 switch (octets[1]) { 1633 case 0: /* no gateway */ 1634 if (token->length != 1 || token->data[0] != '.') 1635 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[3]), NAME(type)); 1636 break; 1637 case 1: /* IPv4 address */ 1638 type = (const type_info_t *)ipseckey_ipv4; 1639 fields = type->rdata.fields; 1640 if ((code = parse_ip4(parser, type, &fields[3], rdata, token)) < 0) 1641 return code; 1642 break; 1643 case 2: /* IPv6 address */ 1644 type = (const type_info_t *)ipseckey_ipv6; 1645 fields = type->rdata.fields; 1646 if ((code = parse_ip6(parser, type, &fields[3], rdata, token)) < 0) 1647 return code; 1648 break; 1649 case 3: /* domain name */ 1650 if ((code = parse_name(parser, type, &fields[3], rdata, token)) < 0) 1651 return code; 1652 break; 1653 default: 1654 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[3]), NAME(type)); 1655 } 1656 1657 take(parser, token); 1658 switch (octets[2]) { 1659 case 0: 1660 if ((code = have_delimiter(parser, type, token)) < 0) 1661 return code; 1662 break; 1663 default: 1664 if ((code = parse_base64_sequence(parser, type, &fields[4], rdata, token)) < 0) 1665 return code; 1666 break; 1667 } 1668 1669 return accept_rr(parser, type, rdata); 1670 } 1671 1672 nonnull_all 1673 static int32_t check_rrsig_rr( 1674 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1675 { 1676 int32_t r; 1677 size_t c = 0; 1678 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 1679 const uint8_t *o = parser->rdata->octets; 1680 const rdata_info_t *f = type->rdata.fields; 1681 1682 if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) || 1683 (r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) || 1684 (r = check(&c, check_int8(parser, type, &f[2], o+c, n-c))) || 1685 (r = check(&c, check_ttl(parser, type, &f[3], o+c, n-c))) || 1686 (r = check(&c, check_int32(parser, type, &f[4], o+c, n-c))) || 1687 (r = check(&c, check_int32(parser, type, &f[5], o+c, n-c))) || 1688 (r = check(&c, check_int16(parser, type, &f[6], o+c, n-c))) || 1689 (r = check(&c, check_name(parser, type, &f[7], o+c, n-c)))) 1690 return r; 1691 1692 if (c > n) 1693 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 1694 return accept_rr(parser, type, rdata); 1695 } 1696 1697 nonnull_all 1698 static int32_t parse_rrsig_rdata( 1699 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1700 { 1701 int32_t code; 1702 const rdata_info_t *fields = type->rdata.fields; 1703 1704 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 1705 return code; 1706 if ((code = parse_type(parser, type, &fields[0], rdata, token)) < 0) 1707 return code; 1708 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 1709 return code; 1710 if ((code = parse_algorithm(parser, type, &fields[1], rdata, token)) < 0) 1711 return code; 1712 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 1713 return code; 1714 if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0) 1715 return code; 1716 if ((code = take_contiguous(parser, type, &fields[3], token)) < 0) 1717 return code; 1718 if ((code = parse_ttl(parser, type, &fields[3], rdata, token)) < 0) 1719 return code; 1720 if ((code = take_contiguous(parser, type, &fields[4], token)) < 0) 1721 return code; 1722 if ((code = parse_time(parser, type, &fields[4], rdata, token)) < 0) 1723 return code; 1724 if ((code = take_contiguous(parser, type, &fields[5], token)) < 0) 1725 return code; 1726 if ((code = parse_time(parser, type, &fields[5], rdata, token)) < 0) 1727 return code; 1728 if ((code = take_contiguous(parser, type, &fields[6], token)) < 0) 1729 return code; 1730 if ((code = parse_int16(parser, type, &fields[6], rdata, token)) < 0) 1731 return code; 1732 if ((code = take_contiguous(parser, type, &fields[7], token)) < 0) 1733 return code; 1734 if ((code = parse_name(parser, type, &fields[7], rdata, token)) < 0) 1735 return code; 1736 take(parser, token); 1737 if ((code = parse_base64_sequence(parser, type, &fields[8], rdata, token)) < 0) 1738 return code; 1739 1740 return accept_rr(parser, type, rdata); 1741 } 1742 1743 nonnull_all 1744 static int32_t check_nsec_rr( 1745 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1746 { 1747 int32_t r; 1748 size_t c = 0; 1749 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 1750 const uint8_t *o = parser->rdata->octets; 1751 const rdata_info_t *f = type->rdata.fields; 1752 1753 if ((r = check(&c, check_name(parser, type, &f[0], o, n))) || 1754 (r = check(&c, check_nsec(parser, type, &f[1], o+c, n-c)))) 1755 return r; 1756 1757 if (c != n) 1758 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 1759 return accept_rr(parser, type, rdata); 1760 } 1761 1762 nonnull_all 1763 static int32_t parse_nsec_rdata( 1764 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1765 { 1766 int32_t code; 1767 const rdata_info_t *fields = type->rdata.fields; 1768 1769 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 1770 return code; 1771 if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0) 1772 return code; 1773 take(parser, token); 1774 if ((code = parse_nsec(parser, type, &fields[1], rdata, token)) < 0) 1775 return code; 1776 1777 return accept_rr(parser, type, rdata); 1778 } 1779 1780 nonnull_all 1781 static int32_t check_dnskey_rr( 1782 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1783 { 1784 int32_t r; 1785 size_t c = 0; 1786 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 1787 const uint8_t *o = parser->rdata->octets; 1788 const rdata_info_t *f = type->rdata.fields; 1789 1790 if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) || 1791 (r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) || 1792 (r = check(&c, check_int8(parser, type, &f[2], o+c, n-c)))) 1793 return r; 1794 1795 if (c > n) 1796 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 1797 return accept_rr(parser, type, rdata); 1798 } 1799 1800 nonnull_all 1801 static int32_t parse_dnskey_rdata( 1802 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1803 { 1804 int32_t code; 1805 const rdata_info_t *fields = type->rdata.fields; 1806 1807 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 1808 return code; 1809 if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0) 1810 return code; 1811 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 1812 return code; 1813 if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0) 1814 return code; 1815 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 1816 return code; 1817 if ((code = parse_algorithm(parser, type, &fields[2], rdata, token)) < 0) 1818 return code; 1819 take(parser, token); 1820 if (!(token->length == 1 && (char)*token->data == '0') 1821 && (code = parse_base64_sequence(parser, type, &fields[3], rdata, token)) < 0) 1822 return code; 1823 1824 return accept_rr(parser, type, rdata); 1825 } 1826 1827 nonnull_all 1828 static int32_t check_dhcid_rr( 1829 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1830 { 1831 // RFC4701 section 3.1: 1832 // 2-octet identifier type, 1-octet digest type, followed by one or more 1833 // octets representing the actual identifier 1834 if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets < 4) 1835 SEMANTIC_ERROR(parser, "Invalid %s", NAME(type)); 1836 return accept_rr(parser, type, rdata); 1837 } 1838 1839 nonnull_all 1840 static int32_t parse_dhcid_rdata( 1841 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1842 { 1843 int32_t code; 1844 const rdata_info_t *fields = type->rdata.fields; 1845 1846 if ((code = parse_base64_sequence(parser, type, &fields[0], rdata, token)) < 0) 1847 return code; 1848 1849 return check_dhcid_rr(parser, type, rdata); 1850 } 1851 1852 nonnull_all 1853 static int32_t check_nsec3_rr( 1854 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1855 { 1856 int32_t r; 1857 size_t c = 0; 1858 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 1859 const uint8_t *o = parser->rdata->octets; 1860 const rdata_info_t *f = type->rdata.fields; 1861 1862 if ((r = check(&c, check_int8(parser, type, &f[0], o, n))) || 1863 (r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) || 1864 (r = check(&c, check_int16(parser, type, &f[2], o+c, n-c))) || 1865 (r = check(&c, check_string(parser, type, &f[3], o+c, n-c))) || 1866 (r = check(&c, check_string(parser, type, &f[4], o+c, n-c))) || 1867 (r = check(&c, check_nsec(parser, type, &f[5], o+c, n-c)))) 1868 return r; 1869 1870 if (c != n) 1871 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 1872 return accept_rr(parser, type, rdata); 1873 } 1874 1875 nonnull_all 1876 static int32_t parse_nsec3_rdata( 1877 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1878 { 1879 int32_t code; 1880 const rdata_info_t *fields = type->rdata.fields; 1881 1882 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 1883 return code; 1884 if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0) 1885 return code; 1886 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 1887 return code; 1888 if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0) 1889 return code; 1890 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 1891 return code; 1892 if ((code = parse_int16(parser, type, &fields[2], rdata, token)) < 0) 1893 return code; 1894 if ((code = take_contiguous(parser, type, &fields[3], token)) < 0) 1895 return code; 1896 if ((code = parse_salt(parser, type, &fields[3], rdata, token)) < 0) 1897 return code; 1898 if ((code = take_contiguous(parser, type, &fields[4], token)) < 0) 1899 return code; 1900 if ((code = parse_base32(parser, type, &fields[4], rdata, token)) < 0) 1901 return code; 1902 take(parser, token); 1903 if ((code = parse_nsec(parser, type, &fields[5], rdata, token)) < 0) 1904 return code; 1905 1906 return accept_rr(parser, type, rdata); 1907 } 1908 1909 nonnull_all 1910 static int32_t check_nsec3param_rr( 1911 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1912 { 1913 int32_t r; 1914 size_t c = 0; 1915 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 1916 const uint8_t *o = parser->rdata->octets; 1917 const rdata_info_t *f = type->rdata.fields; 1918 1919 if ((r = check(&c, check_int8(parser, type, &f[0], o, n))) || 1920 (r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) || 1921 (r = check(&c, check_int16(parser, type, &f[2], o+c, n-c))) || 1922 (r = check(&c, check_string(parser, type, &f[3], o+c, n-c)))) 1923 return r; 1924 1925 if (c != n) 1926 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 1927 return accept_rr(parser, type, rdata); 1928 } 1929 1930 nonnull_all 1931 static int32_t parse_nsec3param_rdata( 1932 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1933 { 1934 int32_t code; 1935 const rdata_info_t *fields = type->rdata.fields; 1936 1937 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 1938 return code; 1939 if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0) 1940 return code; 1941 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 1942 return code; 1943 if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0) 1944 return code; 1945 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 1946 return code; 1947 if ((code = parse_int16(parser, type, &fields[2], rdata, token)) < 0) 1948 return code; 1949 if ((code = take_contiguous(parser, type, &fields[3], token)) < 0) 1950 return code; 1951 if ((code = parse_salt(parser, type, &fields[3], rdata, token)) < 0) 1952 return code; 1953 if ((code = take_delimiter(parser, type, token)) < 0) 1954 return code; 1955 return accept_rr(parser, type, rdata); 1956 } 1957 1958 nonnull_all 1959 static int32_t check_tlsa_rr( 1960 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 1961 { 1962 int32_t r; 1963 size_t c = 0; 1964 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 1965 const uint8_t *o = parser->rdata->octets; 1966 const rdata_info_t *f = type->rdata.fields; 1967 1968 if ((r = check(&c, check_int8(parser, type, &f[0], o, n))) || 1969 (r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) || 1970 (r = check(&c, check_int8(parser, type, &f[2], o+c, n-c)))) 1971 return r; 1972 1973 if (c >= n) 1974 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 1975 return accept_rr(parser, type, rdata); 1976 } 1977 1978 nonnull_all 1979 static int32_t parse_tlsa_rdata( 1980 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 1981 { 1982 int32_t code; 1983 const rdata_info_t *fields = type->rdata.fields; 1984 1985 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 1986 return code; 1987 if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0) 1988 return code; 1989 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 1990 return code; 1991 if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0) 1992 return code; 1993 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 1994 return code; 1995 if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0) 1996 return code; 1997 take(parser, token); 1998 if ((code = parse_base16_sequence(parser, type, &fields[3], rdata, token)) < 0) 1999 return code; 2000 2001 return accept_rr(parser, type, rdata); 2002 } 2003 2004 nonnull_all 2005 static int32_t check_hip_rr( 2006 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2007 { 2008 // FIXME: verify field lengths etc 2009 return accept_rr(parser, type, rdata); 2010 } 2011 2012 nonnull_all 2013 static int32_t parse_hip_rdata( 2014 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2015 { 2016 int32_t code; 2017 const rdata_info_t *fields = type->rdata.fields; 2018 uint8_t *octets = rdata->octets; 2019 2020 // reserve octet for HIT length 2021 rdata->octets += 1; 2022 2023 // PK algorithm 2024 if ((code = have_contiguous(parser, type, &fields[1], token)) < 0) 2025 return code; 2026 if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0) 2027 return code; 2028 2029 // reserve octets for PK length 2030 rdata->octets += 2; 2031 2032 // HIT 2033 if ((code = take_contiguous(parser, type, &fields[3], token)) < 0) 2034 return code; 2035 if ((code = parse_base16(parser, type, &fields[3], rdata, token)) < 0) 2036 return code; 2037 2038 if ((rdata->octets - octets) > 255 + 4) 2039 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[3]), NAME(type)); 2040 uint8_t hit_length = (uint8_t)((rdata->octets - octets) - 4); 2041 octets[0] = hit_length; 2042 2043 // Public Key 2044 if ((code = take_contiguous(parser, type, &fields[4], token)) < 0) 2045 return code; 2046 if ((code = parse_base64(parser, type, &fields[4], rdata, token)) < 0) 2047 return code; 2048 2049 uint16_t pk_length = htobe16((uint16_t)(((rdata->octets - octets) - hit_length) - 4)); 2050 memcpy(&octets[2], &pk_length, sizeof(pk_length)); 2051 2052 take(parser, token); 2053 while (is_contiguous(token)) { 2054 if ((code = parse_name(parser, type, &fields[5], rdata, token)) < 0) 2055 return code; 2056 take(parser, token); 2057 } 2058 2059 if ((code = have_delimiter(parser, type, token)) < 0) 2060 return code; 2061 return accept_rr(parser, type, rdata); 2062 } 2063 2064 nonnull_all 2065 static int32_t check_openpgpkey_rr( 2066 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2067 { 2068 // FIXME: as the RDATA contains a digest, it is likely we can make this 2069 // check stricter, at least, for known algorithms 2070 if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets < 4) 2071 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 2072 return accept_rr(parser, type, rdata); 2073 } 2074 2075 nonnull_all 2076 static int32_t parse_openpgpkey_rdata( 2077 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2078 { 2079 int32_t code; 2080 const rdata_info_t *fields = type->rdata.fields; 2081 2082 if ((code = parse_base64_sequence(parser, type, &fields[0], rdata, token)) < 0) 2083 return code; 2084 2085 return accept_rr(parser, type, rdata); 2086 } 2087 2088 nonnull_all 2089 static int32_t check_csync_rr( 2090 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2091 { 2092 int32_t r; 2093 size_t c = 0; 2094 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 2095 const uint8_t *o = parser->rdata->octets; 2096 const rdata_info_t *f = type->rdata.fields; 2097 2098 if ((r = check(&c, check_int32(parser, type, &f[0], o, n))) || 2099 (r = check(&c, check_int16(parser, type, &f[1], o+c, n-c))) || 2100 (r = check(&c, check_nsec(parser, type, &f[2], o+c, n-c)))) 2101 return r; 2102 2103 if (c != n) 2104 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 2105 return accept_rr(parser, type, rdata); 2106 } 2107 2108 nonnull_all 2109 static int32_t parse_csync_rdata( 2110 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2111 { 2112 int32_t code; 2113 const rdata_info_t *fields = type->rdata.fields; 2114 2115 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 2116 return code; 2117 if ((code = parse_int32(parser, type, &fields[0], rdata, token)) < 0) 2118 return code; 2119 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 2120 return code; 2121 if ((code = parse_int16(parser, type, &fields[1], rdata, token)) < 0) 2122 return code; 2123 take(parser, token); 2124 if ((code = parse_nsec(parser, type, &fields[2], rdata, token)) < 0) 2125 return code; 2126 2127 return accept_rr(parser, type, rdata); 2128 } 2129 2130 nonnull_all 2131 static int32_t check_zonemd_rr( 2132 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2133 { 2134 int32_t r; 2135 size_t c = 0; 2136 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 2137 const uint8_t *o = parser->rdata->octets; 2138 const rdata_info_t *f = type->rdata.fields; 2139 2140 if ((r = check(&c, check_int32(parser, type, &f[0], o, n))) || 2141 (r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) || 2142 (r = check(&c, check_int8(parser, type, &f[2], o+c, n-c)))) 2143 return r; 2144 2145 const uint8_t digest_algorithm = parser->rdata->octets[5]; 2146 if ((digest_algorithm & 0x3) == digest_algorithm) { 2147 // https://www.iana.org/assignments/dns-parameters#zonemd-hash-algorithms 2148 static const uint8_t digest_sizes[4] = { 2149 0, // 0: Reserved 2150 48, // 1: SHA-384 2151 64, // 2: SHA-512 2152 0 // 3: Unassigned 2153 }; 2154 2155 const uint8_t digest_size = digest_sizes[ digest_algorithm ]; 2156 if (digest_size && n - 6 != digest_size) 2157 SEMANTIC_ERROR(parser, "Invalid digest in %s", NAME(type)); 2158 } 2159 2160 return accept_rr(parser, type, rdata); 2161 } 2162 2163 nonnull_all 2164 static int32_t parse_zonemd_rdata( 2165 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2166 { 2167 int32_t code; 2168 const rdata_info_t *fields = type->rdata.fields; 2169 2170 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 2171 return code; 2172 if ((code = parse_int32(parser, type, &fields[0], rdata, token)) < 0) 2173 return code; 2174 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 2175 return code; 2176 if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0) 2177 return code; 2178 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 2179 return code; 2180 if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0) 2181 return code; 2182 take(parser, token); 2183 if ((code = parse_base16_sequence(parser, type, &fields[3], rdata, token)) < 0) 2184 return code; 2185 2186 const uint8_t digest_algorithm = parser->rdata->octets[5]; 2187 if ((digest_algorithm & 0x3) == digest_algorithm) { 2188 // https://www.iana.org/assignments/dns-parameters#zonemd-hash-algorithms 2189 static const uint8_t digest_sizes[4] = { 2190 0, // 0: Reserved 2191 48, // 1: SHA-384 2192 64, // 2: SHA-512 2193 0 // 3: Unassigned 2194 }; 2195 2196 const uint8_t digest_size = digest_sizes[ digest_algorithm ]; 2197 size_t length = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 2198 if (digest_size && length - 6 != digest_size) 2199 SEMANTIC_ERROR(parser, "Invalid digest in %s", NAME(type)); 2200 } 2201 2202 return accept_rr(parser, type, rdata); 2203 } 2204 2205 nonnull_all 2206 static int32_t check_svcb_rr( 2207 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2208 { 2209 // 2210 // FIXME: implement checking parameters etc 2211 // 2212 // - check if all keys in mandatory exist 2213 // - check if at least keys and key lengths are valid 2214 // 2215 // FIXME: implement reordering parameters in strict (primary) mode 2216 // FIXME: note that when reordering or checking, rdata may not actually 2217 // contain valid parameters 2218 // 2219 2220 return accept_rr(parser, type, rdata); 2221 } 2222 2223 nonnull_all 2224 static int32_t parse_svcb_rdata( 2225 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2226 { 2227 int32_t code; 2228 const rdata_info_t *fields = type->rdata.fields; 2229 2230 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 2231 return code; 2232 if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0) 2233 return code; 2234 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 2235 return code; 2236 if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0) 2237 return code; 2238 take(parser, token); 2239 if ((code = parse_svc_params(parser, type, &fields[2], rdata, token)) < 0) 2240 return code; 2241 2242 return accept_rr(parser, type, rdata); 2243 } 2244 2245 nonnull_all 2246 static int32_t check_https_rr( 2247 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2248 { 2249 // 2250 // FIXME: incorporate fixes mentioned in check_svcb_rr 2251 // 2252 2253 return accept_rr(parser, type, rdata); 2254 } 2255 2256 nonnull_all 2257 static int32_t parse_https_rdata( 2258 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2259 { 2260 int32_t code; 2261 const rdata_info_t *fields = type->rdata.fields; 2262 2263 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 2264 return code; 2265 if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0) 2266 return code; 2267 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 2268 return code; 2269 if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0) 2270 return code; 2271 take(parser, token); 2272 if ((code = parse_svc_params(parser, type, &fields[2], rdata, token)) < 0) 2273 return code; 2274 2275 return accept_rr(parser, type, rdata); 2276 } 2277 2278 nonnull_all 2279 static int32_t check_dsync_rr( 2280 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2281 { 2282 int32_t r; 2283 size_t c = 0; 2284 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 2285 const uint8_t *o = parser->rdata->octets; 2286 const rdata_info_t *f = type->rdata.fields; 2287 2288 if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) || 2289 (r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) || 2290 (r = check(&c, check_int16(parser, type, &f[2], o+c, n-c))) || 2291 (r = check(&c, check_name(parser, type, &f[3], o+c, n-c)))) 2292 return r; 2293 2294 const uint8_t dsync_scheme = o[2]; 2295 uint16_t dsync_type; 2296 memcpy(&dsync_type, o, sizeof(dsync_type)); 2297 dsync_type = be16toh(dsync_type); 2298 if (dsync_scheme == 1 && dsync_type != ZONE_TYPE_CDS 2299 && dsync_type != ZONE_TYPE_CSYNC) 2300 SEMANTIC_ERROR(parser, "Wrong type for scheme 1 in %s", NAME(type)); 2301 2302 if (c > n) 2303 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 2304 return accept_rr(parser, type, rdata); 2305 } 2306 2307 nonnull_all 2308 static int32_t parse_dsync_rdata( 2309 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2310 { 2311 int32_t code; 2312 const rdata_info_t *fields = type->rdata.fields; 2313 2314 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 2315 return code; 2316 if ((code = parse_type(parser, type, &fields[0], rdata, token)) < 0) 2317 return code; 2318 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 2319 return code; 2320 if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0) 2321 return code; 2322 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 2323 return code; 2324 if ((code = parse_int16(parser, type, &fields[2], rdata, token)) < 0) 2325 return code; 2326 if ((code = take_contiguous(parser, type, &fields[3], token)) < 0) 2327 return code; 2328 if ((code = parse_name(parser, type, &fields[3], rdata, token)) < 0) 2329 return code; 2330 2331 const uint8_t dsync_scheme = parser->rdata->octets[2]; 2332 uint16_t dsync_type; 2333 memcpy(&dsync_type, parser->rdata->octets, sizeof(dsync_type)); 2334 dsync_type = be16toh(dsync_type); 2335 if (dsync_scheme == 1 && dsync_type != ZONE_TYPE_CDS 2336 && dsync_type != ZONE_TYPE_CSYNC) 2337 SEMANTIC_ERROR(parser, "Wrong type for scheme 1 in %s", NAME(type)); 2338 2339 return accept_rr(parser, type, rdata); 2340 } 2341 2342 nonnull_all 2343 static int32_t check_nid_rr( 2344 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2345 { 2346 int32_t r; 2347 size_t c = 0; 2348 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 2349 const uint8_t *o = parser->rdata->octets; 2350 const rdata_info_t *f = type->rdata.fields; 2351 2352 if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) || 2353 (r = check(&c, check_ilnp64(parser, type, &f[1], o+c, n-c)))) 2354 return r; 2355 if (c != n) 2356 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 2357 return accept_rr(parser, type, rdata); 2358 } 2359 2360 nonnull_all 2361 static int32_t parse_nid_rdata( 2362 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2363 { 2364 int32_t code; 2365 const rdata_info_t *fields = type->rdata.fields; 2366 2367 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 2368 return code; 2369 if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0) 2370 return code; 2371 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 2372 return code; 2373 if ((code = parse_ilnp64(parser, type, &fields[1], rdata, token)) < 0) 2374 return code; 2375 if ((code = take_delimiter(parser, type, token)) < 0) 2376 return code; 2377 return accept_rr(parser, type, rdata); 2378 } 2379 2380 nonnull_all 2381 static int32_t check_l32_rr( 2382 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2383 { 2384 int32_t r; 2385 size_t c = 0; 2386 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 2387 const uint8_t *o = parser->rdata->octets; 2388 const rdata_info_t *f = type->rdata.fields; 2389 2390 if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) || 2391 (r = check(&c, check_ip4(parser, type, &f[1], o+c, n-c)))) 2392 return r; 2393 2394 if (c != n) 2395 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 2396 return accept_rr(parser, type, rdata); 2397 } 2398 2399 nonnull_all 2400 static int32_t parse_l32_rdata( 2401 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2402 { 2403 int32_t code; 2404 const rdata_info_t *fields = type->rdata.fields; 2405 2406 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 2407 return code; 2408 if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0) 2409 return code; 2410 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 2411 return code; 2412 if ((code = parse_ip4(parser, type, &fields[1], rdata, token)) < 0) 2413 return code; 2414 if ((code = take_delimiter(parser, type, token)) < 0) 2415 return code; 2416 return accept_rr(parser, type, rdata); 2417 } 2418 2419 nonnull_all 2420 static int32_t check_l64_rr( 2421 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2422 { 2423 int32_t r; 2424 size_t c = 0; 2425 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 2426 const uint8_t *o = parser->rdata->octets; 2427 const rdata_info_t *f = type->rdata.fields; 2428 2429 if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) || 2430 (r = check(&c, check_ilnp64(parser, type, &f[1], o+c, n-c)))) 2431 return r; 2432 if (c != n) 2433 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 2434 return accept_rr(parser, type, rdata); 2435 } 2436 2437 nonnull_all 2438 static int32_t parse_l64_rdata( 2439 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2440 { 2441 int32_t code; 2442 const rdata_info_t *fields = type->rdata.fields; 2443 2444 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 2445 return code; 2446 if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0) 2447 return code; 2448 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 2449 return code; 2450 if ((code = parse_ilnp64(parser, type, &fields[1], rdata, token)) < 0) 2451 return code; 2452 if ((code = take_delimiter(parser, type, token)) < 0) 2453 return code; 2454 return accept_rr(parser, type, rdata); 2455 } 2456 2457 nonnull_all 2458 static int32_t check_eui48_rr( 2459 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2460 { 2461 if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets != 6) 2462 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 2463 return accept_rr(parser, type, rdata); 2464 } 2465 2466 nonnull_all 2467 static int32_t parse_eui48_rdata( 2468 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2469 { 2470 int32_t code; 2471 const rdata_info_t *fields = type->rdata.fields; 2472 2473 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 2474 return code; 2475 if ((code = parse_eui48(parser, type, &fields[0], rdata, token)) < 0) 2476 return code; 2477 if ((code = take_delimiter(parser, type, token)) < 0) 2478 return code; 2479 return accept_rr(parser, type, rdata); 2480 } 2481 2482 nonnull_all 2483 static int32_t check_eui64_rr( 2484 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2485 { 2486 if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets != 8) 2487 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 2488 return accept_rr(parser, type, rdata); 2489 } 2490 2491 nonnull_all 2492 static int32_t parse_eui64_rdata( 2493 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2494 { 2495 int32_t code; 2496 const rdata_info_t *fields = type->rdata.fields; 2497 2498 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 2499 return code; 2500 if ((code = parse_eui64(parser, type, &fields[0], rdata, token)) < 0) 2501 return code; 2502 if ((code = take_delimiter(parser, type, token)) < 0) 2503 return code; 2504 return accept_rr(parser, type, rdata); 2505 } 2506 2507 nonnull_all 2508 static int32_t check_uri_rr( 2509 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2510 { 2511 int32_t r; 2512 size_t c = 0; 2513 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 2514 const uint8_t *o = parser->rdata->octets; 2515 const rdata_info_t *f = type->rdata.fields; 2516 2517 if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) || 2518 (r = check(&c, check_int16(parser, type, &f[1], o+c, n-c)))) 2519 return r; 2520 if (c >= n) 2521 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 2522 return accept_rr(parser, type, rdata); 2523 } 2524 2525 nonnull_all 2526 static int32_t parse_uri_rdata( 2527 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2528 { 2529 int32_t code; 2530 const rdata_info_t *fields = type->rdata.fields; 2531 2532 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 2533 return code; 2534 if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0) 2535 return code; 2536 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 2537 return code; 2538 if ((code = parse_int16(parser, type, &fields[1], rdata, token)) < 0) 2539 return code; 2540 if ((code = take_quoted(parser, type, &fields[2], token)) < 0) 2541 return code; 2542 if ((code = parse_text(parser, type, &fields[2], rdata, token)) < 0) 2543 return code; 2544 if ((code = take_delimiter(parser, type, token)) < 0) 2545 return code; 2546 return accept_rr(parser, type, rdata); 2547 } 2548 2549 nonnull_all 2550 static int32_t check_caa_rr( 2551 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2552 { 2553 int32_t r; 2554 size_t c = 0; 2555 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 2556 const uint8_t *o = parser->rdata->octets; 2557 const rdata_info_t *f = type->rdata.fields; 2558 2559 if ((r = check(&c, check_int8(parser, type, &f[0], o, n))) || 2560 (r = check(&c, check_int8(parser, type, &f[1], o+c, n-c)))) 2561 return r; 2562 if (c >= n) 2563 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 2564 return accept_rr(parser, type, rdata); 2565 } 2566 2567 nonnull_all 2568 static int32_t parse_caa_rdata( 2569 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2570 { 2571 int32_t code; 2572 const rdata_info_t *fields = type->rdata.fields; 2573 2574 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 2575 return code; 2576 if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0) 2577 return code; 2578 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 2579 return code; 2580 if ((code = parse_caa_tag(parser, type, &fields[1], rdata, token)) < 0) 2581 return code; 2582 if ((code = take_quoted_or_contiguous(parser, type, &fields[2], token)) < 0) 2583 return code; 2584 if ((code = parse_text(parser, type, &fields[2], rdata, token)) < 0) 2585 return code; 2586 if ((code = take_delimiter(parser, type, token)) < 0) 2587 return code; 2588 return accept_rr(parser, type, rdata); 2589 } 2590 2591 nonnull_all 2592 static int32_t check_doa_rr( 2593 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2594 { 2595 int32_t r; 2596 size_t c = 0; 2597 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 2598 const uint8_t *o = parser->rdata->octets; 2599 const rdata_info_t *f = type->rdata.fields; 2600 2601 if ((r = check(&c, check_int32(parser, type, &f[0], o, n))) || 2602 (r = check(&c, check_int32(parser, type, &f[1], o+c, n-c))) || 2603 (r = check(&c, check_int8(parser, type, &f[2], o+c, n-c))) || 2604 (r = check(&c, check_string(parser, type, &f[3], o+c, n-c)))) 2605 return r; 2606 if (c > n) 2607 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 2608 return accept_rr(parser, type, rdata); 2609 } 2610 2611 nonnull_all 2612 static int32_t parse_doa_rdata( 2613 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2614 { 2615 int32_t code; 2616 const rdata_info_t *fields = type->rdata.fields; 2617 2618 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 2619 return code; 2620 if ((code = parse_int32(parser, type, &fields[0], rdata, token)) < 0) 2621 return code; 2622 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 2623 return code; 2624 if ((code = parse_int32(parser, type, &fields[1], rdata, token)) < 0) 2625 return code; 2626 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 2627 return code; 2628 if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0) 2629 return code; 2630 if ((code = take_quoted_or_contiguous(parser, type, &fields[3], token)) < 0) 2631 return code; 2632 if ((code = parse_string(parser, type, &fields[3], rdata, token)) < 0) 2633 return code; 2634 take(parser, token); 2635 if (!(token->length == 1 && ((char)*token->data == '0' || (char)*token->data == '-')) 2636 && (code = parse_base64_sequence(parser, type, &fields[4], rdata, token)) < 0) 2637 return code; 2638 return accept_rr(parser, type, rdata); 2639 } 2640 2641 nonnull_all 2642 static int32_t check_amtrelay_rr( 2643 parser_t *parser, const type_info_t *type, const rdata_t *rdata); 2644 2645 nonnull_all 2646 static int32_t parse_amtrelay_rdata( 2647 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token); 2648 2649 diagnostic_push() 2650 gcc_diagnostic_ignored(missing-field-initializers) 2651 clang_diagnostic_ignored(missing-field-initializers) 2652 2653 static const rdata_info_t amtrelay_ipv4_rdata_fields[] = { 2654 FIELD("precedence"), 2655 FIELD("discovery optional"), 2656 FIELD("type"), 2657 FIELD("relay") 2658 }; 2659 2660 static const type_info_t amtrelay_ipv4[] = { 2661 TYPE("AMTRELAY", ZONE_TYPE_AMTRELAY, ZONE_CLASS_IN, FIELDS(amtrelay_ipv4_rdata_fields), 2662 check_amtrelay_rr, parse_amtrelay_rdata), 2663 }; 2664 2665 static const rdata_info_t amtrelay_ipv6_rdata_fields[] = { 2666 FIELD("precedence"), 2667 FIELD("discovery optional"), 2668 FIELD("type"), 2669 FIELD("relay") 2670 }; 2671 2672 static const type_info_t amtrelay_ipv6[] = { 2673 TYPE("AMTRELAY", ZONE_TYPE_AMTRELAY, ZONE_CLASS_IN, FIELDS(amtrelay_ipv6_rdata_fields), 2674 check_amtrelay_rr, parse_amtrelay_rdata), 2675 }; 2676 2677 diagnostic_pop() 2678 2679 nonnull_all 2680 static int32_t check_amtrelay_rr( 2681 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2682 { 2683 int32_t r; 2684 size_t c = 0; 2685 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 2686 const uint8_t *o = parser->rdata->octets; 2687 const type_info_t *t = type; 2688 const rdata_info_t *f = type->rdata.fields; 2689 2690 if ((r = check(&c, check_int8(parser, type, &f[0], o, n))) || 2691 (r = check(&c, check_int8(parser, type, &f[2], o+c, n-c)))) 2692 return r; 2693 2694 switch (parser->rdata->octets[1] & 0x7f) { 2695 case 1: /* IPv4 address */ 2696 t = (const type_info_t *)amtrelay_ipv4; 2697 f = amtrelay_ipv4_rdata_fields; 2698 if ((r = check(&c, check_ip4(parser, t, &f[3], o+c, n-c))) < 0) 2699 return r; 2700 break; 2701 case 2: /* IPv6 address */ 2702 t = (const type_info_t *)amtrelay_ipv6; 2703 f = amtrelay_ipv6_rdata_fields; 2704 if ((r = check(&c, check_ip6(parser, t, &f[3], o+c, n-c))) < 0) 2705 return r; 2706 break; 2707 case 0: /* no gateway */ 2708 break; 2709 case 3: /* domain name */ 2710 if ((r = check(&c, check_name(parser, t, &f[3], o+c, n-c))) < 0) 2711 return r; 2712 break; 2713 default: 2714 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 2715 } 2716 if (c < n) 2717 SYNTAX_ERROR(parser, "Trailing data in %s", NAME(t)); 2718 return accept_rr(parser, t, rdata); 2719 } 2720 2721 nonnull_all 2722 static int32_t parse_amtrelay_rdata( 2723 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2724 { 2725 int32_t code; 2726 const rdata_info_t *fields = type->rdata.fields; 2727 uint8_t *octets = rdata->octets; 2728 uint8_t D; 2729 2730 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 2731 return code; 2732 if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0) 2733 return code; 2734 2735 if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) 2736 return code; 2737 if (token->length != 1) 2738 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[1]), NAME(type)); 2739 switch((char)*token->data) { 2740 case '0': 2741 D = 0x00; 2742 break; 2743 case '1': 2744 D = 0x80; 2745 break; 2746 default : 2747 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[1]), NAME(type)); 2748 } 2749 2750 if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) 2751 return code; 2752 if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0) 2753 return code; 2754 2755 if ((code = take_contiguous(parser, type, &fields[3], token)) < 0) 2756 return code; 2757 switch (octets[1]) { 2758 case 0: 2759 /* no gateway requires a '.' as the relay in presentation format 2760 * without parsing it into wireformat rdata */ 2761 if (!(token->length == 1 && *token->data == '.')) 2762 SYNTAX_ERROR(parser, "Invalid %s in %s, the no gateway type (type 0) of AMTRELAY requires the relay field to have '.' in it", NAME(&fields[3]), NAME(type)); 2763 break; 2764 case 1: /* IPv4 address */ 2765 type = (const type_info_t *)amtrelay_ipv4; 2766 fields = type->rdata.fields; 2767 if ((code = parse_ip4(parser, type, &fields[3], rdata, token)) < 0) 2768 return code; 2769 break; 2770 case 2: /* IPv6 address */ 2771 type = (const type_info_t *)amtrelay_ipv6; 2772 fields = type->rdata.fields; 2773 if ((code = parse_ip6(parser, type, &fields[3], rdata, token)) < 0) 2774 return code; 2775 break; 2776 case 3: /* domain name */ 2777 if ((code = parse_name(parser, type, &fields[3], rdata, token)) < 0) 2778 return code; 2779 break; 2780 default: 2781 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[3]), NAME(type)); 2782 } 2783 octets[1] |= D; 2784 if ((code = take_delimiter(parser, type, token)) < 0) 2785 return code; 2786 return accept_rr(parser, type, rdata); 2787 } 2788 2789 nonnull_all 2790 static int32_t check_ipn_rr( 2791 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2792 { 2793 int32_t r; 2794 size_t c = 0; 2795 const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; 2796 const uint8_t *o = parser->rdata->octets; 2797 const rdata_info_t *f = type->rdata.fields; 2798 2799 if ((r = check(&c, check_int64(parser, type, &f[0], o, n)))) 2800 return r; 2801 if (c > n) 2802 SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); 2803 return accept_rr(parser, type, rdata); 2804 } 2805 2806 nonnull_all 2807 static int32_t parse_ipn_rdata( 2808 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2809 { 2810 int32_t code; 2811 const rdata_info_t *fields = type->rdata.fields; 2812 token_t left, right; 2813 2814 /* draft-johnson-dns-ipn-cla-07 Section 3.1. IPN: 2815 * Presentation format for these resource records are either a 64 bit 2816 * unsigned decimal integer, or two 32 bit unsigned decimal integers 2817 * delimited by a period with the most significant 32 bits first and least 2818 * significant 32 bits last. 2819 */ 2820 if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) 2821 return code; 2822 if (!(right.data = memchr(token->data, '.', token->length))) { 2823 if ((code = parse_int64(parser, type, &fields[0], rdata, token)) < 0) 2824 return code; 2825 if ((code = take_delimiter(parser, type, token)) < 0) 2826 return code; 2827 return accept_rr(parser, type, rdata); 2828 } 2829 left.code = token->code; 2830 left.data = token->data; 2831 left.length = (size_t)(right.data - token->data); 2832 right.code = token->code; 2833 right.data += 1; 2834 right.length = token->length - left.length - 1; 2835 if ((code = parse_int32(parser, type, &fields[0], rdata, &left)) < 0) 2836 return code; 2837 if ((code = parse_int32(parser, type, &fields[0], rdata, &right)) < 0) 2838 return code; 2839 if ((code = take_delimiter(parser, type, token)) < 0) 2840 return code; 2841 return accept_rr(parser, type, rdata); 2842 } 2843 2844 nonnull_all 2845 static int32_t check_generic_rr( 2846 parser_t *parser, const type_info_t *type, const rdata_t *rdata) 2847 { 2848 return accept_rr(parser, type, rdata); 2849 } 2850 2851 nonnull_all 2852 static int32_t parse_generic_rdata( 2853 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2854 { 2855 int32_t code; 2856 uint16_t rdlength; 2857 static const rdata_info_t fields[] = { 2858 FIELD("rdlength"), 2859 FIELD("rdata") 2860 }; 2861 2862 // discard '\#' 2863 if ((code = take_contiguous(parser, type, &fields[0], token)) < 0) 2864 return code; 2865 if (!scan_int16(token->data, token->length, &rdlength)) 2866 SYNTAX_ERROR(parser, "Invalid RDLENGTH in %s", NAME(type)); 2867 2868 take(parser, token); 2869 if (is_contiguous(token)) { 2870 struct base16_state state = { .eof = 0, .bytes = 0, .carry = 0 }; 2871 2872 do { 2873 size_t length = token->length + 1 / 2; 2874 if (length > (uintptr_t)rdata->limit - (uintptr_t)rdata->octets) 2875 SYNTAX_ERROR(parser, "Invalid RDATA in %s", NAME(type)); 2876 if (!base16_stream_decode(&state, token->data, token->length, rdata->octets, &length)) 2877 SYNTAX_ERROR(parser, "Invalid RDATA in %s", NAME(type)); 2878 rdata->octets += length; 2879 take(parser, token); 2880 } while (is_contiguous(token)); 2881 2882 if (state.bytes) 2883 *rdata->octets++ = state.carry; 2884 } 2885 2886 if ((code = have_delimiter(parser, type, token)) < 0) 2887 return code; 2888 if (rdata->octets - parser->rdata->octets != rdlength) 2889 SYNTAX_ERROR(parser, "Invalid RDATA in %s", NAME(type)); 2890 return type->check(parser, type, rdata); 2891 } 2892 2893 nonnull_all 2894 static int32_t parse_unknown_rdata( 2895 parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) 2896 { 2897 (void)type; 2898 (void)rdata; 2899 (void)token; 2900 SYNTAX_ERROR(parser, "Unknown record type"); 2901 } 2902 2903 diagnostic_push() 2904 gcc_diagnostic_ignored(missing-field-initializers) 2905 clang_diagnostic_ignored(missing-field-initializers) 2906 2907 static const class_info_t classes[] = { 2908 UNKNOWN_CLASS(0), 2909 CLASS("IN", ZONE_CLASS_IN), 2910 CLASS("CS", ZONE_CLASS_CS), 2911 CLASS("CH", ZONE_CLASS_CH), 2912 CLASS("HS", ZONE_CLASS_HS) 2913 }; 2914 2915 static const rdata_info_t a_rdata_fields[] = { 2916 FIELD("address") 2917 }; 2918 2919 static const rdata_info_t ns_rdata_fields[] = { 2920 FIELD("host") 2921 }; 2922 2923 static const rdata_info_t md_rdata_fields[] = { 2924 FIELD("madname") 2925 }; 2926 2927 static const rdata_info_t mf_rdata_fields[] = { 2928 FIELD("madname") 2929 }; 2930 2931 static const rdata_info_t cname_rdata_fields[] = { 2932 FIELD("host") 2933 }; 2934 2935 static const rdata_info_t soa_rdata_fields[] = { 2936 FIELD("primary"), 2937 FIELD("mailbox"), 2938 FIELD("serial"), 2939 FIELD("refresh"), 2940 FIELD("retry"), 2941 FIELD("expire"), 2942 FIELD("minimum") 2943 }; 2944 2945 static const rdata_info_t mb_rdata_fields[] = { 2946 FIELD("madname") 2947 }; 2948 2949 static const rdata_info_t mg_rdata_fields[] = { 2950 FIELD("mgmname") 2951 }; 2952 2953 static const rdata_info_t mr_rdata_fields[] = { 2954 FIELD("newname") 2955 }; 2956 2957 static const rdata_info_t ptr_rdata_fields[] = { 2958 FIELD("ptrdname") 2959 }; 2960 2961 static const rdata_info_t hinfo_rdata_fields[] = { 2962 FIELD("cpu"), 2963 FIELD("os") 2964 }; 2965 2966 static const rdata_info_t minfo_rdata_fields[] = { 2967 FIELD("rmailbx"), 2968 FIELD("emailbx") 2969 }; 2970 2971 static const rdata_info_t null_rdata_fields[] = { 2972 FIELD("anything") 2973 }; 2974 2975 static const rdata_info_t wks_rdata_fields[] = { 2976 FIELD("address"), 2977 FIELD("protocol"), 2978 FIELD("bitmap") 2979 }; 2980 2981 static const rdata_info_t mx_rdata_fields[] = { 2982 FIELD("priority"), 2983 FIELD("hostname") 2984 }; 2985 2986 static const rdata_info_t txt_rdata_fields[] = { 2987 FIELD("text") 2988 }; 2989 2990 static const rdata_info_t rp_rdata_fields[] = { 2991 FIELD("mailbox"), 2992 FIELD("text") 2993 }; 2994 2995 static const rdata_info_t afsdb_rdata_fields[] = { 2996 FIELD("subtype"), 2997 FIELD("hostname") 2998 }; 2999 3000 static const rdata_info_t x25_rdata_fields[] = { 3001 FIELD("address") 3002 }; 3003 3004 static const rdata_info_t isdn_rdata_fields[] = { 3005 FIELD("address"), 3006 FIELD("subaddress") 3007 }; 3008 3009 static const rdata_info_t rt_rdata_fields[] = { 3010 FIELD("preference"), 3011 FIELD("hostname") 3012 }; 3013 3014 static const rdata_info_t nsap_rdata_fields[] = { 3015 FIELD("address") 3016 }; 3017 3018 static const rdata_info_t nsap_ptr_rdata_fields[] = { 3019 FIELD("hostname") 3020 }; 3021 3022 static const rdata_info_t key_rdata_fields[] = { 3023 FIELD("flags"), 3024 FIELD("protocol"), 3025 FIELD("algorithm"), 3026 FIELD("publickey") 3027 }; 3028 3029 static const rdata_info_t px_rdata_fields[] = { 3030 FIELD("preference"), 3031 FIELD("map822"), 3032 FIELD("mapx400") 3033 }; 3034 3035 static const rdata_info_t gpos_rdata_fields[] = { 3036 FIELD("latitude"), 3037 FIELD("longitude"), 3038 FIELD("altitude") 3039 }; 3040 3041 static const rdata_info_t aaaa_rdata_fields[] = { 3042 FIELD("address") 3043 }; 3044 3045 static const rdata_info_t loc_rdata_fields[] = { 3046 FIELD("version"), 3047 FIELD("size"), 3048 FIELD("horizontal precision"), 3049 FIELD("vertical precision"), 3050 FIELD("latitude"), 3051 FIELD("longitude"), 3052 FIELD("altitude") 3053 }; 3054 3055 static const rdata_info_t nxt_rdata_fields[] = { 3056 FIELD("next domain name"), 3057 FIELD("type bit map") 3058 }; 3059 3060 static const rdata_info_t eid_rdata_fields[] = { 3061 FIELD("end point identifier") 3062 }; 3063 3064 static const rdata_info_t nimloc_rdata_fields[] = { 3065 FIELD("nimrod locator") 3066 }; 3067 3068 static const rdata_info_t srv_rdata_fields[] = { 3069 FIELD("priority"), 3070 FIELD("weight"), 3071 FIELD("port"), 3072 FIELD("target") 3073 }; 3074 3075 static const rdata_info_t atma_rdata_fields[] = { 3076 FIELD("address") 3077 }; 3078 3079 static const rdata_info_t naptr_rdata_fields[] = { 3080 FIELD("order"), 3081 FIELD("preference"), 3082 FIELD("flags"), 3083 FIELD("services"), 3084 FIELD("regex"), 3085 FIELD("replacement"), 3086 }; 3087 3088 static const rdata_info_t kx_rdata_fields[] = { 3089 FIELD("preference"), 3090 FIELD("exchanger") 3091 }; 3092 3093 static const rdata_info_t sig_rdata_fields[] = { 3094 FIELD("sigtype"), 3095 FIELD("algorithm"), 3096 FIELD("labels"), 3097 FIELD("origttl"), 3098 FIELD("expire"), 3099 FIELD("inception"), 3100 FIELD("keytag"), 3101 FIELD("signer"), 3102 FIELD("signature") 3103 }; 3104 3105 static const rdata_info_t cert_rdata_fields[] = { 3106 FIELD("type"), 3107 FIELD("key tag"), 3108 FIELD("algorithm"), 3109 FIELD("certificate") 3110 }; 3111 3112 static const rdata_info_t dname_rdata_fields[] = { 3113 FIELD("source") 3114 }; 3115 3116 static const rdata_info_t sink_rdata_fields[] = { 3117 FIELD("coding"), 3118 FIELD("subcoding"), 3119 FIELD("data") 3120 }; 3121 3122 static const rdata_info_t apl_rdata_fields[] = { 3123 FIELD("prefix") 3124 }; 3125 3126 static const rdata_info_t ds_rdata_fields[] = { 3127 FIELD("keytag"), 3128 FIELD("algorithm"), 3129 FIELD("digtype"), 3130 FIELD("digest") 3131 }; 3132 3133 static const rdata_info_t sshfp_rdata_fields[] = { 3134 FIELD("algorithm"), 3135 FIELD("ftype"), 3136 FIELD("fingerprint") 3137 }; 3138 3139 // IPSECKEY is different because the rdata depends on the algorithm 3140 static const rdata_info_t ipseckey_rdata_fields[] = { 3141 FIELD("precedence"), 3142 FIELD("gateway type"), 3143 FIELD("algorithm"), 3144 FIELD("gateway"), 3145 FIELD("public key") 3146 }; 3147 3148 static const rdata_info_t rrsig_rdata_fields[] = { 3149 FIELD("rrtype"), 3150 FIELD("algorithm"), 3151 FIELD("labels"), 3152 FIELD("origttl"), 3153 FIELD("expire"), 3154 FIELD("inception"), 3155 FIELD("keytag"), 3156 FIELD("signer"), 3157 FIELD("signature") 3158 }; 3159 3160 static const rdata_info_t nsec_rdata_fields[] = { 3161 FIELD("next"), 3162 FIELD("types") 3163 }; 3164 3165 static const rdata_info_t dnskey_rdata_fields[] = { 3166 FIELD("flags"), 3167 FIELD("protocol"), 3168 FIELD("algorithm"), 3169 FIELD("publickey") 3170 }; 3171 3172 static const rdata_info_t dhcid_rdata_fields[] = { 3173 FIELD("dhcpinfo") 3174 }; 3175 3176 static const rdata_info_t nsec3_rdata_fields[] = { 3177 FIELD("algorithm"), 3178 FIELD("flags"), 3179 FIELD("iterations"), 3180 FIELD("salt"), 3181 FIELD("next"), 3182 FIELD("types") 3183 }; 3184 3185 static const rdata_info_t nsec3param_rdata_fields[] = { 3186 FIELD("algorithm"), 3187 FIELD("flags"), 3188 FIELD("iterations"), 3189 FIELD("salt") 3190 }; 3191 3192 static const rdata_info_t tlsa_rdata_fields[] = { 3193 FIELD("usage"), 3194 FIELD("selector"), 3195 FIELD("matching type"), 3196 FIELD("certificate association data") 3197 }; 3198 3199 static const rdata_info_t smimea_rdata_fields[] = { 3200 FIELD("usage"), 3201 FIELD("selector"), 3202 FIELD("matching type"), 3203 FIELD("certificate association data") 3204 }; 3205 3206 static const rdata_info_t cds_rdata_fields[] = { 3207 FIELD("keytag"), 3208 FIELD("algorithm"), 3209 FIELD("digtype"), 3210 FIELD("digest") 3211 }; 3212 3213 static const rdata_info_t cdnskey_rdata_fields[] = { 3214 FIELD("flags"), 3215 FIELD("protocol"), 3216 FIELD("algorithm"), 3217 FIELD("publickey") 3218 }; 3219 3220 static const rdata_info_t hip_rdata_fields[] = { 3221 FIELD("HIT length"), 3222 FIELD("PK algorithm"), 3223 FIELD("PK length"), 3224 FIELD("HIT"), 3225 FIELD("Public Key"), 3226 FIELD("Rendezvous Servers") 3227 }; 3228 3229 // https://www.iana.org/assignments/dns-parameters/NINFO/ninfo-completed-template 3230 static const rdata_info_t ninfo_rdata_fields[] = { 3231 FIELD("text") 3232 }; 3233 3234 // https://www.iana.org/assignments/dns-parameters/RKEY/rkey-completed-template 3235 static const rdata_info_t rkey_rdata_fields[] = { 3236 FIELD("flags"), 3237 FIELD("protocol"), 3238 FIELD("algorithm"), 3239 FIELD("publickey") 3240 }; 3241 3242 // https://www.iana.org/assignments/dns-parameters/TALINK/talink-completed-template 3243 static const rdata_info_t talink_rdata_fields[] = { 3244 FIELD("start or previous"), 3245 FIELD("end or next") 3246 }; 3247 3248 static const rdata_info_t openpgpkey_rdata_fields[] = { 3249 FIELD("key") 3250 }; 3251 3252 static const rdata_info_t csync_rdata_fields[] = { 3253 FIELD("serial"), 3254 FIELD("flags"), 3255 FIELD("types") 3256 }; 3257 3258 static const rdata_info_t zonemd_rdata_fields[] = { 3259 FIELD("serial"), 3260 FIELD("scheme"), 3261 FIELD("algorithm"), 3262 FIELD("digest"), 3263 }; 3264 3265 static const rdata_info_t svcb_rdata_fields[] = { 3266 FIELD("priority"), 3267 FIELD("target"), 3268 FIELD("params") 3269 }; 3270 3271 static const rdata_info_t https_rdata_fields[] = { 3272 FIELD("priority"), 3273 FIELD("target"), 3274 FIELD("params") 3275 }; 3276 3277 static const rdata_info_t dsync_rdata_fields[] = { 3278 FIELD("rrtype"), 3279 FIELD("scheme"), 3280 FIELD("port"), 3281 FIELD("target") 3282 }; 3283 3284 static const rdata_info_t spf_rdata_fields[] = { 3285 FIELD("text") 3286 }; 3287 3288 static const rdata_info_t nid_rdata_fields[] = { 3289 FIELD("preference"), 3290 FIELD("nodeid") 3291 }; 3292 3293 // RFC6742 specifies the syntax for the locator is compatible with the syntax 3294 // for IPv4 addresses, but then proceeds to provide an example with leading 3295 // zeroes. The example is corrected in the errata. 3296 static const rdata_info_t l32_rdata_fields[] = { 3297 FIELD("preference"), 3298 FIELD("locator") 3299 }; 3300 3301 static const rdata_info_t l64_rdata_fields[] = { 3302 FIELD("preference"), 3303 FIELD("locator") 3304 }; 3305 3306 static const rdata_info_t lp_rdata_fields[] = { 3307 FIELD("preference"), 3308 FIELD("pointer") 3309 }; 3310 3311 static const rdata_info_t eui48_rdata_fields[] = { 3312 FIELD("address") 3313 }; 3314 3315 static const rdata_info_t eui64_rdata_fields[] = { 3316 FIELD("address") 3317 }; 3318 3319 static const rdata_info_t uri_rdata_fields[] = { 3320 FIELD("priority"), 3321 FIELD("weight"), 3322 FIELD("target") 3323 }; 3324 3325 static const rdata_info_t caa_rdata_fields[] = { 3326 FIELD("flags"), 3327 FIELD("tag"), 3328 FIELD("value") 3329 }; 3330 3331 // https://www.iana.org/assignments/dns-parameters/AVC/avc-completed-template 3332 static const rdata_info_t avc_rdata_fields[] = { 3333 FIELD("text") 3334 }; 3335 3336 // draft-durand-doa-over-dns-02 3337 static const rdata_info_t doa_rdata_fields[] = { 3338 FIELD("enterprise"), 3339 FIELD("type"), 3340 FIELD("location"), 3341 FIELD("media type"), 3342 FIELD("data") 3343 }; 3344 3345 // RFC 8777 3346 // AMTRELAY is different because the rdata depends on the type 3347 static const rdata_info_t amtrelay_rdata_fields[] = { 3348 FIELD("precedence"), 3349 FIELD("discovery optional"), 3350 FIELD("type"), 3351 FIELD("relay"), 3352 }; 3353 3354 3355 // RFC 9606 3356 static const rdata_info_t resinfo_rdata_fields[] = { 3357 FIELD("text") 3358 }; 3359 3360 // https://www.iana.org/assignments/dns-parameters/WALLET/wallet-completed-template 3361 static const rdata_info_t wallet_rdata_fields[] = { 3362 FIELD("text") 3363 }; 3364 3365 // https://www.iana.org/assignments/dns-parameters/CLA/cla-completed-template 3366 static const rdata_info_t cla_rdata_fields[] = { 3367 FIELD("text") 3368 }; 3369 3370 // https://www.iana.org/assignments/dns-parameters/IPN/ipn-completed-template 3371 // and https://datatracker.ietf.org/doc/draft-johnson-dns-ipn-cla/07/ 3372 static const rdata_info_t ipn_rdata_fields[] = { 3373 FIELD("CBHE Node Number") 3374 }; 3375 3376 static const rdata_info_t ta_rdata_fields[] = { 3377 FIELD("key"), 3378 FIELD("algorithm"), 3379 FIELD("type"), 3380 FIELD("digest") 3381 }; 3382 3383 static const rdata_info_t dlv_rdata_fields[] = { 3384 FIELD("key"), 3385 FIELD("algorithm"), 3386 FIELD("type"), 3387 FIELD("digest") 3388 }; 3389 3390 // https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml 3391 static const type_info_t types[] = { 3392 UNKNOWN_TYPE(0), 3393 3394 TYPE("A", ZONE_TYPE_A, ZONE_CLASS_ANY, FIELDS(a_rdata_fields), 3395 check_a_rr, parse_a_rdata), 3396 TYPE("NS", ZONE_TYPE_NS, ZONE_CLASS_ANY, FIELDS(ns_rdata_fields), 3397 check_ns_rr, parse_ns_rdata), 3398 TYPE("MD", ZONE_TYPE_MD, ZONE_CLASS_ANY, FIELDS(md_rdata_fields), // obsolete 3399 check_ns_rr, parse_ns_rdata), 3400 TYPE("MF", ZONE_TYPE_MF, ZONE_CLASS_ANY, FIELDS(mf_rdata_fields), // obsolete 3401 check_ns_rr, parse_ns_rdata), 3402 TYPE("CNAME", ZONE_TYPE_CNAME, ZONE_CLASS_ANY, FIELDS(cname_rdata_fields), 3403 check_ns_rr, parse_ns_rdata), 3404 TYPE("SOA", ZONE_TYPE_SOA, ZONE_CLASS_ANY, FIELDS(soa_rdata_fields), 3405 check_soa_rr, parse_soa_rdata), 3406 TYPE("MB", ZONE_TYPE_MB, ZONE_CLASS_ANY, FIELDS(mb_rdata_fields), // experimental 3407 check_ns_rr, parse_ns_rdata), 3408 TYPE("MG", ZONE_TYPE_MG, ZONE_CLASS_ANY, FIELDS(mg_rdata_fields), // experimental 3409 check_ns_rr, parse_ns_rdata), 3410 TYPE("MR", ZONE_TYPE_MR, ZONE_CLASS_ANY, FIELDS(mr_rdata_fields), // experimental 3411 check_ns_rr, parse_ns_rdata), 3412 TYPE("NULL", ZONE_TYPE_NULL, ZONE_CLASS_ANY, FIELDS(null_rdata_fields), // experimetal 3413 check_generic_rr, parse_unknown_rdata), 3414 TYPE("WKS", ZONE_TYPE_WKS, ZONE_CLASS_IN, FIELDS(wks_rdata_fields), 3415 check_wks_rr, parse_wks_rdata), 3416 TYPE("PTR", ZONE_TYPE_PTR, ZONE_CLASS_ANY, FIELDS(ptr_rdata_fields), 3417 check_ns_rr, parse_ns_rdata), 3418 TYPE("HINFO", ZONE_TYPE_HINFO, ZONE_CLASS_ANY, FIELDS(hinfo_rdata_fields), 3419 check_hinfo_rr, parse_hinfo_rdata), 3420 TYPE("MINFO", ZONE_TYPE_MINFO, ZONE_CLASS_ANY, FIELDS(minfo_rdata_fields), 3421 check_minfo_rr, parse_minfo_rdata), 3422 TYPE("MX", ZONE_TYPE_MX, ZONE_CLASS_ANY, FIELDS(mx_rdata_fields), 3423 check_mx_rr, parse_mx_rdata), 3424 TYPE("TXT", ZONE_TYPE_TXT, ZONE_CLASS_ANY, FIELDS(txt_rdata_fields), 3425 check_txt_rr, parse_txt_rdata), 3426 TYPE("RP", ZONE_TYPE_RP, ZONE_CLASS_ANY, FIELDS(rp_rdata_fields), 3427 check_minfo_rr, parse_minfo_rdata), 3428 TYPE("AFSDB", ZONE_TYPE_AFSDB, ZONE_CLASS_ANY, FIELDS(afsdb_rdata_fields), 3429 check_mx_rr, parse_mx_rdata), 3430 TYPE("X25", ZONE_TYPE_X25, ZONE_CLASS_ANY, FIELDS(x25_rdata_fields), 3431 check_x25_rr, parse_x25_rdata), 3432 TYPE("ISDN", ZONE_TYPE_ISDN, ZONE_CLASS_ANY, FIELDS(isdn_rdata_fields), 3433 check_isdn_rr, parse_isdn_rdata), 3434 TYPE("RT", ZONE_TYPE_RT, ZONE_CLASS_ANY, FIELDS(rt_rdata_fields), 3435 check_rt_rr, parse_rt_rdata), 3436 TYPE("NSAP", ZONE_TYPE_NSAP, ZONE_CLASS_IN, FIELDS(nsap_rdata_fields), 3437 check_nsap_rr, parse_nsap_rdata), 3438 TYPE("NSAP-PTR", ZONE_TYPE_NSAP_PTR, ZONE_CLASS_IN, FIELDS(nsap_ptr_rdata_fields), 3439 check_nsap_ptr_rr, parse_nsap_ptr_rdata), 3440 TYPE("SIG", ZONE_TYPE_SIG, ZONE_CLASS_ANY, FIELDS(sig_rdata_fields), 3441 check_rrsig_rr, parse_rrsig_rdata), 3442 TYPE("KEY", ZONE_TYPE_KEY, ZONE_CLASS_ANY, FIELDS(key_rdata_fields), 3443 check_key_rr, parse_key_rdata), 3444 TYPE("PX", ZONE_TYPE_PX, ZONE_CLASS_IN, FIELDS(px_rdata_fields), 3445 check_px_rr, parse_px_rdata), 3446 TYPE("GPOS", ZONE_TYPE_GPOS, ZONE_CLASS_ANY, FIELDS(gpos_rdata_fields), 3447 check_gpos_rr, parse_gpos_rdata), 3448 TYPE("AAAA", ZONE_TYPE_AAAA, ZONE_CLASS_IN, FIELDS(aaaa_rdata_fields), 3449 check_aaaa_rr, parse_aaaa_rdata), 3450 TYPE("LOC", ZONE_TYPE_LOC, ZONE_CLASS_ANY, FIELDS(loc_rdata_fields), 3451 check_loc_rr, parse_loc_rdata), 3452 TYPE("NXT", ZONE_TYPE_NXT, ZONE_CLASS_ANY, FIELDS(nxt_rdata_fields), // obsolete 3453 check_nxt_rr, parse_nxt_rdata), 3454 TYPE("EID", ZONE_TYPE_EID, ZONE_CLASS_IN, FIELDS(eid_rdata_fields), 3455 check_eid_rr, parse_eid_rdata), 3456 TYPE("NIMLOC", ZONE_TYPE_NIMLOC, ZONE_CLASS_IN, FIELDS(nimloc_rdata_fields), 3457 check_eid_rr, parse_eid_rdata), 3458 TYPE("SRV", ZONE_TYPE_SRV, ZONE_CLASS_IN, FIELDS(srv_rdata_fields), 3459 check_srv_rr, parse_srv_rdata), 3460 TYPE("ATMA", ZONE_TYPE_ATMA, ZONE_CLASS_IN, FIELDS(atma_rdata_fields), 3461 check_atma_rr, parse_atma_rdata), 3462 TYPE("NAPTR", ZONE_TYPE_NAPTR, ZONE_CLASS_IN, FIELDS(naptr_rdata_fields), 3463 check_naptr_rr, parse_naptr_rdata), 3464 TYPE("KX", ZONE_TYPE_KX, ZONE_CLASS_IN, FIELDS(kx_rdata_fields), 3465 check_mx_rr, parse_mx_rdata), 3466 TYPE("CERT", ZONE_TYPE_CERT, ZONE_CLASS_ANY, FIELDS(cert_rdata_fields), 3467 check_cert_rr, parse_cert_rdata), 3468 3469 UNKNOWN_TYPE(38), 3470 3471 TYPE("DNAME", ZONE_TYPE_DNAME, ZONE_CLASS_ANY, FIELDS(dname_rdata_fields), 3472 check_ns_rr, parse_ns_rdata), 3473 3474 TYPE("SINK", ZONE_TYPE_SINK, ZONE_CLASS_ANY, FIELDS(sink_rdata_fields), 3475 check_sink_rr, parse_sink_rdata), 3476 UNKNOWN_TYPE(41), 3477 3478 TYPE("APL", ZONE_TYPE_APL, ZONE_CLASS_IN, FIELDS(apl_rdata_fields), 3479 check_apl_rr, parse_apl_rdata), 3480 TYPE("DS", ZONE_TYPE_DS, ZONE_CLASS_ANY, FIELDS(ds_rdata_fields), 3481 check_ds_rr, parse_ds_rdata), 3482 TYPE("SSHFP", ZONE_TYPE_SSHFP, ZONE_CLASS_ANY, FIELDS(sshfp_rdata_fields), 3483 check_sshfp_rr, parse_sshfp_rdata), 3484 TYPE("IPSECKEY", ZONE_TYPE_IPSECKEY, ZONE_CLASS_IN, FIELDS(ipseckey_rdata_fields), 3485 check_ipseckey_rr, parse_ipseckey_rdata), 3486 TYPE("RRSIG", ZONE_TYPE_RRSIG, ZONE_CLASS_ANY, FIELDS(rrsig_rdata_fields), 3487 check_rrsig_rr, parse_rrsig_rdata), 3488 TYPE("NSEC", ZONE_TYPE_NSEC, ZONE_CLASS_ANY, FIELDS(nsec_rdata_fields), 3489 check_nsec_rr, parse_nsec_rdata), 3490 TYPE("DNSKEY", ZONE_TYPE_DNSKEY, ZONE_CLASS_ANY, FIELDS(dnskey_rdata_fields), 3491 check_dnskey_rr, parse_dnskey_rdata), 3492 TYPE("DHCID", ZONE_TYPE_DHCID, ZONE_CLASS_IN, FIELDS(dhcid_rdata_fields), 3493 check_dhcid_rr, parse_dhcid_rdata), 3494 TYPE("NSEC3", ZONE_TYPE_NSEC3, ZONE_CLASS_ANY, FIELDS(nsec3_rdata_fields), 3495 check_nsec3_rr, parse_nsec3_rdata), 3496 TYPE("NSEC3PARAM", ZONE_TYPE_NSEC3PARAM, ZONE_CLASS_ANY, FIELDS(nsec3param_rdata_fields), 3497 check_nsec3param_rr, parse_nsec3param_rdata), 3498 TYPE("TLSA", ZONE_TYPE_TLSA, ZONE_CLASS_ANY, FIELDS(tlsa_rdata_fields), 3499 check_tlsa_rr, parse_tlsa_rdata), 3500 TYPE("SMIMEA", ZONE_TYPE_SMIMEA, ZONE_CLASS_ANY, FIELDS(smimea_rdata_fields), 3501 check_tlsa_rr, parse_tlsa_rdata), 3502 3503 UNKNOWN_TYPE(54), 3504 3505 TYPE("HIP", ZONE_TYPE_HIP, ZONE_CLASS_ANY, FIELDS(hip_rdata_fields), 3506 check_hip_rr, parse_hip_rdata), 3507 TYPE("NINFO", ZONE_TYPE_NINFO, ZONE_CLASS_ANY, FIELDS(ninfo_rdata_fields), 3508 check_txt_rr, parse_txt_rdata), 3509 TYPE("RKEY", ZONE_TYPE_RKEY, ZONE_CLASS_ANY, FIELDS(rkey_rdata_fields), 3510 check_dnskey_rr, parse_dnskey_rdata), 3511 TYPE("TALINK", ZONE_TYPE_TALINK, ZONE_CLASS_ANY, FIELDS(talink_rdata_fields), 3512 check_minfo_rr, parse_minfo_rdata), 3513 TYPE("CDS", ZONE_TYPE_CDS, ZONE_CLASS_ANY, FIELDS(cds_rdata_fields), 3514 check_ds_rr, parse_ds_rdata), 3515 TYPE("CDNSKEY", ZONE_TYPE_CDNSKEY, ZONE_CLASS_ANY, FIELDS(cdnskey_rdata_fields), 3516 check_dnskey_rr, parse_dnskey_rdata), 3517 TYPE("OPENPGPKEY", ZONE_TYPE_OPENPGPKEY, ZONE_CLASS_ANY, FIELDS(openpgpkey_rdata_fields), 3518 check_openpgpkey_rr, parse_openpgpkey_rdata), 3519 TYPE("CSYNC", ZONE_TYPE_CSYNC, ZONE_CLASS_ANY, FIELDS(csync_rdata_fields), 3520 check_csync_rr, parse_csync_rdata), 3521 TYPE("ZONEMD", ZONE_TYPE_ZONEMD, ZONE_CLASS_ANY, FIELDS(zonemd_rdata_fields), 3522 check_zonemd_rr, parse_zonemd_rdata), 3523 TYPE("SVCB", ZONE_TYPE_SVCB, ZONE_CLASS_IN, FIELDS(svcb_rdata_fields), 3524 check_svcb_rr, parse_svcb_rdata), 3525 TYPE("HTTPS", ZONE_TYPE_HTTPS, ZONE_CLASS_IN, FIELDS(https_rdata_fields), 3526 check_https_rr, parse_https_rdata), 3527 TYPE("DSYNC", ZONE_TYPE_DSYNC, ZONE_CLASS_ANY, FIELDS(dsync_rdata_fields), 3528 check_dsync_rr, parse_dsync_rdata), 3529 UNKNOWN_TYPE(67), 3530 UNKNOWN_TYPE(68), 3531 UNKNOWN_TYPE(69), 3532 UNKNOWN_TYPE(70), 3533 UNKNOWN_TYPE(71), 3534 UNKNOWN_TYPE(72), 3535 UNKNOWN_TYPE(73), 3536 UNKNOWN_TYPE(74), 3537 UNKNOWN_TYPE(75), 3538 UNKNOWN_TYPE(76), 3539 UNKNOWN_TYPE(77), 3540 UNKNOWN_TYPE(78), 3541 UNKNOWN_TYPE(79), 3542 UNKNOWN_TYPE(80), 3543 UNKNOWN_TYPE(81), 3544 UNKNOWN_TYPE(82), 3545 UNKNOWN_TYPE(83), 3546 UNKNOWN_TYPE(84), 3547 UNKNOWN_TYPE(85), 3548 UNKNOWN_TYPE(86), 3549 UNKNOWN_TYPE(87), 3550 UNKNOWN_TYPE(88), 3551 UNKNOWN_TYPE(89), 3552 UNKNOWN_TYPE(90), 3553 UNKNOWN_TYPE(91), 3554 UNKNOWN_TYPE(92), 3555 UNKNOWN_TYPE(93), 3556 UNKNOWN_TYPE(94), 3557 UNKNOWN_TYPE(95), 3558 UNKNOWN_TYPE(96), 3559 UNKNOWN_TYPE(97), 3560 UNKNOWN_TYPE(98), 3561 3562 TYPE("SPF", ZONE_TYPE_SPF, ZONE_CLASS_ANY, FIELDS(spf_rdata_fields), // obsolete 3563 check_txt_rr, parse_txt_rdata), 3564 3565 UNKNOWN_TYPE(100), 3566 UNKNOWN_TYPE(101), 3567 UNKNOWN_TYPE(102), 3568 UNKNOWN_TYPE(103), 3569 3570 TYPE("NID", ZONE_TYPE_NID, ZONE_CLASS_ANY, FIELDS(nid_rdata_fields), 3571 check_nid_rr, parse_nid_rdata), 3572 TYPE("L32", ZONE_TYPE_L32, ZONE_CLASS_ANY, FIELDS(l32_rdata_fields), 3573 check_l32_rr, parse_l32_rdata), 3574 TYPE("L64", ZONE_TYPE_L64, ZONE_CLASS_ANY, FIELDS(l64_rdata_fields), 3575 check_l64_rr, parse_l64_rdata), 3576 TYPE("LP", ZONE_TYPE_LP, ZONE_CLASS_ANY, FIELDS(lp_rdata_fields), 3577 check_mx_rr, parse_mx_rdata), 3578 TYPE("EUI48", ZONE_TYPE_EUI48, ZONE_CLASS_ANY, FIELDS(eui48_rdata_fields), 3579 check_eui48_rr, parse_eui48_rdata), 3580 TYPE("EUI64", ZONE_TYPE_EUI64, ZONE_CLASS_ANY, FIELDS(eui64_rdata_fields), 3581 check_eui64_rr, parse_eui64_rdata), 3582 3583 UNKNOWN_TYPE(110), 3584 UNKNOWN_TYPE(111), 3585 UNKNOWN_TYPE(112), 3586 UNKNOWN_TYPE(113), 3587 UNKNOWN_TYPE(114), 3588 UNKNOWN_TYPE(115), 3589 UNKNOWN_TYPE(116), 3590 UNKNOWN_TYPE(117), 3591 UNKNOWN_TYPE(118), 3592 UNKNOWN_TYPE(119), 3593 UNKNOWN_TYPE(120), 3594 UNKNOWN_TYPE(121), 3595 UNKNOWN_TYPE(122), 3596 UNKNOWN_TYPE(123), 3597 UNKNOWN_TYPE(124), 3598 UNKNOWN_TYPE(125), 3599 UNKNOWN_TYPE(126), 3600 UNKNOWN_TYPE(127), 3601 UNKNOWN_TYPE(128), 3602 UNKNOWN_TYPE(129), 3603 UNKNOWN_TYPE(130), 3604 UNKNOWN_TYPE(131), 3605 UNKNOWN_TYPE(132), 3606 UNKNOWN_TYPE(133), 3607 UNKNOWN_TYPE(134), 3608 UNKNOWN_TYPE(135), 3609 UNKNOWN_TYPE(136), 3610 UNKNOWN_TYPE(137), 3611 UNKNOWN_TYPE(138), 3612 UNKNOWN_TYPE(139), 3613 UNKNOWN_TYPE(140), 3614 UNKNOWN_TYPE(141), 3615 UNKNOWN_TYPE(142), 3616 UNKNOWN_TYPE(143), 3617 UNKNOWN_TYPE(144), 3618 UNKNOWN_TYPE(145), 3619 UNKNOWN_TYPE(146), 3620 UNKNOWN_TYPE(147), 3621 UNKNOWN_TYPE(148), 3622 UNKNOWN_TYPE(149), 3623 UNKNOWN_TYPE(150), 3624 UNKNOWN_TYPE(151), 3625 UNKNOWN_TYPE(152), 3626 UNKNOWN_TYPE(153), 3627 UNKNOWN_TYPE(154), 3628 UNKNOWN_TYPE(155), 3629 UNKNOWN_TYPE(156), 3630 UNKNOWN_TYPE(157), 3631 UNKNOWN_TYPE(158), 3632 UNKNOWN_TYPE(159), 3633 UNKNOWN_TYPE(160), 3634 UNKNOWN_TYPE(161), 3635 UNKNOWN_TYPE(162), 3636 UNKNOWN_TYPE(163), 3637 UNKNOWN_TYPE(164), 3638 UNKNOWN_TYPE(165), 3639 UNKNOWN_TYPE(166), 3640 UNKNOWN_TYPE(167), 3641 UNKNOWN_TYPE(168), 3642 UNKNOWN_TYPE(169), 3643 UNKNOWN_TYPE(170), 3644 UNKNOWN_TYPE(171), 3645 UNKNOWN_TYPE(172), 3646 UNKNOWN_TYPE(173), 3647 UNKNOWN_TYPE(174), 3648 UNKNOWN_TYPE(175), 3649 UNKNOWN_TYPE(176), 3650 UNKNOWN_TYPE(177), 3651 UNKNOWN_TYPE(178), 3652 UNKNOWN_TYPE(179), 3653 UNKNOWN_TYPE(180), 3654 UNKNOWN_TYPE(181), 3655 UNKNOWN_TYPE(182), 3656 UNKNOWN_TYPE(183), 3657 UNKNOWN_TYPE(184), 3658 UNKNOWN_TYPE(185), 3659 UNKNOWN_TYPE(186), 3660 UNKNOWN_TYPE(187), 3661 UNKNOWN_TYPE(188), 3662 UNKNOWN_TYPE(189), 3663 UNKNOWN_TYPE(190), 3664 UNKNOWN_TYPE(191), 3665 UNKNOWN_TYPE(192), 3666 UNKNOWN_TYPE(193), 3667 UNKNOWN_TYPE(194), 3668 UNKNOWN_TYPE(195), 3669 UNKNOWN_TYPE(196), 3670 UNKNOWN_TYPE(197), 3671 UNKNOWN_TYPE(198), 3672 UNKNOWN_TYPE(199), 3673 UNKNOWN_TYPE(200), 3674 UNKNOWN_TYPE(201), 3675 UNKNOWN_TYPE(202), 3676 UNKNOWN_TYPE(203), 3677 UNKNOWN_TYPE(204), 3678 UNKNOWN_TYPE(205), 3679 UNKNOWN_TYPE(206), 3680 UNKNOWN_TYPE(207), 3681 UNKNOWN_TYPE(208), 3682 UNKNOWN_TYPE(209), 3683 UNKNOWN_TYPE(210), 3684 UNKNOWN_TYPE(211), 3685 UNKNOWN_TYPE(212), 3686 UNKNOWN_TYPE(213), 3687 UNKNOWN_TYPE(214), 3688 UNKNOWN_TYPE(215), 3689 UNKNOWN_TYPE(216), 3690 UNKNOWN_TYPE(217), 3691 UNKNOWN_TYPE(218), 3692 UNKNOWN_TYPE(219), 3693 UNKNOWN_TYPE(220), 3694 UNKNOWN_TYPE(221), 3695 UNKNOWN_TYPE(222), 3696 UNKNOWN_TYPE(223), 3697 UNKNOWN_TYPE(224), 3698 UNKNOWN_TYPE(225), 3699 UNKNOWN_TYPE(226), 3700 UNKNOWN_TYPE(227), 3701 UNKNOWN_TYPE(228), 3702 UNKNOWN_TYPE(229), 3703 UNKNOWN_TYPE(230), 3704 UNKNOWN_TYPE(231), 3705 UNKNOWN_TYPE(232), 3706 UNKNOWN_TYPE(233), 3707 UNKNOWN_TYPE(234), 3708 UNKNOWN_TYPE(235), 3709 UNKNOWN_TYPE(236), 3710 UNKNOWN_TYPE(237), 3711 UNKNOWN_TYPE(238), 3712 UNKNOWN_TYPE(239), 3713 UNKNOWN_TYPE(240), 3714 UNKNOWN_TYPE(241), 3715 UNKNOWN_TYPE(242), 3716 UNKNOWN_TYPE(243), 3717 UNKNOWN_TYPE(244), 3718 UNKNOWN_TYPE(245), 3719 UNKNOWN_TYPE(246), 3720 UNKNOWN_TYPE(247), 3721 UNKNOWN_TYPE(248), 3722 UNKNOWN_TYPE(249), 3723 UNKNOWN_TYPE(250), 3724 UNKNOWN_TYPE(251), 3725 UNKNOWN_TYPE(252), 3726 UNKNOWN_TYPE(253), 3727 UNKNOWN_TYPE(254), 3728 UNKNOWN_TYPE(255), 3729 3730 TYPE("URI", ZONE_TYPE_URI, ZONE_CLASS_ANY, FIELDS(uri_rdata_fields), 3731 check_uri_rr, parse_uri_rdata), 3732 TYPE("CAA", ZONE_TYPE_CAA, ZONE_CLASS_ANY, FIELDS(caa_rdata_fields), 3733 check_caa_rr, parse_caa_rdata), 3734 TYPE("AVC", ZONE_TYPE_AVC, ZONE_CLASS_ANY, FIELDS(avc_rdata_fields), 3735 check_txt_rr, parse_txt_rdata), 3736 TYPE("DOA", ZONE_TYPE_DOA, ZONE_CLASS_ANY, FIELDS(doa_rdata_fields), 3737 check_doa_rr, parse_doa_rdata), 3738 TYPE("AMTRELAY", ZONE_TYPE_AMTRELAY, ZONE_CLASS_ANY, FIELDS(amtrelay_rdata_fields), 3739 check_amtrelay_rr, parse_amtrelay_rdata), 3740 TYPE("RESINFO", ZONE_TYPE_RESINFO, ZONE_CLASS_ANY, FIELDS(resinfo_rdata_fields), 3741 check_txt_rr, parse_txt_rdata), 3742 TYPE("WALLET", ZONE_TYPE_WALLET, ZONE_CLASS_ANY, FIELDS(wallet_rdata_fields), 3743 check_txt_rr, parse_txt_rdata), 3744 TYPE("CLA", ZONE_TYPE_CLA, ZONE_CLASS_ANY, FIELDS(cla_rdata_fields), 3745 check_txt_rr, parse_txt_rdata), 3746 TYPE("IPN", ZONE_TYPE_IPN, ZONE_CLASS_ANY, FIELDS(ipn_rdata_fields), 3747 check_ipn_rr, parse_ipn_rdata), 3748 3749 UNKNOWN_TYPE(265), 3750 UNKNOWN_TYPE(266), 3751 UNKNOWN_TYPE(267), 3752 UNKNOWN_TYPE(268), 3753 UNKNOWN_TYPE(269), 3754 3755 /* Map 32768 in hash.c to 270 */ 3756 TYPE("TA", ZONE_TYPE_TA, ZONE_CLASS_ANY, FIELDS(ta_rdata_fields), // obsolete 3757 check_ds_rr, parse_ds_rdata), 3758 /* Map 32769 in hash.c to 271 */ 3759 TYPE("DLV", ZONE_TYPE_DLV, ZONE_CLASS_ANY, FIELDS(dlv_rdata_fields), // obsolete 3760 check_ds_rr, parse_ds_rdata) 3761 }; 3762 3763 #undef UNKNOWN_CLASS 3764 #undef CLASS 3765 #undef UNKNOWN_TYPE 3766 #undef TYPE 3767 3768 diagnostic_pop() 3769 3770 #endif // TYPES_H 3771