]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
allow for nested VPs in one place
authorAlan T. DeKok <aland@freeradius.org>
Tue, 8 Jun 2021 13:25:01 +0000 (09:25 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 8 Jun 2021 13:26:05 +0000 (09:26 -0400)
src/protocols/dhcpv4/encode.c
src/tests/unit/protocols/dhcpv4/base.txt

index 35613d63d3e2f25e80d457ffa6285506f975903d..a13a9f31b7dbc4d5149910964f68bb749e709a62 100644 (file)
@@ -549,6 +549,47 @@ ssize_t fr_dhcpv4_encode_option(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *e
 
        FR_PROTO_STACK_PRINT(&da_stack, depth);
 
+       if (!da_stack.da[depth + 1]) {
+               fr_dcursor_t child_cursor;
+
+               switch (vp->da->type) {
+               case FR_TYPE_STRUCTURAL:
+                       break;
+
+               default:
+                       fr_strerror_printf("Failed encoding attribute '%s' due to da_stack issue", vp->da->name);
+                       (void)fr_dcursor_next(cursor);
+                       return 0;
+               }
+
+               fr_dcursor_init(&child_cursor, &vp->vp_group);
+               vp = fr_dcursor_current(&child_cursor);
+               fr_proto_da_stack_build(&da_stack, vp->da);
+
+               switch (da_stack.da[depth]->type) {
+               case FR_TYPE_VSA:
+                       len = encode_vsio_hdr(&work_dbuff, &da_stack, depth, &child_cursor, encode_ctx);
+                       break;
+
+               case FR_TYPE_TLV:
+                       len = encode_tlv_hdr(&work_dbuff, &da_stack, depth, &child_cursor, encode_ctx);
+                       break;
+
+               default:
+                       len = encode_rfc_hdr(&work_dbuff, &da_stack, depth, &child_cursor, encode_ctx);
+                       break;
+               }
+
+               if (len <= 0) return len;
+               
+               /*
+                *      skip this VP, and re-build the da stack.
+                */
+               vp = fr_dcursor_next(cursor);
+               fr_proto_da_stack_build(&da_stack, vp ? vp->da : NULL);
+               goto done;
+       }
+
        /*
         *      We only have two types of options in DHCPv4
         */
@@ -568,6 +609,7 @@ ssize_t fr_dhcpv4_encode_option(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *e
 
        if (len <= 0) return len;
 
+done:
        FR_PROTO_TRACE("Complete option is %zu byte(s)", fr_dbuff_used(&work_dbuff));
        FR_PROTO_HEX_DUMP(dbuff->p, fr_dbuff_used(&work_dbuff), NULL);
 
index dc78d82075c6c08ca8dd13123a75a0e97aa7cf9c..98ac15a9af7c7c4aef69e13c52383452e8aef19e 100644 (file)
@@ -13,6 +13,13 @@ match 52 0d 01 03 ab cd ef 02 06 01 02 03 04 05 06
 decode-pair -
 match Relay-Agent-Information.Circuit-Id = 0xabcdef, Relay-Agent-Information.Remote-Id = 0x010203040506
 
+#
+#  And then again as nested pairs
+#
+encode-pair Relay-Agent-Information = { Circuit-Id = 0xabcdef, Remote-Id = 0x010203040506 }
+match 52 0d 01 03 ab cd ef 02 06 01 02 03 04 05 06
+
+
 encode-pair Subnet-Mask = 255.255.0.0
 match 01 04 ff ff 00 00