rdata.c revision e4653123ecc6cdbfc0b9eda6e98e44af3b1f9a08
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews/*
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Copyright (C) 1998 Internet Software Consortium.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Permission to use, copy, modify, and distribute this software for any
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * purpose with or without fee is hereby granted, provided that the above
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * copyright notice and this permission notice appear in all copies.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * SOFTWARE.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
e4653123ecc6cdbfc0b9eda6e98e44af3b1f9a08Mark Andrews /* $Id: rdata.c,v 1.28 1999/02/05 06:41:20 marka Exp $ */
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff#include <config.h>
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff#include <stdio.h>
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews#include <time.h>
3761c433912beabe43abeed2c3513b6201c59f64Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <isc/buffer.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <isc/lex.h>
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff#include <isc/assertions.h>
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <dns/types.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <dns/result.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <dns/rdata.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <dns/region.h>
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews#include <dns/rdataclass.h>
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews#include <dns/rdatatype.h>
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews#include <dns/rcode.h>
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews#include <dns/cert.h>
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews#include <dns/secalg.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
eb6bd543c7d072efdca509eb17f8f301c1467b53Mark Andrews#define RETERR(x) do { \
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews dns_result_t __r = (x); \
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews if (__r != DNS_R_SUCCESS) \
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews return (__r); \
eb6bd543c7d072efdca509eb17f8f301c1467b53Mark Andrews } while (0)
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic dns_result_t txt_totext(isc_region_t *source, isc_buffer_t *target);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic dns_result_t txt_fromtext(isc_textregion_t *source,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t *target);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic dns_result_t txt_fromwire(isc_buffer_t *source,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t *target);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic isc_boolean_t name_prefix(dns_name_t *name, dns_name_t *origin,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_name_t *target);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic unsigned int name_length(dns_name_t *name);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic dns_result_t str_totext(char *source, isc_buffer_t *target);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic isc_boolean_t buffer_empty(isc_buffer_t *source);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic void buffer_fromregion(isc_buffer_t *buffer,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_region_t *region,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned int type);
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrewsstatic dns_result_t uint32_tobuffer(isc_uint32_t,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t *target);
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrewsstatic dns_result_t uint16_tobuffer(isc_uint32_t,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t *target);
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrewsstatic isc_uint32_t uint32_fromregion(isc_region_t *region);
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrewsstatic isc_uint16_t uint16_fromregion(isc_region_t *region);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrewsstatic dns_result_t gettoken(isc_lex_t *lexer, isc_token_t *token,
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews isc_tokentype_t expect, isc_boolean_t eol);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrewsstatic dns_result_t mem_tobuffer(isc_buffer_t *target, void *base,
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews unsigned int length);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrewsstatic int compare_region(isc_region_t *r1, isc_region_t *r2);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic int hexvalue(char value);
8a17d1e7cdba9fdcf71fb2f821a954a251204105Mark Andrewsstatic int decvalue(char value);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic dns_result_t base64_totext(isc_region_t *source,
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews isc_buffer_t *target);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic dns_result_t base64_tobuffer(isc_lex_t *lexer,
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews isc_buffer_t *target,
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews int length);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic dns_result_t time_totext(unsigned long value,
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews isc_buffer_t *target);
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrewsstatic dns_result_t time_tobuffer(char *source, isc_buffer_t *target);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsstatic dns_result_t btoa_totext(unsigned char *inbuf, int inbuflen,
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews isc_buffer_t *target);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsstatic dns_result_t atob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic const char hexdigits[] = "0123456789abcdef";
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic const char decdigits[] = "0123456789";
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic const char octdigits[] = "01234567";
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include "code.h"
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews#define META 0x0001
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews#define RESERVED 0x0002
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews#define METATYPES \
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews { 0, "NONE", META }, \
fcf8db89e6c5740822838380c3a4ffcfb7754992Mark Andrews { 31, "EID", RESERVED }, \
fcf8db89e6c5740822838380c3a4ffcfb7754992Mark Andrews { 32, "NIMLOC", RESERVED }, \
06a49674418e8a74e879b63ea4ce4cb2261bbc70Mark Andrews { 34, "ATMA", RESERVED }, \
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews { 100, "UINFO", RESERVED }, \
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews { 101, "UID", RESERVED }, \
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews { 102, "GID", RESERVED }, \
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews { 249, "TKEY", META }, \
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews { 250, "TSIG", META }, \
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews { 251, "IXFR", META }, \
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews { 252, "AXFR", META }, \
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews { 253, "MAILB", META }, \
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews { 254, "MAILA", META }, \
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews { 255, "ANY", META },
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews#define METACLASSES \
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews { 0, "NONE", META }, \
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews { 255, "ANY", META },
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews#define RCODENAMES \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews /* standard rcodes */ \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews { dns_rcode_noerror, "NOERROR", 0}, \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews { dns_rcode_formerr, "FORMERR", 0}, \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews { dns_rcode_servfail, "SERVFAIL", 0}, \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews { dns_rcode_nxdomain, "NXDOMAIN", 0}, \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews { dns_rcode_notimp, "NOTIMP", 0}, \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews { dns_rcode_refused, "REFUSED", 0}, \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews { dns_rcode_yxdomain, "YXDOMAIN", 0}, \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews { dns_rcode_yxrrset, "YXRRSET", 0}, \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews { dns_rcode_nxrrset, "NXRRSET", 0}, \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews { dns_rcode_notauth, "NOTAUTH", 0}, \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews { dns_rcode_notzone, "NOTZONE", 0}, \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews /* extended rcodes */ \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews { dns_rcode_badsig, "BADSIG", 0}, \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews { dns_rcode_badkey, "BADKEY", 0}, \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews { dns_rcode_badtime, "BADTIME", 0}, \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews { dns_rcode_badmode, "BADMODE", 0}, \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews { 0, NULL, 0 }
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews#define CERTNAMES \
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews { 1, "SKIX", 0}, \
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews { 2, "SPKI", 0}, \
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews { 3, "PGP", 0}, \
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews { 253, "URI", 0}, \
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews { 254, "OID", 0}, \
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews { 0, NULL, 0}
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews#define SECALGNAMES \
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews { 1, "RSA/MD5", 0}, \
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews { 2, "Diffie-Hellman", 0}, \
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews { 3, "DSA", 0}, \
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews { 4, "Ellyptic-Curve", 0}, \
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews { 253, "Private/Domain", 0}, \
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews { 254, "Private/OID", 0}, \
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews { 0, NULL, 0}
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrewsstruct tbl {
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews unsigned int value;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews char *name;
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews int flags;
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews} types[] = { TYPENAMES METATYPES {0, NULL, 0} },
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrewsclasses[] = { CLASSNAMES METACLASSES { 0, NULL, 0} },
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsrcodes[] = { RCODENAMES },
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewscerts[] = { CERTNAMES },
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewssecalgs[] = { SECALGNAMES };
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews/***
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *** Initialization
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ***/
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsvoid
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_rdata_init(dns_rdata_t *rdata) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(rdata != NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rdata->data = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rdata->length = 0;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rdata->class = 0;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rdata->type = 0;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ISC_LINK_INIT(rdata, link);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* ISC_LIST_INIT(rdata->list); */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews/***
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *** Comparisons
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ***/
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsint
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_rdata_compare(dns_rdata_t *rdata1, dns_rdata_t *rdata2) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews int result = 0;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews isc_boolean_t use_default = ISC_FALSE;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(rdata1 != NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(rdata2 != NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(rdata1->data != NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(rdata2->data != NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rdata1->class != rdata2->class)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (rdata1->class < rdata2->class ? -1 : 1);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rdata1->type != rdata2->type)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (rdata1->type < rdata2->type ? -1 : 1);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews COMPARESWITCH
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (use_default) {
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews isc_region_t r1;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews isc_region_t r2;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews dns_rdata_toregion(rdata1, &r1);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews dns_rdata_toregion(rdata2, &r2);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews result = compare_region(&r1, &r2);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (result);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews/***
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *** Conversions
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ***/
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsvoid
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_rdata_fromregion(dns_rdata_t *rdata,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdataclass_t class, dns_rdatatype_t type,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_region_t *r) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rdata->data = r->base;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rdata->length = r->length;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rdata->class = class;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rdata->type = type;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsvoid
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_rdata_toregion(dns_rdata_t *rdata, isc_region_t *r) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews r->base = rdata->data;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews r->length = rdata->length;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_rdata_fromwire(dns_rdata_t *rdata,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdataclass_t class, dns_rdatatype_t type,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t *source,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_decompress_t *dctx,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_boolean_t downcase,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t *target) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews dns_result_t result = DNS_R_NOTIMPLEMENTED;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_region_t region;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t ss;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t st;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews isc_boolean_t use_default = ISC_FALSE;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ss = *source;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews st = *target;
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff region.base = (unsigned char *)(target->base) + target->used;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews FROMWIRESWITCH
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (use_default)
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews (void)NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* We should have consumed all out buffer */
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (result == DNS_R_SUCCESS && !buffer_empty(source))
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews result = DNS_R_EXTRADATA;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rdata && result == DNS_R_SUCCESS) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews region.length = target->used - st.used;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_fromregion(rdata, class, type, &region);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (result != DNS_R_SUCCESS) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *source = ss;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *target = st;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (result);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t *target) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews dns_result_t result = DNS_R_NOTIMPLEMENTED;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews isc_boolean_t use_default = ISC_FALSE;
f0a5bb8f86631ce638cb2b6c65bbb9bcf9b0cdc0Bob Halley isc_region_t tr;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews TOWIRESWITCH
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (use_default) {
f0a5bb8f86631ce638cb2b6c65bbb9bcf9b0cdc0Bob Halley isc_buffer_available(target, &tr);
f0a5bb8f86631ce638cb2b6c65bbb9bcf9b0cdc0Bob Halley if (tr.length < rdata->length)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_NOSPACE);
f0a5bb8f86631ce638cb2b6c65bbb9bcf9b0cdc0Bob Halley memcpy(tr.base, rdata->data, rdata->length);
f0a5bb8f86631ce638cb2b6c65bbb9bcf9b0cdc0Bob Halley isc_buffer_add(target, rdata->length);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_SUCCESS);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (result);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_rdata_fromtext(dns_rdata_t *rdata,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdataclass_t class, dns_rdatatype_t type,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_lex_t *lexer, dns_name_t *origin,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_boolean_t downcase,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t *target) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews dns_result_t result = DNS_R_NOTIMPLEMENTED;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_region_t region;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t st;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews isc_boolean_t use_default = ISC_FALSE;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews isc_token_t token;
f305d86668bfd4d4727c3e0f70e7e97a2fa1b772Bob Halley unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF |
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews ISC_LEXOPT_DNSMULTILINE;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews st = *target;
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff region.base = (unsigned char *)(target->base) + target->used;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews FROMTEXTSWITCH
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (use_default)
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews (void)NULL;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews /*
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews * Consume to end of line / file.
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews * If not at end of line initially set error code.
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews */
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews do {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (isc_lex_gettoken(lexer, options, &token)
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews != ISC_R_SUCCESS) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (result == DNS_R_SUCCESS)
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews result = DNS_R_UNEXPECTED;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews break;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews } else if (token.type != isc_tokentype_eol &&
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews token.type != isc_tokentype_eof) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (result == DNS_R_SUCCESS)
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews result = DNS_R_EXTRATOKEN;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews } else
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews break;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews } while (1);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rdata != NULL && result == DNS_R_SUCCESS) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews region.length = target->used - st.used;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_fromregion(rdata, class, type, &region);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (result != DNS_R_SUCCESS) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *target = st;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (result);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_rdata_totext(dns_rdata_t *rdata, isc_buffer_t *target) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews dns_result_t result = DNS_R_NOTIMPLEMENTED;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_name_t *origin = NULL;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews isc_boolean_t use_default = ISC_FALSE;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews TOTEXTSWITCH
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (use_default)
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews (void)NULL;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (result);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_rdata_fromstruct(dns_rdata_t *rdata,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdataclass_t class, dns_rdatatype_t type,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews void *source,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t *target) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews dns_result_t result = DNS_R_NOTIMPLEMENTED;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t st;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_region_t region;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews isc_boolean_t use_default = ISC_FALSE;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff region.base = (unsigned char *)(target->base) + target->used;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews st = *target;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews FROMSTRUCTSWITCH
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (use_default)
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews (void)NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rdata != NULL && result == DNS_R_SUCCESS) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews region.length = target->used - st.used;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_fromregion(rdata, class, type, &region);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (result != DNS_R_SUCCESS)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *target = st;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (result);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_rdata_tostruct(dns_rdata_t *rdata, void *target) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews dns_result_t result = DNS_R_NOTIMPLEMENTED;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews isc_boolean_t use_default = ISC_FALSE;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews TOSTRUCTSWITCH
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (use_default)
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews (void)NULL;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (result);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrewsdns_result_t
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrewsdns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews int i = 0;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews unsigned int n;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews while (classes[i].name != NULL) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews n = strlen(classes[i].name);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews if (n == source->length &&
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews strncasecmp(source->base, classes[i].name, n) == 0) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews *classp = classes[i].value;
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews if ((classes[i].flags & RESERVED) != 0)
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews return (DNS_R_NOTIMPLEMENTED);
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews return (DNS_R_SUCCESS);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews i++;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews return (DNS_R_UNKNOWN);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews}
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrewsdns_result_t
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrewsdns_rdataclass_totext(dns_rdataclass_t class, isc_buffer_t *target) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews int i = 0;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews char buf[sizeof "65000"];
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews while (classes[i].name != NULL) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews if (classes[i].value == class) {
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews return (str_totext(classes[i].name, target));
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews i++;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews sprintf(buf, "%u", class);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews return (str_totext(buf, target));
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews}
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrewsdns_result_t
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrewsdns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews int i = 0;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews unsigned int n;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews while (types[i].name != NULL) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews n = strlen(types[i].name);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews if (n == source->length &&
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews strncasecmp(source->base, types[i].name, n) == 0) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews *typep = types[i].value;
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews if ((types[i].flags & RESERVED) != 0)
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews return (DNS_R_NOTIMPLEMENTED);
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews return (DNS_R_SUCCESS);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews i++;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews return (DNS_R_UNKNOWN);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews}
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrewsdns_result_t
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrewsdns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews int i = 0;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews char buf[sizeof "65000"];
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews while (types[i].name != NULL) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews if (types[i].value == type) {
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews return (str_totext(types[i].name, target));
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews }
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews i++;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews }
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews sprintf(buf, "%u", type);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews return (str_totext(buf, target));
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews}
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrewsdns_result_t
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrewsdns_rcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source) {
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews int i = 0;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews unsigned int n;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews while (rcodes[i].name != NULL) {
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews n = strlen(rcodes[i].name);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews if (n == source->length &&
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews strncasecmp(source->base, rcodes[i].name, n) == 0) {
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews *rcodep = rcodes[i].value;
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews return (DNS_R_SUCCESS);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews i++;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews return (DNS_R_UNKNOWN);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews}
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrewsdns_result_t
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrewsdns_rcode_totext(dns_rcode_t rcode, isc_buffer_t *target) {
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews int i = 0;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews char buf[sizeof "65000"];
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews while (rcodes[i].name != NULL) {
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews if (rcodes[i].value == rcode) {
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews return (str_totext(rcodes[i].name, target));
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews }
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews i++;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews }
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews sprintf(buf, "%u", rcode);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews return (str_totext(buf, target));
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews}
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsdns_result_t
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsdns_cert_fromtext(dns_cert_t *certp, isc_textregion_t *source) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews int i = 0;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews unsigned int n;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews while (certs[i].name != NULL) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews n = strlen(certs[i].name);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews if (n == source->length &&
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews strncasecmp(source->base, certs[i].name, n) == 0) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews *certp = certs[i].value;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews return (DNS_R_SUCCESS);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews }
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews i++;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews }
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews return (DNS_R_UNKNOWN);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews}
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsdns_result_t
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsdns_cert_totext(dns_cert_t cert, isc_buffer_t *target) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews int i = 0;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews char buf[sizeof "65000"];
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews while (certs[i].name != NULL) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews if (certs[i].value == cert) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews return (str_totext(certs[i].name, target));
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews }
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews i++;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews }
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews sprintf(buf, "%u", cert);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews return (str_totext(buf, target));
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews}
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsdns_result_t
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsdns_secalg_fromtext(dns_secalg_t *secalgp, isc_textregion_t *source) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews int i = 0;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews unsigned int n;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews while (secalgs[i].name != NULL) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews n = strlen(secalgs[i].name);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews if (n == source->length &&
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews strncasecmp(source->base, secalgs[i].name, n) == 0) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews *secalgp = secalgs[i].value;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews return (DNS_R_SUCCESS);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews }
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews i++;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews }
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews return (DNS_R_UNKNOWN);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews}
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsdns_result_t
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsdns_secalg_totext(dns_secalg_t secalg, isc_buffer_t *target) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews int i = 0;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews char buf[sizeof "65000"];
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews while (secalgs[i].name != NULL) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews if (secalgs[i].value == secalg) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews return (str_totext(secalgs[i].name, target));
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews }
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews i++;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews }
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews sprintf(buf, "%u", secalg);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews return (str_totext(buf, target));
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews}
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews /* Private function */
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic unsigned int
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsname_length(dns_name_t *name) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (name->length);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic dns_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewstxt_totext(isc_region_t *source, isc_buffer_t *target) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned int tl;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned int n;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned char *sp;
fe47f41b13620bfafc4f8cf65d5df24f1e568764Bob Halley char *tp;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_region_t region;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_available(target, &region);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews sp = source->base;
fe47f41b13620bfafc4f8cf65d5df24f1e568764Bob Halley tp = (char *)region.base;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tl = region.length;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews n = *sp++;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews INSIST(n + 1 <= source->length);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (tl < 1)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_NOSPACE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *tp++ = '"';
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tl--;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews while (n--) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (*sp < 0x20 || *sp > 0x7f) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (tl < 4)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_NOSPACE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews sprintf(tp, "\\%03u", *sp++);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tp += 4;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tl -= 4;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews continue;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (tl < 2)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_NOSPACE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *tp++ = '\\';
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tl--;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (tl < 1)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_NOSPACE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *tp++ = *sp++;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tl--;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (tl < 1)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_NOSPACE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *tp++ = '"';
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tl--;
fe47f41b13620bfafc4f8cf65d5df24f1e568764Bob Halley isc_buffer_add(target, tp - (char *)region.base);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_region_consume(source, *source->base + 1);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_SUCCESS);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic dns_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewstxt_fromtext(isc_textregion_t *source, isc_buffer_t *target) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_region_t tregion;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_available(target, &tregion);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (tregion.length < source->length + 1)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_NOSPACE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (source->length > 255)
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews return (DNS_R_TEXTTOLONG);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *tregion.base = source->length;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews memcpy(tregion.base + 1, source->base, source->length);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_add(target, source->length + 1);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_SUCCESS);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic dns_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewstxt_fromwire(isc_buffer_t *source, isc_buffer_t *target) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned int n;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_region_t sregion;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_region_t tregion;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
26b0f58b6c4d65bc8b131debf40b8c376c2978bfBob Halley isc_buffer_active(source, &sregion);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (sregion.length == 0)
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews return(DNS_R_UNEXPECTEDEND);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews n = *sregion.base + 1;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (n > sregion.length)
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews return (DNS_R_UNEXPECTEDEND);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_available(target, &tregion);
bfb2a81b65579882a80855c279cedc45aebd62e8Mark Andrews if (n > tregion.length)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_NOSPACE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews memcpy(tregion.base, sregion.base, n);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_forward(source, n);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_add(target, n);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_SUCCESS);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic isc_boolean_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsname_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews int l1, l2;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (origin == NULL)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews goto return_false;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (dns_name_compare(origin, dns_rootname) == 0)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews goto return_false;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (!dns_name_issubdomain(name, origin))
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews goto return_false;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews l1 = dns_name_countlabels(name);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews l2 = dns_name_countlabels(origin);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (l1 == l2)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews goto return_false;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_name_getlabelsequence(name, 0, l1 - l2, target);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_TRUE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsreturn_false:
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *target = *name;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_FALSE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic dns_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstr_totext(char *source, isc_buffer_t *target) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned int l;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_region_t region;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_available(target, &region);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews l = strlen(source);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (l > region.length)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_NOSPACE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews memcpy(region.base, source, l);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_add(target, l);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_SUCCESS);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic isc_boolean_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsbuffer_empty(isc_buffer_t *source) {
26b0f58b6c4d65bc8b131debf40b8c376c2978bfBob Halley return((source->current == source->active) ? ISC_TRUE : ISC_FALSE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic void
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsbuffer_fromregion(isc_buffer_t *buffer, isc_region_t *region,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned int type) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_init(buffer, region->base, region->length, type);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_add(buffer, region->length);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews isc_buffer_setactive(buffer, region->length);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic dns_result_t
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrewsuint32_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_region_t region;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_available(target, &region);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (region.length < 4)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_NOSPACE);
e4653123ecc6cdbfc0b9eda6e98e44af3b1f9a08Mark Andrews isc_buffer_putuint32(target, value);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_SUCCESS);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic dns_result_t
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrewsuint16_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_region_t region;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
1c3191528684f3dd93ebb122298c2f8ebfc6d397Mark Andrews if (value > 0xffff)
1c3191528684f3dd93ebb122298c2f8ebfc6d397Mark Andrews return (DNS_R_RANGE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_available(target, &region);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (region.length < 2)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_NOSPACE);
e4653123ecc6cdbfc0b9eda6e98e44af3b1f9a08Mark Andrews isc_buffer_putuint16(target, value);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DNS_R_SUCCESS);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrewsstatic isc_uint32_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsuint32_fromregion(isc_region_t *region) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned long value;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews INSIST(region->length >= 4);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews value = region->base[0] << 24;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews value |= region->base[1] << 16;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews value |= region->base[2] << 8;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews value |= region->base[3];
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return(value);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrewsstatic isc_uint16_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsuint16_fromregion(isc_region_t *region) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews INSIST(region->length >= 2);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return ((region->base[0] << 8) | region->base[1]);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrewsstatic dns_result_t
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrewsgettoken(isc_lex_t *lexer, isc_token_t *token, isc_tokentype_t expect,
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews isc_boolean_t eol) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF |
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews ISC_LEXOPT_DNSMULTILINE;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews
2192b4497348ccab94ca6f3f779cec399c72a8efMark Andrews if (expect == isc_tokentype_qstring)
2192b4497348ccab94ca6f3f779cec399c72a8efMark Andrews options |= ISC_LEXOPT_QSTRING;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews if (expect == isc_tokentype_number)
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews options |= ISC_LEXOPT_NUMBER;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews if (isc_lex_gettoken(lexer, options, token) != ISC_R_SUCCESS)
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews return (DNS_R_UNEXPECTED);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews if (eol && ((token->type == isc_tokentype_eol) ||
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews (token->type == isc_tokentype_eof)))
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews return (DNS_R_SUCCESS);
2192b4497348ccab94ca6f3f779cec399c72a8efMark Andrews if (token->type == isc_tokentype_string &&
2192b4497348ccab94ca6f3f779cec399c72a8efMark Andrews expect == isc_tokentype_qstring)
2192b4497348ccab94ca6f3f779cec399c72a8efMark Andrews return (DNS_R_SUCCESS);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews if (token->type != expect) {
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews isc_lex_ungettoken(lexer, token);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews if (token->type == isc_tokentype_eol ||
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews token->type == isc_tokentype_eof)
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews return(DNS_R_UNEXPECTEDEND);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews return (DNS_R_UNEXPECTED);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews }
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews return (DNS_R_SUCCESS);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews}
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrewsstatic dns_result_t
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrewsmem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) {
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews isc_region_t tr;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews isc_buffer_available(target, &tr);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews if (length > tr.length)
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews return (DNS_R_NOSPACE);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews memcpy(tr.base, base, length);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews isc_buffer_add(target, length);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews return (DNS_R_SUCCESS);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews}
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrewsstatic int
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrewscompare_region(isc_region_t *r1, isc_region_t *r2) {
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews unsigned int l;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews int result;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews l = (r1->length < r2->length) ? r1->length : r2->length;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews if ((result = memcmp(r1->base, r2->base, l)) != 0)
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews return ((result < 0) ? -1 : 1);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews else
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews return ((r1->length == r2->length) ? 0 :
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews (r1->length < r2->length) ? -1 : 1);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews}
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic int
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewshexvalue(char value) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews char *s;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (!isascii(value&0xff))
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (-1);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (isupper(value))
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews value = tolower(value);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if ((s = strchr(hexdigits, value)) == NULL)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (-1);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (s - hexdigits);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews}
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
8a17d1e7cdba9fdcf71fb2f821a954a251204105Mark Andrewsstatic int
8a17d1e7cdba9fdcf71fb2f821a954a251204105Mark Andrewsdecvalue(char value) {
8a17d1e7cdba9fdcf71fb2f821a954a251204105Mark Andrews char *s;
8a17d1e7cdba9fdcf71fb2f821a954a251204105Mark Andrews if (!isascii(value&0xff))
8a17d1e7cdba9fdcf71fb2f821a954a251204105Mark Andrews return (-1);
8a17d1e7cdba9fdcf71fb2f821a954a251204105Mark Andrews if ((s = strchr(decdigits, value)) == NULL)
8a17d1e7cdba9fdcf71fb2f821a954a251204105Mark Andrews return (-1);
8a17d1e7cdba9fdcf71fb2f821a954a251204105Mark Andrews return (s - decdigits);
8a17d1e7cdba9fdcf71fb2f821a954a251204105Mark Andrews}
8a17d1e7cdba9fdcf71fb2f821a954a251204105Mark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic const char base64[] =
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic dns_result_t
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsbase64_totext(isc_region_t *source, isc_buffer_t *target) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews char buf[5];
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews int loops = 0;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews memset(buf, 0, sizeof buf);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews RETERR(str_totext("( " /*)*/, target));
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews while (source->length > 2) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews buf[0] = base64[(source->base[0]>>2)&0x3f];
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews buf[1] = base64[((source->base[0]<<4)&0x30)|
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews ((source->base[1]>>4)&0x0f)];
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews buf[2] = base64[((source->base[1]<<2)&0x3c)|
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews ((source->base[2]>>6)&0x03)];
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews buf[3] = base64[source->base[2]&0x3f];
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews RETERR(str_totext(buf, target));
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews isc_region_consume(source, 3);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (source->length != 0 && ++loops == 15) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews loops = 0;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews RETERR(str_totext(" ", target));
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews }
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews }
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (source->length == 2) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews buf[0] = base64[(source->base[0]>>2)&0x3f];
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews buf[1] = base64[((source->base[0]<<4)&0x30)|
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews ((source->base[1]>>4)&0x0f)];
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews buf[2] = base64[((source->base[1]<<4)&0x3c)];
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews buf[3] = '=';
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews RETERR(str_totext(buf, target));
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews } else if (source->length == 1) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews buf[0] = base64[(source->base[0]>>2)&0x3f];
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews buf[1] = base64[((source->base[0]<<4)&0x30)];
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews buf[2] = buf[3] = '=';
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews RETERR(str_totext(buf, target));
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews }
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews RETERR(str_totext(" )", target));
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (DNS_R_SUCCESS);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews}
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic dns_result_t
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrewsbase64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews int digits = 0;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews isc_textregion_t *tr;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews int val[4];
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews unsigned char buf[3];
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews int seen_end = 0;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews unsigned int i;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews isc_token_t token;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews char *s;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews int n;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews while (!seen_end && (length != 0)) {
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews if (length > 0)
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews RETERR(gettoken(lexer, &token, isc_tokentype_string,
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews ISC_FALSE));
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews else
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews RETERR(gettoken(lexer, &token, isc_tokentype_string,
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews ISC_TRUE));
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (token.type != isc_tokentype_string)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews break;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews tr = &token.value.as_textregion;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews for (i = 0 ;i < tr->length; i++) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (seen_end)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (DNS_R_SYNTAX);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if ((s = strchr(base64, tr->base[i])) == NULL)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (DNS_R_SYNTAX);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews val[digits++] = s - base64;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (digits == 4) {
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews if (val[0] == 64 || val[1] == 64)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (DNS_R_SYNTAX);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (val[2] == 64 && val[3] != 64)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (DNS_R_SYNTAX);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews n = (val[2] == 64) ? 1 :
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews (val[3] == 64) ? 2 : 3;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews if (n != 3) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews seen_end = 1;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews if (val[2] == 64)
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews val[2] = 0;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews if (val[3] == 64)
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews val[3] = 0;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews }
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews buf[0] = (val[0]<<2)|(val[1]>>4);
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews buf[1] = (val[1]<<4)|(val[2]>>2);
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews buf[2] = (val[2]<<6)|(val[3]);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews RETERR(mem_tobuffer(target, buf, n));
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews if (length >= 0)
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews if (n > length)
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews return (DNS_R_SYNTAX);
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews else
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews length -= n;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews digits = 0;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews }
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews }
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews }
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews if (length < 0 && !seen_end)
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews isc_lex_ungettoken(lexer, &token);
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews if (length > 0)
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews return (DNS_R_UNEXPECTEDEND);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (digits)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (DNS_R_SYNTAX);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (DNS_R_SUCCESS);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews}
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrewsstatic int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic dns_result_t
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewstime_totext(unsigned long value, isc_buffer_t *target) {
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews isc_int64_t start;
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews isc_int64_t base;
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews isc_int64_t t;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews struct tm tm;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews char buf[sizeof "YYYYMMDDHHMMSS"];
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews int secs;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews /* find the right epoch */
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews start = time(NULL);
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews start -= 0x7fffffff;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews base = 0;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews while ((t = (base + value)) < start) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews base += 0x80000000;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews base += 0x80000000;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews }
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews#define is_leap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews#define year_secs(y) ((is_leap(y) ? 366 : 365 ) * 86400)
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews#define month_secs(m, y) ((days[m] + ((m == 1 && is_leap(y)) ? 1 : 0 )) * 86400)
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews tm.tm_year = 70;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews while ((secs = year_secs(tm.tm_year + 1900 + 1)) <= t) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews t -= secs;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews tm.tm_year++;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews }
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews tm.tm_mon = 0;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews while ((secs = month_secs(tm.tm_mon, tm.tm_year + 1900)) <= t) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews t -= secs;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews tm.tm_mon++;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews }
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews tm.tm_mday = 1;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews while (86400 <= t) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews t -= 86400;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews tm.tm_mday++;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews }
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews tm.tm_hour = 0;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews while (3600 <= t) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews t -= 3600;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews tm.tm_hour++;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews }
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews tm.tm_min = 0;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews while (60 <= t) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews t -= 60;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews tm.tm_min++;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews }
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews tm.tm_sec = t;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews /* yy mm dd HH MM SS */
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews sprintf(buf, "%04d%02d%02d%02d%02d%02d",
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews tm.tm_hour, tm.tm_min, tm.tm_sec);
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews return (str_totext(buf, target));
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews}
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrewsstatic dns_result_t
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrewstime_tobuffer(char *source, isc_buffer_t *target) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews int year, month, day, hour, minute, second;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews unsigned long value;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews int secs;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews int i;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews#define RANGE(min, max, value) \
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews do { \
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews if (value < (min) || value > (max)) \
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews return (DNS_R_RANGE); \
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews } while (0)
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews if (strlen(source) != 14)
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews return (DNS_R_SYNTAX);
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews if (sscanf(source, "%4d%2d%2d%2d%2d%2d",
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews &year, &month, &day, &hour, &minute, &second) != 6)
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews return (DNS_R_SYNTAX);
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews RANGE(1970, 9999, year);
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews RANGE(1, 12, month);
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews RANGE(1, days[month - 1] +
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews ((month == 2 && is_leap(year)) ? 1 : 0), day);
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews RANGE(0, 23, hour);
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews RANGE(0, 59, minute);
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews RANGE(0, 60, second); /* leap second */
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews /* calulate seconds since epoch */
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews value = second + (60 * minute) + (3600 * hour) + ((day - 1) * 86400);
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews for (i = 0; i < (month - 1) ; i++)
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews value += days[i] * 86400;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews if (is_leap(year) && month > 2)
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews value += 86400;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews for (i = 1970; i < year; i++) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews secs = (is_leap(i) ? 366 : 365) * 86400;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews value += secs;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews }
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews return (uint32_tobuffer(value, target));
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews}
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsstatic const char atob_digits[86] =
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews"!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstu";
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews/*
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * Subroutines to convert between 8 bit binary bytes and printable ASCII.
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * Computes the number of bytes, and three kinds of simple checksums.
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * Incoming bytes are collected into 32-bit words, then printed in base 85:
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * exp(85,5) > exp(2,32)
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * The ASCII characters used are between '!' and 'u';
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data.
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews *
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * the atob/btoa programs, released with the compress program, in mod.sources.
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * Modified by Mike Schwartz 8/19/86 for use in BIND.
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * Modified to be re-entrant 3/2/99.
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews */
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsstruct state {
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews isc_int32_t Ceor;
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews isc_int32_t Csum;
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews isc_int32_t Crot;
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews isc_int32_t word;
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews isc_int32_t bcount;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews};
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews#define Ceor state->Ceor
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews#define Csum state->Csum
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews#define Crot state->Crot
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews#define word state->word
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews#define bcount state->bcount
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews#define times85(x) ((((((x<<2)+x)<<2)+x)<<2)+x)
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsstatic dns_result_t byte_atob(int c, isc_buffer_t *target,
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews struct state *state);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsstatic dns_result_t putbyte(int c, isc_buffer_t *, struct state *state);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsstatic dns_result_t byte_btoa(int c, isc_buffer_t *, struct state *state);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews/* Decode ASCII-encoded byte c into binary representation and
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * place into *bufp, advancing bufp
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews */
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsstatic dns_result_t
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsbyte_atob(int c, isc_buffer_t *target, struct state *state) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews char *s;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (c == 'z') {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (bcount != 0)
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews return(DNS_R_SYNTAX);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews else {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(putbyte(0, target, state));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(putbyte(0, target, state));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(putbyte(0, target, state));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(putbyte(0, target, state));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews }
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews } else if ((s = strchr(atob_digits, c)) != NULL) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (bcount == 0) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews word = s - atob_digits;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews ++bcount;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews } else if (bcount < 4) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews word = times85(word);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews word += s - atob_digits;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews ++bcount;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews } else {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews word = times85(word);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews word += s - atob_digits;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(putbyte((word >> 24) & 0xff, target, state));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(putbyte((word >> 16) & 0xff, target, state));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(putbyte((word >> 8) & 0xff, target, state));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(putbyte(word & 0xff, target, state));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews word = 0;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews bcount = 0;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews }
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews } else
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews return(DNS_R_SYNTAX);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews return(DNS_R_SUCCESS);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews}
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews/* Compute checksum info and place c into target */
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsstatic dns_result_t
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsputbyte(int c, isc_buffer_t *target, struct state *state) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews isc_region_t tr;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews Ceor ^= c;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews Csum += c;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews Csum += 1;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if ((Crot & 0x80000000)) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews Crot <<= 1;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews Crot += 1;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews } else {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews Crot <<= 1;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews }
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews Crot += c;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews isc_buffer_available(target, &tr);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (tr.length < 1)
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews return (DNS_R_NOSPACE);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews tr.base[0] = c;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews isc_buffer_add(target, 1);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews return (DNS_R_SUCCESS);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews}
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews/* Read the ASCII-encoded data from inbuf, of length inbuflen, and convert
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews it into T_UNSPEC (binary data) in outbuf, not to exceed outbuflen bytes;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews outbuflen must be divisible by 4. (Note: this is because outbuf is filled
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews in 4 bytes at a time. If the actual data doesn't end on an even 4-byte
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews boundary, there will be no problem...it will be padded with 0 bytes, and
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews numbytes will indicate the correct number of bytes. The main point is
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews that since the buffer is filled in 4 bytes at a time, even if there is
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews not a full 4 bytes of data at the end, there has to be room to 0-pad the
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews data, so the buffer must be of size divisible by 4). Place the number of
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews output bytes in numbytes, and return a failure/success status */
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsstatic dns_result_t
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsatob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target) {
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews isc_int32_t oeor, osum, orot;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews struct state statebuf, *state= &statebuf;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews isc_token_t token;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews char c;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews char *e;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews Ceor = Csum = Crot = word = bcount = 0;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews while (token.value.as_textregion.length != 0) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if ((c = token.value.as_textregion.base[0]) == 'x') {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews break;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews } else
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(byte_atob(c, target, state));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews isc_textregion_consume(&token.value.as_textregion, 1);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews }
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews /* number of bytes */
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if ((token.value.as_ulong % 4) != 0)
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews isc_buffer_subtract(target, 4 - (token.value.as_ulong % 4));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews /* checksum */
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews oeor = strtoul(token.value.as_pointer, &e, 16);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (*e != 0)
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews return (DNS_R_SYNTAX);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews /* checksum */
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews osum = strtoul(token.value.as_pointer, &e, 16);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (*e != 0)
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews return (DNS_R_SYNTAX);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews /* checksum */
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews orot = strtoul(token.value.as_pointer, &e, 16);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (*e != 0)
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews return (DNS_R_SYNTAX);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if ((oeor != Ceor) || (osum != Csum) || (orot != Crot))
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews return(DNS_R_BADCKSUM);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews return(DNS_R_SUCCESS);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews}
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews/* Encode binary byte c into ASCII representation and place into *bufp,
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews advancing bufp */
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsstatic dns_result_t
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsbyte_btoa(int c, isc_buffer_t *target, struct state *state) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews isc_region_t tr;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews isc_buffer_available(target, &tr);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews Ceor ^= c;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews Csum += c;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews Csum += 1;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if ((Crot & 0x80000000)) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews Crot <<= 1;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews Crot += 1;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews } else {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews Crot <<= 1;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews }
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews Crot += c;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews word <<= 8;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews word |= c;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (bcount == 3) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (word == 0) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (tr.length < 1)
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews return (DNS_R_NOSPACE);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews tr.base[0] = 'z';
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews isc_buffer_add(target, 1);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews } else {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews register int tmp = 0;
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews register isc_int32_t tmpword = word;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (tmpword < 0) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews /* Because some don't support u_long */
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews tmp = 32;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews tmpword -= (int32_t)(85 * 85 * 85 * 85 * 32);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews }
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (tmpword < 0) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews tmp = 64;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews tmpword -= (int32_t)(85 * 85 * 85 * 85 * 32);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews }
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (tr.length < 5)
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews return (DNS_R_NOSPACE);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews tr.base[0] = atob_digits[(tmpword /
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews (int32_t)(85 * 85 * 85 * 85))
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews + tmp];
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews tmpword %= (int32_t)(85 * 85 * 85 * 85);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews tr.base[1] = atob_digits[tmpword / (85 * 85 * 85)];
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews tmpword %= (85 * 85 * 85);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews tr.base[2] = atob_digits[tmpword / (85 * 85)];
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews tmpword %= (85 * 85);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews tr.base[3] = atob_digits[tmpword / 85];
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews tmpword %= 85;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews tr.base[4] = atob_digits[tmpword];
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews isc_buffer_add(target, 5);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews }
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews bcount = 0;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews } else {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews bcount += 1;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews }
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews return (DNS_R_SUCCESS);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews}
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews/*
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * Encode the binary data from inbuf, of length inbuflen, into a
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * target. Return success/failure status
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews */
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsstatic dns_result_t
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsbtoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews int inc;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews struct state statebuf, *state = &statebuf;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews char buf[sizeof "x 2000000000 ffffffff ffffffff ffffffff"];
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews Ceor = Csum = Crot = word = bcount = 0;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews for (inc = 0; inc < inbuflen; inbuf++, inc++)
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(byte_btoa(*inbuf, target, state));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews while (bcount != 0)
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(byte_btoa(0, target, state));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews /*
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * Put byte count and checksum information at end of buffer,
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * delimited by 'x'
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews */
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews sprintf(buf, "x %d %x %x %x", inbuflen, Ceor, Csum, Crot);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews return (str_totext(buf, target));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews}