📄 rdata.c
字号:
/* * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *//* $Id: rdata.c,v 1.147.2.11 2003/07/30 01:04:15 marka Exp $ */#include <config.h>#include <ctype.h>#include <isc/base64.h>#include <isc/hex.h>#include <isc/lex.h>#include <isc/mem.h>#include <isc/print.h>#include <isc/string.h>#include <isc/util.h>#include <dns/callbacks.h>#include <dns/cert.h>#include <dns/compress.h>#include <dns/keyflags.h>#include <dns/rcode.h>#include <dns/rdata.h>#include <dns/rdataclass.h>#include <dns/rdatastruct.h>#include <dns/rdatatype.h>#include <dns/result.h>#include <dns/secalg.h>#include <dns/secproto.h>#include <dns/time.h>#include <dns/ttl.h>#define RETERR(x) \ do { \ isc_result_t _r = (x); \ if (_r != ISC_R_SUCCESS) \ return (_r); \ } while (0)#define RETTOK(x) \ do { \ isc_result_t _r = (x); \ if (_r != ISC_R_SUCCESS) { \ isc_lex_ungettoken(lexer, &token); \ return (_r); \ } \ } while (0)#define ARGS_FROMTEXT int rdclass, dns_rdatatype_t type, \ isc_lex_t *lexer, dns_name_t *origin, \ isc_boolean_t downcase, isc_buffer_t *target, \ dns_rdatacallbacks_t *callbacks#define ARGS_TOTEXT dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, \ isc_buffer_t *target#define ARGS_FROMWIRE int rdclass, dns_rdatatype_t type, \ isc_buffer_t *source, dns_decompress_t *dctx, \ isc_boolean_t downcase, isc_buffer_t *target#define ARGS_TOWIRE dns_rdata_t *rdata, dns_compress_t *cctx, \ isc_buffer_t *target#define ARGS_COMPARE const dns_rdata_t *rdata1, const dns_rdata_t *rdata2#define ARGS_FROMSTRUCT int rdclass, dns_rdatatype_t type, \ void *source, isc_buffer_t *target#define ARGS_TOSTRUCT dns_rdata_t *rdata, void *target, isc_mem_t *mctx#define ARGS_FREESTRUCT void *source#define ARGS_ADDLDATA dns_rdata_t *rdata, dns_additionaldatafunc_t add, \ void *arg#define ARGS_DIGEST dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg/* * Context structure for the totext_ functions. * Contains formatting options for rdata-to-text * conversion. */typedef struct dns_rdata_textctx { dns_name_t *origin; /* Current origin, or NULL. */ unsigned int flags; /* DNS_STYLEFLAG_* */ unsigned int width; /* Width of rdata column. */ const char *linebreak; /* Line break string. */} dns_rdata_textctx_t;static isc_result_ttxt_totext(isc_region_t *source, isc_buffer_t *target);static isc_result_ttxt_fromtext(isc_textregion_t *source, isc_buffer_t *target);static isc_result_ttxt_fromwire(isc_buffer_t *source, isc_buffer_t *target);static isc_boolean_tname_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target);static unsigned intname_length(dns_name_t *name);static isc_result_tstr_totext(const char *source, isc_buffer_t *target);static isc_result_tinet_totext(int af, isc_region_t *src, isc_buffer_t *target);static isc_boolean_tbuffer_empty(isc_buffer_t *source);static voidbuffer_fromregion(isc_buffer_t *buffer, isc_region_t *region);static isc_result_tuint32_tobuffer(isc_uint32_t, isc_buffer_t *target);static isc_result_tuint16_tobuffer(isc_uint32_t, isc_buffer_t *target);static isc_result_tuint8_tobuffer(isc_uint32_t, isc_buffer_t *target);static isc_result_tname_tobuffer(dns_name_t *name, isc_buffer_t *target);static isc_uint32_tuint32_fromregion(isc_region_t *region);static isc_uint16_tuint16_fromregion(isc_region_t *region);static isc_uint8_tuint8_fromregion(isc_region_t *region);static isc_result_tmem_tobuffer(isc_buffer_t *target, void *base, unsigned int length);static intcompare_region(isc_region_t *r1, isc_region_t *r2);static inthexvalue(char value);static intdecvalue(char value);static isc_result_tbtoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target);static isc_result_tatob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target);static voiddefault_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *, ...) ISC_FORMAT_PRINTF(2, 3);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);static voidfromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks);static isc_result_trdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, isc_buffer_t *target);static inline intgetquad(const void *src, struct in_addr *dst, isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks){ int result; struct in_addr *tmp; result = inet_aton(src, dst); if (result == 1 && callbacks != NULL && inet_pton(AF_INET, src, &tmp) != 1) { const char *name = isc_lex_getsourcename(lexer); if (name == NULL) name = "UNKNOWN"; (*callbacks->warn)(callbacks, "%s:%lu: warning \"%s\" " "is not a decimal dotted quad", name, isc_lex_getsourceline(lexer), src); } return (result);}static inline isc_result_tname_duporclone(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) { if (mctx != NULL) return (dns_name_dup(source, mctx, target)); dns_name_clone(source, target); return (ISC_R_SUCCESS);}static inline void *mem_maybedup(isc_mem_t *mctx, void *source, size_t length) { void *new; if (mctx == NULL) return (source); new = isc_mem_allocate(mctx, length); if (new != NULL) memcpy(new, source, length); return (new);}static const char hexdigits[] = "0123456789abcdef";static const char decdigits[] = "0123456789";#include "code.h"#define META 0x0001#define RESERVED 0x0002#define RCODENAMES \ /* standard rcodes */ \ { dns_rcode_noerror, "NOERROR", 0}, \ { dns_rcode_formerr, "FORMERR", 0}, \ { dns_rcode_servfail, "SERVFAIL", 0}, \ { dns_rcode_nxdomain, "NXDOMAIN", 0}, \ { dns_rcode_notimp, "NOTIMP", 0}, \ { dns_rcode_refused, "REFUSED", 0}, \ { dns_rcode_yxdomain, "YXDOMAIN", 0}, \ { dns_rcode_yxrrset, "YXRRSET", 0}, \ { dns_rcode_nxrrset, "NXRRSET", 0}, \ { dns_rcode_notauth, "NOTAUTH", 0}, \ { dns_rcode_notzone, "NOTZONE", 0},#define ERCODENAMES \ /* extended rcodes */ \ { dns_rcode_badvers, "BADVERS", 0}, \ { 0, NULL, 0 }#define TSIGRCODENAMES \ /* extended rcodes */ \ { dns_tsigerror_badsig, "BADSIG", 0}, \ { dns_tsigerror_badkey, "BADKEY", 0}, \ { dns_tsigerror_badtime, "BADTIME", 0}, \ { dns_tsigerror_badmode, "BADMODE", 0}, \ { dns_tsigerror_badname, "BADNAME", 0}, \ { dns_tsigerror_badalg, "BADALG", 0}, \ { 0, NULL, 0 }/* RFC2538 section 2.1 */#define CERTNAMES \ { 1, "PKIX", 0}, \ { 2, "SPKI", 0}, \ { 3, "PGP", 0}, \ { 253, "URI", 0}, \ { 254, "OID", 0}, \ { 0, NULL, 0}/* RFC2535 section 7 */#define SECALGNAMES \ { 1, "RSAMD5", 0 }, \ { 2, "DH", 0 }, \ { 3, "DSA", 0 }, \ { 4, "ECC", 0 }, \ { 252, "INDIRECT", 0 }, \ { 253, "PRIVATEDNS", 0 }, \ { 254, "PRIVATEOID", 0 }, \ { 0, NULL, 0}/* RFC2535 section 7.1 */#define SECPROTONAMES \ { 0, "NONE", 0 }, \ { 1, "TLS", 0 }, \ { 2, "EMAIL", 0 }, \ { 3, "DNSSEC", 0 }, \ { 4, "IPSEC", 0 }, \ { 255, "ALL", 0 }, \ { 0, NULL, 0}struct tbl { unsigned int value; const char *name; int flags;};static struct tbl rcodes[] = { RCODENAMES ERCODENAMES };static struct tbl tsigrcodes[] = { RCODENAMES TSIGRCODENAMES };static struct tbl certs[] = { CERTNAMES };static struct tbl secalgs[] = { SECALGNAMES };static struct tbl secprotos[] = { SECPROTONAMES };static struct keyflag { const char *name; unsigned int value; unsigned int mask;} keyflags[] = { { "NOCONF", 0x4000, 0xC000 }, { "NOAUTH", 0x8000, 0xC000 }, { "NOKEY", 0xC000, 0xC000 }, { "FLAG2", 0x2000, 0x2000 }, { "EXTEND", 0x1000, 0x1000 }, { "FLAG4", 0x0800, 0x0800 }, { "FLAG5", 0x0400, 0x0400 }, { "USER", 0x0000, 0x0300 }, { "ZONE", 0x0100, 0x0300 }, { "HOST", 0x0200, 0x0300 }, { "NTYP3", 0x0300, 0x0300 }, { "FLAG8", 0x0080, 0x0080 }, { "FLAG9", 0x0040, 0x0040 }, { "FLAG10", 0x0020, 0x0020 }, { "FLAG11", 0x0010, 0x0010 }, { "SIG0", 0x0000, 0x000F }, { "SIG1", 0x0001, 0x000F }, { "SIG2", 0x0002, 0x000F }, { "SIG3", 0x0003, 0x000F }, { "SIG4", 0x0004, 0x000F }, { "SIG5", 0x0005, 0x000F }, { "SIG6", 0x0006, 0x000F }, { "SIG7", 0x0007, 0x000F }, { "SIG8", 0x0008, 0x000F }, { "SIG9", 0x0009, 0x000F }, { "SIG10", 0x000A, 0x000F }, { "SIG11", 0x000B, 0x000F }, { "SIG12", 0x000C, 0x000F }, { "SIG13", 0x000D, 0x000F }, { "SIG14", 0x000E, 0x000F }, { "SIG15", 0x000F, 0x000F }, { NULL, 0, 0 }};/*** *** Initialization ***/voiddns_rdata_init(dns_rdata_t *rdata) { REQUIRE(rdata != NULL); rdata->data = NULL; rdata->length = 0; rdata->rdclass = 0; rdata->type = 0; rdata->flags = 0; ISC_LINK_INIT(rdata, link); /* ISC_LIST_INIT(rdata->list); */}#if 0#define DNS_RDATA_INITIALIZED(rdata) \ ((rdata)->data == NULL && (rdata)->length == 0 && \ (rdata)->rdclass == 0 && (rdata)->type == 0 && (rdata)->flags == 0 && \ !ISC_LINK_LINKED((rdata), link))#else#ifdef ISC_LIST_CHECKINIT#define DNS_RDATA_INITIALIZED(rdata) \ (!ISC_LINK_LINKED((rdata), link))#else#define DNS_RDATA_INITIALIZED(rdata) ISC_TRUE#endif#endif#define DNS_RDATA_VALIDFLAGS(rdata) \ (((rdata)->flags & ~DNS_RDATA_UPDATE) == 0)voiddns_rdata_reset(dns_rdata_t *rdata) { REQUIRE(rdata != NULL); REQUIRE(!ISC_LINK_LINKED(rdata, link)); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); rdata->data = NULL; rdata->length = 0; rdata->rdclass = 0; rdata->type = 0; rdata->flags = 0;}/*** *** ***/voiddns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target) { REQUIRE(src != NULL); REQUIRE(target != NULL); REQUIRE(DNS_RDATA_INITIALIZED(target)); REQUIRE(DNS_RDATA_VALIDFLAGS(src)); REQUIRE(DNS_RDATA_VALIDFLAGS(target)); target->data = src->data; target->length = src->length; target->rdclass = src->rdclass; target->type = src->type; target->flags = src->flags;}/*** *** Comparisons ***/intdns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2) { int result = 0; isc_boolean_t use_default = ISC_FALSE; REQUIRE(rdata1 != NULL); REQUIRE(rdata2 != NULL); REQUIRE(rdata1->data != NULL); REQUIRE(rdata2->data != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1)); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2)); if (rdata1->rdclass != rdata2->rdclass) return (rdata1->rdclass < rdata2->rdclass ? -1 : 1); if (rdata1->type != rdata2->type) return (rdata1->type < rdata2->type ? -1 : 1); COMPARESWITCH if (use_default) { isc_region_t r1; isc_region_t r2; dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); result = compare_region(&r1, &r2); } return (result);}/*** *** Conversions ***/voiddns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass, dns_rdatatype_t type, isc_region_t *r){ REQUIRE(rdata != NULL); REQUIRE(DNS_RDATA_INITIALIZED(rdata)); REQUIRE(r != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); rdata->data = r->base; rdata->length = r->length; rdata->rdclass = rdclass; rdata->type = type; rdata->flags = 0;}voiddns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r) { REQUIRE(rdata != NULL); REQUIRE(r != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); r->base = rdata->data; r->length = rdata->length;}isc_result_tdns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass, dns_rdatatype_t type, isc_buffer_t *source, dns_decompress_t *dctx, isc_boolean_t downcase, isc_buffer_t *target){ isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_region_t region; isc_buffer_t ss; isc_buffer_t st; isc_boolean_t use_default = ISC_FALSE; isc_uint32_t activelength; REQUIRE(dctx != NULL); if (rdata != NULL) { REQUIRE(DNS_RDATA_INITIALIZED(rdata)); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); } if (type == 0) return (DNS_R_FORMERR); ss = *source; st = *target; activelength = isc_buffer_activelength(source); INSIST(activelength < 65536); FROMWIRESWITCH if (use_default) { if (activelength > isc_buffer_availablelength(target)) result = ISC_R_NOSPACE; else { isc_buffer_putmem(target, isc_buffer_current(source), activelength);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -