diff --git a/CMakeLists.txt b/CMakeLists.txt index ed7df06..e472934 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,7 +138,6 @@ target_sources(zone PRIVATE src/log.c src/parser.c src/fallback/parser.c - src/generic/base16.c src/generic/base64.c) add_executable(zone-bench src/bench.c src/fallback/bench.c) diff --git a/src/fallback/base16.h b/src/fallback/base16.h new file mode 100644 index 0000000..4381904 --- /dev/null +++ b/src/fallback/base16.h @@ -0,0 +1,158 @@ +/* + * base16.h -- some useful comment + * + * Copyright (c) 2022, NLnet Labs. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ +#ifndef BASE16_H +#define BASE16_H + +// hexadecimal characters decode to 0x00 - 0x0f +// delimiting characters decode to 0x80 +// non-delimiters, non-hexadecimal characters decode to 0x90 + +// eui48 and eui64 depend on this table too +static const uint8_t b16rmap[256] = { + // end-of-file (0x00) + 0x80, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0x00 - 0x07 + // tab (0x09), line feed (0x0a), carriage return (0x0d) + 0x90, 0x80, 0x80, 0x90, 0x90, 0x80, 0x90, 0x90, // 0x08 - 0x0f + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0x10 - 0x17 + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0x18 - 0x1f + // space (0x20), quote (0x22) + 0x80, 0x90, 0x80, 0x90, 0x90, 0x90, 0x90, 0x90, // 0x20 - 0x27 + // left paren (0x28), right paren (0x29) + 0x80, 0x80, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0x28 - 0x2f + // digits + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 0x30 - 0x37 + // semicolon (0x3b) + 0x08, 0x09, 0x90, 0x80, 0x90, 0x90, 0x90, 0x90, // 0x38 - 0x3f + // upper case + 0x90, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x90, // 0x40 - 0x47 + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0x48 - 0x4f + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0x50 - 0x57 + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0x58 - 0x5f + // lower case + 0x90, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x90, // 0x60 - 0x67 + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0x68 - 0x6f + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0x70 - 0x77 + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0x78 - 0x7f + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0x80 - 0x87 + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0x88 - 0x8f + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0x90 - 0x97 + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0x98 - 0x9f + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0xa0 - 0xa7 + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0xa8 - 0xaf + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0xb0 - 0xb7 + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0xb8 - 0xbf + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0xc0 - 0xc7 + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0xc8 - 0xcf + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0xd0 - 0xd7 + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0xd8 - 0xdf + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0xe0 - 0xe7 + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0xe8 - 0xef + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0xf0 - 0xf7 + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 0xf8 - 0xff +}; + +// FIXME: RFC3597 section 5 states each word of data must contain an even +// number of hexadecimal digits. The same is not true for DS records. +// RFC4043 section 5.3 merely states whitespace is allowed within the +// hexadecimal text. Words containing an uneven number of hexadecimal +// digits are impractical, but supported (BIND supports uneven +// sequences) +zone_nonnull_all +static zone_really_inline int32_t parse_base16( + zone_parser_t *parser, + const zone_type_info_t *type, + const zone_field_info_t *field, + token_t *token) +{ + int32_t r; + + if ((r = have_contiguous(parser, type, field, token)) < 0) + return r; + + uint8_t x0 = 0x80, x1 = 0x80; + uint8_t *w = &parser->rdata->octets[parser->rdata->length]; + const uint8_t *ws = w, *we = &parser->rdata->octets[ZONE_RDATA_LIMIT]; + const char *p; + + do { + p = token->data; + if (zone_unlikely(!(x0 & 0x80))) { + x1 = b16rmap[(uint8_t)p[0]]; + if (x1 & 0x80) + SYNTAX_ERROR(parser, "Invalid %s in %s record", NAME(field), TNAME(type)); + w[0] = (uint8_t)((x0 << 4) | x1); + w += 1; p += 1; + } + + while (w < we) { + x0 = b16rmap[ (uint8_t)(p[0]) ]; + x1 = b16rmap[ (uint8_t)(p[1]) ]; + if ((x0 | x1) & 0x80) + break; + w[0] = (uint8_t)((x0 << 4) | x1); + w += 1; p += 2; + } + + if (x0 == 0x90 || (x0 != 0x80 && x1 != 0x80)) + SYNTAX_ERROR(parser, "Invalid %s in %s record", NAME(field), TNAME(type)); + + lex(parser, token); + } while (token->code == CONTIGUOUS && w < we); + + if (w - ws == 1 || w >= we || x0 != 0x80) + SYNTAX_ERROR(parser, "Invalid %s in %s record", NAME(field), TNAME(type)); + + if ((r = have_delimiter(parser, type, token)) < 0) + return r; + + parser->rdata->length += (size_t)(w - ws); + return ZONE_BLOB; +} + +zone_nonnull_all +static zone_really_inline int32_t parse_salt( + zone_parser_t *parser, + const zone_type_info_t *type, + const zone_field_info_t *field, + const token_t *token) +{ + int32_t r; + + if ((r = have_contiguous(parser, type, field, token)) < 0) + return r; + + const char *p = token->data; + + if (p[0] == '-' && !is_contiguous((uint8_t)p[1])) { + parser->rdata->octets[parser->rdata->length++] = 0; + return ZONE_STRING; + } + + uint8_t x0 = 0x80, x1 = 0x80; + uint8_t *ws = &parser->rdata->octets[parser->rdata->length], *w = ws + 1; + const uint8_t *we = w + 255; + + while (w < we) { + x0 = b16rmap[ (uint8_t)(p[0]) ]; + x1 = b16rmap[ (uint8_t)(p[1]) ]; + if ((x0 | x1) & 0x80) + break; + w[0] = (uint8_t)((x0 << 4) | x1); + w += 1; p += 2; + } + + if (w - ws == 1 || w >= we || x0 != 0x80) + SYNTAX_ERROR(parser, "Invalid %s in %s record", NAME(field), TNAME(type)); + + *ws = (uint8_t)((w - ws) - 1); + parser->rdata->length += (size_t)(w - ws); + return ZONE_STRING; +} + +#endif // BASE16_H diff --git a/src/fallback/eui.h b/src/fallback/eui.h new file mode 100644 index 0000000..97881a8 --- /dev/null +++ b/src/fallback/eui.h @@ -0,0 +1,111 @@ +/* + * eui48.h -- some useful comment + * + * Copyright (c) 2023, NLnet Labs. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ +#ifndef EUI_H +#define EUI_H + +// RFC7043 section 3.2: xx-xx-xx-xx-xx-xx +zone_nonnull_all +static zone_really_inline int32_t parse_eui48( + zone_parser_t *parser, + const zone_type_info_t *type, + const zone_field_info_t *field, + const token_t *token) +{ + uint8_t c, x[12]; + uint8_t *w = parser->rdata->octets + parser->rdata->length; + const uint8_t *p = (uint8_t *)token->data; + + c = (p[ 2] == '-') & (p[ 5] == '-') & + (p[ 8] == '-') & (p[11] == '-') & + (p[14] == '-'); + if (!c) + SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type)); + + x[ 0] = b16rmap[p[ 0]]; + x[ 1] = b16rmap[p[ 1]]; + x[ 2] = b16rmap[p[ 3]]; + x[ 3] = b16rmap[p[ 4]]; + x[ 4] = b16rmap[p[ 6]]; + x[ 5] = b16rmap[p[ 7]]; + x[ 6] = b16rmap[p[ 9]]; + x[ 7] = b16rmap[p[10]]; + x[ 8] = b16rmap[p[12]]; + x[ 9] = b16rmap[p[13]]; + x[10] = b16rmap[p[15]]; + x[11] = b16rmap[p[16]]; + + c = x[ 0] | x[ 1] | x[ 2] | x[ 3] | x[ 4] | x[ 5] | + x[ 6] | x[ 7] | x[ 8] | x[ 9] | x[10] | x[11]; + if (c & 0x80) + SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type)); + + w[0] = (uint8_t)((x[ 0] << 4) | x[ 1]); + w[1] = (uint8_t)((x[ 2] << 4) | x[ 3]); + w[2] = (uint8_t)((x[ 4] << 4) | x[ 5]); + w[3] = (uint8_t)((x[ 6] << 4) | x[ 7]); + w[4] = (uint8_t)((x[ 8] << 4) | x[ 9]); + w[5] = (uint8_t)((x[10] << 4) | x[11]); + + parser->rdata->length += 6; + return ZONE_EUI48; +} + +// RFC7043 section 4.2, require xx-xx-xx-xx-xx-xx-xx-xx +zone_nonnull_all +static zone_really_inline int32_t parse_eui64( + zone_parser_t *parser, + const zone_type_info_t *type, + const zone_field_info_t *field, + const token_t *token) +{ + uint8_t c, x[16]; + uint8_t *w = parser->rdata->octets + parser->rdata->length; + const uint8_t *p = (uint8_t *)token->data; + + c = (p[ 2] == '-') & (p[ 5] == '-') & (p[ 8] == '-') & (p[11] == '-') & + (p[14] == '-') & (p[17] == '-') & (p[20] == '-'); + if (!c) + SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type)); + + x[ 0] = b16rmap[p[ 0]]; + x[ 1] = b16rmap[p[ 1]]; + x[ 2] = b16rmap[p[ 3]]; + x[ 3] = b16rmap[p[ 4]]; + x[ 4] = b16rmap[p[ 6]]; + x[ 5] = b16rmap[p[ 7]]; + x[ 6] = b16rmap[p[ 9]]; + x[ 7] = b16rmap[p[10]]; + x[ 8] = b16rmap[p[12]]; + x[ 9] = b16rmap[p[13]]; + x[10] = b16rmap[p[15]]; + x[11] = b16rmap[p[16]]; + x[12] = b16rmap[p[18]]; + x[13] = b16rmap[p[19]]; + x[14] = b16rmap[p[21]]; + x[15] = b16rmap[p[22]]; + + c = x[ 0] | x[ 1] | x[ 2] | x[ 3] | x[ 4] | x[ 5] | x[ 6] | x[ 7] | + x[ 8] | x[ 9] | x[10] | x[11] | x[12] | x[13] | x[14] | x[15]; + if (c & 0x80) + SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type)); + + w[0] = (uint8_t)((x[ 0] << 4) | x[ 1]); + w[1] = (uint8_t)((x[ 2] << 4) | x[ 3]); + w[2] = (uint8_t)((x[ 4] << 4) | x[ 5]); + w[3] = (uint8_t)((x[ 6] << 4) | x[ 7]); + w[4] = (uint8_t)((x[ 8] << 4) | x[ 9]); + w[5] = (uint8_t)((x[10] << 4) | x[11]); + w[6] = (uint8_t)((x[12] << 4) | x[13]); + w[7] = (uint8_t)((x[14] << 4) | x[15]); + + parser->rdata->length += 8; + return ZONE_EUI64; +} + +#endif // EUI_H diff --git a/src/fallback/parser.c b/src/fallback/parser.c index 5241e3b..facc03e 100644 --- a/src/fallback/parser.c +++ b/src/fallback/parser.c @@ -19,12 +19,13 @@ #include "fallback/ip4.h" #include "generic/ip6.h" #include "fallback/text.h" -#include "generic/base16.h" +#include "fallback/base16.h" #include "fallback/base32.h" #include "generic/base64.h" #include "generic/nsec.h" #include "generic/caa.h" #include "generic/ilnp64.h" +#include "fallback/eui.h" #include "visit.h" #include "types.h" #include "fallback/type.h" diff --git a/src/generic/base16.c b/src/generic/base16.c deleted file mode 100644 index 702b48d..0000000 --- a/src/generic/base16.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * generic/base16.c -- some useful comment - * - * Copyright (c) 2022-2023, NLnet Labs. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - * - */ -#include - -static const uint8_t b16rmap[256] = { - 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0 - 7 */ - 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, /* 8 - 15 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 - 23 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 24 - 31 */ - 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 32 - 39 */ - 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, /* 40 - 47 */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 48 - 55 */ - 0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 56 - 63 */ - 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, /* 64 - 71 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 72 - 79 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 80 - 87 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 88 - 95 */ - 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, /* 96 - 103 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 104 - 111 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 112 - 119 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 120 - 127 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 128 - 135 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 136 - 143 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 144 - 151 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 152 - 159 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 160 - 167 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 168 - 175 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 176 - 183 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 184 - 191 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 192 - 199 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 200 - 207 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 208 - 215 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 216 - 223 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 224 - 231 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 232 - 239 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 240 - 247 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 248 - 255 */ -}; - -const uint8_t *zone_b16rmap = b16rmap; diff --git a/src/generic/base16.h b/src/generic/base16.h deleted file mode 100644 index 51f8476..0000000 --- a/src/generic/base16.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * base16.h -- some useful comment - * - * Copyright (c) 2022, NLnet Labs. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - * - */ -#ifndef BASE16_H -#define BASE16_H - -extern const uint8_t *zone_b16rmap; - -static const uint8_t b16rmap_special = 0xf0; -static const uint8_t b16rmap_end = 0xfd; -static const uint8_t b16rmap_space = 0xfe; - -zone_nonnull_all -static zone_really_inline int32_t parse_base16( - zone_parser_t *parser, - const zone_type_info_t *type, - const zone_field_info_t *field, - token_t *token) -{ - int32_t r; - uint32_t state = 0; - - if ((r = have_contiguous(parser, type, field, token)) < 0) - return r; - - do { - const char *p = token->data; - for (;; p++) { - const uint8_t ofs = zone_b16rmap[(uint8_t)*p]; - - if (ofs >= b16rmap_special) - break; - - if (state == 0) - parser->rdata->octets[parser->rdata->length] = (uint8_t)(ofs << 4); - else - parser->rdata->octets[parser->rdata->length++] |= ofs; - - state = !state; - } - - if (is_contiguous((uint8_t)*p)) - SYNTAX_ERROR(parser, "Invalid %s in %s record", NAME(field), TNAME(type)); - lex(parser, token); - } while (token->code == CONTIGUOUS); - - if (state != 0) - SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type)); - if ((r = have_delimiter(parser, type, token)) < 0) - return r; - - return ZONE_BLOB; -} - -zone_nonnull_all -static zone_really_inline int32_t parse_salt( - zone_parser_t *parser, - const zone_type_info_t *type, - const zone_field_info_t *field, - token_t *token) -{ - int32_t r; - uint32_t state = 0; - - if ((r = have_contiguous(parser, type, field, token)) < 0) - return r; - - const char *p = token->data; - - if (*p == '-' && contiguous[ (uint8_t)*(p+1) ] != CONTIGUOUS) { - parser->rdata->octets[parser->rdata->length++] = 0; - return ZONE_STRING; - } - - size_t rdlength = parser->rdata->length++; - - for (;; p++) { - const uint8_t ofs = zone_b16rmap[(uint8_t)*p]; - - if (ofs >= b16rmap_special) - break; - - if (state == 0) - parser->rdata->octets[parser->rdata->length] = (uint8_t)(ofs << 4); - else - parser->rdata->octets[parser->rdata->length++] |= ofs; - - state = !state; - } - - if (p == token->data || contiguous[ (uint8_t)*p ] == CONTIGUOUS) - SYNTAX_ERROR(parser, "Invalid %s in %s record", NAME(field), TNAME(type)); - if (state != 0) - SYNTAX_ERROR(parser, "Invalid %s in %s record", NAME(field), TNAME(type)); - - parser->rdata->octets[rdlength] = (uint8_t)(parser->rdata->length - rdlength); - return ZONE_STRING; -} - -#endif // BASE16_H diff --git a/src/haswell/parser.c b/src/haswell/parser.c index c41ce5a..327dc9b 100644 --- a/src/haswell/parser.c +++ b/src/haswell/parser.c @@ -23,12 +23,13 @@ #include "westmere/ip4.h" #include "generic/ip6.h" #include "generic/text.h" -#include "generic/base16.h" +#include "fallback/base16.h" #include "haswell/base32.h" #include "generic/base64.h" #include "generic/nsec.h" #include "generic/caa.h" #include "generic/ilnp64.h" +#include "fallback/eui.h" #include "visit.h" #include "types.h" #include "westmere/type.h" diff --git a/src/parser.c b/src/parser.c index 5becf00..3391285 100644 --- a/src/parser.c +++ b/src/parser.c @@ -690,6 +690,24 @@ int32_t zone_check_l64_rdata( return accept_rr(parser); } +zone_nonnull_all +int32_t zone_check_eui48_rdata( + zone_parser_t *parser, const zone_type_info_t *type) +{ + if (parser->rdata->length != 6) + SYNTAX_ERROR(parser, "Invalid %s", TNAME(type)); + return accept_rr(parser); +} + +zone_nonnull_all +int32_t zone_check_eui64_rdata( + zone_parser_t *parser, const zone_type_info_t *type) +{ + if (parser->rdata->length != 8) + SYNTAX_ERROR(parser, "Invalid %s", TNAME(type)); + return accept_rr(parser); +} + zone_nonnull_all int32_t zone_check_uri_rdata( zone_parser_t *parser, const zone_type_info_t *type) diff --git a/src/types.h b/src/types.h index cecc7a7..abeea0d 100644 --- a/src/types.h +++ b/src/types.h @@ -624,6 +624,44 @@ static int32_t parse_l64_rdata( return accept_rr(parser); } +zone_nonnull_all +extern int32_t zone_check_eui48_rdata( + zone_parser_t *parser, const zone_type_info_t *type); + +zone_nonnull_all +static int32_t parse_eui48_rdata( + zone_parser_t *parser, const zone_type_info_t *type, token_t *token) +{ + int32_t r; + + if ((r = parse_eui48(parser, type, &type->rdata.fields[0], token)) < 0) + return r; + lex(parser, token); + if ((r = have_delimiter(parser, type, token)) < 0) + return r; + + return accept_rr(parser); +} + +zone_nonnull_all +extern int32_t zone_check_eui64_rdata( + zone_parser_t *parser, const zone_type_info_t *type); + +zone_nonnull_all +static int32_t parse_eui64_rdata( + zone_parser_t *parser, const zone_type_info_t *type, token_t *token) +{ + int32_t r; + + if ((r = parse_eui64(parser, type, &type->rdata.fields[0], token)) < 0) + return r; + lex(parser, token); + if ((r = have_delimiter(parser, type, token)) < 0) + return r; + + return accept_rr(parser); +} + zone_nonnull_all extern int32_t zone_check_uri_rdata( zone_parser_t *parser, const zone_type_info_t *type); @@ -1043,6 +1081,14 @@ static const zone_field_info_t lp_rdata_fields[] = { FIELD("pointer", ZONE_NAME, 0) }; +static const zone_field_info_t eui48_rdata_fields[] = { + FIELD("address", ZONE_EUI48, 0) +}; + +static const zone_field_info_t eui64_rdata_fields[] = { + FIELD("address", ZONE_EUI64, 0) +}; + static const zone_field_info_t uri_rdata_fields[] = { FIELD("priority", ZONE_INT16, 0), FIELD("weight", ZONE_INT16, 0), @@ -1238,9 +1284,11 @@ static const type_descriptor_t types[] = { zone_check_l64_rdata, parse_l64_rdata), TYPE("LP", ZONE_LP, ZONE_ANY, FIELDS(lp_rdata_fields), zone_check_mx_rdata, parse_mx_rdata), + TYPE("EUI48", ZONE_EUI48, ZONE_ANY, FIELDS(eui48_rdata_fields), + zone_check_eui48_rdata, parse_eui48_rdata), + TYPE("EUI64", ZONE_EUI64, ZONE_ANY, FIELDS(eui64_rdata_fields), + zone_check_eui64_rdata, parse_eui64_rdata), - UNKNOWN_TYPE(108), - UNKNOWN_TYPE(109), UNKNOWN_TYPE(110), UNKNOWN_TYPE(111), UNKNOWN_TYPE(112), diff --git a/src/westmere/parser.c b/src/westmere/parser.c index 9e221d1..2d33255 100644 --- a/src/westmere/parser.c +++ b/src/westmere/parser.c @@ -23,12 +23,13 @@ #include "westmere/ip4.h" #include "generic/ip6.h" #include "generic/text.h" -#include "generic/base16.h" +#include "fallback/base16.h" #include "westmere/base32.h" #include "generic/base64.h" #include "generic/nsec.h" #include "generic/caa.h" #include "generic/ilnp64.h" +#include "fallback/eui.h" #include "visit.h" #include "types.h" #include "westmere/type.h" diff --git a/tests/types.c b/tests/types.c index 3ad45db..7dfd483 100644 --- a/tests/types.c +++ b/tests/types.c @@ -387,6 +387,20 @@ static const char lp_generic_text[] = static const rdata_t lp_rdata = RDATA(0x00, 0x0a, 11, 'l', '6', '4', '-', 's', 'u', 'b', 'n', 'e', 't', '1', EXAMPLE_COM); +static const char eui48_text[] = + PAD(" EUI48 00-00-5e-00-53-2a"); +static const char eui48_generic_text[] = + PAD(" EUI48 \\# 6 00005e00532a"); +static const rdata_t eui48_rdata = + RDATA(0x00, 0x00, 0x5e, 0x00, 0x53, 0x2a); + +static const char eui64_text[] = + PAD(" EUI64 00-00-5e-ef-10-00-00-2a"); +static const char eui64_generic_text[] = + PAD(" EUI64 \\# 8 00005eef1000002a"); +static const rdata_t eui64_rdata = + RDATA(0x00, 0x00, 0x5e, 0xef, 0x10, 0x00, 0x00, 0x2a); + static const char uri_text[] = PAD(" URI 10 1 \"ftp://ftp1.example.com/public\""); static const char uri_generic_text[] = @@ -496,6 +510,10 @@ static const test_t tests[] = { { ZONE_L64, l64_generic_text, &l64_rdata }, { ZONE_LP, lp_text, &lp_rdata }, { ZONE_LP, lp_generic_text, &lp_rdata }, + { ZONE_EUI48, eui48_text, &eui48_rdata }, + { ZONE_EUI48, eui48_generic_text, &eui48_rdata }, + { ZONE_EUI64, eui64_text, &eui64_rdata }, + { ZONE_EUI64, eui64_generic_text, &eui64_rdata }, { ZONE_URI, uri_text, &uri_rdata }, { ZONE_URI, uri_generic_text, &uri_rdata }, { ZONE_CAA, caa_text, &caa_rdata },