Skip to content
Permalink
Browse files

encode structs, and add tests for them

  • Loading branch information
alandekok committed Aug 13, 2019
1 parent 27a592f commit c37a24c53c8070752d8619aa8ee649b7b7ee5ec6
Showing with 62 additions and 0 deletions.
  1. +59 −0 src/lib/util/struct.c
  2. +3 −0 src/tests/unit/radius_struct.txt
@@ -210,6 +210,8 @@ ssize_t fr_struct_to_network(uint8_t *out, size_t outlen,
unsigned int child_num = 1;
uint8_t *p = out;
VALUE_PAIR const *vp = fr_cursor_current(cursor);
fr_dict_attr_t const *key_da;
uint8_t *key_data;

VP_VERIFY(fr_cursor_current(cursor));

@@ -224,6 +226,9 @@ ssize_t fr_struct_to_network(uint8_t *out, size_t outlen,
return -1;
}

key_da = NULL;
key_data = NULL;

while (outlen) {
fr_dict_attr_t const *child;

@@ -237,6 +242,11 @@ ssize_t fr_struct_to_network(uint8_t *out, size_t outlen,

if (!child) break;

if (child->flags.extra) {
key_da = child;
key_data = p;
}

if (child->flags.length > outlen) {
len = outlen;
} else {
@@ -256,6 +266,11 @@ ssize_t fr_struct_to_network(uint8_t *out, size_t outlen,
len = fr_value_box_to_network(NULL, p, outlen, &vp->data);
if (len <= 0) return -1;

if (child->flags.extra) {
key_da = child;
key_data = p;
}

p += len;
outlen -= len; /* Subtract from the buffer we have available */
child_num++;
@@ -272,5 +287,49 @@ ssize_t fr_struct_to_network(uint8_t *out, size_t outlen,
if (!vp || (vp->da->parent != parent)) break;
}

if (!vp || !outlen) return p - out;

/*
* Encode the key field based on the value of the next
* attribute. Note that there isn't much point in
* converting key_da->attr into a value_box_t, and then
* calling fr_value_box_to_network() to do the work. The
* code below isn't much larger in the source, but is
* rather substantially simpler over all.
*/
if (key_da && (vp->da->parent == key_da)) {
switch (key_da->type) {
case FR_TYPE_UINT8:
*key_data = key_da->attr;
break;

case FR_TYPE_UINT16:
if ((p - key_data) < 2) return p - out;

key_data[0] = (key_da->attr >> 8) & 0xff;
key_data[1] = key_da->attr & 0xff;
break;

case FR_TYPE_UINT32:
if ((p - key_data) < 4) return p - out;

key_data[0] = (key_da->attr >> 24) & 0xff;
key_data[1] = (key_da->attr >> 16) & 0xff;
key_data[2] = (key_da->attr >> 8) & 0xff;
key_data[3] = key_da->attr & 0xff;
break;

default:
return p - out;
}

/*
* We don't need to recurse. the caller will see
* that the next attribute is of type 'struct',
* and will call this function again to encode
* it.
*/
}

return p - out;
}
@@ -56,3 +56,6 @@ data Unit-Struct4-Int1 = 1, Unit-Struct4-Int2 = 2, Unit-Struct4-Short = 4

decode-pair ff 09 01 00 00 1a 99 05 06
data Key-Field = Sub-Struct, Filler = 6809, Nested-Sub1 = 5, Nested-Sub2 = 6

encode-pair Key-Field = Sub-Struct, Filler = 6809, Nested-Sub1 = 5, Nested-Sub2 = 6
data ff 0b 01 00 00 1a 99 01 04 05 06

0 comments on commit c37a24c

Please sign in to comment.
You can’t perform that action at this time.