2 * Copyright (C) 2004, 2005 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: name.c,v 1.127.2.7.2.14 2005/10/14 01:38:48 marka Exp $ */
24 #include <isc/buffer.h>
27 #include <isc/print.h>
28 #include <isc/string.h>
31 #include <dns/compress.h>
33 #include <dns/result.h>
35 #define VALID_NAME(n) ISC_MAGIC_VALID(n, DNS_NAME_MAGIC)
54 static char digitvalue[256] = {
55 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
56 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
57 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
58 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/
59 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
60 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
61 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
62 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
63 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
64 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
65 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
66 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
67 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
68 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
69 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
70 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
73 static unsigned char maptolower[] = {
74 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
75 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
76 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
77 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
78 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
79 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
80 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
81 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
82 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
83 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
84 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
85 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
86 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
87 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
88 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
89 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
90 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
91 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
92 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
93 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
94 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
95 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
96 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
97 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
98 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
99 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
100 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
101 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
102 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
103 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
104 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
105 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
108 #define CONVERTTOASCII(c)
109 #define CONVERTFROMASCII(c)
111 #define INIT_OFFSETS(name, var, default) \
112 if (name->offsets != NULL) \
113 var = name->offsets; \
117 #define SETUP_OFFSETS(name, var, default) \
118 if (name->offsets != NULL) \
119 var = name->offsets; \
122 set_offsets(name, var, NULL); \
126 * Note: If additional attributes are added that should not be set for
127 * empty names, MAKE_EMPTY() must be changed so it clears them.
129 #define MAKE_EMPTY(name) \
131 name->ndata = NULL; \
134 name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; \
138 * A name is "bindable" if it can be set to point to a new value, i.e.
139 * name->ndata and name->length may be changed.
141 #define BINDABLE(name) \
142 ((name->attributes & (DNS_NAMEATTR_READONLY|DNS_NAMEATTR_DYNAMIC)) \
146 * Note that the name data must be a char array, not a string
147 * literal, to avoid compiler warnings about discarding
148 * the const attribute of a string.
150 static unsigned char root_ndata[] = { '\0' };
151 static unsigned char root_offsets[] = { 0 };
153 static dns_name_t root =
157 DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
159 {(void *)-1, (void *)-1},
163 /* XXXDCL make const? */
164 LIBDNS_EXTERNAL_DATA dns_name_t *dns_rootname = &root;
166 static unsigned char wild_ndata[] = { '\001', '*' };
167 static unsigned char wild_offsets[] = { 0 };
169 static dns_name_t wild =
173 DNS_NAMEATTR_READONLY,
175 {(void *)-1, (void *)-1},
179 /* XXXDCL make const? */
180 LIBDNS_EXTERNAL_DATA dns_name_t *dns_wildcardname = &wild;
183 dns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive);
186 set_offsets(const dns_name_t *name, unsigned char *offsets,
187 dns_name_t *set_name);
190 dns_name_init(dns_name_t *name, unsigned char *offsets) {
194 DNS_NAME_INIT(name, offsets);
198 dns_name_reset(dns_name_t *name) {
199 REQUIRE(VALID_NAME(name));
200 REQUIRE(BINDABLE(name));
202 DNS_NAME_RESET(name);
206 dns_name_invalidate(dns_name_t *name) {
208 * Make 'name' invalid.
211 REQUIRE(VALID_NAME(name));
217 name->attributes = 0;
218 name->offsets = NULL;
220 ISC_LINK_INIT(name, link);
224 dns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer) {
226 * Dedicate a buffer for use with 'name'.
229 REQUIRE(VALID_NAME(name));
230 REQUIRE((buffer != NULL && name->buffer == NULL) ||
233 name->buffer = buffer;
237 dns_name_hasbuffer(const dns_name_t *name) {
239 * Does 'name' have a dedicated buffer?
242 REQUIRE(VALID_NAME(name));
244 if (name->buffer != NULL)
251 dns_name_isabsolute(const dns_name_t *name) {
254 * Does 'name' end in the root label?
257 REQUIRE(VALID_NAME(name));
259 if ((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
264 #define hyphenchar(c) ((c) == 0x2d)
265 #define asterchar(c) ((c) == 0x2a)
266 #define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
267 || ((c) >= 0x61 && (c) <= 0x7a))
268 #define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
269 #define borderchar(c) (alphachar(c) || digitchar(c))
270 #define middlechar(c) (borderchar(c) || hyphenchar(c))
271 #define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
274 dns_name_ismailbox(const dns_name_t *name) {
275 unsigned char *ndata, ch;
279 REQUIRE(VALID_NAME(name));
280 REQUIRE(name->labels > 0);
281 REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
286 if (name->length == 1)
298 if (ndata == name->ndata + name->length)
302 * RFC292/RFC1123 hostname.
304 while (ndata < (name->ndata + name->length)) {
310 if (first || n == 0) {
324 dns_name_ishostname(const dns_name_t *name, isc_boolean_t wildcard) {
325 unsigned char *ndata, ch;
329 REQUIRE(VALID_NAME(name));
330 REQUIRE(name->labels > 0);
331 REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
336 if (name->length == 1)
340 * Skip wildcard if this is a ownername.
343 if (wildcard && ndata[0] == 1 && ndata[1] == '*')
347 * RFC292/RFC1123 hostname.
349 while (ndata < (name->ndata + name->length)) {
355 if (first || n == 0) {
369 dns_name_iswildcard(const dns_name_t *name) {
370 unsigned char *ndata;
373 * Is 'name' a wildcard name?
376 REQUIRE(VALID_NAME(name));
377 REQUIRE(name->labels > 0);
379 if (name->length >= 2) {
381 if (ndata[0] == 1 && ndata[1] == '*')
388 static inline unsigned int
389 name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
391 const unsigned char *s;
395 length = name->length;
400 * This hash function is similar to the one Ousterhout
404 if (case_sensitive) {
406 h += ( h << 3 ) + *s;
423 dns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
425 * Provide a hash value for 'name'.
427 REQUIRE(VALID_NAME(name));
429 if (name->labels == 0)
432 return (name_hash(name, case_sensitive));
436 dns_name_fullhash(dns_name_t *name, isc_boolean_t case_sensitive) {
438 * Provide a hash value for 'name'.
440 REQUIRE(VALID_NAME(name));
442 if (name->labels == 0)
445 return (isc_hash_calc((const unsigned char *)name->ndata,
446 name->length, case_sensitive));
450 dns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
452 * This function was deprecated due to the breakage of the name space
453 * convention. We only keep this internally to provide binary backward
456 REQUIRE(VALID_NAME(name));
458 return (dns_name_fullhash(name, case_sensitive));
462 dns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive) {
463 unsigned char *offsets;
470 * Provide a hash value for 'name'.
472 REQUIRE(VALID_NAME(name));
474 if (name->labels == 0)
476 else if (name->labels == 1)
477 return (name_hash(name, case_sensitive));
479 SETUP_OFFSETS(name, offsets, odata);
480 DNS_NAME_INIT(&tname, NULL);
483 for (i = 0; i < name->labels; i++) {
484 tname.ndata = name->ndata + offsets[i];
485 if (i == name->labels - 1)
486 tname.length = name->length - offsets[i];
488 tname.length = offsets[i + 1] - offsets[i];
489 h += name_hash(&tname, case_sensitive);
496 dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
497 int *orderp, unsigned int *nlabelsp)
499 unsigned int l1, l2, l, count1, count2, count, nlabels;
500 int cdiff, ldiff, chdiff;
501 unsigned char *label1, *label2;
502 unsigned char *offsets1, *offsets2;
503 dns_offsets_t odata1, odata2;
504 dns_namereln_t namereln = dns_namereln_none;
507 * Determine the relative ordering under the DNSSEC order relation of
508 * 'name1' and 'name2', and also determine the hierarchical
509 * relationship of the names.
511 * Note: It makes no sense for one of the names to be relative and the
512 * other absolute. If both names are relative, then to be meaningfully
513 * compared the caller must ensure that they are both relative to the
517 REQUIRE(VALID_NAME(name1));
518 REQUIRE(VALID_NAME(name2));
519 REQUIRE(orderp != NULL);
520 REQUIRE(nlabelsp != NULL);
522 * Either name1 is absolute and name2 is absolute, or neither is.
524 REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
525 (name2->attributes & DNS_NAMEATTR_ABSOLUTE));
527 SETUP_OFFSETS(name1, offsets1, odata1);
528 SETUP_OFFSETS(name2, offsets2, odata2);
533 ldiff = (int)l1 - (int)l2;
543 label1 = &name1->ndata[offsets1[l1]];
544 label2 = &name2->ndata[offsets2[l2]];
549 * We dropped bitstring labels, and we don't support any
550 * other extended label types.
552 INSIST(count1 <= 63 && count2 <= 63);
554 cdiff = (int)count1 - (int)count2;
561 chdiff = (int)maptolower[*label1] -
562 (int)maptolower[*label2];
580 namereln = dns_namereln_contains;
582 namereln = dns_namereln_subdomain;
584 namereln = dns_namereln_equal;
589 if (nlabels > 0 && namereln == dns_namereln_none)
590 namereln = dns_namereln_commonancestor;
596 dns_name_compare(const dns_name_t *name1, const dns_name_t *name2) {
598 unsigned int nlabels;
601 * Determine the relative ordering under the DNSSEC order relation of
602 * 'name1' and 'name2'.
604 * Note: It makes no sense for one of the names to be relative and the
605 * other absolute. If both names are relative, then to be meaningfully
606 * compared the caller must ensure that they are both relative to the
610 (void)dns_name_fullcompare(name1, name2, &order, &nlabels);
616 dns_name_equal(const dns_name_t *name1, const dns_name_t *name2) {
617 unsigned int l, count;
619 unsigned char *label1, *label2;
622 * Are 'name1' and 'name2' equal?
624 * Note: It makes no sense for one of the names to be relative and the
625 * other absolute. If both names are relative, then to be meaningfully
626 * compared the caller must ensure that they are both relative to the
630 REQUIRE(VALID_NAME(name1));
631 REQUIRE(VALID_NAME(name2));
633 * Either name1 is absolute and name2 is absolute, or neither is.
635 REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
636 (name2->attributes & DNS_NAMEATTR_ABSOLUTE));
638 if (name1->length != name2->length)
643 if (l != name2->labels)
646 label1 = name1->ndata;
647 label2 = name2->ndata;
651 if (count != *label2++)
654 INSIST(count <= 63); /* no bitstring support */
658 c = maptolower[*label1++];
659 if (c != maptolower[*label2++])
668 dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) {
669 unsigned int l1, l2, l, count1, count2, count;
670 unsigned char c1, c2;
671 unsigned char *label1, *label2;
674 * Compare two absolute names as rdata.
677 REQUIRE(VALID_NAME(name1));
678 REQUIRE(name1->labels > 0);
679 REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
680 REQUIRE(VALID_NAME(name2));
681 REQUIRE(name2->labels > 0);
682 REQUIRE((name2->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
687 l = (l1 < l2) ? l1 : l2;
689 label1 = name1->ndata;
690 label2 = name2->ndata;
696 /* no bitstring support */
697 INSIST(count1 <= 63 && count2 <= 63);
699 if (count1 != count2)
700 return ((count1 < count2) ? -1 : 1);
704 c1 = maptolower[*label1++];
705 c2 = maptolower[*label2++];
714 * If one name had more labels than the other, their common
715 * prefix must have been different because the shorter name
716 * ended with the root label and the longer one can't have
717 * a root label in the middle of it. Therefore, if we get
718 * to this point, the lengths must be equal.
726 dns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2) {
728 unsigned int nlabels;
729 dns_namereln_t namereln;
732 * Is 'name1' a subdomain of 'name2'?
734 * Note: It makes no sense for one of the names to be relative and the
735 * other absolute. If both names are relative, then to be meaningfully
736 * compared the caller must ensure that they are both relative to the
740 namereln = dns_name_fullcompare(name1, name2, &order, &nlabels);
741 if (namereln == dns_namereln_subdomain ||
742 namereln == dns_namereln_equal)
749 dns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname) {
751 unsigned int nlabels, labels;
754 REQUIRE(VALID_NAME(name));
755 REQUIRE(name->labels > 0);
756 REQUIRE(VALID_NAME(wname));
757 labels = wname->labels;
759 REQUIRE(dns_name_iswildcard(wname));
761 DNS_NAME_INIT(&tname, NULL);
762 dns_name_getlabelsequence(wname, 1, labels - 1, &tname);
763 if (dns_name_fullcompare(name, &tname, &order, &nlabels) ==
764 dns_namereln_subdomain)
770 dns_name_countlabels(const dns_name_t *name) {
772 * How many labels does 'name' have?
775 REQUIRE(VALID_NAME(name));
777 ENSURE(name->labels <= 128);
779 return (name->labels);
783 dns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label) {
784 unsigned char *offsets;
788 * Make 'label' refer to the 'n'th least significant label of 'name'.
791 REQUIRE(VALID_NAME(name));
792 REQUIRE(name->labels > 0);
793 REQUIRE(n < name->labels);
794 REQUIRE(label != NULL);
796 SETUP_OFFSETS(name, offsets, odata);
798 label->base = &name->ndata[offsets[n]];
799 if (n == name->labels - 1)
800 label->length = name->length - offsets[n];
802 label->length = offsets[n + 1] - offsets[n];
806 dns_name_getlabelsequence(const dns_name_t *source,
807 unsigned int first, unsigned int n,
810 unsigned char *offsets;
812 unsigned int firstoffset, endoffset;
815 * Make 'target' refer to the 'n' labels including and following
816 * 'first' in 'source'.
819 REQUIRE(VALID_NAME(source));
820 REQUIRE(VALID_NAME(target));
821 REQUIRE(first <= source->labels);
822 REQUIRE(first + n <= source->labels);
823 REQUIRE(BINDABLE(target));
825 SETUP_OFFSETS(source, offsets, odata);
827 if (first == source->labels)
828 firstoffset = source->length;
830 firstoffset = offsets[first];
832 if (first + n == source->labels)
833 endoffset = source->length;
835 endoffset = offsets[first + n];
837 target->ndata = &source->ndata[firstoffset];
838 target->length = endoffset - firstoffset;
840 if (first + n == source->labels && n > 0 &&
841 (source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
842 target->attributes |= DNS_NAMEATTR_ABSOLUTE;
844 target->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
849 * If source and target are the same, and we're making target
850 * a prefix of source, the offsets table is correct already
851 * so we don't need to call set_offsets().
853 if (target->offsets != NULL &&
854 (target != source || first != 0))
855 set_offsets(target, target->offsets, NULL);
859 dns_name_clone(dns_name_t *source, dns_name_t *target) {
862 * Make 'target' refer to the same name as 'source'.
865 REQUIRE(VALID_NAME(source));
866 REQUIRE(VALID_NAME(target));
867 REQUIRE(BINDABLE(target));
869 target->ndata = source->ndata;
870 target->length = source->length;
871 target->labels = source->labels;
872 target->attributes = source->attributes &
873 (unsigned int)~(DNS_NAMEATTR_READONLY | DNS_NAMEATTR_DYNAMIC |
874 DNS_NAMEATTR_DYNOFFSETS);
875 if (target->offsets != NULL && source->labels > 0) {
876 if (source->offsets != NULL)
877 memcpy(target->offsets, source->offsets,
880 set_offsets(target, target->offsets, NULL);
885 dns_name_fromregion(dns_name_t *name, const isc_region_t *r) {
886 unsigned char *offsets;
892 * Make 'name' refer to region 'r'.
895 REQUIRE(VALID_NAME(name));
897 REQUIRE(BINDABLE(name));
899 INIT_OFFSETS(name, offsets, odata);
901 if (name->buffer != NULL) {
902 isc_buffer_clear(name->buffer);
903 isc_buffer_availableregion(name->buffer, &r2);
904 len = (r->length < r2.length) ? r->length : r2.length;
905 if (len > DNS_NAME_MAXWIRE)
906 len = DNS_NAME_MAXWIRE;
907 memcpy(r2.base, r->base, len);
908 name->ndata = r2.base;
911 name->ndata = r->base;
912 name->length = (r->length <= DNS_NAME_MAXWIRE) ?
913 r->length : DNS_NAME_MAXWIRE;
917 set_offsets(name, offsets, name);
920 name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
923 if (name->buffer != NULL)
924 isc_buffer_add(name->buffer, name->length);
928 dns_name_toregion(dns_name_t *name, isc_region_t *r) {
930 * Make 'r' refer to 'name'.
933 REQUIRE(VALID_NAME(name));
936 DNS_NAME_TOREGION(name, r);
941 dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
942 dns_name_t *origin, unsigned int options,
943 isc_buffer_t *target)
945 unsigned char *ndata, *label;
949 unsigned int value, count;
950 unsigned int n1, n2, tlen, nrem, nused, digits, labels, tused;
952 unsigned char *offsets;
954 isc_boolean_t downcase;
957 * Convert the textual representation of a DNS name at source
958 * into uncompressed wire form stored in target.
961 * Relative domain names will have 'origin' appended to them
962 * unless 'origin' is NULL, in which case relative domain names
963 * will remain relative.
966 REQUIRE(VALID_NAME(name));
967 REQUIRE(ISC_BUFFER_VALID(source));
968 REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
969 (target == NULL && ISC_BUFFER_VALID(name->buffer)));
971 downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0);
973 if (target == NULL && name->buffer != NULL) {
974 target = name->buffer;
975 isc_buffer_clear(target);
978 REQUIRE(BINDABLE(name));
980 INIT_OFFSETS(name, offsets, odata);
984 * Initialize things to make the compiler happy; they're not required.
994 * Make 'name' empty in case of failure.
999 * Set up the state machine.
1001 tdata = (char *)source->base + source->current;
1002 tlen = isc_buffer_remaininglength(source);
1004 ndata = isc_buffer_used(target);
1005 nrem = isc_buffer_availablelength(target);
1013 while (nrem > 0 && tlen > 0 && !done) {
1021 * Is this the root name?
1025 return (DNS_R_EMPTYLABEL);
1033 if (c == '@' && tlen == 0) {
1046 state = ft_initialescape;
1049 state = ft_ordinary;
1051 return (ISC_R_NOSPACE);
1056 return (DNS_R_EMPTYLABEL);
1059 INSIST(labels <= 127);
1060 offsets[labels] = nused;
1069 } else if (c == '\\') {
1073 return (DNS_R_LABELTOOLONG);
1077 c = maptolower[(int)c];
1083 case ft_initialescape:
1086 * This looks like a bitstring label, which
1087 * was deprecated. Intentionally drop it.
1089 return (DNS_R_BADLABELTYPE);
1094 if (!isdigit(c & 0xff)) {
1096 return (DNS_R_LABELTOOLONG);
1100 c = maptolower[(int)c];
1104 state = ft_ordinary;
1109 state = ft_escdecimal;
1112 if (!isdigit(c & 0xff))
1113 return (DNS_R_BADESCAPE);
1115 value += digitvalue[(int)c];
1119 return (DNS_R_BADESCAPE);
1121 return (DNS_R_LABELTOOLONG);
1124 value = maptolower[value];
1128 state = ft_ordinary;
1132 FATAL_ERROR(__FILE__, __LINE__,
1133 "Unexpected state %d", state);
1134 /* Does not return. */
1140 return (ISC_R_NOSPACE);
1142 if (state != ft_ordinary && state != ft_at)
1143 return (ISC_R_UNEXPECTEDEND);
1144 if (state == ft_ordinary) {
1148 INSIST(labels <= 127);
1149 offsets[labels] = nused;
1151 if (origin != NULL) {
1152 if (nrem < origin->length)
1153 return (ISC_R_NOSPACE);
1154 label = origin->ndata;
1155 n1 = origin->length;
1159 INSIST(n2 <= 63); /* no bitstring support */
1166 c = maptolower[(int)c];
1172 INSIST(labels <= 127);
1173 offsets[labels] = nused;
1176 if ((origin->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
1177 name->attributes |= DNS_NAMEATTR_ABSOLUTE;
1180 name->attributes |= DNS_NAMEATTR_ABSOLUTE;
1182 name->ndata = (unsigned char *)target->base + target->used;
1183 name->labels = labels;
1184 name->length = nused;
1186 isc_buffer_forward(source, tused);
1187 isc_buffer_add(target, name->length);
1189 return (ISC_R_SUCCESS);
1193 dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot,
1194 isc_buffer_t *target)
1196 unsigned char *ndata;
1198 unsigned int nlen, tlen;
1200 unsigned int trem, count;
1201 unsigned int labels;
1202 isc_boolean_t saw_root = ISC_FALSE;
1205 * This function assumes the name is in proper uncompressed
1208 REQUIRE(VALID_NAME(name));
1209 REQUIRE(ISC_BUFFER_VALID(target));
1211 ndata = name->ndata;
1212 nlen = name->length;
1213 labels = name->labels;
1214 tdata = isc_buffer_used(target);
1215 tlen = isc_buffer_availablelength(target);
1219 if (labels == 0 && nlen == 0) {
1221 * Special handling for an empty name.
1224 return (ISC_R_NOSPACE);
1227 * The names of these booleans are misleading in this case.
1228 * This empty name is not necessarily from the root node of
1229 * the DNS root zone, nor is a final dot going to be included.
1230 * They need to be set this way, though, to keep the "@"
1231 * from being trounced.
1233 saw_root = ISC_TRUE;
1234 omit_final_dot = ISC_FALSE;
1239 * Skip the while() loop.
1242 } else if (nlen == 1 && labels == 1 && *ndata == '\0') {
1244 * Special handling for the root label.
1247 return (ISC_R_NOSPACE);
1249 saw_root = ISC_TRUE;
1250 omit_final_dot = ISC_FALSE;
1255 * Skip the while() loop.
1260 while (labels > 0 && nlen > 0 && trem > 0) {
1265 saw_root = ISC_TRUE;
1269 INSIST(nlen >= count);
1273 case 0x22: /* '"' */
1274 case 0x28: /* '(' */
1275 case 0x29: /* ')' */
1276 case 0x2E: /* '.' */
1277 case 0x3B: /* ';' */
1278 case 0x5C: /* '\\' */
1279 /* Special modifiers in zone files. */
1280 case 0x40: /* '@' */
1281 case 0x24: /* '$' */
1283 return (ISC_R_NOSPACE);
1285 CONVERTFROMASCII(c);
1292 if (c > 0x20 && c < 0x7f) {
1294 return (ISC_R_NOSPACE);
1295 CONVERTFROMASCII(c);
1302 return (ISC_R_NOSPACE);
1308 *tdata++ = 0x30 + (c % 10);
1317 FATAL_ERROR(__FILE__, __LINE__,
1318 "Unexpected label type %02x", count);
1323 * The following assumes names are absolute. If not, we
1324 * fix things up later. Note that this means that in some
1325 * cases one more byte of text buffer is required than is
1326 * needed in the final output.
1329 return (ISC_R_NOSPACE);
1334 if (nlen != 0 && trem == 0)
1335 return (ISC_R_NOSPACE);
1337 if (!saw_root || omit_final_dot)
1340 isc_buffer_add(target, tlen - trem);
1342 return (ISC_R_SUCCESS);
1346 dns_name_tofilenametext(dns_name_t *name, isc_boolean_t omit_final_dot,
1347 isc_buffer_t *target)
1349 unsigned char *ndata;
1351 unsigned int nlen, tlen;
1353 unsigned int trem, count;
1354 unsigned int labels;
1357 * This function assumes the name is in proper uncompressed
1360 REQUIRE(VALID_NAME(name));
1361 REQUIRE((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
1362 REQUIRE(ISC_BUFFER_VALID(target));
1364 ndata = name->ndata;
1365 nlen = name->length;
1366 labels = name->labels;
1367 tdata = isc_buffer_used(target);
1368 tlen = isc_buffer_availablelength(target);
1372 if (nlen == 1 && labels == 1 && *ndata == '\0') {
1374 * Special handling for the root label.
1377 return (ISC_R_NOSPACE);
1379 omit_final_dot = ISC_FALSE;
1384 * Skip the while() loop.
1389 while (labels > 0 && nlen > 0 && trem > 0) {
1396 INSIST(nlen >= count);
1399 if ((c >= 0x30 && c <= 0x39) || /* digit */
1400 (c >= 0x41 && c <= 0x5A) || /* uppercase */
1401 (c >= 0x61 && c <= 0x7A) || /* lowercase */
1402 c == 0x2D || /* hyphen */
1403 c == 0x5F) /* underscore */
1406 return (ISC_R_NOSPACE);
1408 if (c >= 0x41 && c <= 0x5A)
1410 CONVERTFROMASCII(c);
1417 return (ISC_R_NOSPACE);
1418 sprintf(tdata, "%%%02X", c);
1427 FATAL_ERROR(__FILE__, __LINE__,
1428 "Unexpected label type %02x", count);
1433 * The following assumes names are absolute. If not, we
1434 * fix things up later. Note that this means that in some
1435 * cases one more byte of text buffer is required than is
1436 * needed in the final output.
1439 return (ISC_R_NOSPACE);
1444 if (nlen != 0 && trem == 0)
1445 return (ISC_R_NOSPACE);
1450 isc_buffer_add(target, tlen - trem);
1452 return (ISC_R_SUCCESS);
1456 dns_name_downcase(dns_name_t *source, dns_name_t *name, isc_buffer_t *target) {
1457 unsigned char *sndata, *ndata;
1458 unsigned int nlen, count, labels;
1459 isc_buffer_t buffer;
1462 * Downcase 'source'.
1465 REQUIRE(VALID_NAME(source));
1466 REQUIRE(VALID_NAME(name));
1467 if (source == name) {
1468 REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
1469 isc_buffer_init(&buffer, source->ndata, source->length);
1471 ndata = source->ndata;
1473 REQUIRE(BINDABLE(name));
1474 REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
1475 (target == NULL && ISC_BUFFER_VALID(name->buffer)));
1476 if (target == NULL) {
1477 target = name->buffer;
1478 isc_buffer_clear(name->buffer);
1480 ndata = (unsigned char *)target->base + target->used;
1481 name->ndata = ndata;
1484 sndata = source->ndata;
1485 nlen = source->length;
1486 labels = source->labels;
1488 if (nlen > (target->length - target->used)) {
1490 return (ISC_R_NOSPACE);
1493 while (labels > 0 && nlen > 0) {
1499 INSIST(nlen >= count);
1501 *ndata++ = maptolower[(*sndata++)];
1506 FATAL_ERROR(__FILE__, __LINE__,
1507 "Unexpected label type %02x", count);
1508 /* Does not return. */
1512 if (source != name) {
1513 name->labels = source->labels;
1514 name->length = source->length;
1515 if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
1516 name->attributes = DNS_NAMEATTR_ABSOLUTE;
1518 name->attributes = 0;
1519 if (name->labels > 0 && name->offsets != NULL)
1520 set_offsets(name, name->offsets, NULL);
1523 isc_buffer_add(target, name->length);
1525 return (ISC_R_SUCCESS);
1529 set_offsets(const dns_name_t *name, unsigned char *offsets,
1530 dns_name_t *set_name)
1532 unsigned int offset, count, length, nlabels;
1533 unsigned char *ndata;
1534 isc_boolean_t absolute;
1536 ndata = name->ndata;
1537 length = name->length;
1540 absolute = ISC_FALSE;
1541 while (offset != length) {
1542 INSIST(nlabels < 128);
1543 offsets[nlabels++] = offset;
1546 INSIST(count <= 63);
1549 INSIST(offset <= length);
1551 absolute = ISC_TRUE;
1555 if (set_name != NULL) {
1556 INSIST(set_name == name);
1558 set_name->labels = nlabels;
1559 set_name->length = offset;
1561 set_name->attributes |= DNS_NAMEATTR_ABSOLUTE;
1563 set_name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
1565 INSIST(nlabels == name->labels);
1566 INSIST(offset == name->length);
1570 dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
1571 dns_decompress_t *dctx, unsigned int options,
1572 isc_buffer_t *target)
1574 unsigned char *cdata, *ndata;
1575 unsigned int cused; /* Bytes of compressed name data used */
1576 unsigned int hops, nused, labels, n, nmax;
1577 unsigned int current, new_current, biggest_pointer;
1579 fw_state state = fw_start;
1581 unsigned char *offsets;
1582 dns_offsets_t odata;
1583 isc_boolean_t downcase;
1586 * Copy the possibly-compressed name at source into target,
1590 REQUIRE(VALID_NAME(name));
1591 REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
1592 (target == NULL && ISC_BUFFER_VALID(name->buffer)));
1594 downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0);
1596 if (target == NULL && name->buffer != NULL) {
1597 target = name->buffer;
1598 isc_buffer_clear(target);
1601 REQUIRE(dctx != NULL);
1602 REQUIRE(BINDABLE(name));
1604 INIT_OFFSETS(name, offsets, odata);
1607 * Make 'name' empty in case of failure.
1612 * Initialize things to make the compiler happy; they're not required.
1624 ndata = isc_buffer_used(target);
1628 * Find the maximum number of uncompressed target name
1629 * bytes we are willing to generate. This is the smaller
1630 * of the available target buffer length and the
1631 * maximum legal domain name length (255).
1633 nmax = isc_buffer_availablelength(target);
1634 if (nmax > DNS_NAME_MAXWIRE)
1635 nmax = DNS_NAME_MAXWIRE;
1637 cdata = isc_buffer_current(source);
1640 current = source->current;
1641 biggest_pointer = current;
1644 * Note: The following code is not optimized for speed, but
1645 * rather for correctness. Speed will be addressed in the future.
1648 while (current < source->active && !done) {
1657 offsets[labels] = nused;
1659 if (nused + c + 1 > nmax)
1666 state = fw_ordinary;
1667 } else if (c >= 128 && c < 192) {
1669 * 14 bit local compression pointer.
1670 * Local compression is no longer an
1673 return (DNS_R_BADLABELTYPE);
1674 } else if (c >= 192) {
1676 * Ordinary 14-bit pointer.
1678 if ((dctx->allowed & DNS_COMPRESS_GLOBAL14) ==
1680 return (DNS_R_DISALLOWED);
1681 new_current = c & 0x3F;
1683 state = fw_newcurrent;
1685 return (DNS_R_BADLABELTYPE);
1703 if (new_current >= biggest_pointer)
1704 return (DNS_R_BADPOINTER);
1705 biggest_pointer = new_current;
1706 current = new_current;
1707 cdata = (unsigned char *)source->base +
1710 if (hops > DNS_POINTER_MAXHOPS)
1711 return (DNS_R_TOOMANYHOPS);
1715 FATAL_ERROR(__FILE__, __LINE__,
1716 "Unknown state %d", state);
1717 /* Does not return. */
1722 return (ISC_R_UNEXPECTEDEND);
1724 name->ndata = (unsigned char *)target->base + target->used;
1725 name->labels = labels;
1726 name->length = nused;
1727 name->attributes |= DNS_NAMEATTR_ABSOLUTE;
1729 isc_buffer_forward(source, cused);
1730 isc_buffer_add(target, name->length);
1732 return (ISC_R_SUCCESS);
1735 if (nmax == DNS_NAME_MAXWIRE)
1737 * The name did not fit even though we had a buffer
1738 * big enough to fit a maximum-length name.
1740 return (DNS_R_NAMETOOLONG);
1743 * The name might fit if only the caller could give us a
1744 * big enough buffer.
1746 return (ISC_R_NOSPACE);
1751 dns_name_towire(dns_name_t *name, dns_compress_t *cctx, isc_buffer_t *target) {
1752 unsigned int methods;
1753 isc_uint16_t offset;
1754 dns_name_t gp; /* Global compression prefix */
1755 isc_boolean_t gf; /* Global compression target found */
1756 isc_uint16_t go; /* Global compression offset */
1761 * Convert 'name' into wire format, compressing it as specified by the
1762 * compression context 'cctx', and storing the result in 'target'.
1765 REQUIRE(VALID_NAME(name));
1766 REQUIRE(cctx != NULL);
1767 REQUIRE(ISC_BUFFER_VALID(target));
1770 * If 'name' doesn't have an offsets table, make a clone which
1773 if (name->offsets == NULL) {
1774 DNS_NAME_INIT(&clname, clo);
1775 dns_name_clone(name, &clname);
1778 DNS_NAME_INIT(&gp, NULL);
1780 offset = target->used; /*XXX*/
1782 methods = dns_compress_getmethods(cctx);
1784 if ((methods & DNS_COMPRESS_GLOBAL14) != 0)
1785 gf = dns_compress_findglobal(cctx, name, &gp, &go);
1790 * If the offset is too high for 14 bit global compression, we're
1793 if (gf && go >= 0x4000)
1797 * Will the compression pointer reduce the message size?
1799 if (gf && (gp.length + 2) >= name->length)
1803 if (target->length - target->used < gp.length)
1804 return (ISC_R_NOSPACE);
1805 (void)memcpy((unsigned char *)target->base + target->used,
1806 gp.ndata, (size_t)gp.length);
1807 isc_buffer_add(target, gp.length);
1809 if (target->length - target->used < 2)
1810 return (ISC_R_NOSPACE);
1811 isc_buffer_putuint16(target, go);
1813 dns_compress_add(cctx, name, &gp, offset);
1815 if (target->length - target->used < name->length)
1816 return (ISC_R_NOSPACE);
1817 (void)memcpy((unsigned char *)target->base + target->used,
1818 name->ndata, (size_t)name->length);
1819 isc_buffer_add(target, name->length);
1820 dns_compress_add(cctx, name, name, offset);
1822 return (ISC_R_SUCCESS);
1826 dns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix, dns_name_t *name,
1827 isc_buffer_t *target)
1829 unsigned char *ndata, *offsets;
1830 unsigned int nrem, labels, prefix_length, length;
1831 isc_boolean_t copy_prefix = ISC_TRUE;
1832 isc_boolean_t copy_suffix = ISC_TRUE;
1833 isc_boolean_t absolute = ISC_FALSE;
1834 dns_name_t tmp_name;
1835 dns_offsets_t odata;
1838 * Concatenate 'prefix' and 'suffix'.
1841 REQUIRE(prefix == NULL || VALID_NAME(prefix));
1842 REQUIRE(suffix == NULL || VALID_NAME(suffix));
1843 REQUIRE(name == NULL || VALID_NAME(name));
1844 REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
1845 (target == NULL && name != NULL && ISC_BUFFER_VALID(name->buffer)));
1846 if (prefix == NULL || prefix->labels == 0)
1847 copy_prefix = ISC_FALSE;
1848 if (suffix == NULL || suffix->labels == 0)
1849 copy_suffix = ISC_FALSE;
1851 (prefix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) {
1852 absolute = ISC_TRUE;
1853 REQUIRE(!copy_suffix);
1856 DNS_NAME_INIT(&tmp_name, odata);
1859 if (target == NULL) {
1860 INSIST(name->buffer != NULL);
1861 target = name->buffer;
1862 isc_buffer_clear(name->buffer);
1865 REQUIRE(BINDABLE(name));
1870 nrem = target->length - target->used;
1871 ndata = (unsigned char *)target->base + target->used;
1872 if (nrem > DNS_NAME_MAXWIRE)
1873 nrem = DNS_NAME_MAXWIRE;
1878 prefix_length = prefix->length;
1879 length += prefix_length;
1880 labels += prefix->labels;
1883 length += suffix->length;
1884 labels += suffix->labels;
1886 if (length > DNS_NAME_MAXWIRE) {
1888 return (DNS_R_NAMETOOLONG);
1890 if (length > nrem) {
1892 return (ISC_R_NOSPACE);
1896 if ((suffix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
1897 absolute = ISC_TRUE;
1898 if (suffix == name && suffix->buffer == target)
1899 memmove(ndata + prefix_length, suffix->ndata,
1902 memcpy(ndata + prefix_length, suffix->ndata,
1907 * If 'prefix' and 'name' are the same object, and the object has
1908 * a dedicated buffer, and we're using it, then we don't have to
1911 if (copy_prefix && (prefix != name || prefix->buffer != target))
1912 memcpy(ndata, prefix->ndata, prefix_length);
1914 name->ndata = ndata;
1915 name->labels = labels;
1916 name->length = length;
1918 name->attributes = DNS_NAMEATTR_ABSOLUTE;
1920 name->attributes = 0;
1922 if (name->labels > 0 && name->offsets != NULL) {
1923 INIT_OFFSETS(name, offsets, odata);
1924 set_offsets(name, offsets, NULL);
1927 isc_buffer_add(target, name->length);
1929 return (ISC_R_SUCCESS);
1933 dns_name_split(dns_name_t *name, unsigned int suffixlabels,
1934 dns_name_t *prefix, dns_name_t *suffix)
1937 unsigned int splitlabel;
1939 REQUIRE(VALID_NAME(name));
1940 REQUIRE(suffixlabels > 0);
1941 REQUIRE(suffixlabels < name->labels);
1942 REQUIRE(prefix != NULL || suffix != NULL);
1943 REQUIRE(prefix == NULL ||
1944 (VALID_NAME(prefix) &&
1945 prefix->buffer != NULL &&
1947 REQUIRE(suffix == NULL ||
1948 (VALID_NAME(suffix) &&
1949 suffix->buffer != NULL &&
1952 splitlabel = name->labels - suffixlabels;
1955 dns_name_getlabelsequence(name, 0, splitlabel, prefix);
1958 dns_name_getlabelsequence(name, splitlabel,
1959 suffixlabels, suffix);
1965 dns_name_dup(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) {
1967 * Make 'target' a dynamically allocated copy of 'source'.
1970 REQUIRE(VALID_NAME(source));
1971 REQUIRE(source->length > 0);
1972 REQUIRE(VALID_NAME(target));
1973 REQUIRE(BINDABLE(target));
1976 * Make 'target' empty in case of failure.
1980 target->ndata = isc_mem_get(mctx, source->length);
1981 if (target->ndata == NULL)
1982 return (ISC_R_NOMEMORY);
1984 memcpy(target->ndata, source->ndata, source->length);
1986 target->length = source->length;
1987 target->labels = source->labels;
1988 target->attributes = DNS_NAMEATTR_DYNAMIC;
1989 if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
1990 target->attributes |= DNS_NAMEATTR_ABSOLUTE;
1991 if (target->offsets != NULL) {
1992 if (source->offsets != NULL)
1993 memcpy(target->offsets, source->offsets,
1996 set_offsets(target, target->offsets, NULL);
1999 return (ISC_R_SUCCESS);
2003 dns_name_dupwithoffsets(dns_name_t *source, isc_mem_t *mctx,
2007 * Make 'target' a read-only dynamically allocated copy of 'source'.
2008 * 'target' will also have a dynamically allocated offsets table.
2011 REQUIRE(VALID_NAME(source));
2012 REQUIRE(source->length > 0);
2013 REQUIRE(VALID_NAME(target));
2014 REQUIRE(BINDABLE(target));
2015 REQUIRE(target->offsets == NULL);
2018 * Make 'target' empty in case of failure.
2022 target->ndata = isc_mem_get(mctx, source->length + source->labels);
2023 if (target->ndata == NULL)
2024 return (ISC_R_NOMEMORY);
2026 memcpy(target->ndata, source->ndata, source->length);
2028 target->length = source->length;
2029 target->labels = source->labels;
2030 target->attributes = DNS_NAMEATTR_DYNAMIC | DNS_NAMEATTR_DYNOFFSETS |
2031 DNS_NAMEATTR_READONLY;
2032 if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
2033 target->attributes |= DNS_NAMEATTR_ABSOLUTE;
2034 target->offsets = target->ndata + source->length;
2035 if (source->offsets != NULL)
2036 memcpy(target->offsets, source->offsets, source->labels);
2038 set_offsets(target, target->offsets, NULL);
2040 return (ISC_R_SUCCESS);
2044 dns_name_free(dns_name_t *name, isc_mem_t *mctx) {
2051 REQUIRE(VALID_NAME(name));
2052 REQUIRE((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0);
2054 size = name->length;
2055 if ((name->attributes & DNS_NAMEATTR_DYNOFFSETS) != 0)
2056 size += name->labels;
2057 isc_mem_put(mctx, name->ndata, size);
2058 dns_name_invalidate(name);
2062 dns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg) {
2063 dns_name_t downname;
2064 unsigned char data[256];
2065 isc_buffer_t buffer;
2066 isc_result_t result;
2070 * Send 'name' in DNSSEC canonical form to 'digest'.
2073 REQUIRE(VALID_NAME(name));
2074 REQUIRE(digest != NULL);
2076 DNS_NAME_INIT(&downname, NULL);
2077 isc_buffer_init(&buffer, data, sizeof(data));
2079 result = dns_name_downcase(name, &downname, &buffer);
2080 if (result != ISC_R_SUCCESS)
2083 isc_buffer_usedregion(&buffer, &r);
2085 return ((digest)(arg, &r));
2089 dns_name_dynamic(dns_name_t *name) {
2090 REQUIRE(VALID_NAME(name));
2093 * Returns whether there is dynamic memory associated with this name.
2096 return ((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0 ?
2097 ISC_TRUE : ISC_FALSE);
2101 dns_name_print(dns_name_t *name, FILE *stream) {
2102 isc_result_t result;
2108 * Print 'name' on 'stream'.
2111 REQUIRE(VALID_NAME(name));
2113 isc_buffer_init(&b, t, sizeof(t));
2114 result = dns_name_totext(name, ISC_FALSE, &b);
2115 if (result != ISC_R_SUCCESS)
2117 isc_buffer_usedregion(&b, &r);
2118 fprintf(stream, "%.*s", (int)r.length, (char *)r.base);
2120 return (ISC_R_SUCCESS);
2124 dns_name_format(dns_name_t *name, char *cp, unsigned int size) {
2125 isc_result_t result;
2131 * Leave room for null termination after buffer.
2133 isc_buffer_init(&buf, cp, size - 1);
2134 result = dns_name_totext(name, ISC_TRUE, &buf);
2135 if (result == ISC_R_SUCCESS) {
2140 isc_buffer_usedregion(&buf, &r);
2141 ((char *) r.base)[r.length] = '\0';
2144 snprintf(cp, size, "<unknown>");
2148 dns_name_copy(dns_name_t *source, dns_name_t *dest, isc_buffer_t *target) {
2149 unsigned char *ndata;
2152 * Make dest a copy of source.
2155 REQUIRE(VALID_NAME(source));
2156 REQUIRE(VALID_NAME(dest));
2157 REQUIRE(target != NULL || dest->buffer != NULL);
2159 if (target == NULL) {
2160 target = dest->buffer;
2161 isc_buffer_clear(dest->buffer);
2164 REQUIRE(BINDABLE(dest));
2169 if (target->length - target->used < source->length)
2170 return (ISC_R_NOSPACE);
2172 ndata = (unsigned char *)target->base + target->used;
2173 dest->ndata = target->base;
2175 memcpy(ndata, source->ndata, source->length);
2177 dest->ndata = ndata;
2178 dest->labels = source->labels;
2179 dest->length = source->length;
2180 if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
2181 dest->attributes = DNS_NAMEATTR_ABSOLUTE;
2183 dest->attributes = 0;
2185 if (dest->labels > 0 && dest->offsets != NULL) {
2186 if (source->offsets != NULL)
2187 memcpy(dest->offsets, source->offsets, source->labels);
2189 set_offsets(dest, dest->offsets, NULL);
2192 isc_buffer_add(target, dest->length);
2194 return (ISC_R_SUCCESS);