23RCSID(
"$Id: b3f8fe232c9beaf6d70d889e4e0f6cb2992b10fb $")
25#include <freeradius-devel/util/dict_priv.h>
31 if (
parent->flags.internal) {
32 fr_strerror_printf(
"Cannot create 'raw' attribute of data type '%s' which is 'internal'",
38 fr_strerror_printf(
"Cannot create 'raw' attribute of data type '%s' which has parent data type 'union'",
52 if (da->flags.internal) {
53 fr_strerror_printf(
"Cannot create unknown attribute from internal attribute %s", da->name);
64 if (da->type !=
type) {
65 fr_strerror_printf(
"Cannot allocate unknown attribute (%s) which changes data type from '%s' to '%s'",
79 fr_strerror_printf(
"Cannot create 'raw' attribute of data type '%s' which has parent data type 'struct'",
90 flags->
length = da->flags.length;
92 }
else if (da->type !=
type) {
97 fr_strerror_printf(
"Cannot create 'raw' attribute in 'struct' which changes data type from '%s' to '%s'",
128#ifdef STATIC_ANALYZER
129 if (!unknown->name || !unknown->parent)
return NULL;
134 if (da->attr == unknown->attr)
return da;
136 fr_strerror_printf(
"Unknown attribute '%s' conflicts with existing attribute in namespace '%s'",
137 da->name, unknown->parent->name);
144 if (unknown->parent && unknown->parent->flags.is_unknown) {
154 memcpy(&flags, &unknown->flags,
sizeof(flags));
166 if (
dict_vendor_add(dict, unknown->name, unknown->attr) < 0)
return NULL;
229 if (!da || !*da)
return;
232 if (!(*da)->flags.is_unknown) {
295 if (da->parent->flags.is_unknown) {
353 if (!da->flags.is_unknown)
switch (
type) {
388 if (
parent->flags.internal) {
389 fr_strerror_printf(
"Cannot create 'raw' attribute from internal parent '%s' of data type '%s'",
395 if ((uint64_t) num >= ((uint64_t) 1 << (8 *
parent->flags.type_size))) {
396 fr_strerror_printf(
"Invalid attribute number '%u' - it must be no more than %u bits in size",
397 num, 8 *
parent->flags.type_size);
411 if (
parent->flags.is_unknown)
goto fail;
419 fr_strerror_printf(
"Cannot allocate unknown attribute '%u' data type '%s' with parent %s data type '%s'",
502 switch (our_parent->type) {
566 fr_sbuff_marker(&c_start, &our_in);
605 for (da_u = da->parent, da_k =
parent;
606 da_k && da_u && da_u->flags.is_unknown;
607 da_u = da_u->parent, da_k = da_k->parent) {
608 if (
unlikely(da_u->attr != da_k->attr)) {
610 "known parent number %u (%s)",
611 da_u->attr, da_k->attr, da_k->name);
615 if (
unlikely(da_u->depth != da_k->depth)) {
617 "known parent depth %u (%s)",
618 da_u->depth, da_k->depth, da_k->name);
622 if ((da_k == NULL) != (da_u == NULL)) {
624 "for unknown attribute %u", da->attr);
631 "in dictionary", da->attr);
653 if (!da->flags.is_unknown)
return da;
664 if (dict->root == da)
return dict->root;
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
fr_dict_t const * fr_dict_by_da(fr_dict_attr_t const *da)
Attempt to locate the protocol dictionary containing an attribute.
static fr_dict_attr_t * fr_dict_attr_unknown_vendor_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int vendor)
bool const fr_dict_attr_allowed_chars[UINT8_MAX+1]
Characters allowed in a single dictionary attribute name.
static fr_dict_attr_t * fr_dict_attr_unknown_copy(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
fr_dict_attr_t const * fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *attr))
Locate a fr_dict_attr_t by its name.
fr_dict_attr_t * fr_dict_attr_unconst(fr_dict_attr_t const *da)
Coerce to non-const.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
unsigned int is_raw
This dictionary attribute was constructed from a known attribute to allow the user to assign octets v...
uint16_t length
length of the attribute
@ FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC
Protocol specific extensions.
unsigned int is_known_width
is treated as if it has a known width for structs
#define FR_DICT_MAX_TLV_STACK
Maximum TLV stack size.
int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, unsigned int attr, fr_type_t type, fr_dict_attr_flags_t const *flags))
Add an attribute to the dictionary.
static 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 const * fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr)
Check if a child attribute exists in a parent using an attribute number.
#define FR_DICT_ATTR_MAX_NAME_LEN
Maximum length of a attribute name.
unsigned int is_unknown
This dictionary attribute is ephemeral and not part of the main dictionary.
Values of the encryption flags.
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
static void * dict_attr_ext_copy(fr_dict_attr_t **da_out_p, fr_dict_attr_t const *da_in, fr_dict_attr_ext_t ext)
Copy a single attribute extension from one attribute to another.
#define dict_attr_alloc(_ctx, _parent, _name, _attr, _type, _args)
#define INTERNAL_IF_NULL(_dict, _ret)
Set the internal dictionary if none was provided.
int dict_attr_add_to_namespace(fr_dict_attr_t const *parent, fr_dict_attr_t *da)
Add an attribute to the name table for an attribute.
int dict_attr_child_add(fr_dict_attr_t *parent, fr_dict_attr_t *child)
Add a child to a parent.
int dict_vendor_add(fr_dict_t *dict, char const *name, unsigned int num)
Add a vendor to the dictionary.
#define dict_attr_init(_da_p, _parent, _name, _attr, _type, _args)
Full initialisation functions.
fr_dict_attr_t * dict_attr_alloc_null(TALLOC_CTX *ctx, fr_dict_protocol_t const *dict)
Partial initialisation functions.
Optional arguments for initialising/allocating attributes.
fr_slen_t fr_dict_attr_unknown_afrom_oid_substr(TALLOC_CTX *ctx, fr_dict_attr_t const **out, fr_dict_attr_t const *parent, fr_sbuff_t *in, fr_type_t type)
Create a fr_dict_attr_t from an ASCII attribute and value.
fr_dict_attr_t * fr_dict_attr_unknown_alloc(TALLOC_CTX *ctx, fr_dict_attr_t const *da, fr_type_t type)
Allocate an unknown DA.
fr_dict_attr_t const * fr_dict_attr_unknown_resolve(fr_dict_t const *dict, fr_dict_attr_t const *da)
Check to see if we can convert a nested TLV structure to known attributes.
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)
Initialise a fr_dict_attr_t from a number and a data type.
int fr_dict_attr_unknown_parent_to_known(fr_dict_attr_t *da, fr_dict_attr_t const *parent)
Fixup the parent of an unknown attribute using an equivalent known attribute.
void fr_dict_attr_unknown_free(fr_dict_attr_t const **da)
Free dynamically allocated (unknown attributes)
fr_dict_attr_t const * fr_dict_attr_unknown_add(fr_dict_t *dict, fr_dict_attr_t const *unknown)
Converts an unknown to a known by adding it to the internal dictionaries.
fr_dict_attr_t * fr_dict_attr_unknown_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Copy a known or unknown attribute to produce an unknown attribute with the specified name.
static int dict_attr_unknown_init(fr_dict_attr_t const *parent, UNUSED fr_dict_attr_t const *da, fr_type_t type, fr_dict_attr_flags_t *flags)
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_STRUCT
like TLV, but without T or L, and fixed-width children
@ FR_TYPE_VENDOR
Attribute that represents a vendor in the attribute tree.
@ FR_TYPE_VSA
Vendor-Specific, for RADIUS attribute 26.
@ FR_TYPE_OCTETS
Raw octets.
@ FR_TYPE_GROUP
A grouping of other attributes.
@ FR_SBUFF_PARSE_OK
No error.
size_t fr_sbuff_adv_past_allowed(fr_sbuff_t *sbuff, size_t len, bool const allowed[static UINT8_MAX+1], fr_sbuff_term_t const *tt)
Wind position past characters in the allowed set.
bool fr_sbuff_next_if_char(fr_sbuff_t *sbuff, char c)
Return true if the current char matches, and if it does, advance.
#define fr_sbuff_current(_sbuff_or_marker)
#define fr_sbuff_is_char(_sbuff_or_marker, _c)
#define FR_SBUFF_ERROR_RETURN(_sbuff_or_marker)
#define FR_SBUFF_SET_RETURN(_dst, _src)
#define FR_SBUFF(_sbuff_or_marker)
#define fr_sbuff_out(_err, _out, _in)
#define fr_sbuff_behind(_sbuff_or_marker)
fr_aka_sim_id_type_t type
static int talloc_const_free(void const *ptr)
Free const'd memory.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_printf_push(_fmt,...)
Add a message to an existing stack of messages at the tail.
#define fr_strerror_const(_msg)
#define fr_type_is_structural(_x)
@ FR_TYPE_UNION
A union of limited children.
#define FR_TYPE_STRUCTURAL_EXCEPT_VSA
#define fr_type_is_structural_except_vsa(_x)
#define FR_TYPE_STRUCTURAL
#define fr_type_is_leaf(_x)
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
static size_t char ** out