mirror of https://github.com/getdnsapi/getdns.git
DOA & AMTRELAY RR types implementation
This commit is contained in:
parent
71b773ab2f
commit
034b775e5c
|
@ -1,6 +1,8 @@
|
||||||
* 2019-??-??: Version 1.?.?
|
* 2019-??-??: Version 1.?.?
|
||||||
* Issue #419: Escape backslashed when printing in JSON format.
|
* Issue #419: Escape backslashed when printing in JSON format.
|
||||||
Thanks boB Rudis
|
Thanks boB Rudis
|
||||||
|
* DOA rr-type
|
||||||
|
* AMTRELAY rr-type
|
||||||
|
|
||||||
* 2019-01-11: Version 1.5.1
|
* 2019-01-11: Version 1.5.1
|
||||||
* Introduce proof of concept GnuTLS implementation. Incomplete support
|
* Introduce proof of concept GnuTLS implementation. Incomplete support
|
||||||
|
|
|
@ -303,6 +303,7 @@ static struct const_name_info consts_name_info[] = {
|
||||||
{ "GETDNS_RRTYPE_A6", 38 },
|
{ "GETDNS_RRTYPE_A6", 38 },
|
||||||
{ "GETDNS_RRTYPE_AAAA", 28 },
|
{ "GETDNS_RRTYPE_AAAA", 28 },
|
||||||
{ "GETDNS_RRTYPE_AFSDB", 18 },
|
{ "GETDNS_RRTYPE_AFSDB", 18 },
|
||||||
|
{ "GETDNS_RRTYPE_AMTRELAY", 260 },
|
||||||
{ "GETDNS_RRTYPE_ANY", 255 },
|
{ "GETDNS_RRTYPE_ANY", 255 },
|
||||||
{ "GETDNS_RRTYPE_APL", 42 },
|
{ "GETDNS_RRTYPE_APL", 42 },
|
||||||
{ "GETDNS_RRTYPE_ATMA", 34 },
|
{ "GETDNS_RRTYPE_ATMA", 34 },
|
||||||
|
|
|
@ -439,6 +439,7 @@ typedef enum getdns_callback_type_t {
|
||||||
#define GETDNS_RRTYPE_CAA 257
|
#define GETDNS_RRTYPE_CAA 257
|
||||||
#define GETDNS_RRTYPE_AVC 258
|
#define GETDNS_RRTYPE_AVC 258
|
||||||
#define GETDNS_RRTYPE_DOA 259
|
#define GETDNS_RRTYPE_DOA 259
|
||||||
|
#define GETDNS_RRTYPE_AMTRELAY 260
|
||||||
#define GETDNS_RRTYPE_TA 32768
|
#define GETDNS_RRTYPE_TA 32768
|
||||||
#define GETDNS_RRTYPE_DLV 32769
|
#define GETDNS_RRTYPE_DLV 32769
|
||||||
/** @}
|
/** @}
|
||||||
|
|
|
@ -232,6 +232,15 @@ static const gldns_rdf_type type_caa_wireformat[] = {
|
||||||
GLDNS_RDF_TYPE_TAG,
|
GLDNS_RDF_TYPE_TAG,
|
||||||
GLDNS_RDF_TYPE_LONG_STR
|
GLDNS_RDF_TYPE_LONG_STR
|
||||||
};
|
};
|
||||||
|
#ifdef DRAFT_RRTYPES
|
||||||
|
static const gldns_rdf_type type_doa_wireformat[] = {
|
||||||
|
GLDNS_RDF_TYPE_INT32, GLDNS_RDF_TYPE_INT32, GLDNS_RDF_TYPE_INT8,
|
||||||
|
GLDNS_RDF_TYPE_STR, GLDNS_RDF_TYPE_B64
|
||||||
|
};
|
||||||
|
static const gldns_rdf_type type_amtrelay_wireformat[] = {
|
||||||
|
GLDNS_RDF_TYPE_AMTRELAY
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/* All RR's defined in 1035 are well known and can thus
|
/* All RR's defined in 1035 are well known and can thus
|
||||||
* be compressed. See RFC3597. These RR's are:
|
* be compressed. See RFC3597. These RR's are:
|
||||||
|
@ -608,8 +617,14 @@ static gldns_rr_descriptor rdata_field_descriptors[] = {
|
||||||
#ifdef DRAFT_RRTYPES
|
#ifdef DRAFT_RRTYPES
|
||||||
/* 258 */
|
/* 258 */
|
||||||
{GLDNS_RR_TYPE_AVC, "AVC", 1, 0, NULL, GLDNS_RDF_TYPE_STR, GLDNS_RR_NO_COMPRESS, 0 },
|
{GLDNS_RR_TYPE_AVC, "AVC", 1, 0, NULL, GLDNS_RDF_TYPE_STR, GLDNS_RR_NO_COMPRESS, 0 },
|
||||||
|
/* 259 */
|
||||||
|
{GLDNS_RR_TYPE_DOA, "DOA", 1, 0, type_doa_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||||
|
/* 260 */
|
||||||
|
{GLDNS_RR_TYPE_AMTRELAY, "AMTRELAY", 1, 0, type_amtrelay_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||||
#else
|
#else
|
||||||
{GLDNS_RR_TYPE_NULL, "TYPE258", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
{GLDNS_RR_TYPE_NULL, "TYPE258", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||||
|
{GLDNS_RR_TYPE_NULL, "TYPE259", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||||
|
{GLDNS_RR_TYPE_NULL, "TYPE260", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* split in array, no longer contiguous */
|
/* split in array, no longer contiguous */
|
||||||
|
|
|
@ -38,7 +38,7 @@ extern "C" {
|
||||||
#define GLDNS_KEY_REVOKE_KEY 0x0080 /* used to revoke KSK, rfc 5011 */
|
#define GLDNS_KEY_REVOKE_KEY 0x0080 /* used to revoke KSK, rfc 5011 */
|
||||||
|
|
||||||
/* The first fields are contiguous and can be referenced instantly */
|
/* The first fields are contiguous and can be referenced instantly */
|
||||||
#define GLDNS_RDATA_FIELD_DESCRIPTORS_COMMON 259
|
#define GLDNS_RDATA_FIELD_DESCRIPTORS_COMMON 260
|
||||||
|
|
||||||
/** lookuptable for rr classes */
|
/** lookuptable for rr classes */
|
||||||
extern struct gldns_struct_lookup_table* gldns_rr_classes;
|
extern struct gldns_struct_lookup_table* gldns_rr_classes;
|
||||||
|
@ -226,7 +226,8 @@ enum gldns_enum_rr_type
|
||||||
GLDNS_RR_TYPE_URI = 256, /* RFC 7553 */
|
GLDNS_RR_TYPE_URI = 256, /* RFC 7553 */
|
||||||
GLDNS_RR_TYPE_CAA = 257, /* RFC 6844 */
|
GLDNS_RR_TYPE_CAA = 257, /* RFC 6844 */
|
||||||
GLDNS_RR_TYPE_AVC = 258,
|
GLDNS_RR_TYPE_AVC = 258,
|
||||||
GLDNS_RR_TYPE_DOA = 259,
|
GLDNS_RR_TYPE_DOA = 259, /* draft-durand-doa-over-dns */
|
||||||
|
GLDNS_RR_TYPE_AMTRELAY= 260, /* draft-ietf-mboned-driad-amt-discovery */
|
||||||
|
|
||||||
/** DNSSEC Trust Authorities */
|
/** DNSSEC Trust Authorities */
|
||||||
GLDNS_RR_TYPE_TA = 32768,
|
GLDNS_RR_TYPE_TA = 32768,
|
||||||
|
@ -351,6 +352,9 @@ enum gldns_enum_rdf_type
|
||||||
*/
|
*/
|
||||||
GLDNS_RDF_TYPE_LONG_STR,
|
GLDNS_RDF_TYPE_LONG_STR,
|
||||||
|
|
||||||
|
/* draft-ietf-mboned-driad-amt-discovery */
|
||||||
|
GLDNS_RDF_TYPE_AMTRELAY,
|
||||||
|
|
||||||
/** TSIG extended 16bit error value */
|
/** TSIG extended 16bit error value */
|
||||||
GLDNS_RDF_TYPE_TSIGERROR,
|
GLDNS_RDF_TYPE_TSIGERROR,
|
||||||
|
|
||||||
|
|
|
@ -997,6 +997,8 @@ int gldns_str2wire_rdf_buf(const char* str, uint8_t* rd, size_t* len,
|
||||||
return gldns_str2wire_hip_buf(str, rd, len);
|
return gldns_str2wire_hip_buf(str, rd, len);
|
||||||
case GLDNS_RDF_TYPE_INT16_DATA:
|
case GLDNS_RDF_TYPE_INT16_DATA:
|
||||||
return gldns_str2wire_int16_data_buf(str, rd, len);
|
return gldns_str2wire_int16_data_buf(str, rd, len);
|
||||||
|
case GLDNS_RDF_TYPE_AMTRELAY:
|
||||||
|
return gldns_str2wire_amtrelay_buf(str, rd, len);
|
||||||
case GLDNS_RDF_TYPE_UNKNOWN:
|
case GLDNS_RDF_TYPE_UNKNOWN:
|
||||||
case GLDNS_RDF_TYPE_SERVICE:
|
case GLDNS_RDF_TYPE_SERVICE:
|
||||||
return GLDNS_WIREPARSE_ERR_NOT_IMPL;
|
return GLDNS_WIREPARSE_ERR_NOT_IMPL;
|
||||||
|
@ -2118,3 +2120,77 @@ int gldns_str2wire_int16_data_buf(const char* str, uint8_t* rd, size_t* len)
|
||||||
*len = ((size_t)n)+2;
|
*len = ((size_t)n)+2;
|
||||||
return GLDNS_WIREPARSE_ERR_OK;
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int gldns_str2wire_amtrelay_buf(const char* str, uint8_t* rd, size_t* len)
|
||||||
|
{
|
||||||
|
size_t relay_len = 0;
|
||||||
|
int s;
|
||||||
|
uint8_t relay_type;
|
||||||
|
char token[512];
|
||||||
|
gldns_buffer strbuf;
|
||||||
|
gldns_buffer_init_frm_data(&strbuf, (uint8_t*)str, strlen(str));
|
||||||
|
|
||||||
|
if(*len < 2)
|
||||||
|
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||||
|
/* precedence */
|
||||||
|
if(gldns_bget_token(&strbuf, token, "\t\n ", sizeof(token)) <= 0)
|
||||||
|
return RET_ERR(GLDNS_WIREPARSE_ERR_INVALID_STR,
|
||||||
|
gldns_buffer_position(&strbuf));
|
||||||
|
rd[0] = (uint8_t)atoi(token);
|
||||||
|
/* discovery_optional */
|
||||||
|
if(gldns_bget_token(&strbuf, token, "\t\n ", sizeof(token)) <= 0)
|
||||||
|
return RET_ERR(GLDNS_WIREPARSE_ERR_INVALID_STR,
|
||||||
|
gldns_buffer_position(&strbuf));
|
||||||
|
if ((token[0] != '0' && token[0] != '1') || token[1] != 0)
|
||||||
|
return RET_ERR(GLDNS_WIREPARSE_ERR_INVALID_STR,
|
||||||
|
gldns_buffer_position(&strbuf));
|
||||||
|
|
||||||
|
rd[1] = *token == '1' ? 0x80 : 0x00;
|
||||||
|
/* relay_type */
|
||||||
|
if(gldns_bget_token(&strbuf, token, "\t\n ", sizeof(token)) <= 0)
|
||||||
|
return RET_ERR(GLDNS_WIREPARSE_ERR_INVALID_STR,
|
||||||
|
gldns_buffer_position(&strbuf));
|
||||||
|
relay_type = (uint8_t)atoi(token);
|
||||||
|
if (relay_type > 0x7F)
|
||||||
|
return RET_ERR(GLDNS_WIREPARSE_ERR_INVALID_STR,
|
||||||
|
gldns_buffer_position(&strbuf));
|
||||||
|
rd[1] |= relay_type;
|
||||||
|
|
||||||
|
if (relay_type == 0) {
|
||||||
|
*len = 2;
|
||||||
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
|
}
|
||||||
|
/* relay */
|
||||||
|
if(gldns_bget_token(&strbuf, token, "\t\n ", sizeof(token)) <= 0)
|
||||||
|
return RET_ERR(GLDNS_WIREPARSE_ERR_INVALID_STR,
|
||||||
|
gldns_buffer_position(&strbuf));
|
||||||
|
if(relay_type == 1) {
|
||||||
|
/* IP4 */
|
||||||
|
relay_len = *len - 2;
|
||||||
|
s = gldns_str2wire_a_buf(token, rd+2, &relay_len);
|
||||||
|
if(s) return RET_ERR_SHIFT(s, gldns_buffer_position(&strbuf));
|
||||||
|
} else if(relay_type == 2) {
|
||||||
|
/* IP6 */
|
||||||
|
relay_len = *len - 2;
|
||||||
|
s = gldns_str2wire_aaaa_buf(token, rd+2, &relay_len);
|
||||||
|
if(s) return RET_ERR_SHIFT(s, gldns_buffer_position(&strbuf));
|
||||||
|
} else if(relay_type == 3) {
|
||||||
|
/* DNAME */
|
||||||
|
relay_len = *len - 2;
|
||||||
|
s = gldns_str2wire_dname_buf(token, rd+2, &relay_len);
|
||||||
|
if(s) return RET_ERR_SHIFT(s, gldns_buffer_position(&strbuf));
|
||||||
|
} else {
|
||||||
|
/* unknown gateway type */
|
||||||
|
return RET_ERR(GLDNS_WIREPARSE_ERR_INVALID_STR,
|
||||||
|
gldns_buffer_position(&strbuf));
|
||||||
|
}
|
||||||
|
/* double check for size */
|
||||||
|
if(*len < 2 + relay_len)
|
||||||
|
return RET_ERR(GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL,
|
||||||
|
gldns_buffer_position(&strbuf));
|
||||||
|
|
||||||
|
*len = 2 + relay_len;
|
||||||
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -554,6 +554,15 @@ int gldns_str2wire_hip_buf(const char* str, uint8_t* rd, size_t* len);
|
||||||
*/
|
*/
|
||||||
int gldns_str2wire_int16_data_buf(const char* str, uint8_t* rd, size_t* len);
|
int gldns_str2wire_int16_data_buf(const char* str, uint8_t* rd, size_t* len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert rdf of type GLDNS_RDF_TYPE_AMTRELAY from string to wireformat.
|
||||||
|
* @param str: the text to convert for this rdata element.
|
||||||
|
* @param rd: rdata buffer for the wireformat.
|
||||||
|
* @param len: length of rd buffer on input, used length on output.
|
||||||
|
* @return 0 on success, error on failure.
|
||||||
|
*/
|
||||||
|
int gldns_str2wire_amtrelay_buf(const char* str, uint8_t* rd, size_t* len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strip whitespace from the start and the end of line.
|
* Strip whitespace from the start and the end of line.
|
||||||
* @param line: modified with 0 to shorten it.
|
* @param line: modified with 0 to shorten it.
|
||||||
|
|
|
@ -1004,6 +1004,9 @@ int gldns_wire2str_rdf_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
|
||||||
return gldns_wire2str_tag_scan(d, dlen, s, slen);
|
return gldns_wire2str_tag_scan(d, dlen, s, slen);
|
||||||
case GLDNS_RDF_TYPE_LONG_STR:
|
case GLDNS_RDF_TYPE_LONG_STR:
|
||||||
return gldns_wire2str_long_str_scan(d, dlen, s, slen);
|
return gldns_wire2str_long_str_scan(d, dlen, s, slen);
|
||||||
|
case GLDNS_RDF_TYPE_AMTRELAY:
|
||||||
|
return gldns_wire2str_amtrelay_scan(d, dlen, s, slen, pkt,
|
||||||
|
pktlen);
|
||||||
case GLDNS_RDF_TYPE_TSIGERROR:
|
case GLDNS_RDF_TYPE_TSIGERROR:
|
||||||
return gldns_wire2str_tsigerror_scan(d, dlen, s, slen);
|
return gldns_wire2str_tsigerror_scan(d, dlen, s, slen);
|
||||||
}
|
}
|
||||||
|
@ -1707,6 +1710,61 @@ int gldns_wire2str_long_str_scan(uint8_t** d, size_t* dl, char** s, size_t* sl)
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* internal scan routine that can modify arguments on failure */
|
||||||
|
static int gldns_wire2str_amtrelay_scan_internal(uint8_t** d, size_t* dl,
|
||||||
|
char** s, size_t* sl, uint8_t* pkt, size_t pktlen)
|
||||||
|
{
|
||||||
|
/* https://www.ietf.org/id/draft-ietf-mboned-driad-amt-discovery-01.txt */
|
||||||
|
uint8_t precedence, discovery_optional, relay_type;
|
||||||
|
int w = 0;
|
||||||
|
|
||||||
|
if(*dl < 2) return -1;
|
||||||
|
precedence = (*d)[0];
|
||||||
|
discovery_optional= (*d)[1] >> 7;
|
||||||
|
relay_type = (*d)[1] % 0x7F;
|
||||||
|
if(relay_type > 3)
|
||||||
|
return -1; /* unknown */
|
||||||
|
(*d)+=2;
|
||||||
|
(*dl)-=2;
|
||||||
|
w += gldns_str_print(s, sl, "%d %d %d ",
|
||||||
|
(int)precedence, (int)discovery_optional, (int)relay_type);
|
||||||
|
|
||||||
|
switch(relay_type) {
|
||||||
|
case 0: /* no relay */
|
||||||
|
break;
|
||||||
|
case 1: /* ip4 */
|
||||||
|
w += gldns_wire2str_a_scan(d, dl, s, sl);
|
||||||
|
break;
|
||||||
|
case 2: /* ip6 */
|
||||||
|
w += gldns_wire2str_aaaa_scan(d, dl, s, sl);
|
||||||
|
break;
|
||||||
|
case 3: /* dname */
|
||||||
|
w += gldns_wire2str_dname_scan(d, dl, s, sl, pkt, pktlen);
|
||||||
|
break;
|
||||||
|
default: /* unknown */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gldns_wire2str_amtrelay_scan(uint8_t** d, size_t* dl, char** s, size_t* sl,
|
||||||
|
uint8_t* pkt, size_t pktlen)
|
||||||
|
{
|
||||||
|
uint8_t* od = *d;
|
||||||
|
char* os = *s;
|
||||||
|
size_t odl = *dl, osl = *sl;
|
||||||
|
int w=gldns_wire2str_amtrelay_scan_internal(d, dl, s, sl, pkt, pktlen);
|
||||||
|
if(w == -1) {
|
||||||
|
*d = od;
|
||||||
|
*s = os;
|
||||||
|
*dl = odl;
|
||||||
|
*sl = osl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int gldns_wire2str_tsigerror_scan(uint8_t** d, size_t* dl, char** s, size_t* sl)
|
int gldns_wire2str_tsigerror_scan(uint8_t** d, size_t* dl, char** s, size_t* sl)
|
||||||
{
|
{
|
||||||
gldns_lookup_table *lt;
|
gldns_lookup_table *lt;
|
||||||
|
|
|
@ -916,6 +916,21 @@ int gldns_wire2str_tag_scan(uint8_t** data, size_t* data_len, char** str,
|
||||||
int gldns_wire2str_long_str_scan(uint8_t** data, size_t* data_len, char** str,
|
int gldns_wire2str_long_str_scan(uint8_t** data, size_t* data_len, char** str,
|
||||||
size_t* str_len);
|
size_t* str_len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scan wireformat AMTRELAY field to string, with user buffers.
|
||||||
|
* It shifts the arguments to move along (see gldns_wire2str_pkt_scan).
|
||||||
|
* @param data: wireformat data.
|
||||||
|
* @param data_len: length of data buffer.
|
||||||
|
* @param str: string buffer.
|
||||||
|
* @param str_len: length of string buffer.
|
||||||
|
* @param pkt: packet for decompression, if NULL no decompression.
|
||||||
|
* @param pktlen: length of packet buffer.
|
||||||
|
* @return number of characters (except null) needed to print.
|
||||||
|
* Can return -1 on failure.
|
||||||
|
*/
|
||||||
|
int gldns_wire2str_amtrelay_scan(uint8_t** data, size_t* data_len, char** str,
|
||||||
|
size_t* str_len, uint8_t* pkt, size_t pktlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print EDNS LLQ option data to string. User buffers, moves string pointers.
|
* Print EDNS LLQ option data to string. User buffers, moves string pointers.
|
||||||
* @param str: string buffer.
|
* @param str: string buffer.
|
||||||
|
|
228
src/rr-dict.c
228
src/rr-dict.c
|
@ -431,6 +431,214 @@ static _getdns_rdf_special hip_public_key = {
|
||||||
hip_public_key_dict2wire, NULL
|
hip_public_key_dict2wire, NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const uint8_t *
|
||||||
|
amtrelay_D_rdf_end(const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
|
||||||
|
{
|
||||||
|
(void)pkt;
|
||||||
|
return rdf < pkt_end ? rdf + 1 : NULL;
|
||||||
|
}
|
||||||
|
static getdns_return_t
|
||||||
|
amtrelay_D_wire2dict(getdns_dict *dict, const uint8_t *rdf)
|
||||||
|
{
|
||||||
|
return getdns_dict_set_int(dict, "discovery_optional", (*rdf >> 7));
|
||||||
|
}
|
||||||
|
static getdns_return_t
|
||||||
|
amtrelay_D_dict2wire(const getdns_dict *dict,
|
||||||
|
uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
|
||||||
|
{
|
||||||
|
getdns_return_t r;
|
||||||
|
uint32_t value;
|
||||||
|
(void)rdata; /* unused parameter */
|
||||||
|
|
||||||
|
if ((r = getdns_dict_get_int(dict, "discovery_optional", &value)))
|
||||||
|
return r;
|
||||||
|
|
||||||
|
*rdf_len = 1;
|
||||||
|
if (*rdf_len < 1)
|
||||||
|
return GETDNS_RETURN_NEED_MORE_SPACE;
|
||||||
|
|
||||||
|
*rdf_len = 1;
|
||||||
|
*rdf = value ? 0x80 : 0x00;
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
static _getdns_rdf_special amtrelay_D = {
|
||||||
|
amtrelay_D_rdf_end,
|
||||||
|
amtrelay_D_wire2dict, NULL,
|
||||||
|
amtrelay_D_dict2wire, NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t *
|
||||||
|
amtrelay_rtype_rdf_end(
|
||||||
|
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
|
||||||
|
{
|
||||||
|
return rdf;
|
||||||
|
}
|
||||||
|
static getdns_return_t
|
||||||
|
amtrelay_rtype_wire2dict(getdns_dict *dict, const uint8_t *rdf)
|
||||||
|
{
|
||||||
|
return _getdns_dict_set_int(
|
||||||
|
dict, "replay_type", (rdf[-1] & 0x7F));
|
||||||
|
}
|
||||||
|
static getdns_return_t
|
||||||
|
amtrelay_rtype_dict2wire(
|
||||||
|
const getdns_dict *dict, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
|
||||||
|
{
|
||||||
|
getdns_return_t r;
|
||||||
|
uint32_t value;
|
||||||
|
|
||||||
|
if ((r = getdns_dict_get_int(dict, "relay_type", &value)))
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (rdf - 1 < rdata)
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
|
||||||
|
*rdf_len = 0;
|
||||||
|
rdf[-1] |= (value & 0x7F);
|
||||||
|
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
static _getdns_rdf_special amtrelay_rtype = {
|
||||||
|
amtrelay_rtype_rdf_end,
|
||||||
|
amtrelay_rtype_wire2dict, NULL,
|
||||||
|
amtrelay_rtype_dict2wire, NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t *
|
||||||
|
amtrelay_relay_rdf_end(
|
||||||
|
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
|
||||||
|
{
|
||||||
|
const uint8_t *end;
|
||||||
|
|
||||||
|
if (rdf - 4 < pkt)
|
||||||
|
return NULL;
|
||||||
|
switch (rdf[-1] & 0x7F) {
|
||||||
|
case 0: end = rdf;
|
||||||
|
break;
|
||||||
|
case 1: end = rdf + 4;
|
||||||
|
break;
|
||||||
|
case 2: end = rdf + 16;
|
||||||
|
break;
|
||||||
|
case 3: for (end = rdf; end < pkt_end; end += *end + 1)
|
||||||
|
if ((*end & 0xC0) == 0xC0)
|
||||||
|
end += 2;
|
||||||
|
else if (*end & 0xC0)
|
||||||
|
return NULL;
|
||||||
|
else if (!*end) {
|
||||||
|
end += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return end <= pkt_end ? end : NULL;
|
||||||
|
}
|
||||||
|
static getdns_return_t
|
||||||
|
amtrelay_relay_equip_const_bindata(
|
||||||
|
const uint8_t *rdf, size_t *size, const uint8_t **data)
|
||||||
|
{
|
||||||
|
*data = rdf;
|
||||||
|
switch (rdf[-1] & 0x7F) {
|
||||||
|
case 0: *size = 0;
|
||||||
|
break;
|
||||||
|
case 1: *size = 4;
|
||||||
|
break;
|
||||||
|
case 2: *size = 16;
|
||||||
|
break;
|
||||||
|
case 3: while (*rdf)
|
||||||
|
if ((*rdf & 0xC0) == 0xC0)
|
||||||
|
rdf += 2;
|
||||||
|
else if (*rdf & 0xC0)
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
else
|
||||||
|
rdf += *rdf + 1;
|
||||||
|
*size = rdf + 1 - *data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getdns_return_t
|
||||||
|
amtrelay_relay_wire2dict(getdns_dict *dict, const uint8_t *rdf)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
const uint8_t *data;
|
||||||
|
|
||||||
|
if (amtrelay_relay_equip_const_bindata(rdf, &size, &data))
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
|
||||||
|
else if (! size)
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
else
|
||||||
|
return _getdns_dict_set_const_bindata(dict, "relay", size, data);
|
||||||
|
}
|
||||||
|
static getdns_return_t
|
||||||
|
amtrelay_relay_2wire(
|
||||||
|
const getdns_bindata *value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
|
||||||
|
{
|
||||||
|
assert(rdf - 1 >= rdata && (rdf[-1] & 0x7F) > 0);
|
||||||
|
|
||||||
|
switch (rdf[-1] & 0x7F) {
|
||||||
|
case 1: if (!value || value->size != 4)
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
if (*rdf_len < 4) {
|
||||||
|
*rdf_len = 4;
|
||||||
|
return GETDNS_RETURN_NEED_MORE_SPACE;
|
||||||
|
}
|
||||||
|
*rdf_len = 4;
|
||||||
|
(void)memcpy(rdf, value->data, 4);
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
case 2: if (!value || value->size != 16)
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
if (*rdf_len < 16) {
|
||||||
|
*rdf_len = 16;
|
||||||
|
return GETDNS_RETURN_NEED_MORE_SPACE;
|
||||||
|
}
|
||||||
|
*rdf_len = 16;
|
||||||
|
(void)memcpy(rdf, value->data, 16);
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
case 3: if (!value || value->size == 0)
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
/* Assume bindata is a valid dname; garbage in, garbage out */
|
||||||
|
if (*rdf_len < value->size) {
|
||||||
|
*rdf_len = value->size;
|
||||||
|
return GETDNS_RETURN_NEED_MORE_SPACE;
|
||||||
|
}
|
||||||
|
*rdf_len = value->size;
|
||||||
|
(void)memcpy(rdf, value->data, value->size);
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
default:
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
static getdns_return_t
|
||||||
|
amtrelay_relay_dict2wire(
|
||||||
|
const getdns_dict *dict, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
|
||||||
|
{
|
||||||
|
getdns_return_t r;
|
||||||
|
getdns_bindata *value;
|
||||||
|
|
||||||
|
if (rdf - 1 < rdata)
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
|
||||||
|
else if ((rdf[-1] & 0x7F) == 0) {
|
||||||
|
*rdf_len = 0;
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
else if ((r = getdns_dict_get_bindata(dict, "relay", &value)))
|
||||||
|
return r;
|
||||||
|
else
|
||||||
|
return amtrelay_relay_2wire(value, rdata, rdf, rdf_len);
|
||||||
|
}
|
||||||
|
static _getdns_rdf_special amtrelay_relay = {
|
||||||
|
amtrelay_relay_rdf_end,
|
||||||
|
amtrelay_relay_wire2dict, NULL,
|
||||||
|
amtrelay_relay_dict2wire, NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static _getdns_rdata_def a_rdata[] = {
|
static _getdns_rdata_def a_rdata[] = {
|
||||||
{ "ipv4_address" , GETDNS_RDF_A , NULL }};
|
{ "ipv4_address" , GETDNS_RDF_A , NULL }};
|
||||||
|
@ -665,6 +873,17 @@ static _getdns_rdata_def dlv_rdata[] = {
|
||||||
{ "algorithm" , GETDNS_RDF_I1 , NULL },
|
{ "algorithm" , GETDNS_RDF_I1 , NULL },
|
||||||
{ "digest_type" , GETDNS_RDF_I1 , NULL },
|
{ "digest_type" , GETDNS_RDF_I1 , NULL },
|
||||||
{ "digest" , GETDNS_RDF_X , NULL }};
|
{ "digest" , GETDNS_RDF_X , NULL }};
|
||||||
|
static _getdns_rdata_def doa_rdata[] = {
|
||||||
|
{ "enterprise" , GETDNS_RDF_I4 , NULL },
|
||||||
|
{ "type" , GETDNS_RDF_I4 , NULL },
|
||||||
|
{ "location" , GETDNS_RDF_I1 , NULL },
|
||||||
|
{ "media_type" , GETDNS_RDF_S , NULL },
|
||||||
|
{ "data" , GETDNS_RDF_B , NULL }};
|
||||||
|
static _getdns_rdata_def amtrelay_rdata[] = {
|
||||||
|
{ "precedence" , GETDNS_RDF_I1 , NULL },
|
||||||
|
{ "discovery_optional" , GETDNS_RDF_SPECIAL, &amtrelay_D},
|
||||||
|
{ "relay_type" , GETDNS_RDF_SPECIAL, &amtrelay_rtype },
|
||||||
|
{ "relay" , GETDNS_RDF_SPECIAL, &amtrelay_relay }};
|
||||||
|
|
||||||
static _getdns_rr_def _getdns_rr_defs[] = {
|
static _getdns_rr_def _getdns_rr_defs[] = {
|
||||||
{ NULL, NULL, 0 },
|
{ NULL, NULL, 0 },
|
||||||
|
@ -926,7 +1145,8 @@ static _getdns_rr_def _getdns_rr_defs[] = {
|
||||||
{ "URI", uri_rdata, ALEN( uri_rdata) }, /* 256 - */
|
{ "URI", uri_rdata, ALEN( uri_rdata) }, /* 256 - */
|
||||||
{ "CAA", caa_rdata, ALEN( caa_rdata) },
|
{ "CAA", caa_rdata, ALEN( caa_rdata) },
|
||||||
{ "AVC", txt_rdata, ALEN( txt_rdata) },
|
{ "AVC", txt_rdata, ALEN( txt_rdata) },
|
||||||
{ "DOA", UNKNOWN_RDATA, 0 }, /* - 259 */
|
{ "DOA", doa_rdata, ALEN( doa_rdata) },
|
||||||
|
{ "AMTRELAY", amtrelay_rdata, ALEN( amtrelay_rdata) }, /* - 260 */
|
||||||
{ "TA", ds_rdata, ALEN( ds_rdata) }, /* 32768 */
|
{ "TA", ds_rdata, ALEN( ds_rdata) }, /* 32768 */
|
||||||
{ "DLV", dlv_rdata, ALEN( dlv_rdata) } /* 32769 */
|
{ "DLV", dlv_rdata, ALEN( dlv_rdata) } /* 32769 */
|
||||||
};
|
};
|
||||||
|
@ -934,12 +1154,12 @@ static _getdns_rr_def _getdns_rr_defs[] = {
|
||||||
const _getdns_rr_def *
|
const _getdns_rr_def *
|
||||||
_getdns_rr_def_lookup(uint16_t rr_type)
|
_getdns_rr_def_lookup(uint16_t rr_type)
|
||||||
{
|
{
|
||||||
if (rr_type <= 259)
|
if (rr_type <= 260)
|
||||||
return &_getdns_rr_defs[rr_type];
|
return &_getdns_rr_defs[rr_type];
|
||||||
else if (rr_type == 32768)
|
else if (rr_type == 32768)
|
||||||
return &_getdns_rr_defs[260];
|
|
||||||
else if (rr_type == 32769)
|
|
||||||
return &_getdns_rr_defs[261];
|
return &_getdns_rr_defs[261];
|
||||||
|
else if (rr_type == 32769)
|
||||||
|
return &_getdns_rr_defs[262];
|
||||||
return _getdns_rr_defs;
|
return _getdns_rr_defs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue