24RCSID(
"$Id: a53b9ed97343404844bb6e5cfc97ec1790374a95 $")
26#define _DICT_PRIVATE 1
28#include <freeradius-devel/util/atexit.h>
29#include <freeradius-devel/util/conf.h>
30#include <freeradius-devel/util/dict.h>
31#include <freeradius-devel/util/dict_ext_priv.h>
32#include <freeradius-devel/util/dict_fixup_priv.h>
33#include <freeradius-devel/util/proto.h>
34#include <freeradius-devel/util/rand.h>
35#include <freeradius-devel/util/syserror.h>
44#pragma clang diagnostic ignored "-Wgnu-designator"
47#define DICT_ATTR_ALLOWED_CHARS \
48 ['-'] = true, ['/'] = true, ['_'] = true, \
49 [ '0' ... '9' ] = true, \
50 [ 'A' ... 'Z' ] = true, \
51 [ 'a' ... 'z' ] = true
73 [
'+'] =
true, [
'.'] =
true,
84 .default_type_size = 2,
85 .default_type_length = 2,
93#define FNV_MAGIC_INIT (0x811c9dc5)
94#define FNV_MAGIC_PRIME (0x01000193)
107 char const *p =
name, *q =
name + len;
110 int c = *(
unsigned char const *)p;
111 if (isalpha(c)) c = tolower(c);
145 ret =
strcasecmp(a->root->name, b->root->name);
165 return CMP(a->root->attr, b->root->attr);
214 if (a->depth < b->depth) {
216 if (ret != 0)
return ret;
221 if (a->depth > b->depth) {
223 if (ret != 0)
return ret;
235 if ((a->depth == 0) || (a->parent == b->parent)) {
239 ret =
CMP((a->flags.is_unknown | a->flags.is_raw), (b->flags.is_unknown | b->flags.is_raw));
240 if (ret != 0)
return ret;
242 return CMP(a->attr, b->attr);
323 if (ret != 0)
return ret;
362 if (!da->flags.is_alias)
return da;
387 char *name_start, *name_end;
402 name_len = strlen(
name);
417 if (!name_start)
return -1;
419 name_end = name_start + name_len;
421 memcpy(name_start,
name, name_len);
424 (*da_p)->name = name_start;
425 (*da_p)->name_len = name_len;
502 if (!ext->namespace) {
505 if (!ext->namespace) {
527 ((*da_p)->type !=
type))) {
533 if (
unlikely((*da_p)->state.finalised ==
true)) {
565 (*da_p)->last_child_attr = (1 << 24);
584 (*da_p)->flags.length = 4;
591 (*da_p)->flags.is_known_width = ((*da_p)->flags.length != 0);
598 (*da_p)->type =
type;
618 fr_strerror_const(
"Attribute type must be set before initialising parent. Use dict_attr_type_init() first");
623 fr_strerror_printf(
"Attempting to set parent for '%s' to '%s', but parent already set to '%s'",
624 da->name,
parent->name, da->parent->name);
628 if (
unlikely((*da_p)->state.finalised ==
true)) {
629 fr_strerror_printf(
"Attempting to set parent for '%s' to '%s', but attribute already finalised",
636 da->depth =
parent->depth + 1;
637 da->flags.internal |=
parent->flags.internal;
644 da->flags.type_size =
dict->root->flags.type_size;
645 da->flags.length =
dict->root->flags.type_size;
652 da->flags.type_size = dv->
type;
653 da->flags.length = dv->
length;
658 da->flags.type_size =
dict->root->flags.type_size;
659 da->flags.length =
dict->root->flags.type_size;
676 da->flags.type_size = ext->
vendor->flags.type_size;
677 da->flags.length = ext->
vendor->flags.type_size;
689 if (da->state.attr_set) {
694 da->state.attr_set =
true;
708 fr_strerror_const(
"Attribute must have parent set before automatically setting attribute number");
719 da->filename = filename;
753 da->flags.is_known_width |= da->flags.array;
796 (*da_p)->state.finalised =
true;
801static inline CC_HINT(always_inline)
811 if (
args->flags) (*da_p)->flags = *
args->flags;
820 if (!(*da_p)->flags.internal && !(*da_p)->flags.is_alias &&
822 if (!
parent->flags.type_size) {
827 if ((uint64_t) (*da_p)->attr >= ((uint64_t) 1 << (8 *
parent->flags.type_size))) {
828 fr_strerror_printf(
"Child of parent %s has invalid attribute number %u for type_size %u",
866 char const *
name,
unsigned int attr,
921 (*da_p)->flags.name_only =
true;
933#ifdef WITH_VERIFY_PTR
977 if (proto->
attr.flags.len > 0) {
979 proto->
attr.flags.len) == NULL)) {
1006 char const *
name,
int proto_number,
1071 if (
in->flags.has_fixup) {
1072 fr_strerror_printf(
"Cannot copy from %s - source attribute is waiting for additional definitions",
1086 n->flags.is_ref_target =
false;
1104 if (!dst->flags.local) {
1109 if (src->flags.has_fixup) {
1110 fr_strerror_printf(
"Cannot copy from %s to %s - source attribute is waiting for additional definitions",
1111 src->name, dst->name);
1118 if (src->flags.local) {
1132 if (!copy)
return -1;
1135 copy->depth = copy->parent->depth + 1;
1217 if (src_key->flags.has_fixup) {
1218 fr_strerror_printf(
"Cannot copy from %s - source attribute is waiting for additional definitions",
1224 src_key->attr, src_key->type, &(
dict_attr_args_t){ .flags = &src_key->flags });
1230 dst_key->depth = dst->depth + 1;
1246 if (!src_key)
return 0;
1302 if (!src->flags.has_alias)
return 0;
1304 switch (src->type) {
1322 namespace = dict_attr_namespace(src);
1328 if (!da->flags.is_alias)
continue;
1331 fr_strerror_printf(
"Cannot clone ALIAS %s.%s to %s.%s", src->name, da->name, dst->name, da->name);
1350 fr_strerror_printf(
"Cannot clone ALIAS %s.%s to %s.%s, the alias reference %s is outside of the shared tree",
1351 src->name, da->name, dst->name, da->name, ref->name);
1364 new_ref = dict_alias_reref(dst, src, ref);
1430 fr_strerror_printf(
"Invalid ALIAS to target attribute %s of data type '%s' - the attributes do not share a parent",
1454 self->dict =
parent->dict;
1459 namespace = dict_attr_namespace(parent);
1487 if (!
dict->root)
return -1;
1498 if ((strcmp(old_proto->root->name,
dict->root->name) == 0) &&
1499 (old_proto->root->name ==
dict->root->name)) {
1506 dict->in_protocol_by_name =
true;
1512 dict->in_protocol_by_num =
true;
1579 if (!vendor->
name) {
1594 if ((strcmp(old_vendor->
name, vendor->
name) == 0) && (old_vendor->
pen != vendor->
pen)) {
1690 if (!
parent->flags.is_root &&
parent->flags.name_only &&
1724 for (bin = &children[child->attr & 0xff]; *bin; bin = &(*bin)->next) {
1732 if (child_is_struct && !bin_is_struct)
break;
1734 if (child->attr <= (*bin)->attr)
break;
1737 memcpy(&
this, &bin,
sizeof(
this));
1738 child->next = *
this;
1756 namespace = dict_attr_namespace(parent);
1788 if (a && (
strcasecmp(a->name, da->name) == 0)) {
1789 if ((a->attr != da->attr) || (a->type != da->type) || (a->parent != da->parent)) {
1791 "Originally defined %s[%d]",
1793 a->filename, a->line);
1822 if (
unlikely(da->dict->read_only)) {
1827 if (
unlikely(da->state.finalised ==
false)) {
1850 "Originally defined %s[%d]", da->name, da->parent->name,
1851 exists->filename, exists->line);
1860 if (da->flags.name_only) {
1861 if (da->state.attr_set) {
1864 if (da->attr > da->parent->last_child_attr) {
1865 parent->last_child_attr = da->attr;
1874 if ((da->attr >= (((uint64_t)1) << (8 *
parent->flags.type_size)))) da->flags.internal =
true;
1889 "Originally defined by '%s' at %s[%d]",
1890 da->attr, da->parent->name, exists->name, exists->filename, exists->line);
1913 fr_strerror_printf(
"FATAL - Failed to find attribute number %u we just added to namespace '%s'", da->attr, da->parent->name);
1918 fr_strerror_printf(
"FATAL - Failed to find attribute '%s' we just added to namespace '%s'", da->name, da->parent->name);
1995 bool coerce,
bool takes_precedence,
2023 fr_strerror_const(
"Child attributes cannot be defined for VALUEs which are not 'key' attributes");
2032 if (da->flags.is_alias) {
2076 if (key_child_ref) {
2082 ref->
da = key_child_ref;
2086 if (!enum_value)
goto oom;
2088 if (da->type !=
value->type) {
2110 enumv->
value = enum_value;
2117 memcpy(&tmp, &enumv,
sizeof(tmp));
2136 "Old value was \"%pV\", new value was \"%pV\"",
name, da->name,
2149 if (takes_precedence) {
2191 bool coerce,
bool takes_precedence)
2246 fr_strerror_printf(
"Attribute is wrong type for auto-numbering, expected numeric type, got %s",
2290 if (!a || !b)
return NULL;
2292 if (is_ancestor && (b->depth <= a->depth))
return NULL;
2297 if (a->depth > b->depth) {
2299 for (p_a = a, i = a->depth - b->depth; p_a && (i > 0); p_a = p_a->parent, i--);
2300 if (is_ancestor && (p_a != p_b))
return NULL;
2301 }
else if (a->depth < b->depth) {
2303 for (p_b = b, i = b->depth - a->depth; p_b && (i > 0); p_b = p_b->parent, i--);
2304 if (is_ancestor && (p_a != p_b))
return NULL;
2310 while (p_a && p_b) {
2311 if (p_a == p_b)
return p_a;
2330 char const *p = *oid;
2336 num = strtoul(p, &q, 10);
2337 if ((p == q) || (num == ULONG_MAX)) {
2346 *
out = (
unsigned int)num;
2373 char const *p = oid;
2374 unsigned int num = 0;
2402 "Error at sub OID \"%s\"", (*parent)->name, (*parent)->attr, oid);
2419 num, oid, (*parent)->name);
2431 if (slen <= 0)
return slen - (p - oid);
2432 return slen + (p - oid);
2477 "Error at OID \"%.*s\"",
2504 fr_sbuff_set_to_start(&our_in);
2517 fr_sbuff_set_to_start(&our_in);
2522 fr_sbuff_marker(&c_start, &our_in);
2524 fr_strerror_printf(
"Invalid value \"%.*s\" - attribute numbers must be less than 2^32",
2534 fr_sbuff_set_to_start(&our_in);
2569 fr_sbuff_marker(&m_c, &our_in);
2644 return dict->read_only;
2669 memset(&root, 0,
sizeof(root));
2676 &our_name, SIZE_MAX,
2702 memcpy(
out, &dict_def,
sizeof(*
out));
2710 if (
strcasecmp(root.name,
"internal") != 0) {
2712 memcpy(
out, &dict_def,
sizeof(*
out));
2713 fr_sbuff_set_to_start(&our_name);
2755 &(
fr_dict_t){ .root = &(fr_dict_attr_t){ .name = name } });
2773 &(
fr_dict_t) { .root = &(fr_dict_attr_t){ .attr = num } });
2792 while (da_p->parent) {
2793 da_p = da_p->parent;
2795 "Expected %s, got %s",
2796 !da_p->dict ?
"(null)" :
fr_dict_root(da_p->dict)->name,
2801 if (!da_p->flags.is_root) {
2803 __FUNCTION__, da->name);
2813 return talloc_get_type_abort(da->dict,
fr_dict_t);
2869 while (dict1->next) dict1 = dict1->next;
2871 while (dict2->next) dict2 = dict2->next;
2873 return (dict1 == dict2);
2890 if (!dv.
pen)
return NULL;
2914 if (!
name)
return NULL;
2917 if (!found)
return NULL;
2954 switch (vendor_root->type) {
3014static inline CC_HINT(always_inline)
3018 bool internal,
bool foreign,
3031 if (
unlikely(!internal && !foreign && !dict_def)) {
3047 if (!internal && !foreign)
goto error;
3065 if (!foreign)
goto error;
3079 if (
dict == dict_def)
continue;
3105#define DICT_NAME_APPEND(_in, _dict) \
3108 _n = talloc_strdup_append_buffer(_in, fr_dict_root(_dict)->name); \
3109 if (unlikely(!_n)) { \
3114 _n = talloc_strdup_append_buffer(_in, ", "); \
3115 if (unlikely(!_n)) { \
3123 fr_sbuff_marker(&start, &our_in);
3135 if (
dict == dict_def)
continue;
3162static inline CC_HINT(always_inline)
3166 bool internal,
bool foreign,
3198 internal = foreign =
false;
3201 if (
dict_attr_search(&our_err,
out, initial, &our_in, tt, internal, foreign, func) < 0)
goto error;
3233 bool internal,
bool foreign)
3262 bool internal,
bool foreign)
3291 bool internal,
bool foreign)
3320 bool internal,
bool foreign)
3338 bool internal,
bool foreign)
3400#ifdef STATIC_ANALYZER
3405 &our_name, SIZE_MAX,
3425 if ((
size_t) (p -
buffer) == len) {
3435 namespace = dict_attr_namespace(parent);
3439 fr_sbuff_set_to_start(&our_name);
3445 if (
parent->flags.is_root) {
3456 fr_sbuff_set_to_start(&our_name);
3480 namespace = dict_attr_namespace(parent);
3489 if (
parent->flags.is_root) {
3522#ifdef WITH_VERIFY_PTR
3527 if (!da)
return NULL;
3553 if (!children)
return NULL;
3559 if ((
attr & 0xff) >= talloc_array_length(children))
return NULL;
3561 bin = children[
attr & 0xff];
3563 if (!bin)
return NULL;
3564 if (bin->attr ==
attr) {
3567 memcpy(&
out, &bin,
sizeof(bin));
3590 if (!da)
return NULL;
3668 if (
value->type != da->type)
return NULL;
3688 if (!dv)
return NULL;
3701 if (!
name)
return NULL;
3715 if (len < 0) len = strlen(
name);
3730 size_t found_len = 0;
3744 int len = (p -
name) + 1;
3751 fr_sbuff_next(&our_in);
3823 bool seen_alpha =
false;
3827 fr_sbuff_next(&our_in);
3839 fr_sbuff_set_to_start(&our_in);
3865 if (!
name)
return 0;
3906 for (p = sym_name, q = p + (
talloc_strlen(sym_name)); p < q; p++) *p = *p ==
'-' ?
'_' : *p;
3909 proto = dlsym(
dict->dl->handle, sym_name);
3916 if (!proto)
return 0;
3922 dict->proto = proto;
4019 if (found->
count == 0) {
4021 dependent,
dict->root->name);
4025 if (--found->
count == 0) {
4054 fprintf(stderr,
"DEPENDENTS FOR %s\n",
dict->root->name);
4070 if (!
dict->autoref)
return 0;
4080 for (i = 0; i < talloc_array_length(refd_list); i++) {
4082 fr_strerror_printf(
"failed freeing autoloaded protocol %s", refd_list[i]->root->name);
4087 TALLOC_FREE(
dict->autoref);
4098 if (
dict !=
dict->gctx->internal) {
4101 if (
dict->gctx->attr_protocol_encapsulation &&
dict->root) {
4107#ifdef STATIC_ANALYZER
4117 if (
dict->proto &&
dict->proto->free) {
4118 dict->proto->free();
4125 dict->in_protocol_by_name =
false;
4131 dict->in_protocol_by_num =
false;
4161 if (
dict ==
dict->gctx->internal) {
4162 dict->gctx->internal = NULL;
4163 dict->gctx->attr_protocol_encapsulation = NULL;
4180 fr_strerror_const(
"Initialise global dictionary ctx with fr_dict_global_ctx_init()");
4215 if (!
dict->vendors_by_name) {
4225 if (!
dict->vendors_by_num) {
4234 if (!
dict->autoref) {
4273 .type_size =
parent->root->flags.type_size,
4274 .length =
parent->root->flags.length,
4278 if (!
dict)
return NULL;
4329 if (!*
dict)
return 0;
4359 for (p = to_load; p->
out; p++) {
4368 "an entry to load the attribute \"%s\" is located in, and that "
4369 "the fr_dict_autoload_attr_t symbol name is correct", p->
name);
4399 for (p = to_load; p->
out; p++) {
4406 fr_strerror_printf(
"Autoloader autoloader can't resolve attribute \"%s\", dictionary not loaded", p->
name);
4408 "an entry to load the dictionary \"%s\" is located in, and that "
4409 "the fr_dict_autoload_t symbol name is correct", p->
name);
4413 if (!root || (root->dict != *p->
dict) || (p->
name[0] !=
'.')) {
4414 root = (*p->
dict)->root;
4417 if (p->
name[0] ==
'.') {
4420 fr_strerror_printf(
"Autoloader attribute \"%s\" not found in \"%s\" dictionary under attribute %s", p->
name,
4421 *p->
dict ? (*p->
dict)->
root->name :
"internal", root->name);
4435 if (da->type != p->
type) {
4436 fr_strerror_printf(
"Autoloader attribute \"%s\" should be type %s, but defined as type %s", da->name,
4444 if (p->
out) *(p->
out) = da;
4462 for (p = to_load; p->
out; p++) {
4473 if (strcmp(p->
proto,
"freeradius") == 0) {
4495 for (p = to_free; p->
out; p++) {
4498 if (!*p->
out)
continue;
4501 if (ret == 0) *p->
out = NULL;
4502 if (ret < 0)
return -1;
4639 bool still_loaded =
false;
4668 still_loaded =
true;
4831 dict->read_only =
true;
4836 dict->read_only =
true;
4854 fprintf(fp,
"gctx not initialised\n");
4858 fprintf(fp,
"gctx %p report\n",
dict_gctx);
4865 fprintf(fp,
"\t%s is referenced from %s count (%d)\n",
4874 fprintf(fp,
"\t%s is referenced from %s count (%d)\n",
4938 char const *p =
name, *end;
4939 bool unknown =
false;
4942 if (len < 0) len = strlen(
name);
4954 if ((len > 5) && (memcmp(
name,
"Attr-", 5) == 0)) unknown =
true;
4957 if ((*p ==
'.') && unknown) p++;
4981 char const *p =
name, *end;
4984 if (len < 0) len = strlen(
name);
4999 if (!alnum)
return 0;
5017 size_t len, i, start;
5023 if (!children)
return NULL;
5028 }
else if ((*prev)->next) {
5033 return (*prev)->next;
5040 start = (*prev)->attr & 0xff;
5041 if (start == 255)
return NULL;
5053 len = talloc_array_length(children);
5054 for (i = start; i < len; i++) {
5055 bin = &children[i & 0xff];
5057 if (*bin)
return *bin;
5075 len = talloc_array_length(children);
5076 for (i = 0; i < len; i++) {
5080 if (!children[i])
continue;
5082 for (bin = children[i]; bin; bin = bin->next) {
5084 if (ret < 0)
return ret;
5104 if ((!da->flags.is_root) && (da->depth == 0)) {
5105 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t %s vendor: %u, attr %u: "
5106 "Is not root, but depth is 0",
5111 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t %s vendor: %u, attr %u: "
5112 "Indicated depth (%u) greater than TLV stack depth (%d)",
5117 for (da_p = da; da_p; da_p = da_p->next) {
5121 for (i = da->depth, da_p = da; i >= 0; i--, da_p = da_p->parent) {
5123 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t %s vendor: %u, attr %u: "
5124 "Depth indicated there should be a parent, but parent is NULL",
5127 if (i != (
int)da_p->depth) {
5128 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t %s vendor: %u, attr %u: "
5129 "Depth out of sequence, expected %i, got %u",
5136 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t top of hierarchy was not at depth 0",
5152 "CONSISTENCY CHECK FAILED %s[%d]: %s missing 'children' extension",
5157 "CONSISTENCY CHECK FAILED %s[%d]: %s missing 'namespace' extension",
5192 if (child->parent ==
parent)
return true;
5194 if (child->flags.is_raw)
return true;
5224 if (child->dict !=
parent->dict) {
5229 return (ref && (ref->dict == child->dict));
5260 if (!da->flags.local)
return da;
5264 while (da->dict->next) {
5265 da = da->dict->next->root;
5289 (*da_p)->flags.type_size = 0;
5290 (*da_p)->flags.length = 0;
static int const char char buffer[256]
unsigned int fr_atexit_global_disarm(bool uctx_scope, fr_atexit_t func, void const *uctx)
Remove a specific global destructor (without executing it)
#define fr_atexit_global(_func, _uctx)
Add a free function to the global free list.
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
#define fr_fatal_assert_fail(_msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
#define FR_FAULT_LOG(_fmt,...)
#define fr_cond_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
size_t type
Length of type data.
size_t name_len
Allows for efficient name lookups when operating on partial buffers.
char const * name
of the attribute.
@ FR_DICT_ENUM_EXT_ATTR_REF
Reference to a child attribute associated with this key value.
char const * name
Vendor name.
fr_dict_attr_t const ** attr
The protocol dictionary the attribute should be resolved in.
fr_dict_t const * fr_dict_by_da(fr_dict_attr_t const *da)
Attempt to locate the protocol dictionary containing an attribute.
unsigned int is_root
Is root of a dictionary.
#define fr_dict_autofree(_to_free)
fr_dict_attr_t const * fr_dict_attr_common_parent(fr_dict_attr_t const *a, fr_dict_attr_t const *b, bool is_ancestor)
Find a common ancestor that two TLV type attributes share.
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.
int fr_dict_internal_afrom_file(fr_dict_t **out, char const *dict_subdir, char const *dependent))
(Re-)Initialize the special internal dictionary
fr_value_box_t const ** out
Enumeration value.
fr_dict_t const ** dict
The protocol dictionary the attribute should be resolved in.
int(* fr_dict_walk_t)(fr_dict_attr_t const *da, void *uctx)
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
struct fr_dict_protocol_t::@131 attr
char const * name
of the attribute.
fr_value_box_t const * value
Enum value (what name maps to).
uint32_t pen
Private enterprise number.
fr_type_t type
of the attribute. Mismatch is a fatal error.
int fr_dict_protocol_afrom_file(fr_dict_t **out, char const *proto_name, char const *proto_dir, char const *dependent))
(Re)-initialize a protocol dictionary
size_t length
Length of length data.
char const * base_dir
Directory structure beneath share.
@ FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC
Protocol specific extensions.
@ FR_DICT_ATTR_EXT_ENUMV
Enumeration values.
@ FR_DICT_ATTR_EXT_NAMESPACE
Attribute has its own namespace.
@ FR_DICT_ATTR_EXT_REF
Attribute references another attribute and/or dictionary.
@ FR_DICT_ATTR_EXT_VENDOR
Cached vendor pointer.
@ FR_DICT_ATTR_EXT_NAME
Name of the attribute.
@ FR_DICT_ATTR_EXT_CHILDREN
Attribute has children.
#define fr_dict_autoload(_to_load)
#define FR_DICT_MAX_TLV_STACK
Maximum TLV stack size.
fr_dict_attr_err_t
Errors returned by attribute lookup functions.
@ FR_DICT_ATTR_OK
No error.
@ FR_DICT_ATTR_NOTFOUND
Attribute couldn't be found.
@ FR_DICT_ATTR_EINVAL
Invalid arguments.
@ FR_DICT_ATTR_NO_CHILDREN
Child lookup in attribute with no children.
@ FR_DICT_ATTR_PARSE_ERROR
Attribute string couldn't be parsed.
@ FR_DICT_ATTR_INTERNAL_ERROR
Internal error occurred.
#define FR_DICT_ENUM_MAX_NAME_LEN
Maximum length of a enum value.
#define DICT_AUTOLOAD_TERMINATOR
char const * proto
The protocol dictionary name.
#define fr_dict_attr_is_key_field(_da)
char const * name
Enum name.
char const * name
name of this protocol
#define FR_DICT_VENDOR_MAX_NAME_LEN
Maximum length of a vendor name.
#define FR_DICT_ATTR_MAX_NAME_LEN
Maximum length of a attribute name.
unsigned int is_alias
This isn't a real attribute, it's a reference to to one.
fr_dict_attr_t const * da
the child structure referenced by this value of key
Specifies an attribute which must be present for the module to function.
Values of the encryption flags.
Specifies a dictionary which must be loaded/loadable for the module to function.
Specifies a value which must be present for the module to function.
Enum extension - Sub-struct or union pointer.
Value of an enumerated attribute.
Protocol-specific callbacks in libfreeradius-PROTOCOL.
size_t max_name_len
maximum length of a name
fr_dict_attr_t const * vendor
ancestor which has type FR_TYPE_VENDOR
fr_dict_attr_ref_type_t type
The state of the reference.
fr_hash_table_t * name_by_value
Lookup a name by value.
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
fr_hash_table_t * value_by_name
Lookup an enumeration value by name.
static fr_dict_attr_t const * fr_dict_attr_ref(fr_dict_attr_t const *da)
Return the reference associated with a group type attribute.
static bool fr_dict_attr_has_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
Return whether a da has a given extension or not.
@ FR_DICT_ATTR_REF_ALIAS
The attribute is an alias for another attribute.
@ FR_DICT_ATTR_REF_NONE
No ref set.
static uint32_t fr_dict_vendor_num_by_da(fr_dict_attr_t const *da)
Return the vendor number for an attribute.
Attribute extension - Holds children for an attribute.
Attribute extension - Holds enumeration values.
Attribute extension - Holds a hash table with the names of all children of this attribute.
Attribute extension - Holds a reference to an attribute in another dictionary.
Attribute extension - Cached vendor pointer.
static int dict_attr_ref_set(fr_dict_attr_t const *da, fr_dict_attr_t const *ref, fr_dict_attr_ref_type_t type)
static int dict_attr_children_set(fr_dict_attr_t const *da, fr_dict_attr_t const **children)
static fr_hash_table_t * dict_attr_namespace(fr_dict_attr_t const *da)
Return the namespace hash table associated with the attribute.
static int dict_attr_ref_null(fr_dict_attr_t const *da)
static int dict_attr_ext_copy_all(fr_dict_attr_t **da_out_p, fr_dict_attr_t const *da_in)
Copy all attribute extensions from one attribute to another.
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.
static fr_dict_attr_t const ** dict_attr_children(fr_dict_attr_t const *da)
static void * dict_attr_ext_alloc_size(fr_dict_attr_t **da_p, fr_dict_attr_ext_t ext, size_t ext_len)
Allocate an attribute extension of a particular size.
static void * dict_enum_ext_alloc(fr_dict_enum_value_t **enumv_p, fr_dict_enum_ext_t ext)
Allocate an enum extension.
static int dict_attr_ref_aset(fr_dict_attr_t **da_p, fr_dict_attr_t const *ref, fr_dict_attr_ref_type_t type)
static void * dict_attr_ext_alloc(fr_dict_attr_t **da_p, fr_dict_attr_ext_t ext)
Allocate an attribute extension.
void dict_hash_tables_finalise(fr_dict_t *dict)
Walk a dictionary finalising the hash tables in all attributes with a distinct namespace.
char * dict_dir_default
The default location for loading dictionaries if one wasn't provided.
fr_hash_table_t * protocol_by_name
Hash containing names of all the registered protocols.
#define dict_attr_alloc(_ctx, _parent, _name, _attr, _type, _args)
#define INTERNAL_IF_NULL(_dict, _ret)
Set the internal dictionary if none was provided.
fr_hash_table_t * protocol_by_num
Hash containing numbers of all the registered protocols.
fr_dict_attr_t * root
Root attribute of this dictionary.
dl_loader_t * dict_loader
for protocol validation
#define dict_attr_init(_da_p, _parent, _name, _attr, _type, _args)
Full initialisation functions.
char const * dependent
File holding the reference.
bool dict_attr_valid(fr_dict_attr_t *da)
Validate a new attribute definition.
#define dict_attr_init_name_only(_da_p, _parent, _name, _type, _args)
fr_dict_attr_t const * attr_protocol_encapsulation
int dict_attr_alias_add(fr_dict_attr_t const *parent, char const *alias, fr_dict_attr_t const *ref, bool from_public)
Add an alias to an existing attribute.
fr_dict_t * internal
Magic internal dictionary.
bool free_at_exit
This gctx will be freed on exit.
#define dict_attr_alloc_root(_ctx, _dict, _name, _attr, _args)
bool perm_check
Whether we should check dictionary file permissions as they're loaded.
int count
How many references are held by this file.
Optional arguments for initialising/allocating attributes.
Entry recording dictionary reference holders by file.
Entry in the filename list of files associated with this dictionary.
static fr_dict_protocol_t dict_proto_default
Default protocol rules set for every dictionary.
int fr_dl_dict_attr_autoload(UNUSED dl_t const *module, void *symbol, UNUSED void *user_ctx)
Callback to automatically resolve attributes and check the types are correct.
fr_dict_t * fr_dict_global_ctx_iter_next(fr_dict_global_ctx_iter_t *iter)
int fr_dict_attr_set_group(fr_dict_attr_t **da_p, fr_dict_attr_t const *ref)
int fr_dict_enum_add_name(fr_dict_attr_t *da, char const *name, fr_value_box_t const *value, bool coerce, bool takes_precedence)
Add a value name.
fr_slen_t fr_dict_attr_search_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_t const *dict_def, fr_sbuff_t *name, fr_sbuff_term_t const *tt, bool internal, bool foreign)
Locate a fr_dict_attr_t by its name in the top level namespace of a dictionary.
fr_dict_gctx_t * fr_dict_global_ctx_init(TALLOC_CTX *ctx, bool free_at_exit, char const *dict_dir)
Initialise the global protocol hashes.
int fr_dict_attr_add_initialised(fr_dict_attr_t *da)
A variant of fr_dict_attr_t that allows a pre-allocated, populated fr_dict_attr_t to be added.
ssize_t fr_dict_valid_oid_str(char const *name, ssize_t len)
int fr_dict_global_ctx_dir_set(char const *dict_dir)
Allow the default dict dir to be changed after initialisation.
fr_slen_t fr_dict_enum_name_from_substr(fr_sbuff_t *out, fr_sbuff_parse_error_t *err, fr_sbuff_t *in, fr_sbuff_term_t const *tt)
Extract an enumeration name from a string.
static int _dict_global_free_at_exit(void *uctx)
static uint32_t dict_protocol_num_hash(void const *data)
Hash a protocol number.
static uint32_t dict_vendor_name_hash(void const *data)
Wrap name hash function for fr_dict_vendor_t.
#define DICT_NAME_APPEND(_in, _dict)
static fr_cmp_ret_t dict_vendor_pen_cmp(void const *one, void const *two)
Compare two vendor numbers.
static int _dict_free(fr_dict_t *dict)
fr_dict_t * fr_dict_unconst(fr_dict_t const *dict)
Coerce to non-const.
static int dict_attr_init_common(char const *filename, int line, fr_dict_attr_t **da_p, fr_dict_attr_t const *parent, fr_type_t type, dict_attr_args_t const *args)
fr_dict_t const * fr_dict_by_da(fr_dict_attr_t const *da)
Attempt to locate the protocol dictionary containing an attribute.
int fr_dict_enum_autoload(fr_dict_enum_autoload_t const *to_load)
Process a dict_attr_autoload element to load/verify a dictionary attribute.
fr_dict_enum_value_t const * fr_dict_enum_iter_init(fr_dict_attr_t const *da, fr_dict_enum_iter_t *iter)
Iterate over all enumeration values for an attribute.
int _fr_dict_autofree(fr_dict_autoload_t const *to_free, char const *dependent)
Decrement the reference count on a previously loaded dictionary.
static int dict_autoref_free(fr_dict_t *dict)
int fr_dict_walk(fr_dict_attr_t const *da, fr_dict_walk_t callback, void *uctx)
fr_slen_t dict_by_protocol_substr(fr_dict_attr_err_t *err, fr_dict_t **out, fr_sbuff_t *name, fr_dict_t const *dict_def)
fr_dict_attr_t const * fr_dict_unlocal(fr_dict_attr_t const *da)
bool const fr_dict_attr_nested_allowed_chars[SBUFF_CHAR_CLASS]
Characters allowed in a nested dictionary attribute name.
fr_dict_attr_t const * fr_dict_attr_common_parent(fr_dict_attr_t const *a, fr_dict_attr_t const *b, bool is_ancestor)
Find a common ancestor that two TLV type attributes share.
static int dict_walk(fr_dict_attr_t const *da, fr_dict_walk_t callback, void *uctx)
Call the specified callback for da and then for all its children.
bool const fr_dict_attr_allowed_chars[SBUFF_CHAR_CLASS]
Characters allowed in a single dictionary attribute name.
fr_dict_attr_t * dict_attr_alloc_null(TALLOC_CTX *ctx, fr_dict_protocol_t const *proto)
Allocate a partially completed attribute.
int dict_attr_type_init(fr_dict_attr_t **da_p, fr_type_t type)
Initialise type specific fields within the dictionary attribute.
int dict_attr_parent_init(fr_dict_attr_t **da_p, fr_dict_attr_t const *parent)
Initialise fields which depend on a parent attribute.
static void dependent_debug(fr_dict_t *dict)
fr_dict_t const * fr_dict_proto_dict(fr_dict_t const *dict)
fr_dict_t * dict_alloc(TALLOC_CTX *ctx)
Allocate a new dictionary.
static uint32_t dict_vendor_pen_hash(void const *data)
Hash a vendor number.
static fr_cmp_ret_t dict_protocol_num_cmp(void const *one, void const *two)
Compare two protocol numbers.
static fr_cmp_ret_t dict_enum_value_cmp(void const *one, void const *two)
Compare two dictionary enum values.
int8_t fr_dict_attr_ordered_cmp(fr_dict_attr_t const *a, fr_dict_attr_t const *b)
Compare two attributes by total order.
fr_dict_protocol_t const * fr_dict_protocol(fr_dict_t const *dict)
Return the protocol descriptor for the dictionary.
fr_dict_attr_t * _dict_attr_alloc_root(char const *filename, int line, TALLOC_CTX *ctx, fr_dict_t const *dict, char const *name, int proto_number, dict_attr_args_t const *args)
Allocate a dictionary root attribute on the heap.
fr_dict_attr_t * _dict_attr_alloc(char const *filename, int line, TALLOC_CTX *ctx, fr_dict_attr_t const *parent, char const *name, int attr, fr_type_t type, dict_attr_args_t const *args)
Allocate a dictionary attribute on the heap.
int fr_dict_attr_acopy_local(fr_dict_attr_t const *dst, fr_dict_attr_t const *src)
void fr_dl_dict_autofree(UNUSED dl_t const *module, void *symbol, UNUSED void *user_ctx)
Callback to automatically free a dictionary when the module is unloaded.
fr_dict_autoload_talloc_t * _fr_dict_autoload_talloc(TALLOC_CTX *ctx, fr_dict_t const **out, char const *proto, char const *dependent)
Autoload a dictionary and bind the lifetime to a talloc chunk.
bool const fr_dict_enum_allowed_chars[SBUFF_CHAR_CLASS]
Characters allowed in enumeration value names.
bool fr_dict_compatible(fr_dict_t const *dict1, fr_dict_t const *dict2)
See if two dictionaries have the same end parent.
static fr_slen_t dict_attr_search_qualified(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_t const *dict_def, fr_sbuff_t *in, fr_sbuff_term_t const *tt, bool internal, bool foreign, dict_attr_resolve_func_t func)
Internal function for searching for attributes in multiple dictionaries.
bool dict_attr_can_have_children(fr_dict_attr_t const *da)
See if a fr_dict_attr_t can have children.
fr_dict_attr_t * fr_dict_attr_unconst(fr_dict_attr_t const *da)
Coerce to non-const.
fr_slen_t fr_dict_attr_by_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_attr_t const *parent, fr_sbuff_t *in, fr_sbuff_term_t const *tt)
Resolve an attribute using an OID string.
void fr_dict_attr_verify(char const *file, int line, fr_dict_attr_t const *da)
bool fr_dict_attr_can_contain(fr_dict_attr_t const *parent, fr_dict_attr_t const *child)
See if a structural da is allowed to contain another da.
void dict_attr_location_init(fr_dict_attr_t *da, char const *filename, int line)
Set where the dictionary attribute was defined.
fr_dict_t * dict_by_da(fr_dict_attr_t const *da)
Internal version of fr_dict_by_da.
fr_dict_t * fr_dict_global_ctx_iter_init(fr_dict_global_ctx_iter_t *iter)
Iterate protocols by name.
fr_slen_t fr_dict_attr_search_by_qualified_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_t const *dict_def, fr_sbuff_t *name, fr_sbuff_term_t const *tt, bool internal, bool foreign)
Locate a qualified fr_dict_attr_t by its name and a dictionary qualifier.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
fr_dict_attr_t const * fr_dict_vendor_da_by_num(fr_dict_attr_t const *vendor_root, uint32_t vendor_pen)
Return vendor attribute for the specified dictionary and pen.
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.
fr_dict_attr_t * dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr)
Internal version of fr_dict_attr_child_by_num.
void fr_dict_global_ctx_set(fr_dict_gctx_t const *gctx)
Set a new, active, global dictionary context.
int fr_dl_dict_autoload(UNUSED dl_t const *module, void *symbol, UNUSED void *user_ctx)
Callback to automatically load dictionaries required by modules.
fr_dict_attr_t * dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *name)
static uint32_t dict_attr_name_hash(void const *data)
Wrap name hash function for fr_dict_attr_t.
static int _fr_dict_autoload_talloc_free(fr_dict_autoload_talloc_t const *to_free)
Talloc destructor to automatically free dictionaries.
fr_dict_t * dict_by_protocol_num(unsigned int num)
Internal version of fr_dict_by_protocol_num.
static int dict_attr_acopy_child(fr_dict_t *dict, fr_dict_attr_t *dst, fr_dict_attr_t const *src, fr_dict_attr_t const *child)
fr_slen_t fr_dict_attr_search_by_qualified_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_t const *dict_def, fr_sbuff_t *in, fr_sbuff_term_t const *tt, bool internal, bool foreign)
Locate a qualified fr_dict_attr_t by a dictionary qualified OID string.
dl_t * fr_dict_dl(fr_dict_t const *dict)
static fr_slen_t dict_attr_search(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_t const *dict_def, fr_sbuff_t *in, fr_sbuff_term_t const *tt, bool internal, bool foreign, dict_attr_resolve_func_t func)
Internal function for searching for attributes in multiple dictionaries.
char const * fr_dict_enum_name_by_value(fr_dict_attr_t const *da, fr_value_box_t const *value)
Lookup the name of an enum value in a fr_dict_attr_t.
fr_dict_enum_value_t const * fr_dict_enum_iter_next(fr_dict_attr_t const *da, fr_dict_enum_iter_t *iter)
int fr_dict_enum_add_name_next(fr_dict_attr_t *da, char const *name)
Add an name to an integer attribute hashing the name for the integer value.
int dict_attr_child_add(fr_dict_attr_t *parent, fr_dict_attr_t *child)
Add a child to a parent.
static int dict_attr_children_init(fr_dict_attr_t **da_p)
Add a child/nesting extension to an attribute.
fr_dict_autoload_t load[2]
Autoloader def.
int fr_dict_free(fr_dict_t **dict, char const *dependent)
Decrement the reference count on a previously loaded dictionary.
fr_dict_enum_value_t const * fr_dict_enum_by_value(fr_dict_attr_t const *da, fr_value_box_t const *value)
Lookup the structure representing an enum value in a fr_dict_attr_t.
int dict_dependent_remove(fr_dict_t *dict, char const *dependent)
Decrement ref count for a dependent in a dictionary.
int fr_dict_oid_component_legacy(unsigned int *out, char const **oid)
Process a single OID component.
fr_slen_t fr_dict_enum_by_name_substr(fr_dict_enum_value_t **out, fr_dict_attr_t const *da, fr_sbuff_t *in)
void fr_dict_global_ctx_perm_check(fr_dict_gctx_t *gctx, bool enable)
Set whether we check dictionary file permissions.
void fr_dict_global_ctx_read_only(void)
Mark all dictionaries and the global dictionary ctx as read only.
int _dict_attr_init_name_only(char const *filename, int line, fr_dict_attr_t **da_p, fr_dict_attr_t const *parent, char const *name, fr_type_t type, dict_attr_args_t const *args)
Initialise fields in a dictionary attribute structure.
static fr_cmp_ret_t dict_vendor_name_cmp(void const *one, void const *two)
Compare two attribute names.
fr_dict_attr_t const * fr_dict_attr_by_oid(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *oid)
Resolve an attribute using an OID string.
int dict_vendor_add(fr_dict_t *dict, char const *name, unsigned int num)
Add a vendor to the dictionary.
static int _dict_global_free(fr_dict_gctx_t *gctx)
static fr_cmp_ret_t dict_enum_name_cmp(void const *one, void const *two)
Compare two dictionary attribute enum values.
static int dict_attr_enumv_init(fr_dict_attr_t **da_p)
Initialise a per-attribute enumeration table.
static fr_cmp_ret_t dict_attr_name_cmp(void const *one, void const *two)
Compare two attribute names.
int fr_dict_const_free(fr_dict_t const **dict, char const *dependent)
Decrement the reference count on a previously loaded dictionary.
int fr_dl_dict_enum_autoload(UNUSED dl_t const *module, void *symbol, UNUSED void *user_ctx)
Callback to automatically resolve enum values.
int fr_dict_attr_autoload(fr_dict_attr_autoload_t const *to_load)
Process a dict_attr_autoload element to load/verify a dictionary attribute.
fr_dict_t const * fr_dict_internal(void)
fr_slen_t fr_dict_by_protocol_substr(fr_dict_attr_err_t *err, fr_dict_t const **out, fr_sbuff_t *name, fr_dict_t const *dict_def)
Look up a protocol name embedded in another string.
int fr_dict_dependent_add(fr_dict_t const *dict, char const *dependent)
Manually increase the reference count for a dictionary.
fr_dict_t const * fr_dict_by_protocol_name(char const *name)
Lookup a protocol by its name.
static uint32_t dict_protocol_name_hash(void const *data)
Wrap name hash function for fr_dict_protocol_t.
int dict_attr_finalise(fr_dict_attr_t **da_p, char const *name)
Set remaining fields in a dictionary attribute before insertion.
bool fr_dict_is_read_only(fr_dict_t const *dict)
static uint32_t dict_hash_name(char const *name, size_t len)
Apply a simple (case insensitive) hashing function to the name of an attribute, vendor or protocol.
int fr_dict_attr_add_name_only(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, fr_type_t type, fr_dict_attr_flags_t const *flags)
Add an attribute to the dictionary.
int dict_attr_num_init(fr_dict_attr_t *da, unsigned int num)
Set the attribute number (if any)
static int dict_attr_namespace_init(fr_dict_attr_t **da_p)
Initialise a per-attribute namespace.
char const * fr_dict_global_ctx_dir(void)
int dict_attr_num_init_name_only(fr_dict_attr_t *da)
Set the attribute number (if any)
static fr_cmp_ret_t dict_protocol_name_cmp(void const *one, void const *two)
Compare two protocol names.
static int _dict_attr_free(fr_dict_attr_t *da)
int fr_dict_global_ctx_free(fr_dict_gctx_t const *gctx)
Explicitly free all data associated with a global dictionary context.
int dict_dlopen(fr_dict_t *dict, char const *name)
fr_dict_t * dict_by_protocol_name(char const *name)
Internal version of fr_dict_by_protocol_name.
int dict_attr_acopy_children(fr_dict_t *dict, fr_dict_attr_t *dst, fr_dict_attr_t const *src)
Copy the children of an existing attribute.
fr_dict_vendor_t const * fr_dict_vendor_by_name(fr_dict_t const *dict, char const *name)
Look up a vendor by its name.
int dict_attr_acopy_aliases(UNUSED fr_dict_attr_t *dst, fr_dict_attr_t const *src)
Copy aliases of an existing attribute to a new one.
fr_slen_t(* dict_attr_resolve_func_t)(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_attr_t const *parent, fr_sbuff_t *in, fr_sbuff_term_t const *tt)
Callback function for resolving dictionary attributes.
void fr_dict_gctx_debug(FILE *fp, fr_dict_gctx_t const *gctx)
Dump information about currently loaded dictionaries.
fr_dict_attr_t const * fr_dict_attr_iterate_children(fr_dict_attr_t const *parent, fr_dict_attr_t const **prev)
Iterate over children of a DA.
int dict_attr_enum_add_name(fr_dict_attr_t *da, char const *name, fr_value_box_t const *value, bool coerce, bool takes_precedence, fr_dict_attr_t const *key_child_ref)
int _fr_dict_autoload(fr_dict_autoload_t const *to_load, char const *dependent)
Process a dict_autoload element to load a protocol.
fr_dict_vendor_t const * fr_dict_vendor_by_num(fr_dict_t const *dict, uint32_t vendor_pen)
Look up a vendor by its PEN.
int dict_attr_alias_add(fr_dict_attr_t const *parent, char const *alias, fr_dict_attr_t const *ref, bool from_public)
Add an alias to an existing attribute.
fr_slen_t fr_dict_attr_search_by_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_t const *dict_def, fr_sbuff_t *in, fr_sbuff_term_t const *tt, bool internal, bool foreign)
Locate a qualified fr_dict_attr_t by a dictionary using a non-qualified OID string.
ssize_t fr_dict_valid_name(char const *name, ssize_t len)
#define DICT_ATTR_ALLOWED_CHARS
fr_dict_t * fr_dict_protocol_alloc(fr_dict_t const *parent)
Allocate a new local dictionary.
ssize_t fr_dict_attr_by_oid_legacy(fr_dict_attr_t const **parent, unsigned int *attr, char const *oid)
Get the leaf attribute of an OID string.
fr_dict_attr_t const * fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *name)
Locate a fr_dict_attr_t by its name.
fr_slen_t fr_dict_attr_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_attr_t const *parent, fr_sbuff_t *name, UNUSED fr_sbuff_term_t const *tt)
Look up a dictionary attribute by a name embedded in another string.
static fr_cmp_ret_t _dict_dependent_cmp(void const *a, void const *b)
Find a dependent in the tree of dependents.
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.
int dict_dependent_add(fr_dict_t *dict, char const *dependent)
Record a new dependency on a dictionary.
fr_dict_enum_value_t const * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
static int dict_attr_name_set(fr_dict_attr_t **da_p, char const *name)
Set a dictionary attribute's name.
fr_slen_t fr_dict_oid_component(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_attr_t const *parent, fr_sbuff_t *in, fr_sbuff_term_t const *tt)
Parse an OID component, resolving it to a defined attribute.
static int dict_attr_vendor_set(fr_dict_attr_t **da_p, fr_dict_attr_t const *vendor)
Cache the vendor pointer for an attribute.
static uint32_t dict_enum_name_hash(void const *data)
Hash a enumeration name.
int dict_protocol_add(fr_dict_t *dict)
Add a protocol to the global protocol table.
static uint32_t dict_enum_value_hash(void const *data)
Hash a dictionary enum value.
fr_dict_attr_t const * fr_dict_attr_search_by_qualified_oid(fr_dict_attr_err_t *err, fr_dict_t const *dict_def, char const *name, bool internal, bool foreign)
Locate a qualified fr_dict_attr_t by its name and a dictionary qualifier.
bool dict_has_dependents(fr_dict_t *dict)
Check if a dictionary still has dependents.
fr_dict_gctx_t * dict_gctx
Top level structure containing global dictionary state.
fr_dict_t const * fr_dict_by_protocol_num(unsigned int num)
Lookup a protocol by its number.
int dict_attr_acopy_enumv(fr_dict_attr_t *dst, fr_dict_attr_t const *src)
Copy the VALUEs of an existing attribute, by casting them.
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.
char const * dependent
Dependent that loaded the dictionary.
static fr_dict_attr_t const * dict_attr_alias(fr_dict_attr_err_t *err, fr_dict_attr_t const *da)
Resolve an alias attribute to the concrete attribute it points to.
fr_dict_vendor_t const * fr_dict_vendor_by_da(fr_dict_attr_t const *da)
Look up a vendor by one of its child attributes.
fr_dict_attr_t * dict_attr_acopy(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, fr_dict_attr_t const *in, char const *name)
Copy a an existing attribute, possibly to a new location.
int _dict_attr_init(char const *filename, int line, fr_dict_attr_t **da_p, fr_dict_attr_t const *parent, char const *name, unsigned int attr, fr_type_t type, dict_attr_args_t const *args)
Initialise fields in a dictionary attribute structure.
Structure used to managed the lifetime of a dictionary.
dl_loader_t * dl_loader_init(TALLOC_CTX *ctx, void *uctx, bool uctx_free, bool defer_symbol_init)
Initialise structures needed by the dynamic linker.
int dl_free(dl_t const *dl)
"free" a dl handle, possibly actually freeing it, and unloading the library
dl_t * dl_by_name(dl_loader_t *dl_loader, char const *name, void *uctx, bool uctx_free)
Search for a dl's shared object in various locations.
#define fr_dlist_talloc_init(_head, _type, _field)
Initialise the head structure of a doubly linked list.
void * fr_hash_table_iter_next(fr_hash_table_t *ht, fr_hash_iter_t *iter)
Iterate over entries in a hash table.
int fr_hash_table_find(void **found, fr_hash_table_t *ht, void const *data)
Find data in a hash table.
void * fr_hash_table_iter_init(fr_hash_table_t *ht, fr_hash_iter_t *iter)
Initialise an iterator.
uint32_t fr_hash(void const *data, size_t size)
int fr_hash_table_flatten(TALLOC_CTX *ctx, void **out[], fr_hash_table_t *ht)
Copy all entries out of a hash table into an array.
int fr_hash_table_delete(fr_hash_table_t *ht, void const *data)
Remove and free data (if a free function was specified)
uint32_t fr_hash_string(char const *p)
void fr_hash_table_verify(fr_hash_table_t *ht)
Check hash table is sane.
int fr_hash_table_replace(void **old, fr_hash_table_t *ht, void const *data)
Replace old data with new data, OR insert if there is no old.
uint32_t fr_hash_table_num_elements(fr_hash_table_t *ht)
int fr_hash_table_insert(fr_hash_table_t *ht, void const *data)
Insert data into a hash table.
#define fr_hash_table_alloc(_ctx, _hash_node, _cmp_node, _free_node)
#define fr_hash_table_talloc_alloc(_ctx, _type, _hash_node, _cmp_node, _free_node)
Stores the state of the current iteration operation.
@ FR_TYPE_TIME_DELTA
A period of time measured in nanoseconds.
@ FR_TYPE_INT8
8 Bit signed integer.
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_INT64
64 Bit signed integer.
@ FR_TYPE_INT16
16 Bit signed integer.
@ FR_TYPE_DATE
Unix time stamp, always has value >2^31.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_STRUCT
like TLV, but without T or L, and fixed-width children
@ FR_TYPE_INT32
32 Bit signed integer.
@ FR_TYPE_VENDOR
Attribute that represents a vendor in the attribute tree.
@ FR_TYPE_UINT64
64 Bit unsigned integer.
@ FR_TYPE_VSA
Vendor-Specific, for RADIUS attribute 26.
@ FR_TYPE_OCTETS
Raw octets.
@ FR_TYPE_GROUP
A grouping of other attributes.
ssize_t fr_sbuff_out_bstrncpy_exact(fr_sbuff_t *out, fr_sbuff_t *in, size_t len)
size_t fr_sbuff_out_bstrncpy_allowed(fr_sbuff_t *out, fr_sbuff_t *in, size_t len, bool const allowed[static SBUFF_CHAR_CLASS])
@ FR_SBUFF_PARSE_ERROR_NUM_OVERFLOW
Integer type would overflow.
@ FR_SBUFF_PARSE_ERROR_NOT_FOUND
String does not contain a token matching the output type.
@ FR_SBUFF_PARSE_ERROR_FORMAT
Format of data was invalid.
@ FR_SBUFF_PARSE_OK
No error.
@ FR_SBUFF_PARSE_ERROR_TRAILING
Trailing characters found.
fr_cmp_ret_t
Result of an ordering comparison.
int strncasecmp(char *s1, char *s2, int n)
int strcasecmp(char *s1, char *s2)
uint32_t fr_rb_num_elements(fr_rb_tree_t *tree)
Return how many nodes there are in a tree.
int fr_rb_find(void **found, fr_rb_tree_t const *tree, void const *data)
Find an element in the tree, returning the data, not the node.
void * fr_rb_iter_init_inorder(fr_rb_tree_t *tree, fr_rb_iter_inorder_t *iter)
Initialise an in-order iterator.
int fr_rb_delete(fr_rb_tree_t *tree, void const *data)
Remove node and free data (if a free function was specified)
int fr_rb_insert(fr_rb_tree_t *tree, void const *data)
Insert data into a tree.
void * fr_rb_iter_next_inorder(UNUSED fr_rb_tree_t *tree, fr_rb_iter_inorder_t *iter)
Return the next node.
#define fr_rb_inline_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black tree.
Iterator structure for in-order traversal of an rbtree.
static unsigned int hash(char const *username, unsigned int tablesize)
size_t fr_sbuff_adv_past_allowed(fr_sbuff_t *sbuff, size_t len, bool const allowed[static SBUFF_CHAR_CLASS], fr_sbuff_term_t const *tt)
Wind position past characters in the allowed set.
bool fr_sbuff_is_terminal(fr_sbuff_t *in, fr_sbuff_term_t const *tt)
Efficient terminal string search.
bool const sbuff_char_alpha_num[SBUFF_CHAR_CLASS]
size_t fr_sbuff_adv_until(fr_sbuff_t *sbuff, size_t len, fr_sbuff_term_t const *tt, char escape_chr)
Wind position until we hit a character in the terminal set.
fr_table_num_ordered_t const sbuff_parse_error_table[]
ssize_t fr_sbuff_in_sprintf(fr_sbuff_t *sbuff, char const *fmt,...)
Print using a fmt string to an sbuff.
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_set(_dst, _src)
#define FR_SBUFF_IN(_start, _len_or_end)
#define fr_sbuff_current(_sbuff_or_marker)
#define fr_sbuff_char(_sbuff_or_marker, _eob)
#define fr_sbuff_is_alpha(_sbuff_or_marker)
#define fr_sbuff_buff(_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_init_in(_out, _start, _len_or_end)
#define fr_sbuff_remaining(_sbuff_or_marker)
#define fr_sbuff_len(_sbuff_or_marker)
#define FR_SBUFF_OUT(_start, _len_or_end)
#define fr_sbuff_used(_sbuff_or_marker)
#define fr_sbuff_behind(_sbuff_or_marker)
Set of terminal elements.
fr_aka_sim_id_type_t type
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
#define talloc_get_type_abort_const
static int talloc_const_free(void const *ptr)
Free const'd memory.
static void talloc_bstr_tolower(char *str)
Convert a talloced string to lowercase.
#define talloc_strdup(_ctx, _str)
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
#define add(_type, _out, _in)
char const * fr_strerror(void)
Get the last library error.
#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)
bool const fr_type_fixed_size[FR_TYPE_MAX+1]
bool const fr_type_structural[FR_TYPE_MAX+1]
#define fr_type_is_non_leaf(_x)
#define fr_type_is_variable_size(_x)
#define fr_type_is_structural(_x)
@ FR_TYPE_UNION
A union of limited children.
#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.
fr_cmp_ret_t fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b)
Compare two values.
size_t fr_value_box_network_length(fr_value_box_t const *value)
Get the size of the value held by the fr_value_box_t.
uint32_t fr_value_box_hash(fr_value_box_t const *vb)
Hash the contents of a value box.
int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert one type of fr_value_box_t to another.
int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src)
Copy value data verbatim duplicating any buffers.
int fr_value_box_cmp_op(fr_token_t op, fr_value_box_t const *a, fr_value_box_t const *b)
Compare two attributes using an operator.
void fr_value_box_increment(fr_value_box_t *vb)
Increment a boxed value.
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
#define fr_box_strvalue_len(_val, _len)
#define fr_value_box_init(_vb, _type, _enumv, _tainted)
Initialise a fr_value_box_t.
static size_t char ** out