1 /* $NetBSD: message.h,v 1.8 2014/12/10 04:37:58 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004-2010, 2012-2014 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1999-2003 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* Id */ 21 22 #ifndef DNS_MESSAGE_H 23 #define DNS_MESSAGE_H 1 24 25 /*** 26 *** Imports 27 ***/ 28 29 #include <isc/lang.h> 30 #include <isc/magic.h> 31 32 #include <dns/compress.h> 33 #include <dns/masterdump.h> 34 #include <dns/types.h> 35 36 #include <dst/dst.h> 37 38 /*! \file dns/message.h 39 * \brief Message Handling Module 40 * 41 * How this beast works: 42 * 43 * When a dns message is received in a buffer, dns_message_fromwire() is called 44 * on the memory region. Various items are checked including the format 45 * of the message (if counts are right, if counts consume the entire sections, 46 * and if sections consume the entire message) and known pseudo-RRs in the 47 * additional data section are analyzed and removed. 48 * 49 * TSIG checking is also done at this layer, and any DNSSEC transaction 50 * signatures should also be checked here. 51 * 52 * Notes on using the gettemp*() and puttemp*() functions: 53 * 54 * These functions return items (names, rdatasets, etc) allocated from some 55 * internal state of the dns_message_t. 56 * 57 * Names and rdatasets must be put back into the dns_message_t in 58 * one of two ways. Assume a name was allocated via 59 * dns_message_gettempname(): 60 * 61 *\li (1) insert it into a section, using dns_message_addname(). 62 * 63 *\li (2) return it to the message using dns_message_puttempname(). 64 * 65 * The same applies to rdatasets. 66 * 67 * On the other hand, offsets, rdatalists and rdatas allocated using 68 * dns_message_gettemp*() will always be freed automatically 69 * when the message is reset or destroyed; calling dns_message_puttemp*() 70 * on rdatalists and rdatas is optional and serves only to enable the item 71 * to be reused multiple times during the lifetime of the message; offsets 72 * cannot be reused. 73 * 74 * Buffers allocated using isc_buffer_allocate() can be automatically freed 75 * as well by giving the buffer to the message using dns_message_takebuffer(). 76 * Doing this will cause the buffer to be freed using isc_buffer_free() 77 * when the section lists are cleared, such as in a reset or in a destroy. 78 * Since the buffer itself exists until the message is destroyed, this sort 79 * of code can be written: 80 * 81 * \code 82 * buffer = isc_buffer_allocate(mctx, 512); 83 * name = NULL; 84 * name = dns_message_gettempname(message, &name); 85 * dns_name_init(name, NULL); 86 * result = dns_name_fromtext(name, &source, dns_rootname, 0, buffer); 87 * dns_message_takebuffer(message, &buffer); 88 * \endcode 89 * 90 * 91 * TODO: 92 * 93 * XXX Needed: ways to set and retrieve EDNS information, add rdata to a 94 * section, move rdata from one section to another, remove rdata, etc. 95 */ 96 97 #define DNS_MESSAGEFLAG_QR 0x8000U 98 #define DNS_MESSAGEFLAG_AA 0x0400U 99 #define DNS_MESSAGEFLAG_TC 0x0200U 100 #define DNS_MESSAGEFLAG_RD 0x0100U 101 #define DNS_MESSAGEFLAG_RA 0x0080U 102 #define DNS_MESSAGEFLAG_AD 0x0020U 103 #define DNS_MESSAGEFLAG_CD 0x0010U 104 105 /*%< EDNS0 extended message flags */ 106 #define DNS_MESSAGEEXTFLAG_DO 0x8000U 107 108 /*%< EDNS0 extended OPT codes */ 109 #define DNS_OPT_NSID 0x0003 /*%< NSID opt code */ 110 #define DNS_OPT_CLIENT_SUBNET 0x0008 /*%< client subnet opt code */ 111 #define DNS_OPT_EXPIRE 0x0009 /*%< EXPIRE opt code */ 112 113 /*%< Experimental options [65001...65534] as per RFC6891 */ 114 #define DNS_OPT_SIT 65001 /*%< SIT opt code */ 115 116 /*%< The number of EDNS options we know about. */ 117 #define DNS_EDNSOPTIONS 4 118 119 #define DNS_MESSAGE_REPLYPRESERVE (DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD) 120 #define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO) 121 122 #define DNS_MESSAGE_HEADERLEN 12 /*%< 6 isc_uint16_t's */ 123 124 #define DNS_MESSAGE_MAGIC ISC_MAGIC('M','S','G','@') 125 #define DNS_MESSAGE_VALID(msg) ISC_MAGIC_VALID(msg, DNS_MESSAGE_MAGIC) 126 127 /* 128 * Ordering here matters. DNS_SECTION_ANY must be the lowest and negative, 129 * and DNS_SECTION_MAX must be one greater than the last used section. 130 */ 131 typedef int dns_section_t; 132 #define DNS_SECTION_ANY (-1) 133 #define DNS_SECTION_QUESTION 0 134 #define DNS_SECTION_ANSWER 1 135 #define DNS_SECTION_AUTHORITY 2 136 #define DNS_SECTION_ADDITIONAL 3 137 #define DNS_SECTION_MAX 4 138 139 typedef int dns_pseudosection_t; 140 #define DNS_PSEUDOSECTION_ANY (-1) 141 #define DNS_PSEUDOSECTION_OPT 0 142 #define DNS_PSEUDOSECTION_TSIG 1 143 #define DNS_PSEUDOSECTION_SIG0 2 144 #define DNS_PSEUDOSECTION_MAX 3 145 146 typedef int dns_messagetextflag_t; 147 #define DNS_MESSAGETEXTFLAG_NOCOMMENTS 0x0001 148 #define DNS_MESSAGETEXTFLAG_NOHEADERS 0x0002 149 #define DNS_MESSAGETEXTFLAG_ONESOA 0x0004 150 #define DNS_MESSAGETEXTFLAG_OMITSOA 0x0008 151 #define DNS_MESSAGETEXTFLAG_COMMENTDATA 0x0010 152 153 /* 154 * Dynamic update names for these sections. 155 */ 156 #define DNS_SECTION_ZONE DNS_SECTION_QUESTION 157 #define DNS_SECTION_PREREQUISITE DNS_SECTION_ANSWER 158 #define DNS_SECTION_UPDATE DNS_SECTION_AUTHORITY 159 160 /* 161 * These tell the message library how the created dns_message_t will be used. 162 */ 163 #define DNS_MESSAGE_INTENTUNKNOWN 0 /*%< internal use only */ 164 #define DNS_MESSAGE_INTENTPARSE 1 /*%< parsing messages */ 165 #define DNS_MESSAGE_INTENTRENDER 2 /*%< rendering */ 166 167 /* 168 * Control behavior of parsing 169 */ 170 #define DNS_MESSAGEPARSE_PRESERVEORDER 0x0001 /*%< preserve rdata order */ 171 #define DNS_MESSAGEPARSE_BESTEFFORT 0x0002 /*%< return a message if a 172 recoverable parse error 173 occurs */ 174 #define DNS_MESSAGEPARSE_CLONEBUFFER 0x0004 /*%< save a copy of the 175 source buffer */ 176 #define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /*%< truncation errors are 177 * not fatal. */ 178 179 /* 180 * Control behavior of rendering 181 */ 182 #define DNS_MESSAGERENDER_ORDERED 0x0001 /*%< don't change order */ 183 #define DNS_MESSAGERENDER_PARTIAL 0x0002 /*%< allow a partial rdataset */ 184 #define DNS_MESSAGERENDER_OMITDNSSEC 0x0004 /*%< omit DNSSEC records */ 185 #define DNS_MESSAGERENDER_PREFER_A 0x0008 /*%< prefer A records in 186 additional section. */ 187 #define DNS_MESSAGERENDER_PREFER_AAAA 0x0010 /*%< prefer AAAA records in 188 additional section. */ 189 #ifdef ALLOW_FILTER_AAAA 190 #define DNS_MESSAGERENDER_FILTER_AAAA 0x0020 /*%< filter AAAA records */ 191 #endif 192 193 typedef struct dns_msgblock dns_msgblock_t; 194 195 struct dns_message { 196 /* public from here down */ 197 unsigned int magic; 198 199 dns_messageid_t id; 200 unsigned int flags; 201 dns_rcode_t rcode; 202 unsigned int opcode; 203 dns_rdataclass_t rdclass; 204 205 /* 4 real, 1 pseudo */ 206 unsigned int counts[DNS_SECTION_MAX]; 207 208 /* private from here down */ 209 dns_namelist_t sections[DNS_SECTION_MAX]; 210 dns_name_t *cursors[DNS_SECTION_MAX]; 211 dns_rdataset_t *opt; 212 dns_rdataset_t *sig0; 213 dns_rdataset_t *tsig; 214 215 int state; 216 unsigned int from_to_wire : 2; 217 unsigned int header_ok : 1; 218 unsigned int question_ok : 1; 219 unsigned int tcp_continuation : 1; 220 unsigned int verified_sig : 1; 221 unsigned int verify_attempted : 1; 222 unsigned int free_query : 1; 223 unsigned int free_saved : 1; 224 unsigned int sitok : 1; 225 unsigned int sitbad : 1; 226 227 unsigned int opt_reserved; 228 unsigned int sig_reserved; 229 unsigned int reserved; /* reserved space (render) */ 230 231 isc_buffer_t *buffer; 232 dns_compress_t *cctx; 233 234 isc_mem_t *mctx; 235 isc_mempool_t *namepool; 236 isc_mempool_t *rdspool; 237 238 isc_bufferlist_t scratchpad; 239 isc_bufferlist_t cleanup; 240 241 ISC_LIST(dns_msgblock_t) rdatas; 242 ISC_LIST(dns_msgblock_t) rdatalists; 243 ISC_LIST(dns_msgblock_t) offsets; 244 245 ISC_LIST(dns_rdata_t) freerdata; 246 ISC_LIST(dns_rdatalist_t) freerdatalist; 247 248 dns_rcode_t tsigstatus; 249 dns_rcode_t querytsigstatus; 250 dns_name_t *tsigname; /* Owner name of TSIG, if any */ 251 dns_rdataset_t *querytsig; 252 dns_tsigkey_t *tsigkey; 253 dst_context_t *tsigctx; 254 int sigstart; 255 int timeadjust; 256 257 dns_name_t *sig0name; /* Owner name of SIG0, if any */ 258 dst_key_t *sig0key; 259 dns_rcode_t sig0status; 260 isc_region_t query; 261 isc_region_t saved; 262 263 dns_rdatasetorderfunc_t order; 264 const void * order_arg; 265 }; 266 267 struct dns_ednsopt { 268 isc_uint16_t code; 269 isc_uint16_t length; 270 unsigned char *value; 271 }; 272 273 /*** 274 *** Functions 275 ***/ 276 277 ISC_LANG_BEGINDECLS 278 279 isc_result_t 280 dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp); 281 282 /*%< 283 * Create msg structure. 284 * 285 * This function will allocate some internal blocks of memory that are 286 * expected to be needed for parsing or rendering nearly any type of message. 287 * 288 * Requires: 289 *\li 'mctx' be a valid memory context. 290 * 291 *\li 'msgp' be non-null and '*msg' be NULL. 292 * 293 *\li 'intent' must be one of DNS_MESSAGE_INTENTPARSE or 294 * #DNS_MESSAGE_INTENTRENDER. 295 * 296 * Ensures: 297 *\li The data in "*msg" is set to indicate an unused and empty msg 298 * structure. 299 * 300 * Returns: 301 *\li #ISC_R_NOMEMORY -- out of memory 302 *\li #ISC_R_SUCCESS -- success 303 */ 304 305 void 306 dns_message_reset(dns_message_t *msg, unsigned int intent); 307 /*%< 308 * Reset a message structure to default state. All internal lists are freed 309 * or reset to a default state as well. This is simply a more efficient 310 * way to call dns_message_destroy() followed by dns_message_allocate(), 311 * since it avoid many memory allocations. 312 * 313 * If any data loanouts (buffers, names, rdatas, etc) were requested, 314 * the caller must no longer use them after this call. 315 * 316 * The intended next use of the message will be 'intent'. 317 * 318 * Requires: 319 * 320 *\li 'msg' be valid. 321 * 322 *\li 'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER 323 */ 324 325 void 326 dns_message_destroy(dns_message_t **msgp); 327 /*%< 328 * Destroy all state in the message. 329 * 330 * Requires: 331 * 332 *\li 'msgp' be valid. 333 * 334 * Ensures: 335 *\li '*msgp' == NULL 336 */ 337 338 isc_result_t 339 dns_message_sectiontotext(dns_message_t *msg, dns_section_t section, 340 const dns_master_style_t *style, 341 dns_messagetextflag_t flags, 342 isc_buffer_t *target); 343 344 isc_result_t 345 dns_message_pseudosectiontotext(dns_message_t *msg, 346 dns_pseudosection_t section, 347 const dns_master_style_t *style, 348 dns_messagetextflag_t flags, 349 isc_buffer_t *target); 350 /*%< 351 * Convert section 'section' or 'pseudosection' of message 'msg' to 352 * a cleartext representation 353 * 354 * Notes: 355 * \li See dns_message_totext for meanings of flags. 356 * 357 * Requires: 358 * 359 *\li 'msg' is a valid message. 360 * 361 *\li 'style' is a valid master dump style. 362 * 363 *\li 'target' is a valid buffer. 364 * 365 *\li 'section' is a valid section label. 366 * 367 * Ensures: 368 * 369 *\li If the result is success: 370 * The used space in 'target' is updated. 371 * 372 * Returns: 373 * 374 *\li #ISC_R_SUCCESS 375 *\li #ISC_R_NOSPACE 376 *\li #ISC_R_NOMORE 377 * 378 *\li Note: On error return, *target may be partially filled with data. 379 */ 380 381 isc_result_t 382 dns_message_totext(dns_message_t *msg, const dns_master_style_t *style, 383 dns_messagetextflag_t flags, isc_buffer_t *target); 384 /*%< 385 * Convert all sections of message 'msg' to a cleartext representation 386 * 387 * Notes: 388 * \li In flags, If #DNS_MESSAGETEXTFLAG_OMITDOT is set, then the 389 * final '.' in absolute names will not be emitted. If 390 * #DNS_MESSAGETEXTFLAG_NOCOMMENTS is cleared, lines beginning 391 * with ";;" will be emitted indicating section name. If 392 * #DNS_MESSAGETEXTFLAG_NOHEADERS is cleared, header lines will 393 * be emitted. 394 * 395 * If #DNS_MESSAGETEXTFLAG_ONESOA is set then only print the 396 * first SOA record in the answer section. If 397 * #DNS_MESSAGETEXTFLAG_OMITSOA is set don't print any SOA records 398 * in the answer section. These are useful for suppressing the 399 * display of the second SOA record in a AXFR by setting 400 * #DNS_MESSAGETEXTFLAG_ONESOA on the first message in a AXFR stream 401 * and #DNS_MESSAGETEXTFLAG_OMITSOA on subsequent messages. 402 * 403 * Requires: 404 * 405 *\li 'msg' is a valid message. 406 * 407 *\li 'style' is a valid master dump style. 408 * 409 *\li 'target' is a valid buffer. 410 * 411 * Ensures: 412 * 413 *\li If the result is success: 414 * The used space in 'target' is updated. 415 * 416 * Returns: 417 * 418 *\li #ISC_R_SUCCESS 419 *\li #ISC_R_NOSPACE 420 *\li #ISC_R_NOMORE 421 * 422 *\li Note: On error return, *target may be partially filled with data. 423 */ 424 425 isc_result_t 426 dns_message_parse(dns_message_t *msg, isc_buffer_t *source, 427 unsigned int options); 428 /*%< 429 * Parse raw wire data in 'source' as a DNS message. 430 * 431 * OPT records are detected and stored in the pseudo-section "opt". 432 * TSIGs are detected and stored in the pseudo-section "tsig". 433 * 434 * If #DNS_MESSAGEPARSE_PRESERVEORDER is set, or if the opcode of the message 435 * is UPDATE, a separate dns_name_t object will be created for each RR in the 436 * message. Each such dns_name_t will have a single rdataset containing the 437 * single RR, and the order of the RRs in the message is preserved. 438 * Otherwise, only one dns_name_t object will be created for each unique 439 * owner name in the section, and each such dns_name_t will have a list 440 * of rdatasets. To access the names and their data, use 441 * dns_message_firstname() and dns_message_nextname(). 442 * 443 * If #DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will 444 * not be considered FORMERRs. If the entire message can be parsed, it 445 * will be returned and DNS_R_RECOVERABLE will be returned. 446 * 447 * If #DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete 448 * RR's as possible, DNS_R_RECOVERABLE will be returned. 449 * 450 * OPT and TSIG records are always handled specially, regardless of the 451 * 'preserve_order' setting. 452 * 453 * Requires: 454 *\li "msg" be valid. 455 * 456 *\li "buffer" be a wire format buffer. 457 * 458 * Ensures: 459 *\li The buffer's data format is correct. 460 * 461 *\li The buffer's contents verify as correct regarding header bits, buffer 462 * and rdata sizes, etc. 463 * 464 * Returns: 465 *\li #ISC_R_SUCCESS -- all is well 466 *\li #ISC_R_NOMEMORY -- no memory 467 *\li #DNS_R_RECOVERABLE -- the message parsed properly, but contained 468 * errors. 469 *\li Many other errors possible XXXMLG 470 */ 471 472 isc_result_t 473 dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx, 474 isc_buffer_t *buffer); 475 /*%< 476 * Begin rendering on a message. Only one call can be made to this function 477 * per message. 478 * 479 * The compression context is "owned" by the message library until 480 * dns_message_renderend() is called. It must be invalidated by the caller. 481 * 482 * The buffer is "owned" by the message library until dns_message_renderend() 483 * is called. 484 * 485 * Requires: 486 * 487 *\li 'msg' be valid. 488 * 489 *\li 'cctx' be valid. 490 * 491 *\li 'buffer' is a valid buffer. 492 * 493 * Side Effects: 494 * 495 *\li The buffer is cleared before it is used. 496 * 497 * Returns: 498 *\li #ISC_R_SUCCESS -- all is well 499 *\li #ISC_R_NOSPACE -- output buffer is too small 500 */ 501 502 isc_result_t 503 dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer); 504 /*%< 505 * Reset the buffer. This can be used after growing the old buffer 506 * on a ISC_R_NOSPACE return from most of the render functions. 507 * 508 * On successful completion, the old buffer is no longer used by the 509 * library. The new buffer is owned by the library until 510 * dns_message_renderend() is called. 511 * 512 * Requires: 513 * 514 *\li 'msg' be valid. 515 * 516 *\li dns_message_renderbegin() was called. 517 * 518 *\li buffer != NULL. 519 * 520 * Returns: 521 *\li #ISC_R_NOSPACE -- new buffer is too small 522 *\li #ISC_R_SUCCESS -- all is well. 523 */ 524 525 isc_result_t 526 dns_message_renderreserve(dns_message_t *msg, unsigned int space); 527 /*%< 528 * XXXMLG should use size_t rather than unsigned int once the buffer 529 * API is cleaned up 530 * 531 * Reserve "space" bytes in the given buffer. 532 * 533 * Requires: 534 * 535 *\li 'msg' be valid. 536 * 537 *\li dns_message_renderbegin() was called. 538 * 539 * Returns: 540 *\li #ISC_R_SUCCESS -- all is well. 541 *\li #ISC_R_NOSPACE -- not enough free space in the buffer. 542 */ 543 544 void 545 dns_message_renderrelease(dns_message_t *msg, unsigned int space); 546 /*%< 547 * XXXMLG should use size_t rather than unsigned int once the buffer 548 * API is cleaned up 549 * 550 * Release "space" bytes in the given buffer that was previously reserved. 551 * 552 * Requires: 553 * 554 *\li 'msg' be valid. 555 * 556 *\li 'space' is less than or equal to the total amount of space reserved 557 * via prior calls to dns_message_renderreserve(). 558 * 559 *\li dns_message_renderbegin() was called. 560 */ 561 562 isc_result_t 563 dns_message_rendersection(dns_message_t *msg, dns_section_t section, 564 unsigned int options); 565 /*%< 566 * Render all names, rdatalists, etc from the given section at the 567 * specified priority or higher. 568 * 569 * Requires: 570 *\li 'msg' be valid. 571 * 572 *\li 'section' be a valid section. 573 * 574 *\li dns_message_renderbegin() was called. 575 * 576 * Returns: 577 *\li #ISC_R_SUCCESS -- all records were written, and there are 578 * no more records for this section. 579 *\li #ISC_R_NOSPACE -- Not enough room in the buffer to write 580 * all records requested. 581 *\li #DNS_R_MOREDATA -- All requested records written, and there 582 * are records remaining for this section. 583 */ 584 585 void 586 dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target); 587 /*%< 588 * Render the message header. This is implicitly called by 589 * dns_message_renderend(). 590 * 591 * Requires: 592 * 593 *\li 'msg' be a valid message. 594 * 595 *\li dns_message_renderbegin() was called. 596 * 597 *\li 'target' is a valid buffer with enough space to hold a message header 598 */ 599 600 isc_result_t 601 dns_message_renderend(dns_message_t *msg); 602 /*%< 603 * Finish rendering to the buffer. Note that more data can be in the 604 * 'msg' structure. Destroying the structure will free this, or in a multi- 605 * part EDNS1 message this data can be rendered to another buffer later. 606 * 607 * Requires: 608 * 609 *\li 'msg' be a valid message. 610 * 611 *\li dns_message_renderbegin() was called. 612 * 613 * Returns: 614 *\li #ISC_R_SUCCESS -- all is well. 615 */ 616 617 void 618 dns_message_renderreset(dns_message_t *msg); 619 /*%< 620 * Reset the message so that it may be rendered again. 621 * 622 * Notes: 623 * 624 *\li If dns_message_renderbegin() has been called, dns_message_renderend() 625 * must be called before calling this function. 626 * 627 * Requires: 628 * 629 *\li 'msg' be a valid message with rendering intent. 630 */ 631 632 isc_result_t 633 dns_message_firstname(dns_message_t *msg, dns_section_t section); 634 /*%< 635 * Set internal per-section name pointer to the beginning of the section. 636 * 637 * The functions dns_message_firstname() and dns_message_nextname() may 638 * be used for iterating over the owner names in a section. 639 * 640 * Requires: 641 * 642 *\li 'msg' be valid. 643 * 644 *\li 'section' be a valid section. 645 * 646 * Returns: 647 *\li #ISC_R_SUCCESS -- All is well. 648 *\li #ISC_R_NOMORE -- No names on given section. 649 */ 650 651 isc_result_t 652 dns_message_nextname(dns_message_t *msg, dns_section_t section); 653 /*%< 654 * Sets the internal per-section name pointer to point to the next name 655 * in that section. 656 * 657 * Requires: 658 * 659 * \li 'msg' be valid. 660 * 661 *\li 'section' be a valid section. 662 * 663 *\li dns_message_firstname() must have been called on this section, 664 * and the result was ISC_R_SUCCESS. 665 * 666 * Returns: 667 *\li #ISC_R_SUCCESS -- All is well. 668 *\li #ISC_R_NOMORE -- No more names in given section. 669 */ 670 671 void 672 dns_message_currentname(dns_message_t *msg, dns_section_t section, 673 dns_name_t **name); 674 /*%< 675 * Sets 'name' to point to the name where the per-section internal name 676 * pointer is currently set. 677 * 678 * This function returns the name in the database, so any data associated 679 * with it (via the name's "list" member) contains the actual rdatasets. 680 * 681 * Requires: 682 * 683 *\li 'msg' be valid. 684 * 685 *\li 'name' be non-NULL, and *name be NULL. 686 * 687 *\li 'section' be a valid section. 688 * 689 *\li dns_message_firstname() must have been called on this section, 690 * and the result of it and any dns_message_nextname() calls was 691 * #ISC_R_SUCCESS. 692 */ 693 694 isc_result_t 695 dns_message_findname(dns_message_t *msg, dns_section_t section, 696 dns_name_t *target, dns_rdatatype_t type, 697 dns_rdatatype_t covers, dns_name_t **foundname, 698 dns_rdataset_t **rdataset); 699 /*%< 700 * Search for a name in the specified section. If it is found, *name is 701 * set to point to the name, and *rdataset is set to point to the found 702 * rdataset (if type is specified as other than dns_rdatatype_any). 703 * 704 * Requires: 705 *\li 'msg' be valid. 706 * 707 *\li 'section' be a valid section. 708 * 709 *\li If a pointer to the name is desired, 'foundname' should be non-NULL. 710 * If it is non-NULL, '*foundname' MUST be NULL. 711 * 712 *\li If a type other than dns_datatype_any is searched for, 'rdataset' 713 * may be non-NULL, '*rdataset' be NULL, and will point at the found 714 * rdataset. If the type is dns_datatype_any, 'rdataset' must be NULL. 715 * 716 *\li 'target' be a valid name. 717 * 718 *\li 'type' be a valid type. 719 * 720 *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. 721 * Otherwise it should be 0. 722 * 723 * Returns: 724 *\li #ISC_R_SUCCESS -- all is well. 725 *\li #DNS_R_NXDOMAIN -- name does not exist in that section. 726 *\li #DNS_R_NXRRSET -- The name does exist, but the desired 727 * type does not. 728 */ 729 730 isc_result_t 731 dns_message_findtype(dns_name_t *name, dns_rdatatype_t type, 732 dns_rdatatype_t covers, dns_rdataset_t **rdataset); 733 /*%< 734 * Search the name for the specified type. If it is found, *rdataset is 735 * filled in with a pointer to that rdataset. 736 * 737 * Requires: 738 *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL. 739 * 740 *\li 'type' be a valid type, and NOT dns_rdatatype_any. 741 * 742 *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. 743 * Otherwise it should be 0. 744 * 745 * Returns: 746 *\li #ISC_R_SUCCESS -- all is well. 747 *\li #ISC_R_NOTFOUND -- the desired type does not exist. 748 */ 749 750 isc_result_t 751 dns_message_find(dns_name_t *name, dns_rdataclass_t rdclass, 752 dns_rdatatype_t type, dns_rdatatype_t covers, 753 dns_rdataset_t **rdataset); 754 /*%< 755 * Search the name for the specified rdclass and type. If it is found, 756 * *rdataset is filled in with a pointer to that rdataset. 757 * 758 * Requires: 759 *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL. 760 * 761 *\li 'type' be a valid type, and NOT dns_rdatatype_any. 762 * 763 *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. 764 * Otherwise it should be 0. 765 * 766 * Returns: 767 *\li #ISC_R_SUCCESS -- all is well. 768 *\li #ISC_R_NOTFOUND -- the desired type does not exist. 769 */ 770 771 void 772 dns_message_movename(dns_message_t *msg, dns_name_t *name, 773 dns_section_t fromsection, 774 dns_section_t tosection); 775 /*%< 776 * Move a name from one section to another. 777 * 778 * Requires: 779 * 780 *\li 'msg' be valid. 781 * 782 *\li 'name' must be a name already in 'fromsection'. 783 * 784 *\li 'fromsection' must be a valid section. 785 * 786 *\li 'tosection' must be a valid section. 787 */ 788 789 void 790 dns_message_addname(dns_message_t *msg, dns_name_t *name, 791 dns_section_t section); 792 /*%< 793 * Adds the name to the given section. 794 * 795 * It is the caller's responsibility to enforce any unique name requirements 796 * in a section. 797 * 798 * Requires: 799 * 800 *\li 'msg' be valid, and be a renderable message. 801 * 802 *\li 'name' be a valid absolute name. 803 * 804 *\li 'section' be a named section. 805 */ 806 807 void 808 dns_message_removename(dns_message_t *msg, dns_name_t *name, 809 dns_section_t section); 810 /*%< 811 * Remove a existing name from a given section. 812 * 813 * It is the caller's responsibility to ensure the name is part of the 814 * given section. 815 * 816 * Requires: 817 * 818 *\li 'msg' be valid, and be a renderable message. 819 * 820 *\li 'name' be a valid absolute name. 821 * 822 *\li 'section' be a named section. 823 */ 824 825 826 /* 827 * LOANOUT FUNCTIONS 828 * 829 * Each of these functions loan a particular type of data to the caller. 830 * The storage for these will vanish when the message is destroyed or 831 * reset, and must NOT be used after these operations. 832 */ 833 834 isc_result_t 835 dns_message_gettempname(dns_message_t *msg, dns_name_t **item); 836 /*%< 837 * Return a name that can be used for any temporary purpose, including 838 * inserting into the message's linked lists. The name must be returned 839 * to the message code using dns_message_puttempname() or inserted into 840 * one of the message's sections before the message is destroyed. 841 * 842 * It is the caller's responsibility to initialize this name. 843 * 844 * Requires: 845 *\li msg be a valid message 846 * 847 *\li item != NULL && *item == NULL 848 * 849 * Returns: 850 *\li #ISC_R_SUCCESS -- All is well. 851 *\li #ISC_R_NOMEMORY -- No item can be allocated. 852 */ 853 854 isc_result_t 855 dns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item); 856 /*%< 857 * Return an offsets array that can be used for any temporary purpose, 858 * such as attaching to a temporary name. The offsets will be freed 859 * when the message is destroyed or reset. 860 * 861 * Requires: 862 *\li msg be a valid message 863 * 864 *\li item != NULL && *item == NULL 865 * 866 * Returns: 867 *\li #ISC_R_SUCCESS -- All is well. 868 *\li #ISC_R_NOMEMORY -- No item can be allocated. 869 */ 870 871 isc_result_t 872 dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item); 873 /*%< 874 * Return a rdata that can be used for any temporary purpose, including 875 * inserting into the message's linked lists. The rdata will be freed 876 * when the message is destroyed or reset. 877 * 878 * Requires: 879 *\li msg be a valid message 880 * 881 *\li item != NULL && *item == NULL 882 * 883 * Returns: 884 *\li #ISC_R_SUCCESS -- All is well. 885 *\li #ISC_R_NOMEMORY -- No item can be allocated. 886 */ 887 888 isc_result_t 889 dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item); 890 /*%< 891 * Return a rdataset that can be used for any temporary purpose, including 892 * inserting into the message's linked lists. The name must be returned 893 * to the message code using dns_message_puttempname() or inserted into 894 * one of the message's sections before the message is destroyed. 895 * 896 * Requires: 897 *\li msg be a valid message 898 * 899 *\li item != NULL && *item == NULL 900 * 901 * Returns: 902 *\li #ISC_R_SUCCESS -- All is well. 903 *\li #ISC_R_NOMEMORY -- No item can be allocated. 904 */ 905 906 isc_result_t 907 dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item); 908 /*%< 909 * Return a rdatalist that can be used for any temporary purpose, including 910 * inserting into the message's linked lists. The rdatalist will be 911 * destroyed when the message is destroyed or reset. 912 * 913 * Requires: 914 *\li msg be a valid message 915 * 916 *\li item != NULL && *item == NULL 917 * 918 * Returns: 919 *\li #ISC_R_SUCCESS -- All is well. 920 *\li #ISC_R_NOMEMORY -- No item can be allocated. 921 */ 922 923 void 924 dns_message_puttempname(dns_message_t *msg, dns_name_t **item); 925 /*%< 926 * Return a borrowed name to the message's name free list. 927 * 928 * Requires: 929 *\li msg be a valid message 930 * 931 *\li item != NULL && *item point to a name returned by 932 * dns_message_gettempname() 933 * 934 * Ensures: 935 *\li *item == NULL 936 */ 937 938 void 939 dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item); 940 /*%< 941 * Return a borrowed rdata to the message's rdata free list. 942 * 943 * Requires: 944 *\li msg be a valid message 945 * 946 *\li item != NULL && *item point to a rdata returned by 947 * dns_message_gettemprdata() 948 * 949 * Ensures: 950 *\li *item == NULL 951 */ 952 953 void 954 dns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item); 955 /*%< 956 * Return a borrowed rdataset to the message's rdataset free list. 957 * 958 * Requires: 959 *\li msg be a valid message 960 * 961 *\li item != NULL && *item point to a rdataset returned by 962 * dns_message_gettemprdataset() 963 * 964 * Ensures: 965 *\li *item == NULL 966 */ 967 968 void 969 dns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item); 970 /*%< 971 * Return a borrowed rdatalist to the message's rdatalist free list. 972 * 973 * Requires: 974 *\li msg be a valid message 975 * 976 *\li item != NULL && *item point to a rdatalist returned by 977 * dns_message_gettemprdatalist() 978 * 979 * Ensures: 980 *\li *item == NULL 981 */ 982 983 isc_result_t 984 dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp, 985 unsigned int *flagsp); 986 /*%< 987 * Assume the remaining region of "source" is a DNS message. Peek into 988 * it and fill in "*idp" with the message id, and "*flagsp" with the flags. 989 * 990 * Requires: 991 * 992 *\li source != NULL 993 * 994 * Ensures: 995 * 996 *\li if (idp != NULL) *idp == message id. 997 * 998 *\li if (flagsp != NULL) *flagsp == message flags. 999 * 1000 * Returns: 1001 * 1002 *\li #ISC_R_SUCCESS -- all is well. 1003 * 1004 *\li #ISC_R_UNEXPECTEDEND -- buffer doesn't contain enough for a header. 1005 */ 1006 1007 isc_result_t 1008 dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section); 1009 /*%< 1010 * Start formatting a reply to the query in 'msg'. 1011 * 1012 * Requires: 1013 * 1014 *\li 'msg' is a valid message with parsing intent, and contains a query. 1015 * 1016 * Ensures: 1017 * 1018 *\li The message will have a rendering intent. If 'want_question_section' 1019 * is true, the message opcode is query or notify, and the question 1020 * section is present and properly formatted, then the question section 1021 * will be included in the reply. All other sections will be cleared. 1022 * The QR flag will be set, the RD flag will be preserved, and all other 1023 * flags will be cleared. 1024 * 1025 * Returns: 1026 * 1027 *\li #ISC_R_SUCCESS -- all is well. 1028 * 1029 *\li #DNS_R_FORMERR -- the header or question section of the 1030 * message is invalid, replying is impossible. 1031 * If DNS_R_FORMERR is returned when 1032 * want_question_section is ISC_FALSE, then 1033 * it's the header section that's bad; 1034 * otherwise either of the header or question 1035 * sections may be bad. 1036 */ 1037 1038 dns_rdataset_t * 1039 dns_message_getopt(dns_message_t *msg); 1040 /*%< 1041 * Get the OPT record for 'msg'. 1042 * 1043 * Requires: 1044 * 1045 *\li 'msg' is a valid message. 1046 * 1047 * Returns: 1048 * 1049 *\li The OPT rdataset of 'msg', or NULL if there isn't one. 1050 */ 1051 1052 isc_result_t 1053 dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt); 1054 /*%< 1055 * Set the OPT record for 'msg'. 1056 * 1057 * Requires: 1058 * 1059 *\li 'msg' is a valid message with rendering intent 1060 * and no sections have been rendered. 1061 * 1062 *\li 'opt' is a valid OPT record. 1063 * 1064 * Ensures: 1065 * 1066 *\li The OPT record has either been freed or ownership of it has 1067 * been transferred to the message. 1068 * 1069 *\li If ISC_R_SUCCESS was returned, the OPT record will be rendered 1070 * when dns_message_renderend() is called. 1071 * 1072 * Returns: 1073 * 1074 *\li #ISC_R_SUCCESS -- all is well. 1075 * 1076 *\li #ISC_R_NOSPACE -- there is no space for the OPT record. 1077 */ 1078 1079 dns_rdataset_t * 1080 dns_message_gettsig(dns_message_t *msg, dns_name_t **owner); 1081 /*%< 1082 * Get the TSIG record and owner for 'msg'. 1083 * 1084 * Requires: 1085 * 1086 *\li 'msg' is a valid message. 1087 *\li 'owner' is NULL or *owner is NULL. 1088 * 1089 * Returns: 1090 * 1091 *\li The TSIG rdataset of 'msg', or NULL if there isn't one. 1092 * 1093 * Ensures: 1094 * 1095 * \li If 'owner' is not NULL, it will point to the owner name. 1096 */ 1097 1098 isc_result_t 1099 dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key); 1100 /*%< 1101 * Set the tsig key for 'msg'. This is only necessary for when rendering a 1102 * query or parsing a response. The key (if non-NULL) is attached to, and 1103 * will be detached when the message is destroyed. 1104 * 1105 * Requires: 1106 * 1107 *\li 'msg' is a valid message with rendering intent, 1108 * dns_message_renderbegin() has been called, and no sections have been 1109 * rendered. 1110 *\li 'key' is a valid tsig key or NULL. 1111 * 1112 * Returns: 1113 * 1114 *\li #ISC_R_SUCCESS -- all is well. 1115 * 1116 *\li #ISC_R_NOSPACE -- there is no space for the TSIG record. 1117 */ 1118 1119 dns_tsigkey_t * 1120 dns_message_gettsigkey(dns_message_t *msg); 1121 /*%< 1122 * Gets the tsig key for 'msg'. 1123 * 1124 * Requires: 1125 * 1126 *\li 'msg' is a valid message 1127 */ 1128 1129 isc_result_t 1130 dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig); 1131 /*%< 1132 * Indicates that 'querytsig' is the TSIG from the signed query for which 1133 * 'msg' is the response. This is also used for chained TSIGs in TCP 1134 * responses. 1135 * 1136 * Requires: 1137 * 1138 *\li 'querytsig' is a valid buffer as returned by dns_message_getquerytsig() 1139 * or NULL 1140 * 1141 *\li 'msg' is a valid message 1142 * 1143 * Returns: 1144 * 1145 *\li #ISC_R_SUCCESS 1146 *\li #ISC_R_NOMEMORY 1147 */ 1148 1149 isc_result_t 1150 dns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx, 1151 isc_buffer_t **querytsig); 1152 /*%< 1153 * Gets the tsig from the TSIG from the signed query 'msg'. This is also used 1154 * for chained TSIGs in TCP responses. Unlike dns_message_gettsig, this makes 1155 * a copy of the data, so can be used if the message is destroyed. 1156 * 1157 * Requires: 1158 * 1159 *\li 'msg' is a valid signed message 1160 *\li 'mctx' is a valid memory context 1161 *\li querytsig != NULL && *querytsig == NULL 1162 * 1163 * Returns: 1164 * 1165 *\li #ISC_R_SUCCESS 1166 *\li #ISC_R_NOMEMORY 1167 * 1168 * Ensures: 1169 *\li 'tsig' points to NULL or an allocated buffer which must be freed 1170 * by the caller. 1171 */ 1172 1173 dns_rdataset_t * 1174 dns_message_getsig0(dns_message_t *msg, dns_name_t **owner); 1175 /*%< 1176 * Get the SIG(0) record and owner for 'msg'. 1177 * 1178 * Requires: 1179 * 1180 *\li 'msg' is a valid message. 1181 *\li 'owner' is NULL or *owner is NULL. 1182 * 1183 * Returns: 1184 * 1185 *\li The SIG(0) rdataset of 'msg', or NULL if there isn't one. 1186 * 1187 * Ensures: 1188 * 1189 * \li If 'owner' is not NULL, it will point to the owner name. 1190 */ 1191 1192 isc_result_t 1193 dns_message_setsig0key(dns_message_t *msg, dst_key_t *key); 1194 /*%< 1195 * Set the SIG(0) key for 'msg'. 1196 * 1197 * Requires: 1198 * 1199 *\li 'msg' is a valid message with rendering intent, 1200 * dns_message_renderbegin() has been called, and no sections have been 1201 * rendered. 1202 *\li 'key' is a valid sig key or NULL. 1203 * 1204 * Returns: 1205 * 1206 *\li #ISC_R_SUCCESS -- all is well. 1207 * 1208 *\li #ISC_R_NOSPACE -- there is no space for the SIG(0) record. 1209 */ 1210 1211 dst_key_t * 1212 dns_message_getsig0key(dns_message_t *msg); 1213 /*%< 1214 * Gets the SIG(0) key for 'msg'. 1215 * 1216 * Requires: 1217 * 1218 *\li 'msg' is a valid message 1219 */ 1220 1221 void 1222 dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer); 1223 /*%< 1224 * Give the *buffer to the message code to clean up when it is no 1225 * longer needed. This is usually when the message is reset or 1226 * destroyed. 1227 * 1228 * Requires: 1229 * 1230 *\li msg be a valid message. 1231 * 1232 *\li buffer != NULL && *buffer is a valid isc_buffer_t, which was 1233 * dynamically allocated via isc_buffer_allocate(). 1234 */ 1235 1236 isc_result_t 1237 dns_message_signer(dns_message_t *msg, dns_name_t *signer); 1238 /*%< 1239 * If this message was signed, return the identity of the signer. 1240 * Unless ISC_R_NOTFOUND is returned, signer will reflect the name of the 1241 * key that signed the message. 1242 * 1243 * Requires: 1244 * 1245 *\li msg is a valid parsed message. 1246 *\li signer is a valid name 1247 * 1248 * Returns: 1249 * 1250 *\li #ISC_R_SUCCESS - the message was signed, and *signer 1251 * contains the signing identity 1252 * 1253 *\li #ISC_R_NOTFOUND - no TSIG or SIG(0) record is present in the 1254 * message 1255 * 1256 *\li #DNS_R_TSIGVERIFYFAILURE - the message was signed by a TSIG, but the 1257 * signature failed to verify 1258 * 1259 *\li #DNS_R_TSIGERRORSET - the message was signed by a TSIG and 1260 * verified, but the query was rejected by 1261 * the server 1262 * 1263 *\li #DNS_R_NOIDENTITY - the message was signed by a TSIG and 1264 * verified, but the key has no identity since 1265 * it was generated by an unsigned TKEY process 1266 * 1267 *\li #DNS_R_SIGINVALID - the message was signed by a SIG(0), but 1268 * the signature failed to verify 1269 * 1270 *\li #DNS_R_NOTVERIFIEDYET - the message was signed by a TSIG or SIG(0), 1271 * but the signature has not been verified yet 1272 */ 1273 1274 isc_result_t 1275 dns_message_checksig(dns_message_t *msg, dns_view_t *view); 1276 /*%< 1277 * If this message was signed, verify the signature. 1278 * 1279 * Requires: 1280 * 1281 *\li msg is a valid parsed message. 1282 *\li view is a valid view or NULL 1283 * 1284 * Returns: 1285 * 1286 *\li #ISC_R_SUCCESS - the message was unsigned, or the message 1287 * was signed correctly. 1288 * 1289 *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen 1290 *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected 1291 *\li #DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify 1292 */ 1293 1294 isc_result_t 1295 dns_message_rechecksig(dns_message_t *msg, dns_view_t *view); 1296 /*%< 1297 * Reset the signature state and then if the message was signed, 1298 * verify the message. 1299 * 1300 * Requires: 1301 * 1302 *\li msg is a valid parsed message. 1303 *\li view is a valid view or NULL 1304 * 1305 * Returns: 1306 * 1307 *\li #ISC_R_SUCCESS - the message was unsigned, or the message 1308 * was signed correctly. 1309 * 1310 *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen 1311 *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected 1312 *\li #DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify 1313 */ 1314 1315 void 1316 dns_message_resetsig(dns_message_t *msg); 1317 /*%< 1318 * Reset the signature state. 1319 * 1320 * Requires: 1321 *\li 'msg' is a valid parsed message. 1322 */ 1323 1324 isc_region_t * 1325 dns_message_getrawmessage(dns_message_t *msg); 1326 /*%< 1327 * Retrieve the raw message in compressed wire format. The message must 1328 * have been successfully parsed for it to have been saved. 1329 * 1330 * Requires: 1331 *\li msg is a valid parsed message. 1332 * 1333 * Returns: 1334 *\li NULL if there is no saved message. 1335 * a pointer to a region which refers the dns message. 1336 */ 1337 1338 void 1339 dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order, 1340 const void *order_arg); 1341 /*%< 1342 * Define the order in which RR sets get rendered by 1343 * dns_message_rendersection() to be the ascending order 1344 * defined by the integer value returned by 'order' when 1345 * given each RR and 'arg' as arguments. If 'order' and 1346 * 'order_arg' are NULL, a default order is used. 1347 * 1348 * Requires: 1349 *\li msg be a valid message. 1350 *\li order_arg is NULL if and only if order is NULL. 1351 */ 1352 1353 void 1354 dns_message_settimeadjust(dns_message_t *msg, int timeadjust); 1355 /*%< 1356 * Adjust the time used to sign/verify a message by timeadjust. 1357 * Currently only TSIG. 1358 * 1359 * Requires: 1360 *\li msg be a valid message. 1361 */ 1362 1363 int 1364 dns_message_gettimeadjust(dns_message_t *msg); 1365 /*%< 1366 * Return the current time adjustment. 1367 * 1368 * Requires: 1369 *\li msg be a valid message. 1370 */ 1371 1372 void 1373 dns_message_logpacket(dns_message_t *message, const char *description, 1374 isc_logcategory_t *category, isc_logmodule_t *module, 1375 int level, isc_mem_t *mctx); 1376 void 1377 dns_message_logfmtpacket(dns_message_t *message, const char *description, 1378 isc_logcategory_t *category, isc_logmodule_t *module, 1379 const dns_master_style_t *style, int level, 1380 isc_mem_t *mctx); 1381 /*%< 1382 * Log 'message' at the specified logging parameters. 1383 * 'description' will be emitted at the start of the message and will 1384 * normally end with a newline. 1385 */ 1386 1387 isc_result_t 1388 dns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt, 1389 unsigned int version, isc_uint16_t udpsize, 1390 unsigned int flags, dns_ednsopt_t *ednsopts, size_t count); 1391 /*%< 1392 * Built a opt record. 1393 * 1394 * Requires: 1395 * \li msg be a valid message. 1396 * \li opt to be a non NULL and *opt to be NULL. 1397 * 1398 * Returns: 1399 * \li ISC_R_SUCCESS on success. 1400 * \li ISC_R_NOMEMORY 1401 * \li ISC_R_NOSPACE 1402 * \li other. 1403 */ 1404 1405 ISC_LANG_ENDDECLS 1406 1407 #endif /* DNS_MESSAGE_H */ 1408