rdata.c revision e4653123ecc6cdbfc0b9eda6e98e44af3b1f9a08
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Copyright (C) 1998 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
e4653123ecc6cdbfc0b9eda6e98e44af3b1f9a08Mark Andrews /* $Id: rdata.c,v 1.28 1999/02/05 06:41:20 marka Exp $ */
eb6bd543c7d072efdca509eb17f8f301c1467b53Mark Andrews#define RETERR(x) do { \
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 Andrewsstatic dns_result_t txt_fromwire(isc_buffer_t *source,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic isc_boolean_t name_prefix(dns_name_t *name, dns_name_t *origin,
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 unsigned int type);
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrewsstatic dns_result_t uint32_tobuffer(isc_uint32_t,
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrewsstatic dns_result_t uint16_tobuffer(isc_uint32_t,
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 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 dns_result_t base64_totext(isc_region_t *source,
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic dns_result_t base64_tobuffer(isc_lex_t *lexer,
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic dns_result_t time_totext(unsigned long value,
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 Andrewsstatic dns_result_t atob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic const char hexdigits[] = "0123456789abcdef";
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews /* standard rcodes */ \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews /* extended rcodes */ \
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews unsigned int value;
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews} types[] = { TYPENAMES METATYPES {0, NULL, 0} },
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrewsclasses[] = { CLASSNAMES METACLASSES { 0, NULL, 0} },
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *** Initialization
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* ISC_LIST_INIT(rdata->list); */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *** Comparisons
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_rdata_compare(dns_rdata_t *rdata1, dns_rdata_t *rdata2) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (rdata1->class < rdata2->class ? -1 : 1);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *** Conversions
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_rdata_toregion(dns_rdata_t *rdata, isc_region_t *r) {
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff region.base = (unsigned char *)(target->base) + target->used;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* We should have consumed all out buffer */
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (result == DNS_R_SUCCESS && !buffer_empty(source))
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_fromregion(rdata, class, type, ®ion);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx,
f305d86668bfd4d4727c3e0f70e7e97a2fa1b772Bob Halley unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF |
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.
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews } while (1);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rdata != NULL && result == DNS_R_SUCCESS) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_fromregion(rdata, class, type, ®ion);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_rdata_totext(dns_rdata_t *rdata, isc_buffer_t *target) {
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff region.base = (unsigned char *)(target->base) + target->used;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rdata != NULL && result == DNS_R_SUCCESS) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_fromregion(rdata, class, type, ®ion);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_rdata_tostruct(dns_rdata_t *rdata, void *target) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrewsdns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews unsigned int n;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews strncasecmp(source->base, classes[i].name, n) == 0) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrewsdns_rdataclass_totext(dns_rdataclass_t class, isc_buffer_t *target) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrewsdns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews unsigned int n;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews strncasecmp(source->base, types[i].name, n) == 0) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrewsdns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target) {
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrewsdns_rcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source) {
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews unsigned int n;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews strncasecmp(source->base, rcodes[i].name, n) == 0) {
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrewsdns_rcode_totext(dns_rcode_t rcode, isc_buffer_t *target) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsdns_cert_fromtext(dns_cert_t *certp, isc_textregion_t *source) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews unsigned int n;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews strncasecmp(source->base, certs[i].name, n) == 0) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsdns_cert_totext(dns_cert_t cert, isc_buffer_t *target) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsdns_secalg_fromtext(dns_secalg_t *secalgp, isc_textregion_t *source) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews unsigned int n;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews strncasecmp(source->base, secalgs[i].name, n) == 0) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsdns_secalg_totext(dns_secalg_t secalg, isc_buffer_t *target) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews /* 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) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews memcpy(tregion.base + 1, source->base, source->length);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewstxt_fromwire(isc_buffer_t *source, isc_buffer_t *target) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned int n;
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);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstr_totext(char *source, isc_buffer_t *target) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned int l;
26b0f58b6c4d65bc8b131debf40b8c376c2978bfBob Halley return((source->current == source->active) ? ISC_TRUE : ISC_FALSE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsbuffer_fromregion(isc_buffer_t *buffer, isc_region_t *region,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned int type) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_init(buffer, region->base, region->length, type);
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrewsuint32_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrewsuint16_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
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 |
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews if (isc_lex_gettoken(lexer, options, token) != ISC_R_SUCCESS)
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)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (-1);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (-1);
8a17d1e7cdba9fdcf71fb2f821a954a251204105Mark Andrews return (-1);
8a17d1e7cdba9fdcf71fb2f821a954a251204105Mark Andrews return (-1);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic const char base64[] =
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsbase64_totext(isc_region_t *source, isc_buffer_t *target) {
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrewsbase64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews unsigned int i;
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews RETERR(gettoken(lexer, &token, isc_tokentype_string,
904294c0c952227f7778fd0ba2ccea08c097b872Mark Andrews RETERR(gettoken(lexer, &token, isc_tokentype_string,
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews if (n != 3) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrewsstatic int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewstime_totext(unsigned long value, isc_buffer_t *target) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews /* find the right epoch */
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 while ((secs = year_secs(tm.tm_year + 1900 + 1)) <= t) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews while ((secs = month_secs(tm.tm_mon, tm.tm_year + 1900)) <= t) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews while (86400 <= t) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews while (3600 <= t) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews while (60 <= t) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews /* yy mm dd HH MM SS */
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrewstime_tobuffer(char *source, isc_buffer_t *target) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews unsigned long value;
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews &year, &month, &day, &hour, &minute, &second) != 6)
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews /* calulate seconds since epoch */
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews value = second + (60 * minute) + (3600 * hour) + ((day - 1) * 86400);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews"!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`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.
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsstatic dns_result_t byte_atob(int c, isc_buffer_t *target,
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/* Decode ASCII-encoded byte c into binary representation and
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews * 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));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews/* Compute checksum info and place c into target */
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsputbyte(int c, isc_buffer_t *target, struct state *state) {
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 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);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews /* 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 /* 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 /* 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 /* 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 if ((oeor != Ceor) || (osum != Csum) || (orot != Crot))
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews/* Encode binary byte c into ASCII representation and place into *bufp,
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews advancing bufp */
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrewsbyte_btoa(int c, isc_buffer_t *target, struct state *state) {
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews register int tmp = 0;
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews /* Because some don't support u_long */
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);