24RCSID(
"$Id: bedbe7c2db07b52933f2b48eb515e3fd680a6282 $")
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)) {
959 char const *
name,
int proto_number,
991 char const *
name,
int attr,
1062 if (!dst->flags.local) {
1070 if (src->flags.local) {
1092 uint depth_diff = dst->depth - src->depth;
1101 if (child->dict == dict) {
1112 copy->depth += depth_diff;
1131 if (cloned < 0)
return -1;
1206 self->dict =
parent->dict;
1210 namespace = dict_attr_namespace(parent);
1238 if (!dict->root)
return -1;
1245 fr_strerror_printf(
"%s: Failed inserting protocol name %s", __FUNCTION__, dict->root->name);
1249 if ((strcmp(old_proto->root->name, dict->root->name) == 0) &&
1250 (old_proto->root->name == dict->root->name)) {
1251 fr_strerror_printf(
"%s: Duplicate protocol name %s", __FUNCTION__, dict->root->name);
1257 dict->in_protocol_by_name =
true;
1260 fr_strerror_printf(
"%s: Duplicate protocol number %u", __FUNCTION__, dict->root->attr);
1263 dict->in_protocol_by_num =
true;
1282 dict->root->name, dict->root->attr,
FR_TYPE_GROUP, &flags) < 0) {
1330 if (!vendor->
name) {
1345 if ((strcmp(old_vendor->
name, vendor->
name) == 0) && (old_vendor->
pen != vendor->
pen)) {
1462 if (!
parent->flags.is_root &&
parent->flags.name_only &&
1496 for (bin = &children[child->attr & 0xff]; *bin; bin = &(*bin)->next) {
1504 if (child_is_struct && !bin_is_struct)
break;
1506 if (child->attr <= (*bin)->attr)
break;
1509 memcpy(&
this, &bin,
sizeof(
this));
1510 child->next = *
this;
1528 namespace = dict_attr_namespace(parent);
1560 if (a && (
strcasecmp(a->name, da->name) == 0)) {
1561 if ((a->attr != da->attr) || (a->type != da->type) || (a->parent != da->parent)) {
1563 "Originally defined %s[%d]",
1565 a->filename, a->line);
1594 if (
unlikely(da->dict->read_only)) {
1599 if (
unlikely(da->state.finalised ==
false)) {
1622 "Originally defined %s[%d]", da->name, da->parent->name,
1623 exists->filename, exists->line);
1632 if (da->flags.name_only) {
1633 if (da->state.attr_set) {
1636 if (da->attr > da->parent->last_child_attr) {
1637 parent->last_child_attr = da->attr;
1646 if ((da->attr >= (((uint64_t)1) << (8 *
parent->flags.type_size)))) da->flags.internal =
true;
1661 "Originally defined by '%s' at %s[%d]",
1662 da->attr, exists->name, exists->filename, exists->line);
1685 fr_strerror_printf(
"FATAL - Failed to find attribute number %u we just added to parent '%s'", da->attr, da->parent->name);
1690 fr_strerror_printf(
"FATAL - Failed to find attribute '%s' we just added to parent '%s'", da->name, da->parent->name);
1754 bool coerce,
bool takes_precedence,
1782 fr_strerror_const(
"Child structures cannot be defined for VALUEs which are not for 'key' attributes");
1791 if (da->flags.is_alias) {
1836 if (child_struct) enumv->
child_struct[0] = child_struct;
1838 if (!enum_value)
goto oom;
1840 if (da->type !=
value->type) {
1862 enumv->
value = enum_value;
1869 memcpy(&tmp, &enumv,
sizeof(tmp));
1888 "Old value was \"%pV\", new value was \"%pV\"",
name, da->name,
1901 if (takes_precedence) {
1943 bool coerce,
bool takes_precedence)
1998 fr_strerror_printf(
"Attribute is wrong type for auto-numbering, expected numeric type, got %s",
2042 if (!a || !b)
return NULL;
2044 if (is_ancestor && (b->depth <= a->depth))
return NULL;
2049 if (a->depth > b->depth) {
2051 for (p_a = a, i = a->depth - b->depth; p_a && (i > 0); p_a = p_a->parent, i--);
2052 if (is_ancestor && (p_a != p_b))
return NULL;
2053 }
else if (a->depth < b->depth) {
2055 for (p_b = b, i = b->depth - a->depth; p_b && (i > 0); p_b = p_b->parent, i--);
2056 if (is_ancestor && (p_a != p_b))
return NULL;
2062 while (p_a && p_b) {
2063 if (p_a == p_b)
return p_a;
2082 char const *p = *oid;
2088 num = strtoul(p, &q, 10);
2089 if ((p == q) || (num == ULONG_MAX)) {
2098 *
out = (
unsigned int)num;
2127 char const *p = oid;
2128 unsigned int num = 0;
2151 switch ((*parent)->type) {
2157 fr_strerror_printf(
"Attribute %s (%u) is not a TLV, so cannot contain a child attribute. "
2158 "Error at sub OID \"%s\"", (*parent)->name, (*parent)->attr, oid);
2186 num, oid, (*parent)->name);
2198 if (slen <= 0)
return slen - (p - oid);
2199 return slen + (p - oid);
2249 "Error at OID \"%.*s\"",
2265 fr_sbuff_set_to_start(&our_in);
2332 fr_sbuff_marker(&m_c, &our_in);
2407 return dict->read_only;
2432 memset(&root, 0,
sizeof(root));
2439 &our_name, SIZE_MAX,
2461 if (*(our_name.
p) && (*(our_name.
p) !=
'.')) {
2462 memcpy(
out, &dict_def,
sizeof(*
out));
2470 if (
strcasecmp(root.name,
"internal") != 0) {
2472 memcpy(
out, &dict_def,
sizeof(*
out));
2473 fr_sbuff_set_to_start(&our_name);
2513 &(
fr_dict_t){ .root = &(fr_dict_attr_t){ .name = name } });
2527 &(
fr_dict_t) { .root = &(fr_dict_attr_t){ .attr = num } });
2544 while (da_p->parent) {
2545 da_p = da_p->parent;
2547 "Expected %s, got %s",
2548 !da_p->dict ?
"(null)" :
fr_dict_root(da_p->dict)->name,
2553 if (!da_p->flags.is_root) {
2555 __FUNCTION__, da->name);
2565 return talloc_get_type_abort(da->dict,
fr_dict_t);
2621 while (dict1->next) dict1 = dict1->next;
2623 while (dict2->next) dict2 = dict2->next;
2625 return (dict1 == dict2);
2641 if (!dv.
pen)
return NULL;
2663 if (!
name)
return 0;
2666 if (!found)
return 0;
2699 switch (vendor_root->type) {
2759static inline CC_HINT(always_inline)
2763 bool internal,
bool foreign,
2776 if (
unlikely(!internal && !foreign && !dict_def)) {
2792 if (!internal && !foreign)
goto error;
2810 if (!foreign)
goto error;
2824 if (dict == dict_def)
continue;
2850#define DICT_NAME_APPEND(_in, _dict) \
2853 _n = talloc_strdup_append_buffer(_in, fr_dict_root(_dict)->name); \
2854 if (unlikely(!_n)) { \
2859 _n = talloc_strdup_append_buffer(_in, ", "); \
2860 if (unlikely(!_n)) { \
2868 fr_sbuff_marker(&start, &our_in);
2870 list = talloc_strdup(NULL,
"");
2880 if (dict == dict_def)
continue;
2907static inline CC_HINT(always_inline)
2911 bool internal,
bool foreign,
2943 internal = foreign =
false;
2946 if (
dict_attr_search(&our_err,
out, initial, &our_in, tt, internal, foreign, func) < 0)
goto error;
2978 bool internal,
bool foreign)
3007 bool internal,
bool foreign)
3036 bool internal,
bool foreign)
3065 bool internal,
bool foreign)
3083 bool internal,
bool foreign)
3145#ifdef STATIC_ANALYZER
3150 &our_name, SIZE_MAX,
3170 if ((
size_t) (p -
buffer) == len) {
3180 namespace = dict_attr_namespace(parent);
3184 fr_sbuff_set_to_start(&our_name);
3190 if (
parent->flags.is_root) {
3194 parent = dict->next->root;
3201 fr_sbuff_set_to_start(&our_name);
3225 namespace = dict_attr_namespace(parent);
3234 if (
parent->flags.is_root) {
3238 parent = dict->next->root;
3270 if (!da)
return NULL;
3296 if (!children)
return NULL;
3302 if ((attr & 0xff) > talloc_array_length(children))
return NULL;
3304 bin = children[attr & 0xff];
3306 if (!bin)
return NULL;
3307 if (bin->attr == attr) {
3310 memcpy(&
out, &bin,
sizeof(bin));
3333 if (!da)
return NULL;
3369 if (
value->type != da->type)
return NULL;
3387 if (!dv)
return NULL;
3399 if (!
name)
return NULL;
3413 if (len < 0) len = strlen(
name);
3426 size_t found_len = 0;
3440 int len = (p -
name) + 1;
3447 fr_sbuff_next(&our_in);
3519 bool seen_alpha =
false;
3523 fr_sbuff_next(&our_in);
3535 fr_sbuff_set_to_start(&our_in);
3561 if (!
name)
return 0;
3603 for (p = sym_name, q = p + (talloc_array_length(sym_name) - 1); p < q; p++) *p = *p ==
'-' ?
'_' : *p;
3606 proto = dlsym(dict->dl->handle, sym_name);
3613 if (!
proto)
return 0;
3619 dict->proto =
proto;
3712 fr_strerror_printf(
"Dependent \"%s\" not found in dictionary \"%s\"", dependent, dict->root->name);
3716 if (found->
count == 0) {
3718 dependent, dict->root->name);
3722 if (--found->
count == 0) {
3751 fprintf(stderr,
"DEPENDENTS FOR %s\n", dict->root->name);
3767 if (!dict->autoref)
return 0;
3777 for (i = 0; i < talloc_array_length(refd_list); i++) {
3778 if (
fr_dict_free(&refd_list[i], dict->root->name) < 0) {
3779 fr_strerror_printf(
"failed freeing autoloaded protocol %s", refd_list[i]->root->name);
3784 TALLOC_FREE(dict->autoref);
3795 if (dict != dict->gctx->internal) {
3798 if (dict->gctx->attr_protocol_encapsulation && dict->root) {
3804#ifdef STATIC_ANALYZER
3814 if (dict->proto && dict->proto->free) {
3815 dict->proto->free();
3819 fr_strerror_printf(
"Failed removing dictionary from protocol hash \"%s\"", dict->root->name);
3822 dict->in_protocol_by_name =
false;
3825 fr_strerror_printf(
"Failed removing dictionary from protocol number_hash \"%s\"", dict->root->name);
3828 dict->in_protocol_by_num =
false;
3834 fr_strerror_printf(
"Refusing to free dictionary \"%s\", still has dependents", dict->root->name);
3858 if (dict == dict->gctx->internal) {
3859 dict->gctx->internal = NULL;
3860 dict->gctx->attr_protocol_encapsulation = NULL;
3877 fr_strerror_const(
"Initialise global dictionary ctx with fr_dict_global_ctx_init()");
3912 if (!dict->vendors_by_name) {
3922 if (!dict->vendors_by_num) {
3931 if (!dict->autoref) {
3975 if (!dict)
return NULL;
3991 dict->root->dict = dict;
4026 if (!*dict)
return 0;
4056 for (p = to_load; p->
out; p++) {
4065 "an entry to load the attribute \"%s\" is located in, and that "
4066 "the fr_dict_autoload_attr_t symbol name is correct", p->
name);
4095 for (p = to_load; p->
out; p++) {
4102 fr_strerror_printf(
"Autoloader autoloader can't resolve attribute \"%s\", dictionary not loaded", p->
name);
4104 "an entry to load the dictionary \"%s\" is located in, and that "
4105 "the fr_dict_autoload_t symbol name is correct", p->
name);
4116 if (da->type != p->
type) {
4117 fr_strerror_printf(
"Autoloader attribute \"%s\" should be type %s, but defined as type %s", da->name,
4125 if (p->
out) *(p->
out) = da;
4143 for (p = to_load; p->
out; p++) {
4154 if (strcmp(p->
proto,
"freeradius") == 0) {
4176 for (p = to_free; p->
out; p++) {
4179 if (!*p->
out)
continue;
4182 if (ret == 0) *p->
out = NULL;
4183 if (ret < 0)
return -1;
4237 dict_ref->
dependent = talloc_strdup(dict_ref, dependent);
4320 bool still_loaded =
false;
4334 (void)talloc_get_type_abort(dict,
fr_dict_t);
4342 (void)talloc_get_type_abort(dict,
fr_dict_t);
4349 still_loaded =
true;
4517 dict->read_only =
true;
4522 dict->read_only =
true;
4622 char const *p =
name, *end;
4623 bool unknown =
false;
4626 if (len < 0) len = strlen(
name);
4638 if ((len > 5) && (memcmp(
name,
"Attr-", 5) == 0)) unknown =
true;
4641 if ((*p ==
'.') && unknown) p++;
4665 char const *p =
name, *end;
4668 if (len < 0) len = strlen(
name);
4683 if (!alnum)
return 0;
4701 size_t len, i, start;
4703 if (!
parent || !prev)
return NULL;
4709 if (!children)
return NULL;
4714 }
else if ((*prev)->next) {
4719 return (*prev)->next;
4726 start = (*prev)->attr & 0xff;
4727 if (start == 255)
return NULL;
4739 len = talloc_array_length(children);
4740 for (i = start; i < len; i++) {
4741 bin = &children[i & 0xff];
4743 if (*bin)
return *bin;
4761 len = talloc_array_length(children);
4762 for (i = 0; i < len; i++) {
4766 if (!children[i])
continue;
4768 for (bin = children[i]; bin; bin = bin->next) {
4770 if (ret < 0)
return ret;
4792 if ((!da->flags.is_root) && (da->depth == 0)) {
4793 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t %s vendor: %u, attr %u: "
4794 "Is not root, but depth is 0",
4799 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t %s vendor: %u, attr %u: "
4800 "Indicated depth (%u) greater than TLV stack depth (%d)",
4805 for (da_p = da; da_p; da_p = da_p->next) {
4809 for (i = da->depth, da_p = da; (i >= 0) && da; i--, da_p = da_p->parent) {
4811 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t %s vendor: %u, attr %u: "
4812 "Depth indicated there should be a parent, but parent is NULL",
4815 if (i != (
int)da_p->depth) {
4816 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t %s vendor: %u, attr %u: "
4817 "Depth out of sequence, expected %i, got %u",
4824 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%d]: fr_dict_attr_t top of hierarchy was not at depth 0",
4840 "CONSISTENCY CHECK FAILED %s[%d]: %s missing 'children' extension",
4845 "CONSISTENCY CHECK FAILED %s[%d]: %s missing 'namespace' extension",
4880 if (child->parent ==
parent)
return true;
4882 if (child->flags.is_raw)
return true;
4891 return (child->parent->parent ==
parent);
4922 if (child->dict !=
parent->dict) {
4927 return (ref && (ref->dict == child->dict));
4958 if (!da->flags.local)
return da;
4962 while (da->dict->next) {
4963 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.
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 * 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.
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)
static char const * proto(int id, int porttype)
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