Commit bf555703 authored by Bob Halley's avatar Bob Halley

OPT support

parent 8d0470db
......@@ -90,7 +90,7 @@ printsection(dns_message_t *msg, dns_section_t sectionid, char *section_name)
char t[1000];
isc_boolean_t first;
isc_boolean_t no_rdata;
if (sectionid == DNS_SECTION_QUESTION)
no_rdata = ISC_TRUE;
else
......@@ -117,11 +117,22 @@ printsection(dns_message_t *msg, dns_section_t sectionid, char *section_name)
for (rdataset = ISC_LIST_HEAD(name->list);
rdataset != NULL;
rdataset = ISC_LIST_NEXT(rdataset, link)) {
result = dns_rdataset_totext(rdataset, print_name,
ISC_FALSE, no_rdata,
&target);
if (result != DNS_R_SUCCESS)
return (result);
if (rdataset->type == dns_rdatatype_opt) {
/*
* XXX
*/
printf("OPT: udp=%u, ttl=%u\n",
(unsigned int)rdataset->rdclass,
(unsigned int)rdataset->ttl);
} else {
result = dns_rdataset_totext(rdataset,
print_name,
ISC_FALSE,
no_rdata,
&target);
if (result != DNS_R_SUCCESS)
return (result);
}
#ifdef USEINITALWS
if (first) {
print_name = &empty_name;
......
......@@ -40,6 +40,8 @@ extern int h_errno;
#include <dns/message.h>
#include <dns/name.h>
#include <dns/fixedname.h>
#include <dns/rdata.h>
#include <dns/rdatalist.h>
#include <dns/rdataset.h>
#include <dns/rdataclass.h>
#include <dns/rdatatype.h>
......@@ -47,6 +49,8 @@ extern int h_errno;
#include "printmsg.h"
#define SDIG_BUFFER_SIZE 2048
static dns_message_t *message = NULL;
static isc_boolean_t have_ipv6 = ISC_FALSE;
......@@ -89,6 +93,49 @@ add_type(dns_message_t *message, dns_name_t *name, dns_rdataclass_t rdclass,
ISC_LIST_APPEND(name->list, rdataset, link);
}
static void
add_opt(dns_message_t *message, dns_name_t *name, isc_uint16_t udpsize) {
dns_rdataset_t *rdataset;
dns_rdatalist_t *rdatalist;
dns_rdata_t *rdata;
isc_result_t result;
rdataset = NULL;
result = dns_message_gettemprdataset(message, &rdataset);
check_result(result, "dns_message_gettemprdataset()");
dns_rdataset_init(rdataset);
rdatalist = NULL;
result = dns_message_gettemprdatalist(message, &rdatalist);
check_result(result, "dns_message_gettemprdatalist()");
rdata = NULL;
result = dns_message_gettemprdata(message, &rdata);
check_result(result, "dns_message_gettemprdata()");
rdatalist->type = dns_rdatatype_opt;
rdatalist->covers = 0;
/*
* Set Maximum UDP buffer size.
*/
rdatalist->rdclass = udpsize;
/*
* Set EXTENDED-RCODE, VERSION, and Z to 0.
*/
rdatalist->ttl = 0;
/*
* No ENDS options.
*/
rdata->data = NULL;
rdata->length = 0;
ISC_LIST_INIT(rdatalist->rdata);
ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
dns_rdatalist_tordataset(rdatalist, rdataset);
ISC_LIST_APPEND(name->list, rdataset, link);
}
static void
hex_dump(isc_buffer_t *b)
{
......@@ -167,9 +214,10 @@ int
main(int argc, char *argv[]) {
char *server;
unsigned int port;
isc_boolean_t vc, have_name, have_type;
isc_boolean_t vc, have_name, have_type, edns0;
dns_fixedname_t fname;
dns_name_t *name;
dns_name_t optname;
dns_rdatatype_t rdtype;
dns_rdataclass_t rdclass, nclass;
size_t len;
......@@ -182,8 +230,8 @@ main(int argc, char *argv[]) {
isc_task_t *task;
isc_socketmgr_t *socketmgr;
isc_socket_t *sock;
unsigned char *data[512];
unsigned char *data2[512];
unsigned char *data[SDIG_BUFFER_SIZE];
unsigned char *data2[SDIG_BUFFER_SIZE];
isc_sockaddr_t sockaddr;
int i;
......@@ -220,9 +268,12 @@ main(int argc, char *argv[]) {
have_name = ISC_FALSE;
have_type = ISC_FALSE;
rdclass = dns_rdataclass_in;
edns0 = ISC_FALSE;
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
dns_name_init(&optname, NULL);
dns_name_clone(dns_rootname, &optname);
message = NULL;
result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message);
check_result(result, "dns_message_create()");
......@@ -243,6 +294,12 @@ main(int argc, char *argv[]) {
argc--;
} else if (strcmp(argv[0], "+vc") == 0) {
fatal("TCP transport not yet implemented");
} else if (strcmp(argv[0], "+edns0") == 0) {
if (!edns0) {
add_opt(message, &optname,
(isc_uint16_t)SDIG_BUFFER_SIZE);
edns0 = ISC_TRUE;
}
} else {
len = strlen(argv[0]);
tr.base = argv[0];
......@@ -283,6 +340,8 @@ main(int argc, char *argv[]) {
message->opcode = dns_opcode_query;
message->flags |= DNS_MESSAGEFLAG_RD;
dns_message_addname(message, name, DNS_SECTION_QUESTION);
if (edns0)
dns_message_addname(message, &optname, DNS_SECTION_ADDITIONAL);
isc_buffer_init(&b, data, sizeof data, ISC_BUFFERTYPE_BINARY);
result = dns_message_renderbegin(message, &b);
......@@ -290,9 +349,17 @@ main(int argc, char *argv[]) {
result = dns_message_rendersection(message, DNS_SECTION_QUESTION,
0, 0);
check_result(result, "dns_message_rendersection()");
if (edns0) {
result = dns_message_rendersection(message,
DNS_SECTION_ADDITIONAL,
0, 0);
check_result(result, "dns_message_rendersection()");
}
result = dns_message_renderend(message);
check_result(result, "dns_message_renderend()");
(void)printmessage(message);
get_address(server, port, &sockaddr);
result = isc_socket_create(socketmgr, isc_sockaddr_pf(&sockaddr),
......
......@@ -116,7 +116,7 @@ struct dns_message {
/* private from here down */
dns_namelist_t sections[DNS_SECTION_MAX];
dns_name_t *cursors[DNS_SECTION_MAX];
dns_rdata_t *opt;
dns_rdataset_t *opt;
int state;
unsigned int from_to_wire : 2;
......
......@@ -936,8 +936,10 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
for (count = 0 ; count < msg->counts[sectionid] ; count++) {
int recstart = source->current;
isc_boolean_t skip_search;
section = &msg->sections[sectionid];
skip_search = ISC_FALSE;
name = newname(msg);
if (name == NULL)
return (DNS_R_NOMEMORY);
......@@ -983,16 +985,32 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
return (DNS_R_FORMERR);
/*
* If it is a tsig, verify that it is in the additional data
* section, and switch sections for the rest of this rdata.
* Special type handling for TSIG and OPT.
*/
if (rdtype == dns_rdatatype_tsig) {
/*
* If it is a tsig, verify that it is in the
* additional data section, and switch sections for
* the rest of this rdata.
*/
if (sectionid != DNS_SECTION_ADDITIONAL)
return (DNS_R_FORMERR);
if (rdclass != dns_rdataclass_any)
return (DNS_R_FORMERR);
section = &msg->sections[DNS_SECTION_TSIG];
msg->tsigstart = recstart;
skip_search = ISC_TRUE;
} else if (rdtype == dns_rdatatype_opt) {
/*
* The name of an OPT record must be ".", it
* must be in the additional data section, and
* it must be the first OPT we've seen.
*/
if (!dns_name_equal(dns_rootname, name) ||
sectionid != DNS_SECTION_ADDITIONAL ||
msg->opt != NULL)
return (DNS_R_FORMERR);
skip_search = ISC_TRUE;
}
/*
......@@ -1008,8 +1026,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
* If we are doing a dynamic update don't bother searching
* for a name, just append this one to the end of the message.
*/
if (preserve_order || msg->opcode == dns_opcode_update
|| rdtype == dns_rdatatype_tsig) {
if (preserve_order || msg->opcode == dns_opcode_update ||
skip_search) {
ISC_LIST_APPEND(*section, name, link);
} else {
/*
......@@ -1031,14 +1049,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
}
}
/*
* If this is an OPT record, There Can Be Only One.
*/
#if 0 /* until there is a dns_rdatatype_opt XXXMLG */
if (rdtype == dns_rdatatype_opt && msg->opt != NULL)
return (DNS_R_FORMERR);
#endif
/*
* Read the rdata from the wire format. Interpret the
* rdata according to its actual class, even if it had a
......@@ -1067,8 +1077,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
* Search name for the particular type and class.
* Skip this stage if in update mode, or this is a TSIG.
*/
if (preserve_order || msg->opcode == dns_opcode_update
|| rdtype == dns_rdatatype_tsig)
if (preserve_order || msg->opcode == dns_opcode_update ||
skip_search)
result = DNS_R_NOTFOUND;
else
result = findtype(&rdataset, name, rdtype, covers);
......@@ -1117,10 +1127,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
/*
* If this is an OPT record, remember it.
*/
#if 0 /* until there is a dns_rdatatype_opt XXXMLG */
if (rdtype == dns_rdatatype_opt)
msg->opt = rdata;
#endif
msg->opt = rdataset;
}
return (DNS_R_SUCCESS);
......
/*
* Copyright (C) 1998, 1999 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: opt_41.c,v 1.1 1999/09/01 20:50:04 halley Exp $ */
#ifndef RDATA_GENERIC_OPT_41_C
#define RDATA_GENERIC_OPT_41_C
static inline dns_result_t
fromtext_opt(dns_rdataclass_t rdclass, dns_rdatatype_t type,
isc_lex_t *lexer, dns_name_t *origin,
isc_boolean_t downcase, isc_buffer_t *target)
{
/*
* OPT records do not have a text format.
*/
REQUIRE(type == 41);
(void)rdclass;
(void)lexer;
(void)origin;
(void)downcase;
(void)target;
return (DNS_R_NOTIMPLEMENTED);
}
static inline dns_result_t
totext_opt(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
isc_buffer_t *target)
{
/*
* OPT records do not have a text format.
*/
REQUIRE(rdata->type == 41);
(void)tctx;
(void)target;
return (DNS_R_NOTIMPLEMENTED);
}
static inline dns_result_t
fromwire_opt(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_region_t sregion;
isc_region_t tregion;
isc_uint16_t option, length;
unsigned int total;
REQUIRE(type == 41);
(void)rdclass;
(void)dctx;
(void)downcase;
isc_buffer_active(source, &sregion);
total = 0;
while (sregion.length != 0) {
if (sregion.length < 4)
return (DNS_R_UNEXPECTEDEND);
option = uint16_fromregion(&sregion);
length = uint16_fromregion(&sregion);
isc_region_consume(&sregion, 4);
total += 4;
if (sregion.length < length)
return (DNS_R_UNEXPECTEDEND);
isc_region_consume(&sregion, length);
total += length;
}
isc_buffer_active(source, &sregion);
isc_buffer_available(target, &tregion);
if (tregion.length < total)
return (DNS_R_NOSPACE);
memcpy(tregion.base, sregion.base, total);
isc_buffer_forward(source, total);
isc_buffer_add(target, total);
return (DNS_R_SUCCESS);
}
static inline dns_result_t
towire_opt(dns_rdata_t *rdata, dns_compress_t *cctx, isc_buffer_t *target) {
REQUIRE(rdata->type == 41);
(void)cctx;
return (mem_tobuffer(target, rdata->data, rdata->length));
}
static inline int
compare_opt(dns_rdata_t *rdata1, dns_rdata_t *rdata2) {
isc_region_t r1;
isc_region_t r2;
REQUIRE(rdata1->type == rdata2->type);
REQUIRE(rdata1->rdclass == rdata2->rdclass);
REQUIRE(rdata1->type == 41);
dns_rdata_toregion(rdata1, &r1);
dns_rdata_toregion(rdata2, &r2);
return (compare_region(&r1, &r2));
}
static inline dns_result_t
fromstruct_opt(dns_rdataclass_t rdclass, dns_rdatatype_t type, void *source,
isc_buffer_t *target)
{
REQUIRE(type == 41);
(void)rdclass;
(void)source;
(void)target;
return (DNS_R_NOTIMPLEMENTED);
}
static inline dns_result_t
tostruct_opt(dns_rdata_t *rdata, void *target, isc_mem_t *mctx) {
REQUIRE(rdata->type == 41);
(void)target;
(void)mctx;
return (DNS_R_NOTIMPLEMENTED);
}
static inline void
freestruct_opt(void *source) {
(void)source;
}
static inline dns_result_t
additionaldata_opt(dns_rdata_t *rdata, dns_additionaldatafunc_t add,
void *arg)
{
REQUIRE(rdata->type == 41);
(void)add;
(void)arg;
return (DNS_R_SUCCESS);
}
static inline dns_result_t
digest_opt(dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg) {
/*
* OPT records are not digested.
*/
REQUIRE(rdata->type == 41);
(void)digest;
(void)arg;
return (DNS_R_NOTIMPLEMENTED);
}
#endif /* RDATA_GENERIC_OPT_41_C */
/*
* Copyright (C) 1998, 1999 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: opt_41.h,v 1.1 1999/09/01 20:50:04 halley Exp $ */
typedef struct dns_rdata_opt {
dns_rdatacommon_t common;
isc_mem_t *mctx; /* if required */
/* XXXRTH Not implemented. */
} dns_rdata_opt_t;
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