static inline isc_result_t fromwire_x25(ARGS_FROMWIRE) { isc_region_t sr; REQUIRE(type == 19); UNUSED(type); UNUSED(dctx); UNUSED(rdclass); UNUSED(options); isc_buffer_activeregion(source, &sr); if (sr.length < 5) return (DNS_R_FORMERR); return (txt_fromwire(source, target)); }
static inline isc_result_t fromwire_l64(ARGS_FROMWIRE) { isc_region_t sregion; REQUIRE(type == 106); UNUSED(type); UNUSED(options); UNUSED(rdclass); UNUSED(dctx); isc_buffer_activeregion(source, &sregion); if (sregion.length != 10) return (DNS_R_FORMERR); isc_buffer_forward(source, sregion.length); return (mem_tobuffer(target, sregion.base, sregion.length)); }
static inline isc_result_t generic_fromwire_ds(ARGS_FROMWIRE) { isc_region_t sr; UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); /* * Check digest lengths if we know them. */ if (sr.length < 4 || (sr.base[3] == DNS_DSDIGEST_SHA1 && sr.length < 4 + ISC_SHA1_DIGESTLENGTH) || (sr.base[3] == DNS_DSDIGEST_SHA256 && sr.length < 4 + ISC_SHA256_DIGESTLENGTH) || #ifdef ISC_GOST_DIGESTLENGTH (sr.base[3] == DNS_DSDIGEST_GOST && sr.length < 4 + ISC_GOST_DIGESTLENGTH) || #endif (sr.base[3] == DNS_DSDIGEST_SHA384 && sr.length < 4 + ISC_SHA384_DIGESTLENGTH)) return (ISC_R_UNEXPECTEDEND); /* * Only copy digest lengths if we know them. * If there is extra data dns_rdata_fromwire() will * detect that. */ if (sr.base[3] == DNS_DSDIGEST_SHA1) sr.length = 4 + ISC_SHA1_DIGESTLENGTH; else if (sr.base[3] == DNS_DSDIGEST_SHA256) sr.length = 4 + ISC_SHA256_DIGESTLENGTH; #ifdef ISC_GOST_DIGESTLENGTH else if (sr.base[3] == DNS_DSDIGEST_GOST) sr.length = 4 + ISC_GOST_DIGESTLENGTH; #endif else if (sr.base[3] == DNS_DSDIGEST_SHA384) sr.length = 4 + ISC_SHA384_DIGESTLENGTH; isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); }
static inline isc_result_t fromwire_naptr(ARGS_FROMWIRE) { dns_name_t name; isc_region_t sr; unsigned char *regex; REQUIRE(type == dns_rdatatype_naptr); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&name, NULL); /* * Order, preference. */ isc_buffer_activeregion(source, &sr); if (sr.length < 4) return (ISC_R_UNEXPECTEDEND); RETERR(mem_tobuffer(target, sr.base, 4)); isc_buffer_forward(source, 4); /* * Flags. */ RETERR(txt_fromwire(source, target)); /* * Service. */ RETERR(txt_fromwire(source, target)); /* * Regexp. */ regex = isc_buffer_used(target); RETERR(txt_fromwire(source, target)); RETERR(txt_valid_regex(regex)); /* * Replacement. */ return (dns_name_fromwire(&name, source, dctx, options, target)); }
static inline isc_result_t fromwire_keydata(ARGS_FROMWIRE) { isc_region_t sr; REQUIRE(type == 65533); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); if (sr.length < 16) return (ISC_R_UNEXPECTEDEND); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); }
static inline isc_result_t fromwire_caa(ARGS_FROMWIRE) { isc_region_t sr; unsigned int len, i; REQUIRE(type == 257); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); /* * Flags */ isc_buffer_activeregion(source, &sr); if (sr.length < 2) return (ISC_R_UNEXPECTEDEND); /* * Flags, tag length */ RETERR(mem_tobuffer(target, sr.base, 2)); len = sr.base[1]; isc_region_consume(&sr, 2); isc_buffer_forward(source, 2); /* * Zero length tag fields are illegal. */ if (sr.length < len || len == 0) RETERR(DNS_R_FORMERR); /* Check the Tag's value */ for (i = 0; i < len; i++) if (!alphanumeric[sr.base[i]]) RETERR(DNS_R_FORMERR); /* * Tag + Value */ isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); }
static inline isc_result_t fromwire_openpgpkey(ARGS_FROMWIRE) { isc_region_t sr; REQUIRE(type == dns_rdatatype_openpgpkey); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); /* * Keyring. */ isc_buffer_activeregion(source, &sr); if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); }
static inline isc_result_t fromwire_in_nsap(ARGS_FROMWIRE) { isc_region_t region; REQUIRE(type == 22); REQUIRE(rdclass == 1); UNUSED(type); UNUSED(dctx); UNUSED(options); UNUSED(rdclass); isc_buffer_activeregion(source, ®ion); if (region.length < 1) return (ISC_R_UNEXPECTEDEND); RETERR(mem_tobuffer(target, region.base, region.length)); isc_buffer_forward(source, region.length); return (ISC_R_SUCCESS); }
static inline isc_result_t fromwire_lp(ARGS_FROMWIRE) { dns_name_t name; isc_region_t sregion; REQUIRE(type == dns_rdatatype_lp); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, NULL); isc_buffer_activeregion(source, &sregion); if (sregion.length < 2) return (ISC_R_UNEXPECTEDEND); RETERR(mem_tobuffer(target, sregion.base, 2)); isc_buffer_forward(source, 2); return (dns_name_fromwire(&name, source, dctx, options, target)); }
static inline isc_result_t fromwire_nsec3(ARGS_FROMWIRE) { isc_region_t sr, rr; unsigned int saltlen, hashlen; REQUIRE(type == dns_rdatatype_nsec3); UNUSED(type); UNUSED(rdclass); UNUSED(options); UNUSED(dctx); isc_buffer_activeregion(source, &sr); rr = sr; /* hash(1), flags(1), iteration(2), saltlen(1) */ if (sr.length < 5U) RETERR(DNS_R_FORMERR); saltlen = sr.base[4]; isc_region_consume(&sr, 5); if (sr.length < saltlen) RETERR(DNS_R_FORMERR); isc_region_consume(&sr, saltlen); if (sr.length < 1U) RETERR(DNS_R_FORMERR); hashlen = sr.base[0]; isc_region_consume(&sr, 1); if (sr.length < hashlen) RETERR(DNS_R_FORMERR); isc_region_consume(&sr, hashlen); RETERR(typemap_test(&sr, ISC_TRUE)); RETERR(mem_tobuffer(target, rr.base, rr.length)); isc_buffer_forward(source, rr.length); 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 fromwire_uri(ARGS_FROMWIRE) { isc_region_t region; REQUIRE(type == 256); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); /* * Priority, weight */ isc_buffer_activeregion(source, ®ion); if (region.length < 4) return (ISC_R_UNEXPECTEDEND); /* * Priority, weight and target URI */ isc_buffer_forward(source, region.length); return (mem_tobuffer(target, region.base, region.length)); }
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 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); }