📄 rdata.c
字号:
isc_buffer_forward(source, activelength); result = ISC_R_SUCCESS; } } /* * We should have consumed all of our buffer. */ if (result == ISC_R_SUCCESS && !buffer_empty(source)) result = DNS_R_EXTRADATA; if (rdata != NULL && result == ISC_R_SUCCESS) { region.base = isc_buffer_used(&st); region.length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st); dns_rdata_fromregion(rdata, rdclass, type, ®ion); } if (result != ISC_R_SUCCESS) { *source = ss; *target = st; } return (result);}isc_result_tdns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx, isc_buffer_t *target){ isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_boolean_t use_default = ISC_FALSE; isc_region_t tr; isc_buffer_t st; REQUIRE(rdata != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); /* * Some DynDNS meta-RRs have empty rdata. */ if ((rdata->flags & DNS_RDATA_UPDATE) != 0) { INSIST(rdata->length == 0); return (ISC_R_SUCCESS); } st = *target; TOWIRESWITCH if (use_default) { isc_buffer_availableregion(target, &tr); if (tr.length < rdata->length) return (ISC_R_NOSPACE); memcpy(tr.base, rdata->data, rdata->length); isc_buffer_add(target, rdata->length); return (ISC_R_SUCCESS); } if (result != ISC_R_SUCCESS) { *target = st; INSIST(target->used < 65536); dns_compress_rollback(cctx, (isc_uint16_t)target->used); } return (result);}/* * If the binary data in 'src' is valid uncompressed wire format * rdata of class 'rdclass' and type 'type', return ISC_R_SUCCESS * and copy the validated rdata to 'dest'. Otherwise return an error. */static isc_result_trdata_validate(isc_buffer_t *src, isc_buffer_t *dest, dns_rdataclass_t rdclass, dns_rdatatype_t type){ dns_decompress_t dctx; dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE); isc_buffer_setactive(src, isc_buffer_usedlength(src)); result = dns_rdata_fromwire(&rdata, rdclass, type, src, &dctx, ISC_FALSE, dest); dns_decompress_invalidate(&dctx); return (result);}static isc_result_tunknown_fromtext(dns_rdataclass_t rdclass, dns_rdatatype_t type, isc_lex_t *lexer, isc_mem_t *mctx, isc_buffer_t *target){ isc_result_t result; isc_buffer_t *buf = NULL; isc_token_t token; if (type == 0 || dns_rdatatype_ismeta(type)) return (DNS_R_METATYPE); result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE); if (result == ISC_R_SUCCESS && token.value.as_ulong > 65535U) return (ISC_R_RANGE); result = isc_buffer_allocate(mctx, &buf, token.value.as_ulong); if (result != ISC_R_SUCCESS) return (result); result = isc_hex_tobuffer(lexer, buf, (unsigned int)token.value.as_ulong); if (result != ISC_R_SUCCESS) goto failure; if (isc_buffer_usedlength(buf) != token.value.as_ulong) { result = ISC_R_UNEXPECTEDEND; goto failure; } if (dns_rdatatype_isknown(type)) { result = rdata_validate(buf, target, rdclass, type); } else { isc_region_t r; isc_buffer_usedregion(buf, &r); result = isc_buffer_copyregion(target, &r); } if (result != ISC_R_SUCCESS) goto failure; isc_buffer_free(&buf); return (ISC_R_SUCCESS); failure: isc_buffer_free(&buf); return (result);}isc_result_tdns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass, dns_rdatatype_t type, isc_lex_t *lexer, dns_name_t *origin, isc_boolean_t downcase, isc_mem_t *mctx, isc_buffer_t *target, dns_rdatacallbacks_t *callbacks){ isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_region_t region; isc_buffer_t st; isc_token_t token; unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF | ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE; char *name; unsigned long line; void (*callback)(dns_rdatacallbacks_t *, const char *, ...); isc_result_t tresult; REQUIRE(origin == NULL || dns_name_isabsolute(origin) == ISC_TRUE); if (rdata != NULL) { REQUIRE(DNS_RDATA_INITIALIZED(rdata)); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); } if (callbacks != NULL) { REQUIRE(callbacks->warn != NULL); REQUIRE(callbacks->error != NULL); } st = *target; if (callbacks != NULL) callback = callbacks->error; else callback = default_fromtext_callback; result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, ISC_FALSE); if (result != ISC_R_SUCCESS) { name = isc_lex_getsourcename(lexer); line = isc_lex_getsourceline(lexer); fromtext_error(callback, callbacks, name, line, &token, result); return (result); } if (strcmp((char *)token.value.as_pointer, "\\#") == 0) result = unknown_fromtext(rdclass, type, lexer, mctx, target); else { isc_lex_ungettoken(lexer, &token); FROMTEXTSWITCH } /* * Consume to end of line / file. * If not at end of line initially set error code. * Call callback via fromtext_error once if there was an error. */ do { name = isc_lex_getsourcename(lexer); line = isc_lex_getsourceline(lexer); tresult = isc_lex_gettoken(lexer, options, &token); if (tresult != ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) result = tresult; if (callback != NULL) fromtext_error(callback, callbacks, name, line, NULL, result); break; } else if (token.type != isc_tokentype_eol && token.type != isc_tokentype_eof) { if (result == ISC_R_SUCCESS) result = DNS_R_EXTRATOKEN; if (callback != NULL) { fromtext_error(callback, callbacks, name, line, &token, result); callback = NULL; } } else if (result != ISC_R_SUCCESS && callback != NULL) { fromtext_error(callback, callbacks, name, line, &token, result); break; } else { if (token.type == isc_tokentype_eof) fromtext_warneof(lexer, callbacks); break; } } while (1); if (rdata != NULL && result == ISC_R_SUCCESS) { region.base = isc_buffer_used(&st); region.length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st); dns_rdata_fromregion(rdata, rdclass, type, ®ion); } if (result != ISC_R_SUCCESS) { *target = st; } return (result);}static isc_result_trdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, isc_buffer_t *target){ isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_boolean_t use_default = ISC_FALSE; char buf[sizeof("65536")]; isc_region_t sr; REQUIRE(rdata != NULL); REQUIRE(tctx->origin == NULL || dns_name_isabsolute(tctx->origin) == ISC_TRUE); /* * Some DynDNS meta-RRs have empty rdata. */ if ((rdata->flags & DNS_RDATA_UPDATE) != 0) { INSIST(rdata->length == 0); return (ISC_R_SUCCESS); } TOTEXTSWITCH if (use_default) { sprintf(buf, "\\# "); result = str_totext(buf, target); dns_rdata_toregion(rdata, &sr); INSIST(sr.length < 65536); sprintf(buf, "%u", sr.length); result = str_totext(buf, target); if (sr.length != 0 && result == ISC_R_SUCCESS) { if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) result = str_totext(" ( ", target); else result = str_totext(" ", target); if (result == ISC_R_SUCCESS) result = isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak, target); if (result == ISC_R_SUCCESS && (tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) result = str_totext(" )", target); } } return (result);}isc_result_tdns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target){ dns_rdata_textctx_t tctx; REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); /* * Set up formatting options for single-line output. */ tctx.origin = origin; tctx.flags = 0; tctx.width = 60; tctx.linebreak = " "; return (rdata_totext(rdata, &tctx, target));}isc_result_tdns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin, unsigned int flags, unsigned int width, char *linebreak, isc_buffer_t *target){ dns_rdata_textctx_t tctx; REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); /* * Set up formatting options for formatted output. */ tctx.origin = origin; tctx.flags = flags; if ((flags & DNS_STYLEFLAG_MULTILINE) != 0) { tctx.width = width; tctx.linebreak = linebreak; } else { tctx.width = 60; /* Used for hex word length only. */ tctx.linebreak = " "; } return (rdata_totext(rdata, &tctx, target));}isc_result_tdns_rdata_fromstruct(dns_rdata_t *rdata, dns_rdataclass_t rdclass, dns_rdatatype_t type, void *source, isc_buffer_t *target){ isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_buffer_t st; isc_region_t region; isc_boolean_t use_default = ISC_FALSE; REQUIRE(source != NULL); if (rdata != NULL) { REQUIRE(DNS_RDATA_INITIALIZED(rdata)); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); } st = *target; FROMSTRUCTSWITCH if (use_default) (void)NULL; if (rdata != NULL && result == ISC_R_SUCCESS) { region.base = isc_buffer_used(&st); region.length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st); dns_rdata_fromregion(rdata, rdclass, type, ®ion); } if (result != ISC_R_SUCCESS) *target = st; return (result);}isc_result_tdns_rdata_tostruct(dns_rdata_t *rdata, void *target, isc_mem_t *mctx) { isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_boolean_t use_default = ISC_FALSE; REQUIRE(rdata != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); TOSTRUCTSWITCH if (use_default) (void)NULL; return (result);}voiddns_rdata_freestruct(void *source) { dns_rdatacommon_t *common = source; REQUIRE(source != NULL); FREESTRUCTSWITCH}isc_result_tdns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add, void *arg){ isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_boolean_t use_default = ISC_FALSE; /* * Call 'add' for each name and type from 'rdata' which is subject to * additional section processing. */ REQUIRE(rdata != NULL); REQUIRE(add != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); ADDITIONALDATASWITCH /* No additional processing for unknown types */ if (use_default) result = ISC_R_SUCCESS; return (result);}isc_result_tdns_rdata_digest(dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg) { isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_boolean_t use_default = ISC_FALSE; isc_region_t r; /* * Send 'rdata' in DNSSEC canonical form to 'digest'. */ REQUIRE(rdata != NULL); REQUIRE(digest != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); DIGESTSWITCH if (use_default) { dns_rdata_toregion(rdata, &r); result = (digest)(arg, &r); } return (result);}unsigned intdns_rdatatype_attributes(dns_rdatatype_t type){ if (type < (sizeof(typeattr)/sizeof(typeattr[0]))) return (typeattr[type].flags); return (DNS_RDATATYPEATTR_UNKNOWN);}#define NUMBERSIZE sizeof("037777777777") /* 2^32-1 octal + NUL */static isc_result_tdns_mnemonic_fromtext(unsigned int *valuep, isc_textregion_t *source, struct tbl *table, unsigned int max){ int i; if (isdigit(source->base[0] & 0xff) && source->length <= NUMBERSIZE - 1) { unsigned int n; char *e; char buffer[NUMBERSIZE]; /* * We have a potential number. Try to parse it with strtoul(). * strtoul() requires null termination, so we must make * a copy. */ strncpy(buffer, source->base, NUMBERSIZE); INSIST(buffer[source->length] == '\0'); n = strtoul(buffer, &e, 10); if (*e == 0) { if (n > max) return (ISC_R_RANGE); *valuep = n; return (ISC_R_SUCCESS); } /* * It was not a number after all; fall through. */ } for (i = 0; table[i].name != NULL; i++) { unsigned int n; n = strlen(table[i].name); if (n == source->length && strncasecmp(source->base, table[i].name, n) == 0) { *valuep = table[i].value; return (ISC_R_SUCCESS); } } return (DNS_R_UNKNOWN);}static isc_result_tdns_mnemonic_totext(unsigned int value, isc_buffer_t *target, struct tbl *table){ int i = 0; char buf[sizeof "4294967296"]; while (table[i].name != NULL) { if (table[i].value == value) { return (str_totext(table[i].name, target)); } i++; } sprintf(buf, "%u", value); return (str_totext(buf, target));}/* * This uses lots of hard coded values, but how often do we actually * add classes? */isc_result_tdns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source) {#define COMPARE(string, rdclass) \ if (((sizeof(string) - 1) == source->length) \ && (strncasecmp(source->base, string, source->length) == 0)) { \ *classp = rdclass; \ return (ISC_R_SUCCESS); \ } switch (tolower((unsigned char)source->base[0])) { case 'a': COMPARE("any", dns_rdataclass_any); break; case 'c': /* * RFC1035 says the mnemonic for the CHAOS class is CH, * but historical BIND practice is to call it CHAOS. * We will accept both forms, but only generate CH. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -