26RCSID(
"$Id: d93822134153d8dd3659dd2569a3927e9138d845 $")
28#include <freeradius-devel/util/conf.h>
29#include <freeradius-devel/util/syserror.h>
30#include <freeradius-devel/util/atexit.h>
31#include <freeradius-devel/util/dict_priv.h>
32#include <freeradius-devel/util/hash.h>
59static char const *
mib = NULL;
65#define DEBUG2(fmt, ...) if (fr_log_fp && (fr_debug_lvl > 2)) fr_fprintf(fr_log_fp , fmt "\n", ## __VA_ARGS__)
66#define DEBUG(fmt, ...) if (fr_log_fp && (fr_debug_lvl > 1)) fr_fprintf(fr_log_fp , fmt "\n", ## __VA_ARGS__)
67#define INFO(fmt, ...) if (fr_log_fp && (fr_debug_lvl > 0)) fr_fprintf(fr_log_fp , fmt "\n", ## __VA_ARGS__)
72 fprintf(stderr,
"usage: radict [OPTS] [attribute...]\n");
73 fprintf(stderr,
" -A Export aliases.\n");
74 fprintf(stderr,
" -c Print out in CSV format.\n");
75 fprintf(stderr,
" -D <dictdir> Set main dictionary directory (defaults to " DICTDIR
").\n");
76 fprintf(stderr,
" -f Export dictionary definitions in the normal dictionary format\n");
77 fprintf(stderr,
" -F <format> Set output format. Use 'csv', 'full', or 'dictionary'\n");
78 fprintf(stderr,
" -E Export dictionary definitions.\n");
79 fprintf(stderr,
" -h Print help text.\n");
80 fprintf(stderr,
" -H Show the headers of each field.\n");
81 fprintf(stderr,
" -M <name> Mangle names for MIB, and set MIB root.\n");
82 fprintf(stderr,
" -O Print the pool size and the bytes used for each protocol dictionary,\n");
83 fprintf(stderr,
" and exit with an error if any protocol dictionary overflows its pool.\n");
84 fprintf(stderr,
" -p <protocol> Set protocol by name\n");
85 fprintf(stderr,
" -P <percent> Measure the memory that each protocol dictionary uses, then set pool= on\n");
86 fprintf(stderr,
" the PROTOCOL line of the dictionary to the measured size plus <percent> percent.\n");
87 fprintf(stderr,
" -r Write out attributes recursively.\n");
88 fprintf(stderr,
" -V Write out all attribute values.\n");
89 fprintf(stderr,
" -x Debugging mode.\n");
90 fprintf(stderr,
"\n");
91 fprintf(stderr,
"Very simple interface to extract attribute definitions from FreeRADIUS dictionaries\n");
94static int load_dicts(
char const *dict_dir,
char const *protocol)
100 DEBUG(
"Reading directory %s", dict_dir);
102 dir = opendir(dict_dir);
108 while ((dp = readdir(dir)) != NULL) {
109 struct stat stat_buff;
112 if (dp->d_name[0] ==
'.')
continue;
117 if (protocol && (strcmp(dp->d_name, protocol) != 0))
continue;
122 if (strcmp(dp->d_name,
"freeradius") == 0)
continue;
126 if (stat(file_str, &stat_buff) == -1) {
137 if ((stat_buff.st_mode & S_IFMT) == S_IFDIR) {
139 struct stat dict_stat_buff;
143 ret = stat(dict_file, &dict_stat_buff);
156 DEBUG(
"Loading dictionary: %s/dictionary", file_str);
207 if (!da->flags.is_alias) {
220 printf(
"%s,%s,%s,%u,%s,%s\n",
231 printf(
"%s\t%s\t%s\t%u\t%s\t%s\n",
253 str =
fr_asprintf(NULL,
"%s,%s,%s,%u,%s,%s,%s,%pV",
266 str =
fr_asprintf(NULL,
"%s\t%s\t%s\t%u\t%s\t%s\t%s\t%pV",
287 namespace = dict_attr_namespace(da);
334 char const *start = da->name;
343 if (
mib && da->parent) {
346 len = strlen(da->parent->name);
354 mangle = (strncmp(da->parent->name, da->name,
len) == 0);
358 len = strlen(root->name);
362 if (mangle) start +=
len;
367 for (p = start; *p !=
'\0'; p++) {
368 if ((*p >=
'0') && (*p <=
'9')) {
373 if (islower((
unsigned int) *p)) {
378 if (isupper((
unsigned int) *p)) {
379 if (mangle && (p > start)) {
383 *q++ = tolower((
unsigned int)*p);
398 fprintf(fp,
"%s",
buffer);
429#define CHECK_TYPE(_parent) \
431 if ((parent->type != FR_TYPE_STRUCT) && (parent->type != FR_TYPE_TLV)) { \
432 fprintf(stderr, "%s is not a struct or tlv\n", parent->name); \
435 if (!children_ok(parent)) fr_exit(EXIT_FAILURE); \
450 fprintf(fp,
"/*\n *\t%s\n */\n",
parent->name);
451 fprintf(fp,
"typedef struct {\n");
454 unsigned int length = 0;
468 fprintf(fp,
"\tunsigned int : %u\t", da->flags.length);
470 }
else switch (da->type) {
480 length = da->flags.length;
499 fprintf(fp,
"[%u]", length);
507 fprintf(fp,
"fr_stats_");
511 fprintf(fp,
"_t;\n");
524 fprintf(fp,
"static fr_dict_attr_t const *attr_%s;\n",
parent_name);
527 fprintf(fp,
"static fr_dict_attr_t const *attr_%s_",
parent_name);
538#define ENUM_NAME(_x) [_x] = STRINGIFY(_x)
587 int i, num_elements = 0;
597 fprintf(fp,
"fr_stats_link_t const fr_stats_link_%s_%s = {\n", dict_name,
parent_name);
599 fprintf(fp,
"\t.name = \"fr_stats_%s_%s_t\",\n", dict_name,
parent_name);
600 fprintf(fp,
"\t.root_p = &attr_%s,\n",
parent_name);
601 if (
mib) fprintf(fp,
"\t.mib = \"%s\",\n",
mib);
602 fprintf(fp,
"\t.size = sizeof(fr_stats_%s_%s_t),\n", dict_name,
parent_name);
607 fprintf(fp,
"\t.num_elements = %d,\n", num_elements);
609 fprintf(fp,
"\t.entry = {\n");
616 fprintf(fp,
"\t\t{\n");
617 fprintf(fp,
"\t\t\t.da_p = &attr_%s_",
parent_name);
623 fprintf(fp,
"\t\t\t.offset = offsetof(fr_stats_%s_%s_t, ", dict_name,
parent_name);
627 fprintf(fp,
"\t\t\t.size = %u,\n", da->flags.length);
629 fprintf(fp,
"\t\t},\n");
632 fprintf(fp,
"\t},\n");
633 fprintf(fp,
"};\n\n");
651 fprintf(fp,
"{ .out = &attr_%s, .name = \"%s\", .type = %s, .dict = &dict_%s },\n",
660 fprintf(fp,
", .name = \".%s\", .type = %s, .dict = &dict_%s },\n",
681 fprintf(fp,
"/*\n * fr_stats_%s_%s_instance_t\n */\n", dict_name,
parent_name);
682 fprintf(fp,
"FR_STATS_TYPEDEF(%s_%s);\n\n", dict_name,
parent_name);
684 fprintf(fp,
"extern fr_stats_link_t const fr_stats_link_%s_%s;\n\n", dict_name,
parent_name);
711 if (!da->flags.is_root) {
712 uintptr_t addr = (uintptr_t)da;
714 if (!stats->
found || (addr < stats->low)) {
717 if (!stats->
found || (addr > stats->
high)) {
732 len = talloc_array_length(children);
733 for (i = 0; i <
len; i++) {
734 for (p = children[i]; p; p = p->next) {
754 {
L(
"fancy"), NULL },
773#define RADICT_POOL_MAX_SIZE ((size_t)64 * 1000 * 1000)
777#define RADICT_POOL_STEP_SIZE ((size_t)10 * 1000 * 1000)
790 size_t overflow_max = 0;
799 if (!overflowed)
continue;
802 if (
dict->pool_size > overflow_max) overflow_max =
dict->pool_size;
817static char const *
line_field_next(
char const **field_end,
char const *p,
char const *end)
819 while ((p < end) && isspace((
uint8_t)*p)) {
822 if ((p == end) || (*p ==
'#'))
return NULL;
825 while ((*field_end < end) && !isspace((
uint8_t)**field_end)) {
834static bool line_field_is(
char const *field,
char const *field_end,
char const *keyword)
836 size_t len = strlen(keyword);
838 return ((
size_t)(field_end - field) ==
len) && (
strncasecmp(field, keyword,
len) == 0);
850 old_umask = umask(S_IRWXG | S_IRWXO);
859 if (fchmod(fd, mode & 07777) < 0) {
873 if (errno == EINTR)
continue;
888 if (rename(tmp, filename) < 0) {
924 char const *field, *field_end, *number_end, *opts, *opts_end = NULL;
925 char *new_opts, *
out;
929 fp = fopen(filename,
"r");
934 if (fstat(fileno(fp), &st) < 0) {
940 MEM(buf = talloc_array(NULL,
char, st.st_size + 1));
941 len = fread(buf, 1, st.st_size, fp);
942 if (ferror(fp) || (
len != (
size_t)st.st_size)) {
956 for (i = 1; i < root->line; i++) {
959 nl = memchr(
line,
'\n', buf_end -
line);
961 fr_strerror_printf(
"Failed finding the PROTOCOL line, \"%s\" has fewer than %u lines",
962 filename, root->line);
975 if (!field || !
line_field_is(field, field_end,
"PROTOCOL") ||
979 "[BEGIN] PROTOCOL <name> <number>", root->name, filename, root->line);
982 number_end = field_end;
992 for (p = opts; p < opts_end; p = q + 1) {
993 q = memchr(p,
',', opts_end - p);
994 if (!q) q = opts_end;
996 if (((q - p) >= 5) && (strncmp(p,
"pool=", 5) == 0))
continue;
998 MEM(new_opts = talloc_asprintf_append_buffer(new_opts,
"%s%.*s",
999 new_opts[0] ?
"," :
"", (int)(q - p), p));
1002 MEM(new_opts = talloc_asprintf_append_buffer(new_opts,
"%spool=%zuMB", new_opts[0] ?
"," :
"", pool_mb));
1011 (
int)(opts - buf), buf, new_opts, opts_end));
1014 (
int)(number_end - buf), buf, new_opts, number_end));
1050 size_t used, live, pool_mb;
1057 if (root->file == 0)
continue;
1070 pool_mb = ((
used + (
used * overhead) / 100) + (1000 * 1000) - 1) / (1000 * 1000);
1072 fr_fprintf(stdout,
"%s\t%s[%u]\tused %pV\tpool=%zuMB\n",
1108 if (root->file == 0)
continue;
1112 fr_fprintf(stdout,
"%s\t%s[%u]\tpool %pV\tused %pV\tlive %pV\tholes %pV\ttail %pV\n",
1119 fr_fprintf(stdout,
"%s\t%s[%u]\tpool %pV\toverflowed\n",
1121 fr_strerror_printf(
"%s overflowed its %pV pool, run radict -P to set a larger pool= on %s[%u]",
1146 fr_perror(
"radict - Global context init failed");
1155 fr_perror(
"radict - Loading internal dictionary failed");
1164 fr_perror(
"radict - Loading dictionaries failed");
1193 fr_perror(
"radict - Error freeing dictionaries");
1216 size_t overflow_max;
1222 fr_strerror_printf(
"Stopping, a dictionary overflowed a %pV pool and the next pool would be "
1223 "larger than RADICT_POOL_MAX_SIZE (%pV)",
1229 DEBUG(
"Reloading the dictionaries with pools of at least %pV",
fr_box_size(pool_size_min));
1232 if (
dicts_load(gctx_p, dict_dir, protocol, pool_size_min) < 0)
return -1;
1244 char const *dict_dir = DICTDIR;
1248 bool export =
false;
1249 bool file_export =
false;
1251 char const *protocol = NULL;
1254 bool pool_set =
false;
1255 bool pool_check =
false;
1256 unsigned int pool_overhead = 0;
1272 talloc_set_log_stderr();
1277 while ((c = getopt(argc, argv,
"AcfF:ED:M:Op:P:rVxhH")) != -1)
switch (c) {
1297 fprintf(stderr,
"Invalid output format '%s'\n", optarg);
1327 unsigned long overhead;
1329 overhead = strtoul(optarg, &q, 10);
1330 if ((q == optarg) || (*q !=
'\0') || (overhead > 1000)) {
1331 fprintf(stderr,
"Invalid -P percentage '%s', expected an integer from 0 to 1000\n", optarg);
1334 pool_overhead = overhead;
1368 if (
dicts_load(&gctx, dict_dir, protocol, 0) < 0) {
1374 fr_perror(
"radict - No dictionaries loaded");
1392 printf(
"Dictionary,OID,Attribute,ID,Type,Flags\n");
1397 printf(
"Dictionary\tOID\tAttribute\tID\tType\tFlags\n");
1425 DEBUG2(
"Pool used overflowed");
1449 if (argc == 0)
goto finish;
1451 while (argc-- > 0) {
1467 DEBUG2(
"Dictionary %s does not contain attribute %s\n",
1482 if (!found) ret = 64;
static int const char char buffer[256]
int fr_atexit_global_setup(void)
Setup the atexit handler, should be called at the start of a program's execution.
int fr_atexit_global_trigger_all(void)
Cause all global free triggers to fire.
#define L(_str)
Helper for initialising arrays of string literals.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
int fr_fault_setup(TALLOC_CTX *ctx, char const *cmd, char const *program, unsigned long fault_signals)
Registers signal handlers to execute panic_action on fatal signal.
#define fr_exit(_x)
Exit, producing a log message in debug builds.
#define fr_cond_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
#define PANIC_ACTION_SIGNALS
@ FR_DICT_ATTR_EXT_ENUMV
Enumeration values.
fr_dict_t const * fr_dict_by_da(fr_dict_attr_t const *da)
Attempt to locate the protocol dictionary containing an attribute.
void fr_dict_alias_export(FILE *fp, fr_dict_attr_t const *parent)
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
#define da_is_bit_field(_da)
fr_value_box_t const * value
Enum value (what name maps to).
int fr_dict_free(fr_dict_t **dict, char const *dependent)
Decrement the reference count on a previously loaded dictionary.
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
char const * fr_dict_attr_filename(fr_dict_attr_t const *da)
Resolve an attribute's location file id to the filename.
int fr_dict_global_ctx_free(fr_dict_gctx_t const *gctx)
Explicitly free all data associated with a global dictionary context.
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.
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.
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.
char const * name
Enum name.
#define FR_DICT_ATTR_MAX_NAME_LEN
Maximum length of a attribute name.
void fr_dict_export(FILE *fp, fr_dict_t const *dict)
Export in the standard form: ATTRIBUTE name oid flags.
Value of an enumerated attribute.
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.
Attribute extension - Holds enumeration values.
static fr_dict_attr_t const ** dict_attr_children(fr_dict_attr_t const *da)
size_t pool_size_min
Smallest pool, in bytes, that dict_alloc() creates.
fr_hash_table_t * protocol_by_name
Hash containing names of all the registered protocols.
int fr_dict_internal_afrom_file(fr_dict_t **out, char const *dict_subdir, char const *dependent)
(Re-)Initialize the special internal dictionary
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_iter_init(fr_hash_table_t *ht, fr_hash_iter_t *iter)
Initialise an iterator.
Stores the state of the current iteration operation.
@ FR_TYPE_TIME_DELTA
A period of time measured in nanoseconds.
@ FR_TYPE_FLOAT32
Single precision floating point.
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_INT8
8 Bit signed integer.
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_ETHERNET
48 Bit Mac-Address.
@ FR_TYPE_IPV6_PREFIX
IPv6 Prefix.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_MAX
Number of defined data types.
@ 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_COMBO_IP_PREFIX
IPv4 or IPv6 address prefix depending on length.
@ 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_IPV6_ADDR
128 Bit IPv6 Address.
@ FR_TYPE_IPV4_PREFIX
IPv4 Prefix.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_SIZE
Unsigned integer capable of representing any memory address on the local system.
@ FR_TYPE_VSA
Vendor-Specific, for RADIUS attribute 26.
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
@ FR_TYPE_IFID
Interface ID.
@ FR_TYPE_OCTETS
Raw octets.
@ FR_TYPE_GROUP
A grouping of other attributes.
@ FR_TYPE_FLOAT64
Double precision floating point.
ssize_t fr_dict_attr_flags_print(fr_sbuff_t *out, fr_dict_t const *dict, fr_type_t type, fr_dict_attr_flags_t const *flags)
ssize_t fr_dict_attr_oid_print(fr_sbuff_t *out, fr_dict_attr_t const *ancestor, fr_dict_attr_t const *da, bool numeric)
static uint8_t depth(fr_minmax_heap_index_t i)
int strncasecmp(char *s1, char *s2, int n)
int strcasecmp(char *s1, char *s2)
ssize_t fr_fprintf(FILE *fp, char const *fmt,...)
Special version of fprintf which implements custom format specifiers.
char * fr_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Special version of asprintf which implements custom format specifiers.
static char const * line_field_next(char const **field_end, char const *p, char const *end)
Find the next whitespace-separated field on a dictionary line.
static char const * fr_type_to_enum_name[]
int main(int argc, char *argv[])
static int file_replace(char const *filename, mode_t mode, char const *data, size_t len)
Write data to a temporary file, then rename the temporary file over filename.
static fr_dict_t ** dict_end
static void da_print_struct(FILE *fp, fr_dict_attr_t const *parent)
Print structures and mappings, mainly for statistics.
#define RADICT_POOL_STEP_SIZE
Bytes that radict -P adds to the largest overflowed pool to set the minimum pool size for the next re...
static void da_normalize_name(fr_dict_attr_t const *da, char buffer[static FR_DICT_ATTR_MAX_NAME_LEN *2+1])
static void da_print_name(FILE *fp, fr_dict_attr_t const *da)
static fr_table_num_ordered_t const format_table[]
static int load_dicts(char const *dict_dir, char const *protocol)
static void da_print_stats_link(FILE *fp, fr_dict_attr_t const *parent)
static int protocol_line_pool_set(fr_dict_t const *dict, size_t pool_mb)
Set pool=<size> on the PROTOCOL line that defines a dictionary.
static int dicts_pool_grow(fr_dict_gctx_t **gctx_p, char const *dict_dir, char const *protocol)
Reload the dictionaries with larger pools until no pool overflows.
uint64_t count
Attributes exported.
static void da_print_stats_h(FILE *fp, fr_dict_attr_t const *parent)
uintptr_t high
Highest attribute address seen.
static bool print_recursive
static fr_dict_t * dicts[255]
#define RADICT_POOL_MAX_SIZE
Largest pool that radict -P loads a dictionary with.
static bool print_headers
static char const * length_to_c_type[]
static const bool type_allowed[FR_TYPE_MAX]
static size_t format_table_len
static fr_table_ptr_ordered_t const function_table[]
bool found
low and high hold an address.
static bool line_field_is(char const *field, char const *field_end, char const *keyword)
Check whether a field is a dictionary keyword.
static size_t function_table_len
static int dicts_load(fr_dict_gctx_t **gctx_out, char const *dict_dir, char const *protocol, size_t pool_size_min)
Load the internal dictionary, then the protocol dictionaries.
static void da_print_info(fr_dict_t const *dict, fr_dict_attr_t const *da, int depth)
static void da_print_attr_autoload(FILE *fp, fr_dict_attr_t const *parent)
static void da_print_base_c_da_def(FILE *fp, fr_dict_attr_t const *parent)
uintptr_t low
Lowest attribute address seen.
#define CHECK_TYPE(_parent)
static void raddict_export(raddict_stats_t *stats, fr_dict_t const *dict, fr_dict_attr_t const *da)
@ RADICT_OUT_ATTR_AUTOLOAD
@ RADICT_OUT_BASE_C_DA_DEF
static char const * type_to_c_type[]
static char const * parent_oid
static int protocol_pools_check(fr_dict_gctx_t *gctx)
Print the pool size and the bytes used for every loaded protocol dictionary.
static int protocol_lines_pool_set(fr_dict_gctx_t *gctx, unsigned int overhead)
Set pool= on the PROTOCOL line of every loaded protocol dictionary.
void(* da_print_func_t)(FILE *fp, fr_dict_attr_t const *da)
static size_t dicts_overflow_max(fr_dict_gctx_t *gctx)
Find the size of the largest overflowed pool among the loaded protocol dictionaries.
static int dicts_free(fr_dict_gctx_t *gctx)
Release radict's references to the dictionaries, then free the global dictionary context.
static const char * spaces
static radict_out_t output_format
static bool children_ok(fr_dict_attr_t const *parent)
#define ENUM_NAME(_x)
Map data types to enum names representing those types.
Totals gathered while exporting a dictionary.
#define fr_sbuff_start(_sbuff_or_marker)
#define FR_SBUFF_OUT(_start, _len_or_end)
fr_aka_sim_id_type_t type
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
An element in an arbitrarily ordered array of name to num mappings.
An element in an arbitrarily ordered array of name to ptr mappings.
size_t talloc_pool_used(bool *overflowed, size_t *live, TALLOC_CTX const *pool, size_t pool_size)
Measure how many bytes of a talloc pool are used and live, and whether the pool overflowed.
#define talloc_autofree_context
The original function is deprecated, so replace it with our version.
#define talloc_strdup(_ctx, _str)
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
#define FR_DICTIONARY_FILE
#define FR_DICTIONARY_INTERNAL_DIR
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)
@ FR_TYPE_UNION
A union of limited children.
@ FR_TYPE_ATTR
A contains an attribute reference.
#define fr_type_is_structural(_x)
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
int fr_check_lib_magic(uint64_t magic)
Check if the application linking to the library has the correct magic number.
#define RADIUSD_MAGIC_NUMBER
static fr_sbuff_err_t char ** out
static fr_sbuff_err_t char size_t * len
#define fr_box_size(_val)