23 RCSID(
"$Id: be45c6c79b638a31de8dc2b9a2fe27043983bc87 $")
25 #define _DICT_PRIVATE 1
27 #include <freeradius-devel/util/atexit.h>
28 #include <freeradius-devel/util/conf.h>
29 #include <freeradius-devel/util/dict.h>
30 #include <freeradius-devel/util/dict_fixup_priv.h>
31 #include <freeradius-devel/util/proto.h>
32 #include <freeradius-devel/util/rand.h>
33 #include <freeradius-devel/util/sbuff.h>
34 #include <freeradius-devel/util/syserror.h>
36 #ifdef HAVE_SYS_STAT_H
37 # include <sys/stat.h>
46 [
'-'] =
true, [
'/'] =
true, [
'_'] =
true,
47 [
'0'] =
true, [
'1'] =
true, [
'2'] =
true, [
'3'] =
true, [
'4'] =
true,
48 [
'5'] =
true, [
'6'] =
true, [
'7'] =
true, [
'8'] =
true, [
'9'] =
true,
49 [
'A'] =
true, [
'B'] =
true, [
'C'] =
true, [
'D'] =
true, [
'E'] =
true,
50 [
'F'] =
true, [
'G'] =
true, [
'H'] =
true, [
'I'] =
true, [
'J'] =
true,
51 [
'K'] =
true, [
'L'] =
true, [
'M'] =
true, [
'N'] =
true, [
'O'] =
true,
52 [
'P'] =
true, [
'Q'] =
true, [
'R'] =
true, [
'S'] =
true, [
'T'] =
true,
53 [
'U'] =
true, [
'V'] =
true, [
'W'] =
true, [
'X'] =
true, [
'Y'] =
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,
67 [
'+'] =
true, [
'-'] =
true, [
'.'] =
true, [
'/'] =
true, [
'_'] =
true,
68 [
'0'] =
true, [
'1'] =
true, [
'2'] =
true, [
'3'] =
true, [
'4'] =
true,
69 [
'5'] =
true, [
'6'] =
true, [
'7'] =
true, [
'8'] =
true, [
'9'] =
true,
70 [
'A'] =
true, [
'B'] =
true, [
'C'] =
true, [
'D'] =
true, [
'E'] =
true,
71 [
'F'] =
true, [
'G'] =
true, [
'H'] =
true, [
'I'] =
true, [
'J'] =
true,
72 [
'K'] =
true, [
'L'] =
true, [
'M'] =
true, [
'N'] =
true, [
'O'] =
true,
73 [
'P'] =
true, [
'Q'] =
true, [
'R'] =
true, [
'S'] =
true, [
'T'] =
true,
74 [
'U'] =
true, [
'V'] =
true, [
'W'] =
true, [
'X'] =
true, [
'Y'] =
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,
89 #define FNV_MAGIC_INIT (0x811c9dc5)
90 #define FNV_MAGIC_PRIME (0x01000193)
108 char const *p =
name, *q =
name + len;
111 int c = *(
unsigned char const *)p;
112 if (isalpha(c)) c = tolower(c);
145 ret =
strcasecmp(a->root->name, b->root->name);
165 return CMP(a->root->attr, b->root->attr);
306 if (!da->flags.is_alias)
return da;
331 char *name_start, *name_end;
346 name_len = strlen(
name);
361 if (!name_start)
return -1;
363 name_end = name_start + name_len;
365 memcpy(name_start,
name, name_len);
368 (*da_p)->name = name_start;
369 (*da_p)->name_len = name_len;
445 if (!p_ext)
return 1;
497 if (!ext->namespace) {
500 if (!ext->namespace) {
523 char const *
name,
int attr,
532 .last_child_attr = (1 << 24),
534 .flags = *
args->flags,
542 (*da_p)->dict =
parent->dict;
543 (*da_p)->depth =
parent->depth + 1;
630 #ifdef WITH_VERIFY_PTR
676 memset(da->ext, 0,
sizeof(da->ext));
699 char const *
name,
int attr,
789 if (cloned < 0)
return -1;
860 if (!
dict->root)
return -1;
871 if ((strcmp(old_proto->root->name,
dict->root->name) == 0) &&
872 (old_proto->root->name ==
dict->root->name)) {
879 dict->in_protocol_by_name =
true;
885 dict->in_protocol_by_num =
true;
966 if ((strcmp(old_vendor->
name, vendor->
name) == 0) && (old_vendor->
pen != vendor->
pen)) {
1083 if (!
parent->flags.is_root &&
parent->flags.name_only &&
1117 for (bin = &children[child->attr & 0xff]; *bin; bin = &(*bin)->next) {
1125 if (child_is_struct && !bin_is_struct)
break;
1127 if (child->attr <= (*bin)->attr)
break;
1130 memcpy(&
this, &bin,
sizeof(
this));
1131 child->next = *
this;
1149 namespace = dict_attr_namespace(parent);
1181 if (a && (
strcasecmp(a->name, da->name) == 0)) {
1182 if ((a->attr != da->attr) || (a->type != da->type) || (a->parent != da->parent)) {
1207 if (old->parent !=
parent) {
1209 n->name, old->parent->name,
parent->name);
1213 if (old->attr !=
n->attr) {
1215 n->name, old->attr,
n->attr);
1219 if (old->type !=
n->type) {
1221 "(old attribute \"%s\" has type %s, new attribute \"%s\" has type %s)",
1251 bool self_allocated =
false;
1261 self_allocated = (attr < 0);
1271 #define FLAGS_EQUAL(_x) (old->flags._x == flags->_x)
1278 if ((old->parent ==
parent) && (old->type ==
type) &&
1280 ((old->attr == (
unsigned int) attr) || self_allocated)) {
1348 bool coerce,
bool takes_precedence,
1376 fr_strerror_const(
"Child structures cannot be defined for VALUEs which are not for 'key' attributes");
1385 if (da->flags.is_alias) {
1430 if (child_struct) enumv->
child_struct[0] = child_struct;
1432 if (!enum_value)
goto oom;
1434 if (da->type !=
value->type) {
1456 enumv->
value = enum_value;
1463 memcpy(&tmp, &enumv,
sizeof(tmp));
1482 "Old value was \"%pV\", new value was \"%pV\"",
name, da->name,
1495 if (takes_precedence) {
1537 bool coerce,
bool takes_precedence)
1592 fr_strerror_printf(
"Attribute is wrong type for auto-numbering, expected numeric type, got %s",
1636 if (!a || !b)
return NULL;
1638 if (is_ancestor && (b->depth <= a->depth))
return NULL;
1643 if (a->depth > b->depth) {
1645 for (p_a = a, i = a->depth - b->depth; p_a && (i > 0); p_a = p_a->parent, i--);
1646 if (is_ancestor && (p_a != p_b))
return NULL;
1647 }
else if (a->depth < b->depth) {
1649 for (p_b = b, i = b->depth - a->depth; p_b && (i > 0); p_b = p_b->parent, i--);
1650 if (is_ancestor && (p_a != p_b))
return NULL;
1656 while (p_a && p_b) {
1657 if (p_a == p_b)
return p_a;
1676 char const *p = *oid;
1682 num = strtoul(p, &q, 10);
1683 if ((p == q) || (num == ULONG_MAX)) {
1692 *
out = (
unsigned int)num;
1721 char const *p = oid;
1722 unsigned int num = 0;
1745 switch ((*parent)->type) {
1751 fr_strerror_printf(
"Attribute %s (%i) is not a TLV, so cannot contain a child attribute. "
1752 "Error at sub OID \"%s\"", (*parent)->name, (*parent)->attr, oid);
1780 num, oid, (*parent)->name);
1792 if (slen <= 0)
return slen - (p - oid);
1793 return slen + (p - oid);
1843 "Error at OID \"%.*s\"",
1859 fr_sbuff_set_to_start(&our_in);
1929 fr_sbuff_marker(&m_c, &our_in);
2004 return dict->read_only;
2029 memset(&root, 0,
sizeof(root));
2036 &our_name, SIZE_MAX,
2058 if (*(our_name.
p) && (*(our_name.
p) !=
'.')) {
2059 memcpy(
out, &dict_def,
sizeof(*
out));
2067 if (
strcasecmp(root.name,
"internal") != 0) {
2069 memcpy(
out, &dict_def,
sizeof(*
out));
2070 fr_sbuff_set_to_start(&our_name);
2110 &(
fr_dict_t){ .root = &(fr_dict_attr_t){ .name = name } });
2124 &(
fr_dict_t) { .root = &(fr_dict_attr_t){ .attr = num } });
2141 while (da_p->parent) {
2142 da_p = da_p->parent;
2144 "Expected %s, got %s",
2145 !da_p->dict ?
"(null)" :
fr_dict_root(da_p->dict)->name,
2150 if (!da_p->flags.is_root) {
2152 __FUNCTION__, da->name);
2162 return talloc_get_type_abort(da->dict,
fr_dict_t);
2218 while (dict1->next) dict1 = dict1->next;
2220 while (dict2->next) dict2 = dict2->next;
2222 return (dict1 == dict2);
2238 if (!dv.
pen)
return NULL;
2260 if (!
name)
return 0;
2263 if (!found)
return 0;
2296 switch (vendor_root->type) {
2356 static inline CC_HINT(always_inline)
2360 bool internal,
bool foreign,
2373 if (
unlikely(!
internal && !foreign && !dict_def)) {
2389 if (!
internal && !foreign)
goto error;
2407 if (!foreign)
goto error;
2421 if (
dict == dict_def)
continue;
2447 #define DICT_NAME_APPEND(_in, _dict) \
2450 _n = talloc_strdup_append_buffer(_in, fr_dict_root(_dict)->name); \
2451 if (unlikely(!_n)) { \
2456 _n = talloc_strdup_append_buffer(_in, ", "); \
2457 if (unlikely(!_n)) { \
2465 fr_sbuff_marker(&start, &our_in);
2467 list = talloc_strdup(NULL,
"");
2477 if (
dict == dict_def)
continue;
2504 static inline CC_HINT(always_inline)
2508 bool internal,
bool foreign,
2540 internal = foreign =
false;
2543 if (
dict_attr_search(&our_err,
out, initial, &our_in, tt,
internal, foreign, func) < 0)
goto error;
2575 bool internal,
bool foreign)
2604 bool internal,
bool foreign)
2633 bool internal,
bool foreign)
2662 bool internal,
bool foreign)
2680 bool internal,
bool foreign)
2742 #ifdef STATIC_ANALYZER
2747 &our_name, SIZE_MAX,
2767 if ((
size_t) (p -
buffer) == len) {
2777 namespace = dict_attr_namespace(parent);
2781 fr_sbuff_set_to_start(&our_name);
2787 if (
parent->flags.is_root) {
2798 fr_sbuff_set_to_start(&our_name);
2822 namespace = dict_attr_namespace(parent);
2831 if (
parent->flags.is_root) {
2867 if (!da)
return NULL;
2893 if (!children)
return NULL;
2899 if ((attr & 0xff) > talloc_array_length(children))
return NULL;
2901 bin = children[attr & 0xff];
2903 if (!bin)
return NULL;
2904 if (bin->attr == attr) {
2907 memcpy(&
out, &bin,
sizeof(bin));
2930 if (!da)
return NULL;
2966 if (
value->type != da->type)
return NULL;
2984 if (!dv)
return NULL;
2996 if (!
name)
return NULL;
3010 if (len < 0) len = strlen(
name);
3023 size_t found_len = 0;
3037 int len = (p -
name) + 1;
3044 fr_sbuff_next(&our_in);
3116 bool seen_alpha =
false;
3120 fr_sbuff_next(&our_in);
3132 fr_sbuff_set_to_start(&our_in);
3157 if (!
name)
return 0;
3160 for (p = module_name, q = p + talloc_array_length(p) - 1; p < q; p++) *p = tolower((
uint8_t) *p);
3272 if (found->
count == 0) {
3274 dependent,
dict->root->name);
3278 if (--found->
count == 0) {
3307 fprintf(stderr,
"DEPENDENTS FOR %s\n",
dict->root->name);
3323 if (!
dict->autoref)
return 0;
3333 for (i = 0; i < talloc_array_length(refd_list); i++) {
3335 fr_strerror_printf(
"failed freeing autoloaded protocol %s", refd_list[i]->root->name);
3340 TALLOC_FREE(
dict->autoref);
3351 if (
dict !=
dict->gctx->internal) {
3354 if (
dict->gctx->attr_protocol_encapsulation &&
dict->root) {
3360 #ifdef STATIC_ANALYZER
3370 if (
dict->proto &&
dict->proto->free) {
3371 dict->proto->free();
3378 dict->in_protocol_by_name =
false;
3384 dict->in_protocol_by_num =
false;
3414 if (
dict ==
dict->gctx->internal) {
3415 dict->gctx->internal = NULL;
3416 dict->gctx->attr_protocol_encapsulation = NULL;
3433 fr_strerror_const(
"Initialise global dictionary ctx with fr_dict_global_ctx_init()");
3463 if (!
dict->vendors_by_name) {
3473 if (!
dict->vendors_by_num) {
3482 if (!
dict->autoref) {
3495 dict->default_type_size = 1;
3496 dict->default_type_length = 1;
3526 if (!
dict)
return NULL;
3531 dict->default_type_size = 2;
3532 dict->default_type_length = 2;
3583 if (!*
dict)
return 0;
3613 for (p = to_load; p->
out; p++) {
3622 "an entry to load the attribute \"%s\" is located in, and that "
3623 "the fr_dict_autoload_attr_t symbol name is correct", p->
name);
3652 for (p = to_load; p->
out; p++) {
3659 fr_strerror_printf(
"Autoloader autoloader can't resolve attribute \"%s\", dictionary not loaded", p->
name);
3661 "an entry to load the dictionary \"%s\" is located in, and that "
3662 "the fr_dict_autoload_t symbol name is correct", p->
name);
3669 *p->
dict ? (*p->
dict)->root->name :
"internal");
3673 if (da->type != p->
type) {
3674 fr_strerror_printf(
"Autoloader attribute \"%s\" should be type %s, but defined as type %s", da->name,
3682 if (p->
out) *(p->
out) = da;
3700 for (p = to_load; p->
out; p++) {
3711 if (strcmp(p->
proto,
"freeradius") == 0) {
3733 for (p = to_free; p->
out; p++) {
3736 if (!*p->
out)
continue;
3739 if (ret == 0) *p->
out = NULL;
3740 if (ret < 0)
return -1;
3794 dict_ref->
dependent = talloc_strdup(dict_ref, dependent);
3893 #define COPY(_x) dict->_x = proto->_x
3894 COPY(default_type_size);
3895 COPY(default_type_length);
3897 COPY(subtype_table_len);
3912 bool still_loaded =
false;
3941 still_loaded =
true;
4111 dict->read_only =
true;
4116 dict->read_only =
true;
4216 char const *p =
name, *end;
4217 bool unknown =
false;
4220 if (len < 0) len = strlen(
name);
4232 if ((len > 5) && (memcmp(
name,
"Attr-", 5) == 0)) unknown =
true;
4235 if ((*p ==
'.') && unknown) p++;
4259 char const *p =
name, *end;
4262 if (len < 0) len = strlen(
name);
4277 if (!alnum)
return 0;
4295 size_t len, i, start;
4297 if (!
parent || !prev)
return NULL;
4303 if (!children)
return NULL;
4308 }
else if ((*prev)->next) {
4313 return (*prev)->next;
4320 start = (*prev)->attr & 0xff;
4321 if (start == 255)
return NULL;
4333 len = talloc_array_length(children);
4334 for (i = start; i < len; i++) {
4335 bin = &children[i & 0xff];
4337 if (*bin)
return *bin;
4355 len = talloc_array_length(children);
4356 for (i = 0; i < len; i++) {
4360 if (!children[i])
continue;
4362 for (bin = children[i]; bin; bin = bin->next) {
4364 if (ret < 0)
return ret;
4386 if ((!da->flags.is_root) && (da->depth == 0)) {
4387 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t %s vendor: %i, attr %i: "
4388 "Is not root, but depth is 0",
4393 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t %s vendor: %i, attr %i: "
4394 "Indicated depth (%u) greater than TLV stack depth (%u)",
4399 for (da_p = da; da_p; da_p = da_p->next) {
4403 for (i = da->depth, da_p = da; (i >= 0) && da; i--, da_p = da_p->parent) {
4404 if (i != (
int)da_p->depth) {
4405 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t %s vendor: %i, attr %i: "
4406 "Depth out of sequence, expected %i, got %u",
4413 fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t top of hierarchy was not at depth 0",
4429 "CONSISTENCY CHECK FAILED %s[%u]: %s missing 'children' extension",
4434 "CONSISTENCY CHECK FAILED %s[%u]: %s missing 'namespace' extension",
4469 if (child->parent ==
parent)
return true;
4471 if (child->flags.is_raw)
return true;
4480 return (child->parent->parent ==
parent);
4511 if (child->dict !=
parent->dict) {
4516 return (ref && (ref->dict == child->dict));
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.
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_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.
#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.
struct dict_attr_s fr_dict_attr_t
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
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
fr_hash_table_t * name_by_value
Lookup a name by value.
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.
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 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.
static uint32_t fr_dict_vendor_num_by_da(fr_dict_attr_t const *da)
Return the vendor number for an attribute.
fr_dict_attr_t const * ref
reference, only for FR_TYPE_GROUP
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)
static int dict_attr_children_set(fr_dict_attr_t const *da, fr_dict_attr_t const **children)
static void * dict_attr_ext_alloc_size(fr_dict_attr_t **da_p, fr_dict_attr_ext_t ext, size_t ext_len)
Allocate an attribute extension of a particular size.
static void * dict_attr_ext_alloc(fr_dict_attr_t **da_p, fr_dict_attr_ext_t ext)
Allocate an attribute extension.
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_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)
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 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.
dl_loader_t * dict_loader
for protocol validation
char const * dependent
File holding the reference.
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.
bool perm_check
Whether we should check dictionary file permissions as they're loaded.
int count
How many references are held by this file.
bool dict_attr_fields_valid(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, int *attr, fr_type_t type, fr_dict_attr_flags_t *flags)
Validate a new attribute definition.
Optional arguments for initialising/allocating attributes.
Entry recording dictionary reference holders by file.
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_init(fr_dict_global_ctx_iter_t *iter)
Iterate protocols by name.
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.
dl_t * fr_dict_dl(fr_dict_t const *dict)
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.
char const * fr_dict_global_ctx_dir(void)
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_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.
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)
fr_dict_attr_t * fr_dict_attr_unconst(fr_dict_attr_t const *da)
Coerce to non-const.
static int _dict_free(fr_dict_t *dict)
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 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.
fr_dict_t * dict_by_da(fr_dict_attr_t const *da)
Internal version of fr_dict_by_da.
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)
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_t * fr_dict_protocol_alloc(fr_dict_t const *parent)
Allocate a new local dictionary.
static void dependent_debug(fr_dict_t *dict)
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.
static int _dict_validation_onload(dl_t const *dl, void *symbol, UNUSED void *user_ctx)
Callback to automatically load validation routines for dictionaries.
fr_dict_attr_t * dict_attr_alloc_null(TALLOC_CTX *ctx)
Allocate a partially completed attribute.
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.
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.
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 int dict_attr_compatible(fr_dict_attr_t const *parent, fr_dict_attr_t const *old, fr_dict_attr_t const *n)
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.
static int8_t _dict_dependent_cmp(void const *a, void const *b)
Find a dependent in the tree of dependents.
fr_dict_attr_t const * fr_dict_attr_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.
int dict_attr_init(fr_dict_attr_t **da_p, fr_dict_attr_t const *parent, char const *name, int attr, fr_type_t type, dict_attr_args_t const *args)
Initialise fields in a dictionary attribute structure.
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.
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 fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, int attr, fr_type_t type, fr_dict_attr_flags_t const *flags)
Add an attribute to the dictionary.
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.
fr_dict_t const * fr_dict_by_protocol_num(unsigned int num)
Lookup a protocol by its number.
fr_dict_t * dict_by_protocol_num(unsigned int num)
Internal version of fr_dict_by_protocol_num.
fr_dict_t const * fr_dict_by_protocol_name(char const *name)
Lookup a protocol by its name.
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.
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.
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.
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.
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.
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.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
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_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.
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.
fr_dict_t * dict_by_protocol_name(char const *name)
Internal version of fr_dict_by_protocol_name.
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.
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_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.
fr_dict_t * dict_alloc(TALLOC_CTX *ctx)
Allocate a new dictionary.
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_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.
static uint32_t dict_protocol_name_hash(void const *data)
Wrap name hash function for fr_dict_protocol_t.
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.
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.
fr_dict_enum_value_t * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
fr_dict_t const * fr_dict_internal(void)
fr_dict_t * fr_dict_unconst(fr_dict_t const *dict)
Coerce to non-const.
static int dict_attr_namespace_init(fr_dict_attr_t **da_p)
Initialise a per-attribute namespace.
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_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_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_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_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(* 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.
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_t * fr_dict_global_ctx_iter_next(fr_dict_global_ctx_iter_t *iter)
int _fr_dict_autoload(fr_dict_autoload_t const *to_load, char const *dependent)
Process a dict_autoload element to load a protocol.
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_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.
fr_dict_attr_t * dict_attr_alloc(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.
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.
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.
fr_dict_protocol_t const * fr_dict_protocol(fr_dict_t const *dict)
Return the protocol descriptor for the dictionary.
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.
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.
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.
char const * dependent
Dependent that loaded the dictionary.
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_gctx_t * fr_dict_global_ctx_init(TALLOC_CTX *ctx, bool free_at_exit, char const *dict_dir)
Initialise the global protocol hashes.
static int dict_attr_ref_init(fr_dict_attr_t **da_p, fr_dict_attr_t const *ref)
Set a reference for a grouping attribute or an alias attribute.
fr_dict_attr_t * dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *name)
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.
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.
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.
int dl_symbol_init_cb_register(dl_loader_t *dl_loader, unsigned int priority, char const *symbol, dl_onload_t func, void *uctx)
Register a callback to execute when a dl with a particular symbol is first loaded.
int dl_free(dl_t const *dl)
"free" a dl handle, possibly actually freeing it, and unloading the library
void * uctx
API client's opaque data.
void * fr_hash_table_iter_init(fr_hash_table_t *ht, fr_hash_iter_t *iter)
Initialise an iterator.
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.
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.
#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.
static fr_table_num_ordered_t const subtype_table[]
@ FR_TYPE_INT8
8 Bit signed integer.
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_INT64
64 Bit signed integer.
@ FR_TYPE_INT16
16 Bit signed integer.
@ 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_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])
static size_t array[MY_ARRAY_SIZE]
int strncasecmp(char *s1, char *s2, int n)
int strcasecmp(char *s1, char *s2)
static bool attr_valid(UNUSED fr_dict_t *dict, UNUSED fr_dict_attr_t const *parent, UNUSED char const *name, UNUSED int attr, fr_type_t type, fr_dict_attr_flags_t *flags)
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_next_inorder(fr_rb_iter_inorder_t *iter)
Return the next 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)
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_find(fr_rb_tree_t const *tree, void const *data)
Find an element in the tree, returning the data, not the node.
#define fr_rb_inline_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black tree.
Iterator structure for in-order traversal of an rbtree.
static request_init_args_t default_args
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(_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_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
#define talloc_get_type_abort_const
static int talloc_const_free(void const *ptr)
Free const'd memory.
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_structural[FR_TYPE_MAX+1]
#define fr_type_is_non_leaf(_x)
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
#define fr_type_is_structural(_x)
#define FR_TYPE_STRUCTURAL
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.
FR_SBUFF_SET_RETURN(sbuff, &our_sbuff)
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
#define fr_box_strvalue_len(_val, _len)
static size_t char ** out