diff --git a/src/lib/util/dict.h b/src/lib/util/dict.h index 6939c74d8ba6b..e3abfe76d6e50 100644 --- a/src/lib/util/dict.h +++ b/src/lib/util/dict.h @@ -537,23 +537,31 @@ static inline fr_dict_attr_t *fr_dict_attr_unknown_copy(TALLOC_CTX *ctx, fr_dict return fr_dict_attr_unknown_afrom_da(ctx, da); } -fr_dict_attr_t *fr_dict_attr_unknown_typed_afrom_num(TALLOC_CTX *ctx, - fr_dict_attr_t const *parent, - unsigned int num, fr_type_t type) - CC_HINT(nonnull(2)); +fr_dict_attr_t *fr_dict_attr_unknown_typed_afrom_num_raw(TALLOC_CTX *ctx, + fr_dict_attr_t const *parent, + unsigned int num, fr_type_t type, bool raw) + CC_HINT(nonnull(2)); + +static inline CC_HINT(nonnull(2)) fr_dict_attr_t *fr_dict_attr_unknown_typed_afrom_num(TALLOC_CTX *ctx, + fr_dict_attr_t const *parent, + unsigned int num, fr_type_t type) +{ + return fr_dict_attr_unknown_typed_afrom_num_raw(ctx, parent, num, type, false); +} + static inline CC_HINT(nonnull(2)) fr_dict_attr_t *fr_dict_attr_unknown_vendor_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int vendor) { - return fr_dict_attr_unknown_typed_afrom_num(ctx, parent, vendor, FR_TYPE_VENDOR); + return fr_dict_attr_unknown_typed_afrom_num_raw(ctx, parent, vendor, FR_TYPE_VENDOR, false); } static inline CC_HINT(nonnull(2)) fr_dict_attr_t *fr_dict_attr_unknown_raw_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int attr) { - return fr_dict_attr_unknown_typed_afrom_num(ctx, parent, attr, FR_TYPE_OCTETS); + return fr_dict_attr_unknown_typed_afrom_num_raw(ctx, parent, attr, FR_TYPE_OCTETS, true); } fr_dict_attr_t *fr_dict_attr_unknown_raw_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da) diff --git a/src/lib/util/dict_unknown.c b/src/lib/util/dict_unknown.c index cb91c5f231d81..108e5a8f1bcb7 100644 --- a/src/lib/util/dict_unknown.c +++ b/src/lib/util/dict_unknown.c @@ -260,15 +260,17 @@ fr_dict_attr_t *fr_dict_attr_unknown_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t co * @param[in] parent of the unknown attribute (may also be unknown). * @param[in] num of the unknown attribute. * @param[in] type data type + * @param[in] raw is it raw, i.e. _bad_ value, versus unknown? * @return * - An fr_dict_attr_t on success. * - NULL on failure. */ -fr_dict_attr_t *fr_dict_attr_unknown_typed_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int num, fr_type_t type) +fr_dict_attr_t *fr_dict_attr_unknown_typed_afrom_num_raw(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int num, fr_type_t type, bool raw) { fr_dict_attr_flags_t flags = { .is_unknown = true, .internal = parent->flags.internal, + .is_raw = raw, }; switch (type) { @@ -285,15 +287,18 @@ fr_dict_attr_t *fr_dict_attr_unknown_typed_afrom_num(TALLOC_CTX *ctx, fr_dict_at flags.length = 1; break; - /* - * We don't know what data type it is, so it's raw. - */ case FR_TYPE_NULL: - type = FR_TYPE_OCTETS; - flags.is_raw = 1; - break; + case FR_TYPE_VALUE_BOX: + case FR_TYPE_VOID: + case FR_TYPE_MAX: + fr_strerror_printf("%s: Cannot allocate unknown %s attribute (%u) - invalid data type", + __FUNCTION__, + fr_type_to_str(type), num); + return NULL; default: + if (fr_dict_attr_is_key_field(parent)) break; + if (!fr_type_is_structural_except_vsa(parent->type)) { fail: fr_strerror_printf("%s: Cannot allocate unknown %s attribute (%u) with parent type %s", diff --git a/src/tests/unit/protocols/bfd/base.txt b/src/tests/unit/protocols/bfd/base.txt index 2bc7ad6eca3b9..dfd904788523d 100644 --- a/src/tests/unit/protocols/bfd/base.txt +++ b/src/tests/unit/protocols/bfd/base.txt @@ -47,7 +47,8 @@ match 20 c4 03 21 de ad be ef 21 12 68 09 00 00 00 1f 00 00 00 7f 00 00 00 ff 00 decode-proto - match Packet-Type = ::Up, Packet = { version = 1, diagnostic = ::none, state = ::up, poll = no, final = no, control-plane-independent = no, auth-present = yes, demand = no, multipoint = no, detect-multi = 3, length = 33, my-discriminator = 3735928559, your-discriminator = 554854409, desired-min-tx-interval = 31, required-min-tx-interval = 127, required-min-echo-interval = 255, auth-type = 0, raw.auth-type.0 = 0x0a0f0068656c6c6f } -#match Packet = { version = 1, diagnostic = none, state = up, poll = no, final = no, control-plane-independent = no, auth-present = yes, demand = no, multipoint = no, detect-multi = 3, length = 24, my-discriminator = 3735928559, your-discriminator = 554854409, desired-min-tx-interval = 31, required-min-tx-interval = 127, required-min-echo-interval = 255, auth-type.simple-password = { key-id = 0, reserved = 0, password = "hello" } } +encode-proto - +match 20 c4 03 21 de ad be ef 21 12 68 09 00 00 00 1f 00 00 00 7f 00 00 00 ff 00 0a 0f 00 68 65 6c 6c 6f count -match 17 +match 19