2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1998-2003 Internet Software Consortium.
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.
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.
18 /* $Id: rdata.c,v 1.147.2.12 2004/03/09 06:11:05 marka Exp $ */
23 #include <isc/base64.h>
27 #include <isc/print.h>
28 #include <isc/string.h>
31 #include <dns/callbacks.h>
33 #include <dns/compress.h>
34 #include <dns/keyflags.h>
35 #include <dns/rcode.h>
36 #include <dns/rdata.h>
37 #include <dns/rdataclass.h>
38 #include <dns/rdatastruct.h>
39 #include <dns/rdatatype.h>
40 #include <dns/result.h>
41 #include <dns/secalg.h>
42 #include <dns/secproto.h>
48 isc_result_t _r = (x); \
49 if (_r != ISC_R_SUCCESS) \
54 isc_result_t _r = (x); \
55 if (_r != ISC_R_SUCCESS) { \
56 isc_lex_ungettoken(lexer, &token); \
61 #define ARGS_FROMTEXT int rdclass, dns_rdatatype_t type, \
62 isc_lex_t *lexer, dns_name_t *origin, \
63 isc_boolean_t downcase, isc_buffer_t *target, \
64 dns_rdatacallbacks_t *callbacks
66 #define ARGS_TOTEXT dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, \
69 #define ARGS_FROMWIRE int rdclass, dns_rdatatype_t type, \
70 isc_buffer_t *source, dns_decompress_t *dctx, \
71 isc_boolean_t downcase, isc_buffer_t *target
73 #define ARGS_TOWIRE dns_rdata_t *rdata, dns_compress_t *cctx, \
76 #define ARGS_COMPARE const dns_rdata_t *rdata1, const dns_rdata_t *rdata2
78 #define ARGS_FROMSTRUCT int rdclass, dns_rdatatype_t type, \
79 void *source, isc_buffer_t *target
81 #define ARGS_TOSTRUCT dns_rdata_t *rdata, void *target, isc_mem_t *mctx
83 #define ARGS_FREESTRUCT void *source
85 #define ARGS_ADDLDATA dns_rdata_t *rdata, dns_additionaldatafunc_t add, \
88 #define ARGS_DIGEST dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg
91 * Context structure for the totext_ functions.
92 * Contains formatting options for rdata-to-text
95 typedef struct dns_rdata_textctx {
96 dns_name_t *origin; /* Current origin, or NULL. */
97 unsigned int flags; /* DNS_STYLEFLAG_* */
98 unsigned int width; /* Width of rdata column. */
99 const char *linebreak; /* Line break string. */
100 } dns_rdata_textctx_t;
103 txt_totext(isc_region_t *source, isc_buffer_t *target);
106 txt_fromtext(isc_textregion_t *source, isc_buffer_t *target);
109 txt_fromwire(isc_buffer_t *source, isc_buffer_t *target);
112 name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target);
115 name_length(dns_name_t *name);
118 str_totext(const char *source, isc_buffer_t *target);
121 inet_totext(int af, isc_region_t *src, isc_buffer_t *target);
124 buffer_empty(isc_buffer_t *source);
127 buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region);
130 uint32_tobuffer(isc_uint32_t, isc_buffer_t *target);
133 uint16_tobuffer(isc_uint32_t, isc_buffer_t *target);
136 uint8_tobuffer(isc_uint32_t, isc_buffer_t *target);
139 name_tobuffer(dns_name_t *name, isc_buffer_t *target);
142 uint32_fromregion(isc_region_t *region);
145 uint16_fromregion(isc_region_t *region);
148 uint8_fromregion(isc_region_t *region);
151 mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length);
154 compare_region(isc_region_t *r1, isc_region_t *r2);
157 hexvalue(char value);
160 decvalue(char value);
163 btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target);
166 atob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target);
169 default_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *, ...)
170 ISC_FORMAT_PRINTF(2, 3);
173 fromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...),
174 dns_rdatacallbacks_t *callbacks, const char *name,
175 unsigned long line, isc_token_t *token, isc_result_t result);
178 fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks);
181 rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
182 isc_buffer_t *target);
185 getquad(const void *src, struct in_addr *dst,
186 isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks)
191 result = inet_aton(src, dst);
192 if (result == 1 && callbacks != NULL &&
193 inet_pton(AF_INET, src, &tmp) != 1) {
194 const char *name = isc_lex_getsourcename(lexer);
197 (*callbacks->warn)(callbacks, "%s:%lu: warning \"%s\" "
198 "is not a decimal dotted quad", name,
199 isc_lex_getsourceline(lexer), src);
204 static inline isc_result_t
205 name_duporclone(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) {
208 return (dns_name_dup(source, mctx, target));
209 dns_name_clone(source, target);
210 return (ISC_R_SUCCESS);
214 mem_maybedup(isc_mem_t *mctx, void *source, size_t length) {
219 new = isc_mem_allocate(mctx, length);
221 memcpy(new, source, length);
226 static const char hexdigits[] = "0123456789abcdef";
227 static const char decdigits[] = "0123456789";
232 #define RESERVED 0x0002
235 /* standard rcodes */ \
236 { dns_rcode_noerror, "NOERROR", 0}, \
237 { dns_rcode_formerr, "FORMERR", 0}, \
238 { dns_rcode_servfail, "SERVFAIL", 0}, \
239 { dns_rcode_nxdomain, "NXDOMAIN", 0}, \
240 { dns_rcode_notimp, "NOTIMP", 0}, \
241 { dns_rcode_refused, "REFUSED", 0}, \
242 { dns_rcode_yxdomain, "YXDOMAIN", 0}, \
243 { dns_rcode_yxrrset, "YXRRSET", 0}, \
244 { dns_rcode_nxrrset, "NXRRSET", 0}, \
245 { dns_rcode_notauth, "NOTAUTH", 0}, \
246 { dns_rcode_notzone, "NOTZONE", 0},
248 #define ERCODENAMES \
249 /* extended rcodes */ \
250 { dns_rcode_badvers, "BADVERS", 0}, \
253 #define TSIGRCODENAMES \
254 /* extended rcodes */ \
255 { dns_tsigerror_badsig, "BADSIG", 0}, \
256 { dns_tsigerror_badkey, "BADKEY", 0}, \
257 { dns_tsigerror_badtime, "BADTIME", 0}, \
258 { dns_tsigerror_badmode, "BADMODE", 0}, \
259 { dns_tsigerror_badname, "BADNAME", 0}, \
260 { dns_tsigerror_badalg, "BADALG", 0}, \
263 /* RFC2538 section 2.1 */
273 /* RFC2535 section 7 */
275 #define SECALGNAMES \
276 { 1, "RSAMD5", 0 }, \
280 { 252, "INDIRECT", 0 }, \
281 { 253, "PRIVATEDNS", 0 }, \
282 { 254, "PRIVATEOID", 0 }, \
285 /* RFC2535 section 7.1 */
287 #define SECPROTONAMES \
291 { 3, "DNSSEC", 0 }, \
302 static struct tbl rcodes[] = { RCODENAMES ERCODENAMES };
303 static struct tbl tsigrcodes[] = { RCODENAMES TSIGRCODENAMES };
304 static struct tbl certs[] = { CERTNAMES };
305 static struct tbl secalgs[] = { SECALGNAMES };
306 static struct tbl secprotos[] = { SECPROTONAMES };
308 static struct keyflag {
313 { "NOCONF", 0x4000, 0xC000 },
314 { "NOAUTH", 0x8000, 0xC000 },
315 { "NOKEY", 0xC000, 0xC000 },
316 { "FLAG2", 0x2000, 0x2000 },
317 { "EXTEND", 0x1000, 0x1000 },
318 { "FLAG4", 0x0800, 0x0800 },
319 { "FLAG5", 0x0400, 0x0400 },
320 { "USER", 0x0000, 0x0300 },
321 { "ZONE", 0x0100, 0x0300 },
322 { "HOST", 0x0200, 0x0300 },
323 { "NTYP3", 0x0300, 0x0300 },
324 { "FLAG8", 0x0080, 0x0080 },
325 { "FLAG9", 0x0040, 0x0040 },
326 { "FLAG10", 0x0020, 0x0020 },
327 { "FLAG11", 0x0010, 0x0010 },
328 { "SIG0", 0x0000, 0x000F },
329 { "SIG1", 0x0001, 0x000F },
330 { "SIG2", 0x0002, 0x000F },
331 { "SIG3", 0x0003, 0x000F },
332 { "SIG4", 0x0004, 0x000F },
333 { "SIG5", 0x0005, 0x000F },
334 { "SIG6", 0x0006, 0x000F },
335 { "SIG7", 0x0007, 0x000F },
336 { "SIG8", 0x0008, 0x000F },
337 { "SIG9", 0x0009, 0x000F },
338 { "SIG10", 0x000A, 0x000F },
339 { "SIG11", 0x000B, 0x000F },
340 { "SIG12", 0x000C, 0x000F },
341 { "SIG13", 0x000D, 0x000F },
342 { "SIG14", 0x000E, 0x000F },
343 { "SIG15", 0x000F, 0x000F },
352 dns_rdata_init(dns_rdata_t *rdata) {
354 REQUIRE(rdata != NULL);
361 ISC_LINK_INIT(rdata, link);
362 /* ISC_LIST_INIT(rdata->list); */
366 #define DNS_RDATA_INITIALIZED(rdata) \
367 ((rdata)->data == NULL && (rdata)->length == 0 && \
368 (rdata)->rdclass == 0 && (rdata)->type == 0 && (rdata)->flags == 0 && \
369 !ISC_LINK_LINKED((rdata), link))
371 #ifdef ISC_LIST_CHECKINIT
372 #define DNS_RDATA_INITIALIZED(rdata) \
373 (!ISC_LINK_LINKED((rdata), link))
375 #define DNS_RDATA_INITIALIZED(rdata) ISC_TRUE
378 #define DNS_RDATA_VALIDFLAGS(rdata) \
379 (((rdata)->flags & ~DNS_RDATA_UPDATE) == 0)
382 dns_rdata_reset(dns_rdata_t *rdata) {
384 REQUIRE(rdata != NULL);
386 REQUIRE(!ISC_LINK_LINKED(rdata, link));
387 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
401 dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target) {
403 REQUIRE(src != NULL);
404 REQUIRE(target != NULL);
406 REQUIRE(DNS_RDATA_INITIALIZED(target));
408 REQUIRE(DNS_RDATA_VALIDFLAGS(src));
409 REQUIRE(DNS_RDATA_VALIDFLAGS(target));
411 target->data = src->data;
412 target->length = src->length;
413 target->rdclass = src->rdclass;
414 target->type = src->type;
415 target->flags = src->flags;
424 dns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2) {
426 isc_boolean_t use_default = ISC_FALSE;
428 REQUIRE(rdata1 != NULL);
429 REQUIRE(rdata2 != NULL);
430 REQUIRE(rdata1->data != NULL);
431 REQUIRE(rdata2->data != NULL);
432 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1));
433 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2));
435 if (rdata1->rdclass != rdata2->rdclass)
436 return (rdata1->rdclass < rdata2->rdclass ? -1 : 1);
438 if (rdata1->type != rdata2->type)
439 return (rdata1->type < rdata2->type ? -1 : 1);
447 dns_rdata_toregion(rdata1, &r1);
448 dns_rdata_toregion(rdata2, &r2);
449 result = compare_region(&r1, &r2);
459 dns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
460 dns_rdatatype_t type, isc_region_t *r)
463 REQUIRE(rdata != NULL);
464 REQUIRE(DNS_RDATA_INITIALIZED(rdata));
467 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
469 rdata->data = r->base;
470 rdata->length = r->length;
471 rdata->rdclass = rdclass;
477 dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r) {
479 REQUIRE(rdata != NULL);
481 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
483 r->base = rdata->data;
484 r->length = rdata->length;
488 dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
489 dns_rdatatype_t type, isc_buffer_t *source,
490 dns_decompress_t *dctx, isc_boolean_t downcase,
491 isc_buffer_t *target)
493 isc_result_t result = ISC_R_NOTIMPLEMENTED;
497 isc_boolean_t use_default = ISC_FALSE;
498 isc_uint32_t activelength;
500 REQUIRE(dctx != NULL);
502 REQUIRE(DNS_RDATA_INITIALIZED(rdata));
503 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
507 return (DNS_R_FORMERR);
512 activelength = isc_buffer_activelength(source);
513 INSIST(activelength < 65536);
518 if (activelength > isc_buffer_availablelength(target))
519 result = ISC_R_NOSPACE;
521 isc_buffer_putmem(target, isc_buffer_current(source),
523 isc_buffer_forward(source, activelength);
524 result = ISC_R_SUCCESS;
529 * We should have consumed all of our buffer.
531 if (result == ISC_R_SUCCESS && !buffer_empty(source))
532 result = DNS_R_EXTRADATA;
534 if (rdata != NULL && result == ISC_R_SUCCESS) {
535 region.base = isc_buffer_used(&st);
536 region.length = isc_buffer_usedlength(target) -
537 isc_buffer_usedlength(&st);
538 dns_rdata_fromregion(rdata, rdclass, type, ®ion);
541 if (result != ISC_R_SUCCESS) {
549 dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx,
550 isc_buffer_t *target)
552 isc_result_t result = ISC_R_NOTIMPLEMENTED;
553 isc_boolean_t use_default = ISC_FALSE;
557 REQUIRE(rdata != NULL);
558 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
561 * Some DynDNS meta-RRs have empty rdata.
563 if ((rdata->flags & DNS_RDATA_UPDATE) != 0) {
564 INSIST(rdata->length == 0);
565 return (ISC_R_SUCCESS);
573 isc_buffer_availableregion(target, &tr);
574 if (tr.length < rdata->length)
575 return (ISC_R_NOSPACE);
576 memcpy(tr.base, rdata->data, rdata->length);
577 isc_buffer_add(target, rdata->length);
578 return (ISC_R_SUCCESS);
580 if (result != ISC_R_SUCCESS) {
582 INSIST(target->used < 65536);
583 dns_compress_rollback(cctx, (isc_uint16_t)target->used);
589 * If the binary data in 'src' is valid uncompressed wire format
590 * rdata of class 'rdclass' and type 'type', return ISC_R_SUCCESS
591 * and copy the validated rdata to 'dest'. Otherwise return an error.
594 rdata_validate(isc_buffer_t *src, isc_buffer_t *dest, dns_rdataclass_t rdclass,
595 dns_rdatatype_t type)
597 dns_decompress_t dctx;
598 dns_rdata_t rdata = DNS_RDATA_INIT;
601 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
602 isc_buffer_setactive(src, isc_buffer_usedlength(src));
603 result = dns_rdata_fromwire(&rdata, rdclass, type, src,
604 &dctx, ISC_FALSE, dest);
605 dns_decompress_invalidate(&dctx);
611 unknown_fromtext(dns_rdataclass_t rdclass, dns_rdatatype_t type,
612 isc_lex_t *lexer, isc_mem_t *mctx, isc_buffer_t *target)
615 isc_buffer_t *buf = NULL;
618 if (type == 0 || dns_rdatatype_ismeta(type))
619 return (DNS_R_METATYPE);
621 result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
623 if (result == ISC_R_SUCCESS && token.value.as_ulong > 65535U)
624 return (ISC_R_RANGE);
625 result = isc_buffer_allocate(mctx, &buf, token.value.as_ulong);
626 if (result != ISC_R_SUCCESS)
629 result = isc_hex_tobuffer(lexer, buf,
630 (unsigned int)token.value.as_ulong);
631 if (result != ISC_R_SUCCESS)
633 if (isc_buffer_usedlength(buf) != token.value.as_ulong) {
634 result = ISC_R_UNEXPECTEDEND;
638 if (dns_rdatatype_isknown(type)) {
639 result = rdata_validate(buf, target, rdclass, type);
642 isc_buffer_usedregion(buf, &r);
643 result = isc_buffer_copyregion(target, &r);
645 if (result != ISC_R_SUCCESS)
648 isc_buffer_free(&buf);
649 return (ISC_R_SUCCESS);
652 isc_buffer_free(&buf);
657 dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
658 dns_rdatatype_t type, isc_lex_t *lexer,
659 dns_name_t *origin, isc_boolean_t downcase, isc_mem_t *mctx,
660 isc_buffer_t *target, dns_rdatacallbacks_t *callbacks)
662 isc_result_t result = ISC_R_NOTIMPLEMENTED;
666 unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF |
667 ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE;
670 void (*callback)(dns_rdatacallbacks_t *, const char *, ...);
671 isc_result_t tresult;
673 REQUIRE(origin == NULL || dns_name_isabsolute(origin) == ISC_TRUE);
675 REQUIRE(DNS_RDATA_INITIALIZED(rdata));
676 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
678 if (callbacks != NULL) {
679 REQUIRE(callbacks->warn != NULL);
680 REQUIRE(callbacks->error != NULL);
685 if (callbacks != NULL)
686 callback = callbacks->error;
688 callback = default_fromtext_callback;
690 result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
692 if (result != ISC_R_SUCCESS) {
693 name = isc_lex_getsourcename(lexer);
694 line = isc_lex_getsourceline(lexer);
695 fromtext_error(callback, callbacks, name, line,
700 if (strcmp((char *)token.value.as_pointer, "\\#") == 0)
701 result = unknown_fromtext(rdclass, type, lexer, mctx, target);
703 isc_lex_ungettoken(lexer, &token);
709 * Consume to end of line / file.
710 * If not at end of line initially set error code.
711 * Call callback via fromtext_error once if there was an error.
714 name = isc_lex_getsourcename(lexer);
715 line = isc_lex_getsourceline(lexer);
716 tresult = isc_lex_gettoken(lexer, options, &token);
717 if (tresult != ISC_R_SUCCESS) {
718 if (result == ISC_R_SUCCESS)
720 if (callback != NULL)
721 fromtext_error(callback, callbacks, name,
724 } else if (token.type != isc_tokentype_eol &&
725 token.type != isc_tokentype_eof) {
726 if (result == ISC_R_SUCCESS)
727 result = DNS_R_EXTRATOKEN;
728 if (callback != NULL) {
729 fromtext_error(callback, callbacks, name,
730 line, &token, result);
733 } else if (result != ISC_R_SUCCESS && callback != NULL) {
734 fromtext_error(callback, callbacks, name, line,
738 if (token.type == isc_tokentype_eof)
739 fromtext_warneof(lexer, callbacks);
744 if (rdata != NULL && result == ISC_R_SUCCESS) {
745 region.base = isc_buffer_used(&st);
746 region.length = isc_buffer_usedlength(target) -
747 isc_buffer_usedlength(&st);
748 dns_rdata_fromregion(rdata, rdclass, type, ®ion);
750 if (result != ISC_R_SUCCESS) {
757 rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
758 isc_buffer_t *target)
760 isc_result_t result = ISC_R_NOTIMPLEMENTED;
761 isc_boolean_t use_default = ISC_FALSE;
762 char buf[sizeof("65536")];
765 REQUIRE(rdata != NULL);
766 REQUIRE(tctx->origin == NULL ||
767 dns_name_isabsolute(tctx->origin) == ISC_TRUE);
770 * Some DynDNS meta-RRs have empty rdata.
772 if ((rdata->flags & DNS_RDATA_UPDATE) != 0) {
773 INSIST(rdata->length == 0);
774 return (ISC_R_SUCCESS);
780 sprintf(buf, "\\# ");
781 result = str_totext(buf, target);
782 dns_rdata_toregion(rdata, &sr);
783 INSIST(sr.length < 65536);
784 sprintf(buf, "%u", sr.length);
785 result = str_totext(buf, target);
786 if (sr.length != 0 && result == ISC_R_SUCCESS) {
787 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
788 result = str_totext(" ( ", target);
790 result = str_totext(" ", target);
791 if (result == ISC_R_SUCCESS)
792 result = isc_hex_totext(&sr, tctx->width - 2,
795 if (result == ISC_R_SUCCESS &&
796 (tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
797 result = str_totext(" )", target);
805 dns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target)
807 dns_rdata_textctx_t tctx;
809 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
812 * Set up formatting options for single-line output.
814 tctx.origin = origin;
817 tctx.linebreak = " ";
818 return (rdata_totext(rdata, &tctx, target));
822 dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin,
823 unsigned int flags, unsigned int width,
824 char *linebreak, isc_buffer_t *target)
826 dns_rdata_textctx_t tctx;
828 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
831 * Set up formatting options for formatted output.
833 tctx.origin = origin;
835 if ((flags & DNS_STYLEFLAG_MULTILINE) != 0) {
837 tctx.linebreak = linebreak;
839 tctx.width = 60; /* Used for hex word length only. */
840 tctx.linebreak = " ";
842 return (rdata_totext(rdata, &tctx, target));
846 dns_rdata_fromstruct(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
847 dns_rdatatype_t type, void *source,
848 isc_buffer_t *target)
850 isc_result_t result = ISC_R_NOTIMPLEMENTED;
853 isc_boolean_t use_default = ISC_FALSE;
855 REQUIRE(source != NULL);
857 REQUIRE(DNS_RDATA_INITIALIZED(rdata));
858 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
868 if (rdata != NULL && result == ISC_R_SUCCESS) {
869 region.base = isc_buffer_used(&st);
870 region.length = isc_buffer_usedlength(target) -
871 isc_buffer_usedlength(&st);
872 dns_rdata_fromregion(rdata, rdclass, type, ®ion);
874 if (result != ISC_R_SUCCESS)
880 dns_rdata_tostruct(dns_rdata_t *rdata, void *target, isc_mem_t *mctx) {
881 isc_result_t result = ISC_R_NOTIMPLEMENTED;
882 isc_boolean_t use_default = ISC_FALSE;
884 REQUIRE(rdata != NULL);
885 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
896 dns_rdata_freestruct(void *source) {
897 dns_rdatacommon_t *common = source;
898 REQUIRE(source != NULL);
904 dns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add,
907 isc_result_t result = ISC_R_NOTIMPLEMENTED;
908 isc_boolean_t use_default = ISC_FALSE;
911 * Call 'add' for each name and type from 'rdata' which is subject to
912 * additional section processing.
915 REQUIRE(rdata != NULL);
916 REQUIRE(add != NULL);
917 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
921 /* No additional processing for unknown types */
923 result = ISC_R_SUCCESS;
929 dns_rdata_digest(dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg) {
930 isc_result_t result = ISC_R_NOTIMPLEMENTED;
931 isc_boolean_t use_default = ISC_FALSE;
935 * Send 'rdata' in DNSSEC canonical form to 'digest'.
938 REQUIRE(rdata != NULL);
939 REQUIRE(digest != NULL);
940 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
945 dns_rdata_toregion(rdata, &r);
946 result = (digest)(arg, &r);
953 dns_rdatatype_attributes(dns_rdatatype_t type)
955 if (type < (sizeof(typeattr)/sizeof(typeattr[0])))
956 return (typeattr[type].flags);
957 return (DNS_RDATATYPEATTR_UNKNOWN);
960 #define NUMBERSIZE sizeof("037777777777") /* 2^32-1 octal + NUL */
963 dns_mnemonic_fromtext(unsigned int *valuep, isc_textregion_t *source,
964 struct tbl *table, unsigned int max)
968 if (isdigit(source->base[0] & 0xff) &&
969 source->length <= NUMBERSIZE - 1) {
972 char buffer[NUMBERSIZE];
974 * We have a potential number. Try to parse it with strtoul().
975 * strtoul() requires null termination, so we must make
978 strncpy(buffer, source->base, NUMBERSIZE);
979 INSIST(buffer[source->length] == '\0');
981 n = strtoul(buffer, &e, 10);
984 return (ISC_R_RANGE);
986 return (ISC_R_SUCCESS);
989 * It was not a number after all; fall through.
993 for (i = 0; table[i].name != NULL; i++) {
995 n = strlen(table[i].name);
996 if (n == source->length &&
997 strncasecmp(source->base, table[i].name, n) == 0) {
998 *valuep = table[i].value;
999 return (ISC_R_SUCCESS);
1002 return (DNS_R_UNKNOWN);
1006 dns_mnemonic_totext(unsigned int value, isc_buffer_t *target,
1010 char buf[sizeof "4294967296"];
1011 while (table[i].name != NULL) {
1012 if (table[i].value == value) {
1013 return (str_totext(table[i].name, target));
1017 sprintf(buf, "%u", value);
1018 return (str_totext(buf, target));
1023 * This uses lots of hard coded values, but how often do we actually
1027 dns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source) {
1028 #define COMPARE(string, rdclass) \
1029 if (((sizeof(string) - 1) == source->length) \
1030 && (strncasecmp(source->base, string, source->length) == 0)) { \
1031 *classp = rdclass; \
1032 return (ISC_R_SUCCESS); \
1035 switch (tolower((unsigned char)source->base[0])) {
1037 COMPARE("any", dns_rdataclass_any);
1041 * RFC1035 says the mnemonic for the CHAOS class is CH,
1042 * but historical BIND practice is to call it CHAOS.
1043 * We will accept both forms, but only generate CH.
1045 COMPARE("ch", dns_rdataclass_chaos);
1046 COMPARE("chaos", dns_rdataclass_chaos);
1048 if (source->length > 5 &&
1049 source->length < (5 + sizeof("65000")) &&
1050 strncasecmp("class", source->base, 5) == 0) {
1051 char buf[sizeof("65000")];
1055 strncpy(buf, source->base + 5, source->length - 5);
1056 buf[source->length - 5] = '\0';
1057 val = strtoul(buf, &endp, 10);
1058 if (*endp == '\0' && val <= 0xffff) {
1059 *classp = (dns_rdataclass_t)val;
1060 return (ISC_R_SUCCESS);
1065 COMPARE("hs", dns_rdataclass_hs);
1066 COMPARE("hesiod", dns_rdataclass_hs);
1069 COMPARE("in", dns_rdataclass_in);
1072 COMPARE("none", dns_rdataclass_none);
1075 COMPARE("reserved0", dns_rdataclass_reserved0);
1081 return (DNS_R_UNKNOWN);
1085 dns_rdataclass_totext(dns_rdataclass_t rdclass, isc_buffer_t *target) {
1086 char buf[sizeof("CLASS65535")];
1089 case dns_rdataclass_any:
1090 return (str_totext("ANY", target));
1091 case dns_rdataclass_chaos:
1092 return (str_totext("CH", target));
1093 case dns_rdataclass_hs:
1094 return (str_totext("HS", target));
1095 case dns_rdataclass_in:
1096 return (str_totext("IN", target));
1097 case dns_rdataclass_none:
1098 return (str_totext("NONE", target));
1099 case dns_rdataclass_reserved0:
1100 return (str_totext("RESERVED0", target));
1102 sprintf(buf, "CLASS%u", rdclass);
1103 return (str_totext(buf, target));
1108 dns_rdataclass_format(dns_rdataclass_t rdclass,
1109 char *array, unsigned int size)
1111 isc_result_t result;
1114 isc_buffer_init(&buf, array, size);
1115 result = dns_rdataclass_totext(rdclass, &buf);
1119 if (result == ISC_R_SUCCESS) {
1120 if (isc_buffer_availablelength(&buf) >= 1)
1121 isc_buffer_putuint8(&buf, 0);
1123 result = ISC_R_NOSPACE;
1125 if (result != ISC_R_SUCCESS) {
1126 snprintf(array, size, "<unknown>");
1127 array[size - 1] = '\0';
1132 dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source) {
1140 return (DNS_R_UNKNOWN);
1142 a = tolower((unsigned char)source->base[0]);
1143 b = tolower((unsigned char)source->base[n - 1]);
1145 hash = ((a + n) * b) % 256;
1148 * This switch block is inlined via #define, and will use "return"
1149 * to return a result to the caller if it is a valid (known)
1152 RDATATYPE_FROMTEXT_SW(hash, source->base, n, typep);
1154 if (source->length > 4 && source->length < (4 + sizeof("65000")) &&
1155 strncasecmp("type", source->base, 4) == 0) {
1156 char buf[sizeof("65000")];
1160 strncpy(buf, source->base + 4, source->length - 4);
1161 buf[source->length - 4] = '\0';
1162 val = strtoul(buf, &endp, 10);
1163 if (*endp == '\0' && val <= 0xffff) {
1164 *typep = (dns_rdatatype_t)val;
1165 return (ISC_R_SUCCESS);
1169 return (DNS_R_UNKNOWN);
1173 dns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target) {
1174 char buf[sizeof("TYPE65536")];
1176 if (type < (sizeof(typeattr)/sizeof(typeattr[0])))
1177 return (str_totext(typeattr[type].name, target));
1178 snprintf(buf, sizeof buf, "TYPE%u", type);
1179 return (str_totext(buf, target));
1183 dns_rdatatype_format(dns_rdatatype_t rdtype,
1184 char *array, unsigned int size)
1186 isc_result_t result;
1189 isc_buffer_init(&buf, array, size);
1190 result = dns_rdatatype_totext(rdtype, &buf);
1194 if (result == ISC_R_SUCCESS) {
1195 if (isc_buffer_availablelength(&buf) >= 1)
1196 isc_buffer_putuint8(&buf, 0);
1198 result = ISC_R_NOSPACE;
1200 if (result != ISC_R_SUCCESS) {
1201 snprintf(array, size, "<unknown>");
1202 array[size - 1] = '\0';
1207 /* XXXRTH Should we use a hash table here? */
1210 dns_rcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source) {
1212 RETERR(dns_mnemonic_fromtext(&value, source, rcodes, 0xffff));
1214 return (ISC_R_SUCCESS);
1218 dns_rcode_totext(dns_rcode_t rcode, isc_buffer_t *target) {
1219 return (dns_mnemonic_totext(rcode, target, rcodes));
1223 dns_tsigrcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source) {
1225 RETERR(dns_mnemonic_fromtext(&value, source, tsigrcodes, 0xffff));
1227 return (ISC_R_SUCCESS);
1231 dns_tsigrcode_totext(dns_rcode_t rcode, isc_buffer_t *target) {
1232 return (dns_mnemonic_totext(rcode, target, tsigrcodes));
1236 dns_cert_fromtext(dns_cert_t *certp, isc_textregion_t *source) {
1238 RETERR(dns_mnemonic_fromtext(&value, source, certs, 0xffff));
1240 return (ISC_R_SUCCESS);
1244 dns_cert_totext(dns_cert_t cert, isc_buffer_t *target) {
1245 return (dns_mnemonic_totext(cert, target, certs));
1249 dns_secalg_fromtext(dns_secalg_t *secalgp, isc_textregion_t *source) {
1251 RETERR(dns_mnemonic_fromtext(&value, source, secalgs, 0xff));
1253 return (ISC_R_SUCCESS);
1257 dns_secalg_totext(dns_secalg_t secalg, isc_buffer_t *target) {
1258 return (dns_mnemonic_totext(secalg, target, secalgs));
1262 dns_secproto_fromtext(dns_secproto_t *secprotop, isc_textregion_t *source) {
1264 RETERR(dns_mnemonic_fromtext(&value, source, secprotos, 0xff));
1266 return (ISC_R_SUCCESS);
1270 dns_secproto_totext(dns_secproto_t secproto, isc_buffer_t *target) {
1271 return (dns_mnemonic_totext(secproto, target, secprotos));
1275 dns_keyflags_fromtext(dns_keyflags_t *flagsp, isc_textregion_t *source)
1278 unsigned int value, mask;
1280 if (isdigit(source->base[0] & 0xff) &&
1281 source->length <= NUMBERSIZE - 1) {
1284 char buffer[NUMBERSIZE];
1286 * We have a potential number. Try to parse it with strtoul().
1287 * strtoul() requires null termination, so we must make
1290 strncpy(buffer, source->base, NUMBERSIZE);
1291 INSIST(buffer[source->length] == '\0');
1293 n = strtoul(buffer, &e, 0); /* Allow hex/octal. */
1296 return (ISC_R_RANGE);
1298 return (ISC_R_SUCCESS);
1300 /* It was not a number after all; fall through. */
1303 text = source->base;
1304 end = source->base + source->length;
1307 while (text < end) {
1310 char *delim = memchr(text, '|', end - text);
1315 for (p = keyflags; p->name != NULL; p++) {
1316 if (strncasecmp(p->name, text, len) == 0)
1319 if (p->name == NULL)
1320 return (DNS_R_UNKNOWN);
1323 if ((mask & p->mask) != 0)
1324 warn("overlapping key flags");
1329 text++; /* Skip "|" */
1332 return (ISC_R_SUCCESS);
1340 name_length(dns_name_t *name) {
1341 return (name->length);
1345 txt_totext(isc_region_t *source, isc_buffer_t *target) {
1350 isc_region_t region;
1352 isc_buffer_availableregion(target, ®ion);
1354 tp = (char *)region.base;
1359 REQUIRE(n + 1 <= source->length);
1362 return (ISC_R_NOSPACE);
1366 if (*sp < 0x20 || *sp >= 0x7f) {
1368 return (ISC_R_NOSPACE);
1369 sprintf(tp, "\\%03u", *sp++);
1374 if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c) {
1376 return (ISC_R_NOSPACE);
1381 return (ISC_R_NOSPACE);
1386 return (ISC_R_NOSPACE);
1389 isc_buffer_add(target, tp - (char *)region.base);
1390 isc_region_consume(source, *source->base + 1);
1391 return (ISC_R_SUCCESS);
1395 txt_fromtext(isc_textregion_t *source, isc_buffer_t *target) {
1396 isc_region_t tregion;
1397 isc_boolean_t escape;
1398 unsigned int n, nrem;
1404 isc_buffer_availableregion(target, &tregion);
1408 nrem = tregion.length;
1411 return (ISC_R_NOSPACE);
1418 * Maximum text string length.
1424 if (escape && (d = decvalue((char)c)) != -1) {
1427 return (DNS_R_SYNTAX);
1429 if ((d = decvalue(*s++)) != -1)
1432 return (DNS_R_SYNTAX);
1434 return (DNS_R_SYNTAX);
1436 if ((d = decvalue(*s++)) != -1)
1439 return (DNS_R_SYNTAX);
1441 return (DNS_R_SYNTAX);
1442 } else if (!escape && c == '\\') {
1448 return (ISC_R_NOSPACE);
1453 return (DNS_R_SYNTAX);
1454 *tregion.base = t - tregion.base - 1;
1455 isc_buffer_add(target, *tregion.base + 1);
1456 return (ISC_R_SUCCESS);
1460 txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) {
1462 isc_region_t sregion;
1463 isc_region_t tregion;
1465 isc_buffer_activeregion(source, &sregion);
1466 if (sregion.length == 0)
1467 return(ISC_R_UNEXPECTEDEND);
1468 n = *sregion.base + 1;
1469 if (n > sregion.length)
1470 return (ISC_R_UNEXPECTEDEND);
1472 isc_buffer_availableregion(target, &tregion);
1473 if (n > tregion.length)
1474 return (ISC_R_NOSPACE);
1476 memcpy(tregion.base, sregion.base, n);
1477 isc_buffer_forward(source, n);
1478 isc_buffer_add(target, n);
1479 return (ISC_R_SUCCESS);
1482 static isc_boolean_t
1483 name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target) {
1489 if (dns_name_compare(origin, dns_rootname) == 0)
1492 if (!dns_name_issubdomain(name, origin))
1495 l1 = dns_name_countlabels(name);
1496 l2 = dns_name_countlabels(origin);
1501 dns_name_getlabelsequence(name, 0, l1 - l2, target);
1510 str_totext(const char *source, isc_buffer_t *target) {
1512 isc_region_t region;
1514 isc_buffer_availableregion(target, ®ion);
1517 if (l > region.length)
1518 return (ISC_R_NOSPACE);
1520 memcpy(region.base, source, l);
1521 isc_buffer_add(target, l);
1522 return (ISC_R_SUCCESS);
1526 inet_totext(int af, isc_region_t *src, isc_buffer_t *target) {
1529 /* Note - inet_ntop doesn't do size checking on its input. */
1530 if (inet_ntop(af, src->base, tmpbuf, sizeof(tmpbuf)) == NULL)
1531 return (ISC_R_NOSPACE);
1532 if (strlen(tmpbuf) > isc_buffer_availablelength(target))
1533 return (ISC_R_NOSPACE);
1534 isc_buffer_putstr(target, tmpbuf);
1535 return (ISC_R_SUCCESS);
1538 static isc_boolean_t
1539 buffer_empty(isc_buffer_t *source) {
1540 return((source->current == source->active) ? ISC_TRUE : ISC_FALSE);
1544 buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region) {
1545 isc_buffer_init(buffer, region->base, region->length);
1546 isc_buffer_add(buffer, region->length);
1547 isc_buffer_setactive(buffer, region->length);
1551 uint32_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
1552 isc_region_t region;
1554 isc_buffer_availableregion(target, ®ion);
1555 if (region.length < 4)
1556 return (ISC_R_NOSPACE);
1557 isc_buffer_putuint32(target, value);
1558 return (ISC_R_SUCCESS);
1562 uint16_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
1563 isc_region_t region;
1566 return (ISC_R_RANGE);
1567 isc_buffer_availableregion(target, ®ion);
1568 if (region.length < 2)
1569 return (ISC_R_NOSPACE);
1570 isc_buffer_putuint16(target, (isc_uint16_t)value);
1571 return (ISC_R_SUCCESS);
1575 uint8_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
1576 isc_region_t region;
1579 return (ISC_R_RANGE);
1580 isc_buffer_availableregion(target, ®ion);
1581 if (region.length < 1)
1582 return (ISC_R_NOSPACE);
1583 isc_buffer_putuint8(target, (isc_uint8_t)value);
1584 return (ISC_R_SUCCESS);
1588 name_tobuffer(dns_name_t *name, isc_buffer_t *target) {
1590 dns_name_toregion(name, &r);
1591 return (isc_buffer_copyregion(target, &r));
1595 uint32_fromregion(isc_region_t *region) {
1596 unsigned long value;
1598 REQUIRE(region->length >= 4);
1599 value = region->base[0] << 24;
1600 value |= region->base[1] << 16;
1601 value |= region->base[2] << 8;
1602 value |= region->base[3];
1607 uint16_fromregion(isc_region_t *region) {
1609 REQUIRE(region->length >= 2);
1611 return ((region->base[0] << 8) | region->base[1]);
1615 uint8_fromregion(isc_region_t *region) {
1617 REQUIRE(region->length >= 1);
1619 return (region->base[0]);
1623 mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) {
1626 isc_buffer_availableregion(target, &tr);
1627 if (length > tr.length)
1628 return (ISC_R_NOSPACE);
1629 memcpy(tr.base, base, length);
1630 isc_buffer_add(target, length);
1631 return (ISC_R_SUCCESS);
1635 compare_region(isc_region_t *r1, isc_region_t *r2) {
1639 l = (r1->length < r2->length) ? r1->length : r2->length;
1641 if ((result = memcmp(r1->base, r2->base, l)) != 0)
1642 return ((result < 0) ? -1 : 1);
1644 return ((r1->length == r2->length) ? 0 :
1645 (r1->length < r2->length) ? -1 : 1);
1649 hexvalue(char value) {
1653 c = (unsigned char)value;
1659 if ((s = strchr(hexdigits, value)) == NULL)
1661 return (s - hexdigits);
1665 decvalue(char value) {
1669 * isascii() is valid for full range of int values, no need to
1672 if (!isascii(value))
1674 if ((s = strchr(decdigits, value)) == NULL)
1676 return (s - decdigits);
1679 static const char atob_digits[86] =
1680 "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \
1681 "abcdefghijklmnopqrstu";
1683 * Subroutines to convert between 8 bit binary bytes and printable ASCII.
1684 * Computes the number of bytes, and three kinds of simple checksums.
1685 * Incoming bytes are collected into 32-bit words, then printed in base 85:
1686 * exp(85,5) > exp(2,32)
1687 * The ASCII characters used are between '!' and 'u';
1688 * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data.
1690 * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for
1691 * the atob/btoa programs, released with the compress program, in mod.sources.
1692 * Modified by Mike Schwartz 8/19/86 for use in BIND.
1693 * Modified to be re-entrant 3/2/99.
1705 #define Ceor state->Ceor
1706 #define Csum state->Csum
1707 #define Crot state->Crot
1708 #define word state->word
1709 #define bcount state->bcount
1711 #define times85(x) ((((((x<<2)+x)<<2)+x)<<2)+x)
1713 static isc_result_t byte_atob(int c, isc_buffer_t *target,
1714 struct state *state);
1715 static isc_result_t putbyte(int c, isc_buffer_t *, struct state *state);
1716 static isc_result_t byte_btoa(int c, isc_buffer_t *, struct state *state);
1719 * Decode ASCII-encoded byte c into binary representation and
1720 * place into *bufp, advancing bufp.
1723 byte_atob(int c, isc_buffer_t *target, struct state *state) {
1727 return(DNS_R_SYNTAX);
1729 RETERR(putbyte(0, target, state));
1730 RETERR(putbyte(0, target, state));
1731 RETERR(putbyte(0, target, state));
1732 RETERR(putbyte(0, target, state));
1734 } else if ((s = strchr(atob_digits, c)) != NULL) {
1736 word = s - atob_digits;
1738 } else if (bcount < 4) {
1739 word = times85(word);
1740 word += s - atob_digits;
1743 word = times85(word);
1744 word += s - atob_digits;
1745 RETERR(putbyte((word >> 24) & 0xff, target, state));
1746 RETERR(putbyte((word >> 16) & 0xff, target, state));
1747 RETERR(putbyte((word >> 8) & 0xff, target, state));
1748 RETERR(putbyte(word & 0xff, target, state));
1753 return(DNS_R_SYNTAX);
1754 return(ISC_R_SUCCESS);
1758 * Compute checksum info and place c into target.
1761 putbyte(int c, isc_buffer_t *target, struct state *state) {
1767 if ((Crot & 0x80000000)) {
1774 isc_buffer_availableregion(target, &tr);
1776 return (ISC_R_NOSPACE);
1778 isc_buffer_add(target, 1);
1779 return (ISC_R_SUCCESS);
1783 * Read the ASCII-encoded data from inbuf, of length inbuflen, and convert
1784 * it into T_UNSPEC (binary data) in outbuf, not to exceed outbuflen bytes;
1785 * outbuflen must be divisible by 4. (Note: this is because outbuf is filled
1786 * in 4 bytes at a time. If the actual data doesn't end on an even 4-byte
1787 * boundary, there will be no problem...it will be padded with 0 bytes, and
1788 * numbytes will indicate the correct number of bytes. The main point is
1789 * that since the buffer is filled in 4 bytes at a time, even if there is
1790 * not a full 4 bytes of data at the end, there has to be room to 0-pad the
1791 * data, so the buffer must be of size divisible by 4). Place the number of
1792 * output bytes in numbytes, and return a failure/success status.
1796 atob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target) {
1797 long oeor, osum, orot;
1798 struct state statebuf, *state= &statebuf;
1803 Ceor = Csum = Crot = word = bcount = 0;
1805 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
1807 while (token.value.as_textregion.length != 0) {
1808 if ((c = token.value.as_textregion.base[0]) == 'x') {
1811 RETERR(byte_atob(c, target, state));
1812 isc_textregion_consume(&token.value.as_textregion, 1);
1818 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
1820 if ((token.value.as_ulong % 4) != 0U)
1821 isc_buffer_subtract(target, 4 - (token.value.as_ulong % 4));
1826 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
1828 oeor = strtol(token.value.as_pointer, &e, 16);
1830 return (DNS_R_SYNTAX);
1835 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
1837 osum = strtol(token.value.as_pointer, &e, 16);
1839 return (DNS_R_SYNTAX);
1844 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
1846 orot = strtol(token.value.as_pointer, &e, 16);
1848 return (DNS_R_SYNTAX);
1850 if ((oeor != Ceor) || (osum != Csum) || (orot != Crot))
1851 return(DNS_R_BADCKSUM);
1852 return (ISC_R_SUCCESS);
1856 * Encode binary byte c into ASCII representation and place into *bufp,
1860 byte_btoa(int c, isc_buffer_t *target, struct state *state) {
1863 isc_buffer_availableregion(target, &tr);
1867 if ((Crot & 0x80000000)) {
1880 return (ISC_R_NOSPACE);
1882 isc_buffer_add(target, 1);
1884 register int tmp = 0;
1885 register isc_int32_t tmpword = word;
1889 * Because some don't support u_long.
1892 tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32);
1896 tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32);
1899 return (ISC_R_NOSPACE);
1900 tr.base[0] = atob_digits[(tmpword /
1901 (isc_int32_t)(85 * 85 * 85 * 85))
1903 tmpword %= (isc_int32_t)(85 * 85 * 85 * 85);
1904 tr.base[1] = atob_digits[tmpword / (85 * 85 * 85)];
1905 tmpword %= (85 * 85 * 85);
1906 tr.base[2] = atob_digits[tmpword / (85 * 85)];
1907 tmpword %= (85 * 85);
1908 tr.base[3] = atob_digits[tmpword / 85];
1910 tr.base[4] = atob_digits[tmpword];
1911 isc_buffer_add(target, 5);
1917 return (ISC_R_SUCCESS);
1922 * Encode the binary data from inbuf, of length inbuflen, into a
1923 * target. Return success/failure status
1926 btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target) {
1928 struct state statebuf, *state = &statebuf;
1929 char buf[sizeof "x 2000000000 ffffffff ffffffff ffffffff"];
1931 Ceor = Csum = Crot = word = bcount = 0;
1932 for (inc = 0; inc < inbuflen; inbuf++, inc++)
1933 RETERR(byte_btoa(*inbuf, target, state));
1936 RETERR(byte_btoa(0, target, state));
1939 * Put byte count and checksum information at end of buffer,
1942 sprintf(buf, "x %d %x %x %x", inbuflen, Ceor, Csum, Crot);
1943 return (str_totext(buf, target));
1948 default_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *fmt,
1956 vfprintf(stderr, fmt, ap);
1961 fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) {
1962 if (isc_lex_isfile(lexer) && callbacks != NULL) {
1963 const char *name = isc_lex_getsourcename(lexer);
1966 (*callbacks->warn)(callbacks,
1967 "%s:%lu: file does not end with newline",
1968 name, isc_lex_getsourceline(lexer));
1973 fromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...),
1974 dns_rdatacallbacks_t *callbacks, const char *name,
1975 unsigned long line, isc_token_t *token, isc_result_t result)
1980 if (token != NULL) {
1981 switch (token->type) {
1982 case isc_tokentype_eol:
1983 (*callback)(callbacks, "%s: %s:%lu: near eol: %s",
1984 "dns_rdata_fromtext", name, line,
1985 dns_result_totext(result));
1987 case isc_tokentype_eof:
1988 (*callback)(callbacks, "%s: %s:%lu: near eof: %s",
1989 "dns_rdata_fromtext", name, line,
1990 dns_result_totext(result));
1992 case isc_tokentype_number:
1993 (*callback)(callbacks, "%s: %s:%lu: near %lu: %s",
1994 "dns_rdata_fromtext", name, line,
1995 token->value.as_ulong,
1996 dns_result_totext(result));
1998 case isc_tokentype_string:
1999 case isc_tokentype_qstring:
2000 (*callback)(callbacks, "%s: %s:%lu: near '%s': %s",
2001 "dns_rdata_fromtext", name, line,
2002 (char *)token->value.as_pointer,
2003 dns_result_totext(result));
2006 (*callback)(callbacks, "%s: %s:%lu: %s",
2007 "dns_rdata_fromtext", name, line,
2008 dns_result_totext(result));
2012 (*callback)(callbacks, "dns_rdata_fromtext: %s:%lu: %s",
2013 name, line, dns_result_totext(result));
2018 dns_rdata_covers(dns_rdata_t *rdata) {
2019 return (covers_sig(rdata));
2023 dns_rdatatype_ismeta(dns_rdatatype_t type) {
2024 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_META) != 0)
2030 dns_rdatatype_issingleton(dns_rdatatype_t type) {
2031 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_SINGLETON)
2038 dns_rdatatype_notquestion(dns_rdatatype_t type) {
2039 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_NOTQUESTION)
2046 dns_rdatatype_questiononly(dns_rdatatype_t type) {
2047 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_QUESTIONONLY)
2054 dns_rdataclass_ismeta(dns_rdataclass_t rdclass) {
2056 if (rdclass == dns_rdataclass_reserved0
2057 || rdclass == dns_rdataclass_none
2058 || rdclass == dns_rdataclass_any)
2061 return (ISC_FALSE); /* Assume it is not a meta class. */
2065 dns_rdatatype_isdnssec(dns_rdatatype_t type) {
2066 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_DNSSEC) != 0)
2072 dns_rdatatype_iszonecutauth(dns_rdatatype_t type) {
2073 if ((dns_rdatatype_attributes(type)
2074 & (DNS_RDATATYPEATTR_DNSSEC | DNS_RDATATYPEATTR_ZONECUTAUTH))
2081 dns_rdatatype_isknown(dns_rdatatype_t type) {
2082 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_UNKNOWN)