Commit 5d51e67c authored by Mark Andrews's avatar Mark Andrews
Browse files

Initial "rdata" support. RFC 1035 RR types minus WKS

	totext/fromtext should all work
	towire/fromwire mostly work
	tostruct/fromstruct return DNS_R_NOTIMPLEMENTED
	compare untested
parent bc6f28fa
...@@ -21,7 +21,8 @@ TARGETS = name_test \ ...@@ -21,7 +21,8 @@ TARGETS = name_test \
lex_test \ lex_test \
task_test \ task_test \
timer_test \ timer_test \
wire_test wire_test \
rdata_test
@BIND9_MAKE_RULES@ @BIND9_MAKE_RULES@
...@@ -49,5 +50,8 @@ task_test: task_test.o ../../lib/isc/libisc.a ../../lib/dns/libdns.a ...@@ -49,5 +50,8 @@ task_test: task_test.o ../../lib/isc/libisc.a ../../lib/dns/libdns.a
timer_test: timer_test.o ../../lib/isc/libisc.a ../../lib/dns/libdns.a timer_test: timer_test.o ../../lib/isc/libisc.a ../../lib/dns/libdns.a
${CC} -o $@ timer_test.o ${LIBS} ${CC} -o $@ timer_test.o ${LIBS}
rdata_test: rdata_test.o ../../lib/isc/libisc.a ../../lib/dns/libdns.a
${CC} -o $@ rdata_test.o ${LIBS}
clean distclean:: clean distclean::
rm -f ${TARGETS} rm -f ${TARGETS}
/*
* Copyright (C) 1998 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.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <isc/assertions.h>
#include <isc/error.h>
#include <isc/lex.h>
#include <dns/rdata.h>
#include <dns/compress.h>
isc_mem_t *mctx;
isc_lex_t *lex;
isc_lexspecials_t specials;
int
main(int argc, char *argv[]) {
isc_token_t token;
isc_result_t result;
int quiet = 0;
int c;
int stats = 0;
unsigned int options = 0;
unsigned int parens = 0;
int type;
char outbuf[1024];
char inbuf[1024];
char wirebuf[1024];
isc_buffer_t dbuf;
isc_buffer_t tbuf;
isc_buffer_t wbuf;
dns_rdata_t rdata;
int need_eol = 0;
int wire = 0;
dns_compress_t cctx;
dns_decompress_t dctx;
while ((c = getopt(argc, argv, "qsw")) != -1) {
switch (c) {
case 'q':
quiet = 1;
break;
case 's':
stats = 1;
break;
case 'w':
wire = 1;
break;
}
}
memset(&cctx, '0', sizeof cctx);
memset(&dctx, '0', sizeof dctx);
RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
RUNTIME_CHECK(isc_lex_create(mctx, 256, &lex) == ISC_R_SUCCESS);
/* Set up to lex DNS master file. */
specials['('] = 1;
specials[')'] = 1;
specials['"'] = 1;
isc_lex_setspecials(lex, specials);
options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF |
ISC_LEXOPT_INITIALWS | ISC_LEXOPT_QSTRING;
isc_lex_setcomments(lex, ISC_LEXCOMMENT_DNSMASTERFILE);
RUNTIME_CHECK(isc_lex_openstream(lex, stdin) == ISC_R_SUCCESS);
while ((result = isc_lex_gettoken(lex, options | ISC_LEXOPT_NUMBER,
&token)) == ISC_R_SUCCESS) {
/* fprintf(stdout, "token.type = %d\n", token.type); */
if (token.type == isc_tokentype_special) {
if (token.value.as_char == '(') {
parens++;
options &= ~ISC_LEXOPT_EOL;
options &= ~ISC_LEXOPT_INITIALWS;
} else if (token.value.as_char == ')') {
if (parens == 0) {
printf("mismatched parens\n");
exit(1);
}
parens--;
if (parens == 0) {
options |= ISC_LEXOPT_EOL;
options |= ISC_LEXOPT_INITIALWS;
}
}
continue;
}
if (need_eol) {
if (token.type == isc_tokentype_eol ||
token.type == isc_tokentype_eof)
need_eol = 0;
continue;
}
if (token.type != isc_tokentype_number)
continue;
dns_rdata_init(&rdata);
type = token.value.as_ulong;
fprintf(stdout, "type = %d\n", type);
fflush(stdout);
isc_buffer_init(&dbuf, inbuf, sizeof(inbuf),
ISC_BUFFERTYPE_BINARY);
result = dns_rdata_fromtext(&rdata, 1, type, lex,
NULL, ISC_FALSE, &dbuf);
if (result != DNS_R_SUCCESS) {
fprintf(stdout,
"dns_rdata_fromtext != DNS_R_SUCCESS\n");
fflush(stdout);
need_eol = 1;
continue;
}
/* Convert to wire and back? */
if (wire) {
isc_buffer_init(&wbuf, wirebuf, sizeof(wirebuf),
ISC_BUFFERTYPE_BINARY);
if (dns_rdata_towire(&rdata, &cctx, &wbuf)
!= DNS_R_SUCCESS) {
fprintf(stdout,
"dns_rdata_towire != DNS_R_SUCCESS\n");
fflush(stdout);
continue;
}
dns_rdata_init(&rdata);
isc_buffer_init(&dbuf, inbuf, sizeof(inbuf),
ISC_BUFFERTYPE_BINARY);
if (dns_rdata_fromwire(&rdata, 1, type, &wbuf, &dctx,
ISC_FALSE, &dbuf) != DNS_R_SUCCESS) {
fprintf(stdout,
"dns_rdata_fromwire != DNS_R_SUCCESS\n");
fflush(stdout);
continue;
}
}
isc_buffer_init(&tbuf, outbuf, sizeof(outbuf),
ISC_BUFFERTYPE_TEXT);
if (dns_rdata_totext(&rdata, &tbuf) != DNS_R_SUCCESS)
fprintf(stdout, "dns_rdata_totext != DNS_R_SUCCESS\n");
else
fprintf(stdout, "\"%.*s\"\n",
(int)tbuf.used, (char*)tbuf.base);
fflush(stdout);
}
if (result != ISC_R_EOF)
printf("Result: %s\n", isc_result_totext(result));
isc_lex_close(lex);
isc_lex_destroy(&lex);
if (!quiet && stats)
isc_mem_stats(mctx, stdout);
isc_mem_destroy(&mctx);
return (0);
}
...@@ -12,7 +12,7 @@ CINCLUDES = -I${srcdir}/../isc/unix/include \ ...@@ -12,7 +12,7 @@ CINCLUDES = -I${srcdir}/../isc/unix/include \
CDEFINES = CDEFINES =
CWARNINGS = CWARNINGS =
OBJS = name.o rdatalist.o rdataset.o result.o version.o OBJS = name.o rdatalist.o rdataset.o result.o version.o rdata.o
SUBDIRS = include SUBDIRS = include
TARGETS = timestamp TARGETS = timestamp
...@@ -39,3 +39,11 @@ install:: timestamp installdirs ...@@ -39,3 +39,11 @@ install:: timestamp installdirs
clean distclean:: clean distclean::
rm -f libdns.a timestamp rm -f libdns.a timestamp
rdata.o: code.h
code.h: gen
./gen > code.h
gen: gen.c
${CC} ${ALL_CFLAGS} -o $@ $?
/*
* Copyright (C) 1998 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.
*/
#include <sys/types.h>
#include <ctype.h>
#include <dirent.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define FROMTEXTDECL "dns_rdataclass_t class, dns_rdatatype_t type, isc_lex_t *lexer, dns_name_t *origin, isc_boolean_t downcase, isc_buffer_t *target"
#define FROMTEXTARGS "class, type, lexer, origin, downcase, target"
#define FROMTEXTCLASS "class"
#define FROMTEXTTYPE "type"
#define FROMTEXTDEF "DNS_R_DEFAULT"
#define TOTEXTDECL "dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target"
#define TOTEXTARGS "rdata, origin, target"
#define TOTEXTCLASS "rdata->class"
#define TOTEXTTYPE "rdata->type"
#define TOTEXTDEF "DNS_R_DEFAULT"
#define FROMWIREDECL "dns_rdataclass_t class, dns_rdatatype_t type, isc_buffer_t *source, dns_decompress_t *dctx, isc_boolean_t downcase, isc_buffer_t *target"
#define FROMWIREARGS "class, type, source, dctx, downcase, target"
#define FROMWIRECLASS "class"
#define FROMWIRETYPE "type"
#define FROMWIREDEF "DNS_R_DEFAULT"
#define TOWIREDECL "dns_rdata_t *rdata, dns_compress_t *cctx, isc_buffer_t *target"
#define TOWIREARGS "rdata, cctx, target"
#define TOWIRECLASS "rdata->class"
#define TOWIRETYPE "rdata->type"
#define TOWIREDEF "DNS_R_DEFAULT"
#define FROMSTRUCTDECL "dns_rdataclass_t class, dns_rdatatype_t type, void *source, isc_buffer_t *target"
#define FROMSTRUCTARGS "class, type, source, target"
#define FROMSTRUCTCLASS "class"
#define FROMSTRUCTTYPE "type"
#define FROMSTRUCTDEF "DNS_R_DEFAULT"
#define TOSTRUCTDECL "dns_rdata_t *rdata, void *target"
#define TOSTRUCTARGS "rdata, target"
#define TOSTRUCTCLASS "rdata->class"
#define TOSTRUCTTYPE "rdata->type"
#define TOSTRUCTDEF "DNS_R_DEFAULT"
#define COMPAREDECL "dns_rdata_t *rdata1, dns_rdata_t *rdata2"
#define COMPAREARGS "rdata1, rdata2"
#define COMPARECLASS "rdata1->class"
#define COMPARETYPE "rdata1->type"
#define COMPAREDEF "-2"
char copyright[] =
"/*\n\
* Copyright (C) 1998%s Internet Software Consortium.\n\
*\n\
* Permission to use, copy, modify, and distribute this software for any\n\
* purpose with or without fee is hereby granted, provided that the above\n\
* copyright notice and this permission notice appear in all copies.\n\
*\n\
* THE SOFTWARE IS PROVIDED \"AS IS\" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\n\
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\n\
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\n\
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\n\
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\n\
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\n\
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\n\
* SOFTWARE.\n\
*/\n\
\n\
/* THIS FILE IS AUTOMATICALLY GENERATED: DO NOT EDIT */\n\
\n";
struct cc {
struct cc *next;
int type;
} *classes;
struct tt {
struct tt *next;
int class;
int type;
char classname[11];
char typename[11];
char dirname[sizeof "rdata/0123456789_65535" ];
} *types;
char * upper(char *);
void doswitch(char *, char *, char *, char *, char *, char *);
void dodecl(char *, char *, char *);
void add(int, char *, int, char *, char *);
void sd(int, char *, char *);
char *
upper(char *s) {
static char buf[11];
char *b = buf;
char c;
while ((c = *s++)) {
*b++ = islower(c) ? toupper(c) : c;
}
*b = '\0';
return (buf);
}
void
doswitch(char *name, char *function, char *args,
char *tsw, char *csw, char *res)
{
struct tt *tt;
int first = 1;
int lasttype = 0;
int subswitch = 0;
for (tt = types; tt != NULL ; tt = tt->next) {
if (first) {
fprintf(stdout, "\n#define %s \\\n", name);
fprintf(stdout, "\tswitch (%s) { \\\n" /*}*/, tsw);
first = 0;
}
if (tt->type != lasttype && subswitch) {
fprintf(stdout, "\t\tdefault: result = %s; \\\n",
res);
fputs(/*{*/ "\t\t} \\\n", stdout);
subswitch = 0;
}
if (tt->class && tt->type != lasttype) {
fprintf(stdout, "\tcase %d: switch (%s) { \\\n" /*}*/,
tt->type, tsw);
subswitch = 1;
}
if (tt->class == 0)
fprintf(stdout,
"\tcase %d: result = %s_%s(%s); break;",
tt->type, function, tt->typename, args);
else
fprintf(stdout,
"\t\tcase %d: result = %s_%s_%s(%s); break;",
tt->class, function, tt->classname,
tt->typename, args);
fputs(" \\\n", stdout);
lasttype = tt->type;
}
if (subswitch) {
fprintf(stdout, "\t\tdefault: result = %s; \\\n", res);
fputs(/*{*/ "\t\t}\n", stdout);
}
if (first)
fprintf(stdout, "\n#define %s result = %s;\n", name, res);
else {
fprintf(stdout, "\tdefault: result = %s; \\\n", res);
fputs(/*{*/ "\t}\n", stdout);
}
}
void
dodecl(char *type, char *function, char *args) {
struct tt *tt;
fputs("\n", stdout);
for (tt = types; tt ; tt = tt->next)
if (tt->class)
fprintf(stdout,
"static %s %s_%s_%s(%s);\n",
type, function, tt->classname,
tt->typename, args);
else
fprintf(stdout,
"static %s %s_%s(%s);\n",
type, function, tt->typename, args);
}
void
add(int class, char *classname, int type, char *typename, char *dirname) {
struct tt *newtt = (struct tt *)malloc(sizeof *newtt);
struct tt *tt, *oldtt;
struct cc *newcc;
struct cc *cc, *oldcc;
if (newtt == NULL)
exit(1);
newtt->next = NULL;
newtt->class = class;
newtt->type = type;
strcpy(newtt->classname, classname);
strcpy(newtt->typename, typename);
strcpy(newtt->dirname, dirname);
tt = types;
oldtt = NULL;
while (tt && (tt->type < type)) {
oldtt = tt;
tt = tt->next;
}
while (tt && (tt->type == type) && (tt->class < class)) {
if (strcmp(tt->typename, typename) != 0)
exit(1);
oldtt = tt;
tt = tt->next;
}
if (tt && (tt->type == type) && (tt->class == class))
exit(1);
newtt->next = tt;
if (oldtt)
oldtt->next = newtt;
else
types = newtt;
/* do a class switch for this type */
if (class == 0)
return;
newcc = (struct cc *)malloc(sizeof *newcc);
newcc->type = type;
cc = classes;
oldcc = NULL;
while (cc && (cc->type < type)) {
oldcc = cc;
cc = cc->next;
}
if (cc && cc->type == type) {
free((char *)newcc);
return;
}
newcc->next = cc;
if (oldcc)
oldcc->next = newcc;
else
classes = newcc;
}
void
sd(int class, char *classname, char *dir) {
char buf[sizeof "0123456789_65535.h"];
DIR *d;
int type;
char typename[11];
struct dirent *dp;
if ((d = opendir(dir)) == NULL)
return;
while ((dp = readdir(d)) != NULL) {
if (sscanf(dp->d_name, "%10[0-9a-z]_%d.h",
typename, &type) != 2)
continue;
if ((type > 65535) || (type < 0))
continue;
sprintf(buf, "%s_%d.h", typename, type);
if (strcmp(buf, dp->d_name) != 0)
continue;
add(class, classname, type, typename, dir);
}
closedir(d);
}
int
main(int argc, char **argv) {
DIR *d;
char buf[sizeof "rdata/0123456789_65535" ];
int class;
char classname[11];
struct dirent *dp;
struct tt *tt;
struct tm *tm;
time_t now;
char year[11];
argc = argc;
argv = argv;
if ((d = opendir("rdata")) == NULL)
exit(1);
while ((dp = readdir(d)) != NULL) {
if (sscanf(dp->d_name, "%10[0-9a-z]_%d",
classname, &class) != 2)
continue;
if ((class > 65535) || (class < 0))
continue;
sprintf(buf, "rdata/%s_%d", classname, class);
if (strcmp(buf + 6, dp->d_name) != 0)
continue;
sd(class, classname, buf);
}
sd(0, "", "rdata/generic");
closedir(d);
if (time(&now) != -1) {
if ((tm = localtime(&now)) != NULL && tm->tm_year > 98)
sprintf(year, "-%d", tm->tm_year + 1900);
else
year[0] = 0;
} else
year[0] = 0;
fprintf(stdout, copyright, year);
dodecl("dns_result_t", "fromtext", FROMTEXTDECL);
dodecl("dns_result_t", "totext", TOTEXTDECL);
dodecl("dns_result_t", "fromwire", FROMWIREDECL);
dodecl("dns_result_t", "towire", TOWIREDECL);
dodecl("int", "compare", COMPAREDECL);
dodecl("dns_result_t", "fromstruct", FROMSTRUCTDECL);
dodecl("dns_result_t", "tostruct", TOSTRUCTDECL);
doswitch("FROMTEXTSWITCH", "fromtext", FROMTEXTARGS,
FROMTEXTTYPE, FROMTEXTCLASS, FROMTEXTDEF);
doswitch("TOTEXTSWITCH", "totext", TOTEXTARGS,
TOTEXTTYPE, TOTEXTCLASS, TOTEXTDEF);
doswitch("FROMWIRESWITCH", "fromwire", FROMWIREARGS,
FROMWIRETYPE, FROMWIRECLASS, FROMWIREDEF);
doswitch("TOWIRESWITCH", "towire", TOWIREARGS,
TOWIRETYPE, TOWIRECLASS, TOWIREDEF);
doswitch("COMPARESWITCH", "compare", COMPAREARGS,
COMPARETYPE, COMPARECLASS, COMPAREDEF);
doswitch("FROMSTRUCTSWITCH", "fromstruct", FROMSTRUCTARGS,
FROMSTRUCTTYPE, FROMSTRUCTCLASS, FROMSTRUCTDEF);
doswitch("TOSTRUCTSWITCH", "tostruct", TOSTRUCTARGS,
TOSTRUCTTYPE, TOSTRUCTCLASS, TOSTRUCTDEF);
fprintf(stdout, "\n#define TYPENAMES%s\n",
types != NULL ? " \\" : "");
for (tt = types; tt != NULL ; tt = tt->next)
if (tt->class == 0)
fprintf(stdout,
"\t{ %d, \"%s\" },%s\n",
tt->type, tt->typename,
tt->next != NULL ? " \\" : "");
fputs("\n", stdout);
for (tt = types; tt ; tt = tt->next)
fprintf(stdout, "#include \"%s/%s_%d.h\"\n",
tt->dirname, tt->typename, tt->type);
if (ferror(stdout) != 0)
exit(1);
exit(0);
}
...@@ -260,7 +260,7 @@ dns_result_t dns_rdata_fromtext(dns_rdata_t *rdata, ...@@ -260,7 +260,7 @@ dns_result_t dns_rdata_fromtext(dns_rdata_t *rdata,
* *
* Notes: * Notes:
* Relative domain names in the rdata will have 'origin' appended to them. * Relative domain names in the rdata will have 'origin' appended to them.
* If 'origin' is NULL, then relative domain names will remain relative. * A NULL origin implies "origin == dns_rootname".
* *
* If 'downcase' is true, any uppercase letters in domain names in * If 'downcase' is true, any uppercase letters in domain names in
* 'source' will be downcased when they are copied into 'target'. * 'source' will be downcased when they are copied into 'target'.
......