Beispiel #1
0
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));
}
Beispiel #2
0
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));
}
Beispiel #3
0
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));
}
Beispiel #4
0
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));
}
Beispiel #5
0
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));
}
Beispiel #6
0
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));
}
Beispiel #7
0
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, &region);
	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);
}
Beispiel #9
0
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));
}
Beispiel #10
0
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);
}
Beispiel #11
0
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, &region);
	if (region.length < 4U)
		RETERR(DNS_R_FORMERR);

	rr = region;
	hit_len = uint8_fromregion(&region);
	if (hit_len == 0)
		RETERR(DNS_R_FORMERR);
	isc_region_consume(&region, 2);  	/* hit length + algorithm */
	key_len = uint16_fromregion(&region);
	if (key_len == 0)
		RETERR(DNS_R_FORMERR);
	isc_region_consume(&region, 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);
}
Beispiel #12
0
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, &region);
	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));
}
Beispiel #13
0
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);
}
Beispiel #14
0
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);
}