From: Alan T. DeKok Date: Fri, 13 Aug 2021 17:49:25 +0000 (-0400) Subject: correct encoding of vendor-class "data" field X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ec737ff97102fd3c9ef7b79c384a846212d2f31f;p=thirdparty%2Ffreeradius-server.git correct encoding of vendor-class "data" field Which should be repeated 16-bit length + data The decoder already worked correctly, once the dictionary was updated. --- diff --git a/share/dictionary/dhcpv6/dictionary.rfc3315 b/share/dictionary/dhcpv6/dictionary.rfc3315 index 4bffb726b34..8ed32523caa 100644 --- a/share/dictionary/dhcpv6/dictionary.rfc3315 +++ b/share/dictionary/dhcpv6/dictionary.rfc3315 @@ -125,7 +125,7 @@ ATTRIBUTE Rapid-Commit 14 bool ATTRIBUTE User-Class 15 octets array ATTRIBUTE Vendor-Class 16 struct MEMBER PEN uint32 -MEMBER Data octets # really 2 octets length + data, repeated +MEMBER Data octets array ATTRIBUTE Vendor-Opts 17 vsa ATTRIBUTE Interface-ID 18 octets diff --git a/src/protocols/dhcpv6/encode.c b/src/protocols/dhcpv6/encode.c index 48fbec22e45..ca043858792 100644 --- a/src/protocols/dhcpv6/encode.c +++ b/src/protocols/dhcpv6/encode.c @@ -79,6 +79,26 @@ static inline ssize_t encode_option_hdr(fr_dbuff_marker_t *m, uint16_t option, s } +static inline ssize_t encode_array(fr_dbuff_t *dbuff, + fr_da_stack_t *da_stack, int depth, + fr_dcursor_t *cursor, void *encode_ctx); + +static ssize_t encode_value_trampoline(fr_dbuff_t *dbuff, + fr_da_stack_t *da_stack, unsigned int depth, + fr_dcursor_t *cursor, void *encode_ctx) +{ + fr_dict_attr_t const *da = da_stack->da[depth]; + + /* + * Write out the option's value + */ + if (da->flags.array) { + return encode_array(dbuff, da_stack, depth, cursor, encode_ctx); + } + + return encode_value(dbuff, da_stack, depth, cursor, encode_ctx); +} + static ssize_t encode_value(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, unsigned int depth, fr_dcursor_t *cursor, void *encode_ctx) @@ -95,7 +115,7 @@ static ssize_t encode_value(fr_dbuff_t *dbuff, * Pack multiple attributes into into a single option */ if ((vp->da->type == FR_TYPE_STRUCT) || (da->type == FR_TYPE_STRUCT)) { - slen = fr_struct_to_network(&work_dbuff, da_stack, depth, cursor, encode_ctx, encode_value, encode_tlv); + slen = fr_struct_to_network(&work_dbuff, da_stack, depth, cursor, encode_ctx, encode_value_trampoline, encode_tlv); if (slen <= 0) return slen; /* diff --git a/src/tests/unit/protocols/dhcpv6/rfc8415.txt b/src/tests/unit/protocols/dhcpv6/rfc8415.txt index 5e5ade413f5..74a8773c7a7 100644 --- a/src/tests/unit/protocols/dhcpv6/rfc8415.txt +++ b/src/tests/unit/protocols/dhcpv6/rfc8415.txt @@ -628,7 +628,7 @@ match User-Class = 0x1122, User-Class = 0x334455 # value in the option-len field). # encode-pair Vendor-Class.PEN = 11344, Vendor-Class.Data = 0xb33f -match 00 10 00 06 00 00 2c 50 b3 3f +match 00 10 00 08 00 00 2c 50 00 02 b3 3f decode-pair - match Vendor-Class.PEN = 11344, Vendor-Class.Data = 0xb33f