Skip to content

Commit

Permalink
IPN RR type
Browse files Browse the repository at this point in the history
  • Loading branch information
wtoorop committed Jan 21, 2025
1 parent 4892c59 commit 4265c17
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 9 deletions.
2 changes: 2 additions & 0 deletions include/zone.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ extern "C" {
#define ZONE_TYPE_WALLET (262u)
/** BP Convergence Layer Adapter */
#define ZONE_TYPE_CLA (263u)
/** BP Node Number */
#define ZONE_TYPE_IPN (264u)
/** DNSSEC Trust Authorities */
#define ZONE_TYPE_TA (32768u)
/** DNSSEC Lookaside Validation @rfc{4431} @obsolete */
Expand Down
5 changes: 3 additions & 2 deletions scripts/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ static const tuple_t types_and_classes[] = {
{ "RESINFO", 261, true },
{ "WALLET", 262, true },
{ "CLA", 263, true },
{ "IPN", 264, true },
{ "TA", 32768, true },
{ "DLV", 32769, true }
};
Expand Down Expand Up @@ -135,9 +136,9 @@ static void print_table(uint64_t magic)
for (size_t j=i+8; i < j; i++) {
uint16_t code;
switch(keys[i].code) {
case 32768: code = 265; // index of TA in types array in generic/types.h
case 32768: code = 270; // index of TA in types array in generic/types.h
break;
case 32769: code = 266; // index of DLV in types array in generic/types.h
case 32769: code = 271; // index of DLV in types array in generic/types.h
break;
default : code = keys[i].code;
break;
Expand Down
37 changes: 37 additions & 0 deletions src/generic/number.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,26 @@ static really_inline int32_t scan_int32(
return sum <= 4294967295u;
}

nonnull((1,3))
static really_inline int32_t scan_int64(
const char *data, size_t length, uint64_t *number)
{
uint64_t sum = (uint8_t)data[0] - '0';

if (sum > 9 || !length || length > 20)
return 0;

for (size_t count=1; count < length; count++) {
const uint8_t digit = (uint8_t)data[count] - '0';
sum = sum * 10 + digit;
if (digit > 9)
return 0;
}

*number = sum;
return 1; /* TODO: detect overflow */
}

nonnull_all
static really_inline int32_t parse_int8(
parser_t *parser,
Expand Down Expand Up @@ -118,4 +138,21 @@ static really_inline int32_t parse_int32(
return 0;
}

nonnull_all
static really_inline int64_t parse_int64(
parser_t *parser,
const type_info_t *type,
const rdata_info_t *field,
rdata_t *rdata,
const token_t *token)
{
uint64_t number;
if (!scan_int64(token->data, token->length, &number))
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type));
number = htobe64(number);
memcpy(rdata->octets, &number, 8);
rdata->octets += 8;
return 0;
}

#endif // NUMBER_H
4 changes: 2 additions & 2 deletions src/generic/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ static const struct {
V(0), V(0), T(55), V(0), T(28), V(0), V(0), V(0),
V(0), V(0), V(0), V(0), V(0), V(0), V(0), T(39),
T(35), V(0), V(0), T(5), T(29), T(262), V(0), V(0),
T(109), V(0), V(0), V(0), V(0), V(0), V(0), V(0),
T(109), V(0), T(264), V(0), V(0), V(0), V(0), V(0),
V(0), T(21), V(0), V(0), V(0), V(0), V(0), V(0),
T(37), C(1), T(58), V(0), V(0), V(0), V(0), V(0),
V(0), V(0), V(0), C(3), V(0), T(52), T(11), T(20),
Expand All @@ -43,7 +43,7 @@ static const struct {
V(0), T(259), T(59), V(0), V(0), V(0), T(42), T(36),
T(8), T(15), V(0), T(26), T(27), T(6), V(0), T(99),
V(0), V(0), V(0), V(0), V(0), V(0), V(0), T(53),
T(9), T(63), T(33), V(0), T(266), T(265), V(0), T(40),
T(9), T(63), T(33), V(0), T(271), T(270), V(0), T(40),
V(0), V(0), T(24), T(19), V(0), V(0), V(0), V(0),
V(0), V(0), V(0), T(108), V(0), V(0), V(0), T(62),
V(0), V(0), V(0), V(0), V(0), T(66), T(4), V(0),
Expand Down
75 changes: 72 additions & 3 deletions src/generic/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ static really_inline int32_t check_bytes(

#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)
Expand Down Expand Up @@ -2780,6 +2782,61 @@ static int32_t parse_amtrelay_rdata(
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;

/* draft-johnson-dns-ipn-cla-07 Section 3.1. IPN:
* Presentation format for these resource records are either a 64 bit
* unsigned decimal integer, or two 32 bit unsigned decimal integers
* delimited by a period with the most significant 32 bits first and least
* significant 32 bits last.
*/
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 = 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)
Expand Down Expand Up @@ -3306,6 +3363,12 @@ static const rdata_info_t cla_rdata_fields[] = {
FIELD("text")
};

// https://www.iana.org/assignments/dns-parameters/IPN/ipn-completed-template
// and https://datatracker.ietf.org/doc/draft-johnson-dns-ipn-cla/07/
static const rdata_info_t ipn_rdata_fields[] = {
FIELD("CBHE Node Number")
};

static const rdata_info_t ta_rdata_fields[] = {
FIELD("key"),
FIELD("algorithm"),
Expand Down Expand Up @@ -3676,13 +3739,19 @@ static const type_info_t types[] = {
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(264),
UNKNOWN_TYPE(265),
UNKNOWN_TYPE(266),
UNKNOWN_TYPE(267),
UNKNOWN_TYPE(268),
UNKNOWN_TYPE(269),

/* Map 32768 in hash.c to 265 */
/* Map 32768 in hash.c to 270 */
TYPE("TA", ZONE_TYPE_TA, ZONE_CLASS_ANY, FIELDS(ta_rdata_fields), // obsolete
check_ds_rr, parse_ds_rdata),
/* Map 32769 in hash.c to 266 */
/* Map 32769 in hash.c to 271 */
TYPE("DLV", ZONE_TYPE_DLV, ZONE_CLASS_ANY, FIELDS(dlv_rdata_fields), // obsolete
check_ds_rr, parse_ds_rdata)
};
Expand Down
4 changes: 2 additions & 2 deletions src/westmere/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ static const struct {
V(0), V(0), T(55), V(0), T(28), V(0), V(0), V(0),
V(0), V(0), V(0), V(0), V(0), V(0), V(0), T(39),
T(35), V(0), V(0), T(5), T(29), T(262), V(0), V(0),
T(109), V(0), V(0), V(0), V(0), V(0), V(0), V(0),
T(109), V(0), T(264), V(0), V(0), V(0), V(0), V(0),
V(0), T(21), V(0), V(0), V(0), V(0), V(0), V(0),
T(37), C(1), T(58), V(0), V(0), V(0), V(0), V(0),
V(0), V(0), V(0), C(3), V(0), T(52), T(11), T(20),
Expand All @@ -43,7 +43,7 @@ static const struct {
V(0), T(259), T(59), V(0), V(0), V(0), T(42), T(36),
T(8), T(15), V(0), T(26), T(27), T(6), V(0), T(99),
V(0), V(0), V(0), V(0), V(0), V(0), V(0), T(53),
T(9), T(63), T(33), V(0), T(266), T(265), V(0), T(40),
T(9), T(63), T(33), V(0), T(271), T(270), V(0), T(40),
V(0), V(0), T(24), T(19), V(0), V(0), V(0), V(0),
V(0), V(0), V(0), T(108), V(0), V(0), V(0), T(62),
V(0), V(0), V(0), V(0), V(0), T(66), T(4), V(0),
Expand Down
21 changes: 21 additions & 0 deletions tests/types.c
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,24 @@ static const rdata_t amtrelay3_rdata =
, 3, 'c', 'o', 'm'
, 0);

static const char ipn_text[] =
PAD("foo. IPN 100");
static const rdata_t ipn_rdata =
RDATA( 0, 0, 0, 0
, 0, 0, 0, 100);

static const char ipn2_text[] =
PAD("foo. IPN 429496729700");
static const rdata_t ipn2_rdata =
RDATA( 0, 0, 0, 100
, 0, 0, 0, 100);

static const char ipn3_text[] =
PAD("foo. IPN 100.100");
static const rdata_t ipn3_rdata =
RDATA( 0, 0, 0, 100
, 0, 0, 0, 100);

static const char dlv_text[] =
PAD("foo. DLV 58470 5 1 ( 3079F1593EBAD6DC121E202A8B766A6A4837206C )");
static const char dlv_generic_text[] =
Expand Down Expand Up @@ -1167,6 +1185,9 @@ static const test_t tests[] = {
{ ZONE_TYPE_AMTRELAY, amtrelay2_generic_text, &amtrelay2_rdata },
{ ZONE_TYPE_AMTRELAY, amtrelay3_text, &amtrelay3_rdata },
{ ZONE_TYPE_AMTRELAY, amtrelay3_generic_text, &amtrelay3_rdata },
{ ZONE_TYPE_IPN, ipn_text, &ipn_rdata },
{ ZONE_TYPE_IPN, ipn2_text, &ipn2_rdata },
{ ZONE_TYPE_IPN, ipn3_text, &ipn3_rdata },
{ ZONE_TYPE_DLV, dlv_text, &cds_rdata },
{ ZONE_TYPE_DLV, dlv_generic_text, &cds_rdata }
};
Expand Down

0 comments on commit 4265c17

Please sign in to comment.