📄 rdata.c
字号:
/* Note - inet_ntop doesn't do size checking on its input. */ if (inet_ntop(af, src->base, tmpbuf, sizeof(tmpbuf)) == NULL) return (ISC_R_NOSPACE); if (strlen(tmpbuf) > isc_buffer_availablelength(target)) return (ISC_R_NOSPACE); isc_buffer_putstr(target, tmpbuf); return (ISC_R_SUCCESS);}static isc_boolean_tbuffer_empty(isc_buffer_t *source) { return((source->current == source->active) ? ISC_TRUE : ISC_FALSE);}static voidbuffer_fromregion(isc_buffer_t *buffer, isc_region_t *region) { isc_buffer_init(buffer, region->base, region->length); isc_buffer_add(buffer, region->length); isc_buffer_setactive(buffer, region->length);}static isc_result_tuint32_tobuffer(isc_uint32_t value, isc_buffer_t *target) { isc_region_t region; isc_buffer_availableregion(target, ®ion); if (region.length < 4) return (ISC_R_NOSPACE); isc_buffer_putuint32(target, value); return (ISC_R_SUCCESS);}static isc_result_tuint16_tobuffer(isc_uint32_t value, isc_buffer_t *target) { isc_region_t region; if (value > 0xffff) return (ISC_R_RANGE); isc_buffer_availableregion(target, ®ion); if (region.length < 2) return (ISC_R_NOSPACE); isc_buffer_putuint16(target, (isc_uint16_t)value); return (ISC_R_SUCCESS);}static isc_result_tuint8_tobuffer(isc_uint32_t value, isc_buffer_t *target) { isc_region_t region; if (value > 0xff) return (ISC_R_RANGE); isc_buffer_availableregion(target, ®ion); if (region.length < 1) return (ISC_R_NOSPACE); isc_buffer_putuint8(target, (isc_uint8_t)value); return (ISC_R_SUCCESS);}static isc_result_tname_tobuffer(dns_name_t *name, isc_buffer_t *target) { isc_region_t r; dns_name_toregion(name, &r); return (isc_buffer_copyregion(target, &r));}static isc_uint32_tuint32_fromregion(isc_region_t *region) { unsigned long value; REQUIRE(region->length >= 4); value = region->base[0] << 24; value |= region->base[1] << 16; value |= region->base[2] << 8; value |= region->base[3]; return(value);}static isc_uint16_tuint16_fromregion(isc_region_t *region) { REQUIRE(region->length >= 2); return ((region->base[0] << 8) | region->base[1]);}static isc_uint8_tuint8_fromregion(isc_region_t *region) { REQUIRE(region->length >= 1); return (region->base[0]);}static isc_result_tmem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) { isc_region_t tr; isc_buffer_availableregion(target, &tr); if (length > tr.length) return (ISC_R_NOSPACE); memcpy(tr.base, base, length); isc_buffer_add(target, length); return (ISC_R_SUCCESS);}static inthexvalue(char value) { char *s; unsigned char c; c = (unsigned char)value; if (!isascii(c)) return (-1); if (isupper(c)) c = tolower(c); if ((s = strchr(hexdigits, value)) == NULL) return (-1); return (s - hexdigits);}static intdecvalue(char value) { char *s; /* * isascii() is valid for full range of int values, no need to * mask or cast. */ if (!isascii(value)) return (-1); if ((s = strchr(decdigits, value)) == NULL) return (-1); return (s - decdigits);}static const char atob_digits[86] = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \ "abcdefghijklmnopqrstu";/* * Subroutines to convert between 8 bit binary bytes and printable ASCII. * Computes the number of bytes, and three kinds of simple checksums. * Incoming bytes are collected into 32-bit words, then printed in base 85: * exp(85,5) > exp(2,32) * The ASCII characters used are between '!' and 'u'; * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data. * * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for * the atob/btoa programs, released with the compress program, in mod.sources. * Modified by Mike Schwartz 8/19/86 for use in BIND. * Modified to be re-entrant 3/2/99. */struct state { isc_int32_t Ceor; isc_int32_t Csum; isc_int32_t Crot; isc_int32_t word; isc_int32_t bcount;};#define Ceor state->Ceor#define Csum state->Csum#define Crot state->Crot#define word state->word#define bcount state->bcount#define times85(x) ((((((x<<2)+x)<<2)+x)<<2)+x)static isc_result_t byte_atob(int c, isc_buffer_t *target, struct state *state);static isc_result_t putbyte(int c, isc_buffer_t *, struct state *state);static isc_result_t byte_btoa(int c, isc_buffer_t *, struct state *state);/* * Decode ASCII-encoded byte c into binary representation and * place into *bufp, advancing bufp. */static isc_result_tbyte_atob(int c, isc_buffer_t *target, struct state *state) { char *s; if (c == 'z') { if (bcount != 0) return(DNS_R_SYNTAX); else { RETERR(putbyte(0, target, state)); RETERR(putbyte(0, target, state)); RETERR(putbyte(0, target, state)); RETERR(putbyte(0, target, state)); } } else if ((s = strchr(atob_digits, c)) != NULL) { if (bcount == 0) { word = s - atob_digits; ++bcount; } else if (bcount < 4) { word = times85(word); word += s - atob_digits; ++bcount; } else { word = times85(word); word += s - atob_digits; RETERR(putbyte((word >> 24) & 0xff, target, state)); RETERR(putbyte((word >> 16) & 0xff, target, state)); RETERR(putbyte((word >> 8) & 0xff, target, state)); RETERR(putbyte(word & 0xff, target, state)); word = 0; bcount = 0; } } else return(DNS_R_SYNTAX); return(ISC_R_SUCCESS);}/* * Compute checksum info and place c into target. */static isc_result_tputbyte(int c, isc_buffer_t *target, struct state *state) { isc_region_t tr; Ceor ^= c; Csum += c; Csum += 1; if ((Crot & 0x80000000)) { Crot <<= 1; Crot += 1; } else { Crot <<= 1; } Crot += c; isc_buffer_availableregion(target, &tr); if (tr.length < 1) return (ISC_R_NOSPACE); tr.base[0] = c; isc_buffer_add(target, 1); return (ISC_R_SUCCESS);}/* * Read the ASCII-encoded data from inbuf, of length inbuflen, and convert * it into T_UNSPEC (binary data) in outbuf, not to exceed outbuflen bytes; * outbuflen must be divisible by 4. (Note: this is because outbuf is filled * in 4 bytes at a time. If the actual data doesn't end on an even 4-byte * boundary, there will be no problem...it will be padded with 0 bytes, and * numbytes will indicate the correct number of bytes. The main point is * that since the buffer is filled in 4 bytes at a time, even if there is * not a full 4 bytes of data at the end, there has to be room to 0-pad the * data, so the buffer must be of size divisible by 4). Place the number of * output bytes in numbytes, and return a failure/success status. */static isc_result_tatob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target) { long oeor, osum, orot; struct state statebuf, *state= &statebuf; isc_token_t token; char c; char *e; Ceor = Csum = Crot = word = bcount = 0; RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); while (token.value.as_textregion.length != 0) { if ((c = token.value.as_textregion.base[0]) == 'x') { break; } else RETERR(byte_atob(c, target, state)); isc_textregion_consume(&token.value.as_textregion, 1); } /* * Number of bytes. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if ((token.value.as_ulong % 4) != 0U) isc_buffer_subtract(target, 4 - (token.value.as_ulong % 4)); /* * Checksum. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); oeor = strtol(DNS_AS_STR(token), &e, 16); if (*e != 0) return (DNS_R_SYNTAX); /* * Checksum. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); osum = strtol(DNS_AS_STR(token), &e, 16); if (*e != 0) return (DNS_R_SYNTAX); /* * Checksum. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); orot = strtol(DNS_AS_STR(token), &e, 16); if (*e != 0) return (DNS_R_SYNTAX); if ((oeor != Ceor) || (osum != Csum) || (orot != Crot)) return(DNS_R_BADCKSUM); return (ISC_R_SUCCESS);}/* * Encode binary byte c into ASCII representation and place into *bufp, * advancing bufp. */static isc_result_tbyte_btoa(int c, isc_buffer_t *target, struct state *state) { isc_region_t tr; isc_buffer_availableregion(target, &tr); Ceor ^= c; Csum += c; Csum += 1; if ((Crot & 0x80000000)) { Crot <<= 1; Crot += 1; } else { Crot <<= 1; } Crot += c; word <<= 8; word |= c; if (bcount == 3) { if (word == 0) { if (tr.length < 1) return (ISC_R_NOSPACE); tr.base[0] = 'z'; isc_buffer_add(target, 1); } else { register int tmp = 0; register isc_int32_t tmpword = word; if (tmpword < 0) { /* * Because some don't support u_long. */ tmp = 32; tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32); } if (tmpword < 0) { tmp = 64; tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32); } if (tr.length < 5) return (ISC_R_NOSPACE); tr.base[0] = atob_digits[(tmpword / (isc_int32_t)(85 * 85 * 85 * 85)) + tmp]; tmpword %= (isc_int32_t)(85 * 85 * 85 * 85); tr.base[1] = atob_digits[tmpword / (85 * 85 * 85)]; tmpword %= (85 * 85 * 85); tr.base[2] = atob_digits[tmpword / (85 * 85)]; tmpword %= (85 * 85); tr.base[3] = atob_digits[tmpword / 85]; tmpword %= 85; tr.base[4] = atob_digits[tmpword]; isc_buffer_add(target, 5); } bcount = 0; } else { bcount += 1; } return (ISC_R_SUCCESS);}/* * Encode the binary data from inbuf, of length inbuflen, into a * target. Return success/failure status */static isc_result_tbtoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target) { int inc; struct state statebuf, *state = &statebuf; char buf[sizeof("x 2000000000 ffffffff ffffffff ffffffff")]; Ceor = Csum = Crot = word = bcount = 0; for (inc = 0; inc < inbuflen; inbuf++, inc++) RETERR(byte_btoa(*inbuf, target, state)); while (bcount != 0) RETERR(byte_btoa(0, target, state)); /* * Put byte count and checksum information at end of buffer, * delimited by 'x' */ snprintf(buf, sizeof(buf), "x %d %x %x %x", inbuflen, Ceor, Csum, Crot); return (str_totext(buf, target));}static voiddefault_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, ...){ va_list ap; UNUSED(callbacks); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); fprintf(stderr, "\n");}static voidfromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) { if (isc_lex_isfile(lexer) && callbacks != NULL) { const char *name = isc_lex_getsourcename(lexer); if (name == NULL) name = "UNKNOWN"; (*callbacks->warn)(callbacks, "%s:%lu: file does not end with newline", name, isc_lex_getsourceline(lexer)); }}static voidwarn_badname(dns_name_t *name, isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks){ const char *file; unsigned long line; char namebuf[DNS_NAME_FORMATSIZE]; if (lexer != NULL) { file = isc_lex_getsourcename(lexer); line = isc_lex_getsourceline(lexer); dns_name_format(name, namebuf, sizeof(namebuf)); (*callbacks->warn)(callbacks, "%s:%u: %s: %s", file, line, namebuf, dns_result_totext(DNS_R_BADNAME)); }}static voidfromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...), dns_rdatacallbacks_t *callbacks, const char *name, unsigned long line, isc_token_t *token, isc_result_t result){ if (name == NULL) name = "UNKNOWN"; if (token != NULL) { switch (token->type) { case isc_tokentype_eol: (*callback)(callbacks, "%s: %s:%lu: near eol: %s", "dns_rdata_fromtext", name, line, dns_result_totext(result)); break; case isc_tokentype_eof: (*callback)(callbacks, "%s: %s:%lu: near eof: %s", "dns_rdata_fromtext", name, line, dns_result_totext(result)); break; case isc_tokentype_number: (*callback)(callbacks, "%s: %s:%lu: near %lu: %s", "dns_rdata_fromtext", name, line, token->value.as_ulong, dns_result_totext(result)); break; case isc_tokentype_string: case isc_tokentype_qstring: (*callback)(callbacks, "%s: %s:%lu: near '%s': %s", "dns_rdata_fromtext", name, line, DNS_AS_STR(*token), dns_result_totext(result)); break; default: (*callback)(callbacks, "%s: %s:%lu: %s", "dns_rdata_fromtext", name, line, dns_result_totext(result)); break; } } else { (*callback)(callbacks, "dns_rdata_fromtext: %s:%lu: %s", name, line, dns_result_totext(result)); }}dns_rdatatype_tdns_rdata_covers(dns_rdata_t *rdata) { if (rdata->type == 46) return (covers_rrsig(rdata)); return (covers_sig(rdata));}isc_boolean_tdns_rdatatype_ismeta(dns_rdatatype_t type) { if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_META) != 0) return (ISC_TRUE); return (ISC_FALSE);}isc_boolean_tdns_rdatatype_issingleton(dns_rdatatype_t type) { if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_SINGLETON) != 0) return (ISC_TRUE); return (ISC_FALSE);}isc_boolean_tdns_rdatatype_notquestion(dns_rdatatype_t type) { if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_NOTQUESTION) != 0) return (ISC_TRUE); return (ISC_FALSE);}isc_boolean_tdns_rdatatype_questiononly(dns_rdatatype_t type) { if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_QUESTIONONLY) != 0) return (ISC_TRUE); return (ISC_FALSE);}isc_boolean_tdns_rdatatype_atparent(dns_rdatatype_t type) { if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_ATPARENT) != 0) return (ISC_TRUE); return (ISC_FALSE);}isc_boolean_tdns_rdataclass_ismeta(dns_rdataclass_t rdclass) { if (rdclass == dns_rdataclass_reserved0 || rdclass == dns_rdataclass_none || rdclass == dns_rdataclass_any) return (ISC_TRUE); return (ISC_FALSE); /* Assume it is not a meta class. */}isc_boolean_tdns_rdatatype_isdnssec(dns_rdatatype_t type) { if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_DNSSEC) != 0) return (ISC_TRUE); return (ISC_FALSE);}isc_boolean_tdns_rdatatype_iszonecutauth(dns_rdatatype_t type) { if ((dns_rdatatype_attributes(type) & (DNS_RDATATYPEATTR_DNSSEC | DNS_RDATATYPEATTR_ZONECUTAUTH)) != 0) return (ISC_TRUE); return (ISC_FALSE);}isc_boolean_tdns_rdatatype_isknown(dns_rdatatype_t type) { if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_UNKNOWN) == 0) return (ISC_TRUE); return (ISC_FALSE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -