name.c revision 3e6753a75350a990d2723a936657e5dabc1c5e30
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * Copyright (C) 1998-2000 Internet Software Consortium.
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * Permission to use, copy, modify, and distribute this software for any
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * purpose with or without fee is hereby granted, provided that the above
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * copyright notice and this permission notice appear in all copies.
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley/* $Id: name.c,v 1.114 2001/01/04 20:00:55 bwelling Exp $ */
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley#define VALID_NAME(n) ISC_MAGIC_VALID(n, DNS_NAME_MAGIC)
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halleytypedef enum {
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halleytypedef enum {
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halleystatic unsigned char maptolower[] = {
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley var = default; \
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * Note: If additional attributes are added that should not be set for
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * empty names, MAKE_EMPTY() must be changed so it clears them.
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * A name is "bindable" if it can be set to point to a new value, i.e.
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * name->ndata and name->length may be changed.
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley ((name->attributes & (DNS_NAMEATTR_READONLY|DNS_NAMEATTR_DYNAMIC)) \
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * This silliness is to avoid warnings about the const attribute of a string
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * being discarded, as can happen (depending on the compiler and flags)
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * when name.ndata or name.offsets is assigned to via a string literal.
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * Unfortunately, gcc -Wwrite-strings produces incorrect warnings for
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * assigning a const string to the ndata or offsets members in
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * "const struct dns_name root", which (at least according to the ANSI
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * Draft dated August 3, 1998) should have the effect of declaring all
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * members of the struct as const.
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley/* XXXDCL make const? */
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley/* XXXDCL make const? */
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halleyset_offsets(const dns_name_t *name, unsigned char *offsets,
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halleycompact(dns_name_t *name, unsigned char *offsets);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * Yes, get_bit and set_bit are lame. We define them here so they can
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * be inlined by smart compilers.
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halleystatic inline unsigned int
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halleystatic inline void
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halleyset_bit(unsigned char *array, unsigned int idx, unsigned int bit) {
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * Get the type of 'label'.
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley unsigned int count;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * The number of bits in a bitstring label.
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley REQUIRE(label->base[0] == DNS_LABELTYPE_BITSTRING);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halleydns_label_getbit(dns_label_t *label, unsigned int n) {
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * The 'n'th most significant bit of 'label'.
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * Numbering starts at 0.
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley REQUIRE(label->base[0] == DNS_LABELTYPE_BITSTRING);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halleydns_name_init(dns_name_t *name, unsigned char *offsets) {
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * Initialize 'name'.
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
unsigned char *ndata;
return (ISC_TRUE);
return (ISC_FALSE);
unsigned char *ndata;
while (nrem > 0) {
nrem--;
if (count == 0)
return (requiresedns);
unsigned int length;
if (case_sensitive) {
while (length > 0) {
length--;
while (length > 0) {
c = maptolower[*s];
length--;
int *orderp,
nlabels = 0;
nbits = 0;
if (ldiff < 0)
l = l1;
l = l2;
l1--;
l2--;
if (cdiff < 0)
while (count > 0) {
if (chdiff != 0) {
goto done;
count--;
label1++;
label2++;
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);
unsigned int l, count;
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_FALSE);
while (count > 0) {
count--;
return (ISC_FALSE);
return (ISC_FALSE);
if (count == 0)
while (count > 0) {
count--;
c = *label1++;
if (c != *label2++)
return (ISC_FALSE);
return (ISC_TRUE);
while (count > 0) {
count--;
if (count1 == 0)
if (count2 == 0)
while (count > 0) {
count--;
int order;
&nbits);
return (ISC_TRUE);
return (ISC_FALSE);
int order;
return (ISC_TRUE);
return (ISC_FALSE);
unsigned char *ndata;
depth = 0;
while (nrem > 0) {
nrem--;
n = *ndata++;
nrem--;
depth += n;
count++;
depth++;
if (count == 0)
return (depth);
unsigned char *offsets;
unsigned int first, unsigned int n,
unsigned char *offsets;
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:
return (DNS_R_LABELTOOLONG);
count++;
CONVERTTOASCII(c);
if (downcase)
c = maptolower[(int)c];
*ndata++ = c;
nrem--;
nused++;
digits = 0;
value = 0;
case ft_escdecimal:
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;
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:
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:
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)
if (bitlength != 0) {
return (DNS_R_BADBITSTRING);
return (DNS_R_BADBITSTRING);
n1++;
return (DNS_R_BADBITSTRING);
if (value != 0)
count = 0;
n1++;
return (DNS_R_BADBITSTRING);
if (n1 != 0) {
if ((value &
return (DNS_R_BADBITSTRING);
return (DNS_R_BADBITSTRING);
if (count > 0) {
nrem--;
nused++;
n1++;
return (ISC_R_NOSPACE);
nrem--;
nused++;
*label = 0;
labels++;
return (DNS_R_BADBITSTRING);
case ft_bitlength:
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 (ISC_R_NOSPACE);
return (ISC_R_UNEXPECTEDEND);
labels++;
return (ISC_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 (ISC_R_SUCCESS);
unsigned char *ndata;
char *tdata;
unsigned int labels;
if (trem == 0)
return (ISC_R_NOSPACE);
trem--;
nlen = 0;
if (trem == 0)
return (ISC_R_NOSPACE);
trem--;
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--;
return (ISC_R_NOSPACE);
if (count == 0)
nlen--;
bytes++;
nibbles++;
return (ISC_R_NOSPACE);
while (nibbles > 0) {
c = *ndata++;
nibbles--;
if (nibbles != 0) {
nibbles--;
return (ISC_R_NOSPACE);
for (i = 0; i < len; i++)
if (trem == 0)
return (ISC_R_NOSPACE);
trem--;
return (ISC_R_NOSPACE);
trem++;
return (ISC_R_SUCCESS);
return (ISC_R_NOSPACE);
labels--;
nlen--;
while (count > 0) {
nlen--;
count--;
if (count == 0)
nlen--;
bytes++;
while (bytes > 0) {
bytes--;
return (ISC_R_SUCCESS);
unsigned char *ndata;
offset = 0;
nlabels = 0;
offset++;
if (count == 0) {
n = *ndata++;
offset++;
count++;
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;
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);
} else if (c == DNS_LABELTYPE_BITSTRING) {
labels++;
goto full;
nused++;
*ndata++ = c;
return (DNS_R_BADLABELTYPE);
case fw_ordinary:
if (downcase)
c = maptolower[c];
case fw_copy:
*ndata++ = c;
case fw_bitstring:
goto full;
*ndata++ = c;
case fw_newcurrent:
new_current += c;
return (DNS_R_BADPOINTER);
hops++;
return (DNS_R_TOOMANYHOPS);
if (!done)
return (ISC_R_UNEXPECTEDEND);
if (saw_bitstring)
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 (copy_prefix &&
if (absolute)
if (saw_bitstring)
return (ISC_R_SUCCESS);
(*p == 0 || *p > nbits)));
if (nbits > 0) {
*p = *p - nbits;
return(ISC_R_NOSPACE);
if (mod == 0) {
while (len--) {
if (src <= p)
*dst++ |=
prefix);
if (nbits > 0) {
src++;
return (ISC_R_NOSPACE);
if (len > 0) {
src = p;
if (len > 0) {
if (mod != 0)
return (result);
suffixlabels = 0;
nbits = 0;
label--;
n = *ndata++;
suffixlabels++;
if (n <= depth) {
depth -= n;
depth = 0;
suffixlabels++;
depth--;
if (depth != 0) {
INSIST(0);
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);
isc_region_t r;
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);