23RCSID(
"$Id: 06124fe02b3d45e7e2f7a4508bda0b11c07dbe4f $")
25#include <freeradius-devel/util/dict_priv.h>
32 fr_strerror_printf(
"Cannot create 'raw' attribute of data type '%s' which is a local variable",
37 if (
parent->flags.internal) {
38 fr_strerror_printf(
"Cannot create 'raw' attribute of data type '%s' which is 'internal'",
44 fr_strerror_printf(
"Cannot create 'raw' attribute of data type '%s' which has parent data type 'union'",
58 if (da->flags.internal) {
59 fr_strerror_printf(
"Cannot create unknown attribute from internal attribute %s", da->name);
70 if (da->type !=
type) {
71 fr_strerror_printf(
"Cannot allocate unknown attribute (%s) which changes data type from '%s' to '%s'",
85 fr_strerror_printf(
"Cannot create 'raw' attribute of data type '%s' which has parent data type 'struct'",
96 flags->
length = da->flags.length;
98 }
else if (da->type !=
type) {
103 fr_strerror_printf(
"Cannot create 'raw' attribute in 'struct' which changes data type from '%s' to '%s'",
134#ifdef STATIC_ANALYZER
135 if (!unknown->name || !unknown->parent)
return NULL;
140 if (da->attr == unknown->attr)
return da;
142 fr_strerror_printf(
"Unknown attribute '%s' conflicts with existing attribute in namespace '%s'",
143 da->name, unknown->parent->name);
150 if (unknown->parent && unknown->parent->flags.is_unknown) {
160 memcpy(&flags, &unknown->flags,
sizeof(flags));
172 if (
dict_vendor_add(dict, unknown->name, unknown->attr) < 0)
return NULL;
235 if (!da || !*da)
return;
238 if (!(*da)->flags.is_unknown) {
301 if (da->parent->flags.is_unknown) {
359 if (!da->flags.is_unknown)
switch (
type) {
394 if (
parent->flags.internal) {
395 fr_strerror_printf(
"Cannot create 'raw' attribute from internal parent '%s' of data type '%s'",
401 if ((uint64_t) num >= ((uint64_t) 1 << (8 *
parent->flags.type_size))) {
402 fr_strerror_printf(
"Invalid attribute number '%u' - it must be no more than %u bits in size",
403 num, 8 *
parent->flags.type_size);
417 if (
parent->flags.is_unknown)
goto fail;
425 fr_strerror_printf(
"Cannot allocate unknown attribute '%u' data type '%s' with parent %s data type '%s'",
517 switch (our_parent->type) {
581 fr_sbuff_marker(&c_start, &our_in);
583 fr_strerror_printf(
"Invalid value \"%.*s\" - attribute numbers must be less than 2^32",
593 fr_sbuff_marker(&c_start, &our_in);
611 if (((
depth == 0) && (len == 0)) || ((
depth > 0) && (len > 0))) {
650 for (da_u = da->parent, da_k =
parent;
651 da_k && da_u && da_u->flags.is_unknown;
652 da_u = da_u->parent, da_k = da_k->parent) {
653 if (
unlikely(da_u->attr != da_k->attr)) {
655 "known parent number %u (%s)",
656 da_u->attr, da_k->attr, da_k->name);
660 if (
unlikely(da_u->depth != da_k->depth)) {
662 "known parent depth %u (%s)",
663 da_u->depth, da_k->depth, da_k->name);
667 if ((da_k == NULL) != (da_u == NULL)) {
669 "for unknown attribute %u", da->attr);
676 "in dictionary", da->attr);
698 if (!da->flags.is_unknown)
return da;
709 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_ERROR_NUM_OVERFLOW
Integer type would overflow.
@ FR_SBUFF_PARSE_OK
No error.
static uint8_t depth(fr_minmax_heap_index_t i)
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