rdata.h revision 170222
1/* 2 * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1998-2003 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id: rdata.h,v 1.60.18.3 2005/05/19 04:59:56 marka Exp $ */ 19 20#ifndef DNS_RDATA_H 21#define DNS_RDATA_H 1 22 23/***** 24 ***** Module Info 25 *****/ 26 27/*! \file 28 * \brief 29 * Provides facilities for manipulating DNS rdata, including conversions to 30 * and from wire format and text format. 31 * 32 * Given the large amount of rdata possible in a nameserver, it was important 33 * to come up with a very efficient way of storing rdata, but at the same 34 * time allow it to be manipulated. 35 * 36 * The decision was to store rdata in uncompressed wire format, 37 * and not to make it a fully abstracted object; i.e. certain parts of the 38 * server know rdata is stored that way. This saves a lot of memory, and 39 * makes adding rdata to messages easy. Having much of the server know 40 * the representation would be perilous, and we certainly don't want each 41 * user of rdata to be manipulating such a low-level structure. This is 42 * where the rdata module comes in. The module allows rdata handles to be 43 * created and attached to uncompressed wire format regions. All rdata 44 * operations and conversions are done through these handles. 45 * 46 * Implementation Notes: 47 * 48 *\li The routines in this module are expected to be synthesized by the 49 * build process from a set of source files, one per rdata type. For 50 * portability, it's probably best that the building be done by a C 51 * program. Adding a new rdata type will be a simple matter of adding 52 * a file to a directory and rebuilding the server. *All* knowlege of 53 * the format of a particular rdata type is in this file. 54 * 55 * MP: 56 *\li Clients of this module must impose any required synchronization. 57 * 58 * Reliability: 59 *\li This module deals with low-level byte streams. Errors in any of 60 * the functions are likely to crash the server or corrupt memory. 61 * 62 *\li Rdata is typed, and the caller must know what type of rdata it has. 63 * A caller that gets this wrong could crash the server. 64 * 65 *\li The fromstruct() and tostruct() routines use a void * pointer to 66 * represent the structure. The caller must ensure that it passes a 67 * pointer to the appropriate type, or the server could crash or memory 68 * could be corrupted. 69 * 70 * Resources: 71 *\li None. 72 * 73 * Security: 74 * 75 *\li *** WARNING *** 76 * dns_rdata_fromwire() deals with raw network data. An error in 77 * this routine could result in the failure or hijacking of the server. 78 * 79 * Standards: 80 *\li RFC1035 81 *\li Draft EDNS0 (0) 82 *\li Draft EDNS1 (0) 83 *\li Draft Binary Labels (2) 84 *\li Draft Local Compression (1) 85 *\li Various RFCs for particular types; these will be documented in the 86 * sources files of the types. 87 * 88 */ 89 90/*** 91 *** Imports 92 ***/ 93 94#include <isc/lang.h> 95 96#include <dns/types.h> 97#include <dns/name.h> 98 99ISC_LANG_BEGINDECLS 100 101 102/*** 103 *** Types 104 ***/ 105 106/*% 107 ***** An 'rdata' is a handle to a binary region. The handle has an RR 108 ***** class and type, and the data in the binary region is in the format 109 ***** of the given class and type. 110 *****/ 111/*% 112 * Clients are strongly discouraged from using this type directly, with 113 * the exception of the 'link' field which may be used directly for whatever 114 * purpose the client desires. 115 */ 116struct dns_rdata { 117 unsigned char * data; 118 unsigned int length; 119 dns_rdataclass_t rdclass; 120 dns_rdatatype_t type; 121 unsigned int flags; 122 ISC_LINK(dns_rdata_t) link; 123}; 124 125#define DNS_RDATA_INIT { NULL, 0, 0, 0, 0, {(void*)(-1), (void *)(-1)}} 126 127#define DNS_RDATA_UPDATE 0x0001 /*%< update pseudo record */ 128 129/* 130 * Flags affecting rdata formatting style. Flags 0xFFFF0000 131 * are used by masterfile-level formatting and defined elsewhere. 132 * See additional comments at dns_rdata_tofmttext(). 133 */ 134 135/*% Split the rdata into multiple lines to try to keep it 136 within the "width". */ 137#define DNS_STYLEFLAG_MULTILINE 0x00000001U 138 139/*% Output explanatory comments. */ 140#define DNS_STYLEFLAG_COMMENT 0x00000002U 141 142#define DNS_RDATA_DOWNCASE DNS_NAME_DOWNCASE 143#define DNS_RDATA_CHECKNAMES DNS_NAME_CHECKNAMES 144#define DNS_RDATA_CHECKNAMESFAIL DNS_NAME_CHECKNAMESFAIL 145#define DNS_RDATA_CHECKREVERSE DNS_NAME_CHECKREVERSE 146#define DNS_RDATA_CHECKMX DNS_NAME_CHECKMX 147#define DNS_RDATA_CHECKMXFAIL DNS_NAME_CHECKMXFAIL 148 149/*** 150 *** Initialization 151 ***/ 152 153void 154dns_rdata_init(dns_rdata_t *rdata); 155/*%< 156 * Make 'rdata' empty. 157 * 158 * Requires: 159 * 'rdata' is a valid rdata (i.e. not NULL, points to a struct dns_rdata) 160 */ 161 162void 163dns_rdata_reset(dns_rdata_t *rdata); 164/*%< 165 * Make 'rdata' empty. 166 * 167 * Requires: 168 *\li 'rdata' is a previously initialized rdata and is not linked. 169 */ 170 171void 172dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target); 173/*%< 174 * Clone 'target' from 'src'. 175 * 176 * Requires: 177 *\li 'src' to be initialized. 178 *\li 'target' to be initialized. 179 */ 180 181/*** 182 *** Comparisons 183 ***/ 184 185int 186dns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2); 187/*%< 188 * Determine the relative ordering under the DNSSEC order relation of 189 * 'rdata1' and 'rdata2'. 190 * 191 * Requires: 192 * 193 *\li 'rdata1' is a valid, non-empty rdata 194 * 195 *\li 'rdata2' is a valid, non-empty rdata 196 * 197 * Returns: 198 *\li < 0 'rdata1' is less than 'rdata2' 199 *\li 0 'rdata1' is equal to 'rdata2' 200 *\li > 0 'rdata1' is greater than 'rdata2' 201 */ 202 203/*** 204 *** Conversions 205 ***/ 206 207void 208dns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass, 209 dns_rdatatype_t type, isc_region_t *r); 210/*%< 211 * Make 'rdata' refer to region 'r'. 212 * 213 * Requires: 214 * 215 *\li The data in 'r' is properly formatted for whatever type it is. 216 */ 217 218void 219dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r); 220/*%< 221 * Make 'r' refer to 'rdata'. 222 */ 223 224isc_result_t 225dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass, 226 dns_rdatatype_t type, isc_buffer_t *source, 227 dns_decompress_t *dctx, unsigned int options, 228 isc_buffer_t *target); 229/*%< 230 * Copy the possibly-compressed rdata at source into the target region. 231 * 232 * Notes: 233 *\li Name decompression policy is controlled by 'dctx'. 234 * 235 * 'options' 236 *\li DNS_RDATA_DOWNCASE downcase domain names when they are copied 237 * into target. 238 * 239 * Requires: 240 * 241 *\li 'rdclass' and 'type' are valid. 242 * 243 *\li 'source' is a valid buffer, and the active region of 'source' 244 * references the rdata to be processed. 245 * 246 *\li 'target' is a valid buffer. 247 * 248 *\li 'dctx' is a valid decompression context. 249 * 250 * Ensures, 251 * if result is success: 252 * \li If 'rdata' is not NULL, it is attached to the target. 253 * \li The conditions dns_name_fromwire() ensures for names hold 254 * for all names in the rdata. 255 * \li The current location in source is advanced, and the used space 256 * in target is updated. 257 * 258 * Result: 259 *\li Success 260 *\li Any non-success status from dns_name_fromwire() 261 *\li Various 'Bad Form' class failures depending on class and type 262 *\li Bad Form: Input too short 263 *\li Resource Limit: Not enough space 264 */ 265 266isc_result_t 267dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx, 268 isc_buffer_t *target); 269/*%< 270 * Convert 'rdata' into wire format, compressing it as specified by the 271 * compression context 'cctx', and storing the result in 'target'. 272 * 273 * Notes: 274 *\li If the compression context allows global compression, then the 275 * global compression table may be updated. 276 * 277 * Requires: 278 *\li 'rdata' is a valid, non-empty rdata 279 * 280 *\li target is a valid buffer 281 * 282 *\li Any offsets specified in a global compression table are valid 283 * for target. 284 * 285 * Ensures, 286 * if the result is success: 287 * \li The used space in target is updated. 288 * 289 * Returns: 290 *\li Success 291 *\li Any non-success status from dns_name_towire() 292 *\li Resource Limit: Not enough space 293 */ 294 295isc_result_t 296dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass, 297 dns_rdatatype_t type, isc_lex_t *lexer, dns_name_t *origin, 298 unsigned int options, isc_mem_t *mctx, 299 isc_buffer_t *target, dns_rdatacallbacks_t *callbacks); 300/*%< 301 * Convert the textual representation of a DNS rdata into uncompressed wire 302 * form stored in the target region. Tokens constituting the text of the rdata 303 * are taken from 'lexer'. 304 * 305 * Notes: 306 *\li Relative domain names in the rdata will have 'origin' appended to them. 307 * A NULL origin implies "origin == dns_rootname". 308 * 309 * 310 * 'options' 311 *\li DNS_RDATA_DOWNCASE downcase domain names when they are copied 312 * into target. 313 *\li DNS_RDATA_CHECKNAMES perform checknames checks. 314 *\li DNS_RDATA_CHECKNAMESFAIL fail if the checknames check fail. If 315 * not set a warning will be issued. 316 *\li DNS_RDATA_CHECKREVERSE this should set if the owner name ends 317 * in IP6.ARPA, IP6.INT or IN-ADDR.ARPA. 318 * 319 * Requires: 320 * 321 *\li 'rdclass' and 'type' are valid. 322 * 323 *\li 'lexer' is a valid isc_lex_t. 324 * 325 *\li 'mctx' is a valid isc_mem_t. 326 * 327 *\li 'target' is a valid region. 328 * 329 *\li 'origin' if non NULL it must be absolute. 330 * 331 *\li 'callbacks' to be NULL or callbacks->warn and callbacks->error be 332 * initialized. 333 * 334 * Ensures, 335 * if result is success: 336 *\li If 'rdata' is not NULL, it is attached to the target. 337 338 *\li The conditions dns_name_fromtext() ensures for names hold 339 * for all names in the rdata. 340 341 *\li The used space in target is updated. 342 * 343 * Result: 344 *\li Success 345 *\li Translated result codes from isc_lex_gettoken 346 *\li Various 'Bad Form' class failures depending on class and type 347 *\li Bad Form: Input too short 348 *\li Resource Limit: Not enough space 349 *\li Resource Limit: Not enough memory 350 */ 351 352isc_result_t 353dns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target); 354/*%< 355 * Convert 'rdata' into text format, storing the result in 'target'. 356 * The text will consist of a single line, with fields separated by 357 * single spaces. 358 * 359 * Notes: 360 *\li If 'origin' is not NULL, then any names in the rdata that are 361 * subdomains of 'origin' will be made relative it. 362 * 363 *\li XXX Do we *really* want to support 'origin'? I'm inclined towards "no" 364 * at the moment. 365 * 366 * Requires: 367 * 368 *\li 'rdata' is a valid, non-empty rdata 369 * 370 *\li 'origin' is NULL, or is a valid name 371 * 372 *\li 'target' is a valid text buffer 373 * 374 * Ensures, 375 * if the result is success: 376 * 377 * \li The used space in target is updated. 378 * 379 * Returns: 380 *\li Success 381 *\li Any non-success status from dns_name_totext() 382 *\li Resource Limit: Not enough space 383 */ 384 385isc_result_t 386dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin, unsigned int flags, 387 unsigned int width, char *linebreak, isc_buffer_t *target); 388/*%< 389 * Like dns_rdata_totext, but do formatted output suitable for 390 * database dumps. This is intended for use by dns_db_dump(); 391 * library users are discouraged from calling it directly. 392 * 393 * If (flags & #DNS_STYLEFLAG_MULTILINE) != 0, attempt to stay 394 * within 'width' by breaking the text into multiple lines. 395 * The string 'linebreak' is inserted between lines, and parentheses 396 * are added when necessary. Because RRs contain unbreakable elements 397 * such as domain names whose length is variable, unpredictable, and 398 * potentially large, there is no guarantee that the lines will 399 * not exceed 'width' anyway. 400 * 401 * If (flags & #DNS_STYLEFLAG_MULTILINE) == 0, the rdata is always 402 * printed as a single line, and no parentheses are used. 403 * The 'width' and 'linebreak' arguments are ignored. 404 * 405 * If (flags & #DNS_STYLEFLAG_COMMENT) != 0, output explanatory 406 * comments next to things like the SOA timer fields. Some 407 * comments (e.g., the SOA ones) are only printed when multiline 408 * output is selected. 409 */ 410 411isc_result_t 412dns_rdata_fromstruct(dns_rdata_t *rdata, dns_rdataclass_t rdclass, 413 dns_rdatatype_t type, void *source, isc_buffer_t *target); 414/*%< 415 * Convert the C structure representation of an rdata into uncompressed wire 416 * format in 'target'. 417 * 418 * XXX Should we have a 'size' parameter as a sanity check on target? 419 * 420 * Requires: 421 * 422 *\li 'rdclass' and 'type' are valid. 423 * 424 *\li 'source' points to a valid C struct for the class and type. 425 * 426 *\li 'target' is a valid buffer. 427 * 428 *\li All structure pointers to memory blocks should be NULL if their 429 * corresponding length values are zero. 430 * 431 * Ensures, 432 * if result is success: 433 * \li If 'rdata' is not NULL, it is attached to the target. 434 * 435 * \li The used space in 'target' is updated. 436 * 437 * Result: 438 *\li Success 439 *\li Various 'Bad Form' class failures depending on class and type 440 *\li Resource Limit: Not enough space 441 */ 442 443isc_result_t 444dns_rdata_tostruct(dns_rdata_t *rdata, void *target, isc_mem_t *mctx); 445/*%< 446 * Convert an rdata into its C structure representation. 447 * 448 * If 'mctx' is NULL then 'rdata' must persist while 'target' is being used. 449 * 450 * If 'mctx' is non NULL then memory will be allocated if required. 451 * 452 * Requires: 453 * 454 *\li 'rdata' is a valid, non-empty rdata. 455 * 456 *\li 'target' to point to a valid pointer for the type and class. 457 * 458 * Result: 459 *\li Success 460 *\li Resource Limit: Not enough memory 461 */ 462 463void 464dns_rdata_freestruct(void *source); 465/*%< 466 * Free dynamic memory attached to 'source' (if any). 467 * 468 * Requires: 469 * 470 *\li 'source' to point to the structure previously filled in by 471 * dns_rdata_tostruct(). 472 */ 473 474isc_boolean_t 475dns_rdatatype_ismeta(dns_rdatatype_t type); 476/*%< 477 * Return true iff the rdata type 'type' is a meta-type 478 * like ANY or AXFR. 479 */ 480 481isc_boolean_t 482dns_rdatatype_issingleton(dns_rdatatype_t type); 483/*%< 484 * Return true iff the rdata type 'type' is a singleton type, 485 * like CNAME or SOA. 486 * 487 * Requires: 488 * \li 'type' is a valid rdata type. 489 * 490 */ 491 492isc_boolean_t 493dns_rdataclass_ismeta(dns_rdataclass_t rdclass); 494/*%< 495 * Return true iff the rdata class 'rdclass' is a meta-class 496 * like ANY or NONE. 497 */ 498 499isc_boolean_t 500dns_rdatatype_isdnssec(dns_rdatatype_t type); 501/*%< 502 * Return true iff 'type' is one of the DNSSEC 503 * rdata types that may exist alongside a CNAME record. 504 * 505 * Requires: 506 * \li 'type' is a valid rdata type. 507 */ 508 509isc_boolean_t 510dns_rdatatype_iszonecutauth(dns_rdatatype_t type); 511/*%< 512 * Return true iff rdata of type 'type' is considered authoritative 513 * data (not glue) in the NSEC chain when it occurs in the parent zone 514 * at a zone cut. 515 * 516 * Requires: 517 * \li 'type' is a valid rdata type. 518 * 519 */ 520 521isc_boolean_t 522dns_rdatatype_isknown(dns_rdatatype_t type); 523/*%< 524 * Return true iff the rdata type 'type' is known. 525 * 526 * Requires: 527 * \li 'type' is a valid rdata type. 528 * 529 */ 530 531 532isc_result_t 533dns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add, 534 void *arg); 535/*%< 536 * Call 'add' for each name and type from 'rdata' which is subject to 537 * additional section processing. 538 * 539 * Requires: 540 * 541 *\li 'rdata' is a valid, non-empty rdata. 542 * 543 *\li 'add' is a valid dns_additionalfunc_t. 544 * 545 * Ensures: 546 * 547 *\li If successful, then add() will have been called for each name 548 * and type subject to additional section processing. 549 * 550 *\li If add() returns something other than #ISC_R_SUCCESS, that result 551 * will be returned as the result of dns_rdata_additionaldata(). 552 * 553 * Returns: 554 * 555 *\li ISC_R_SUCCESS 556 * 557 *\li Many other results are possible if not successful. 558 */ 559 560isc_result_t 561dns_rdata_digest(dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg); 562/*%< 563 * Send 'rdata' in DNSSEC canonical form to 'digest'. 564 * 565 * Note: 566 *\li 'digest' may be called more than once by dns_rdata_digest(). The 567 * concatenation of all the regions, in the order they were given 568 * to 'digest', will be the DNSSEC canonical form of 'rdata'. 569 * 570 * Requires: 571 * 572 *\li 'rdata' is a valid, non-empty rdata. 573 * 574 *\li 'digest' is a valid dns_digestfunc_t. 575 * 576 * Ensures: 577 * 578 *\li If successful, then all of the rdata's data has been sent, in 579 * DNSSEC canonical form, to 'digest'. 580 * 581 *\li If digest() returns something other than ISC_R_SUCCESS, that result 582 * will be returned as the result of dns_rdata_digest(). 583 * 584 * Returns: 585 * 586 *\li ISC_R_SUCCESS 587 * 588 *\li Many other results are possible if not successful. 589 */ 590 591isc_boolean_t 592dns_rdatatype_questiononly(dns_rdatatype_t type); 593/*%< 594 * Return true iff rdata of type 'type' can only appear in the question 595 * section of a properly formatted message. 596 * 597 * Requires: 598 * \li 'type' is a valid rdata type. 599 * 600 */ 601 602isc_boolean_t 603dns_rdatatype_notquestion(dns_rdatatype_t type); 604/*%< 605 * Return true iff rdata of type 'type' can not appear in the question 606 * section of a properly formatted message. 607 * 608 * Requires: 609 * \li 'type' is a valid rdata type. 610 * 611 */ 612 613isc_boolean_t 614dns_rdatatype_atparent(dns_rdatatype_t type); 615/*%< 616 * Return true iff rdata of type 'type' should appear at the parent of 617 * a zone cut. 618 * 619 * Requires: 620 * \li 'type' is a valid rdata type. 621 * 622 */ 623 624unsigned int 625dns_rdatatype_attributes(dns_rdatatype_t rdtype); 626/*%< 627 * Return attributes for the given type. 628 * 629 * Requires: 630 *\li 'rdtype' are known. 631 * 632 * Returns: 633 *\li a bitmask consisting of the following flags. 634 */ 635 636/*% only one may exist for a name */ 637#define DNS_RDATATYPEATTR_SINGLETON 0x00000001U 638/*% requires no other data be present */ 639#define DNS_RDATATYPEATTR_EXCLUSIVE 0x00000002U 640/*% Is a meta type */ 641#define DNS_RDATATYPEATTR_META 0x00000004U 642/*% Is a DNSSEC type, like RRSIG or NSEC */ 643#define DNS_RDATATYPEATTR_DNSSEC 0x00000008U 644/*% Is a zone cut authority type */ 645#define DNS_RDATATYPEATTR_ZONECUTAUTH 0x00000010U 646/*% Is reserved (unusable) */ 647#define DNS_RDATATYPEATTR_RESERVED 0x00000020U 648/*% Is an unknown type */ 649#define DNS_RDATATYPEATTR_UNKNOWN 0x00000040U 650/*% Is META, and can only be in a question section */ 651#define DNS_RDATATYPEATTR_QUESTIONONLY 0x00000080U 652/*% is META, and can NOT be in a question section */ 653#define DNS_RDATATYPEATTR_NOTQUESTION 0x00000100U 654/*% Is present at zone cuts in the parent, not the child */ 655#define DNS_RDATATYPEATTR_ATPARENT 0x00000200U 656 657dns_rdatatype_t 658dns_rdata_covers(dns_rdata_t *rdata); 659/*%< 660 * Return the rdatatype that this type covers. 661 * 662 * Requires: 663 *\li 'rdata' is a valid, non-empty rdata. 664 * 665 *\li 'rdata' is a type that covers other rdata types. 666 * 667 * Returns: 668 *\li The type covered. 669 */ 670 671isc_boolean_t 672dns_rdata_checkowner(dns_name_t* name, dns_rdataclass_t rdclass, 673 dns_rdatatype_t type, isc_boolean_t wildcard); 674/* 675 * Returns whether this is a valid ownername for this <type,class>. 676 * If wildcard is true allow the first label to be a wildcard if 677 * appropriate. 678 * 679 * Requires: 680 * 'name' is a valid name. 681 */ 682 683isc_boolean_t 684dns_rdata_checknames(dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad); 685/* 686 * Returns whether 'rdata' contains valid domain names. The checks are 687 * sensitive to the owner name. 688 * 689 * If 'bad' is non-NULL and a domain name fails the check the 690 * the offending name will be return in 'bad' by cloning from 691 * the 'rdata' contents. 692 * 693 * Requires: 694 * 'rdata' to be valid. 695 * 'owner' to be valid. 696 * 'bad' to be NULL or valid. 697 */ 698 699ISC_LANG_ENDDECLS 700 701#endif /* DNS_RDATA_H */ 702