name.c revision a41d348e14b0465c6444cdfd2d59f9370fd44fe8
4a979d35776321abc952346ba128d1a3cef730ceAutomatic Updater * Copyright (C) 1998, 1999 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Permission to use, copy, modify, and distribute this software for any
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * purpose with or without fee is hereby granted, provided that the above
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * copyright notice and this permission notice appear in all copies.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrencetypedef enum {
ea872078bfa9473cfe9c89b474dae2496377797bDavid Lawrencetypedef enum {
e72c1e7e465822fc9b5067b2dd3cf047f6132214Mark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
e72c1e7e465822fc9b5067b2dd3cf047f6132214Mark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
6c6ceac1bc66812f6e0097dcf5fd8b901c3fecd1Andreas Gustafsson -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrewsstatic unsigned char maptolower[] = {
e2c97aef510f4cdced2894ab2a5daf2b1d316e2aAutomatic Updater 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
ed9ca2306508e3106e3d111d7cf39bf82f8689d0Mark Andrews 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
355cc22e32085faeb553fe6c37de69e83b9d5191Andreas Gustafsson 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
355cc22e32085faeb553fe6c37de69e83b9d5191Andreas Gustafsson 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
6c6ceac1bc66812f6e0097dcf5fd8b901c3fecd1Andreas Gustafsson 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
355cc22e32085faeb553fe6c37de69e83b9d5191Andreas Gustafsson 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
355cc22e32085faeb553fe6c37de69e83b9d5191Andreas Gustafsson 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence set_offsets(name, var, ISC_FALSE, ISC_FALSE, ISC_FALSE); \
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrencestatic void set_offsets(dns_name_t *name, unsigned char *offsets,
6c6ceac1bc66812f6e0097dcf5fd8b901c3fecd1Andreas Gustafsson isc_boolean_t set_labels, isc_boolean_t set_length,
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halleystatic void compact(dns_name_t *name, unsigned char *offsets);
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley * Yes, get_bit and set_bit are lame. We define them here so they can
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * be inlined by smart compilers.
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrencestatic unsigned int
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halleyget_bit(unsigned char *array, unsigned int index) {
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrenceset_bit(unsigned char *array, unsigned int index, unsigned int bit) {
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley * Get the type of 'label'.
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley unsigned int count;
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence * The number of bits in a bitstring label.
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley REQUIRE(label->base[0] == DNS_LABELTYPE_BITSTRING);
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrencedns_label_getbit(dns_label_t *label, unsigned int n) {
1d9958c6cc291916010779792f0fbdf6cd5ba368Mark Andrews * The 'n'th most significant bit of 'label'.
28b863e609ff2d97b78663b46894494cfa2ea411Mark Andrews * Numbering starts at 0.
1d9958c6cc291916010779792f0fbdf6cd5ba368Mark Andrews REQUIRE(label->base[0] == DNS_LABELTYPE_BITSTRING);
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrencedns_name_init(dns_name_t *name, unsigned char *offsets) {
ff8cd3afa7f900d7986ccbc3638235cb8ad6f1ecAndreas Gustafsson * Make 'name' empty.
b38ab99bdc833da490c0ca0cbd05fb9d54dff997Andreas Gustafsson * Make 'name' invalid.
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrewsdns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer) {
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt * Dedicate a binary buffer for use with 'name'.
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews REQUIRE(isc_buffer_type(buffer) == ISC_BUFFERTYPE_BINARY);
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt * Does 'name' have a dedicated buffer?
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt * Does 'name' end in the root label?
return (ISC_TRUE);
return (ISC_FALSE);
unsigned int length;
if (case_sensitive) {
while (length > 0) {
length--;
while (length > 0) {
c = maptolower[*s];
length--;
int *orderp,
nlabels = 0;
nbits = 0;
l = l1;
l = l2;
ldiff = 0;
l1--;
l2--;
cdiff = 0;
while (count > 0) {
count--;
goto done;
goto done;
if (cdiff != 0) {
goto done;
nlabels++;
if (count2 == 0)
goto done;
if (count1 == 0)
goto done;
if (count1 == 0)
if (count2 == 0)
cdiff = 0;
for (n = 0; n < count; n++) {
goto done;
goto done;
if (nbits == 0)
nlabels++;
nbits++;
if (cdiff != 0) {
if (cdiff < 0) {
if (l1 > 0)
namereln =
if (l2 > 0)
namereln =
goto done;
nbits = 0;
if (ldiff < 0)
else if (ldiff > 0)
done:
return (namereln);
int order;
return (order);
while (count > 0) {
count--;
if (count1 == 0)
if (count2 == 0)
while (count > 0) {
int order;
&nbits);
return (ISC_TRUE);
return (ISC_FALSE);
unsigned char *offsets;
unsigned int first, unsigned int n,
unsigned char *offsets;
REQUIRE(n > 0);
unsigned char *offsets;
unsigned int len;
if (r->length > 0)
char *tdata;
unsigned char *offsets;
offsets[0] = 0;
n1 = 0;
n2 = 0;
vlen = 0;
digits = 0;
value = 0;
count = 0;
tbcount = 0;
bitlength = 0;
maxlength = 0;
tused = 0;
nused = 0;
labels = 0;
c = *tdata++;
tlen--;
tused++;
switch (state) {
case ft_init:
if (tlen != 0)
return (DNS_R_EMPTYLABEL);
labels++;
*ndata++ = 0;
nrem--;
nused++;
case ft_start:
ndata++;
nrem--;
nused++;
count = 0;
case ft_ordinary:
if (count == 0)
return (DNS_R_EMPTYLABEL);
labels++;
if (tlen == 0) {
labels++;
*ndata++ = 0;
nrem--;
nused++;
return (DNS_R_LABELTOOLONG);
count++;
CONVERTTOASCII(c);
if (downcase)
c = maptolower[(int)c];
*ndata++ = c;
nrem--;
nused++;
case ft_initialescape:
ndata++;
nrem--;
nused++;
case ft_escape:
if (!isdigit(c)) {
return (DNS_R_LABELTOOLONG);
count++;
CONVERTTOASCII(c);
if (downcase)
c = maptolower[(int)c];
*ndata++ = c;
nrem--;
nused++;
digits = 0;
value = 0;
case ft_escdecimal:
if (!isdigit(c))
return (DNS_R_BADESCAPE);
digits++;
return (DNS_R_BADESCAPE);
return (DNS_R_LABELTOOLONG);
count++;
if (downcase)
nrem--;
nused++;
case ft_bitstring:
tbcount = 0;
value = 0;
} else if (isdigit(c)) {
n1 = 0;
n2 = 0;
digits = 0;
goto no_read;
return (DNS_R_BADBITSTRING);
case ft_binary:
goto no_read;
count++;
tbcount++;
return (DNS_R_BITSTRINGTOOLONG);
nrem--;
nused++;
count = 0;
case ft_octal:
goto no_read;
return (DNS_R_BITSTRINGTOOLONG);
nrem--;
nused++;
count = 0;
nrem--;
nused++;
nrem--;
nused++;
case ft_hex:
if (!isxdigit(c)) {
goto no_read;
return (DNS_R_BITSTRINGTOOLONG);
nrem--;
nused++;
count = 0;
case ft_dottedquad:
return (DNS_R_BADDOTTEDQUAD);
n1++;
goto no_read;
value = 0;
digits = 0;
case ft_dqdecimal:
if (!isdigit(c)) {
return (DNS_R_BADDOTTEDQUAD);
goto no_read;
digits++;
return (DNS_R_BADDOTTEDQUAD);
case ft_maybeslash:
bitlength = 0;
case ft_finishbitstring:
if (tbcount == 0)
return (DNS_R_BADBITSTRING);
if (count > 0) {
if (n1 != 0)
nrem--;
nused++;
if (bitlength != 0) {
return (DNS_R_BADBITSTRING);
return (DNS_R_BADBITSTRING);
n1++;
return (DNS_R_BADBITSTRING);
n1++;
return (DNS_R_BADBITSTRING);
if (n1 != 0) {
if ((value &
return (DNS_R_BADBITSTRING);
n1++;
return (DNS_R_NOSPACE);
nrem--;
nused++;
*label = 0;
labels++;
return (DNS_R_BADBITSTRING);
case ft_bitlength:
if (!isdigit(c)) {
if (bitlength == 0)
return (DNS_R_BADBITSTRING);
goto no_read;
return (DNS_R_BADBITSTRING);
case ft_eatdot:
return (DNS_R_BADBITSTRING);
if (tlen == 0) {
labels++;
*ndata++ = 0;
nrem--;
nused++;
if (!done) {
if (nrem == 0)
return (DNS_R_NOSPACE);
return (DNS_R_UNEXPECTEDEND);
labels++;
return (DNS_R_NOSPACE);
while (n1 > 0) {
while (n2 > 0) {
c = *label++;
if (downcase)
c = maptolower[(int)c];
*ndata++ = c;
n2--;
if (bitlength == 0)
n2++;
while (n2 > 0) {
n2--;
labels++;
if (n1 > 0) {
if (saw_bitstring)
return (DNS_R_SUCCESS);
unsigned char *ndata;
char *tdata;
unsigned int labels;
labels = 0;
nlen = 0;
if (trem == 0)
return (DNS_R_NOSPACE);
trem--;
labels--;
nlen--;
if (count == 0) {
while (count > 0) {
c = *ndata;
return (DNS_R_NOSPACE);
*tdata++ = c;
ndata++;
nlen--;
if (trem == 0)
return (DNS_R_NOSPACE);
*tdata++ = c;
ndata++;
trem--;
nlen--;
return (DNS_R_NOSPACE);
ndata++;
nlen--;
count--;
return (DNS_R_NOSPACE);
if (count == 0)
nlen--;
bytes++;
nibbles++;
return (DNS_R_NOSPACE);
while (nibbles > 0) {
c = *ndata++;
nibbles--;
if (nibbles != 0) {
nibbles--;
return (DNS_R_NOSPACE);
for (i = 0; i < len; i++)
if (trem == 0)
return (DNS_R_NOSPACE);
trem--;
return (DNS_R_NOSPACE);
trem++;
return (DNS_R_SUCCESS);
unsigned char *ndata;
offset = 0;
nlabels = 0;
while (nrem > 0) {
nrem--;
offset++;
if (count == 0) {
n = *ndata++;
nrem--;
offset++;
count++;
if (set_labels)
if (set_length)
if (set_absolute) {
if (absolute)
if (currbits == 0)
currindex = 0;
if (headbits == 0)
if (headrem != 0)
if (headrem != 0) {
bit);
currindex++;
headindex++;
headbits++;
count--;
headrem--;
} while (headrem != 0);
tailindex = 0;
tailbits = 0;
while (count > 0) {
currindex++;
tailindex++;
tailbits++;
count--;
newbits = 0;
newindex = 0;
bit);
currindex++;
newindex++;
newbits++;
if (newrem != 0) {
count++;
while (newrem > 0) {
newrem--;
newindex++;
count++;
while (count > 0) {
count--;
count++;
while (count > 0) {
count--;
goto again;
unsigned char *offsets;
unsigned int bits;
new_current = 0;
labels = 0;
hops = 0;
nused = 0;
cused = 0;
c = *cdata++;
current++;
if (hops == 0)
cused++;
switch (state) {
case fw_start:
labels++;
return (DNS_R_NOSPACE);
*ndata++ = c;
return (DNS_R_DISALLOWED);
return (DNS_R_DISALLOWED);
} else if (c == DNS_LABELTYPE_BITSTRING) {
labels++;
if (nrem == 0)
return (DNS_R_NOSPACE);
nrem--;
nused++;
*ndata++ = c;
} else if (c == DNS_LABELTYPE_GLOBALCOMP16) {
return (DNS_R_DISALLOWED);
new_current = 0;
} else if (c == DNS_LABELTYPE_LOCALCOMP) {
return (DNS_R_DISALLOWED);
new_current = 0;
return (DNS_R_BADLABELTYPE);
case fw_ordinary:
if (downcase)
c = maptolower[c];
case fw_copy:
*ndata++ = c;
case fw_bitstring:
return (DNS_R_NOSPACE);
*ndata++ = c;
case fw_newcurrent:
new_current += c;
return (DNS_R_BADPOINTER);
return (DNS_R_BADPOINTER);
lcount--;
ll = 0;
&label);
if (labeltype ==
ll++;
if (i > lcount)
return (DNS_R_BADPOINTER);
&label);
return (DNS_R_NOSPACE);
bits--;
bits);
} while (bits != 0);
labels++;
lcount - i,
return (DNS_R_NOSPACE);
if (local)
return (DNS_R_BADPOINTER);
hops++;
return (DNS_R_TOOMANYHOPS);
if (!done)
return (DNS_R_UNEXPECTEDEND);
if (saw_bitstring)
return (DNS_R_SUCCESS);
unsigned int methods;
unsigned int offset;
if (gf) {
return (DNS_R_NOSPACE);
return (DNS_R_NOSPACE);
return (DNS_R_NOSPACE);
} else if (lf) {
return (DNS_R_NOSPACE);
return (DNS_R_NOSPACE);
return (DNS_R_NOSPACE);
return (DNS_R_NOSPACE);
return (DNS_R_SUCCESS);
if (copy_prefix &&
length = 0;
prefix_length = 0;
labels = 0;
if (copy_prefix) {
if (copy_suffix) {
return (DNS_R_NOSPACE);
if (copy_suffix) {
if (copy_prefix &&
if (absolute)
if (saw_bitstring)
return (DNS_R_SUCCESS);
(nbits != 0 &&
(*p == 0 || *p > nbits)));
if (nbits > 0) {
*p = *p - nbits;
return(DNS_R_NOSPACE);
if (mod == 0) {
while (len--) {
if (len > 0)
*dst++ &=
prefix);
if (nbits > 0) {
return (DNS_R_NOSPACE);
if (len > 0) {
src = p;
if (len > 0) {
if (mod)
return (result);