4 * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1998-2003 Internet Software Consortium.
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.
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.
20 /* Id: rdata.c,v 1.204 2009/12/04 21:09:33 marka Exp */
27 #include <isc/base64.h>
31 #include <isc/parseint.h>
32 #include <isc/print.h>
33 #include <isc/string.h>
34 #include <isc/stdlib.h>
37 #include <dns/callbacks.h>
39 #include <dns/compress.h>
40 #include <dns/enumtype.h>
41 #include <dns/keyflags.h>
42 #include <dns/keyvalues.h>
43 #include <dns/message.h>
44 #include <dns/rcode.h>
45 #include <dns/rdata.h>
46 #include <dns/rdataclass.h>
47 #include <dns/rdatastruct.h>
48 #include <dns/rdatatype.h>
49 #include <dns/result.h>
50 #include <dns/secalg.h>
51 #include <dns/secproto.h>
57 isc_result_t _r = (x); \
58 if (_r != ISC_R_SUCCESS) \
64 isc_result_t _r = (x); \
65 if (_r != ISC_R_SUCCESS) { \
66 isc_lex_ungettoken(lexer, &token); \
71 #define DNS_AS_STR(t) ((t).value.as_textregion.base)
73 #define ARGS_FROMTEXT int rdclass, dns_rdatatype_t type, \
74 isc_lex_t *lexer, dns_name_t *origin, \
75 unsigned int options, isc_buffer_t *target, \
76 dns_rdatacallbacks_t *callbacks
78 #define ARGS_TOTEXT dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, \
81 #define ARGS_FROMWIRE int rdclass, dns_rdatatype_t type, \
82 isc_buffer_t *source, dns_decompress_t *dctx, \
83 unsigned int options, isc_buffer_t *target
85 #define ARGS_TOWIRE dns_rdata_t *rdata, dns_compress_t *cctx, \
88 #define ARGS_COMPARE const dns_rdata_t *rdata1, const dns_rdata_t *rdata2
90 #define ARGS_FROMSTRUCT int rdclass, dns_rdatatype_t type, \
91 void *source, isc_buffer_t *target
93 #define ARGS_TOSTRUCT dns_rdata_t *rdata, void *target, isc_mem_t *mctx
95 #define ARGS_FREESTRUCT void *source
97 #define ARGS_ADDLDATA dns_rdata_t *rdata, dns_additionaldatafunc_t add, \
100 #define ARGS_DIGEST dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg
102 #define ARGS_CHECKOWNER dns_name_t *name, dns_rdataclass_t rdclass, \
103 dns_rdatatype_t type, isc_boolean_t wildcard
105 #define ARGS_CHECKNAMES dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad
109 * Context structure for the totext_ functions.
110 * Contains formatting options for rdata-to-text
113 typedef struct dns_rdata_textctx
{
114 dns_name_t
*origin
; /*%< Current origin, or NULL. */
115 unsigned int flags
; /*%< DNS_STYLEFLAG_* */
116 unsigned int width
; /*%< Width of rdata column. */
117 const char *linebreak
; /*%< Line break string. */
118 } dns_rdata_textctx_t
;
121 txt_totext(isc_region_t
*source
, isc_buffer_t
*target
);
124 txt_fromtext(isc_textregion_t
*source
, isc_buffer_t
*target
);
127 txt_fromwire(isc_buffer_t
*source
, isc_buffer_t
*target
);
130 name_prefix(dns_name_t
*name
, dns_name_t
*origin
, dns_name_t
*target
);
133 name_length(dns_name_t
*name
);
136 str_totext(const char *source
, isc_buffer_t
*target
);
139 inet_totext(int af
, isc_region_t
*src
, isc_buffer_t
*target
);
142 buffer_empty(isc_buffer_t
*source
);
145 buffer_fromregion(isc_buffer_t
*buffer
, isc_region_t
*region
);
148 uint32_tobuffer(isc_uint32_t
, isc_buffer_t
*target
);
151 uint16_tobuffer(isc_uint32_t
, isc_buffer_t
*target
);
154 uint8_tobuffer(isc_uint32_t
, isc_buffer_t
*target
);
157 name_tobuffer(dns_name_t
*name
, isc_buffer_t
*target
);
160 uint32_fromregion(isc_region_t
*region
);
163 uint16_fromregion(isc_region_t
*region
);
166 uint8_fromregion(isc_region_t
*region
);
169 uint8_consume_fromregion(isc_region_t
*region
);
172 mem_tobuffer(isc_buffer_t
*target
, void *base
, unsigned int length
);
175 hexvalue(char value
);
178 decvalue(char value
);
181 btoa_totext(unsigned char *inbuf
, int inbuflen
, isc_buffer_t
*target
);
184 atob_tobuffer(isc_lex_t
*lexer
, isc_buffer_t
*target
);
187 default_fromtext_callback(dns_rdatacallbacks_t
*callbacks
, const char *, ...)
188 ISC_FORMAT_PRINTF(2, 3);
191 fromtext_error(void (*callback
)(dns_rdatacallbacks_t
*, const char *, ...),
192 dns_rdatacallbacks_t
*callbacks
, const char *name
,
193 unsigned long line
, isc_token_t
*token
, isc_result_t result
);
196 fromtext_warneof(isc_lex_t
*lexer
, dns_rdatacallbacks_t
*callbacks
);
199 rdata_totext(dns_rdata_t
*rdata
, dns_rdata_textctx_t
*tctx
,
200 isc_buffer_t
*target
);
203 warn_badname(dns_name_t
*name
, isc_lex_t
*lexer
,
204 dns_rdatacallbacks_t
*callbacks
);
207 warn_badmx(isc_token_t
*token
, isc_lex_t
*lexer
,
208 dns_rdatacallbacks_t
*callbacks
);
211 uint16_consume_fromregion(isc_region_t
*region
);
214 getquad(const void *src
, struct in_addr
*dst
,
215 isc_lex_t
*lexer
, dns_rdatacallbacks_t
*callbacks
)
220 result
= inet_aton(src
, dst
);
221 if (result
== 1 && callbacks
!= NULL
&&
222 inet_pton(AF_INET
, src
, &tmp
) != 1) {
223 const char *name
= isc_lex_getsourcename(lexer
);
226 (*callbacks
->warn
)(callbacks
, "%s:%lu: \"%s\" "
227 "is not a decimal dotted quad", name
,
228 isc_lex_getsourceline(lexer
), src
);
233 static inline isc_result_t
234 name_duporclone(dns_name_t
*source
, isc_mem_t
*mctx
, dns_name_t
*target
) {
237 return (dns_name_dup(source
, mctx
, target
));
238 dns_name_clone(source
, target
);
239 return (ISC_R_SUCCESS
);
243 mem_maybedup(isc_mem_t
*mctx
, void *source
, size_t length
) {
248 new = isc_mem_allocate(mctx
, length
);
250 memcpy(new, source
, length
);
255 static const char hexdigits
[] = "0123456789abcdef";
256 static const char decdigits
[] = "0123456789";
261 #define RESERVED 0x0002
268 dns_rdata_init(dns_rdata_t
*rdata
) {
270 REQUIRE(rdata
!= NULL
);
277 ISC_LINK_INIT(rdata
, link
);
278 /* ISC_LIST_INIT(rdata->list); */
282 dns_rdata_reset(dns_rdata_t
*rdata
) {
284 REQUIRE(rdata
!= NULL
);
286 REQUIRE(!ISC_LINK_LINKED(rdata
, link
));
287 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata
));
301 dns_rdata_clone(const dns_rdata_t
*src
, dns_rdata_t
*target
) {
303 REQUIRE(src
!= NULL
);
304 REQUIRE(target
!= NULL
);
306 REQUIRE(DNS_RDATA_INITIALIZED(target
));
308 REQUIRE(DNS_RDATA_VALIDFLAGS(src
));
309 REQUIRE(DNS_RDATA_VALIDFLAGS(target
));
311 target
->data
= src
->data
;
312 target
->length
= src
->length
;
313 target
->rdclass
= src
->rdclass
;
314 target
->type
= src
->type
;
315 target
->flags
= src
->flags
;
324 dns_rdata_compare(const dns_rdata_t
*rdata1
, const dns_rdata_t
*rdata2
) {
326 isc_boolean_t use_default
= ISC_FALSE
;
328 REQUIRE(rdata1
!= NULL
);
329 REQUIRE(rdata2
!= NULL
);
330 REQUIRE(rdata1
->data
!= NULL
);
331 REQUIRE(rdata2
->data
!= NULL
);
332 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1
));
333 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2
));
335 if (rdata1
->rdclass
!= rdata2
->rdclass
)
336 return (rdata1
->rdclass
< rdata2
->rdclass
? -1 : 1);
338 if (rdata1
->type
!= rdata2
->type
)
339 return (rdata1
->type
< rdata2
->type
? -1 : 1);
347 dns_rdata_toregion(rdata1
, &r1
);
348 dns_rdata_toregion(rdata2
, &r2
);
349 result
= isc_region_compare(&r1
, &r2
);
355 dns_rdata_casecompare(const dns_rdata_t
*rdata1
, const dns_rdata_t
*rdata2
) {
357 isc_boolean_t use_default
= ISC_FALSE
;
359 REQUIRE(rdata1
!= NULL
);
360 REQUIRE(rdata2
!= NULL
);
361 REQUIRE(rdata1
->data
!= NULL
);
362 REQUIRE(rdata2
->data
!= NULL
);
363 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1
));
364 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2
));
366 if (rdata1
->rdclass
!= rdata2
->rdclass
)
367 return (rdata1
->rdclass
< rdata2
->rdclass
? -1 : 1);
369 if (rdata1
->type
!= rdata2
->type
)
370 return (rdata1
->type
< rdata2
->type
? -1 : 1);
378 dns_rdata_toregion(rdata1
, &r1
);
379 dns_rdata_toregion(rdata2
, &r2
);
380 result
= isc_region_compare(&r1
, &r2
);
390 dns_rdata_fromregion(dns_rdata_t
*rdata
, dns_rdataclass_t rdclass
,
391 dns_rdatatype_t type
, isc_region_t
*r
)
394 REQUIRE(rdata
!= NULL
);
395 REQUIRE(DNS_RDATA_INITIALIZED(rdata
));
398 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata
));
400 rdata
->data
= r
->base
;
401 rdata
->length
= r
->length
;
402 rdata
->rdclass
= rdclass
;
408 dns_rdata_toregion(const dns_rdata_t
*rdata
, isc_region_t
*r
) {
410 REQUIRE(rdata
!= NULL
);
412 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata
));
414 r
->base
= rdata
->data
;
415 r
->length
= rdata
->length
;
419 dns_rdata_fromwire(dns_rdata_t
*rdata
, dns_rdataclass_t rdclass
,
420 dns_rdatatype_t type
, isc_buffer_t
*source
,
421 dns_decompress_t
*dctx
, unsigned int options
,
422 isc_buffer_t
*target
)
424 isc_result_t result
= ISC_R_NOTIMPLEMENTED
;
428 isc_boolean_t use_default
= ISC_FALSE
;
429 isc_uint32_t activelength
;
431 REQUIRE(dctx
!= NULL
);
433 REQUIRE(DNS_RDATA_INITIALIZED(rdata
));
434 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata
));
438 return (DNS_R_FORMERR
);
443 activelength
= isc_buffer_activelength(source
);
444 INSIST(activelength
< 65536);
449 if (activelength
> isc_buffer_availablelength(target
))
450 result
= ISC_R_NOSPACE
;
452 isc_buffer_putmem(target
, isc_buffer_current(source
),
454 isc_buffer_forward(source
, activelength
);
455 result
= ISC_R_SUCCESS
;
460 * We should have consumed all of our buffer.
462 if (result
== ISC_R_SUCCESS
&& !buffer_empty(source
))
463 result
= DNS_R_EXTRADATA
;
465 if (rdata
!= NULL
&& result
== ISC_R_SUCCESS
) {
466 region
.base
= isc_buffer_used(&st
);
467 region
.length
= isc_buffer_usedlength(target
) -
468 isc_buffer_usedlength(&st
);
469 dns_rdata_fromregion(rdata
, rdclass
, type
, ®ion
);
472 if (result
!= ISC_R_SUCCESS
) {
480 dns_rdata_towire(dns_rdata_t
*rdata
, dns_compress_t
*cctx
,
481 isc_buffer_t
*target
)
483 isc_result_t result
= ISC_R_NOTIMPLEMENTED
;
484 isc_boolean_t use_default
= ISC_FALSE
;
488 REQUIRE(rdata
!= NULL
);
489 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata
));
492 * Some DynDNS meta-RRs have empty rdata.
494 if ((rdata
->flags
& DNS_RDATA_UPDATE
) != 0) {
495 INSIST(rdata
->length
== 0);
496 return (ISC_R_SUCCESS
);
504 isc_buffer_availableregion(target
, &tr
);
505 if (tr
.length
< rdata
->length
)
506 return (ISC_R_NOSPACE
);
507 memcpy(tr
.base
, rdata
->data
, rdata
->length
);
508 isc_buffer_add(target
, rdata
->length
);
509 return (ISC_R_SUCCESS
);
511 if (result
!= ISC_R_SUCCESS
) {
513 INSIST(target
->used
< 65536);
514 dns_compress_rollback(cctx
, (isc_uint16_t
)target
->used
);
520 * If the binary data in 'src' is valid uncompressed wire format
521 * rdata of class 'rdclass' and type 'type', return ISC_R_SUCCESS
522 * and copy the validated rdata to 'dest'. Otherwise return an error.
525 rdata_validate(isc_buffer_t
*src
, isc_buffer_t
*dest
, dns_rdataclass_t rdclass
,
526 dns_rdatatype_t type
)
528 dns_decompress_t dctx
;
529 dns_rdata_t rdata
= DNS_RDATA_INIT
;
532 dns_decompress_init(&dctx
, -1, DNS_DECOMPRESS_NONE
);
533 isc_buffer_setactive(src
, isc_buffer_usedlength(src
));
534 result
= dns_rdata_fromwire(&rdata
, rdclass
, type
, src
,
536 dns_decompress_invalidate(&dctx
);
542 unknown_fromtext(dns_rdataclass_t rdclass
, dns_rdatatype_t type
,
543 isc_lex_t
*lexer
, isc_mem_t
*mctx
, isc_buffer_t
*target
)
546 isc_buffer_t
*buf
= NULL
;
549 if (type
== 0 || dns_rdatatype_ismeta(type
))
550 return (DNS_R_METATYPE
);
552 result
= isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_number
,
554 if (result
== ISC_R_SUCCESS
&& token
.value
.as_ulong
> 65535U)
555 return (ISC_R_RANGE
);
556 result
= isc_buffer_allocate(mctx
, &buf
, token
.value
.as_ulong
);
557 if (result
!= ISC_R_SUCCESS
)
560 result
= isc_hex_tobuffer(lexer
, buf
,
561 (unsigned int)token
.value
.as_ulong
);
562 if (result
!= ISC_R_SUCCESS
)
564 if (isc_buffer_usedlength(buf
) != token
.value
.as_ulong
) {
565 result
= ISC_R_UNEXPECTEDEND
;
569 if (dns_rdatatype_isknown(type
)) {
570 result
= rdata_validate(buf
, target
, rdclass
, type
);
573 isc_buffer_usedregion(buf
, &r
);
574 result
= isc_buffer_copyregion(target
, &r
);
576 if (result
!= ISC_R_SUCCESS
)
579 isc_buffer_free(&buf
);
580 return (ISC_R_SUCCESS
);
583 isc_buffer_free(&buf
);
588 dns_rdata_fromtext(dns_rdata_t
*rdata
, dns_rdataclass_t rdclass
,
589 dns_rdatatype_t type
, isc_lex_t
*lexer
,
590 dns_name_t
*origin
, unsigned int options
, isc_mem_t
*mctx
,
591 isc_buffer_t
*target
, dns_rdatacallbacks_t
*callbacks
)
593 isc_result_t result
= ISC_R_NOTIMPLEMENTED
;
597 unsigned int lexoptions
= ISC_LEXOPT_EOL
| ISC_LEXOPT_EOF
|
598 ISC_LEXOPT_DNSMULTILINE
| ISC_LEXOPT_ESCAPE
;
601 void (*callback
)(dns_rdatacallbacks_t
*, const char *, ...);
602 isc_result_t tresult
;
604 REQUIRE(origin
== NULL
|| dns_name_isabsolute(origin
) == ISC_TRUE
);
606 REQUIRE(DNS_RDATA_INITIALIZED(rdata
));
607 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata
));
609 if (callbacks
!= NULL
) {
610 REQUIRE(callbacks
->warn
!= NULL
);
611 REQUIRE(callbacks
->error
!= NULL
);
616 if (callbacks
!= NULL
)
617 callback
= callbacks
->error
;
619 callback
= default_fromtext_callback
;
621 result
= isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_qstring
,
623 if (result
!= ISC_R_SUCCESS
) {
624 name
= isc_lex_getsourcename(lexer
);
625 line
= isc_lex_getsourceline(lexer
);
626 fromtext_error(callback
, callbacks
, name
, line
,
631 if (strcmp(DNS_AS_STR(token
), "\\#") == 0)
632 result
= unknown_fromtext(rdclass
, type
, lexer
, mctx
, target
);
634 isc_lex_ungettoken(lexer
, &token
);
640 * Consume to end of line / file.
641 * If not at end of line initially set error code.
642 * Call callback via fromtext_error once if there was an error.
645 name
= isc_lex_getsourcename(lexer
);
646 line
= isc_lex_getsourceline(lexer
);
647 tresult
= isc_lex_gettoken(lexer
, lexoptions
, &token
);
648 if (tresult
!= ISC_R_SUCCESS
) {
649 if (result
== ISC_R_SUCCESS
)
651 if (callback
!= NULL
)
652 fromtext_error(callback
, callbacks
, name
,
655 } else if (token
.type
!= isc_tokentype_eol
&&
656 token
.type
!= isc_tokentype_eof
) {
657 if (result
== ISC_R_SUCCESS
)
658 result
= DNS_R_EXTRATOKEN
;
659 if (callback
!= NULL
) {
660 fromtext_error(callback
, callbacks
, name
,
661 line
, &token
, result
);
664 } else if (result
!= ISC_R_SUCCESS
&& callback
!= NULL
) {
665 fromtext_error(callback
, callbacks
, name
, line
,
669 if (token
.type
== isc_tokentype_eof
)
670 fromtext_warneof(lexer
, callbacks
);
675 if (rdata
!= NULL
&& result
== ISC_R_SUCCESS
) {
676 region
.base
= isc_buffer_used(&st
);
677 region
.length
= isc_buffer_usedlength(target
) -
678 isc_buffer_usedlength(&st
);
679 dns_rdata_fromregion(rdata
, rdclass
, type
, ®ion
);
681 if (result
!= ISC_R_SUCCESS
) {
688 rdata_totext(dns_rdata_t
*rdata
, dns_rdata_textctx_t
*tctx
,
689 isc_buffer_t
*target
)
691 isc_result_t result
= ISC_R_NOTIMPLEMENTED
;
692 isc_boolean_t use_default
= ISC_FALSE
;
693 char buf
[sizeof("65535")];
696 REQUIRE(rdata
!= NULL
);
697 REQUIRE(tctx
->origin
== NULL
||
698 dns_name_isabsolute(tctx
->origin
) == ISC_TRUE
);
701 * Some DynDNS meta-RRs have empty rdata.
703 if ((rdata
->flags
& DNS_RDATA_UPDATE
) != 0) {
704 INSIST(rdata
->length
== 0);
705 return (ISC_R_SUCCESS
);
711 strlcpy(buf
, "\\# ", sizeof(buf
));
712 result
= str_totext(buf
, target
);
713 dns_rdata_toregion(rdata
, &sr
);
714 INSIST(sr
.length
< 65536);
715 snprintf(buf
, sizeof(buf
), "%u", sr
.length
);
716 result
= str_totext(buf
, target
);
717 if (sr
.length
!= 0 && result
== ISC_R_SUCCESS
) {
718 if ((tctx
->flags
& DNS_STYLEFLAG_MULTILINE
) != 0)
719 result
= str_totext(" ( ", target
);
721 result
= str_totext(" ", target
);
722 if (result
== ISC_R_SUCCESS
)
723 result
= isc_hex_totext(&sr
, tctx
->width
- 2,
726 if (result
== ISC_R_SUCCESS
&&
727 (tctx
->flags
& DNS_STYLEFLAG_MULTILINE
) != 0)
728 result
= str_totext(" )", target
);
736 dns_rdata_totext(dns_rdata_t
*rdata
, dns_name_t
*origin
, isc_buffer_t
*target
)
738 dns_rdata_textctx_t tctx
;
740 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata
));
743 * Set up formatting options for single-line output.
745 tctx
.origin
= origin
;
748 tctx
.linebreak
= " ";
749 return (rdata_totext(rdata
, &tctx
, target
));
753 dns_rdata_tofmttext(dns_rdata_t
*rdata
, dns_name_t
*origin
,
754 unsigned int flags
, unsigned int width
,
755 const char *linebreak
, isc_buffer_t
*target
)
757 dns_rdata_textctx_t tctx
;
759 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata
));
762 * Set up formatting options for formatted output.
764 tctx
.origin
= origin
;
766 if ((flags
& DNS_STYLEFLAG_MULTILINE
) != 0) {
768 tctx
.linebreak
= linebreak
;
770 tctx
.width
= 60; /* Used for hex word length only. */
771 tctx
.linebreak
= " ";
773 return (rdata_totext(rdata
, &tctx
, target
));
777 dns_rdata_fromstruct(dns_rdata_t
*rdata
, dns_rdataclass_t rdclass
,
778 dns_rdatatype_t type
, void *source
,
779 isc_buffer_t
*target
)
781 isc_result_t result
= ISC_R_NOTIMPLEMENTED
;
784 isc_boolean_t use_default
= ISC_FALSE
;
786 REQUIRE(source
!= NULL
);
788 REQUIRE(DNS_RDATA_INITIALIZED(rdata
));
789 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata
));
799 if (rdata
!= NULL
&& result
== ISC_R_SUCCESS
) {
800 region
.base
= isc_buffer_used(&st
);
801 region
.length
= isc_buffer_usedlength(target
) -
802 isc_buffer_usedlength(&st
);
803 dns_rdata_fromregion(rdata
, rdclass
, type
, ®ion
);
805 if (result
!= ISC_R_SUCCESS
)
811 dns_rdata_tostruct(dns_rdata_t
*rdata
, void *target
, isc_mem_t
*mctx
) {
812 isc_result_t result
= ISC_R_NOTIMPLEMENTED
;
813 isc_boolean_t use_default
= ISC_FALSE
;
815 REQUIRE(rdata
!= NULL
);
816 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata
));
827 dns_rdata_freestruct(void *source
) {
828 dns_rdatacommon_t
*common
= source
;
829 REQUIRE(source
!= NULL
);
835 dns_rdata_additionaldata(dns_rdata_t
*rdata
, dns_additionaldatafunc_t add
,
838 isc_result_t result
= ISC_R_NOTIMPLEMENTED
;
839 isc_boolean_t use_default
= ISC_FALSE
;
842 * Call 'add' for each name and type from 'rdata' which is subject to
843 * additional section processing.
846 REQUIRE(rdata
!= NULL
);
847 REQUIRE(add
!= NULL
);
848 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata
));
852 /* No additional processing for unknown types */
854 result
= ISC_R_SUCCESS
;
860 dns_rdata_digest(dns_rdata_t
*rdata
, dns_digestfunc_t digest
, void *arg
) {
861 isc_result_t result
= ISC_R_NOTIMPLEMENTED
;
862 isc_boolean_t use_default
= ISC_FALSE
;
866 * Send 'rdata' in DNSSEC canonical form to 'digest'.
869 REQUIRE(rdata
!= NULL
);
870 REQUIRE(digest
!= NULL
);
871 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata
));
876 dns_rdata_toregion(rdata
, &r
);
877 result
= (digest
)(arg
, &r
);
884 dns_rdata_checkowner(dns_name_t
*name
, dns_rdataclass_t rdclass
,
885 dns_rdatatype_t type
, isc_boolean_t wildcard
)
887 isc_boolean_t result
;
894 dns_rdata_checknames(dns_rdata_t
*rdata
, dns_name_t
*owner
, dns_name_t
*bad
)
896 isc_boolean_t result
;
903 dns_rdatatype_attributes(dns_rdatatype_t type
)
905 RDATATYPE_ATTRIBUTE_SW
906 if (type
>= (dns_rdatatype_t
)128 && type
< (dns_rdatatype_t
)255)
907 return (DNS_RDATATYPEATTR_UNKNOWN
| DNS_RDATATYPEATTR_META
);
908 return (DNS_RDATATYPEATTR_UNKNOWN
);
912 dns_rdatatype_fromtext(dns_rdatatype_t
*typep
, isc_textregion_t
*source
) {
920 return (DNS_R_UNKNOWN
);
922 a
= tolower((unsigned char)source
->base
[0]);
923 b
= tolower((unsigned char)source
->base
[n
- 1]);
925 hash
= ((a
+ n
) * b
) % 256;
928 * This switch block is inlined via \#define, and will use "return"
929 * to return a result to the caller if it is a valid (known)
932 RDATATYPE_FROMTEXT_SW(hash
, source
->base
, n
, typep
);
934 if (source
->length
> 4 && source
->length
< (4 + sizeof("65000")) &&
935 strncasecmp("type", source
->base
, 4) == 0) {
936 char buf
[sizeof("65000")];
940 strncpy(buf
, source
->base
+ 4, source
->length
- 4);
941 buf
[source
->length
- 4] = '\0';
942 val
= strtoul(buf
, &endp
, 10);
943 if (*endp
== '\0' && val
<= 0xffff) {
944 *typep
= (dns_rdatatype_t
)val
;
945 return (ISC_R_SUCCESS
);
949 return (DNS_R_UNKNOWN
);
953 dns_rdatatype_totext(dns_rdatatype_t type
, isc_buffer_t
*target
) {
954 char buf
[sizeof("TYPE65535")];
957 snprintf(buf
, sizeof(buf
), "TYPE%u", type
);
958 return (str_totext(buf
, target
));
962 dns_rdatatype_format(dns_rdatatype_t rdtype
,
963 char *array
, unsigned int size
)
968 isc_buffer_init(&buf
, array
, size
);
969 result
= dns_rdatatype_totext(rdtype
, &buf
);
973 if (result
== ISC_R_SUCCESS
) {
974 if (isc_buffer_availablelength(&buf
) >= 1)
975 isc_buffer_putuint8(&buf
, 0);
977 result
= ISC_R_NOSPACE
;
979 if (result
!= ISC_R_SUCCESS
) {
980 snprintf(array
, size
, "<unknown>");
981 array
[size
- 1] = '\0';
990 name_length(dns_name_t
*name
) {
991 return (name
->length
);
995 txt_totext(isc_region_t
*source
, isc_buffer_t
*target
) {
1000 isc_region_t region
;
1002 isc_buffer_availableregion(target
, ®ion
);
1004 tp
= (char *)region
.base
;
1009 REQUIRE(n
+ 1 <= source
->length
);
1012 return (ISC_R_NOSPACE
);
1016 if (*sp
< 0x20 || *sp
>= 0x7f) {
1018 return (ISC_R_NOSPACE
);
1020 *tp
++ = 0x30 + ((*sp
/ 100) % 10);
1021 *tp
++ = 0x30 + ((*sp
/ 10) % 10);
1022 *tp
++ = 0x30 + (*sp
% 10);
1027 /* double quote, semi-colon, backslash */
1028 if (*sp
== 0x22 || *sp
== 0x3b || *sp
== 0x5c) {
1030 return (ISC_R_NOSPACE
);
1035 return (ISC_R_NOSPACE
);
1040 return (ISC_R_NOSPACE
);
1043 isc_buffer_add(target
, tp
- (char *)region
.base
);
1044 isc_region_consume(source
, *source
->base
+ 1);
1045 return (ISC_R_SUCCESS
);
1049 txt_fromtext(isc_textregion_t
*source
, isc_buffer_t
*target
) {
1050 isc_region_t tregion
;
1051 isc_boolean_t escape
;
1052 unsigned int n
, nrem
;
1058 isc_buffer_availableregion(target
, &tregion
);
1062 nrem
= tregion
.length
;
1065 return (ISC_R_NOSPACE
);
1072 * Maximum text string length.
1078 if (escape
&& (d
= decvalue((char)c
)) != -1) {
1081 return (DNS_R_SYNTAX
);
1083 if ((d
= decvalue(*s
++)) != -1)
1086 return (DNS_R_SYNTAX
);
1088 return (DNS_R_SYNTAX
);
1090 if ((d
= decvalue(*s
++)) != -1)
1093 return (DNS_R_SYNTAX
);
1095 return (DNS_R_SYNTAX
);
1096 } else if (!escape
&& c
== '\\') {
1102 return (ISC_R_NOSPACE
);
1107 return (DNS_R_SYNTAX
);
1108 *tregion
.base
= t
- tregion
.base
- 1;
1109 isc_buffer_add(target
, *tregion
.base
+ 1);
1110 return (ISC_R_SUCCESS
);
1114 txt_fromwire(isc_buffer_t
*source
, isc_buffer_t
*target
) {
1116 isc_region_t sregion
;
1117 isc_region_t tregion
;
1119 isc_buffer_activeregion(source
, &sregion
);
1120 if (sregion
.length
== 0)
1121 return(ISC_R_UNEXPECTEDEND
);
1122 n
= *sregion
.base
+ 1;
1123 if (n
> sregion
.length
)
1124 return (ISC_R_UNEXPECTEDEND
);
1126 isc_buffer_availableregion(target
, &tregion
);
1127 if (n
> tregion
.length
)
1128 return (ISC_R_NOSPACE
);
1130 memcpy(tregion
.base
, sregion
.base
, n
);
1131 isc_buffer_forward(source
, n
);
1132 isc_buffer_add(target
, n
);
1133 return (ISC_R_SUCCESS
);
1136 static isc_boolean_t
1137 name_prefix(dns_name_t
*name
, dns_name_t
*origin
, dns_name_t
*target
) {
1143 if (dns_name_compare(origin
, dns_rootname
) == 0)
1146 if (!dns_name_issubdomain(name
, origin
))
1149 l1
= dns_name_countlabels(name
);
1150 l2
= dns_name_countlabels(origin
);
1155 dns_name_getlabelsequence(name
, 0, l1
- l2
, target
);
1164 str_totext(const char *source
, isc_buffer_t
*target
) {
1166 isc_region_t region
;
1168 isc_buffer_availableregion(target
, ®ion
);
1171 if (l
> region
.length
)
1172 return (ISC_R_NOSPACE
);
1174 memcpy(region
.base
, source
, l
);
1175 isc_buffer_add(target
, l
);
1176 return (ISC_R_SUCCESS
);
1180 inet_totext(int af
, isc_region_t
*src
, isc_buffer_t
*target
) {
1183 /* Note - inet_ntop doesn't do size checking on its input. */
1184 if (inet_ntop(af
, src
->base
, tmpbuf
, sizeof(tmpbuf
)) == NULL
)
1185 return (ISC_R_NOSPACE
);
1186 if (strlen(tmpbuf
) > isc_buffer_availablelength(target
))
1187 return (ISC_R_NOSPACE
);
1188 isc_buffer_putstr(target
, tmpbuf
);
1189 return (ISC_R_SUCCESS
);
1192 static isc_boolean_t
1193 buffer_empty(isc_buffer_t
*source
) {
1194 return((source
->current
== source
->active
) ? ISC_TRUE
: ISC_FALSE
);
1198 buffer_fromregion(isc_buffer_t
*buffer
, isc_region_t
*region
) {
1199 isc_buffer_init(buffer
, region
->base
, region
->length
);
1200 isc_buffer_add(buffer
, region
->length
);
1201 isc_buffer_setactive(buffer
, region
->length
);
1205 uint32_tobuffer(isc_uint32_t value
, isc_buffer_t
*target
) {
1206 isc_region_t region
;
1208 isc_buffer_availableregion(target
, ®ion
);
1209 if (region
.length
< 4)
1210 return (ISC_R_NOSPACE
);
1211 isc_buffer_putuint32(target
, value
);
1212 return (ISC_R_SUCCESS
);
1216 uint16_tobuffer(isc_uint32_t value
, isc_buffer_t
*target
) {
1217 isc_region_t region
;
1220 return (ISC_R_RANGE
);
1221 isc_buffer_availableregion(target
, ®ion
);
1222 if (region
.length
< 2)
1223 return (ISC_R_NOSPACE
);
1224 isc_buffer_putuint16(target
, (isc_uint16_t
)value
);
1225 return (ISC_R_SUCCESS
);
1229 uint8_tobuffer(isc_uint32_t value
, isc_buffer_t
*target
) {
1230 isc_region_t region
;
1233 return (ISC_R_RANGE
);
1234 isc_buffer_availableregion(target
, ®ion
);
1235 if (region
.length
< 1)
1236 return (ISC_R_NOSPACE
);
1237 isc_buffer_putuint8(target
, (isc_uint8_t
)value
);
1238 return (ISC_R_SUCCESS
);
1242 name_tobuffer(dns_name_t
*name
, isc_buffer_t
*target
) {
1244 dns_name_toregion(name
, &r
);
1245 return (isc_buffer_copyregion(target
, &r
));
1249 uint32_fromregion(isc_region_t
*region
) {
1252 REQUIRE(region
->length
>= 4);
1253 value
= region
->base
[0] << 24;
1254 value
|= region
->base
[1] << 16;
1255 value
|= region
->base
[2] << 8;
1256 value
|= region
->base
[3];
1261 uint16_consume_fromregion(isc_region_t
*region
) {
1262 isc_uint16_t r
= uint16_fromregion(region
);
1264 isc_region_consume(region
, 2);
1269 uint16_fromregion(isc_region_t
*region
) {
1271 REQUIRE(region
->length
>= 2);
1273 return ((region
->base
[0] << 8) | region
->base
[1]);
1277 uint8_fromregion(isc_region_t
*region
) {
1279 REQUIRE(region
->length
>= 1);
1281 return (region
->base
[0]);
1285 uint8_consume_fromregion(isc_region_t
*region
) {
1286 isc_uint8_t r
= uint8_fromregion(region
);
1288 isc_region_consume(region
, 1);
1293 mem_tobuffer(isc_buffer_t
*target
, void *base
, unsigned int length
) {
1296 isc_buffer_availableregion(target
, &tr
);
1297 if (length
> tr
.length
)
1298 return (ISC_R_NOSPACE
);
1299 memcpy(tr
.base
, base
, length
);
1300 isc_buffer_add(target
, length
);
1301 return (ISC_R_SUCCESS
);
1305 hexvalue(char value
) {
1309 c
= (unsigned char)value
;
1315 if ((s
= strchr(hexdigits
, c
)) == NULL
)
1317 return (s
- hexdigits
);
1321 decvalue(char value
) {
1325 * isascii() is valid for full range of int values, no need to
1328 if (!isascii(value
))
1330 if ((s
= strchr(decdigits
, value
)) == NULL
)
1332 return (s
- decdigits
);
1335 static const char atob_digits
[86] =
1336 "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \
1337 "abcdefghijklmnopqrstu";
1339 * Subroutines to convert between 8 bit binary bytes and printable ASCII.
1340 * Computes the number of bytes, and three kinds of simple checksums.
1341 * Incoming bytes are collected into 32-bit words, then printed in base 85:
1342 * exp(85,5) > exp(2,32)
1343 * The ASCII characters used are between '!' and 'u';
1344 * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data.
1346 * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for
1347 * the atob/btoa programs, released with the compress program, in mod.sources.
1348 * Modified by Mike Schwartz 8/19/86 for use in BIND.
1349 * Modified to be re-entrant 3/2/99.
1361 #define Ceor state->Ceor
1362 #define Csum state->Csum
1363 #define Crot state->Crot
1364 #define word state->word
1365 #define bcount state->bcount
1367 #define times85(x) ((((((x<<2)+x)<<2)+x)<<2)+x)
1369 static isc_result_t
byte_atob(int c
, isc_buffer_t
*target
,
1370 struct state
*state
);
1371 static isc_result_t
putbyte(int c
, isc_buffer_t
*, struct state
*state
);
1372 static isc_result_t
byte_btoa(int c
, isc_buffer_t
*, struct state
*state
);
1375 * Decode ASCII-encoded byte c into binary representation and
1376 * place into *bufp, advancing bufp.
1379 byte_atob(int c
, isc_buffer_t
*target
, struct state
*state
) {
1383 return(DNS_R_SYNTAX
);
1385 RETERR(putbyte(0, target
, state
));
1386 RETERR(putbyte(0, target
, state
));
1387 RETERR(putbyte(0, target
, state
));
1388 RETERR(putbyte(0, target
, state
));
1390 } else if ((s
= strchr(atob_digits
, c
)) != NULL
) {
1392 word
= s
- atob_digits
;
1394 } else if (bcount
< 4) {
1395 word
= times85(word
);
1396 word
+= s
- atob_digits
;
1399 word
= times85(word
);
1400 word
+= s
- atob_digits
;
1401 RETERR(putbyte((word
>> 24) & 0xff, target
, state
));
1402 RETERR(putbyte((word
>> 16) & 0xff, target
, state
));
1403 RETERR(putbyte((word
>> 8) & 0xff, target
, state
));
1404 RETERR(putbyte(word
& 0xff, target
, state
));
1409 return(DNS_R_SYNTAX
);
1410 return(ISC_R_SUCCESS
);
1414 * Compute checksum info and place c into target.
1417 putbyte(int c
, isc_buffer_t
*target
, struct state
*state
) {
1423 if ((Crot
& 0x80000000)) {
1430 isc_buffer_availableregion(target
, &tr
);
1432 return (ISC_R_NOSPACE
);
1434 isc_buffer_add(target
, 1);
1435 return (ISC_R_SUCCESS
);
1439 * Read the ASCII-encoded data from inbuf, of length inbuflen, and convert
1440 * it into T_UNSPEC (binary data) in outbuf, not to exceed outbuflen bytes;
1441 * outbuflen must be divisible by 4. (Note: this is because outbuf is filled
1442 * in 4 bytes at a time. If the actual data doesn't end on an even 4-byte
1443 * boundary, there will be no problem...it will be padded with 0 bytes, and
1444 * numbytes will indicate the correct number of bytes. The main point is
1445 * that since the buffer is filled in 4 bytes at a time, even if there is
1446 * not a full 4 bytes of data at the end, there has to be room to 0-pad the
1447 * data, so the buffer must be of size divisible by 4). Place the number of
1448 * output bytes in numbytes, and return a failure/success status.
1452 atob_tobuffer(isc_lex_t
*lexer
, isc_buffer_t
*target
) {
1453 long oeor
, osum
, orot
;
1454 struct state statebuf
, *state
= &statebuf
;
1459 Ceor
= Csum
= Crot
= word
= bcount
= 0;
1461 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
1463 while (token
.value
.as_textregion
.length
!= 0) {
1464 if ((c
= token
.value
.as_textregion
.base
[0]) == 'x') {
1467 RETERR(byte_atob(c
, target
, state
));
1468 isc_textregion_consume(&token
.value
.as_textregion
, 1);
1474 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_number
,
1476 if ((token
.value
.as_ulong
% 4) != 0U)
1477 isc_buffer_subtract(target
, 4 - (token
.value
.as_ulong
% 4));
1482 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
1484 oeor
= strtol(DNS_AS_STR(token
), &e
, 16);
1486 return (DNS_R_SYNTAX
);
1491 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
1493 osum
= strtol(DNS_AS_STR(token
), &e
, 16);
1495 return (DNS_R_SYNTAX
);
1500 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
1502 orot
= strtol(DNS_AS_STR(token
), &e
, 16);
1504 return (DNS_R_SYNTAX
);
1506 if ((oeor
!= Ceor
) || (osum
!= Csum
) || (orot
!= Crot
))
1507 return(DNS_R_BADCKSUM
);
1508 return (ISC_R_SUCCESS
);
1512 * Encode binary byte c into ASCII representation and place into *bufp,
1516 byte_btoa(int c
, isc_buffer_t
*target
, struct state
*state
) {
1519 isc_buffer_availableregion(target
, &tr
);
1523 if ((Crot
& 0x80000000)) {
1536 return (ISC_R_NOSPACE
);
1538 isc_buffer_add(target
, 1);
1540 register int tmp
= 0;
1541 register isc_int32_t tmpword
= word
;
1545 * Because some don't support u_long.
1548 tmpword
-= (isc_int32_t
)(85 * 85 * 85 * 85 * 32);
1552 tmpword
-= (isc_int32_t
)(85 * 85 * 85 * 85 * 32);
1555 return (ISC_R_NOSPACE
);
1556 tr
.base
[0] = atob_digits
[(tmpword
/
1557 (isc_int32_t
)(85 * 85 * 85 * 85))
1559 tmpword
%= (isc_int32_t
)(85 * 85 * 85 * 85);
1560 tr
.base
[1] = atob_digits
[tmpword
/ (85 * 85 * 85)];
1561 tmpword
%= (85 * 85 * 85);
1562 tr
.base
[2] = atob_digits
[tmpword
/ (85 * 85)];
1563 tmpword
%= (85 * 85);
1564 tr
.base
[3] = atob_digits
[tmpword
/ 85];
1566 tr
.base
[4] = atob_digits
[tmpword
];
1567 isc_buffer_add(target
, 5);
1573 return (ISC_R_SUCCESS
);
1578 * Encode the binary data from inbuf, of length inbuflen, into a
1579 * target. Return success/failure status
1582 btoa_totext(unsigned char *inbuf
, int inbuflen
, isc_buffer_t
*target
) {
1584 struct state statebuf
, *state
= &statebuf
;
1585 char buf
[sizeof("x 2000000000 ffffffff ffffffff ffffffff")];
1587 Ceor
= Csum
= Crot
= word
= bcount
= 0;
1588 for (inc
= 0; inc
< inbuflen
; inbuf
++, inc
++)
1589 RETERR(byte_btoa(*inbuf
, target
, state
));
1592 RETERR(byte_btoa(0, target
, state
));
1595 * Put byte count and checksum information at end of buffer,
1598 snprintf(buf
, sizeof(buf
), "x %d %x %x %x", inbuflen
, Ceor
, Csum
, Crot
);
1599 return (str_totext(buf
, target
));
1604 default_fromtext_callback(dns_rdatacallbacks_t
*callbacks
, const char *fmt
,
1612 vfprintf(stderr
, fmt
, ap
);
1614 fprintf(stderr
, "\n");
1618 fromtext_warneof(isc_lex_t
*lexer
, dns_rdatacallbacks_t
*callbacks
) {
1619 if (isc_lex_isfile(lexer
) && callbacks
!= NULL
) {
1620 const char *name
= isc_lex_getsourcename(lexer
);
1623 (*callbacks
->warn
)(callbacks
,
1624 "%s:%lu: file does not end with newline",
1625 name
, isc_lex_getsourceline(lexer
));
1630 warn_badmx(isc_token_t
*token
, isc_lex_t
*lexer
,
1631 dns_rdatacallbacks_t
*callbacks
)
1636 if (lexer
!= NULL
) {
1637 file
= isc_lex_getsourcename(lexer
);
1638 line
= isc_lex_getsourceline(lexer
);
1639 (*callbacks
->warn
)(callbacks
, "%s:%u: warning: '%s': %s",
1640 file
, line
, DNS_AS_STR(*token
),
1641 dns_result_totext(DNS_R_MXISADDRESS
));
1646 warn_badname(dns_name_t
*name
, isc_lex_t
*lexer
,
1647 dns_rdatacallbacks_t
*callbacks
)
1651 char namebuf
[DNS_NAME_FORMATSIZE
];
1653 if (lexer
!= NULL
) {
1654 file
= isc_lex_getsourcename(lexer
);
1655 line
= isc_lex_getsourceline(lexer
);
1656 dns_name_format(name
, namebuf
, sizeof(namebuf
));
1657 (*callbacks
->warn
)(callbacks
, "%s:%u: warning: %s: %s",
1658 file
, line
, namebuf
,
1659 dns_result_totext(DNS_R_BADNAME
));
1664 fromtext_error(void (*callback
)(dns_rdatacallbacks_t
*, const char *, ...),
1665 dns_rdatacallbacks_t
*callbacks
, const char *name
,
1666 unsigned long line
, isc_token_t
*token
, isc_result_t result
)
1671 if (token
!= NULL
) {
1672 switch (token
->type
) {
1673 case isc_tokentype_eol
:
1674 (*callback
)(callbacks
, "%s: %s:%lu: near eol: %s",
1675 "dns_rdata_fromtext", name
, line
,
1676 dns_result_totext(result
));
1678 case isc_tokentype_eof
:
1679 (*callback
)(callbacks
, "%s: %s:%lu: near eof: %s",
1680 "dns_rdata_fromtext", name
, line
,
1681 dns_result_totext(result
));
1683 case isc_tokentype_number
:
1684 (*callback
)(callbacks
, "%s: %s:%lu: near %lu: %s",
1685 "dns_rdata_fromtext", name
, line
,
1686 token
->value
.as_ulong
,
1687 dns_result_totext(result
));
1689 case isc_tokentype_string
:
1690 case isc_tokentype_qstring
:
1691 (*callback
)(callbacks
, "%s: %s:%lu: near '%s': %s",
1692 "dns_rdata_fromtext", name
, line
,
1694 dns_result_totext(result
));
1697 (*callback
)(callbacks
, "%s: %s:%lu: %s",
1698 "dns_rdata_fromtext", name
, line
,
1699 dns_result_totext(result
));
1703 (*callback
)(callbacks
, "dns_rdata_fromtext: %s:%lu: %s",
1704 name
, line
, dns_result_totext(result
));
1709 dns_rdata_covers(dns_rdata_t
*rdata
) {
1710 if (rdata
->type
== 46)
1711 return (covers_rrsig(rdata
));
1712 return (covers_sig(rdata
));
1716 dns_rdatatype_ismeta(dns_rdatatype_t type
) {
1717 if ((dns_rdatatype_attributes(type
) & DNS_RDATATYPEATTR_META
) != 0)
1723 dns_rdatatype_issingleton(dns_rdatatype_t type
) {
1724 if ((dns_rdatatype_attributes(type
) & DNS_RDATATYPEATTR_SINGLETON
)
1731 dns_rdatatype_notquestion(dns_rdatatype_t type
) {
1732 if ((dns_rdatatype_attributes(type
) & DNS_RDATATYPEATTR_NOTQUESTION
)
1739 dns_rdatatype_questiononly(dns_rdatatype_t type
) {
1740 if ((dns_rdatatype_attributes(type
) & DNS_RDATATYPEATTR_QUESTIONONLY
)
1747 dns_rdatatype_atparent(dns_rdatatype_t type
) {
1748 if ((dns_rdatatype_attributes(type
) & DNS_RDATATYPEATTR_ATPARENT
) != 0)
1754 dns_rdataclass_ismeta(dns_rdataclass_t rdclass
) {
1756 if (rdclass
== dns_rdataclass_reserved0
1757 || rdclass
== dns_rdataclass_none
1758 || rdclass
== dns_rdataclass_any
)
1761 return (ISC_FALSE
); /* Assume it is not a meta class. */
1765 dns_rdatatype_isdnssec(dns_rdatatype_t type
) {
1766 if ((dns_rdatatype_attributes(type
) & DNS_RDATATYPEATTR_DNSSEC
) != 0)
1772 dns_rdatatype_iszonecutauth(dns_rdatatype_t type
) {
1773 if ((dns_rdatatype_attributes(type
)
1774 & (DNS_RDATATYPEATTR_DNSSEC
| DNS_RDATATYPEATTR_ZONECUTAUTH
))
1781 dns_rdatatype_isknown(dns_rdatatype_t type
) {
1782 if ((dns_rdatatype_attributes(type
) & DNS_RDATATYPEATTR_UNKNOWN
)
1789 dns_rdata_exists(dns_rdata_t
*rdata
, dns_rdatatype_t type
) {
1791 REQUIRE(rdata
!= NULL
);
1792 REQUIRE(DNS_RDATA_INITIALIZED(rdata
));
1796 rdata
->flags
= DNS_RDATA_UPDATE
;
1798 rdata
->rdclass
= dns_rdataclass_any
;
1802 dns_rdata_notexist(dns_rdata_t
*rdata
, dns_rdatatype_t type
) {
1804 REQUIRE(rdata
!= NULL
);
1805 REQUIRE(DNS_RDATA_INITIALIZED(rdata
));
1809 rdata
->flags
= DNS_RDATA_UPDATE
;
1811 rdata
->rdclass
= dns_rdataclass_none
;
1815 dns_rdata_deleterrset(dns_rdata_t
*rdata
, dns_rdatatype_t type
) {
1817 REQUIRE(rdata
!= NULL
);
1818 REQUIRE(DNS_RDATA_INITIALIZED(rdata
));
1822 rdata
->flags
= DNS_RDATA_UPDATE
;
1824 rdata
->rdclass
= dns_rdataclass_any
;
1828 dns_rdata_makedelete(dns_rdata_t
*rdata
) {
1829 REQUIRE(rdata
!= NULL
);
1831 rdata
->rdclass
= dns_rdataclass_none
;
1835 dns_rdata_updateop(dns_rdata_t
*rdata
, dns_section_t section
) {
1837 REQUIRE(rdata
!= NULL
);
1838 REQUIRE(DNS_RDATA_INITIALIZED(rdata
));
1841 case DNS_SECTION_PREREQUISITE
:
1842 switch (rdata
->rdclass
) {
1843 case dns_rdataclass_none
:
1844 switch (rdata
->type
) {
1845 case dns_rdatatype_any
:
1846 return ("domain doesn't exist");
1848 return ("rrset doesn't exist");
1850 case dns_rdataclass_any
:
1851 switch (rdata
->type
) {
1852 case dns_rdatatype_any
:
1853 return ("domain exists");
1855 return ("rrset exists (value independent)");
1858 return ("rrset exists (value dependent)");
1860 case DNS_SECTION_UPDATE
:
1861 switch (rdata
->rdclass
) {
1862 case dns_rdataclass_none
:
1864 case dns_rdataclass_any
:
1865 switch (rdata
->type
) {
1866 case dns_rdatatype_any
:
1867 return ("delete all rrsets");
1869 return ("delete rrset");