rdata.c revision 6d12fdf96621801e80f3f4c2a8a569fe48766a20
7d32c065c7bb56f281651ae3dd2888f32ce4f1d9Bob Halley * Copyright (C) 1998, 1999, 2000 Internet Software Consortium.
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 * 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
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence/* $Id: rdata.c,v 1.98 2000/06/01 18:25:34 tale Exp $ */
eb6bd543c7d072efdca509eb17f8f301c1467b53Mark Andrews#define RETERR(x) do { \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#define ARGS_FROMTEXT int rdclass, int type, \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#define ARGS_TOTEXT dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#define ARGS_FROMWIRE int rdclass, int type, \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence isc_buffer_t *source, dns_decompress_t *dctx, \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#define ARGS_TOWIRE dns_rdata_t *rdata, dns_compress_t *cctx, \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#define ARGS_COMPARE const dns_rdata_t *rdata1, const dns_rdata_t *rdata2
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#define ARGS_FROMSTRUCT int rdclass, int type, \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#define ARGS_TOSTRUCT dns_rdata_t *rdata, void *target, isc_mem_t *mctx
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#define ARGS_ADDLDATA dns_rdata_t *rdata, dns_additionaldatafunc_t add, \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#define ARGS_DIGEST dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson * Context structure for the totext_ functions.
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson * Contains formatting options for rdata-to-text
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson dns_name_t *origin; /* Current origin, or NULL. */
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson unsigned int flags; /* DNS_STYLEFLAG_* */
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson unsigned int width; /* Width of rdata column. */
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence const char *linebreak; /* Line break string. */
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencetxt_totext(isc_region_t *source, isc_buffer_t *target);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencetxt_fromtext(isc_textregion_t *source, isc_buffer_t *target);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencetxt_fromwire(isc_buffer_t *source, isc_buffer_t *target);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencename_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencestatic unsigned int
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencestr_totext(const char *source, isc_buffer_t *target);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencebuffer_fromregion(isc_buffer_t *buffer, isc_region_t *region);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrenceuint32_tobuffer(isc_uint32_t, isc_buffer_t *target);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrenceuint16_tobuffer(isc_uint32_t, isc_buffer_t *target);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrenceuint8_tobuffer(isc_uint32_t, isc_buffer_t *target);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencename_tobuffer(dns_name_t *name, isc_buffer_t *target);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencegettoken(isc_lex_t *lexer, isc_token_t *token, isc_tokentype_t expect,
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencemem_tobuffer(isc_buffer_t *target, void *base, unsigned int length);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencecompare_region(isc_region_t *r1, isc_region_t *r2);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencebtoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrenceatob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedefault_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *, ...);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencefromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...),
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence dns_rdatacallbacks_t *callbacks, const char *name,
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence unsigned long line, isc_token_t *token, isc_result_t result);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencerdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrewsname_duporclone(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) {
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrewsstatic inline void *
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrewsmem_maybedup(isc_mem_t *mctx, void *source, size_t length) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic const char hexdigits[] = "0123456789abcdef";
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews /* standard rcodes */ \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews /* extended rcodes */ \
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington /* extended rcodes */ \
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson/* RFC2535 section 7 */
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson/* RFC2535 section 7.1 */
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson { 0, "NONE", 0 }, \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews unsigned int value;
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellingtonstatic struct tbl rcodes[] = { RCODENAMES ERCODENAMES };
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellingtonstatic struct tbl tsigrcodes[] = { RCODENAMES TSIGRCODENAMES };
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graffstatic struct tbl secprotos[] = { SECPROTONAMES };
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *** Initialization
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* ISC_LIST_INIT(rdata->list); */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *** Comparisons
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2) {
d981ca645597116d227a48bf37cc5edc061c854dBob Halley return (rdata1->rdclass < rdata2->rdclass ? -1 : 1);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *** Conversions
d981ca645597116d227a48bf37cc5edc061c854dBob Halleydns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r) {
d981ca645597116d227a48bf37cc5edc061c854dBob Halleydns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews dns_decompress_t *dctx, isc_boolean_t downcase,
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff region.base = (unsigned char *)(target->base) + target->used;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * We should have consumed all of our buffer.
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result == ISC_R_SUCCESS && !buffer_empty(source))
d981ca645597116d227a48bf37cc5edc061c854dBob Halley dns_rdata_fromregion(rdata, rdclass, type, ®ion);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx,
7c0378745269fe49a05904935afc42b85528f53aDavid Lawrence dns_compress_rollback(cctx, (isc_uint16_t)target->used);
d981ca645597116d227a48bf37cc5edc061c854dBob Halleydns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews isc_buffer_t *target, dns_rdatacallbacks_t *callbacks)
f305d86668bfd4d4727c3e0f70e7e97a2fa1b772Bob Halley unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF |
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE;
20b20b23948b90cb2f7d7f402da99d09f837efd0David Lawrence unsigned long line;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence void (*callback)(dns_rdatacallbacks_t *, const char *, ...);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence REQUIRE(origin == NULL || dns_name_isabsolute(origin) == ISC_TRUE);
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff region.base = (unsigned char *)(target->base) + target->used;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews * Consume to end of line / file.
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews * If not at end of line initially set error code.
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews * Call callback via fromtext_error once if there was an error.
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrews iresult = isc_lex_gettoken(lexer, options, &token);
c0d0a59d1b665423b8a0d1829d0f0da121cb3473Andreas Gustafsson "isc_lex_gettoken() failed: %s",
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff } else if (result != ISC_R_SUCCESS && callback != NULL) {
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews fromtext_error(callback, callbacks, name, line,
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews } while (1);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (rdata != NULL && result == ISC_R_SUCCESS) {
d981ca645597116d227a48bf37cc5edc061c854dBob Halley dns_rdata_fromregion(rdata, rdclass, type, ®ion);
ae70d32b67cf30e06553c01479e71c87b21d984cBob Halleyrdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence dns_name_isabsolute(tctx->origin) == ISC_TRUE);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * Some DynDNS meta-RRs have empty rdata.
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencedns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * Set up formatting options for single-line output.
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafssondns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin,
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * Set up formatting options for formatted output.
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson if ((flags & DNS_STYLEFLAG_MULTILINE) != 0) {
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson tctx.width = 60; /* Used for base64 word length only. */
d981ca645597116d227a48bf37cc5edc061c854dBob Halleydns_rdata_fromstruct(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff region.base = (unsigned char *)(target->base) + target->used;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (rdata != NULL && result == ISC_R_SUCCESS) {
d981ca645597116d227a48bf37cc5edc061c854dBob Halley dns_rdata_fromregion(rdata, rdclass, type, ®ion);
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrewsdns_rdata_tostruct(dns_rdata_t *rdata, void *target, isc_mem_t *mctx) {
d981ca645597116d227a48bf37cc5edc061c854dBob Halleydns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add,
d981ca645597116d227a48bf37cc5edc061c854dBob Halley * Call 'add' for each name and type from 'rdata' which is subject to
d981ca645597116d227a48bf37cc5edc061c854dBob Halley * additional section processing.
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halleydns_rdata_digest(dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg) {
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley * Send 'rdata' in DNSSEC canonical form to 'digest'.
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson#define NUMBERSIZE sizeof("037777777777") /* 2^32-1 octal + NUL */
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafssondns_mnemonic_fromtext(unsigned int *valuep, isc_textregion_t *source,
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson unsigned int n;
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson * We have a potential number. Try to parse it with strtoul().
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson * strtoul() requires null termination, so we must make
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson strncpy(buffer, source->base, NUMBERSIZE);
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson if (*e == 0) {
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * It was not a number after all; fall through.
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson for (i = 0; table[i].name != NULL; i++) {
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson unsigned int n;
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson strncasecmp(source->base, table[i].name, n) == 0) {
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafssondns_mnemonic_totext(unsigned int value, isc_buffer_t *target,
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson return (str_totext(table[i].name, target));
fa460c223a69449eaac67ddb6abafe74f5e1ff02Michael Graff * This uses lots of hard coded values, but how often do we actually
fa460c223a69449eaac67ddb6abafe74f5e1ff02Michael Graff * add classes?
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencedns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source) {
16996a04884731d647f43a5eb54f678581f09f68David Lawrence unsigned int attrs;
16996a04884731d647f43a5eb54f678581f09f68David Lawrence * Note: attrs is set and then used in the bit test with RESERVED
16996a04884731d647f43a5eb54f678581f09f68David Lawrence * because testing "(flags & RESERVED) != 0" generates
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence * warnings on IRIX about how the test always has the same value
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence * because it is all constants.
600cfa2ba4c50017581b6c14e3a688a82ecebbe0David Lawrence if (((sizeof(string) - 1) == source->length) \
600cfa2ba4c50017581b6c14e3a688a82ecebbe0David Lawrence && (strcasecmp(source->base, string) == 0)) { \
fc024be774c7cdee938da018aa3994be746e36deDavid Lawrence switch (tolower((unsigned char)source->base[0])) {
16996a04884731d647f43a5eb54f678581f09f68David Lawrence COMPARE("reserved0", META|RESERVED, dns_rdataclass_reserved0);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencedns_rdataclass_totext(dns_rdataclass_t rdclass, isc_buffer_t *target) {
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencedns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source) {
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff unsigned int hash;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews unsigned int n;
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff unsigned char a, b;
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence b = tolower((unsigned char)source->base[n - 1]);
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff * This switch block is inlined via #define, and will use "return"
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff * to return a result to the caller if it is a valid (known)
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff * rdatatype name.
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff RDATATYPE_FROMTEXT_SW(hash, source->base, typep);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencedns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target) {
6324997211a5e2d82528dcde98e8981190a35faeMichael Graff return (str_totext(typeattr[type].name, target));
79eec6934923f97a61edb8dbe2641ce56dc30085Bob Halley/* XXXRTH Should we use a hash table here? */
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrewsdns_rcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source) {
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington RETERR(dns_mnemonic_fromtext(&value, source, rcodes, 0xffff));
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrewsdns_rcode_totext(dns_rcode_t rcode, isc_buffer_t *target) {
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson return (dns_mnemonic_totext(rcode, target, rcodes));
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellingtondns_tsigrcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source) {
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington RETERR(dns_mnemonic_fromtext(&value, source, tsigrcodes, 0xffff));
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellingtondns_tsigrcode_totext(dns_rcode_t rcode, isc_buffer_t *target) {
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington return (dns_mnemonic_totext(rcode, target, tsigrcodes));
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsdns_cert_fromtext(dns_cert_t *certp, isc_textregion_t *source) {
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson RETERR(dns_mnemonic_fromtext(&value, source, certs, 0xffff));
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafssondns_cert_totext(dns_cert_t cert, isc_buffer_t *target) {
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson return (dns_mnemonic_totext(cert, target, certs));
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafssondns_secalg_fromtext(dns_secalg_t *secalgp, isc_textregion_t *source) {
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson RETERR(dns_mnemonic_fromtext(&value, source, secalgs, 0xff));
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafssondns_secalg_totext(dns_secalg_t secalg, isc_buffer_t *target) {
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson return (dns_mnemonic_totext(secalg, target, secalgs));
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafssondns_secproto_fromtext(dns_secproto_t *secprotop, isc_textregion_t *source) {
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson RETERR(dns_mnemonic_fromtext(&value, source, secprotos, 0xff));
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafssondns_secproto_totext(dns_secproto_t secproto, isc_buffer_t *target) {
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson return (dns_mnemonic_totext(secproto, target, secprotos));
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafssondns_keyflags_fromtext(dns_keyflags_t *flagsp, isc_textregion_t *source)
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson unsigned int n;
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson * We have a potential number. Try to parse it with strtoul().
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson * strtoul() requires null termination, so we must make
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson strncpy(buffer, source->base, NUMBERSIZE);
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson n = strtoul(buffer, &e, 0); /* Allow hex/octal. */
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson if (*e == 0) {
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson if (n > 0xffff)
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson /* It was not a number after all; fall through. */
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson char *delim = memchr(text, '|', end - text);
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson for (p = keyflags; p->name != NULL; p++) {
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson if (strncasecmp(p->name, text, len) == 0)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * Private function.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic unsigned int
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;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews while (n--) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c) {
fe47f41b13620bfafc4f8cf65d5df24f1e568764Bob Halley isc_buffer_add(target, tp - (char *)region.base);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewstxt_fromtext(isc_textregion_t *source, isc_buffer_t *target) {
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews unsigned int n, nrem;
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews unsigned char *t;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_availableregion(target, &tregion);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * Length byte.
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * Maximum text string length.
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews while (n-- != 0) {
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews c = (*s++)&0xff;
7c0378745269fe49a05904935afc42b85528f53aDavid Lawrence if (escape && (d = decvalue((char)c)) != -1) {
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews c = c * 10 + d;
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews c = c * 10 + d;
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews if (c > 255)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewstxt_fromwire(isc_buffer_t *source, isc_buffer_t *target) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned int n;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_availableregion(target, &tregion);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsname_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (dns_name_compare(origin, dns_rootname) == 0)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_name_getlabelsequence(name, 0, l1 - l2, target);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencestr_totext(const char *source, isc_buffer_t *target) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned int l;
26b0f58b6c4d65bc8b131debf40b8c376c2978bfBob Halley return((source->current == source->active) ? ISC_TRUE : ISC_FALSE);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrencebuffer_fromregion(isc_buffer_t *buffer, isc_region_t *region) {
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(buffer, region->base, region->length);
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrewsuint32_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrewsuint16_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
7c0378745269fe49a05904935afc42b85528f53aDavid Lawrence isc_buffer_putuint16(target, (isc_uint16_t)value);
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafssonuint8_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
7c0378745269fe49a05904935afc42b85528f53aDavid Lawrence isc_buffer_putuint8(target, (isc_uint8_t)value);
5466ce3f279d9fa83ce826bcdc9482bc591152aeAndreas Gustafssonname_tobuffer(dns_name_t *name, isc_buffer_t *target) {
5466ce3f279d9fa83ce826bcdc9482bc591152aeAndreas Gustafsson return (isc_buffer_copyregion(target, &r));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned long value;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return ((region->base[0] << 8) | region->base[1]);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrewsgettoken(isc_lex_t *lexer, isc_token_t *token, isc_tokentype_t expect,
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF |
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE;
25870d4a37ab4bc8e675502b08335200167cc044Bob Halley result = isc_lex_gettoken(lexer, options, token);
c0d0a59d1b665423b8a0d1829d0f0da121cb3473Andreas Gustafsson "isc_lex_gettoken() failed: %s",
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews if (eol && ((token->type == isc_tokentype_eol) ||
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrewsmem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) {
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrewscompare_region(isc_region_t *r1, isc_region_t *r2) {
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews unsigned int l;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews l = (r1->length < r2->length) ? r1->length : r2->length;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews if ((result = memcmp(r1->base, r2->base, l)) != 0)
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence unsigned char c;
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence c = (unsigned char)value;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (-1);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (-1);
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence * isascii() is valid for full range of int values, no need to
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence * mask or cast.
8a17d1e7cdba9fdcf71fb2f821a954a251204105Mark Andrews return (-1);
8a17d1e7cdba9fdcf71fb2f821a954a251204105Mark Andrews return (-1);
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence "abcdefghijklmnopqrstu";
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 * 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.
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffstatic isc_result_t byte_atob(int c, isc_buffer_t *target,
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffstatic isc_result_t putbyte(int c, isc_buffer_t *, struct state *state);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffstatic isc_result_t byte_btoa(int c, isc_buffer_t *, struct state *state);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * Decode ASCII-encoded byte c into binary representation and
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * place into *bufp, advancing bufp.
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsbyte_atob(int c, isc_buffer_t *target, struct state *state) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (c == 'z') {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews } else if ((s = strchr(atob_digits, c)) != NULL) {
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));
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * Compute checksum info and place c into target.
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsputbyte(int c, isc_buffer_t *target, struct state *state) {
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * Read the ASCII-encoded data from inbuf, of length inbuflen, and convert
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * it into T_UNSPEC (binary data) in outbuf, not to exceed outbuflen bytes;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * outbuflen must be divisible by 4. (Note: this is because outbuf is filled
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * in 4 bytes at a time. If the actual data doesn't end on an even 4-byte
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * boundary, there will be no problem...it will be padded with 0 bytes, and
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * numbytes will indicate the correct number of bytes. The main point is
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * that since the buffer is filled in 4 bytes at a time, even if there is
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * not a full 4 bytes of data at the end, there has to be room to 0-pad the
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * data, so the buffer must be of size divisible by 4). Place the number of
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * output bytes in numbytes, and return a failure/success status.
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsatob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target) {
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 isc_textregion_consume(&token.value.as_textregion, 1);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * Number of bytes.
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews isc_buffer_subtract(target, 4 - (token.value.as_ulong % 4));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE));
df8c9ee4819c97089664ccc035eb2aa7569034fdDavid Lawrence oeor = strtol(token.value.as_pointer, &e, 16);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (*e != 0)
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE));
df8c9ee4819c97089664ccc035eb2aa7569034fdDavid Lawrence osum = strtol(token.value.as_pointer, &e, 16);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (*e != 0)
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE));
df8c9ee4819c97089664ccc035eb2aa7569034fdDavid Lawrence orot = strtol(token.value.as_pointer, &e, 16);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if (*e != 0)
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews if ((oeor != Ceor) || (osum != Csum) || (orot != Crot))
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * Encode binary byte c into ASCII representation and place into *bufp,
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * advancing bufp.
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsbyte_btoa(int c, isc_buffer_t *target, struct state *state) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews register int tmp = 0;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * Because some don't support u_long.
83ac7ce833930a5c6cb92ad9c04a58e775579e73Bob Halley tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32);
83ac7ce833930a5c6cb92ad9c04a58e775579e73Bob Halley tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews tr.base[1] = atob_digits[tmpword / (85 * 85 * 85)];
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * Encode the binary data from inbuf, of length inbuflen, into a
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * target. Return success/failure status
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsbtoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews char buf[sizeof "x 2000000000 ffffffff ffffffff ffffffff"];
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * Put byte count and checksum information at end of buffer,
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * delimited by 'x'
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews sprintf(buf, "x %d %x %x %x", inbuflen, Ceor, Csum, Crot);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedefault_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *fmt,
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencefromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...),
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence dns_rdatacallbacks_t *callbacks, const char *name,
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence unsigned long line, isc_token_t *token, isc_result_t result)
20b20b23948b90cb2f7d7f402da99d09f837efd0David Lawrence (*callback)(callbacks, "%s: %s:%lu: near eol: %s",
20b20b23948b90cb2f7d7f402da99d09f837efd0David Lawrence (*callback)(callbacks, "%s: %s:%lu: near eof: %s",
20b20b23948b90cb2f7d7f402da99d09f837efd0David Lawrence (*callback)(callbacks, "%s: %s:%lu: near %lu: %s",
20b20b23948b90cb2f7d7f402da99d09f837efd0David Lawrence (*callback)(callbacks, "%s: %s:%lu: near '%s': %s",
20b20b23948b90cb2f7d7f402da99d09f837efd0David Lawrence (*callback)(callbacks, "dns_rdata_fromtext: %s:%lu: %s",
6324997211a5e2d82528dcde98e8981190a35faeMichael Graff if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_META) != 0)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencedns_rdatatype_issingleton(dns_rdatatype_t type) {
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_SINGLETON)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencedns_rdatatype_notquestion(dns_rdatatype_t type) {
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_NOTQUESTION)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencedns_rdatatype_questiononly(dns_rdatatype_t type) {
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_QUESTIONONLY)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencedns_rdataclass_ismeta(dns_rdataclass_t rdclass) {
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence return (ISC_FALSE); /* Assume it is not a meta class. */
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencedns_rdatatype_isdnssec(dns_rdatatype_t type) {
6324997211a5e2d82528dcde98e8981190a35faeMichael Graff if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_DNSSEC) != 0)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencedns_rdatatype_iszonecutauth(dns_rdatatype_t type) {
6324997211a5e2d82528dcde98e8981190a35faeMichael Graff & (DNS_RDATATYPEATTR_DNSSEC | DNS_RDATATYPEATTR_ZONECUTAUTH))