24RCSID(
"$Id: 218a00cd70c2ab5f4fce0726825db598b711e30e $")
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>
47 [
'-'] =
true, [
'/'] =
true, [
'_'] =
true,
48 [
'0'] =
true, [
'1'] =
true, [
'2'] =
true, [
'3'] =
true, [
'4'] =
true,
49 [
'5'] =
true, [
'6'] =
true, [
'7'] =
true, [
'8'] =
true, [
'9'] =
true,
50 [
'A'] =
true, [
'B'] =
true, [
'C'] =
true, [
'D'] =
true, [
'E'] =
true,
51 [
'F'] =
true, [
'G'] =
true, [
'H'] =
true, [
'I'] =
true, [
'J'] =
true,
52 [
'K'] =
true, [
'L'] =
true, [
'M'] =
true, [
'N'] =
true, [
'O'] =
true,
53 [
'P'] =
true, [
'Q'] =
true, [
'R'] =
true, [
'S'] =
true, [
'T'] =
true,
54 [
'U'] =
true, [
'V'] =
true, [
'W'] =
true, [
'X'] =
true, [
'Y'] =
true,
56 [
'a'] =
true, [
'b'] =
true, [
'c'] =
true, [
'd'] =
true, [
'e'] =
true,
57 [
'f'] =
true, [
'g'] =
true, [
'h'] =
true, [
'i'] =
true, [
'j'] =
true,
58 [
'k'] =
true, [
'l'] =
true, [
'm'] =
true, [
'n'] =
true, [
'o'] =
true,
59 [
'p'] =
true, [
'q'] =
true, [
'r'] =
true, [
's'] =
true, [
't'] =
true,
60 [
'u'] =
true, [
'v'] =
true, [
'w'] =
true, [
'x'] =
true, [
'y'] =
true,
68 [
'+'] =
true, [
'-'] =
true, [
'.'] =
true, [
'/'] =
true, [
'_'] =
true,
69 [
'0'] =
true, [
'1'] =
true, [
'2'] =
true, [
'3'] =
true, [
'4'] =
true,
70 [
'5'] =
true, [
'6'] =
true, [
'7'] =
true, [
'8'] =
true, [
'9'] =
true,
71 [
'A'] =
true, [
'B'] =
true, [
'C'] =
true, [
'D'] =
true, [
'E'] =
true,
72 [
'F'] =
true, [
'G'] =
true, [
'H'] =
true, [
'I'] =
true, [
'J'] =
true,
73 [
'K'] =
true, [
'L'] =
true, [
'M'] =
true, [
'N'] =
true, [
'O'] =
true,
74 [
'P'] =
true, [
'Q'] =
true, [
'R'] =
true, [
'S'] =
true, [
'T'] =
true,
75 [
'U'] =
true, [
'V'] =
true, [
'W'] =
true, [
'X'] =
true, [
'Y'] =
true,
77 [
'a'] =
true, [
'b'] =
true, [
'c'] =
true, [
'd'] =
true, [
'e'] =
true,
78 [
'f'] =
true, [
'g'] =
true, [
'h'] =
true, [
'i'] =
true, [
'j'] =
true,
79 [
'k'] =
true, [
'l'] =
true, [
'm'] =
true, [
'n'] =
true, [
'o'] =
true,
80 [
'p'] =
true, [
'q'] =
true, [
'r'] =
true, [
's'] =
true, [
't'] =
true,
81 [
'u'] =
true, [
'v'] =
true, [
'w'] =
true, [
'x'] =
true, [
'y'] =
true,
93 .default_type_size = 2,
94 .default_type_length = 2,
102#define FNV_MAGIC_INIT (0x811c9dc5)
103#define FNV_MAGIC_PRIME (0x01000193)
121 char const *p =
name, *q =
name + len;
124 int c = *(
unsigned char const *)p;
125 if (isalpha(c)) c = tolower(c);
159 ret =
strcasecmp(a->root->name, b->root->name);
179 return CMP(a->root->attr, b->root->attr);
320 if (!da->flags.is_alias)
return da;
345 char *name_start, *name_end;
360 name_len = strlen(
name);
375 if (!name_start)
return -1;
377 name_end = name_start + name_len;
379 memcpy(name_start,
name, name_len);
382 (*da_p)->name = name_start;
383 (*da_p)->name_len = name_len;
440 if (!p_ext)
return 1;
492 if (!ext->namespace) {
495 if (!ext->namespace) {
521 if (
unlikely((*da_p)->state.finalised ==
true)) {
554 (*da_p)->last_child_attr = (1 << 24);
581 (*da_p)->flags.length = 4;
588 (*da_p)->flags.is_known_width = ((*da_p)->flags.length != 0);
595 (*da_p)->type =
type;
614 fr_strerror_const(
"Attribute type must be set before initialising parent. Use dict_attr_type_init() first");
619 fr_strerror_printf(
"Attempting to set parent for '%s' to '%s', but parent already set to '%s'",
620 da->name,
parent->name, da->parent->name);
624 if (
unlikely((*da_p)->state.finalised ==
true)) {
625 fr_strerror_printf(
"Attempting to set parent for '%s' to '%s', but attribute already finalised",
632 da->depth =
parent->depth + 1;
641 if (ret < 0)
return -1;
662 if (da->state.attr_set) {
667 da->state.attr_set =
true;
681 fr_strerror_const(
"Attribute must have parent set before automatically setting attribute number");
692 da->filename = filename;
726 da->flags.is_known_width |= da->flags.array;
769 (*da_p)->state.finalised =
true;
774static inline CC_HINT(always_inline)
788 if (
args->flags) (*da_p)->flags = *
args->flags;
822 char const *
name,
unsigned int attr,
871 (*da_p)->flags.name_only =
true;
883#ifdef WITH_VERIFY_PTR
927 if (proto->
attr.flags.len > 0) {
929 proto->
attr.flags.len) == NULL)) {
956 char const *
name,
int proto_number,
990 char const *
name,
int attr,
1020 if (
in->flags.has_fixup) {
1021 fr_strerror_printf(
"Cannot copy from %s - source attribute is waiting for additional definitions",
1052 if (
in->flags.has_fixup) {
1053 fr_strerror_printf(
"Cannot copy from %s - source attribute is waiting for additional definitions",
1073 if (!dst->flags.local) {
1078 if (src->flags.has_fixup) {
1079 fr_strerror_printf(
"Cannot copy from %s to %s - source attribute is waiting for additional definitions",
1080 src->name, dst->name);
1087 if (src->flags.local) {
1108 uint depth_diff = dst->depth - src->depth;
1117 if (child->dict == dict) {
1122 if (!copy)
return -1;
1125 copy->depth += depth_diff;
1208 self->dict =
parent->dict;
1212 namespace = dict_attr_namespace(parent);
1240 if (!dict->root)
return -1;
1247 fr_strerror_printf(
"%s: Failed inserting protocol name %s", __FUNCTION__, dict->root->name);
1251 if ((strcmp(old_proto->root->name, dict->root->name) == 0) &&
1252 (old_proto->root->name == dict->root->name)) {
1253 fr_strerror_printf(
"%s: Duplicate protocol name %s", __FUNCTION__, dict->root->name);
1259 dict->in_protocol_by_name =
true;
1262 fr_strerror_printf(
"%s: Duplicate protocol number %u", __FUNCTION__, dict->root->attr);
1265 dict->in_protocol_by_num =
true;
1284 dict->root->name, dict->root->attr,
FR_TYPE_GROUP, &flags) < 0) {
1332 if (!vendor->
name) {
1347 if ((strcmp(old_vendor->
name, vendor->
name) == 0) && (old_vendor->
pen != vendor->
pen)) {
1464 if (!
parent->flags.is_root &&
parent->flags.name_only &&
1498 for (bin = &children[child->attr & 0xff]; *bin; bin = &(*bin)->next) {
1506 if (child_is_struct && !bin_is_struct)
break;
1508 if (child->attr <= (*bin)->attr)
break;
1511 memcpy(&
this, &bin,
sizeof(
this));
1512 child->next = *
this;
1530 namespace = dict_attr_namespace(parent);
1562 if (a && (
strcasecmp(a->name, da->name) == 0)) {
1563 if ((a->attr != da->attr) || (a->type != da->type) || (a->parent != da->parent)) {
1565 "Originally defined %s[%d]",
1567 a->filename, a->line);
1596 if (
unlikely(da->dict->read_only)) {
1601 if (
unlikely(da->state.finalised ==
false)) {
1624 "Originally defined %s[%d]", da->name, da->parent->name,
1625 exists->filename, exists->line);
1634 if (da->flags.name_only) {
1635 if (da->state.attr_set) {
1638 if (da->attr > da->parent->last_child_attr) {
1639 parent->last_child_attr = da->attr;
1648 if ((da->attr >= (((uint64_t)1) << (8 *
parent->flags.type_size)))) da->flags.internal =
true;
1663 "Originally defined by '%s' at %s[%d]",
1664 da->attr, da->parent->name, exists->name, exists->filename, exists->line);
1687 fr_strerror_printf(
"FATAL - Failed to find attribute number %u we just added to namespace '%s'", da->attr, da->parent->name);
1692 fr_strerror_printf(
"FATAL - Failed to find attribute '%s' we just added to namespace '%s'", da->name, da->parent->name);
1756 bool coerce,
bool takes_precedence,
1784 fr_strerror_const(
"Child structures cannot be defined for VALUEs which are not for 'key' attributes");
1793 if (da->flags.is_alias) {
1838 if (child_struct) enumv->
child_struct[0] = child_struct;
1840 if (!enum_value)
goto oom;
1842 if (da->type !=
value->type) {
1864 enumv->
value = enum_value;
1871 memcpy(&tmp, &enumv,
sizeof(tmp));
1890 "Old value was \"%pV\", new value was \"%pV\"",
name, da->name,
1903 if (takes_precedence) {
1945 bool coerce,
bool takes_precedence)
2000 fr_strerror_printf(
"Attribute is wrong type for auto-numbering, expected numeric type, got %s",
2044 if (!a || !b)
return NULL;
2046 if (is_ancestor && (b->depth <= a->depth))
return NULL;
2051 if (a->depth > b->depth) {
2053 for (p_a = a, i = a->depth - b->depth; p_a && (i > 0); p_a = p_a->parent, i--);
2054 if (is_ancestor && (p_a != p_b))
return NULL;
2055 }
else if (a->depth < b->depth) {
2057 for (p_b = b, i = b->depth - a->depth; p_b && (i > 0); p_b = p_b->parent, i--);
2058 if (is_ancestor && (p_a != p_b))
return NULL;
2064 while (p_a && p_b) {
2065 if (p_a == p_b)
return p_a;
2084 char const *p = *oid;
2090 num = strtoul(p, &q, 10);
2091 if ((p == q) || (num == ULONG_MAX)) {
2100 *
out = (
unsigned int)num;
2129 char const *p = oid;
2130 unsigned int num = 0;
2153 switch ((*parent)->type) {
2159 fr_strerror_printf(
"Attribute %s (%u) is not a TLV, so cannot contain a child attribute. "
2160 "Error at sub OID \"%s\"", (*parent)->name, (*parent)->attr, oid);
2170 (num > ((uint64_t) 1 << (8 * (*parent)->flags.type_size)))) {
2171 fr_strerror_printf(
"TLV attributes must be %" PRIu64
" bits or less", ((uint64_t)1 << (8 * (*parent)->flags.type_size)));
2188 num, oid, (*parent)->name);
2200 if (slen <= 0)
return slen - (p - oid);
2201 return slen + (p - oid);
2251 "Error at OID \"%.*s\"",
2267 fr_sbuff_set_to_start(&our_in);
2334 fr_sbuff_marker(&m_c, &our_in);
2409 return dict->read_only;
2434 memset(&root, 0,
sizeof(root));
2441 &our_name, SIZE_MAX,
2463 if (*(our_name.
p) && (*(our_name.
p) !=
'.')) {
2464 memcpy(
out, &dict_def,
sizeof(*
out));
2472 if (
strcasecmp(root.name,
"internal") != 0) {
2474 memcpy(
out, &dict_def,
sizeof(*
out));
2475 fr_sbuff_set_to_start(&our_name);
2515 &(
fr_dict_t){ .root = &(fr_dict_attr_t){ .name = name } });
2529 &(
fr_dict_t) { .root = &(fr_dict_attr_t){ .attr = num } });
2546 while (da_p->parent) {
2547 da_p = da_p->parent;
2549 "Expected %s, got %s",
2550 !da_p->dict ?
"(null)" :
fr_dict_root(da_p->dict)->name,
2555 if (!da_p->flags.is_root) {
2557 __FUNCTION__, da->name);
2567 return talloc_get_type_abort(da->dict,
fr_dict_t);
2623 while (dict1->next) dict1 = dict1->next;
2625 while (dict2->next) dict2 = dict2->next;
2627 return (dict1 == dict2);
2643 if (!dv.
pen)
return NULL;
2665 if (!
name)
return 0;
2668 if (!found)
return 0;
2701 switch (vendor_root->type) {
2761static inline CC_HINT(always_inline)
2765 bool internal,
bool foreign,
2778 if (
unlikely(!internal && !foreign && !dict_def)) {
2794 if (!internal && !foreign)
goto error;
2812 if (!foreign)
goto error;
2826 if (dict == dict_def)
continue;
2852#define DICT_NAME_APPEND(_in, _dict) \
2855 _n = talloc_strdup_append_buffer(_in, fr_dict_root(_dict)->name); \
2856 if (unlikely(!_n)) { \
2861 _n = talloc_strdup_append_buffer(_in, ", "); \
2862 if (unlikely(!_n)) { \
2870 fr_sbuff_marker(&start, &our_in);
2872 list = talloc_strdup(NULL,
"");
2882 if (dict == dict_def)
continue;
2909static inline CC_HINT(always_inline)
2913 bool internal,
bool foreign,
2945 internal = foreign =
false;
2948 if (
dict_attr_search(&our_err,
out, initial, &our_in, tt, internal, foreign, func) < 0)
goto error;
2980 bool internal,
bool foreign)
3009 bool internal,
bool foreign)
3038 bool internal,
bool foreign)
3067 bool internal,
bool foreign)
3085 bool internal,
bool foreign)
3147#ifdef STATIC_ANALYZER
3152 &our_name, SIZE_MAX,
3172 if ((
size_t) (p -
buffer) == len) {
3182 namespace = dict_attr_namespace(parent);
3186 fr_sbuff_set_to_start(&our_name);
3192 if (
parent->flags.is_root) {
3196 parent = dict->next->root;
3203 fr_sbuff_set_to_start(&our_name);
3227 namespace = dict_attr_namespace(parent);
3236 if (
parent->flags.is_root) {
3240 parent = dict->next->root;
3272 if (!da)
return NULL;
3298 if (!children)
return NULL;
3304 if ((attr & 0xff) > talloc_array_length(children))
return NULL;
3306 bin = children[attr & 0xff];
3308 if (!bin)
return NULL;
3309 if (bin->attr == attr) {
3312 memcpy(&
out, &bin,
sizeof(bin));
3335 if (!da)
return NULL;
3371 if (
value->type != da->type)
return NULL;
3389 if (!dv)
return NULL;
3401 if (!
name)
return NULL;
3415 if (len < 0) len = strlen(
name);
3428 size_t found_len = 0;
3442 int len = (p -
name) + 1;
3449 fr_sbuff_next(&our_in);
3521 bool seen_alpha =
false;
3525 fr_sbuff_next(&our_in);
3537 fr_sbuff_set_to_start(&our_in);
3563 if (!
name)
return 0;
3605 for (p = sym_name, q = p + (talloc_array_length(sym_name) - 1); p < q; p++) *p = *p ==
'-' ?
'_' : *p;
3608 proto = dlsym(dict->dl->handle, sym_name);
3615 if (!proto)
return 0;
3621 dict->proto = proto;
3714 fr_strerror_printf(
"Dependent \"%s\" not found in dictionary \"%s\"", dependent, dict->root->name);
3718 if (found->
count == 0) {
3720 dependent, dict->root->name);
3724 if (--found->
count == 0) {
3753 fprintf(stderr,
"DEPENDENTS FOR %s\n", dict->root->name);
3769 if (!dict->autoref)
return 0;
3779 for (i = 0; i < talloc_array_length(refd_list); i++) {
3780 if (
fr_dict_free(&refd_list[i], dict->root->name) < 0) {
3781 fr_strerror_printf(
"failed freeing autoloaded protocol %s", refd_list[i]->root->name);
3786 TALLOC_FREE(dict->autoref);
3797 if (dict != dict->gctx->internal) {
3800 if (dict->gctx->attr_protocol_encapsulation && dict->root) {
3806#ifdef STATIC_ANALYZER
3816 if (dict->proto && dict->proto->free) {
3817 dict->proto->free();
3821 fr_strerror_printf(
"Failed removing dictionary from protocol hash \"%s\"", dict->root->name);
3824 dict->in_protocol_by_name =
false;
3827 fr_strerror_printf(
"Failed removing dictionary from protocol number_hash \"%s\"", dict->root->name);
3830 dict->in_protocol_by_num =
false;
3836 fr_strerror_printf(
"Refusing to free dictionary \"%s\", still has dependents", dict->root->name);
3860 if (dict == dict->gctx->internal) {
3861 dict->gctx->internal = NULL;
3862 dict->gctx->attr_protocol_encapsulation = NULL;
3879 fr_strerror_const(
"Initialise global dictionary ctx with fr_dict_global_ctx_init()");
3914 if (!dict->vendors_by_name) {
3924 if (!dict->vendors_by_num) {
3933 if (!dict->autoref) {
3977 if (!dict)
return NULL;
3993 dict->root->dict = dict;
4028 if (!*dict)
return 0;
4058 for (p = to_load; p->
out; p++) {
4067 "an entry to load the attribute \"%s\" is located in, and that "
4068 "the fr_dict_autoload_attr_t symbol name is correct", p->
name);
4097 for (p = to_load; p->
out; p++) {
4104 fr_strerror_printf(
"Autoloader autoloader can't resolve attribute \"%s\", dictionary not loaded", p->
name);
4106 "an entry to load the dictionary \"%s\" is located in, and that "
4107 "the fr_dict_autoload_t symbol name is correct", p->
name);
4118 if (da->type != p->
type) {
4119 fr_strerror_printf(
"Autoloader attribute \"%s\" should be type %s, but defined as type %s", da->name,
4127 if (p->
out) *(p->
out) = da;
4145 for (p = to_load; p->
out; p++) {
4156 if (strcmp(p->
proto,
"freeradius") == 0) {
4178 for (p = to_free; p->
out; p++) {
4181 if (!*p->
out)
continue;
4184 if (ret == 0) *p->
out = NULL;
4185 if (ret < 0)
return -1;
4239 dict_ref->
dependent = talloc_strdup(dict_ref, dependent);
4322 bool still_loaded =
false;
4336 (void)talloc_get_type_abort(dict,
fr_dict_t);
4344 (void)talloc_get_type_abort(dict,
fr_dict_t);
4351 still_loaded =
true;
4519 dict->read_only =
true;
4524 dict->read_only =
true;
4624 char const *p =
name, *end;
4625 bool unknown =
false;
4628 if (len < 0) len = strlen(
name);
4640 if ((len > 5) && (memcmp(
name,
"Attr-", 5) == 0)) unknown =
true;
4643 if ((*p ==
'.') && unknown) p++;
4667 char const *p =
name, *end;
4670 if (len < 0) len = strlen(
name);
4685 if (!alnum)
return 0;
4703 size_t len, i, start;
4705 if (!
parent || !prev)
return NULL;
4711 if (!children)
return NULL;
4716 }
else if ((*prev)->next) {
4721 return (*prev)->next;
4728 start = (*prev)->attr & 0xff;
4729 if (start == 255)
return NULL;
4741 len = talloc_array_length(children);
4742 for (i = start; i < len; i++) {
4743 bin = &children[i & 0xff];
4745 if (*bin)
return *bin;
4763 len = talloc_array_length(children);
4764 for (i = 0; i < len; i++) {
4768 if (!children[i])
continue;
4770 for (bin = children[i]; bin; bin = bin->next) {
4772 if (ret < 0)
return ret;
4794 if ((!da->flags.is_root) && (da->depth == 0)) {
4795 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t %s vendor: %u, attr %u: "
4796 "Is not root, but depth is 0",
4801 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t %s vendor: %u, attr %u: "
4802 "Indicated depth (%u) greater than TLV stack depth (%d)",
4807 for (da_p = da; da_p; da_p = da_p->next) {
4811 for (i = da->depth, da_p = da; (i >= 0) && da; i--, da_p = da_p->parent) {
4813 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t %s vendor: %u, attr %u: "
4814 "Depth indicated there should be a parent, but parent is NULL",
4817 if (i != (
int)da_p->depth) {
4818 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t %s vendor: %u, attr %u: "
4819 "Depth out of sequence, expected %i, got %u",
4826 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t top of hierarchy was not at depth 0",
4842 "CONSISTENCY CHECK FAILED %s[%d]: %s missing 'children' extension",
4847 "CONSISTENCY CHECK FAILED %s[%d]: %s missing 'namespace' extension",
4882 if (child->parent ==
parent)
return true;
4884 if (child->flags.is_raw)
return true;
4893 return (child->parent->parent ==
parent);
4924 if (child->dict !=
parent->dict) {
4929 return (ref && (ref->dict == child->dict));
4960 if (!da->flags.local)
return da;
4964 while (da->dict->next) {
4965 da = da->dict->next->root;
4976 while (dict->next) dict = dict->next;
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.
struct fr_dict_protocol_t::@124 attr
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.
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.
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 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.
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)
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.
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.
bool const fr_dict_attr_allowed_chars[UINT8_MAX+1]
Characters allowed in dictionary names.
int fr_dict_attr_set_group(fr_dict_attr_t **da_p)
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.
static int dict_attr_da_stack_set(fr_dict_attr_t **da_p)
Initialise an attribute's da stack from its parent.
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.
static int8_t _dict_dependent_cmp(void const *a, void const *b)
Find a dependent in the tree of dependents.
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.
static int8_t dict_vendor_name_cmp(void const *one, void const *two)
Compare two attribute names.
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.
static int8_t dict_attr_name_cmp(void const *one, void const *two)
Compare two attribute names.
static int8_t dict_vendor_pen_cmp(void const *one, void const *two)
Compare two vendor numbers.
static int8_t dict_enum_value_cmp(void const *one, void const *two)
Compare two dictionary enum values.
fr_dict_attr_t * dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *name)
static void hash_pool_free(void *to_free)
static uint32_t dict_attr_name_hash(void const *data)
Wrap name hash function for fr_dict_attr_t.
bool const fr_dict_enum_allowed_chars[UINT8_MAX+1]
Characters allowed in enumeration value names.
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.
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 * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
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.
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)
static int8_t dict_enum_name_cmp(void const *one, void const *two)
Compare two dictionary attribute enum values.
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.
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 int8_t dict_protocol_name_cmp(void const *one, void const *two)
Compare two protocol names.
static int dict_attr_enumv_init(fr_dict_attr_t **da_p)
Initialise a per-attribute enumeration table.
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_dict_attr_t * dict_attr_acopy(TALLOC_CTX *ctx, fr_dict_attr_t const *in, char const *new_name)
Copy a an existing attribute.
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.
static int8_t dict_protocol_num_cmp(void const *one, void const *two)
Compare two protocol numbers.
int dict_attr_alias_add(fr_dict_attr_t const *parent, char const *alias, fr_dict_attr_t const *ref)
Add an alias to an existing attribute.
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 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.
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.
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.
static fr_dict_attr_t * dict_attr_acopy_dict(TALLOC_CTX *ctx, fr_dict_attr_t *parent, fr_dict_attr_t const *in)
Copy an existing attribute to a different dictionary.
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_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 *child_struct)
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)
fr_dict_t * fr_dict_protocol_alloc(fr_dict_t const *parent)
Allocate a new local dictionary.
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.
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.
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.
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.
void * fr_hash_table_find(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)
bool fr_hash_table_insert(fr_hash_table_t *ht, void const *data)
Insert data into a hash table.
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.
uint32_t fr_hash_string(char const *p)
bool fr_hash_table_delete(fr_hash_table_t *ht, void const *data)
Remove and free data (if a free function was specified)
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)
#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)
@ 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.
size_t fr_sbuff_out_bstrncpy_allowed(fr_sbuff_t *out, fr_sbuff_t *in, size_t len, bool const allowed[static UINT8_MAX+1])
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.
void * fr_rb_iter_init_inorder(fr_rb_iter_inorder_t *iter, fr_rb_tree_t *tree)
Initialise an in-order iterator.
void * fr_rb_iter_next_inorder(fr_rb_iter_inorder_t *iter)
Return the next node.
void * fr_rb_find(fr_rb_tree_t const *tree, void const *data)
Find an element in the tree, returning the data, not the node.
bool fr_rb_insert(fr_rb_tree_t *tree, void const *data)
Insert data into a tree.
bool fr_rb_delete(fr_rb_tree_t *tree, void const *data)
Remove node and free data (if a free function was specified)
#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)
bool fr_sbuff_is_terminal(fr_sbuff_t *in, fr_sbuff_term_t const *tt)
Efficient terminal string search.
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.
bool const sbuff_char_alpha_num[UINT8_MAX+1]
#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)
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.
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, 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.
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)
#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.
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.
int8_t fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b)
Compare two values.
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