Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
158 changes: 158 additions & 0 deletions src/fallback/base16.h
Original file line number Diff line number Diff line change
@@ -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
111 changes: 111 additions & 0 deletions src/fallback/eui.h
Original file line number Diff line number Diff line change
@@ -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
3 changes: 2 additions & 1 deletion src/fallback/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
46 changes: 0 additions & 46 deletions src/generic/base16.c

This file was deleted.

Loading