name.c revision 9c3531d72aeaad6c5f01efe6a1c82023e1379e4d
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Copyright (C) 1998-2000 Internet Software Consortium.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Permission to use, copy, modify, and distribute this software for any
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * purpose with or without fee is hereby granted, provided that the above
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * copyright notice and this permission notice appear in all copies.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/* $Id: name.c,v 1.93 2000/06/22 21:54:32 tale Exp $ */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#define VALID_NAME(n) ISC_MAGIC_VALID(n, DNS_NAME_MAGIC)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunttypedef enum {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunttypedef enum {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic unsigned char maptolower[] = {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt var = default; \
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Note: If additional attributes are added that should not be set for
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * empty names, MAKE_EMPTY() must be changed so it clears them.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * A name is "bindable" if it can be set to point to a new value, i.e.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * name->ndata and name->length may be changed.
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt ((name->attributes & (DNS_NAMEATTR_READONLY|DNS_NAMEATTR_DYNAMIC)) \
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt * This silliness is to avoid warnings about the const attribute of a string
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt * being discarded, as can happen (depending on the compiler and flags)
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt * when name.ndata or name.offsets is assigned to via a string literal.
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt * Unfortunately, gcc -Wwrite-strings produces incorrect warnings for
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt * assigning a const string to the ndata or offsets members in
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt * "const struct dns_name root", which (at least according to the ANSI
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt * Draft dated August 3, 1998) should have the effect of declaring all
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt * members of the struct as const.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/* XXXDCL make const? */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/* XXXDCL make const? */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntset_offsets(const dns_name_t *name, unsigned char *offsets,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Yes, get_bit and set_bit are lame. We define them here so they can
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * be inlined by smart compilers.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic inline unsigned int
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic inline void
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntset_bit(unsigned char *array, unsigned int idx, unsigned int bit) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Get the type of 'label'.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned int count;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * The number of bits in a bitstring label.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE(label->base[0] == DNS_LABELTYPE_BITSTRING);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_label_getbit(dns_label_t *label, unsigned int n) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * The 'n'th most significant bit of 'label'.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Numbering starts at 0.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE(label->base[0] == DNS_LABELTYPE_BITSTRING);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_name_init(dns_name_t *name, unsigned char *offsets) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Initialize 'name'.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Make 'name' invalid.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Dedicate a buffer for use with 'name'.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE((buffer != NULL && name->buffer == NULL) ||
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Does 'name' have a dedicated buffer?
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Does 'name' end in the root label?
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if ((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned char *ndata;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Is 'name' a wildcard name?
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned char *ndata;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Does 'name' require EDNS for transmission?
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt while (nrem > 0) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned int length;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt const unsigned char *s;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned int h = 0;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned int g;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned char c;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Provide a hash value for 'name'.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * P. J. Weinberger's hash function, adapted from p. 436 of
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * _Compilers: Principles, Techniques, and Tools_, Aho, Sethi
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * and Ullman, Addison-Wesley, 1986, ISBN 0-201-10088-6.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt while (length > 0) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt h = ( h << 4 ) + *s;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if ((g = ( h & 0xf0000000 )) != 0) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt h = h ^ (g >> 24);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt while (length > 0) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt h = ( h << 4 ) + c;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if ((g = ( h & 0xf0000000 )) != 0) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt h = h ^ (g >> 24);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Determine the relative ordering under the DNSSEC order relation of
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * 'name1' and 'name2', and also determine the hierarchical
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * relationship of the names.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Note: It makes no sense for one of the names to be relative and the
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * other absolute. If both names are relative, then to be meaningfully
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * compared the caller must ensure that they are both relative to the
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * same domain.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Either name1 is absolute and name2 is absolute, or neither is.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt while (l > 0) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt while (count > 0) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt } else if (count1 == DNS_LABELTYPE_BITSTRING && count2 <= 63) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt } else if (count2 == DNS_LABELTYPE_BITSTRING && count1 <= 63) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt /* Yes, this loop is really slow! */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt for (n = 0; n < count; n++) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * If we're here, then we have two bitstrings
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * of differing length.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * If the name with the shorter bitstring
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * has any labels, then it must be greater
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * than the longer bitstring. This is a bit
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * counterintuitive. If the name with the
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * shorter bitstring has any more labels, then
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * the next label must be an ordinary label.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * It can't be a bitstring label because if it
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * were, then there would be room for it in
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * the current bitstring label (since all
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * bitstrings are canonicalized). Since
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * there's at least one more bit in the
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * name with the longer bitstring, and since
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * a bitlabel sorts before any ordinary label,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * the name with the longer bitstring must
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * be lexically before the one with the shorter
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * bitstring.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * On the other hand, if there are no more
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * labels in the name with the shorter
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * bitstring, then that name contains the
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * other name.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else if (ldiff > 0)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_name_compare(const dns_name_t *name1, const dns_name_t *name2) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Determine the relative ordering under the DNSSEC order relation of
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * 'name1' and 'name2'.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Note: It makes no sense for one of the names to be relative and the
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * other absolute. If both names are relative, then to be meaningfully
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * compared the caller must ensure that they are both relative to the
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * same domain.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt (void)dns_name_fullcompare(name1, name2, &order, &nlabels, &nbits);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_name_equal(const dns_name_t *name1, const dns_name_t *name2) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned int l, count;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned char c;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Are 'name1' and 'name2' equal?
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Note: It makes no sense for one of the names to be relative and the
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * other absolute. If both names are relative, then to be meaningfully
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * compared the caller must ensure that they are both relative to the
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * same domain.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Either name1 is absolute and name2 is absolute, or neither is.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt while (l > 0) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt while (count > 0) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Number of bytes.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt while (count > 0) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (c != *label2++)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Compare two absolute names as rdata.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE((name2->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt while (l > 0) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt while (count > 0) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return (-1);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt } else if (count1 == DNS_LABELTYPE_BITSTRING && count2 <= 63) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt } else if (count2 == DNS_LABELTYPE_BITSTRING && count1 <= 63) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return (-1);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt /* number of bytes */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt while (count > 0) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * If one name had more labels than the other, their common
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * prefix must have been different because the shorter name
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * ended with the root label and the longer one can't have
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * a root label in the middle of it. Therefore, if we get
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * to this point, the lengths must be equal.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Is 'name1' a subdomain of 'name2'?
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Note: It makes no sense for one of the names to be relative and the
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * other absolute. If both names are relative, then to be meaningfully
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * compared the caller must ensure that they are both relative to the
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * same domain.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt namereln = dns_name_fullcompare(name1, name2, &order, &nlabels,
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntdns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt dns_name_getlabelsequence(wname, 1, labels - 1, &tname);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (dns_name_fullcompare(name, &tname, &order, &nlabels, &nbits) ==
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned char *ndata;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * The depth of 'name'.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt while (nrem > 0) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (n % 8 != 0)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * How many labels does 'name' have?
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned char *offsets;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Make 'label' refer to the 'n'th least significant label of 'name'.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_name_getlabelsequence(const dns_name_t *source,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned int first, unsigned int n,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned char *offsets;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Make 'target' refer to the 'n' labels including and following
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * 'first' in 'source'.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt target->length = offsets[first + n] - offsets[first];
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * If source and target are the same, and we're making target
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * a prefix of source, the offsets table is correct already
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * so we don't need to call set_offsets().
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_name_clone(dns_name_t *source, dns_name_t *target) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Make 'target' refer to the same name as 'source'.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt (unsigned int)~(DNS_NAMEATTR_READONLY | DNS_NAMEATTR_DYNAMIC |
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (target->offsets != NULL && source->labels > 0) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_name_fromregion(dns_name_t *name, isc_region_t *r) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned char *offsets;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned int len;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Make 'name' refer to region 'r'.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt len = (r->length < r2.length) ? r->length : r2.length;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt name->length = (r->length <= 255) ? r->length : 255;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_name_toregion(dns_name_t *name, isc_region_t *r) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Make 'r' refer to 'name'.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned int value, count, tbcount, bitlength, maxlength;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned int n1, n2, vlen, tlen, nrem, nused, digits, labels, tused;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unsigned char *offsets;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Convert the textual representation of a DNS name at source
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * into uncompressed wire form stored in target.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Relative domain names will have 'origin' appended to them
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * unless 'origin' is NULL, in which case relative domain names
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * will remain relative.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE(isc_buffer_current(source) < isc_buffer_used(source));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Initialize things to make the compiler happy; they're not required.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Make 'name' empty in case of failure.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Set up the state machine.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Is this the root name?
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (c == '.') {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt /* FALLTHROUGH */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (c == '\\') {
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;
labels = 0;
nlen = 0;
if (trem == 0)
return (ISC_R_NOSPACE);
trem--;
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;
} else if (c == DNS_LABELTYPE_GLOBALCOMP16) {
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:
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_FORMERR);
return (ISC_R_NOSPACE);
unsigned int methods;
if (gf) {
return (ISC_R_NOSPACE);
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 (ISC_R_NOSPACE);
if (copy_suffix) {
if (copy_prefix &&
if (absolute)
if (saw_bitstring)
return (ISC_R_SUCCESS);
(nbits != 0 &&
(*p == 0 || *p > nbits)));
if (nbits > 0) {
*p = *p - nbits;
return(ISC_R_NOSPACE);
if (mod == 0) {
while (len--) {
if (len > 0)
*dst++ |=
prefix);
if (nbits > 0) {
return (ISC_R_NOSPACE);
if (len > 0) {
src = p;
if (len > 0) {
if (mod)
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;