Commit ebfcb6cf authored by Brian Wellington's avatar Brian Wellington
Browse files

550. [func] Support unknown rdata types and classes.

parent 31eef7e2
550. [func] Support unknown rdata types and classes.
549. [bug] "make" did not immediately abort the build when a
subdirectory make failed [RT #450].
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: nsupdate.c,v 1.59 2000/11/08 00:55:26 bwelling Exp $ */
/* $Id: nsupdate.c,v 1.60 2000/11/09 23:54:53 bwelling Exp $ */
#include <config.h>
......@@ -625,8 +625,8 @@ parse_rdata(char **cmdlinep, dns_rdataclass_t rdataclass,
check_result(result, "isc_buffer_allocate");
result = dns_rdata_fromtext(rdata, rdataclass,
rdatatype,
lex, rn, ISC_FALSE, buf,
&callbacks);
lex, rn, ISC_FALSE, mctx,
buf, &callbacks);
bufsz *= 2;
isc_lex_destroy(&lex);
} while (result == ISC_R_NOSPACE);
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rdata_test.c,v 1.31 2000/08/01 01:13:16 tale Exp $ */
/* $Id: rdata_test.c,v 1.32 2000/11/09 23:54:55 bwelling Exp $ */
#include <config.h>
......@@ -929,7 +929,8 @@ main(int argc, char *argv[]) {
dns_rdata_init(&rdata);
isc_buffer_init(&dbuf, inbuf, sizeof(inbuf));
result = dns_rdata_fromtext(&rdata, class, type, lex,
NULL, ISC_FALSE, &dbuf, NULL);
NULL, ISC_FALSE, mctx, &dbuf,
NULL);
if (result != ISC_R_SUCCESS) {
fprintf(stdout,
"dns_rdata_fromtext returned %s(%d)\n",
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: gen.c,v 1.56 2000/11/09 03:03:47 bwelling Exp $ */
/* $Id: gen.c,v 1.57 2000/11/09 23:54:56 bwelling Exp $ */
#include <config.h>
......@@ -37,7 +37,7 @@
#define FROMTEXTARGS "rdclass, type, lexer, origin, downcase, target"
#define FROMTEXTCLASS "rdclass"
#define FROMTEXTTYPE "type"
#define FROMTEXTDEF "use_default = ISC_TRUE"
#define FROMTEXTDEF "result = DNS_R_UNKNOWN"
#define TOTEXTARGS "rdata, tctx, target"
#define TOTEXTCLASS "rdata->rdclass"
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rdata.h,v 1.47 2000/11/09 19:33:48 gson Exp $ */
/* $Id: rdata.h,v 1.48 2000/11/09 23:55:01 bwelling Exp $ */
#ifndef DNS_RDATA_H
#define DNS_RDATA_H 1
......@@ -294,8 +294,8 @@ dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx,
isc_result_t
dns_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_buffer_t *target,
dns_rdatacallbacks_t *callbacks);
isc_boolean_t downcase, isc_mem_t *mctx,
isc_buffer_t *target, dns_rdatacallbacks_t *callbacks);
/*
* Convert the textual representation of a DNS rdata into uncompressed wire
* form stored in the target region. Tokens constituting the text of the rdata
......@@ -314,6 +314,8 @@ dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
*
* 'lexer' is a valid isc_lex_t.
*
* 'mctx' is a valid isc_mem_t.
*
* 'target' is a valid region.
*
* 'origin' if non NULL it must be absolute.
......@@ -333,6 +335,7 @@ dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
* <Various 'Bad Form' class failures depending on class and type>
* Bad Form: Input too short
* Resource Limit: Not enough space
* Resource Limit: Not enough memory
*/
isc_result_t
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rdataclass.h,v 1.14 2000/08/01 01:24:31 tale Exp $ */
/* $Id: rdataclass.h,v 1.15 2000/11/09 23:55:02 bwelling Exp $ */
#ifndef DNS_RDATACLASS_H
#define DNS_RDATACLASS_H 1
......@@ -39,7 +39,6 @@ dns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source);
* Returns:
* ISC_R_SUCCESS on success
* DNS_R_UNKNOWN class is unknown
* ISC_R_NOTIMPLEMENTED class is known, but not implemented
*/
isc_result_t
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rdatatype.h,v 1.13 2000/08/01 01:24:37 tale Exp $ */
/* $Id: rdatatype.h,v 1.14 2000/11/09 23:55:03 bwelling Exp $ */
#ifndef DNS_RDATATYPE_H
#define DNS_RDATATYPE_H 1
......@@ -39,7 +39,6 @@ dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source);
* Returns:
* ISC_R_SUCCESS on success
* DNS_R_UNKNOWN type is unknown
* ISC_R_NOTIMPLEMENTED type is known, but not implemented
*/
isc_result_t
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: master.c,v 1.78 2000/11/08 00:18:18 gson Exp $ */
/* $Id: master.c,v 1.79 2000/11/09 23:54:57 bwelling Exp $ */
#include <config.h>
......@@ -639,7 +639,7 @@ generate(dns_loadctx_t *ctx, char *range, char *lhs, char *gtype, char *rhs) {
isc_buffer_init(&target, target_mem, target_size);
result = dns_rdata_fromtext(&rdata, ctx->zclass, type,
ctx->lex, ctx->origin, ISC_FALSE,
&target, callbacks);
ctx->mctx, &target, callbacks);
isc_lex_close(ctx->lex);
if (result != ISC_R_SUCCESS)
goto error_cleanup;
......@@ -1295,8 +1295,8 @@ load(dns_loadctx_t **ctxp) {
*/
dns_rdata_init(&rdata[rdcount]);
result = dns_rdata_fromtext(&rdata[rdcount], ctx->zclass, type,
ctx->lex, ctx->origin, ISC_FALSE, &target,
callbacks);
ctx->lex, ctx->origin, ISC_FALSE, ctx->mctx,
&target, callbacks);
if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
if (type == dns_rdatatype_sig)
......
......@@ -15,12 +15,13 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rdata.c,v 1.119 2000/11/09 00:20:47 bwelling Exp $ */
/* $Id: rdata.c,v 1.120 2000/11/09 23:54:59 bwelling 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/string.h>
......@@ -533,115 +534,36 @@ dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx,
}
isc_result_t
dns_rdata_fromtextgeneric(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
dns_rdatatype_t type, isc_lex_t *lexer,
isc_buffer_t *target,
dns_rdatacallbacks_t *callbacks)
rdata_valid(isc_buffer_t *buf, dns_rdataclass_t rdclass, dns_rdatatype_t type,
isc_mem_t *mctx)
{
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 iresult;
if (rdata != NULL) {
REQUIRE(DNS_RDATA_INITIALIZED(rdata));
REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
isc_buffer_t *tbuf = NULL;
dns_decompress_t dctx;
dns_rdata_t rdata;
isc_result_t result;
dns_decompress_init(&dctx, -1, ISC_TRUE);
dns_rdata_init(&rdata);
result = isc_buffer_allocate(mctx, &tbuf, isc_buffer_length(buf));
if (result == ISC_R_SUCCESS) {
result = dns_rdata_fromwire(&rdata, rdclass, type, buf, &dctx,
ISC_FALSE, &tbuf);
isc_buffer_free(tbuf);
}
dns_decompress_invalidate(&dctx);
st = *target;
region.base = (unsigned char *)(target->base) + target->used;
result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
ISC_FALSE);
if (result == ISC_R_SUCCESS && token.value.as_ulong > 65535)
result = ISC_R_RANGE;
if (result == ISC_R_SUCCESS)
result = isc_base64_tobuffer(lexer, target,
token.value.as_ulong);
if (callbacks == NULL)
callback = NULL;
else
callback = callbacks->error;
if (callback == NULL)
callback = default_fromtext_callback;
/*
* 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);
iresult = isc_lex_gettoken(lexer, options, &token);
if (iresult != ISC_R_SUCCESS) {
if (result == ISC_R_SUCCESS) {
switch (iresult) {
case ISC_R_NOMEMORY:
result = ISC_R_NOMEMORY;
break;
case ISC_R_NOSPACE:
result = ISC_R_NOSPACE;
break;
default:
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_lex_gettoken() failed: %s",
isc_result_totext(result));
result = ISC_R_UNEXPECTED;
break;
}
}
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.length = target->used - st.used;
dns_rdata_fromregion(rdata, rdclass, type, &region);
}
if (result != ISC_R_SUCCESS) {
*target = st;
}
return (result);
}
isc_result_t
dns_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,
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_boolean_t use_default = ISC_FALSE;
isc_token_t token;
unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF |
ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE;
......@@ -659,17 +581,25 @@ dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
st = *target;
region.base = (unsigned char *)(target->base) + target->used;
FROMTEXTSWITCH
if (use_default) {
result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
ISC_FALSE);
if (result != ISC_R_SUCCESS)
return (result);
if (strcmp((char *)token.value.as_pointer, "\\#") == 0) {
result = isc_lex_getmastertoken(lexer, &token,
isc_tokentype_number,
ISC_FALSE);
if (result == ISC_R_SUCCESS && token.value.as_ulong > 65535)
result = ISC_R_RANGE;
if (result == ISC_R_SUCCESS)
result = isc_base64_tobuffer(lexer, target,
token.value.as_ulong);
result = isc_hex_tobuffer(lexer, target,
token.value.as_ulong);
if (result == ISC_R_SUCCESS && dns_rdatatype_isknown(type))
result = rdata_valid(target, rdclass, type, mctx);
} else {
isc_lex_ungettoken(lexer, &token);
FROMTEXTSWITCH
}
if (callbacks == NULL)
......@@ -763,6 +693,8 @@ rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
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);
......@@ -773,9 +705,9 @@ rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
else
result = str_totext(" ", target);
if (result == ISC_R_SUCCESS)
result = isc_base64_totext(&sr, tctx->width - 2,
tctx->linebreak,
target);
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);
......@@ -820,7 +752,7 @@ dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin,
tctx.width = width;
tctx.linebreak = linebreak;
} else {
tctx.width = 60; /* Used for base64 word length only. */
tctx.width = 60; /* Used for hex word length only. */
tctx.linebreak = " ";
}
return (rdata_totext(rdata, &tctx, target));
......@@ -1009,27 +941,16 @@ dns_mnemonic_totext(unsigned int value, isc_buffer_t *target,
*/
isc_result_t
dns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source) {
unsigned int attrs;
/*
* Note: attrs is set and then used in the bit test with RESERVED
* because testing "(flags & RESERVED) != 0" generates
* warnings on IRIX about how the test always has the same value
* because it is all constants.
*/
#define COMPARE(string, flags, type) \
#define COMPARE(string, rdclass) \
if (((sizeof(string) - 1) == source->length) \
&& (strcasecmp(source->base, string) == 0)) { \
*classp = type; \
attrs = flags; \
if ((attrs & RESERVED) != 0) \
return (ISC_R_NOTIMPLEMENTED); \
*classp = rdclass; \
return (ISC_R_SUCCESS); \
}
switch (tolower((unsigned char)source->base[0])) {
case 'a':
COMPARE("any", META, dns_rdataclass_any);
COMPARE("any", dns_rdataclass_any);
break;
case 'c':
/*
......@@ -1037,20 +958,30 @@ dns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source) {
* but historical BIND practice is to call it CHAOS.
* We will accept both forms, but only generate CH.
*/
COMPARE("ch", 0, dns_rdataclass_chaos);
COMPARE("chaos", 0, dns_rdataclass_chaos);
COMPARE("ch", dns_rdataclass_chaos);
COMPARE("chaos", dns_rdataclass_chaos);
if (source->length > 5 &&
strncasecmp("class", source->base, 5) == 0)
{
char *endp;
int val = strtol(source->base + 5, &endp, 10);
if (*endp == '\0' && val >= 0 && val <= 0xffff) {
*classp = (dns_rdataclass_t)val;
return (ISC_R_SUCCESS);
}
}
break;
case 'h':
COMPARE("hs", 0, dns_rdataclass_hs);
COMPARE("hs", dns_rdataclass_hs);
break;
case 'i':
COMPARE("in", 0, dns_rdataclass_in);
COMPARE("in", dns_rdataclass_in);
break;
case 'n':
COMPARE("none", META, dns_rdataclass_none);
COMPARE("none", dns_rdataclass_none);
break;
case 'r':
COMPARE("reserved0", META|RESERVED, dns_rdataclass_reserved0);
COMPARE("reserved0", dns_rdataclass_reserved0);
break;
}
......@@ -1061,7 +992,7 @@ dns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source) {
isc_result_t
dns_rdataclass_totext(dns_rdataclass_t rdclass, isc_buffer_t *target) {
char buf[sizeof("RDCLASS4294967296")];
char buf[sizeof("CLASS65536")];
switch (rdclass) {
case dns_rdataclass_any:
......@@ -1077,7 +1008,7 @@ dns_rdataclass_totext(dns_rdataclass_t rdclass, isc_buffer_t *target) {
case dns_rdataclass_reserved0:
return (str_totext("RESERVED0", target));
default:
sprintf(buf, "RDCLASS%u", rdclass);
sprintf(buf, "CLASS%u", rdclass);
return (str_totext(buf, target));
}
......@@ -1106,12 +1037,21 @@ dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source) {
*/
RDATATYPE_FROMTEXT_SW(hash, source->base, typep);
if (source->length > 4 && strncasecmp("type", source->base, 4) == 0) {
char *endp;
int val = strtol(source->base + 4, &endp, 10);
if (*endp == '\0' && val >= 0 && val <= 0xffff) {
*typep = (dns_rdatatype_t)val;
return (ISC_R_SUCCESS);
}
}
return (DNS_R_UNKNOWN);
}
isc_result_t
dns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target) {
char buf[sizeof "TYPE4294967296"];
char buf[sizeof "TYPE65536"];
if (type > 255) {
sprintf(buf, "TYPE%u", type);
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: sdb.c,v 1.12 2000/10/18 23:53:27 marka Exp $ */
/* $Id: sdb.c,v 1.13 2000/11/09 23:55:00 bwelling Exp $ */
/* NOMINUM_PUBLIC_DELETE */
......@@ -322,7 +322,7 @@ dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl,
result = dns_rdata_fromtext(rdata, rdatalist->rdclass,
rdatalist->type, lex,
origin, ISC_FALSE,
rdatabuf, NULL);
mctx, rdatabuf, NULL);
if (result != ISC_R_SUCCESS)
isc_buffer_free(&rdatabuf);
size *= 2;
......
......@@ -19,7 +19,7 @@
/*
* Principal Author: Brian Wellington
* $Id: dst_api.c,v 1.65 2000/11/01 00:17:17 bwelling Exp $
* $Id: dst_api.c,v 1.66 2000/11/09 23:55:05 bwelling Exp $
*/
#include <config.h>
......@@ -929,7 +929,7 @@ read_public_key(const char *filename, isc_mem_t *mctx, dst_key_t **keyp) {
isc_buffer_init(&b, rdatabuf, sizeof(rdatabuf));
ret = dns_rdata_fromtext(&rdata, rdclass, dns_rdatatype_key,
lex, NULL, ISC_FALSE, &b, NULL);
lex, NULL, ISC_FALSE, mctx, &b, NULL);
if (ret != ISC_R_SUCCESS)
goto cleanup;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment