24RCSID(
"$Id: 087a610540a2d1b2089d0ba833d0a1e98af4218c $")
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/dict_ext.h>
34#include <freeradius-devel/util/dlist.h>
35#include <freeradius-devel/util/hash.h>
36#include <freeradius-devel/util/proto.h>
37#include <freeradius-devel/util/rand.h>
38#include <freeradius-devel/util/sbuff.h>
39#include <freeradius-devel/util/syserror.h>
40#include <freeradius-devel/util/talloc.h>
52 [
'-'] =
true, [
'/'] =
true, [
'_'] =
true,
53 [
'0'] =
true, [
'1'] =
true, [
'2'] =
true, [
'3'] =
true, [
'4'] =
true,
54 [
'5'] =
true, [
'6'] =
true, [
'7'] =
true, [
'8'] =
true, [
'9'] =
true,
55 [
'A'] =
true, [
'B'] =
true, [
'C'] =
true, [
'D'] =
true, [
'E'] =
true,
56 [
'F'] =
true, [
'G'] =
true, [
'H'] =
true, [
'I'] =
true, [
'J'] =
true,
57 [
'K'] =
true, [
'L'] =
true, [
'M'] =
true, [
'N'] =
true, [
'O'] =
true,
58 [
'P'] =
true, [
'Q'] =
true, [
'R'] =
true, [
'S'] =
true, [
'T'] =
true,
59 [
'U'] =
true, [
'V'] =
true, [
'W'] =
true, [
'X'] =
true, [
'Y'] =
true,
61 [
'a'] =
true, [
'b'] =
true, [
'c'] =
true, [
'd'] =
true, [
'e'] =
true,
62 [
'f'] =
true, [
'g'] =
true, [
'h'] =
true, [
'i'] =
true, [
'j'] =
true,
63 [
'k'] =
true, [
'l'] =
true, [
'm'] =
true, [
'n'] =
true, [
'o'] =
true,
64 [
'p'] =
true, [
'q'] =
true, [
'r'] =
true, [
's'] =
true, [
't'] =
true,
65 [
'u'] =
true, [
'v'] =
true, [
'w'] =
true, [
'x'] =
true, [
'y'] =
true,
73 [
'+'] =
true, [
'-'] =
true, [
'.'] =
true, [
'/'] =
true, [
'_'] =
true,
74 [
'0'] =
true, [
'1'] =
true, [
'2'] =
true, [
'3'] =
true, [
'4'] =
true,
75 [
'5'] =
true, [
'6'] =
true, [
'7'] =
true, [
'8'] =
true, [
'9'] =
true,
76 [
'A'] =
true, [
'B'] =
true, [
'C'] =
true, [
'D'] =
true, [
'E'] =
true,
77 [
'F'] =
true, [
'G'] =
true, [
'H'] =
true, [
'I'] =
true, [
'J'] =
true,
78 [
'K'] =
true, [
'L'] =
true, [
'M'] =
true, [
'N'] =
true, [
'O'] =
true,
79 [
'P'] =
true, [
'Q'] =
true, [
'R'] =
true, [
'S'] =
true, [
'T'] =
true,
80 [
'U'] =
true, [
'V'] =
true, [
'W'] =
true, [
'X'] =
true, [
'Y'] =
true,
82 [
'a'] =
true, [
'b'] =
true, [
'c'] =
true, [
'd'] =
true, [
'e'] =
true,
83 [
'f'] =
true, [
'g'] =
true, [
'h'] =
true, [
'i'] =
true, [
'j'] =
true,
84 [
'k'] =
true, [
'l'] =
true, [
'm'] =
true, [
'n'] =
true, [
'o'] =
true,
85 [
'p'] =
true, [
'q'] =
true, [
'r'] =
true, [
's'] =
true, [
't'] =
true,
86 [
'u'] =
true, [
'v'] =
true, [
'w'] =
true, [
'x'] =
true, [
'y'] =
true,
98 .default_type_size = 2,
99 .default_type_length = 2,
107#define FNV_MAGIC_INIT (0x811c9dc5)
108#define FNV_MAGIC_PRIME (0x01000193)
126 char const *p =
name, *q =
name + len;
129 int c = *(
unsigned char const *)p;
130 if (isalpha(c)) c = tolower(c);
164 ret =
strcasecmp(a->root->name, b->root->name);
184 return CMP(a->root->attr, b->root->attr);
325 if (!da->flags.is_alias)
return da;
350 char *name_start, *name_end;
365 name_len = strlen(
name);
380 if (!name_start)
return -1;
382 name_end = name_start + name_len;
384 memcpy(name_start,
name, name_len);
387 (*da_p)->name = name_start;
388 (*da_p)->name_len = name_len;
445 if (!p_ext)
return 1;
497 if (!ext->namespace) {
500 if (!ext->namespace) {
526 if (
unlikely((*da_p)->state.finalised ==
true)) {
559 (*da_p)->last_child_attr = (1 << 24);
586 (*da_p)->flags.length = 4;
593 (*da_p)->flags.is_known_width = ((*da_p)->flags.length != 0);
600 (*da_p)->type =
type;
619 fr_strerror_const(
"Attribute type must be set before initialising parent. Use dict_attr_type_init() first");
624 fr_strerror_printf(
"Attempting to set parent for '%s' to '%s', but parent already set to '%s'",
625 da->name,
parent->name, da->parent->name);
629 if (
unlikely((*da_p)->state.finalised ==
true)) {
630 fr_strerror_printf(
"Attempting to set parent for '%s' to '%s', but attribute already finalised",
637 da->depth =
parent->depth + 1;
646 if (ret < 0)
return -1;
667 if (da->state.attr_set) {
672 da->state.attr_set =
true;
686 fr_strerror_const(
"Attribute must have parent set before automatically setting attribute number");
697 da->filename = filename;
731 da->flags.is_known_width |= da->flags.array;
774 (*da_p)->state.finalised =
true;
779static inline CC_HINT(always_inline)
793 if (
args->flags) (*da_p)->flags = *
args->flags;
827 char const *
name,
unsigned int attr,
876 (*da_p)->flags.name_only =
true;
888#ifdef WITH_VERIFY_PTR
932 if (proto->
attr.flags.len > 0) {
934 proto->
attr.flags.len) == NULL)) {
961 char const *
name,
int proto_number,
995 char const *
name,
int attr,
1066 if (!dst->flags.local) {
1074 if (src->flags.local) {
1096 uint depth_diff = dst->depth - src->depth;
1105 if (child->dict == dict) {
1116 copy->depth += depth_diff;
1135 if (cloned < 0)
return -1;
1210 self->dict =
parent->dict;
1214 namespace = dict_attr_namespace(parent);
1242 if (!dict->root)
return -1;
1249 fr_strerror_printf(
"%s: Failed inserting protocol name %s", __FUNCTION__, dict->root->name);
1253 if ((strcmp(old_proto->root->name, dict->root->name) == 0) &&
1254 (old_proto->root->name == dict->root->name)) {
1255 fr_strerror_printf(
"%s: Duplicate protocol name %s", __FUNCTION__, dict->root->name);
1261 dict->in_protocol_by_name =
true;
1264 fr_strerror_printf(
"%s: Duplicate protocol number %u", __FUNCTION__, dict->root->attr);
1267 dict->in_protocol_by_num =
true;
1286 dict->root->name, dict->root->attr,
FR_TYPE_GROUP, &flags) < 0) {
1334 if (!vendor->
name) {
1349 if ((strcmp(old_vendor->
name, vendor->
name) == 0) && (old_vendor->
pen != vendor->
pen)) {
1466 if (!
parent->flags.is_root &&
parent->flags.name_only &&
1500 for (bin = &children[child->attr & 0xff]; *bin; bin = &(*bin)->next) {
1508 if (child_is_struct && !bin_is_struct)
break;
1510 if (child->attr <= (*bin)->attr)
break;
1513 memcpy(&
this, &bin,
sizeof(
this));
1514 child->next = *
this;
1532 namespace = dict_attr_namespace(parent);
1564 if (a && (
strcasecmp(a->name, da->name) == 0)) {
1565 if ((a->attr != da->attr) || (a->type != da->type) || (a->parent != da->parent)) {
1567 "Originally defined %s[%d]",
1569 a->filename, a->line);
1598 if (
unlikely(da->dict->read_only)) {
1603 if (
unlikely(da->state.finalised ==
false)) {
1626 "Originally defined %s[%d]", da->name, da->parent->name,
1627 exists->filename, exists->line);
1636 if (da->flags.name_only) {
1637 if (da->state.attr_set) {
1640 if (da->attr > da->parent->last_child_attr) {
1641 parent->last_child_attr = da->attr;
1650 if ((da->attr >= (((uint64_t)1) << (8 *
parent->flags.type_size)))) da->flags.internal =
true;
1665 "Originally defined by '%s' at %s[%d]",
1666 da->attr, exists->name, exists->filename, exists->line);
1689 fr_strerror_printf(
"FATAL - Failed to find attribute number %u we just added to parent '%s'", da->attr, da->parent->name);
1694 fr_strerror_printf(
"FATAL - Failed to find attribute '%s' we just added to parent '%s'", da->name, da->parent->name);
1758 bool coerce,
bool takes_precedence,
1786 fr_strerror_const(
"Child structures cannot be defined for VALUEs which are not for 'key' attributes");
1795 if (da->flags.is_alias) {
1840 if (child_struct) enumv->
child_struct[0] = child_struct;
1842 if (!enum_value)
goto oom;
1844 if (da->type !=
value->type) {
1866 enumv->
value = enum_value;
1873 memcpy(&tmp, &enumv,
sizeof(tmp));
1892 "Old value was \"%pV\", new value was \"%pV\"",
name, da->name,
1905 if (takes_precedence) {
1947 bool coerce,
bool takes_precedence)
2002 fr_strerror_printf(
"Attribute is wrong type for auto-numbering, expected numeric type, got %s",
2046 if (!a || !b)
return NULL;
2048 if (is_ancestor && (b->depth <= a->depth))
return NULL;
2053 if (a->depth > b->depth) {
2055 for (p_a = a, i = a->depth - b->depth; p_a && (i > 0); p_a = p_a->parent, i--);
2056 if (is_ancestor && (p_a != p_b))
return NULL;
2057 }
else if (a->depth < b->depth) {
2059 for (p_b = b, i = b->depth - a->depth; p_b && (i > 0); p_b = p_b->parent, i--);
2060 if (is_ancestor && (p_a != p_b))
return NULL;
2066 while (p_a && p_b) {
2067 if (p_a == p_b)
return p_a;
2086 char const *p = *oid;
2092 num = strtoul(p, &q, 10);
2093 if ((p == q) || (num == ULONG_MAX)) {
2102 *
out = (
unsigned int)num;
2131 char const *p = oid;
2132 unsigned int num = 0;
2155 switch ((*parent)->type) {
2161 fr_strerror_printf(
"Attribute %s (%u) is not a TLV, so cannot contain a child attribute. "
2162 "Error at sub OID \"%s\"", (*parent)->name, (*parent)->attr, oid);
2172 (num > ((uint64_t) 1 << (8 * (*parent)->flags.type_size)))) {
2173 fr_strerror_printf(
"TLV attributes must be %" PRIu64
" bits or less", ((uint64_t)1 << (8 * (*parent)->flags.type_size)));
2190 num, oid, (*parent)->name);
2202 if (slen <= 0)
return slen - (p - oid);
2203 return slen + (p - oid);
2253 "Error at OID \"%.*s\"",
2269 fr_sbuff_set_to_start(&our_in);
2336 fr_sbuff_marker(&m_c, &our_in);
2411 return dict->read_only;
2436 memset(&root, 0,
sizeof(root));
2443 &our_name, SIZE_MAX,
2465 if (*(our_name.
p) && (*(our_name.
p) !=
'.')) {
2466 memcpy(
out, &dict_def,
sizeof(*
out));
2474 if (
strcasecmp(root.name,
"internal") != 0) {
2476 memcpy(
out, &dict_def,
sizeof(*
out));
2477 fr_sbuff_set_to_start(&our_name);
2517 &(
fr_dict_t){ .root = &(fr_dict_attr_t){ .name = name } });
2531 &(
fr_dict_t) { .root = &(fr_dict_attr_t){ .attr = num } });
2548 while (da_p->parent) {
2549 da_p = da_p->parent;
2551 "Expected %s, got %s",
2552 !da_p->dict ?
"(null)" :
fr_dict_root(da_p->dict)->name,
2557 if (!da_p->flags.is_root) {
2559 __FUNCTION__, da->name);
2569 return talloc_get_type_abort(da->dict,
fr_dict_t);
2625 while (dict1->next) dict1 = dict1->next;
2627 while (dict2->next) dict2 = dict2->next;
2629 return (dict1 == dict2);
2645 if (!dv.
pen)
return NULL;
2667 if (!
name)
return 0;
2670 if (!found)
return 0;
2703 switch (vendor_root->type) {
2763static inline CC_HINT(always_inline)
2767 bool internal,
bool foreign,
2780 if (
unlikely(!internal && !foreign && !dict_def)) {
2796 if (!internal && !foreign)
goto error;
2814 if (!foreign)
goto error;
2828 if (dict == dict_def)
continue;
2854#define DICT_NAME_APPEND(_in, _dict) \
2857 _n = talloc_strdup_append_buffer(_in, fr_dict_root(_dict)->name); \
2858 if (unlikely(!_n)) { \
2863 _n = talloc_strdup_append_buffer(_in, ", "); \
2864 if (unlikely(!_n)) { \
2872 fr_sbuff_marker(&start, &our_in);
2874 list = talloc_strdup(NULL,
"");
2884 if (dict == dict_def)
continue;
2911static inline CC_HINT(always_inline)
2915 bool internal,
bool foreign,
2947 internal = foreign =
false;
2950 if (
dict_attr_search(&our_err,
out, initial, &our_in, tt, internal, foreign, func) < 0)
goto error;
2982 bool internal,
bool foreign)
3011 bool internal,
bool foreign)
3040 bool internal,
bool foreign)
3069 bool internal,
bool foreign)
3087 bool internal,
bool foreign)
3149#ifdef STATIC_ANALYZER
3154 &our_name, SIZE_MAX,
3174 if ((
size_t) (p -
buffer) == len) {
3184 namespace = dict_attr_namespace(parent);
3188 fr_sbuff_set_to_start(&our_name);
3194 if (
parent->flags.is_root) {
3198 parent = dict->next->root;
3205 fr_sbuff_set_to_start(&our_name);
3229 namespace = dict_attr_namespace(parent);
3238 if (
parent->flags.is_root) {
3242 parent = dict->next->root;
3274 if (!da)
return NULL;
3300 if (!children)
return NULL;
3306 if ((attr & 0xff) > talloc_array_length(children))
return NULL;
3308 bin = children[attr & 0xff];
3310 if (!bin)
return NULL;
3311 if (bin->attr == attr) {
3314 memcpy(&
out, &bin,
sizeof(bin));
3337 if (!da)
return NULL;
3373 if (
value->type != da->type)
return NULL;
3391 if (!dv)
return NULL;
3403 if (!
name)
return NULL;
3417 if (len < 0) len = strlen(
name);
3430 size_t found_len = 0;
3444 int len = (p -
name) + 1;
3451 fr_sbuff_next(&our_in);
3523 bool seen_alpha =
false;
3527 fr_sbuff_next(&our_in);
3539 fr_sbuff_set_to_start(&our_in);
3565 if (!
name)
return 0;
3607 for (p = sym_name, q = p + (talloc_array_length(sym_name) - 1); p < q; p++) *p = *p ==
'-' ?
'_' : *p;
3610 proto = dlsym(dict->dl->handle, sym_name);
3617 if (!proto)
return 0;
3623 dict->proto = proto;
3716 fr_strerror_printf(
"Dependent \"%s\" not found in dictionary \"%s\"", dependent, dict->root->name);
3720 if (found->
count == 0) {
3722 dependent, dict->root->name);
3726 if (--found->
count == 0) {
3755 fprintf(stderr,
"DEPENDENTS FOR %s\n", dict->root->name);
3771 if (!dict->autoref)
return 0;
3781 for (i = 0; i < talloc_array_length(refd_list); i++) {
3782 if (
fr_dict_free(&refd_list[i], dict->root->name) < 0) {
3783 fr_strerror_printf(
"failed freeing autoloaded protocol %s", refd_list[i]->root->name);
3788 TALLOC_FREE(dict->autoref);
3799 if (dict != dict->gctx->internal) {
3802 if (dict->gctx->attr_protocol_encapsulation && dict->root) {
3808#ifdef STATIC_ANALYZER
3818 if (dict->proto && dict->proto->free) {
3819 dict->proto->free();
3823 fr_strerror_printf(
"Failed removing dictionary from protocol hash \"%s\"", dict->root->name);
3826 dict->in_protocol_by_name =
false;
3829 fr_strerror_printf(
"Failed removing dictionary from protocol number_hash \"%s\"", dict->root->name);
3832 dict->in_protocol_by_num =
false;
3838 fr_strerror_printf(
"Refusing to free dictionary \"%s\", still has dependents", dict->root->name);
3862 if (dict == dict->gctx->internal) {
3863 dict->gctx->internal = NULL;
3864 dict->gctx->attr_protocol_encapsulation = NULL;
3881 fr_strerror_const(
"Initialise global dictionary ctx with fr_dict_global_ctx_init()");
3916 if (!dict->vendors_by_name) {
3926 if (!dict->vendors_by_num) {
3935 if (!dict->autoref) {
3979 if (!dict)
return NULL;
3995 dict->root->dict = dict;
4030 if (!*dict)
return 0;
4060 for (p = to_load; p->
out; p++) {
4069 "an entry to load the attribute \"%s\" is located in, and that "
4070 "the fr_dict_autoload_attr_t symbol name is correct", p->
name);
4099 for (p = to_load; p->
out; p++) {
4106 fr_strerror_printf(
"Autoloader autoloader can't resolve attribute \"%s\", dictionary not loaded", p->
name);
4108 "an entry to load the dictionary \"%s\" is located in, and that "
4109 "the fr_dict_autoload_t symbol name is correct", p->
name);
4120 if (da->type != p->
type) {
4121 fr_strerror_printf(
"Autoloader attribute \"%s\" should be type %s, but defined as type %s", da->name,
4129 if (p->
out) *(p->
out) = da;
4147 for (p = to_load; p->
out; p++) {
4158 if (strcmp(p->
proto,
"freeradius") == 0) {
4180 for (p = to_free; p->
out; p++) {
4183 if (!*p->
out)
continue;
4186 if (ret == 0) *p->
out = NULL;
4187 if (ret < 0)
return -1;
4241 dict_ref->
dependent = talloc_strdup(dict_ref, dependent);
4324 bool still_loaded =
false;
4338 (void)talloc_get_type_abort(dict,
fr_dict_t);
4346 (void)talloc_get_type_abort(dict,
fr_dict_t);
4353 still_loaded =
true;
4521 dict->read_only =
true;
4526 dict->read_only =
true;
4626 char const *p =
name, *end;
4627 bool unknown =
false;
4630 if (len < 0) len = strlen(
name);
4642 if ((len > 5) && (memcmp(
name,
"Attr-", 5) == 0)) unknown =
true;
4645 if ((*p ==
'.') && unknown) p++;
4669 char const *p =
name, *end;
4672 if (len < 0) len = strlen(
name);
4687 if (!alnum)
return 0;
4705 size_t len, i, start;
4707 if (!
parent || !prev)
return NULL;
4713 if (!children)
return NULL;
4718 }
else if ((*prev)->next) {
4723 return (*prev)->next;
4730 start = (*prev)->attr & 0xff;
4731 if (start == 255)
return NULL;
4743 len = talloc_array_length(children);
4744 for (i = start; i < len; i++) {
4745 bin = &children[i & 0xff];
4747 if (*bin)
return *bin;
4765 len = talloc_array_length(children);
4766 for (i = 0; i < len; i++) {
4770 if (!children[i])
continue;
4772 for (bin = children[i]; bin; bin = bin->next) {
4774 if (ret < 0)
return ret;
4796 if ((!da->flags.is_root) && (da->depth == 0)) {
4797 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t %s vendor: %u, attr %u: "
4798 "Is not root, but depth is 0",
4803 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t %s vendor: %u, attr %u: "
4804 "Indicated depth (%u) greater than TLV stack depth (%d)",
4809 for (da_p = da; da_p; da_p = da_p->next) {
4813 for (i = da->depth, da_p = da; (i >= 0) && da; i--, da_p = da_p->parent) {
4815 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t %s vendor: %u, attr %u: "
4816 "Depth indicated there should be a parent, but parent is NULL",
4819 if (i != (
int)da_p->depth) {
4820 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t %s vendor: %u, attr %u: "
4821 "Depth out of sequence, expected %i, got %u",
4828 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t top of hierarchy was not at depth 0",
4844 "CONSISTENCY CHECK FAILED %s[%d]: %s missing 'children' extension",
4849 "CONSISTENCY CHECK FAILED %s[%d]: %s missing 'namespace' extension",
4884 if (child->parent ==
parent)
return true;
4886 if (child->flags.is_raw)
return true;
4895 return (child->parent->parent ==
parent);
4926 if (child->dict !=
parent->dict) {
4931 return (ref && (ref->dict == child->dict));
4962 if (!da->flags.local)
return da;
4966 while (da->dict->next) {
4967 da = da->dict->next->root;
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.
int fr_dict_internal_afrom_file(fr_dict_t **out, char const *internal_name, char const *dependent)
(Re-)Initialize the special internal dictionary
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_value_box_t const ** out
Enumeration value.
fr_dict_t const ** dict
The protocol dictionary the attribute should be resolved in.
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
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.
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.
#define FR_DICT_DA_STACK_CACHE_MAX
Maximum level of da stack caching.
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_DA_STACK
Cached da stack.
@ 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.
struct fr_dict_protocol_t::@121 attr
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 * child_struct[]
for key fields
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.
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.
fr_dict_attr_t const * da_stack[]
Stack of dictionary attributes.
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 - Stack of dictionary attributes that describe the path back to the root of the d...
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 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
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)
void fr_dict_global_ctx_debug(fr_dict_gctx_t const *gctx)
Dump information about currently loaded dictionaries.
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.
ssize_t fr_dict_attr_by_oid_legacy(fr_dict_t const *dict, fr_dict_attr_t const **parent, unsigned int *attr, char const *oid)
Get the leaf attribute of an OID string.
fr_dict_enum_value_t * 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.