#ifndef TYPES_H
#define TYPES_H
nonnull_all
static really_inline int32_t scan_type_or_class(
const char *data,
size_t length,
uint16_t *code,
const mnemonic_t **mnemonic);
nonnull_all
static really_inline int32_t parse_type(
parser_t *parser,
const type_info_t *type,
const rdata_info_t *field,
rdata_t *rdata,
const token_t *token);
nonnull_all
static really_inline int32_t parse_name(
parser_t *parser,
const type_info_t *type,
const rdata_info_t *field,
rdata_t *rdata,
const token_t *token);
nonnull_all
static really_inline int32_t parse_string(
parser_t *parser,
const type_info_t *type,
const rdata_info_t *field,
rdata_t *rdata,
const token_t *token);
nonnull_all
static really_inline int32_t parse_text(
parser_t *parser,
const type_info_t *type,
const rdata_info_t *field,
rdata_t *rdata,
const token_t *token);
#define FIELDS(fields) \
{ (sizeof(fields)/sizeof(fields[0])), fields }
#define FIELD(name) \
{ { { name, sizeof(name) - 1 } } }
#define CLASS(name, code) \
{ { { name, sizeof(name) - 1 }, code } }
#define UNKNOWN_CLASS(code) \
{ { { "", 0 }, code } }
#define TYPE(name, code, _class, fields, check, parse) \
{ { { name, sizeof(name) - 1 }, code }, _class, false, false, fields, check, parse }
#define UNKNOWN_TYPE(code) \
{ { { "", 0 }, code }, 0, false, false, { 0, NULL }, check_generic_rr, parse_unknown_rdata }
nonnull((1,2,3,4))
static really_inline int32_t check_bytes(
parser_t *parser,
const type_info_t *type,
const rdata_info_t *field,
const uint8_t *data,
const size_t length,
const size_t size)
{
(void)data;
if (length < size)
SYNTAX_ERROR(parser, "Missing %s in %s", NAME(field), NAME(type));
return (int32_t)size;
}
#define check_int8(...) check_bytes(__VA_ARGS__, sizeof(uint8_t))
#define check_int16(...) check_bytes(__VA_ARGS__, sizeof(uint16_t))
#define check_int32(...) check_bytes(__VA_ARGS__, sizeof(uint32_t))
#define check_int64(...) check_bytes(__VA_ARGS__, sizeof(uint64_t))
#define check_ip4(...) check_bytes(__VA_ARGS__, 4)
#define check_ip6(...) check_bytes(__VA_ARGS__, 16)
#define check_ilnp64(...) check_bytes(__VA_ARGS__, sizeof(uint64_t))
nonnull((1,2,3,4))
static really_inline int32_t check_ttl(
parser_t *parser,
const type_info_t *type,
const rdata_info_t *field,
const uint8_t *data,
const size_t length)
{
uint32_t number;
if (length < sizeof(number))
SYNTAX_ERROR(parser, "Missing %s in %s", NAME(field), NAME(type));
memcpy(&number, data, sizeof(number));
number = be32toh(number);
if (number > INT32_MAX)
SEMANTIC_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type));
return 4;
}
zone_nonnull((1,2,3,4))
static really_inline int32_t check_name(
parser_t *parser,
const type_info_t *type,
const rdata_info_t *field,
const uint8_t *data,
const size_t length)
{
int32_t label = 0, count = 0;
while (count < (int32_t)length) {
label = data[count];
count += 1 + label;
if (!label)
break;
}
if (!count || count > (int32_t)length)
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type));
return count;
}
zone_nonnull((1,2,3,4))
static really_inline int32_t check_string(
parser_t *parser,
const type_info_t *type,
const rdata_info_t *field,
const uint8_t *data,
const size_t length)
{
int32_t count;
if (!length || (count = 1 + (int32_t)data[0]) > (int32_t)length)
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type));
return count;
}
zone_nonnull((1,2,3,4))
static really_inline int32_t check_nsec(
parser_t *parser,
const type_info_t *type,
const rdata_info_t *field,
const uint8_t *data,
const size_t length)
{
int32_t count = 0;
int32_t last_window = -1;
while ((count + 2) < (int32_t)length) {
const int32_t window = (int32_t)data[0];
const int32_t blocks = (int32_t)data[1];
if (window <= last_window)
SYNTAX_ERROR(parser, "Invalid %s in %s, windows are out-of-order",
NAME(field), NAME(type));
if (!blocks || blocks > 32)
SYNTAX_ERROR(parser, "Invalid %s in %s, blocks are out-of-bounds",
NAME(field), NAME(type));
count += 2 + blocks;
last_window = window;
}
if (count != (int32_t)length)
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type));
return count;
}
zone_nonnull((1))
static really_inline int32_t check(size_t *length, int32_t count)
{
if (count < 0)
return count;
*length += (size_t)count;
return 0;
}
nonnull_all
static really_inline void adjust_line_count(file_t *file)
{
file->line += file->span;
file->span = 0;
}
nonnull_all
static really_inline int32_t accept_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
(void)type;
assert(rdata->octets <= rdata->limit);
assert(rdata->octets >= parser->rdata->octets);
size_t length = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
assert(length <= UINT16_MAX);
assert(parser->owner->length <= UINT8_MAX);
int32_t code = parser->options.accept.callback(
parser,
&(zone_name_t){ (uint8_t)parser->owner->length, parser->owner->octets },
parser->file->last_type,
parser->file->last_class,
*parser->file->ttl,
(uint16_t)length,
parser->rdata->octets,
parser->user_data);
adjust_line_count(parser->file);
return code;
}
nonnull_all
static int32_t check_a_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
assert(rdata->octets >= parser->rdata->octets);
if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets == 4)
return accept_rr(parser, type, rdata);
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
}
nonnull_all
static int32_t parse_a_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_ip4(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_ns_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_name(parser, type, &f[0], o, n))) < 0)
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_ns_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_soa_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_name(parser, type, &f[0], o, n))) ||
(r = check(&c, check_name(parser, type, &f[1], o+c, n-c))) ||
(r = check(&c, check_int32(parser, type, &f[2], o+c, n-c))) ||
(r = check(&c, check_ttl(parser, type, &f[3], o+c, n-c))) ||
(r = check(&c, check_ttl(parser, type, &f[4], o+c, n-c))) ||
(r = check(&c, check_ttl(parser, type, &f[5], o+c, n-c))) ||
(r = check(&c, check_ttl(parser, type, &f[6], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_soa_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_int32(parser, type, &fields[2], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[3], token)) < 0)
return code;
if ((code = parse_ttl(parser, type, &fields[3], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[4], token)) < 0)
return code;
if ((code = parse_ttl(parser, type, &fields[4], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[5], token)) < 0)
return code;
if ((code = parse_ttl(parser, type, &fields[5], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[6], token)) < 0)
return code;
if ((code = parse_ttl(parser, type, &fields[6], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_wks_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_ip4(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int8(parser, type, &f[0], o+c, n-c))))
return r;
if (n > 8192 + 5)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_wks_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_ip4(parser, type, &fields[0], rdata, token) < 0))
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
uint8_t protocol;
if (!scan_protocol(token->data, token->length, &protocol))
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[1]), NAME(type));
*rdata->octets++ = protocol;
uint8_t *bitmap = rdata->octets;
int32_t highest_port = -1;
take(parser, token);
while (is_contiguous(token)) {
uint16_t port;
if (!scan_service(token->data, token->length, protocol, &port))
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&type->rdata.fields[2]), NAME(type));
if (port > highest_port) {
size_t offset = highest_port < 0 ? 0 : (size_t)highest_port / 8 + 1;
size_t length = (size_t)port / 8 + 1;
memset(bitmap + offset, 0, length - offset);
highest_port = port;
}
bitmap[port / 8] |= (1 << (7 - port % 8));
take(parser, token);
}
rdata->octets += (size_t)highest_port / 8 + 1;
if (have_delimiter(parser, type, token) < 0)
return token->code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_hinfo_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_string(parser, type, &f[0], o, n))) ||
(r = check(&c, check_string(parser, type, &f[1], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_hinfo_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous_or_quoted(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_string(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_quoted_or_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_string(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_minfo_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_name(parser, type, &f[0], o, n))) ||
(r = check(&c, check_name(parser, type, &f[1], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_minfo_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_mx_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) ||
(r = check(&c, check_name(parser, type, &f[1], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_mx_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_txt_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_string(parser, type, &f[0], o, n))))
return r;
while (c < n)
if ((r = check(&c, check_string(parser, type, &f[0], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_txt_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
while (is_contiguous_or_quoted(token)) {
if ((code = parse_string(parser, type, &fields[0], rdata, token)) < 0)
return code;
take(parser, token);
}
if ((code = have_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_x25_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_string(parser, type, &f[0], o, n))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_x25_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous_or_quoted(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_string(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_isdn_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_string(parser, type, &f[0], o, n))))
return r;
if (c < n && (r = check(&c, check_string(parser, type, &f[1], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_isdn_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous_or_quoted(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_string(parser, type, &fields[0], rdata, token)) < 0)
return code;
take(parser, token);
if (is_contiguous_or_quoted(token)) {
if ((code = parse_string(parser, type, &fields[1], rdata, token)) < 0)
return code;
take(parser, token);
}
if ((code = have_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_rt_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) ||
(r = check(&c, check_name(parser, type, &f[1], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_rt_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_nsap_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
if (rdata->octets == parser->rdata->octets)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_nsap_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_nsap(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_nsap_ptr_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_string(parser, type, &f[0], o, n))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
}
{
size_t i = 0;
const size_t n = parser->file->owner.length;
const uint8_t *o = parser->file->owner.octets;
for (; i < n; i += 2)
if (o[i] != 1 || (base16_table_dec_32bit_d1[o[i+1]] > 0xff))
break;
const uint8_t nsap_int[] = { 4, 'n', 's', 'a', 'p', 3, 'i', 'n', 't', 0 };
if (strncasecmp((const char *)o + i, (const char *)nsap_int, 9) != 0 || !i || i + 10 != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
}
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_nsap_ptr_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous_or_quoted(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_string(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return check_nsap_ptr_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_key_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
#if 0
int32_t r;
size_t c = 0;
const size_t n = parser->rdata->length;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
#endif
(void)type;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_key_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0)
return code;
take(parser, token);
if ((code = parse_base64_sequence(parser, type, &fields[3], rdata, token)) < 0)
return code;
return check_key_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_px_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) ||
(r = check(&c, check_name(parser, type, &f[1], o+c, n-c))) ||
(r = check(&c, check_name(parser, type, &f[2], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s record", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_px_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[2], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_gpos_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_string(parser, type, &f[0], o, n))) ||
(r = check(&c, check_string(parser, type, &f[1], o+c, n-c))) ||
(r = check(&c, check_string(parser, type, &f[2], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s record", NAME(type));
return accept_rr(parser, type, rdata);
}
static int32_t parse_gpos_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_latitude(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_longitude(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_altitude(parser, type, &fields[2], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_aaaa_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_ip6(parser, type, &f[0], o, n))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s record", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_aaaa_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_ip6(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_loc_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets != 16)
SYNTAX_ERROR(parser, "Invalid %s record", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_loc_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
uint32_t degrees, minutes, seconds;
uint32_t latitude, longitude, altitude;
const rdata_info_t *fields = type->rdata.fields;
static const uint8_t defaults[4] = { 0x00, 0x12, 0x16, 0x13 };
memcpy(rdata->octets, &defaults, sizeof(defaults));
if ((code = have_contiguous(parser, type, &fields[4], token)) < 0)
return code;
if (scan_degrees(token->data, token->length, °rees) == -1)
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[4]), NAME(type));
if ((code = take_contiguous(parser, type, &fields[4], token)) < 0)
return code;
if (scan_minutes(token->data, token->length, &minutes) == -1)
goto north_south;
degrees += minutes;
if ((code = take_contiguous(parser, type, &fields[4], token)) < 0)
return code;
if (scan_seconds(token->data, token->length, &seconds) == -1)
goto north_south;
degrees += seconds;
if ((code = take_contiguous(parser, type, &fields[4], token)) < 0)
return code;
north_south:
if (token->data[0] == 'N')
latitude = htobe32((1u<<31) + degrees);
else if (token->data[0] == 'S')
latitude = htobe32((1u<<31) - degrees);
else
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[4]), NAME(type));
memcpy(&rdata->octets[4], &latitude, sizeof(latitude));
if ((code = take_contiguous(parser, type, &fields[5], token)) < 0)
return code;
if (scan_degrees(token->data, token->length, °rees) == -1)
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[5]), NAME(type));
if ((code = take_contiguous(parser, type, &fields[5], token)) < 0)
return code;
if (scan_minutes(token->data, token->length, &minutes) == -1)
goto east_west;
degrees += minutes;
if ((code = take_contiguous(parser, type, &fields[5], token)) < 0)
return code;
if (scan_seconds(token->data, token->length, &seconds) == -1)
goto east_west;
degrees += seconds;
if ((code = take_contiguous(parser, type, &fields[5], token)) < 0)
return code;
east_west:
if (token->data[0] == 'E')
longitude = htobe32((1u<<31) + degrees);
else if (token->data[0] == 'W')
longitude = htobe32((1u<<31) - degrees);
else
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[5]), NAME(type));
memcpy(&rdata->octets[8], &longitude, sizeof(longitude));
if ((code = take_contiguous(parser, type, &fields[6], token)) < 0)
return code;
if (scan_altitude(token->data, token->length, &altitude) == -1)
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[6]), NAME(type));
altitude = htobe32(altitude);
memcpy(&rdata->octets[12], &altitude, sizeof(altitude));
take(parser, token);
if (!is_contiguous(token))
goto skip_optional;
if (scan_precision(token->data, token->length, &rdata->octets[1]))
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[1]), NAME(type));
take(parser, token);
if (!is_contiguous(token))
goto skip_optional;
if (scan_precision(token->data, token->length, &rdata->octets[2]))
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[2]), NAME(type));
take(parser, token);
if (!is_contiguous(token))
goto skip_optional;
if (scan_precision(token->data, token->length, &rdata->octets[3]))
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[3]), NAME(type));
take(parser, token);
skip_optional:
if ((code = have_delimiter(parser, type, token)) < 0)
return code;
rdata->octets += 16;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_nxt_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_name(parser, type, &f[0], o+c, n-c))))
return r;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_nxt_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0)
return code;
take(parser, token);
if ((code = parse_nxt(parser, type, &fields[1], rdata, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_eid_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets <= 0)
SYNTAX_ERROR(parser, "Invalid %s record", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_eid_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = parse_base16_sequence(parser, type, &fields[1], rdata, token)) < 0)
return code;
return check_eid_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_srv_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int16(parser, type, &f[1], o+c, n-c))) ||
(r = check(&c, check_int16(parser, type, &f[2], o+c, n-c))) ||
(r = check(&c, check_name(parser, type, &f[3], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_srv_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[2], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[3], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[3], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_atma_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
assert(rdata->octets >= parser->rdata->octets);
if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets > 2)
return accept_rr(parser, type, rdata);
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
}
nonnull_all
static int32_t parse_atma_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_atma(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_naptr_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
(void)type;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_naptr_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_quoted_or_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_string(parser, type, &fields[2], rdata, token)) < 0)
return code;
if ((code = take_quoted_or_contiguous(parser, type, &fields[3], token)) < 0)
return code;
if ((code = parse_string(parser, type, &fields[3], rdata, token)) < 0)
return code;
if ((code = take_quoted_or_contiguous(parser, type, &fields[4], token)) < 0)
return code;
if ((code = parse_string(parser, type, &fields[4], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[5], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[5], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_cert_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
(void)type;
assert(rdata->octets >= parser->rdata->octets);
if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets < 6)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_cert_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_certificate_type(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_algorithm(parser, type, &fields[2], rdata, token)) < 0)
return code;
take(parser, token);
if ((code = parse_base64_sequence(parser, type, &fields[3], rdata, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_sink_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
(void)type;
assert(rdata->octets >= parser->rdata->octets);
if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets < 3)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_sink_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0)
return code;
take(parser, token);
if ((code = parse_base64_sequence(parser, type, &fields[3], rdata, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_apl_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_apl_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
while (is_contiguous(token)) {
int32_t length;
const size_t size = (uintptr_t)rdata->limit - (uintptr_t)rdata->octets;
if ((length = scan_apl(token->data, token->length, rdata->octets, size)) < 0)
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[0]), NAME(type));
assert(length == 8 || length == 20 );
rdata->octets += (size_t)length;
take(parser, token);
}
if ((code = have_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_ds_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) ||
(r = check(&c, check_int8(parser, type, &f[2], o+c, n-c))))
return r;
const uint8_t digest_algorithm = parser->rdata->octets[3];
if ((digest_algorithm & 0x7) == digest_algorithm) {
static const uint8_t digest_sizes[8] = {
0,
20,
32,
32,
48,
32,
32,
0
};
const uint8_t digest_size = digest_sizes[ digest_algorithm ];
if (digest_size && n - 4 != digest_size)
SEMANTIC_ERROR(parser, "Invalid digest in %s", NAME(type));
}
if (c > n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_ds_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_algorithm(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0)
return code;
take(parser, token);
if (!(token->length == 1 && (char)*token->data == '0')
&& (code = parse_base16_sequence(parser, type, &fields[3], rdata, token)) < 0)
return code;
const uint8_t digest_algorithm = parser->rdata->octets[3];
if ((digest_algorithm & 0x7) == digest_algorithm) {
static const uint8_t digest_sizes[8] = {
0,
20,
32,
32,
48,
32,
32,
0
};
const uint8_t digest_size = digest_sizes[ digest_algorithm ];
size_t length = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
if (digest_size && length - 4 != digest_size)
SEMANTIC_ERROR(parser, "Invalid digest in %s", NAME(type));
}
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_sshfp_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int8(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))))
return r;
if (c == n)
SYNTAX_ERROR(parser, "Missing %s in %s", NAME((&f[n!=0])), NAME(type));
else if (o[1] == 1 && (n - c) != 20)
SEMANTIC_ERROR(parser, "Wrong fingerprint size for type %s in %s",
"SHA1", NAME(type));
else if (o[1] == 2 && (n - c) != 32)
SEMANTIC_ERROR(parser, "Wrong fingerprint size for type %s in %s",
"SHA256", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_sshfp_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0)
return code;
const uint8_t *fingerprint_type = rdata->octets;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0)
return code;
const uint8_t *fingerprint = rdata->octets;
take(parser, token);
if ((code = parse_base16_sequence(parser, type, &fields[2], rdata, token)) < 0)
return code;
size_t fingerprint_size = (uintptr_t)rdata->octets - (uintptr_t)fingerprint;
if (unlikely(*fingerprint_type == 1 && fingerprint_size != 20))
SEMANTIC_ERROR(parser, "Wrong fingerprint size for type %s in %s",
"SHA1", NAME(type));
if (unlikely(*fingerprint_type == 2 && fingerprint_size != 32))
SEMANTIC_ERROR(parser, "Wrong fingerprint size for type %s in %s",
"SHA256", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_ipseckey_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata);
nonnull_all
static int32_t parse_ipseckey_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token);
diagnostic_push()
gcc_diagnostic_ignored(missing-field-initializers)
clang_diagnostic_ignored(missing-field-initializers)
static const rdata_info_t ipseckey_ipv4_rdata_fields[] = {
FIELD("precedence"),
FIELD("gateway type"),
FIELD("algorithm"),
FIELD("gateway"),
FIELD("public key")
};
static const type_info_t ipseckey_ipv4[] = {
TYPE("IPSECKEY", ZONE_TYPE_IPSECKEY, ZONE_CLASS_IN, FIELDS(ipseckey_ipv4_rdata_fields),
check_ipseckey_rr, parse_ipseckey_rdata),
};
static const rdata_info_t ipseckey_ipv6_rdata_fields[] = {
FIELD("precedence"),
FIELD("gateway type"),
FIELD("algorithm"),
FIELD("gateway"),
FIELD("public key")
};
static const type_info_t ipseckey_ipv6[] = {
TYPE("IPSECKEY", ZONE_TYPE_IPSECKEY, ZONE_CLASS_IN, FIELDS(ipseckey_ipv6_rdata_fields),
check_ipseckey_rr, parse_ipseckey_rdata),
};
diagnostic_pop()
nonnull_all
static int32_t check_ipseckey_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const type_info_t *t = type;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int8(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) ||
(r = check(&c, check_int8(parser, type, &f[2], o+c, n-c))))
return r;
switch (parser->rdata->octets[1]) {
case 1:
t = (const type_info_t *)ipseckey_ipv4;
f = ipseckey_ipv4_rdata_fields;
if ((r = check(&c, check_ip4(parser, t, &f[3], o+c, n-c))) < 0)
return r;
break;
case 2:
t = (const type_info_t *)ipseckey_ipv6;
f = ipseckey_ipv6_rdata_fields;
if ((r = check(&c, check_ip6(parser, t, &f[3], o+c, n-c))) < 0)
return r;
break;
case 0:
break;
case 3:
if ((r = check(&c, check_name(parser, t, &f[3], o+c, n-c))) < 0)
return r;
break;
default:
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
}
switch (parser->rdata->octets[2]) {
case 0:
if (c < n)
SYNTAX_ERROR(parser, "Trailing data in %s", NAME(t));
break;
default:
if (c >= n)
SYNTAX_ERROR(parser, "Missing %s in %s", NAME(&f[4]), NAME(t));
break;
}
return accept_rr(parser, t, rdata);
}
nonnull_all
static int32_t parse_ipseckey_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
uint8_t *octets = rdata->octets;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[3], token)) < 0)
return code;
switch (octets[1]) {
case 0:
if (token->length != 1 || token->data[0] != '.')
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[3]), NAME(type));
break;
case 1:
type = (const type_info_t *)ipseckey_ipv4;
fields = type->rdata.fields;
if ((code = parse_ip4(parser, type, &fields[3], rdata, token)) < 0)
return code;
break;
case 2:
type = (const type_info_t *)ipseckey_ipv6;
fields = type->rdata.fields;
if ((code = parse_ip6(parser, type, &fields[3], rdata, token)) < 0)
return code;
break;
case 3:
if ((code = parse_name(parser, type, &fields[3], rdata, token)) < 0)
return code;
break;
default:
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[3]), NAME(type));
}
take(parser, token);
switch (octets[2]) {
case 0:
if ((code = have_delimiter(parser, type, token)) < 0)
return code;
break;
default:
if ((code = parse_base64_sequence(parser, type, &fields[4], rdata, token)) < 0)
return code;
break;
}
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_rrsig_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) ||
(r = check(&c, check_int8(parser, type, &f[2], o+c, n-c))) ||
(r = check(&c, check_ttl(parser, type, &f[3], o+c, n-c))) ||
(r = check(&c, check_int32(parser, type, &f[4], o+c, n-c))) ||
(r = check(&c, check_int32(parser, type, &f[5], o+c, n-c))) ||
(r = check(&c, check_int16(parser, type, &f[6], o+c, n-c))) ||
(r = check(&c, check_name(parser, type, &f[7], o+c, n-c))))
return r;
if (c > n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_rrsig_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_type(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_algorithm(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[3], token)) < 0)
return code;
if ((code = parse_ttl(parser, type, &fields[3], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[4], token)) < 0)
return code;
if ((code = parse_time(parser, type, &fields[4], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[5], token)) < 0)
return code;
if ((code = parse_time(parser, type, &fields[5], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[6], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[6], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[7], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[7], rdata, token)) < 0)
return code;
take(parser, token);
if ((code = parse_base64_sequence(parser, type, &fields[8], rdata, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_nsec_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_name(parser, type, &f[0], o, n))) ||
(r = check(&c, check_nsec(parser, type, &f[1], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_nsec_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0)
return code;
take(parser, token);
if ((code = parse_nsec(parser, type, &fields[1], rdata, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_dnskey_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) ||
(r = check(&c, check_int8(parser, type, &f[2], o+c, n-c))))
return r;
if (c > n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_dnskey_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_algorithm(parser, type, &fields[2], rdata, token)) < 0)
return code;
take(parser, token);
if (!(token->length == 1 && (char)*token->data == '0')
&& (code = parse_base64_sequence(parser, type, &fields[3], rdata, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_dhcid_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets < 4)
SEMANTIC_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_dhcid_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = parse_base64_sequence(parser, type, &fields[0], rdata, token)) < 0)
return code;
return check_dhcid_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_nsec3_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int8(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) ||
(r = check(&c, check_int16(parser, type, &f[2], o+c, n-c))) ||
(r = check(&c, check_string(parser, type, &f[3], o+c, n-c))) ||
(r = check(&c, check_string(parser, type, &f[4], o+c, n-c))) ||
(r = check(&c, check_nsec(parser, type, &f[5], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_nsec3_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[2], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[3], token)) < 0)
return code;
if ((code = parse_salt(parser, type, &fields[3], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[4], token)) < 0)
return code;
if ((code = parse_base32(parser, type, &fields[4], rdata, token)) < 0)
return code;
take(parser, token);
if ((code = parse_nsec(parser, type, &fields[5], rdata, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_nsec3param_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int8(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) ||
(r = check(&c, check_int16(parser, type, &f[2], o+c, n-c))) ||
(r = check(&c, check_string(parser, type, &f[3], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_nsec3param_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[2], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[3], token)) < 0)
return code;
if ((code = parse_salt(parser, type, &fields[3], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_tlsa_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int8(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) ||
(r = check(&c, check_int8(parser, type, &f[2], o+c, n-c))))
return r;
if (c >= n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_tlsa_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0)
return code;
take(parser, token);
if ((code = parse_base16_sequence(parser, type, &fields[3], rdata, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_hip_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_hip_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
uint8_t *octets = rdata->octets;
rdata->octets += 1;
if ((code = have_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0)
return code;
rdata->octets += 2;
if ((code = take_contiguous(parser, type, &fields[3], token)) < 0)
return code;
if ((code = parse_base16(parser, type, &fields[3], rdata, token)) < 0)
return code;
if ((rdata->octets - octets) > 255 + 4)
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[3]), NAME(type));
uint8_t hit_length = (uint8_t)((rdata->octets - octets) - 4);
octets[0] = hit_length;
if ((code = take_contiguous(parser, type, &fields[4], token)) < 0)
return code;
if ((code = parse_base64(parser, type, &fields[4], rdata, token)) < 0)
return code;
uint16_t pk_length = htobe16((uint16_t)(((rdata->octets - octets) - hit_length) - 4));
memcpy(&octets[2], &pk_length, sizeof(pk_length));
take(parser, token);
while (is_contiguous(token)) {
if ((code = parse_name(parser, type, &fields[5], rdata, token)) < 0)
return code;
take(parser, token);
}
if ((code = have_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_openpgpkey_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets < 4)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_openpgpkey_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = parse_base64_sequence(parser, type, &fields[0], rdata, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_csync_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int32(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int16(parser, type, &f[1], o+c, n-c))) ||
(r = check(&c, check_nsec(parser, type, &f[2], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_csync_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int32(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[1], rdata, token)) < 0)
return code;
take(parser, token);
if ((code = parse_nsec(parser, type, &fields[2], rdata, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_zonemd_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int32(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) ||
(r = check(&c, check_int8(parser, type, &f[2], o+c, n-c))))
return r;
const uint8_t digest_algorithm = parser->rdata->octets[5];
if ((digest_algorithm & 0x3) == digest_algorithm) {
static const uint8_t digest_sizes[4] = {
0,
48,
64,
0
};
const uint8_t digest_size = digest_sizes[ digest_algorithm ];
if (digest_size && n - 6 != digest_size)
SEMANTIC_ERROR(parser, "Invalid digest in %s", NAME(type));
}
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_zonemd_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int32(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0)
return code;
take(parser, token);
if ((code = parse_base16_sequence(parser, type, &fields[3], rdata, token)) < 0)
return code;
const uint8_t digest_algorithm = parser->rdata->octets[5];
if ((digest_algorithm & 0x3) == digest_algorithm) {
static const uint8_t digest_sizes[4] = {
0,
48,
64,
0
};
const uint8_t digest_size = digest_sizes[ digest_algorithm ];
size_t length = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
if (digest_size && length - 6 != digest_size)
SEMANTIC_ERROR(parser, "Invalid digest in %s", NAME(type));
}
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_svcb_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_svcb_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0)
return code;
take(parser, token);
if ((code = parse_svc_params(parser, type, &fields[2], rdata, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_https_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_https_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0)
return code;
take(parser, token);
if ((code = parse_svc_params(parser, type, &fields[2], rdata, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_dsync_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) ||
(r = check(&c, check_int16(parser, type, &f[2], o+c, n-c))) ||
(r = check(&c, check_name(parser, type, &f[3], o+c, n-c))))
return r;
const uint8_t dsync_scheme = o[2];
uint16_t dsync_type;
memcpy(&dsync_type, o, sizeof(dsync_type));
dsync_type = be16toh(dsync_type);
if (dsync_scheme == 1 && dsync_type != ZONE_TYPE_CDS
&& dsync_type != ZONE_TYPE_CSYNC)
SEMANTIC_ERROR(parser, "Wrong type for scheme 1 in %s", NAME(type));
if (c > n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_dsync_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_type(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[2], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[3], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[3], rdata, token)) < 0)
return code;
const uint8_t dsync_scheme = parser->rdata->octets[2];
uint16_t dsync_type;
memcpy(&dsync_type, parser->rdata->octets, sizeof(dsync_type));
dsync_type = be16toh(dsync_type);
if (dsync_scheme == 1 && dsync_type != ZONE_TYPE_CDS
&& dsync_type != ZONE_TYPE_CSYNC)
SEMANTIC_ERROR(parser, "Wrong type for scheme 1 in %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_nid_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) ||
(r = check(&c, check_ilnp64(parser, type, &f[1], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_nid_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_ilnp64(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_l32_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) ||
(r = check(&c, check_ip4(parser, type, &f[1], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_l32_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_ip4(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_l64_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) ||
(r = check(&c, check_ilnp64(parser, type, &f[1], o+c, n-c))))
return r;
if (c != n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_l64_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_ilnp64(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_eui48_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets != 6)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_eui48_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_eui48(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_eui64_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets != 8)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_eui64_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_eui64(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_uri_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int16(parser, type, &f[1], o+c, n-c))))
return r;
if (c >= n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_uri_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_quoted(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_text(parser, type, &fields[2], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_caa_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int8(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))))
return r;
if (c >= n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_caa_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_caa_tag(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_quoted_or_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_text(parser, type, &fields[2], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_doa_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int32(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int32(parser, type, &f[1], o+c, n-c))) ||
(r = check(&c, check_int8(parser, type, &f[2], o+c, n-c))) ||
(r = check(&c, check_string(parser, type, &f[3], o+c, n-c))))
return r;
if (c > n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_doa_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int32(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int32(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0)
return code;
if ((code = take_quoted_or_contiguous(parser, type, &fields[3], token)) < 0)
return code;
if ((code = parse_string(parser, type, &fields[3], rdata, token)) < 0)
return code;
take(parser, token);
if (!(token->length == 1 && ((char)*token->data == '0' || (char)*token->data == '-'))
&& (code = parse_base64_sequence(parser, type, &fields[4], rdata, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_amtrelay_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata);
nonnull_all
static int32_t parse_amtrelay_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token);
diagnostic_push()
gcc_diagnostic_ignored(missing-field-initializers)
clang_diagnostic_ignored(missing-field-initializers)
static const rdata_info_t amtrelay_ipv4_rdata_fields[] = {
FIELD("precedence"),
FIELD("discovery optional"),
FIELD("type"),
FIELD("relay")
};
static const type_info_t amtrelay_ipv4[] = {
TYPE("AMTRELAY", ZONE_TYPE_AMTRELAY, ZONE_CLASS_IN, FIELDS(amtrelay_ipv4_rdata_fields),
check_amtrelay_rr, parse_amtrelay_rdata),
};
static const rdata_info_t amtrelay_ipv6_rdata_fields[] = {
FIELD("precedence"),
FIELD("discovery optional"),
FIELD("type"),
FIELD("relay")
};
static const type_info_t amtrelay_ipv6[] = {
TYPE("AMTRELAY", ZONE_TYPE_AMTRELAY, ZONE_CLASS_IN, FIELDS(amtrelay_ipv6_rdata_fields),
check_amtrelay_rr, parse_amtrelay_rdata),
};
diagnostic_pop()
nonnull_all
static int32_t check_amtrelay_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const type_info_t *t = type;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int8(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int8(parser, type, &f[2], o+c, n-c))))
return r;
switch (parser->rdata->octets[1] & 0x7f) {
case 1:
t = (const type_info_t *)amtrelay_ipv4;
f = amtrelay_ipv4_rdata_fields;
if ((r = check(&c, check_ip4(parser, t, &f[3], o+c, n-c))) < 0)
return r;
break;
case 2:
t = (const type_info_t *)amtrelay_ipv6;
f = amtrelay_ipv6_rdata_fields;
if ((r = check(&c, check_ip6(parser, t, &f[3], o+c, n-c))) < 0)
return r;
break;
case 0:
break;
case 3:
if ((r = check(&c, check_name(parser, t, &f[3], o+c, n-c))) < 0)
return r;
break;
default:
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
}
if (c < n)
SYNTAX_ERROR(parser, "Trailing data in %s", NAME(t));
return accept_rr(parser, t, rdata);
}
nonnull_all
static int32_t parse_amtrelay_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
uint8_t *octets = rdata->octets;
uint8_t D;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if (token->length != 1)
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[1]), NAME(type));
switch((char)*token->data) {
case '0':
D = 0x00;
break;
case '1':
D = 0x80;
break;
default :
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[1]), NAME(type));
}
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[3], token)) < 0)
return code;
switch (octets[1]) {
case 0:
if (!(token->length == 1 && *token->data == '.'))
SYNTAX_ERROR(parser, "Invalid %s in %s, the no gateway type (type 0) of AMTRELAY requires the relay field to have '.' in it", NAME(&fields[3]), NAME(type));
break;
case 1:
type = (const type_info_t *)amtrelay_ipv4;
fields = type->rdata.fields;
if ((code = parse_ip4(parser, type, &fields[3], rdata, token)) < 0)
return code;
break;
case 2:
type = (const type_info_t *)amtrelay_ipv6;
fields = type->rdata.fields;
if ((code = parse_ip6(parser, type, &fields[3], rdata, token)) < 0)
return code;
break;
case 3:
if ((code = parse_name(parser, type, &fields[3], rdata, token)) < 0)
return code;
break;
default:
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[3]), NAME(type));
}
octets[1] |= D;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_ipn_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;
if ((r = check(&c, check_int64(parser, type, &f[0], o, n))))
return r;
if (c > n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_ipn_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;
token_t left, right;
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if (!(right.data = memchr(token->data, '.', token->length))) {
if ((code = parse_int64(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
left.code = token->code;
left.data = token->data;
left.length = (size_t)(right.data - token->data);
right.code = token->code;
right.data += 1;
right.length = token->length - left.length - 1;
if ((code = parse_int32(parser, type, &fields[0], rdata, &left)) < 0)
return code;
if ((code = parse_int32(parser, type, &fields[0], rdata, &right)) < 0)
return code;
if ((code = take_delimiter(parser, type, token)) < 0)
return code;
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t check_generic_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
return accept_rr(parser, type, rdata);
}
nonnull_all
static int32_t parse_generic_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
uint16_t rdlength;
static const rdata_info_t fields[] = {
FIELD("rdlength"),
FIELD("rdata")
};
if ((code = take_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if (!scan_int16(token->data, token->length, &rdlength))
SYNTAX_ERROR(parser, "Invalid RDLENGTH in %s", NAME(type));
take(parser, token);
if (is_contiguous(token)) {
struct base16_state state = { .eof = 0, .bytes = 0, .carry = 0 };
do {
size_t length = token->length + 1 / 2;
if (length > (uintptr_t)rdata->limit - (uintptr_t)rdata->octets)
SYNTAX_ERROR(parser, "Invalid RDATA in %s", NAME(type));
if (!base16_stream_decode(&state, token->data, token->length, rdata->octets, &length))
SYNTAX_ERROR(parser, "Invalid RDATA in %s", NAME(type));
rdata->octets += length;
take(parser, token);
} while (is_contiguous(token));
if (state.bytes)
*rdata->octets++ = state.carry;
}
if ((code = have_delimiter(parser, type, token)) < 0)
return code;
if (rdata->octets - parser->rdata->octets != rdlength)
SYNTAX_ERROR(parser, "Invalid RDATA in %s", NAME(type));
return type->check(parser, type, rdata);
}
nonnull_all
static int32_t parse_unknown_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
(void)type;
(void)rdata;
(void)token;
SYNTAX_ERROR(parser, "Unknown record type");
}
diagnostic_push()
gcc_diagnostic_ignored(missing-field-initializers)
clang_diagnostic_ignored(missing-field-initializers)
static const class_info_t classes[] = {
UNKNOWN_CLASS(0),
CLASS("IN", ZONE_CLASS_IN),
CLASS("CS", ZONE_CLASS_CS),
CLASS("CH", ZONE_CLASS_CH),
CLASS("HS", ZONE_CLASS_HS)
};
static const rdata_info_t a_rdata_fields[] = {
FIELD("address")
};
static const rdata_info_t ns_rdata_fields[] = {
FIELD("host")
};
static const rdata_info_t md_rdata_fields[] = {
FIELD("madname")
};
static const rdata_info_t mf_rdata_fields[] = {
FIELD("madname")
};
static const rdata_info_t cname_rdata_fields[] = {
FIELD("host")
};
static const rdata_info_t soa_rdata_fields[] = {
FIELD("primary"),
FIELD("mailbox"),
FIELD("serial"),
FIELD("refresh"),
FIELD("retry"),
FIELD("expire"),
FIELD("minimum")
};
static const rdata_info_t mb_rdata_fields[] = {
FIELD("madname")
};
static const rdata_info_t mg_rdata_fields[] = {
FIELD("mgmname")
};
static const rdata_info_t mr_rdata_fields[] = {
FIELD("newname")
};
static const rdata_info_t ptr_rdata_fields[] = {
FIELD("ptrdname")
};
static const rdata_info_t hinfo_rdata_fields[] = {
FIELD("cpu"),
FIELD("os")
};
static const rdata_info_t minfo_rdata_fields[] = {
FIELD("rmailbx"),
FIELD("emailbx")
};
static const rdata_info_t null_rdata_fields[] = {
FIELD("anything")
};
static const rdata_info_t wks_rdata_fields[] = {
FIELD("address"),
FIELD("protocol"),
FIELD("bitmap")
};
static const rdata_info_t mx_rdata_fields[] = {
FIELD("priority"),
FIELD("hostname")
};
static const rdata_info_t txt_rdata_fields[] = {
FIELD("text")
};
static const rdata_info_t rp_rdata_fields[] = {
FIELD("mailbox"),
FIELD("text")
};
static const rdata_info_t afsdb_rdata_fields[] = {
FIELD("subtype"),
FIELD("hostname")
};
static const rdata_info_t x25_rdata_fields[] = {
FIELD("address")
};
static const rdata_info_t isdn_rdata_fields[] = {
FIELD("address"),
FIELD("subaddress")
};
static const rdata_info_t rt_rdata_fields[] = {
FIELD("preference"),
FIELD("hostname")
};
static const rdata_info_t nsap_rdata_fields[] = {
FIELD("address")
};
static const rdata_info_t nsap_ptr_rdata_fields[] = {
FIELD("hostname")
};
static const rdata_info_t key_rdata_fields[] = {
FIELD("flags"),
FIELD("protocol"),
FIELD("algorithm"),
FIELD("publickey")
};
static const rdata_info_t px_rdata_fields[] = {
FIELD("preference"),
FIELD("map822"),
FIELD("mapx400")
};
static const rdata_info_t gpos_rdata_fields[] = {
FIELD("latitude"),
FIELD("longitude"),
FIELD("altitude")
};
static const rdata_info_t aaaa_rdata_fields[] = {
FIELD("address")
};
static const rdata_info_t loc_rdata_fields[] = {
FIELD("version"),
FIELD("size"),
FIELD("horizontal precision"),
FIELD("vertical precision"),
FIELD("latitude"),
FIELD("longitude"),
FIELD("altitude")
};
static const rdata_info_t nxt_rdata_fields[] = {
FIELD("next domain name"),
FIELD("type bit map")
};
static const rdata_info_t eid_rdata_fields[] = {
FIELD("end point identifier")
};
static const rdata_info_t nimloc_rdata_fields[] = {
FIELD("nimrod locator")
};
static const rdata_info_t srv_rdata_fields[] = {
FIELD("priority"),
FIELD("weight"),
FIELD("port"),
FIELD("target")
};
static const rdata_info_t atma_rdata_fields[] = {
FIELD("address")
};
static const rdata_info_t naptr_rdata_fields[] = {
FIELD("order"),
FIELD("preference"),
FIELD("flags"),
FIELD("services"),
FIELD("regex"),
FIELD("replacement"),
};
static const rdata_info_t kx_rdata_fields[] = {
FIELD("preference"),
FIELD("exchanger")
};
static const rdata_info_t sig_rdata_fields[] = {
FIELD("sigtype"),
FIELD("algorithm"),
FIELD("labels"),
FIELD("origttl"),
FIELD("expire"),
FIELD("inception"),
FIELD("keytag"),
FIELD("signer"),
FIELD("signature")
};
static const rdata_info_t cert_rdata_fields[] = {
FIELD("type"),
FIELD("key tag"),
FIELD("algorithm"),
FIELD("certificate")
};
static const rdata_info_t dname_rdata_fields[] = {
FIELD("source")
};
static const rdata_info_t sink_rdata_fields[] = {
FIELD("coding"),
FIELD("subcoding"),
FIELD("data")
};
static const rdata_info_t apl_rdata_fields[] = {
FIELD("prefix")
};
static const rdata_info_t ds_rdata_fields[] = {
FIELD("keytag"),
FIELD("algorithm"),
FIELD("digtype"),
FIELD("digest")
};
static const rdata_info_t sshfp_rdata_fields[] = {
FIELD("algorithm"),
FIELD("ftype"),
FIELD("fingerprint")
};
static const rdata_info_t ipseckey_rdata_fields[] = {
FIELD("precedence"),
FIELD("gateway type"),
FIELD("algorithm"),
FIELD("gateway"),
FIELD("public key")
};
static const rdata_info_t rrsig_rdata_fields[] = {
FIELD("rrtype"),
FIELD("algorithm"),
FIELD("labels"),
FIELD("origttl"),
FIELD("expire"),
FIELD("inception"),
FIELD("keytag"),
FIELD("signer"),
FIELD("signature")
};
static const rdata_info_t nsec_rdata_fields[] = {
FIELD("next"),
FIELD("types")
};
static const rdata_info_t dnskey_rdata_fields[] = {
FIELD("flags"),
FIELD("protocol"),
FIELD("algorithm"),
FIELD("publickey")
};
static const rdata_info_t dhcid_rdata_fields[] = {
FIELD("dhcpinfo")
};
static const rdata_info_t nsec3_rdata_fields[] = {
FIELD("algorithm"),
FIELD("flags"),
FIELD("iterations"),
FIELD("salt"),
FIELD("next"),
FIELD("types")
};
static const rdata_info_t nsec3param_rdata_fields[] = {
FIELD("algorithm"),
FIELD("flags"),
FIELD("iterations"),
FIELD("salt")
};
static const rdata_info_t tlsa_rdata_fields[] = {
FIELD("usage"),
FIELD("selector"),
FIELD("matching type"),
FIELD("certificate association data")
};
static const rdata_info_t smimea_rdata_fields[] = {
FIELD("usage"),
FIELD("selector"),
FIELD("matching type"),
FIELD("certificate association data")
};
static const rdata_info_t cds_rdata_fields[] = {
FIELD("keytag"),
FIELD("algorithm"),
FIELD("digtype"),
FIELD("digest")
};
static const rdata_info_t cdnskey_rdata_fields[] = {
FIELD("flags"),
FIELD("protocol"),
FIELD("algorithm"),
FIELD("publickey")
};
static const rdata_info_t hip_rdata_fields[] = {
FIELD("HIT length"),
FIELD("PK algorithm"),
FIELD("PK length"),
FIELD("HIT"),
FIELD("Public Key"),
FIELD("Rendezvous Servers")
};
static const rdata_info_t ninfo_rdata_fields[] = {
FIELD("text")
};
static const rdata_info_t rkey_rdata_fields[] = {
FIELD("flags"),
FIELD("protocol"),
FIELD("algorithm"),
FIELD("publickey")
};
static const rdata_info_t talink_rdata_fields[] = {
FIELD("start or previous"),
FIELD("end or next")
};
static const rdata_info_t openpgpkey_rdata_fields[] = {
FIELD("key")
};
static const rdata_info_t csync_rdata_fields[] = {
FIELD("serial"),
FIELD("flags"),
FIELD("types")
};
static const rdata_info_t zonemd_rdata_fields[] = {
FIELD("serial"),
FIELD("scheme"),
FIELD("algorithm"),
FIELD("digest"),
};
static const rdata_info_t svcb_rdata_fields[] = {
FIELD("priority"),
FIELD("target"),
FIELD("params")
};
static const rdata_info_t https_rdata_fields[] = {
FIELD("priority"),
FIELD("target"),
FIELD("params")
};
static const rdata_info_t dsync_rdata_fields[] = {
FIELD("rrtype"),
FIELD("scheme"),
FIELD("port"),
FIELD("target")
};
static const rdata_info_t spf_rdata_fields[] = {
FIELD("text")
};
static const rdata_info_t nid_rdata_fields[] = {
FIELD("preference"),
FIELD("nodeid")
};
static const rdata_info_t l32_rdata_fields[] = {
FIELD("preference"),
FIELD("locator")
};
static const rdata_info_t l64_rdata_fields[] = {
FIELD("preference"),
FIELD("locator")
};
static const rdata_info_t lp_rdata_fields[] = {
FIELD("preference"),
FIELD("pointer")
};
static const rdata_info_t eui48_rdata_fields[] = {
FIELD("address")
};
static const rdata_info_t eui64_rdata_fields[] = {
FIELD("address")
};
static const rdata_info_t uri_rdata_fields[] = {
FIELD("priority"),
FIELD("weight"),
FIELD("target")
};
static const rdata_info_t caa_rdata_fields[] = {
FIELD("flags"),
FIELD("tag"),
FIELD("value")
};
static const rdata_info_t avc_rdata_fields[] = {
FIELD("text")
};
static const rdata_info_t doa_rdata_fields[] = {
FIELD("enterprise"),
FIELD("type"),
FIELD("location"),
FIELD("media type"),
FIELD("data")
};
static const rdata_info_t amtrelay_rdata_fields[] = {
FIELD("precedence"),
FIELD("discovery optional"),
FIELD("type"),
FIELD("relay"),
};
static const rdata_info_t resinfo_rdata_fields[] = {
FIELD("text")
};
static const rdata_info_t wallet_rdata_fields[] = {
FIELD("text")
};
static const rdata_info_t cla_rdata_fields[] = {
FIELD("text")
};
static const rdata_info_t ipn_rdata_fields[] = {
FIELD("CBHE Node Number")
};
static const rdata_info_t ta_rdata_fields[] = {
FIELD("key"),
FIELD("algorithm"),
FIELD("type"),
FIELD("digest")
};
static const rdata_info_t dlv_rdata_fields[] = {
FIELD("key"),
FIELD("algorithm"),
FIELD("type"),
FIELD("digest")
};
static const type_info_t types[] = {
UNKNOWN_TYPE(0),
TYPE("A", ZONE_TYPE_A, ZONE_CLASS_ANY, FIELDS(a_rdata_fields),
check_a_rr, parse_a_rdata),
TYPE("NS", ZONE_TYPE_NS, ZONE_CLASS_ANY, FIELDS(ns_rdata_fields),
check_ns_rr, parse_ns_rdata),
TYPE("MD", ZONE_TYPE_MD, ZONE_CLASS_ANY, FIELDS(md_rdata_fields),
check_ns_rr, parse_ns_rdata),
TYPE("MF", ZONE_TYPE_MF, ZONE_CLASS_ANY, FIELDS(mf_rdata_fields),
check_ns_rr, parse_ns_rdata),
TYPE("CNAME", ZONE_TYPE_CNAME, ZONE_CLASS_ANY, FIELDS(cname_rdata_fields),
check_ns_rr, parse_ns_rdata),
TYPE("SOA", ZONE_TYPE_SOA, ZONE_CLASS_ANY, FIELDS(soa_rdata_fields),
check_soa_rr, parse_soa_rdata),
TYPE("MB", ZONE_TYPE_MB, ZONE_CLASS_ANY, FIELDS(mb_rdata_fields),
check_ns_rr, parse_ns_rdata),
TYPE("MG", ZONE_TYPE_MG, ZONE_CLASS_ANY, FIELDS(mg_rdata_fields),
check_ns_rr, parse_ns_rdata),
TYPE("MR", ZONE_TYPE_MR, ZONE_CLASS_ANY, FIELDS(mr_rdata_fields),
check_ns_rr, parse_ns_rdata),
TYPE("NULL", ZONE_TYPE_NULL, ZONE_CLASS_ANY, FIELDS(null_rdata_fields),
check_generic_rr, parse_unknown_rdata),
TYPE("WKS", ZONE_TYPE_WKS, ZONE_CLASS_IN, FIELDS(wks_rdata_fields),
check_wks_rr, parse_wks_rdata),
TYPE("PTR", ZONE_TYPE_PTR, ZONE_CLASS_ANY, FIELDS(ptr_rdata_fields),
check_ns_rr, parse_ns_rdata),
TYPE("HINFO", ZONE_TYPE_HINFO, ZONE_CLASS_ANY, FIELDS(hinfo_rdata_fields),
check_hinfo_rr, parse_hinfo_rdata),
TYPE("MINFO", ZONE_TYPE_MINFO, ZONE_CLASS_ANY, FIELDS(minfo_rdata_fields),
check_minfo_rr, parse_minfo_rdata),
TYPE("MX", ZONE_TYPE_MX, ZONE_CLASS_ANY, FIELDS(mx_rdata_fields),
check_mx_rr, parse_mx_rdata),
TYPE("TXT", ZONE_TYPE_TXT, ZONE_CLASS_ANY, FIELDS(txt_rdata_fields),
check_txt_rr, parse_txt_rdata),
TYPE("RP", ZONE_TYPE_RP, ZONE_CLASS_ANY, FIELDS(rp_rdata_fields),
check_minfo_rr, parse_minfo_rdata),
TYPE("AFSDB", ZONE_TYPE_AFSDB, ZONE_CLASS_ANY, FIELDS(afsdb_rdata_fields),
check_mx_rr, parse_mx_rdata),
TYPE("X25", ZONE_TYPE_X25, ZONE_CLASS_ANY, FIELDS(x25_rdata_fields),
check_x25_rr, parse_x25_rdata),
TYPE("ISDN", ZONE_TYPE_ISDN, ZONE_CLASS_ANY, FIELDS(isdn_rdata_fields),
check_isdn_rr, parse_isdn_rdata),
TYPE("RT", ZONE_TYPE_RT, ZONE_CLASS_ANY, FIELDS(rt_rdata_fields),
check_rt_rr, parse_rt_rdata),
TYPE("NSAP", ZONE_TYPE_NSAP, ZONE_CLASS_IN, FIELDS(nsap_rdata_fields),
check_nsap_rr, parse_nsap_rdata),
TYPE("NSAP-PTR", ZONE_TYPE_NSAP_PTR, ZONE_CLASS_IN, FIELDS(nsap_ptr_rdata_fields),
check_nsap_ptr_rr, parse_nsap_ptr_rdata),
TYPE("SIG", ZONE_TYPE_SIG, ZONE_CLASS_ANY, FIELDS(sig_rdata_fields),
check_rrsig_rr, parse_rrsig_rdata),
TYPE("KEY", ZONE_TYPE_KEY, ZONE_CLASS_ANY, FIELDS(key_rdata_fields),
check_key_rr, parse_key_rdata),
TYPE("PX", ZONE_TYPE_PX, ZONE_CLASS_IN, FIELDS(px_rdata_fields),
check_px_rr, parse_px_rdata),
TYPE("GPOS", ZONE_TYPE_GPOS, ZONE_CLASS_ANY, FIELDS(gpos_rdata_fields),
check_gpos_rr, parse_gpos_rdata),
TYPE("AAAA", ZONE_TYPE_AAAA, ZONE_CLASS_IN, FIELDS(aaaa_rdata_fields),
check_aaaa_rr, parse_aaaa_rdata),
TYPE("LOC", ZONE_TYPE_LOC, ZONE_CLASS_ANY, FIELDS(loc_rdata_fields),
check_loc_rr, parse_loc_rdata),
TYPE("NXT", ZONE_TYPE_NXT, ZONE_CLASS_ANY, FIELDS(nxt_rdata_fields),
check_nxt_rr, parse_nxt_rdata),
TYPE("EID", ZONE_TYPE_EID, ZONE_CLASS_IN, FIELDS(eid_rdata_fields),
check_eid_rr, parse_eid_rdata),
TYPE("NIMLOC", ZONE_TYPE_NIMLOC, ZONE_CLASS_IN, FIELDS(nimloc_rdata_fields),
check_eid_rr, parse_eid_rdata),
TYPE("SRV", ZONE_TYPE_SRV, ZONE_CLASS_IN, FIELDS(srv_rdata_fields),
check_srv_rr, parse_srv_rdata),
TYPE("ATMA", ZONE_TYPE_ATMA, ZONE_CLASS_IN, FIELDS(atma_rdata_fields),
check_atma_rr, parse_atma_rdata),
TYPE("NAPTR", ZONE_TYPE_NAPTR, ZONE_CLASS_IN, FIELDS(naptr_rdata_fields),
check_naptr_rr, parse_naptr_rdata),
TYPE("KX", ZONE_TYPE_KX, ZONE_CLASS_IN, FIELDS(kx_rdata_fields),
check_mx_rr, parse_mx_rdata),
TYPE("CERT", ZONE_TYPE_CERT, ZONE_CLASS_ANY, FIELDS(cert_rdata_fields),
check_cert_rr, parse_cert_rdata),
UNKNOWN_TYPE(38),
TYPE("DNAME", ZONE_TYPE_DNAME, ZONE_CLASS_ANY, FIELDS(dname_rdata_fields),
check_ns_rr, parse_ns_rdata),
TYPE("SINK", ZONE_TYPE_SINK, ZONE_CLASS_ANY, FIELDS(sink_rdata_fields),
check_sink_rr, parse_sink_rdata),
UNKNOWN_TYPE(41),
TYPE("APL", ZONE_TYPE_APL, ZONE_CLASS_IN, FIELDS(apl_rdata_fields),
check_apl_rr, parse_apl_rdata),
TYPE("DS", ZONE_TYPE_DS, ZONE_CLASS_ANY, FIELDS(ds_rdata_fields),
check_ds_rr, parse_ds_rdata),
TYPE("SSHFP", ZONE_TYPE_SSHFP, ZONE_CLASS_ANY, FIELDS(sshfp_rdata_fields),
check_sshfp_rr, parse_sshfp_rdata),
TYPE("IPSECKEY", ZONE_TYPE_IPSECKEY, ZONE_CLASS_IN, FIELDS(ipseckey_rdata_fields),
check_ipseckey_rr, parse_ipseckey_rdata),
TYPE("RRSIG", ZONE_TYPE_RRSIG, ZONE_CLASS_ANY, FIELDS(rrsig_rdata_fields),
check_rrsig_rr, parse_rrsig_rdata),
TYPE("NSEC", ZONE_TYPE_NSEC, ZONE_CLASS_ANY, FIELDS(nsec_rdata_fields),
check_nsec_rr, parse_nsec_rdata),
TYPE("DNSKEY", ZONE_TYPE_DNSKEY, ZONE_CLASS_ANY, FIELDS(dnskey_rdata_fields),
check_dnskey_rr, parse_dnskey_rdata),
TYPE("DHCID", ZONE_TYPE_DHCID, ZONE_CLASS_IN, FIELDS(dhcid_rdata_fields),
check_dhcid_rr, parse_dhcid_rdata),
TYPE("NSEC3", ZONE_TYPE_NSEC3, ZONE_CLASS_ANY, FIELDS(nsec3_rdata_fields),
check_nsec3_rr, parse_nsec3_rdata),
TYPE("NSEC3PARAM", ZONE_TYPE_NSEC3PARAM, ZONE_CLASS_ANY, FIELDS(nsec3param_rdata_fields),
check_nsec3param_rr, parse_nsec3param_rdata),
TYPE("TLSA", ZONE_TYPE_TLSA, ZONE_CLASS_ANY, FIELDS(tlsa_rdata_fields),
check_tlsa_rr, parse_tlsa_rdata),
TYPE("SMIMEA", ZONE_TYPE_SMIMEA, ZONE_CLASS_ANY, FIELDS(smimea_rdata_fields),
check_tlsa_rr, parse_tlsa_rdata),
UNKNOWN_TYPE(54),
TYPE("HIP", ZONE_TYPE_HIP, ZONE_CLASS_ANY, FIELDS(hip_rdata_fields),
check_hip_rr, parse_hip_rdata),
TYPE("NINFO", ZONE_TYPE_NINFO, ZONE_CLASS_ANY, FIELDS(ninfo_rdata_fields),
check_txt_rr, parse_txt_rdata),
TYPE("RKEY", ZONE_TYPE_RKEY, ZONE_CLASS_ANY, FIELDS(rkey_rdata_fields),
check_dnskey_rr, parse_dnskey_rdata),
TYPE("TALINK", ZONE_TYPE_TALINK, ZONE_CLASS_ANY, FIELDS(talink_rdata_fields),
check_minfo_rr, parse_minfo_rdata),
TYPE("CDS", ZONE_TYPE_CDS, ZONE_CLASS_ANY, FIELDS(cds_rdata_fields),
check_ds_rr, parse_ds_rdata),
TYPE("CDNSKEY", ZONE_TYPE_CDNSKEY, ZONE_CLASS_ANY, FIELDS(cdnskey_rdata_fields),
check_dnskey_rr, parse_dnskey_rdata),
TYPE("OPENPGPKEY", ZONE_TYPE_OPENPGPKEY, ZONE_CLASS_ANY, FIELDS(openpgpkey_rdata_fields),
check_openpgpkey_rr, parse_openpgpkey_rdata),
TYPE("CSYNC", ZONE_TYPE_CSYNC, ZONE_CLASS_ANY, FIELDS(csync_rdata_fields),
check_csync_rr, parse_csync_rdata),
TYPE("ZONEMD", ZONE_TYPE_ZONEMD, ZONE_CLASS_ANY, FIELDS(zonemd_rdata_fields),
check_zonemd_rr, parse_zonemd_rdata),
TYPE("SVCB", ZONE_TYPE_SVCB, ZONE_CLASS_IN, FIELDS(svcb_rdata_fields),
check_svcb_rr, parse_svcb_rdata),
TYPE("HTTPS", ZONE_TYPE_HTTPS, ZONE_CLASS_IN, FIELDS(https_rdata_fields),
check_https_rr, parse_https_rdata),
TYPE("DSYNC", ZONE_TYPE_DSYNC, ZONE_CLASS_ANY, FIELDS(dsync_rdata_fields),
check_dsync_rr, parse_dsync_rdata),
UNKNOWN_TYPE(67),
UNKNOWN_TYPE(68),
UNKNOWN_TYPE(69),
UNKNOWN_TYPE(70),
UNKNOWN_TYPE(71),
UNKNOWN_TYPE(72),
UNKNOWN_TYPE(73),
UNKNOWN_TYPE(74),
UNKNOWN_TYPE(75),
UNKNOWN_TYPE(76),
UNKNOWN_TYPE(77),
UNKNOWN_TYPE(78),
UNKNOWN_TYPE(79),
UNKNOWN_TYPE(80),
UNKNOWN_TYPE(81),
UNKNOWN_TYPE(82),
UNKNOWN_TYPE(83),
UNKNOWN_TYPE(84),
UNKNOWN_TYPE(85),
UNKNOWN_TYPE(86),
UNKNOWN_TYPE(87),
UNKNOWN_TYPE(88),
UNKNOWN_TYPE(89),
UNKNOWN_TYPE(90),
UNKNOWN_TYPE(91),
UNKNOWN_TYPE(92),
UNKNOWN_TYPE(93),
UNKNOWN_TYPE(94),
UNKNOWN_TYPE(95),
UNKNOWN_TYPE(96),
UNKNOWN_TYPE(97),
UNKNOWN_TYPE(98),
TYPE("SPF", ZONE_TYPE_SPF, ZONE_CLASS_ANY, FIELDS(spf_rdata_fields),
check_txt_rr, parse_txt_rdata),
UNKNOWN_TYPE(100),
UNKNOWN_TYPE(101),
UNKNOWN_TYPE(102),
UNKNOWN_TYPE(103),
TYPE("NID", ZONE_TYPE_NID, ZONE_CLASS_ANY, FIELDS(nid_rdata_fields),
check_nid_rr, parse_nid_rdata),
TYPE("L32", ZONE_TYPE_L32, ZONE_CLASS_ANY, FIELDS(l32_rdata_fields),
check_l32_rr, parse_l32_rdata),
TYPE("L64", ZONE_TYPE_L64, ZONE_CLASS_ANY, FIELDS(l64_rdata_fields),
check_l64_rr, parse_l64_rdata),
TYPE("LP", ZONE_TYPE_LP, ZONE_CLASS_ANY, FIELDS(lp_rdata_fields),
check_mx_rr, parse_mx_rdata),
TYPE("EUI48", ZONE_TYPE_EUI48, ZONE_CLASS_ANY, FIELDS(eui48_rdata_fields),
check_eui48_rr, parse_eui48_rdata),
TYPE("EUI64", ZONE_TYPE_EUI64, ZONE_CLASS_ANY, FIELDS(eui64_rdata_fields),
check_eui64_rr, parse_eui64_rdata),
UNKNOWN_TYPE(110),
UNKNOWN_TYPE(111),
UNKNOWN_TYPE(112),
UNKNOWN_TYPE(113),
UNKNOWN_TYPE(114),
UNKNOWN_TYPE(115),
UNKNOWN_TYPE(116),
UNKNOWN_TYPE(117),
UNKNOWN_TYPE(118),
UNKNOWN_TYPE(119),
UNKNOWN_TYPE(120),
UNKNOWN_TYPE(121),
UNKNOWN_TYPE(122),
UNKNOWN_TYPE(123),
UNKNOWN_TYPE(124),
UNKNOWN_TYPE(125),
UNKNOWN_TYPE(126),
UNKNOWN_TYPE(127),
UNKNOWN_TYPE(128),
UNKNOWN_TYPE(129),
UNKNOWN_TYPE(130),
UNKNOWN_TYPE(131),
UNKNOWN_TYPE(132),
UNKNOWN_TYPE(133),
UNKNOWN_TYPE(134),
UNKNOWN_TYPE(135),
UNKNOWN_TYPE(136),
UNKNOWN_TYPE(137),
UNKNOWN_TYPE(138),
UNKNOWN_TYPE(139),
UNKNOWN_TYPE(140),
UNKNOWN_TYPE(141),
UNKNOWN_TYPE(142),
UNKNOWN_TYPE(143),
UNKNOWN_TYPE(144),
UNKNOWN_TYPE(145),
UNKNOWN_TYPE(146),
UNKNOWN_TYPE(147),
UNKNOWN_TYPE(148),
UNKNOWN_TYPE(149),
UNKNOWN_TYPE(150),
UNKNOWN_TYPE(151),
UNKNOWN_TYPE(152),
UNKNOWN_TYPE(153),
UNKNOWN_TYPE(154),
UNKNOWN_TYPE(155),
UNKNOWN_TYPE(156),
UNKNOWN_TYPE(157),
UNKNOWN_TYPE(158),
UNKNOWN_TYPE(159),
UNKNOWN_TYPE(160),
UNKNOWN_TYPE(161),
UNKNOWN_TYPE(162),
UNKNOWN_TYPE(163),
UNKNOWN_TYPE(164),
UNKNOWN_TYPE(165),
UNKNOWN_TYPE(166),
UNKNOWN_TYPE(167),
UNKNOWN_TYPE(168),
UNKNOWN_TYPE(169),
UNKNOWN_TYPE(170),
UNKNOWN_TYPE(171),
UNKNOWN_TYPE(172),
UNKNOWN_TYPE(173),
UNKNOWN_TYPE(174),
UNKNOWN_TYPE(175),
UNKNOWN_TYPE(176),
UNKNOWN_TYPE(177),
UNKNOWN_TYPE(178),
UNKNOWN_TYPE(179),
UNKNOWN_TYPE(180),
UNKNOWN_TYPE(181),
UNKNOWN_TYPE(182),
UNKNOWN_TYPE(183),
UNKNOWN_TYPE(184),
UNKNOWN_TYPE(185),
UNKNOWN_TYPE(186),
UNKNOWN_TYPE(187),
UNKNOWN_TYPE(188),
UNKNOWN_TYPE(189),
UNKNOWN_TYPE(190),
UNKNOWN_TYPE(191),
UNKNOWN_TYPE(192),
UNKNOWN_TYPE(193),
UNKNOWN_TYPE(194),
UNKNOWN_TYPE(195),
UNKNOWN_TYPE(196),
UNKNOWN_TYPE(197),
UNKNOWN_TYPE(198),
UNKNOWN_TYPE(199),
UNKNOWN_TYPE(200),
UNKNOWN_TYPE(201),
UNKNOWN_TYPE(202),
UNKNOWN_TYPE(203),
UNKNOWN_TYPE(204),
UNKNOWN_TYPE(205),
UNKNOWN_TYPE(206),
UNKNOWN_TYPE(207),
UNKNOWN_TYPE(208),
UNKNOWN_TYPE(209),
UNKNOWN_TYPE(210),
UNKNOWN_TYPE(211),
UNKNOWN_TYPE(212),
UNKNOWN_TYPE(213),
UNKNOWN_TYPE(214),
UNKNOWN_TYPE(215),
UNKNOWN_TYPE(216),
UNKNOWN_TYPE(217),
UNKNOWN_TYPE(218),
UNKNOWN_TYPE(219),
UNKNOWN_TYPE(220),
UNKNOWN_TYPE(221),
UNKNOWN_TYPE(222),
UNKNOWN_TYPE(223),
UNKNOWN_TYPE(224),
UNKNOWN_TYPE(225),
UNKNOWN_TYPE(226),
UNKNOWN_TYPE(227),
UNKNOWN_TYPE(228),
UNKNOWN_TYPE(229),
UNKNOWN_TYPE(230),
UNKNOWN_TYPE(231),
UNKNOWN_TYPE(232),
UNKNOWN_TYPE(233),
UNKNOWN_TYPE(234),
UNKNOWN_TYPE(235),
UNKNOWN_TYPE(236),
UNKNOWN_TYPE(237),
UNKNOWN_TYPE(238),
UNKNOWN_TYPE(239),
UNKNOWN_TYPE(240),
UNKNOWN_TYPE(241),
UNKNOWN_TYPE(242),
UNKNOWN_TYPE(243),
UNKNOWN_TYPE(244),
UNKNOWN_TYPE(245),
UNKNOWN_TYPE(246),
UNKNOWN_TYPE(247),
UNKNOWN_TYPE(248),
UNKNOWN_TYPE(249),
UNKNOWN_TYPE(250),
UNKNOWN_TYPE(251),
UNKNOWN_TYPE(252),
UNKNOWN_TYPE(253),
UNKNOWN_TYPE(254),
UNKNOWN_TYPE(255),
TYPE("URI", ZONE_TYPE_URI, ZONE_CLASS_ANY, FIELDS(uri_rdata_fields),
check_uri_rr, parse_uri_rdata),
TYPE("CAA", ZONE_TYPE_CAA, ZONE_CLASS_ANY, FIELDS(caa_rdata_fields),
check_caa_rr, parse_caa_rdata),
TYPE("AVC", ZONE_TYPE_AVC, ZONE_CLASS_ANY, FIELDS(avc_rdata_fields),
check_txt_rr, parse_txt_rdata),
TYPE("DOA", ZONE_TYPE_DOA, ZONE_CLASS_ANY, FIELDS(doa_rdata_fields),
check_doa_rr, parse_doa_rdata),
TYPE("AMTRELAY", ZONE_TYPE_AMTRELAY, ZONE_CLASS_ANY, FIELDS(amtrelay_rdata_fields),
check_amtrelay_rr, parse_amtrelay_rdata),
TYPE("RESINFO", ZONE_TYPE_RESINFO, ZONE_CLASS_ANY, FIELDS(resinfo_rdata_fields),
check_txt_rr, parse_txt_rdata),
TYPE("WALLET", ZONE_TYPE_WALLET, ZONE_CLASS_ANY, FIELDS(wallet_rdata_fields),
check_txt_rr, parse_txt_rdata),
TYPE("CLA", ZONE_TYPE_CLA, ZONE_CLASS_ANY, FIELDS(cla_rdata_fields),
check_txt_rr, parse_txt_rdata),
TYPE("IPN", ZONE_TYPE_IPN, ZONE_CLASS_ANY, FIELDS(ipn_rdata_fields),
check_ipn_rr, parse_ipn_rdata),
UNKNOWN_TYPE(265),
UNKNOWN_TYPE(266),
UNKNOWN_TYPE(267),
UNKNOWN_TYPE(268),
UNKNOWN_TYPE(269),
TYPE("TA", ZONE_TYPE_TA, ZONE_CLASS_ANY, FIELDS(ta_rdata_fields),
check_ds_rr, parse_ds_rdata),
TYPE("DLV", ZONE_TYPE_DLV, ZONE_CLASS_ANY, FIELDS(dlv_rdata_fields),
check_ds_rr, parse_ds_rdata)
};
#undef UNKNOWN_CLASS
#undef CLASS
#undef UNKNOWN_TYPE
#undef TYPE
diagnostic_pop()
#endif