1 /* 2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #ifndef DNS_RDATA_H 18 #define DNS_RDATA_H 1 19 20 /***** 21 ***** Module Info 22 *****/ 23 24 /*! \file dns/rdata.h 25 * \brief 26 * Provides facilities for manipulating DNS rdata, including conversions to 27 * and from wire format and text format. 28 * 29 * Given the large amount of rdata possible in a nameserver, it was important 30 * to come up with a very efficient way of storing rdata, but at the same 31 * time allow it to be manipulated. 32 * 33 * The decision was to store rdata in uncompressed wire format, 34 * and not to make it a fully abstracted object; i.e. certain parts of the 35 * server know rdata is stored that way. This saves a lot of memory, and 36 * makes adding rdata to messages easy. Having much of the server know 37 * the representation would be perilous, and we certainly don't want each 38 * user of rdata to be manipulating such a low-level structure. This is 39 * where the rdata module comes in. The module allows rdata handles to be 40 * created and attached to uncompressed wire format regions. All rdata 41 * operations and conversions are done through these handles. 42 * 43 * Implementation Notes: 44 * 45 *\li The routines in this module are expected to be synthesized by the 46 * build process from a set of source files, one per rdata type. For 47 * portability, it's probably best that the building be done by a C 48 * program. Adding a new rdata type will be a simple matter of adding 49 * a file to a directory and rebuilding the server. *All* knowledge of 50 * the format of a particular rdata type is in this file. 51 * 52 * MP: 53 *\li Clients of this module must impose any required synchronization. 54 * 55 * Reliability: 56 *\li This module deals with low-level byte streams. Errors in any of 57 * the functions are likely to crash the server or corrupt memory. 58 * 59 *\li Rdata is typed, and the caller must know what type of rdata it has. 60 * A caller that gets this wrong could crash the server. 61 * 62 *\li The fromstruct() and tostruct() routines use a void * pointer to 63 * represent the structure. The caller must ensure that it passes a 64 * pointer to the appropriate type, or the server could crash or memory 65 * could be corrupted. 66 * 67 * Resources: 68 *\li None. 69 * 70 * Security: 71 * 72 *\li *** WARNING *** 73 * dns_rdata_fromwire() deals with raw network data. An error in 74 * this routine could result in the failure or hijacking of the server. 75 * 76 * Standards: 77 *\li RFC1035 78 *\li Draft EDNS0 (0) 79 *\li Draft EDNS1 (0) 80 *\li Draft Binary Labels (2) 81 *\li Draft Local Compression (1) 82 *\li Various RFCs for particular types; these will be documented in the 83 * sources files of the types. 84 * 85 */ 86 87 /*** 88 *** Imports 89 ***/ 90 91 #include <dns/types.h> 92 #include <dns/name.h> 93 #include <dns/message.h> 94 95 /*** 96 *** Types 97 ***/ 98 99 typedef struct dns_rdatacommon { 100 dns_rdataclass_t rdclass; 101 dns_rdatatype_t rdtype; 102 ISC_LINK(struct dns_rdatacommon) link; 103 } dns_rdatacommon_t; 104 105 typedef struct dns_rdata_cname { 106 dns_rdatacommon_t common; 107 dns_name_t cname; 108 } dns_rdata_cname_t; 109 110 typedef struct dns_rdata_ns { 111 dns_rdatacommon_t common; 112 dns_name_t name; 113 } dns_rdata_ns_t; 114 115 typedef struct dns_rdata_soa { 116 dns_rdatacommon_t common; 117 dns_name_t origin; 118 dns_name_t contact; 119 uint32_t serial; /*%< host order */ 120 uint32_t refresh; /*%< host order */ 121 uint32_t retry; /*%< host order */ 122 uint32_t expire; /*%< host order */ 123 uint32_t minimum; /*%< host order */ 124 } dns_rdata_soa_t; 125 126 typedef struct dns_rdata_any_tsig { 127 dns_rdatacommon_t common; 128 dns_name_t algorithm; 129 uint64_t timesigned; 130 uint16_t fudge; 131 uint16_t siglen; 132 unsigned char * signature; 133 uint16_t originalid; 134 uint16_t error; 135 uint16_t otherlen; 136 unsigned char * other; 137 } dns_rdata_any_tsig_t; 138 139 /*% 140 ***** An 'rdata' is a handle to a binary region. The handle has an RR 141 ***** class and type, and the data in the binary region is in the format 142 ***** of the given class and type. 143 *****/ 144 /*% 145 * Clients are strongly discouraged from using this type directly, with 146 * the exception of the 'link' field which may be used directly for whatever 147 * purpose the client desires. 148 */ 149 struct dns_rdata { 150 unsigned char * data; 151 unsigned int length; 152 dns_rdataclass_t rdclass; 153 dns_rdatatype_t type; 154 unsigned int flags; 155 ISC_LINK(dns_rdata_t) link; 156 }; 157 158 #define DNS_RDATA_INIT { NULL, 0, 0, 0, 0, {(void*)(-1), (void *)(-1)}} 159 160 #define DNS_RDATA_INITIALIZED(rdata) \ 161 ((rdata)->data == NULL && (rdata)->length == 0 && \ 162 (rdata)->rdclass == 0 && (rdata)->type == 0 && (rdata)->flags == 0 && \ 163 !ISC_LINK_LINKED((rdata), link)) 164 165 #define DNS_RDATA_UPDATE 0x0001 /*%< update pseudo record. */ 166 #define DNS_RDATA_OFFLINE 0x0002 /*%< RRSIG has a offline key. */ 167 168 #define DNS_RDATA_VALIDFLAGS(rdata) \ 169 (((rdata)->flags & ~(DNS_RDATA_UPDATE|DNS_RDATA_OFFLINE)) == 0) 170 171 /* 172 * The maximum length of a RDATA that can be sent on the wire. 173 * Max packet size (65535) less header (12), less name (1), type (2), 174 * class (2), ttl(4), length (2). 175 * 176 * None of the defined types that support name compression can exceed 177 * this and all new types are to be sent uncompressed. 178 */ 179 180 #define DNS_RDATA_MAXLENGTH 65512U 181 182 /* 183 * Flags affecting rdata formatting style. Flags 0xFFFF0000 184 * are used by masterfile-level formatting and defined elsewhere. 185 * See additional comments at dns_rdata_tofmttext(). 186 */ 187 188 /*% Split the rdata into multiple lines to try to keep it 189 within the "width". */ 190 #define DNS_STYLEFLAG_MULTILINE 0x00000001ULL 191 192 /*% Output explanatory comments. */ 193 #define DNS_STYLEFLAG_COMMENT 0x00000002ULL 194 #define DNS_STYLEFLAG_RRCOMMENT 0x00000004ULL 195 196 /*% Output KEYDATA in human readable format. */ 197 #define DNS_STYLEFLAG_KEYDATA 0x00000008ULL 198 199 /*% Output textual RR type and RDATA in RFC 3597 unknown format */ 200 #define DNS_STYLEFLAG_UNKNOWNFORMAT 0x00000010ULL 201 202 #define DNS_RDATA_DOWNCASE DNS_NAME_DOWNCASE 203 #define DNS_RDATA_CHECKNAMES DNS_NAME_CHECKNAMES 204 #define DNS_RDATA_CHECKNAMESFAIL DNS_NAME_CHECKNAMESFAIL 205 #define DNS_RDATA_CHECKREVERSE DNS_NAME_CHECKREVERSE 206 #define DNS_RDATA_CHECKMX DNS_NAME_CHECKMX 207 #define DNS_RDATA_CHECKMXFAIL DNS_NAME_CHECKMXFAIL 208 #define DNS_RDATA_UNKNOWNESCAPE 0x80000000 209 210 /*** 211 *** Initialization 212 ***/ 213 214 void 215 dns_rdata_init(dns_rdata_t *rdata); 216 /*%< 217 * Make 'rdata' empty. 218 * 219 * Requires: 220 * 'rdata' is a valid rdata (i.e. not NULL, points to a struct dns_rdata) 221 */ 222 223 void 224 dns_rdata_reset(dns_rdata_t *rdata); 225 /*%< 226 * Make 'rdata' empty. 227 * 228 * Requires: 229 *\li 'rdata' is a previously initialized rdata and is not linked. 230 */ 231 232 void 233 dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target); 234 /*%< 235 * Clone 'target' from 'src'. 236 * 237 * Requires: 238 *\li 'src' to be initialized. 239 *\li 'target' to be initialized. 240 */ 241 242 /*** 243 *** Conversions 244 ***/ 245 246 void 247 dns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass, 248 dns_rdatatype_t type, isc_region_t *r); 249 /*%< 250 * Make 'rdata' refer to region 'r'. 251 * 252 * Requires: 253 * 254 *\li The data in 'r' is properly formatted for whatever type it is. 255 */ 256 257 void 258 dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r); 259 /*%< 260 * Make 'r' refer to 'rdata'. 261 */ 262 263 isc_result_t 264 dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass, 265 dns_rdatatype_t type, isc_buffer_t *source, 266 dns_decompress_t *dctx, unsigned int options, 267 isc_buffer_t *target); 268 /*%< 269 * Copy the possibly-compressed rdata at source into the target region. 270 * 271 * Notes: 272 *\li Name decompression policy is controlled by 'dctx'. 273 * 274 * 'options' 275 *\li DNS_RDATA_DOWNCASE downcase domain names when they are copied 276 * into target. 277 * 278 * Requires: 279 * 280 *\li 'rdclass' and 'type' are valid. 281 * 282 *\li 'source' is a valid buffer, and the active region of 'source' 283 * references the rdata to be processed. 284 * 285 *\li 'target' is a valid buffer. 286 * 287 *\li 'dctx' is a valid decompression context. 288 * 289 * Ensures, 290 * if result is success: 291 * \li If 'rdata' is not NULL, it is attached to the target. 292 * \li The conditions dns_name_fromwire() ensures for names hold 293 * for all names in the rdata. 294 * \li The current location in source is advanced, and the used space 295 * in target is updated. 296 * 297 * Result: 298 *\li Success 299 *\li Any non-success status from dns_name_fromwire() 300 *\li Various 'Bad Form' class failures depending on class and type 301 *\li Bad Form: Input too short 302 *\li Resource Limit: Not enough space 303 */ 304 305 isc_result_t 306 dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx, 307 isc_buffer_t *target); 308 /*%< 309 * Convert 'rdata' into wire format, compressing it as specified by the 310 * compression context 'cctx', and storing the result in 'target'. 311 * 312 * Notes: 313 *\li If the compression context allows global compression, then the 314 * global compression table may be updated. 315 * 316 * Requires: 317 *\li 'rdata' is a valid, non-empty rdata 318 * 319 *\li target is a valid buffer 320 * 321 *\li Any offsets specified in a global compression table are valid 322 * for target. 323 * 324 * Ensures, 325 * if the result is success: 326 * \li The used space in target is updated. 327 * 328 * Returns: 329 *\li Success 330 *\li Any non-success status from dns_name_towire() 331 *\li Resource Limit: Not enough space 332 */ 333 334 isc_result_t 335 dns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target); 336 /*%< 337 * Convert 'rdata' into text format, storing the result in 'target'. 338 * The text will consist of a single line, with fields separated by 339 * single spaces. 340 * 341 * Notes: 342 *\li If 'origin' is not NULL, then any names in the rdata that are 343 * subdomains of 'origin' will be made relative it. 344 * 345 *\li XXX Do we *really* want to support 'origin'? I'm inclined towards "no" 346 * at the moment. 347 * 348 * Requires: 349 * 350 *\li 'rdata' is a valid, non-empty rdata 351 * 352 *\li 'origin' is NULL, or is a valid name 353 * 354 *\li 'target' is a valid text buffer 355 * 356 * Ensures, 357 * if the result is success: 358 * 359 * \li The used space in target is updated. 360 * 361 * Returns: 362 *\li Success 363 *\li Any non-success status from dns_name_totext() 364 *\li Resource Limit: Not enough space 365 */ 366 367 isc_result_t 368 dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin, unsigned int flags, 369 unsigned int width, unsigned int split_width, 370 const char *linebreak, isc_buffer_t *target); 371 /*%< 372 * Like dns_rdata_totext, but do formatted output suitable for 373 * database dumps. This is intended for use by dns_db_dump(); 374 * library users are discouraged from calling it directly. 375 * 376 * If (flags & #DNS_STYLEFLAG_MULTILINE) != 0, attempt to stay 377 * within 'width' by breaking the text into multiple lines. 378 * The string 'linebreak' is inserted between lines, and parentheses 379 * are added when necessary. Because RRs contain unbreakable elements 380 * such as domain names whose length is variable, unpredictable, and 381 * potentially large, there is no guarantee that the lines will 382 * not exceed 'width' anyway. 383 * 384 * If (flags & #DNS_STYLEFLAG_MULTILINE) == 0, the rdata is always 385 * printed as a single line, and no parentheses are used. 386 * The 'width' and 'linebreak' arguments are ignored. 387 * 388 * If (flags & #DNS_STYLEFLAG_COMMENT) != 0, output explanatory 389 * comments next to things like the SOA timer fields. Some 390 * comments (e.g., the SOA ones) are only printed when multiline 391 * output is selected. 392 * 393 * base64 rdata text (e.g., DNSKEY records) will be split into chunks 394 * of 'split_width' characters. If split_width == 0, the text will 395 * not be split at all. If split_width == UINT_MAX (0xffffffff), then 396 * it is undefined and falls back to the default value of 'width' 397 */ 398 399 isc_result_t 400 dns_rdata_fromstruct_soa(dns_rdata_t *rdata, dns_rdataclass_t rdclass, 401 dns_rdatatype_t type, dns_rdata_soa_t *soa, 402 isc_buffer_t *target); 403 /*%< 404 * Convert the C structure representation of an rdata into uncompressed wire 405 * format in 'target'. 406 * 407 * XXX Should we have a 'size' parameter as a sanity check on target? 408 * 409 * Requires: 410 * 411 *\li 'rdclass' and 'type' are valid. 412 * 413 *\li 'source' points to a valid C struct for the class and type. 414 * 415 *\li 'target' is a valid buffer. 416 * 417 *\li All structure pointers to memory blocks should be NULL if their 418 * corresponding length values are zero. 419 * 420 * Ensures, 421 * if result is success: 422 * \li If 'rdata' is not NULL, it is attached to the target. 423 * 424 * \li The used space in 'target' is updated. 425 * 426 * Result: 427 *\li Success 428 *\li Various 'Bad Form' class failures depending on class and type 429 *\li Resource Limit: Not enough space 430 */ 431 432 isc_result_t 433 dns_rdata_fromstruct_tsig(dns_rdata_t *rdata, dns_rdataclass_t rdclass, 434 dns_rdatatype_t type, dns_rdata_any_tsig_t *tsig, 435 isc_buffer_t *target); 436 /*%< 437 * Convert the C structure representation of an rdata into uncompressed wire 438 * format in 'target'. 439 * 440 * XXX Should we have a 'size' parameter as a sanity check on target? 441 * 442 * Requires: 443 * 444 *\li 'rdclass' and 'type' are valid. 445 * 446 *\li 'source' points to a valid C struct for the class and type. 447 * 448 *\li 'target' is a valid buffer. 449 * 450 *\li All structure pointers to memory blocks should be NULL if their 451 * corresponding length values are zero. 452 * 453 * Ensures, 454 * if result is success: 455 * \li If 'rdata' is not NULL, it is attached to the target. 456 * 457 * \li The used space in 'target' is updated. 458 * 459 * Result: 460 *\li Success 461 *\li Various 'Bad Form' class failures depending on class and type 462 *\li Resource Limit: Not enough space 463 */ 464 465 isc_result_t 466 dns_rdata_tostruct_cname(const dns_rdata_t *rdata, dns_rdata_cname_t *cname); 467 /*%< 468 * Convert an rdata into its C structure representation. 469 * 470 * 471 * Requires: 472 * 473 *\li 'rdata' is a valid, non-empty rdata. 474 * 475 *\li 'cname' to point to a valid pointer for the type and class. 476 * 477 * Result: 478 *\li Success 479 *\li Resource Limit: Not enough memory 480 */ 481 482 isc_result_t 483 dns_rdata_tostruct_ns(const dns_rdata_t *rdata, dns_rdata_ns_t *ns); 484 /*%< 485 * Convert an rdata into its C structure representation. 486 * 487 * 488 * Requires: 489 * 490 *\li 'rdata' is a valid, non-empty rdata. 491 * 492 *\li 'ns' to point to a valid pointer for the type and class. 493 * 494 * Result: 495 *\li Success 496 *\li Resource Limit: Not enough memory 497 */ 498 499 isc_result_t 500 dns_rdata_tostruct_soa(const dns_rdata_t *rdata, dns_rdata_soa_t *soa); 501 /*%< 502 * Convert an rdata into its C structure representation. 503 * 504 * 505 * Requires: 506 * 507 *\li 'rdata' is a valid, non-empty rdata. 508 * 509 *\li 'soa' to point to a valid pointer for the type and class. 510 * 511 * Result: 512 *\li Success 513 *\li Resource Limit: Not enough memory 514 */ 515 516 isc_result_t 517 dns_rdata_tostruct_tsig(const dns_rdata_t *rdata, dns_rdata_any_tsig_t *tsig); 518 /*%< 519 * Convert an rdata into its C structure representation. 520 * 521 * 522 * Requires: 523 * 524 *\li 'rdata' is a valid, non-empty rdata. 525 * 526 *\li 'tsig' to point to a valid pointer for the type and class. 527 * 528 * Result: 529 *\li Success 530 *\li Resource Limit: Not enough memory 531 */ 532 533 void 534 dns_rdata_freestruct_cname(dns_rdata_cname_t *cname); 535 /*%< 536 * Free dynamic memory attached to 'cname' (if any). 537 * 538 * Requires: 539 * 540 *\li 'cname' to point to the structure previously filled in by 541 * dns_rdata_tostruct_cname(). 542 */ 543 544 void 545 dns_rdata_freestruct_ns(dns_rdata_ns_t *ns); 546 /*%< 547 * Free dynamic memory attached to 'ns' (if any). 548 * 549 * Requires: 550 * 551 *\li 'ns' to point to the structure previously filled in by 552 * dns_rdata_tostruct_ns(). 553 */ 554 555 void 556 dns_rdata_freestruct_soa(dns_rdata_soa_t *soa); 557 /*%< 558 * Free dynamic memory attached to 'soa' (if any). 559 * 560 * Requires: 561 * 562 *\li 'soa' to point to the structure previously filled in by 563 * dns_rdata_tostruct_soa(). 564 */ 565 566 void 567 dns_rdata_freestruct_tsig(dns_rdata_any_tsig_t *tsig); 568 /*%< 569 * Free dynamic memory attached to 'tsig' (if any). 570 * 571 * Requires: 572 * 573 *\li 'tsig' to point to the structure previously filled in by 574 * dns_rdata_tostruct_tsig(). 575 */ 576 577 unsigned int 578 dns_rdatatype_attributes(dns_rdatatype_t rdtype); 579 /*%< 580 * Return attributes for the given type. 581 * 582 * Requires: 583 *\li 'rdtype' are known. 584 * 585 * Returns: 586 *\li a bitmask consisting of the following flags. 587 */ 588 589 /*% Is reserved (unusable) */ 590 #define DNS_RDATATYPEATTR_RESERVED 0x00000020U 591 /*% Is an unknown type */ 592 #define DNS_RDATATYPEATTR_UNKNOWN 0x00000040U 593 594 dns_rdatatype_t 595 dns_rdata_covers(dns_rdata_t *rdata); 596 /*%< 597 * Return the rdatatype that this type covers. 598 * 599 * Requires: 600 *\li 'rdata' is a valid, non-empty rdata. 601 * 602 *\li 'rdata' is a type that covers other rdata types. 603 * 604 * Returns: 605 *\li The type covered. 606 */ 607 608 int 609 dns_rdata_checkowner_nsec3(dns_name_t* name, dns_rdataclass_t rdclass, 610 dns_rdatatype_t type, int wildcard); 611 /* 612 * Returns whether this is a valid ownername for this <type,class>. 613 * If wildcard is true allow the first label to be a wildcard if 614 * appropriate. 615 * 616 * Requires: 617 * 'name' is a valid name. 618 */ 619 620 #endif /* DNS_RDATA_H */ 621