static inline isc_result_t generic_tostruct_ds(ARGS_TOSTRUCT) { dns_rdata_ds_t *ds = target; isc_region_t region; REQUIRE(target != NULL); REQUIRE(rdata->length != 0); REQUIRE(ds->common.rdtype == rdata->type); REQUIRE(ds->common.rdclass == rdata->rdclass); REQUIRE(!ISC_LINK_LINKED(&ds->common, link)); dns_rdata_toregion(rdata, ®ion); ds->key_tag = uint16_fromregion(®ion); isc_region_consume(®ion, 2); ds->algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); ds->digest_type = uint8_fromregion(®ion); isc_region_consume(®ion, 1); ds->length = region.length; ds->digest = mem_maybedup(mctx, region.base, region.length); if (ds->digest == NULL) return (ISC_R_NOMEMORY); ds->mctx = mctx; return (ISC_R_SUCCESS); }
static inline isc_result_t tostruct_tlsa(ARGS_TOSTRUCT) { dns_rdata_tlsa_t *tlsa = target; isc_region_t region; REQUIRE(rdata->type == 52); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); tlsa->common.rdclass = rdata->rdclass; tlsa->common.rdtype = rdata->type; ISC_LINK_INIT(&tlsa->common, link); dns_rdata_toregion(rdata, ®ion); tlsa->usage = uint8_fromregion(®ion); isc_region_consume(®ion, 1); tlsa->selector = uint8_fromregion(®ion); isc_region_consume(®ion, 1); tlsa->match = uint8_fromregion(®ion); isc_region_consume(®ion, 1); tlsa->length = region.length; tlsa->data = mem_maybedup(mctx, region.base, region.length); if (tlsa->data == NULL) return (ISC_R_NOMEMORY); tlsa->mctx = mctx; return (ISC_R_SUCCESS); }
static inline isc_result_t tostruct_keydata(ARGS_TOSTRUCT) { dns_rdata_keydata_t *keydata = target; isc_region_t sr; REQUIRE(rdata->type == 65533); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); keydata->common.rdclass = rdata->rdclass; keydata->common.rdtype = rdata->type; ISC_LINK_INIT(&keydata->common, link); dns_rdata_toregion(rdata, &sr); /* Refresh timer */ if (sr.length < 4) return (ISC_R_UNEXPECTEDEND); keydata->refresh = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* Add hold-down */ if (sr.length < 4) return (ISC_R_UNEXPECTEDEND); keydata->addhd = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* Remove hold-down */ if (sr.length < 4) return (ISC_R_UNEXPECTEDEND); keydata->removehd = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* Flags */ if (sr.length < 2) return (ISC_R_UNEXPECTEDEND); keydata->flags = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* Protocol */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); keydata->protocol = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* Algorithm */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); keydata->algorithm = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* Data */ keydata->datalen = sr.length; keydata->data = mem_maybedup(mctx, sr.base, keydata->datalen); if (keydata->data == NULL) return (ISC_R_NOMEMORY); keydata->mctx = mctx; return (ISC_R_SUCCESS); }
static inline isc_result_t tostruct_hinfo(ARGS_TOSTRUCT) { dns_rdata_hinfo_t *hinfo = target; isc_region_t region; REQUIRE(rdata->type == 13); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); hinfo->common.rdclass = rdata->rdclass; hinfo->common.rdtype = rdata->type; ISC_LINK_INIT(&hinfo->common, link); dns_rdata_toregion(rdata, ®ion); hinfo->cpu_len = uint8_fromregion(®ion); isc_region_consume(®ion, 1); hinfo->cpu = mem_maybedup(mctx, region.base, hinfo->cpu_len); if (hinfo->cpu == NULL) return (ISC_R_NOMEMORY); isc_region_consume(®ion, hinfo->cpu_len); hinfo->os_len = uint8_fromregion(®ion); isc_region_consume(®ion, 1); hinfo->os = mem_maybedup(mctx, region.base, hinfo->os_len); if (hinfo->os == NULL) goto cleanup; hinfo->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL && hinfo->cpu != NULL) isc_mem_free(mctx, hinfo->cpu); return (ISC_R_NOMEMORY); }
static inline isc_result_t tostruct_sshfp(ARGS_TOSTRUCT) { dns_rdata_sshfp_t *sshfp = target; isc_region_t region; REQUIRE(rdata->type == 44); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); sshfp->common.rdclass = rdata->rdclass; sshfp->common.rdtype = rdata->type; ISC_LINK_INIT(&sshfp->common, link); dns_rdata_toregion(rdata, ®ion); sshfp->algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); sshfp->digest_type = uint8_fromregion(®ion); isc_region_consume(®ion, 1); sshfp->length = region.length; sshfp->digest = mem_maybedup(mctx, region.base, region.length); if (sshfp->digest == NULL) return (ISC_R_NOMEMORY); sshfp->mctx = mctx; return (ISC_R_SUCCESS); }
static inline isc_result_t tostruct_hip(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_hip_t *hip = target; REQUIRE(rdata->type == dns_rdatatype_hip); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); hip->common.rdclass = rdata->rdclass; hip->common.rdtype = rdata->type; ISC_LINK_INIT(&hip->common, link); dns_rdata_toregion(rdata, ®ion); hip->hit_len = uint8_fromregion(®ion); isc_region_consume(®ion, 1); hip->algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); hip->key_len = uint16_fromregion(®ion); isc_region_consume(®ion, 2); hip->hit = hip->key = hip->servers = NULL; hip->hit = mem_maybedup(mctx, region.base, hip->hit_len); if (hip->hit == NULL) goto cleanup; isc_region_consume(®ion, hip->hit_len); INSIST(hip->key_len <= region.length); hip->key = mem_maybedup(mctx, region.base, hip->key_len); if (hip->key == NULL) goto cleanup; isc_region_consume(®ion, hip->key_len); hip->servers_len = region.length; if (hip->servers_len != 0) { hip->servers = mem_maybedup(mctx, region.base, region.length); if (hip->servers == NULL) goto cleanup; } hip->offset = hip->servers_len; hip->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (hip->hit != NULL) isc_mem_free(mctx, hip->hit); if (hip->key != NULL) isc_mem_free(mctx, hip->key); if (hip->servers != NULL) isc_mem_free(mctx, hip->servers); return (ISC_R_NOMEMORY); }
static inline isc_result_t totext_ds(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("64000 ")]; unsigned int n; REQUIRE(rdata->type == 43); REQUIRE(rdata->length != 0); UNUSED(tctx); dns_rdata_toregion(rdata, &sr); /* * Key tag. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Algorithm. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Digest type. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u", n); RETERR(str_totext(buf, target)); /* * Digest. */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { if (tctx->width == 0) /* No splitting */ RETERR(isc_hex_totext(&sr, 0, "", target)); else RETERR(isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak, target)); } else RETERR(str_totext("[omitted]", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); }
static inline isc_result_t tostruct_caa(ARGS_TOSTRUCT) { dns_rdata_caa_t *caa = target; isc_region_t sr; REQUIRE(rdata->type == 257); REQUIRE(target != NULL); REQUIRE(rdata->length >= 3U); REQUIRE(rdata->data != NULL); caa->common.rdclass = rdata->rdclass; caa->common.rdtype = rdata->type; ISC_LINK_INIT(&caa->common, link); dns_rdata_toregion(rdata, &sr); /* * Flags */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); caa->flags = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* * Tag length */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); caa->tag_len = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* * Tag */ if (sr.length < caa->tag_len) return (ISC_R_UNEXPECTEDEND); caa->tag = mem_maybedup(mctx, sr.base, caa->tag_len); if (caa->tag == NULL) return (ISC_R_NOMEMORY); isc_region_consume(&sr, caa->tag_len); /* * Value */ caa->value_len = sr.length; caa->value = mem_maybedup(mctx, sr.base, sr.length); if (caa->value == NULL) return (ISC_R_NOMEMORY); caa->mctx = mctx; return (ISC_R_SUCCESS); }
static inline isc_result_t tostruct_gpos (ARGS_TOSTRUCT) { dns_rdata_gpos_t *gpos = target; isc_region_t region; REQUIRE (rdata->type == 27); REQUIRE (target != NULL); REQUIRE (rdata->length != 0); gpos->common.rdclass = rdata->rdclass; gpos->common.rdtype = rdata->type; ISC_LINK_INIT (&gpos->common, link); dns_rdata_toregion (rdata, ®ion); gpos->long_len = uint8_fromregion (®ion); isc_region_consume (®ion, 1); gpos->longitude = mem_maybedup (mctx, region.base, gpos->long_len); if (gpos->longitude == NULL) return (ISC_R_NOMEMORY); isc_region_consume (®ion, gpos->long_len); gpos->lat_len = uint8_fromregion (®ion); isc_region_consume (®ion, 1); gpos->latitude = mem_maybedup (mctx, region.base, gpos->lat_len); if (gpos->latitude == NULL) goto cleanup_longitude; isc_region_consume (®ion, gpos->lat_len); gpos->alt_len = uint8_fromregion (®ion); isc_region_consume (®ion, 1); if (gpos->lat_len > 0) { gpos->altitude = mem_maybedup (mctx, region.base, gpos->alt_len); if (gpos->altitude == NULL) goto cleanup_latitude; } else gpos->altitude = NULL; gpos->mctx = mctx; return (ISC_R_SUCCESS); cleanup_latitude: if (mctx != NULL && gpos->longitude != NULL) isc_mem_free (mctx, gpos->longitude); cleanup_longitude: if (mctx != NULL && gpos->latitude != NULL) isc_mem_free (mctx, gpos->latitude); return (ISC_R_NOMEMORY); }
static inline isc_result_t totext_tlsa(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("64000 ")]; unsigned int n; REQUIRE(rdata->type == 52); REQUIRE(rdata->length != 0); UNUSED(tctx); dns_rdata_toregion(rdata, &sr); /* * Certificate Usage. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Selector. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Matching type. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u", n); RETERR(str_totext(buf, target)); /* * Certificate Association Data. */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_hex_totext(&sr, 0, "", target)); else RETERR(isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); }
static inline isc_result_t totext_nsec3param(ARGS_TOTEXT) { isc_region_t sr; unsigned int i, j; unsigned char hash; unsigned char flags; char buf[sizeof("65535 ")]; isc_uint32_t iterations; REQUIRE(rdata->type == dns_rdatatype_nsec3param); REQUIRE(rdata->length != 0); UNUSED(tctx); dns_rdata_toregion(rdata, &sr); hash = uint8_fromregion(&sr); isc_region_consume(&sr, 1); flags = uint8_fromregion(&sr); isc_region_consume(&sr, 1); iterations = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u ", hash); RETERR(str_totext(buf, target)); sprintf(buf, "%u ", flags); RETERR(str_totext(buf, target)); sprintf(buf, "%u ", iterations); RETERR(str_totext(buf, target)); j = uint8_fromregion(&sr); isc_region_consume(&sr, 1); INSIST(j <= sr.length); if (j != 0) { i = sr.length; sr.length = j; RETERR(isc_hex_totext(&sr, 1, "", target)); sr.length = i - j; } else RETERR(str_totext("-", target)); return (ISC_R_SUCCESS); }
static inline isc_result_t fromstruct_spf(ARGS_FROMSTRUCT) { dns_rdata_spf_t *txt = source; isc_region_t region; isc_uint8_t length; REQUIRE(type == 99); REQUIRE(source != NULL); REQUIRE(txt->common.rdtype == type); REQUIRE(txt->common.rdclass == rdclass); REQUIRE(txt->txt != NULL && txt->txt_len != 0); UNUSED(type); UNUSED(rdclass); region.base = txt->txt; region.length = txt->txt_len; while (region.length > 0) { length = uint8_fromregion(®ion); isc_region_consume(®ion, 1); if (region.length <= length) return (ISC_R_UNEXPECTEDEND); isc_region_consume(®ion, length); } return (mem_tobuffer(target, txt->txt, txt->txt_len)); }
static inline isc_result_t tostruct_cert(ARGS_TOSTRUCT) { dns_rdata_cert_t *cert = target; isc_region_t region; REQUIRE(rdata->type == 37); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); cert->common.rdclass = rdata->rdclass; cert->common.rdtype = rdata->type; ISC_LINK_INIT(&cert->common, link); dns_rdata_toregion(rdata, ®ion); cert->type = uint16_fromregion(®ion); isc_region_consume(®ion, 2); cert->key_tag = uint16_fromregion(®ion); isc_region_consume(®ion, 2); cert->algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); cert->length = region.length; cert->certificate = mem_maybedup(mctx, region.base, region.length); if (cert->certificate == NULL) return (ISC_R_NOMEMORY); cert->mctx = mctx; return (ISC_R_SUCCESS); }
static inline int casecompare_hip(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; dns_name_t name1; dns_name_t name2; int order; isc_uint8_t hit_len; isc_uint16_t key_len; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == 55); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); INSIST(r1.length > 4); INSIST(r2.length > 4); r1.length = 4; r2.length = 4; order = isc_region_compare(&r1, &r2); if (order != 0) return (order); hit_len = uint8_fromregion(&r1); isc_region_consume(&r1, 2); /* hit length + algorithm */ key_len = uint16_fromregion(&r1); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); isc_region_consume(&r1, 4); isc_region_consume(&r2, 4); INSIST(r1.length >= (unsigned) (hit_len + key_len)); INSIST(r2.length >= (unsigned) (hit_len + key_len)); order = isc_region_compare(&r1, &r2); if (order != 0) return (order); isc_region_consume(&r1, hit_len + key_len); isc_region_consume(&r2, hit_len + key_len); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); while (r1.length != 0 && r2.length != 0) { dns_name_fromregion(&name1, &r1); dns_name_fromregion(&name2, &r2); order = dns_name_rdatacompare(&name1, &name2); if (order != 0) return (order); isc_region_consume(&r1, name_length(&name1)); isc_region_consume(&r2, name_length(&name2)); } return (isc_region_compare(&r1, &r2)); }
static inline isc_result_t tostruct_isdn(ARGS_TOSTRUCT) { dns_rdata_isdn_t *isdn = target; isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_isdn); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); isdn->common.rdclass = rdata->rdclass; isdn->common.rdtype = rdata->type; ISC_LINK_INIT(&isdn->common, link); dns_rdata_toregion(rdata, &r); isdn->isdn_len = uint8_fromregion(&r); isc_region_consume(&r, 1); isdn->isdn = mem_maybedup(mctx, r.base, isdn->isdn_len); if (isdn->isdn == NULL) return (ISC_R_NOMEMORY); isc_region_consume(&r, isdn->isdn_len); if (r.length == 0) { isdn->subaddress_len = 0; isdn->subaddress = NULL; } else { isdn->subaddress_len = uint8_fromregion(&r); isc_region_consume(&r, 1); isdn->subaddress = mem_maybedup(mctx, r.base, isdn->subaddress_len); if (isdn->subaddress == NULL) goto cleanup; } isdn->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL && isdn->isdn != NULL) isc_mem_free(mctx, isdn->isdn); return (ISC_R_NOMEMORY); }
static inline isc_result_t tostruct_dnskey(ARGS_TOSTRUCT) { dns_rdata_dnskey_t *dnskey = target; isc_region_t sr; REQUIRE(rdata->type == 48); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); dnskey->common.rdclass = rdata->rdclass; dnskey->common.rdtype = rdata->type; ISC_LINK_INIT(&dnskey->common, link); dns_rdata_toregion(rdata, &sr); /* Flags */ if (sr.length < 2) return (ISC_R_UNEXPECTEDEND); dnskey->flags = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* Protocol */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); dnskey->protocol = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* Algorithm */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); dnskey->algorithm = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* Data */ dnskey->datalen = sr.length; dnskey->data = mem_maybedup(mctx, sr.base, dnskey->datalen); if (dnskey->data == NULL) return (ISC_R_NOMEMORY); dnskey->mctx = mctx; return (ISC_R_SUCCESS); }
static inline isc_result_t totext_sshfp(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("64000 ")]; unsigned int n; REQUIRE(rdata->type == 44); REQUIRE(rdata->length != 0); UNUSED(tctx); dns_rdata_toregion(rdata, &sr); /* * Algorithm. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Digest type. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u", n); RETERR(str_totext(buf, target)); /* * Digest. */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); RETERR(isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); }
static isc_result_t generic_txt_next(dns_rdata_txt_t *txt) { isc_region_t r; isc_uint8_t length; REQUIRE(txt != NULL); REQUIRE(txt->txt != NULL && txt->txt_len != 0); INSIST(txt->offset + 1 <= txt->txt_len); r.base = txt->txt + txt->offset; r.length = txt->txt_len - txt->offset; length = uint8_fromregion(&r); INSIST(txt->offset + 1 + length <= txt->txt_len); txt->offset = txt->offset + 1 + length; if (txt->offset == txt->txt_len) return (ISC_R_NOMORE); return (ISC_R_SUCCESS); }
static inline isc_result_t fromstruct_uri(ARGS_FROMSTRUCT) { dns_rdata_uri_t *uri = source; isc_region_t region; isc_uint8_t len; REQUIRE(type == 256); REQUIRE(source != NULL); REQUIRE(uri->common.rdtype == type); REQUIRE(uri->common.rdclass == rdclass); REQUIRE(uri->target != NULL && uri->tgt_len != 0); UNUSED(type); UNUSED(rdclass); /* * Priority */ RETERR(uint16_tobuffer(uri->priority, target)); /* * Weight */ RETERR(uint16_tobuffer(uri->weight, target)); /* * Target URI */ len = 255U; region.base = uri->target; region.length = uri->tgt_len; while (region.length > 0) { REQUIRE(len == 255U); len = uint8_fromregion(®ion); isc_region_consume(®ion, 1); if (region.length < len) return (ISC_R_UNEXPECTEDEND); isc_region_consume(®ion, len); } return (mem_tobuffer(target, uri->target, uri->tgt_len)); }
static isc_result_t generic_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string) { isc_region_t r; REQUIRE(txt != NULL); REQUIRE(string != NULL); REQUIRE(txt->txt != NULL); REQUIRE(txt->offset < txt->txt_len); INSIST(txt->offset + 1 <= txt->txt_len); r.base = txt->txt + txt->offset; r.length = txt->txt_len - txt->offset; string->length = uint8_fromregion(&r); isc_region_consume(&r, 1); string->data = r.base; INSIST(txt->offset + 1 + string->length <= txt->txt_len); return (ISC_R_SUCCESS); }
static inline isc_result_t fromwire_hip(ARGS_FROMWIRE) { isc_region_t region, rr; dns_name_t name; isc_uint8_t hit_len; isc_uint16_t key_len; REQUIRE(type == dns_rdatatype_hip); UNUSED(type); UNUSED(rdclass); isc_buffer_activeregion(source, ®ion); if (region.length < 4U) RETERR(DNS_R_FORMERR); rr = region; hit_len = uint8_fromregion(®ion); if (hit_len == 0) RETERR(DNS_R_FORMERR); isc_region_consume(®ion, 2); /* hit length + algorithm */ key_len = uint16_fromregion(®ion); if (key_len == 0) RETERR(DNS_R_FORMERR); isc_region_consume(®ion, 2); if (region.length < (unsigned) (hit_len + key_len)) RETERR(DNS_R_FORMERR); RETERR(mem_tobuffer(target, rr.base, 4 + hit_len + key_len)); isc_buffer_forward(source, 4 + hit_len + key_len); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); while (isc_buffer_activelength(source) > 0) { dns_name_init(&name, NULL); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); } return (ISC_R_SUCCESS); }
static inline isc_result_t tostruct_x25(ARGS_TOSTRUCT) { dns_rdata_x25_t *x25 = target; isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_x25); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); x25->common.rdclass = rdata->rdclass; x25->common.rdtype = rdata->type; ISC_LINK_INIT(&x25->common, link); dns_rdata_toregion(rdata, &r); x25->x25_len = uint8_fromregion(&r); isc_region_consume(&r, 1); x25->x25 = mem_maybedup(mctx, r.base, x25->x25_len); if (x25->x25 == NULL) return (ISC_R_NOMEMORY); x25->mctx = mctx; return (ISC_R_SUCCESS); }
static inline isc_result_t totext_ipseckey(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; char buf[sizeof("255 ")]; unsigned short num; unsigned short gateway; REQUIRE(rdata->type == 45); REQUIRE(rdata->length >= 3); dns_name_init(&name, NULL); if (rdata->data[1] > 3U) return (ISC_R_NOTIMPLEMENTED); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext("( ", target)); /* * Precedence. */ dns_rdata_toregion(rdata, ®ion); num = uint8_fromregion(®ion); isc_region_consume(®ion, 1); sprintf(buf, "%u ", num); RETERR(str_totext(buf, target)); /* * Gateway type. */ gateway = uint8_fromregion(®ion); isc_region_consume(®ion, 1); sprintf(buf, "%u ", gateway); RETERR(str_totext(buf, target)); /* * Algorithm. */ num = uint8_fromregion(®ion); isc_region_consume(®ion, 1); sprintf(buf, "%u ", num); RETERR(str_totext(buf, target)); /* * Gateway. */ switch (gateway) { case 0: RETERR(str_totext(".", target)); break; case 1: RETERR(inet_totext(AF_INET, ®ion, target)); isc_region_consume(®ion, 4); break; case 2: RETERR(inet_totext(AF_INET6, ®ion, target)); isc_region_consume(®ion, 16); break; case 3: dns_name_fromregion(&name, ®ion); RETERR(dns_name_totext(&name, ISC_FALSE, target)); isc_region_consume(®ion, name_length(&name)); break; } /* * Key. */ if (region.length > 0U) { RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(®ion, 60, "", target)); else RETERR(isc_base64_totext(®ion, tctx->width - 2, tctx->linebreak, target)); } if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); }
static inline isc_result_t fromwire_opt(ARGS_FROMWIRE) { isc_region_t sregion; isc_region_t tregion; isc_uint16_t opt; isc_uint16_t length; unsigned int total; REQUIRE(type == dns_rdatatype_opt); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sregion); total = 0; while (sregion.length != 0) { if (sregion.length < 4) return (ISC_R_UNEXPECTEDEND); opt = uint16_fromregion(&sregion); isc_region_consume(&sregion, 2); length = uint16_fromregion(&sregion); isc_region_consume(&sregion, 2); total += 4; if (sregion.length < length) return (ISC_R_UNEXPECTEDEND); switch (opt) { case DNS_OPT_CLIENT_SUBNET: { isc_uint16_t family; isc_uint8_t addrlen; isc_uint8_t scope; isc_uint8_t addrbytes; if (length < 4) return (DNS_R_OPTERR); family = uint16_fromregion(&sregion); isc_region_consume(&sregion, 2); addrlen = uint8_fromregion(&sregion); isc_region_consume(&sregion, 1); scope = uint8_fromregion(&sregion); isc_region_consume(&sregion, 1); if (addrlen == 0U && family != 0U) return (DNS_R_OPTERR); switch (family) { case 0: /* * XXXMUKS: In queries and replies, if * FAMILY is set to 0, SOURCE * PREFIX-LENGTH and SCOPE PREFIX-LENGTH * must be 0 and ADDRESS should not be * present as the address and prefix * lengths don't make sense because the * family is unknown. */ if (addrlen != 0U || scope != 0U) return (DNS_R_OPTERR); break; case 1: if (addrlen > 32U || scope > 32U) return (DNS_R_OPTERR); break; case 2: if (addrlen > 128U || scope > 128U) return (DNS_R_OPTERR); break; default: return (DNS_R_OPTERR); } addrbytes = (addrlen + 7) / 8; if (addrbytes + 4 != length) return (DNS_R_OPTERR); if (addrbytes != 0U && (addrlen % 8) != 0) { isc_uint8_t bits = ~0 << (8 - (addrlen % 8)); bits &= sregion.base[addrbytes - 1]; if (bits != sregion.base[addrbytes - 1]) return (DNS_R_OPTERR); } isc_region_consume(&sregion, addrbytes); break; } case DNS_OPT_EXPIRE: /* * Request has zero length. Response is 32 bits. */ if (length != 0 && length != 4) return (DNS_R_OPTERR); isc_region_consume(&sregion, length); break; case DNS_OPT_COOKIE: if (length != 8 && (length < 16 || length > 40)) return (DNS_R_OPTERR); isc_region_consume(&sregion, length); break; default: isc_region_consume(&sregion, length); break; } total += length; } isc_buffer_activeregion(source, &sregion); isc_buffer_availableregion(target, &tregion); if (tregion.length < total) return (ISC_R_NOSPACE); memmove(tregion.base, sregion.base, total); isc_buffer_forward(source, total); isc_buffer_add(target, total); return (ISC_R_SUCCESS); }
static inline isc_result_t tostruct_ipseckey(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_ipseckey_t *ipseckey = target; dns_name_t name; isc_uint32_t n; REQUIRE(rdata->type == 45); REQUIRE(target != NULL); REQUIRE(rdata->length >= 3); if (rdata->data[1] > 3U) return (ISC_R_NOTIMPLEMENTED); ipseckey->common.rdclass = rdata->rdclass; ipseckey->common.rdtype = rdata->type; ISC_LINK_INIT(&ipseckey->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); ipseckey->precedence = uint8_fromregion(®ion); isc_region_consume(®ion, 1); ipseckey->gateway_type = uint8_fromregion(®ion); isc_region_consume(®ion, 1); ipseckey->algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); switch (ipseckey->gateway_type) { case 0: break; case 1: n = uint32_fromregion(®ion); ipseckey->in_addr.s_addr = htonl(n); isc_region_consume(®ion, 4); break; case 2: memmove(ipseckey->in6_addr.s6_addr, region.base, 16); isc_region_consume(®ion, 16); break; case 3: dns_name_init(&ipseckey->gateway, NULL); dns_name_fromregion(&name, ®ion); RETERR(name_duporclone(&name, mctx, &ipseckey->gateway)); isc_region_consume(®ion, name_length(&name)); break; } ipseckey->keylength = region.length; if (ipseckey->keylength != 0U) { ipseckey->key = mem_maybedup(mctx, region.base, ipseckey->keylength); if (ipseckey->key == NULL) { if (ipseckey->gateway_type == 3) dns_name_free(&ipseckey->gateway, ipseckey->mctx); return (ISC_R_NOMEMORY); } } else ipseckey->key = NULL; ipseckey->mctx = mctx; return (ISC_R_SUCCESS); }
static inline isc_result_t totext_nsec3(ARGS_TOTEXT) { isc_region_t sr; unsigned int i, j; unsigned char hash; unsigned char flags; char buf[sizeof("TYPE65535")]; isc_uint32_t iterations; REQUIRE(rdata->type == dns_rdatatype_nsec3); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* Hash */ hash = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u ", hash); RETERR(str_totext(buf, target)); /* Flags */ flags = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u ", flags); RETERR(str_totext(buf, target)); /* Iterations */ iterations = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u ", iterations); RETERR(str_totext(buf, target)); /* Salt */ j = uint8_fromregion(&sr); isc_region_consume(&sr, 1); INSIST(j <= sr.length); if (j != 0) { i = sr.length; sr.length = j; RETERR(isc_hex_totext(&sr, 1, "", target)); sr.length = i - j; } else RETERR(str_totext("-", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); /* Next hash */ j = uint8_fromregion(&sr); isc_region_consume(&sr, 1); INSIST(j <= sr.length); i = sr.length; sr.length = j; RETERR(isc_base32hexnp_totext(&sr, 1, "", target)); sr.length = i - j; if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) == 0) RETERR(str_totext(" ", target)); RETERR(typemap_totext(&sr, tctx, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); }
static inline isc_result_t tostruct_naptr(ARGS_TOSTRUCT) { dns_rdata_naptr_t *naptr = target; isc_region_t r; isc_result_t result; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_naptr); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); naptr->common.rdclass = rdata->rdclass; naptr->common.rdtype = rdata->type; ISC_LINK_INIT(&naptr->common, link); naptr->flags = NULL; naptr->service = NULL; naptr->regexp = NULL; dns_rdata_toregion(rdata, &r); naptr->order = uint16_fromregion(&r); isc_region_consume(&r, 2); naptr->preference = uint16_fromregion(&r); isc_region_consume(&r, 2); naptr->flags_len = uint8_fromregion(&r); isc_region_consume(&r, 1); INSIST(naptr->flags_len <= r.length); naptr->flags = mem_maybedup(mctx, r.base, naptr->flags_len); if (naptr->flags == NULL) goto cleanup; isc_region_consume(&r, naptr->flags_len); naptr->service_len = uint8_fromregion(&r); isc_region_consume(&r, 1); INSIST(naptr->service_len <= r.length); naptr->service = mem_maybedup(mctx, r.base, naptr->service_len); if (naptr->service == NULL) goto cleanup; isc_region_consume(&r, naptr->service_len); naptr->regexp_len = uint8_fromregion(&r); isc_region_consume(&r, 1); INSIST(naptr->regexp_len <= r.length); naptr->regexp = mem_maybedup(mctx, r.base, naptr->regexp_len); if (naptr->regexp == NULL) goto cleanup; isc_region_consume(&r, naptr->regexp_len); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); dns_name_init(&naptr->replacement, NULL); result = name_duporclone(&name, mctx, &naptr->replacement); if (result != ISC_R_SUCCESS) goto cleanup; naptr->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL && naptr->flags != NULL) isc_mem_free(mctx, naptr->flags); if (mctx != NULL && naptr->service != NULL) isc_mem_free(mctx, naptr->service); if (mctx != NULL && naptr->regexp != NULL) isc_mem_free(mctx, naptr->regexp); return (ISC_R_NOMEMORY); }
static inline isc_result_t fromwire_opt(ARGS_FROMWIRE) { isc_region_t sregion; isc_region_t tregion; isc_uint16_t opt; isc_uint16_t length; unsigned int total; REQUIRE(type == 41); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sregion); total = 0; while (sregion.length != 0) { if (sregion.length < 4) return (ISC_R_UNEXPECTEDEND); opt = uint16_fromregion(&sregion); isc_region_consume(&sregion, 2); length = uint16_fromregion(&sregion); isc_region_consume(&sregion, 2); total += 4; if (sregion.length < length) return (ISC_R_UNEXPECTEDEND); switch (opt) { case DNS_OPT_CLIENT_SUBNET: { isc_uint16_t family; isc_uint8_t addrlen; isc_uint8_t scope; isc_uint8_t addrbytes; if (length < 4) return (DNS_R_FORMERR); family = uint16_fromregion(&sregion); isc_region_consume(&sregion, 2); addrlen = uint8_fromregion(&sregion); isc_region_consume(&sregion, 1); scope = uint8_fromregion(&sregion); isc_region_consume(&sregion, 1); switch (family) { case 1: if (addrlen > 32U || scope > 32U) return (DNS_R_FORMERR); break; case 2: if (addrlen > 128U || scope > 128U) return (DNS_R_FORMERR); break; } addrbytes = (addrlen + 7) / 8; if (addrbytes + 4 != length) return (DNS_R_FORMERR); isc_region_consume(&sregion, addrbytes); break; } case DNS_OPT_EXPIRE: /* * Request has zero length. Response is 32 bits. */ if (length != 0 && length != 4) return (DNS_R_FORMERR); isc_region_consume(&sregion, length); break; default: isc_region_consume(&sregion, length); break; } total += length; } isc_buffer_activeregion(source, &sregion); isc_buffer_availableregion(target, &tregion); if (tregion.length < total) return (ISC_R_NOSPACE); memmove(tregion.base, sregion.base, total); isc_buffer_forward(source, total); isc_buffer_add(target, total); return (ISC_R_SUCCESS); }
static inline isc_result_t tostruct_sig(ARGS_TOSTRUCT) { isc_region_t sr; dns_rdata_sig_t *sig = target; dns_name_t signer; REQUIRE(rdata->type == dns_rdatatype_sig); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); sig->common.rdclass = rdata->rdclass; sig->common.rdtype = rdata->type; ISC_LINK_INIT(&sig->common, link); dns_rdata_toregion(rdata, &sr); /* * Type covered. */ sig->covered = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Algorithm. */ sig->algorithm = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* * Labels. */ sig->labels = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* * Original TTL. */ sig->originalttl = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* * Expire time. */ sig->timeexpire = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* * Time signed. */ sig->timesigned = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* * Key ID. */ sig->keyid = uint16_fromregion(&sr); isc_region_consume(&sr, 2); dns_name_init(&signer, NULL); dns_name_fromregion(&signer, &sr); dns_name_init(&sig->signer, NULL); RETERR(name_duporclone(&signer, mctx, &sig->signer)); isc_region_consume(&sr, name_length(&sig->signer)); /* * Signature. */ sig->siglen = sr.length; sig->signature = mem_maybedup(mctx, sr.base, sig->siglen); if (sig->signature == NULL) goto cleanup; sig->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL) dns_name_free(&sig->signer, mctx); return (ISC_R_NOMEMORY); }
static inline isc_result_t totext_hip(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; unsigned int length, key_len, hit_len; unsigned char algorithm; char buf[sizeof("225 ")]; REQUIRE(rdata->type == dns_rdatatype_hip); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, ®ion); hit_len = uint8_fromregion(®ion); isc_region_consume(®ion, 1); algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); key_len = uint16_fromregion(®ion); isc_region_consume(®ion, 2); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext("( ", target)); /* * Algorithm */ sprintf(buf, "%u ", algorithm); RETERR(str_totext(buf, target)); /* * HIT. */ INSIST(hit_len < region.length); length = region.length; region.length = hit_len; RETERR(isc_hex_totext(®ion, 1, "", target)); region.length = length - hit_len; RETERR(str_totext(tctx->linebreak, target)); /* * Public KEY. */ INSIST(key_len <= region.length); length = region.length; region.length = key_len; RETERR(isc_base64_totext(®ion, 1, "", target)); region.length = length - key_len; RETERR(str_totext(tctx->linebreak, target)); /* * Rendezvous Servers. */ dns_name_init(&name, NULL); while (region.length > 0) { dns_name_fromregion(&name, ®ion); RETERR(dns_name_totext(&name, ISC_FALSE, target)); isc_region_consume(®ion, name.length); if (region.length > 0) RETERR(str_totext(tctx->linebreak, target)); } if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); }