]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
encode_vsio can be called with the da_stack built
authorNick Porter <nick@portercomputing.co.uk>
Thu, 3 Oct 2024 13:32:12 +0000 (14:32 +0100)
committerNick Porter <nick@portercomputing.co.uk>
Thu, 3 Oct 2024 13:51:34 +0000 (14:51 +0100)
When called from %dhcpv4.encode()

This is almost a revert of d6d160a, but with the option header and
length handled in encode_vsio()

src/protocols/dhcpv4/encode.c

index acefa97cf8871f382297bdf281cf18bfd2e03eb6..aa74fadbc782f16d6461005c0feecea5830498ba 100644 (file)
@@ -620,12 +620,7 @@ static ssize_t encode_vsio(fr_dbuff_t *dbuff,
                return PAIR_ENCODE_FATAL_ERROR;
        }
 
-       vp = fr_dcursor_current(cursor);
-       fr_assert(vp->da == da);
-
        work_dbuff = FR_DBUFF(dbuff);
-       fr_pair_dcursor_init(&vendor_cursor, &vp->vp_group);
-
        fr_dbuff_marker(&hdr, &work_dbuff);
 
        /*
@@ -634,6 +629,41 @@ static ssize_t encode_vsio(fr_dbuff_t *dbuff,
         */
        FR_DBUFF_IN_BYTES_RETURN(&work_dbuff, (uint8_t) da->attr, 0x00);
 
+       /*
+        *      We are at the VSA.  The next entry in the stack is the vendor.  The entry after that is the vendor data.
+        */
+       if (da_stack->da[depth + 1]) {
+               ssize_t len;
+               fr_dcursor_t vsa_cursor;
+
+               if (da_stack->da[depth + 2]) {
+                       len = encode_vsio_data(&work_dbuff, da_stack, depth + 2, cursor, encode_ctx);
+                       if (len <= 0) return len;
+                       goto done;
+               }
+
+               vp = fr_dcursor_current(cursor);
+               fr_assert(vp->vp_type == FR_TYPE_VENDOR);
+
+               /*
+                *      Copied from below.
+                */
+               fr_pair_dcursor_init(&vsa_cursor, &vp->vp_group);
+               work_dbuff = FR_DBUFF(dbuff);
+
+               while ((vp = fr_dcursor_current(&vsa_cursor)) != NULL) {
+                       fr_proto_da_stack_build(da_stack, vp->da);
+                       len = encode_vsio_data(&work_dbuff, da_stack, depth + 2, &vsa_cursor, encode_ctx);
+                       if (len <= 0) return len;
+               }
+               goto done;
+       }
+
+       vp = fr_dcursor_current(cursor);
+       fr_assert(vp->da == da);
+
+       fr_pair_dcursor_init(&vendor_cursor, &vp->vp_group);
+
        /*
         *      Loop over all vendors, and inside of that, loop over all VSA attributes.
         */
@@ -669,6 +699,7 @@ static ssize_t encode_vsio(fr_dbuff_t *dbuff,
        /*
         *      Write out length for whole option
         */
+done:
        fr_dbuff_advance(&hdr, 1);
        FR_DBUFF_IN_RETURN(&hdr, (uint8_t)(fr_dbuff_used(&work_dbuff) - DHCPV4_OPT_HDR_LEN));