unsigned int dns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive) { unsigned char *offsets; dns_offsets_t odata; dns_name_t tname; unsigned int h = 0; unsigned int i; /* * Provide a hash value for 'name'. */ REQUIRE(VALID_NAME(name)); if (name->labels == 0) return (0); else if (name->labels == 1) return (name_hash(name, case_sensitive)); SETUP_OFFSETS(name, offsets, odata); DNS_NAME_INIT(&tname, NULL); tname.labels = 1; h = 0; for (i = 0; i < name->labels; i++) { tname.ndata = name->ndata + offsets[i]; if (i == name->labels - 1) tname.length = name->length - offsets[i]; else tname.length = offsets[i + 1] - offsets[i]; h += name_hash(&tname, case_sensitive); } return (h); }
isc_result_t dns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg) { dns_name_t downname; unsigned char data[256]; isc_buffer_t buffer; isc_result_t result; isc_region_t r; /* * Send 'name' in DNSSEC canonical form to 'digest'. */ REQUIRE(VALID_NAME(name)); REQUIRE(digest != NULL); DNS_NAME_INIT(&downname, NULL); isc_buffer_init(&buffer, data, sizeof(data)); result = dns_name_downcase(name, &downname, &buffer); if (result != ISC_R_SUCCESS) return (result); isc_buffer_usedregion(&buffer, &r); return ((digest)(arg, &r)); }
void dns_name_init(dns_name_t *name, unsigned char *offsets) { /* * Initialize 'name'. */ DNS_NAME_INIT(name, offsets); }
/** * Convert UUID to "01234567-89ab-cdef-0123-456789abcdef.uuid.ldap." DNS name. * * @param[in] beruuid * @param[out] nameuuid */ void ldap_uuid_to_mname(struct berval *beruuid, dns_name_t *nameuuid) { /* UUID string representation according to RFC 4122 section 3 */ char label_buf[sizeof("01234567-89ab-cdef-0123-456789abcdef") + 1]; /* uncompressed label format, length 36 octets; RFC 1034 section 3.1 */ label_buf[0] = 36; isc_region_t label_reg; label_reg.base = (unsigned char *)label_buf; label_reg.length = sizeof(label_buf) - 1; /* omit final \0 */ dns_name_t relative_name; DNS_NAME_INIT(&relative_name, NULL); /* RFC 4530 section 2.1 format = 16 octets is required */ REQUIRE(beruuid != NULL && beruuid->bv_len == 16); /* fill-in string representation into label buffer */ uuid_unparse((*(const uuid_t *) beruuid->bv_val), label_buf + 1); dns_name_fromregion(&relative_name, &label_reg); INSIST(dns_name_concatenate(&relative_name, &uuid_rootname, nameuuid, NULL) == ISC_R_SUCCESS); return; }
isc_boolean_t dns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname) { int order; unsigned int nlabels, labels; dns_name_t tname; REQUIRE(VALID_NAME(name)); REQUIRE(name->labels > 0); REQUIRE(VALID_NAME(wname)); labels = wname->labels; REQUIRE(labels > 0); REQUIRE(dns_name_iswildcard(wname)); DNS_NAME_INIT(&tname, NULL); dns_name_getlabelsequence(wname, 1, labels - 1, &tname); if (dns_name_fullcompare(name, &tname, &order, &nlabels) == dns_namereln_subdomain) return (ISC_TRUE); return (ISC_FALSE); }
isc_result_t dns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix, dns_name_t *name, isc_buffer_t *target) { unsigned char *ndata, *offsets; unsigned int nrem, labels, prefix_length, length; isc_boolean_t copy_prefix = ISC_TRUE; isc_boolean_t copy_suffix = ISC_TRUE; isc_boolean_t absolute = ISC_FALSE; dns_name_t tmp_name; dns_offsets_t odata; /* * Concatenate 'prefix' and 'suffix'. */ REQUIRE(prefix == NULL || VALID_NAME(prefix)); REQUIRE(suffix == NULL || VALID_NAME(suffix)); REQUIRE(name == NULL || VALID_NAME(name)); REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || (target == NULL && name != NULL && ISC_BUFFER_VALID(name->buffer))); if (prefix == NULL || prefix->labels == 0) copy_prefix = ISC_FALSE; if (suffix == NULL || suffix->labels == 0) copy_suffix = ISC_FALSE; if (copy_prefix && (prefix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) { absolute = ISC_TRUE; REQUIRE(!copy_suffix); } if (name == NULL) { DNS_NAME_INIT(&tmp_name, odata); name = &tmp_name; } if (target == NULL) { INSIST(name->buffer != NULL); target = name->buffer; isc_buffer_clear(name->buffer); } REQUIRE(BINDABLE(name)); /* * Set up. */ nrem = target->length - target->used; ndata = (unsigned char *)target->base + target->used; if (nrem > DNS_NAME_MAXWIRE) nrem = DNS_NAME_MAXWIRE; length = 0; prefix_length = 0; labels = 0; if (copy_prefix) { prefix_length = prefix->length; length += prefix_length; labels += prefix->labels; } if (copy_suffix) { length += suffix->length; labels += suffix->labels; } if (length > DNS_NAME_MAXWIRE) { MAKE_EMPTY(name); return (DNS_R_NAMETOOLONG); } if (length > nrem) { MAKE_EMPTY(name); return (ISC_R_NOSPACE); } if (copy_suffix) { if ((suffix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) absolute = ISC_TRUE; if (suffix == name && suffix->buffer == target) memmove(ndata + prefix_length, suffix->ndata, suffix->length); else memcpy(ndata + prefix_length, suffix->ndata, suffix->length); } /* * If 'prefix' and 'name' are the same object, and the object has * a dedicated buffer, and we're using it, then we don't have to * copy anything. */ if (copy_prefix && (prefix != name || prefix->buffer != target)) memcpy(ndata, prefix->ndata, prefix_length); name->ndata = ndata; name->labels = labels; name->length = length; if (absolute) name->attributes = DNS_NAMEATTR_ABSOLUTE; else name->attributes = 0; if (name->labels > 0 && name->offsets != NULL) { INIT_OFFSETS(name, offsets, odata); set_offsets(name, offsets, NULL); } isc_buffer_add(target, name->length); return (ISC_R_SUCCESS); }
isc_result_t dns_name_towire(dns_name_t *name, dns_compress_t *cctx, isc_buffer_t *target) { unsigned int methods; isc_uint16_t offset; dns_name_t gp; /* Global compression prefix */ isc_boolean_t gf; /* Global compression target found */ isc_uint16_t go; /* Global compression offset */ dns_offsets_t clo; dns_name_t clname; /* * Convert 'name' into wire format, compressing it as specified by the * compression context 'cctx', and storing the result in 'target'. */ REQUIRE(VALID_NAME(name)); REQUIRE(cctx != NULL); REQUIRE(ISC_BUFFER_VALID(target)); /* * If 'name' doesn't have an offsets table, make a clone which * has one. */ if (name->offsets == NULL) { DNS_NAME_INIT(&clname, clo); dns_name_clone(name, &clname); name = &clname; } DNS_NAME_INIT(&gp, NULL); offset = target->used; /*XXX*/ methods = dns_compress_getmethods(cctx); if ((methods & DNS_COMPRESS_GLOBAL14) != 0) gf = dns_compress_findglobal(cctx, name, &gp, &go); else gf = ISC_FALSE; /* * If the offset is too high for 14 bit global compression, we're * out of luck. */ if (gf && go >= 0x4000) gf = ISC_FALSE; /* * Will the compression pointer reduce the message size? */ if (gf && (gp.length + 2) >= name->length) gf = ISC_FALSE; if (gf) { if (target->length - target->used < gp.length) return (ISC_R_NOSPACE); (void)memcpy((unsigned char *)target->base + target->used, gp.ndata, (size_t)gp.length); isc_buffer_add(target, gp.length); go |= 0xc000; if (target->length - target->used < 2) return (ISC_R_NOSPACE); isc_buffer_putuint16(target, go); if (gp.length != 0) dns_compress_add(cctx, name, &gp, offset); } else { if (target->length - target->used < name->length) return (ISC_R_NOSPACE); (void)memcpy((unsigned char *)target->base + target->used, name->ndata, (size_t)name->length); isc_buffer_add(target, name->length); dns_compress_add(cctx, name, name, offset); } return (ISC_R_SUCCESS); }