name.c revision 72bdbe3c70f415a717f59f72d04590d70acb380e
499b34cea04a46823d003d4c0520c8b03e8513cbBrian Wellington * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Copyright (C) 1998-2003 Internet Software Consortium.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * Permission to use, copy, modify, and distribute this software for any
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * purpose with or without fee is hereby granted, provided that the above
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * copyright notice and this permission notice appear in all copies.
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
15a44745412679c30a6d022733925af70a38b715David Lawrence * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15a44745412679c30a6d022733925af70a38b715David Lawrence * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15a44745412679c30a6d022733925af70a38b715David Lawrence * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15a44745412679c30a6d022733925af70a38b715David Lawrence * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15a44745412679c30a6d022733925af70a38b715David Lawrence * PERFORMANCE OF THIS SOFTWARE.
dcc7ea97174501f0409c0c919b3ca04083e4e1b8Andreas Gustafsson/* $Id: name.c,v 1.154 2005/09/10 01:02:08 marka Exp $ */
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence#define VALID_NAME(n) ISC_MAGIC_VALID(n, DNS_NAME_MAGIC)
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewstypedef enum {
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Grafftypedef enum {
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graffstatic unsigned char maptolower[] = {
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
19d1b1667d073850d4366352aaf8319efc5debeeBrian Wellington 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0ad8ee89c532951a55b7de25317eeca2c3b2ed63Andreas Gustafsson 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0ad8ee89c532951a55b7de25317eeca2c3b2ed63Andreas Gustafsson 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
f53848e17123569387b279578f0100dca5407da5Mark Andrews 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews var = default; \
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Note: If additional attributes are added that should not be set for
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * empty names, MAKE_EMPTY() must be changed so it clears them.
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews * A name is "bindable" if it can be set to point to a new value, i.e.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * name->ndata and name->length may be changed.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews ((name->attributes & (DNS_NAMEATTR_READONLY|DNS_NAMEATTR_DYNAMIC)) \
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff * Note that the name data must be a char array, not a string
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * literal, to avoid compiler warnings about discarding
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * the const attribute of a string.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsstatic unsigned char root_offsets[] = { 0 };
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews/* XXXDCL make const? */
b54630c4518a1a173fee3478f4bf51dff450b6dcMark AndrewsLIBDNS_EXTERNAL_DATA dns_name_t *dns_rootname = &root;
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrewsstatic unsigned char wild_ndata[] = { '\001', '*' };
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graffstatic unsigned char wild_offsets[] = { 0 };
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews/* XXXDCL make const? */
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark AndrewsLIBDNS_EXTERNAL_DATA dns_name_t *dns_wildcardname = &wild;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsdns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews * dns_name_t to text post-conversion procedure.
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrewsstatic dns_name_totextfilter_t totext_filter_proc = NULL;
8b61d2012063306528286680bd9f086fa868d86eMark Andrewsset_offsets(const dns_name_t *name, unsigned char *offsets,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsdns_name_init(dns_name_t *name, unsigned char *offsets) {
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * Initialize 'name'.
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington * Make 'name' invalid.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsdns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer) {
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington * Dedicate a buffer for use with 'name'.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews REQUIRE((buffer != NULL && name->buffer == NULL) ||
8b61d2012063306528286680bd9f086fa868d86eMark Andrews * Does 'name' have a dedicated buffer?
4be19dcd14cea678511f1d1b269ab89273e987eeMark Andrews * Does 'name' end in the root label?
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews if ((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews#define borderchar(c) (alphachar(c) || digitchar(c))
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews#define middlechar(c) (borderchar(c) || hyphenchar(c))
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews unsigned int n;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews * Root label.
8b61d2012063306528286680bd9f086fa868d86eMark Andrews while (n--) {
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews while (n--) {
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington if (first || n == 0) {
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsdns_name_ishostname(const dns_name_t *name, isc_boolean_t wildcard) {
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews unsigned int n;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
8b61d2012063306528286680bd9f086fa868d86eMark Andrews * Root label.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Skip wildcard if this is a ownername.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews if (wildcard && ndata[0] == 1 && ndata[1] == '*')
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews while (n--) {
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews if (first || n == 0) {
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews unsigned char *ndata;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Is 'name' a wildcard name?
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrewsdns_name_internalwildcard(const dns_name_t *name) {
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews unsigned char *ndata;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews unsigned int count;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews unsigned int label;
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews * Does 'name' contain a internal wildcard?
668eb43f1f24c887b6972f6a1610b4b38b281080Brian Wellington * Skip first label.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Check all but the last of the remaining labels.
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellingtonstatic inline unsigned int
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellingtonname_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington const unsigned char *s;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington unsigned int h = 0;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington unsigned char c;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington * This hash function is similar to the one Ousterhout
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington * uses in Tcl.
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington h += ( h << 3 ) + *s;
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson h += ( h << 3 ) + c;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellingtondns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * Provide a hash value for 'name'.
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrewsdns_name_fullhash(dns_name_t *name, isc_boolean_t case_sensitive) {
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * Provide a hash value for 'name'.
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews return (isc_hash_calc((const unsigned char *)name->ndata,
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrewsdns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * This function was deprecated due to the breakage of the name space
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * convention. We only keep this internally to provide binary backward
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * compatibility.
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews return (dns_name_fullhash(name, case_sensitive));
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrewsdns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive) {
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews unsigned char *offsets;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews unsigned int h = 0;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews unsigned int i;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * Provide a hash value for 'name'.
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrewsdns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews unsigned int l1, l2, l, count1, count2, count, nlabels;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * Determine the relative ordering under the DNSSEC order relation of
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * 'name1' and 'name2', and also determine the hierarchical
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * relationship of the names.
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * Note: It makes no sense for one of the names to be relative and the
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * other absolute. If both names are relative, then to be meaningfully
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * compared the caller must ensure that they are both relative to the
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * same domain.
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * Either name1 is absolute and name2 is absolute, or neither is.
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews while (l > 0) {
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * We dropped bitstring labels, and we don't support any
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * other extended label types.
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews while (count > 0) {
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews else if (ldiff > 0)
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews if (nlabels > 0 && namereln == dns_namereln_none)
056141f2878d1046306ef0ba035263a00de57f98Mark Andrewsdns_name_compare(const dns_name_t *name1, const dns_name_t *name2) {
6ef15459b8fd3fc8b5672da4ad72c19a755dbe45Mark Andrews unsigned int nlabels;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews * Determine the relative ordering under the DNSSEC order relation of
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews * 'name1' and 'name2'.
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * Note: It makes no sense for one of the names to be relative and the
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * other absolute. If both names are relative, then to be meaningfully
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington * compared the caller must ensure that they are both relative to the
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington * same domain.
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington (void)dns_name_fullcompare(name1, name2, &order, &nlabels);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrewsdns_name_equal(const dns_name_t *name1, const dns_name_t *name2) {
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews unsigned int l, count;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews unsigned char c;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews * Are 'name1' and 'name2' equal?
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews * Note: It makes no sense for one of the names to be relative and the
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews * other absolute. If both names are relative, then to be meaningfully
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews * compared the caller must ensure that they are both relative to the
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews * same domain.
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews * Either name1 is absolute and name2 is absolute, or neither is.
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews while (l > 0) {
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews INSIST(count <= 63); /* no bitstring support */
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews while (count > 0) {
056141f2878d1046306ef0ba035263a00de57f98Mark Andrewsdns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2) {
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews * Are 'name1' and 'name2' equal?
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews * Note: It makes no sense for one of the names to be relative and the
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews * other absolute. If both names are relative, then to be meaningfully
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews * compared the caller must ensure that they are both relative to the
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews * same domain.
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews * Either name1 is absolute and name2 is absolute, or neither is.
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews if (memcmp(name1->ndata, name2->ndata, name1->length) != 0)
056141f2878d1046306ef0ba035263a00de57f98Mark Andrewsdns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) {
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews * Compare two absolute names as rdata.
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews REQUIRE((name2->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews while (l > 0) {
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews /* no bitstring support */
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews while (count > 0) {
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews return (-1);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * If one name had more labels than the other, their common
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * prefix must have been different because the shorter name
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * ended with the root label and the longer one can't have
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington * a root label in the middle of it. Therefore, if we get
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * to this point, the lengths must be equal.
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrewsdns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2) {
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews unsigned int nlabels;
8b61d2012063306528286680bd9f086fa868d86eMark Andrews * Is 'name1' a subdomain of 'name2'?
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews * Note: It makes no sense for one of the names to be relative and the
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington * other absolute. If both names are relative, then to be meaningfully
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington * compared the caller must ensure that they are both relative to the
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington * same domain.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews namereln = dns_name_fullcompare(name1, name2, &order, &nlabels);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsdns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname) {
c27767a7b946f4c6f08d33129691e2d6339e8350Brian Wellington dns_name_getlabelsequence(wname, 1, labels - 1, &tname);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence if (dns_name_fullcompare(name, &tname, &order, &nlabels) ==
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * How many labels does 'name' have?
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsdns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label) {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews unsigned char *offsets;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Make 'label' refer to the 'n'th least significant label of 'name'.
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington label->length = offsets[n + 1] - offsets[n];
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrewsdns_name_getlabelsequence(const dns_name_t *source,
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews unsigned int first, unsigned int n,
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews unsigned char *offsets;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Make 'target' refer to the 'n' labels including and following
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews * 'first' in 'source'.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews (source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington target->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * If source and target are the same, and we're making target
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews * a prefix of source, the offsets table is correct already
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews * so we don't need to call set_offsets().
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellingtondns_name_clone(dns_name_t *source, dns_name_t *target) {
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * Make 'target' refer to the same name as 'source'.
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington (unsigned int)~(DNS_NAMEATTR_READONLY | DNS_NAMEATTR_DYNAMIC |
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington if (target->offsets != NULL && source->labels > 0) {
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington set_offsets(target, target->offsets, NULL);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrewsdns_name_fromregion(dns_name_t *name, const isc_region_t *r) {
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews unsigned char *offsets;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews unsigned int len;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * Make 'name' refer to region 'r'.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews len = (r->length < r2.length) ? r->length : r2.length;
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews name->length = (r->length <= DNS_NAME_MAXWIRE) ?
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrewsdns_name_toregion(dns_name_t *name, isc_region_t *r) {
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * Make 'r' refer to 'name'.
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafssondns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson dns_name_t *origin, unsigned int options,
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson unsigned int value, count, tbcount, bitlength, maxlength;
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson unsigned int n1, n2, vlen, tlen, nrem, nused, digits, labels, tused;
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson unsigned char *offsets;
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * Convert the textual representation of a DNS name at source
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * into uncompressed wire form stored in target.
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * Relative domain names will have 'origin' appended to them
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * unless 'origin' is NULL, in which case relative domain names
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * will remain relative.
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson (target == NULL && ISC_BUFFER_VALID(name->buffer)));
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0);
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * Initialize things to make the compiler happy; they're not required.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * Make 'name' empty in case of failure.
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington * Set up the state machine.
84a47e20aedd16ba86feb25848732338ad618b16Brian Wellington tdata = (char *)source->base + source->current;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Is this the root name?
8b61d2012063306528286680bd9f086fa868d86eMark Andrews if (c == '.') {
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson /* FALLTHROUGH */
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (c == '\\') {
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews /* FALLTHROUGH */
390b2077fc751105e40174ceaa1ce34ef06e7dd4Mark Andrews if (c == '.') {
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson } else if (c == '\\') {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (c == '[') {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * This looks like a bitstring label, which
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * was deprecated. Intentionally drop it.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews /* FALLTHROUGH */
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson /* FALLTHROUGH */
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews /* Does not return. */
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson while (n1 > 0) {
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff while (n2 > 0) {
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews if ((origin->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
390b2077fc751105e40174ceaa1ce34ef06e7dd4Mark Andrews name->ndata = (unsigned char *)target->base + target->used;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews RUNTIME_CHECK(isc_key_create(&totext_filter_proc_key, free) == 0);
8b61d2012063306528286680bd9f086fa868d86eMark Andrewsdns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews unsigned char *ndata;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews unsigned char c;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews unsigned int labels;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews dns_name_totextfilter_t totext_filter_proc = NULL;
c27767a7b946f4c6f08d33129691e2d6339e8350Brian Wellington * This function assumes the name is in proper uncompressed
c27767a7b946f4c6f08d33129691e2d6339e8350Brian Wellington * wire format.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews result = isc_once_do(&once, totext_filter_proc_key_init);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Special handling for an empty name.
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * The names of these booleans are misleading in this case.
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * This empty name is not necessarily from the root node of
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * the DNS root zone, nor is a final dot going to be included.
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * They need to be set this way, though, to keep the "@"
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * from being trounced.
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews * Skip the while() loop.
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews } else if (nlen == 1 && labels == 1 && *ndata == '\0') {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Special handling for the root label.
nlen = 0;
labels--;
nlen--;
if (count == 0) {
while (count > 0) {
c = *ndata;
return (ISC_R_NOSPACE);
CONVERTFROMASCII(c);
*tdata++ = c;
ndata++;
nlen--;
if (trem == 0)
return (ISC_R_NOSPACE);
CONVERTFROMASCII(c);
*tdata++ = c;
ndata++;
trem--;
nlen--;
return (ISC_R_NOSPACE);
ndata++;
nlen--;
count--;
if (trem == 0)
return (ISC_R_NOSPACE);
trem--;
return (ISC_R_NOSPACE);
trem++;
#ifdef ISC_PLATFORM_USETHREADS
if (mem)
return (ISC_R_SUCCESS);
unsigned char *ndata;
char *tdata;
unsigned int labels;
if (trem == 0)
return (ISC_R_NOSPACE);
trem--;
nlen = 0;
labels--;
nlen--;
if (count == 0)
while (count > 0) {
c = *ndata;
if (trem == 0)
return (ISC_R_NOSPACE);
CONVERTFROMASCII(c);
*tdata++ = c;
ndata++;
trem--;
nlen--;
return (ISC_R_NOSPACE);
ndata++;
nlen--;
count--;
if (trem == 0)
return (ISC_R_NOSPACE);
trem--;
return (ISC_R_NOSPACE);
if (omit_final_dot)
trem++;
return (ISC_R_SUCCESS);
return (ISC_R_NOSPACE);
labels--;
nlen--;
while (count > 0) {
nlen--;
count--;
return (ISC_R_SUCCESS);
unsigned char *ndata;
offset = 0;
nlabels = 0;
offset++;
if (count == 0) {
if (absolute)
unsigned char *offsets;
new_current = 0;
labels = 0;
hops = 0;
nused = 0;
cused = 0;
c = *cdata++;
current++;
if (hops == 0)
cused++;
switch (state) {
case fw_start:
labels++;
goto full;
*ndata++ = c;
return (DNS_R_BADLABELTYPE);
return (DNS_R_DISALLOWED);
return (DNS_R_BADLABELTYPE);
case fw_ordinary:
if (downcase)
c = maptolower[c];
case fw_copy:
*ndata++ = c;
case fw_newcurrent:
new_current += c;
return (DNS_R_BADPOINTER);
hops++;
return (DNS_R_TOOMANYHOPS);
if (!done)
return (ISC_R_UNEXPECTEDEND);
return (ISC_R_SUCCESS);
full:
return (DNS_R_NAMETOOLONG);
return (ISC_R_NOSPACE);
unsigned int methods;
if (gf) {
return (ISC_R_NOSPACE);
return (ISC_R_NOSPACE);
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);
if (copy_prefix &&
length = 0;
prefix_length = 0;
labels = 0;
if (copy_prefix) {
if (copy_suffix) {
return (DNS_R_NAMETOOLONG);
return (ISC_R_NOSPACE);
if (copy_suffix) {
if (absolute)
return (ISC_R_SUCCESS);
unsigned int splitlabel;
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
isc_region_t r;
return (result);
isc_buffer_t b;
isc_region_t r;
isc_buffer_init(&b, t, sizeof(t));
return (result);
isc_buffer_usedregion(&b, &r);
return (ISC_R_SUCCESS);
#ifdef ISC_PLATFORM_USETHREADS
return (result);
return (ISC_R_SUCCESS);
return (result);
return (ISC_R_NOMEMORY);
return (result);
return (ISC_R_SUCCESS);
isc_region_t r;
unsigned char *ndata;
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);