Skip to content

Commit

Permalink
Better handle group refs to somewhere in the middle of the tree
Browse files Browse the repository at this point in the history
  • Loading branch information
alandekok committed Dec 5, 2024
1 parent c9790ae commit 9200a8f
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 58 deletions.
6 changes: 5 additions & 1 deletion doc/antora/modules/reference/pages/type/all_types.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ missing, then the relevant field is filled with zeros.

group: A `group` contains an arbitrary collection of children, in any order.
+
A `group` is really a reference to some other attribute elsewhere in
the same protocol dictionary, or to a different protocol dictionary.
The `group` allows for dictionaries to contain cross-references.
+
The `group` can contain any child attributes, so long as they are
within the same protocol namespace. See the
dictionary/attribute.adoc[ATTRIBUTE] documentation for more
Expand All @@ -86,7 +90,7 @@ information.
The `group` only encodes the child attributes which have been created
and stored within the `group`. The order of children does not matter.

tlv:: A `tlv` is a `group` which has a limited subset of children.
tlv:: A `tlv` defines a hierarchy of children, which can only be contained in the `tlv`.
+
The `tlv` can only contain child attributes which have been defined as
children of the `tlv.`
Expand Down
25 changes: 13 additions & 12 deletions src/lib/util/pair_print.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/

/*
* Groups are printed from the referenced attribute.
*/
#define fr_pair_reset_parent(parent) do { \
if (parent && (parent->type == FR_TYPE_GROUP)) { \
parent = fr_dict_attr_ref(parent); \
if (parent->flags.is_root) parent = NULL; \
} \
} while (0)

/** Pair serialisation API
*
* @file src/lib/util/pair_print.c
Expand Down Expand Up @@ -114,10 +124,7 @@ ssize_t fr_pair_print(fr_sbuff_t *out, fr_dict_attr_t const *parent, fr_pair_t c
token = "<INVALID-TOKEN>";
}

/*
* Groups are printed from the root.
*/
if (parent && (parent->type == FR_TYPE_GROUP)) parent = NULL;
fr_pair_reset_parent(parent);

if (vp->vp_raw) FR_SBUFF_IN_STRCPY_LITERAL_RETURN(&our_out, "raw.");
FR_DICT_ATTR_OID_PRINT_RETURN(&our_out, parent, vp->da, false);
Expand Down Expand Up @@ -176,10 +183,7 @@ ssize_t fr_pair_print_secure(fr_sbuff_t *out, fr_dict_attr_t const *parent, fr_p
token = "<INVALID-TOKEN>";
}

/*
* Groups are printed from the root.
*/
if (parent && (parent->type == FR_TYPE_GROUP)) parent = NULL;
fr_pair_reset_parent(parent);

if (vp->vp_raw) FR_SBUFF_IN_STRCPY_LITERAL_RETURN(&our_out, "raw.");
FR_DICT_ATTR_OID_PRINT_RETURN(&our_out, parent, vp->da, false);
Expand Down Expand Up @@ -241,10 +245,7 @@ ssize_t fr_pair_list_print(fr_sbuff_t *out, fr_dict_attr_t const *parent, fr_pai
return fr_sbuff_used(out);
}

/*
* Groups are printed from the root.
*/
if (parent && (parent->type == FR_TYPE_GROUP)) parent = NULL;
fr_pair_reset_parent(parent);

while (true) {
FR_SBUFF_RETURN(fr_pair_print, &our_out, parent, vp);
Expand Down
49 changes: 4 additions & 45 deletions src/tests/unit/protocols/dhcpv6/dictionary
Original file line number Diff line number Diff line change
@@ -1,50 +1,9 @@
BEGIN PROTOCOL DHCPv6 3

#
# Basic options needed by the DHCPv6 pair encoder and decoder
#
ATTRIBUTE Packet-Type 65536 uint32 internal
ATTRIBUTE Transaction-ID 65537 uint32 internal
ATTRIBUTE test-tlv 6809 tlv
ATTRIBUTE child1 .1 uint32
ATTRIBUTE child2 .2 uint32

ATTRIBUTE Option-Request 65535 uint16 array # Magic option listing requested options

#
# Test attributes
#
ATTRIBUTE Test-string 1 string
ATTRIBUTE Test-octets 2 octets

ATTRIBUTE Test-ipaddr 3 ipaddr
ATTRIBUTE Test-ipv4addr 4 ipv4addr
ATTRIBUTE Test-ipv4prefix 5 ipv4prefix
ATTRIBUTE Test-ipv6addr 6 ipv6addr
ATTRIBUTE Test-ipv6prefix 7 ipv6prefix
ATTRIBUTE Test-ifid 8 ifid
ATTRIBUTE Test-ether 11 ether

ATTRIBUTE Test-bool 12 bool

ATTRIBUTE Test-uint8 13 uint8
ATTRIBUTE Test-uint16 14 uint16
ATTRIBUTE Test-uint32 15 uint32
ATTRIBUTE Test-uint64 16 uint64

ATTRIBUTE Test-int8 17 int8
ATTRIBUTE Test-int16 18 int16
ATTRIBUTE Test-int32 19 int32
ATTRIBUTE Test-int64 20 int64

ATTRIBUTE Test-float32 21 float32

ATTRIBUTE Test-time-delta 23 time_delta
ATTRIBUTE Test-date 24 date

ATTRIBUTE Test-size 26 size

ATTRIBUTE Test-tlv 27 tlv
ATTRIBUTE Test-struct 28 struct

ATTRIBUTE Test-vsa 30 vsa
ATTRIBUTE Test-group 32 group
ATTRIBUTE test-group 6810 group ref=test-tlv

END-PROTOCOL DHCPv6
30 changes: 30 additions & 0 deletions src/tests/unit/protocols/dhcpv6/group-tlv.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# -*- text -*-
# Copyright (C) 2019 Network RADIUS SARL ([email protected])
# This work is licensed under CC-BY version 4.0 https://creativecommons.org/licenses/by/4.0
#
# Version $Id$
#

proto dhcpv6
proto-dictionary dhcpv6
load-dictionary dictionary
fuzzer-out dhcpv6

pair test-group = { child1 = 1 }
match test-group = { child1 = 1 }


encode-pair test-group = { child1 = 1 }
match 1a 9a 00 0c 1a 99 00 08 00 01 00 04 00 00 00 01

#
# Yeah, this is wrong. The decoder can only handle group refs which
# point to the top of the tree.
#
# @todo - fix it!
#
decode-pair -
match test-group = { = { child1 = 1 } }

count
match 10

0 comments on commit 9200a8f

Please sign in to comment.