26RCSID(
"$Id: 646c727293efc6c076dc809c408f2a914fdbb3aa $")
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>
56static char const *
mib = NULL;
62#define DEBUG2(fmt, ...) if (fr_log_fp && (fr_debug_lvl > 2)) fprintf(fr_log_fp , fmt "\n", ## __VA_ARGS__)
63#define DEBUG(fmt, ...) if (fr_log_fp && (fr_debug_lvl > 1)) fprintf(fr_log_fp , fmt "\n", ## __VA_ARGS__)
64#define INFO(fmt, ...) if (fr_log_fp && (fr_debug_lvl > 0)) fprintf(fr_log_fp , fmt "\n", ## __VA_ARGS__)
69 fprintf(stderr,
"usage: radict [OPTS] [attribute...]\n");
70 fprintf(stderr,
" -A Export aliases.\n");
71 fprintf(stderr,
" -c Print out in CSV format.\n");
72 fprintf(stderr,
" -D <dictdir> Set main dictionary directory (defaults to " DICTDIR
").\n");
73 fprintf(stderr,
" -f Export dictionary definitions in the normal dictionary format\n");
74 fprintf(stderr,
" -F <format> Set output format. Use 'csv', 'full', or 'dictionary'\n");
75 fprintf(stderr,
" -E Export dictionary definitions.\n");
76 fprintf(stderr,
" -h Print help text.\n");
77 fprintf(stderr,
" -H Show the headers of each field.\n");
78 fprintf(stderr,
" -M <name> Mangle names for MIB, and set MIB root.\n");
79 fprintf(stderr,
" -p <protocol> Set protocol by name\n");
80 fprintf(stderr,
" -r Write out attributes recursively.\n");
81 fprintf(stderr,
" -V Write out all attribute values.\n");
82 fprintf(stderr,
" -x Debugging mode.\n");
83 fprintf(stderr,
"\n");
84 fprintf(stderr,
"Very simple interface to extract attribute definitions from FreeRADIUS dictionaries\n");
87static int load_dicts(
char const *dict_dir,
char const *protocol)
93 DEBUG(
"Reading directory %s", dict_dir);
95 dir = opendir(dict_dir);
101 while ((dp = readdir(dir)) != NULL) {
102 struct stat stat_buff;
105 if (dp->d_name[0] ==
'.')
continue;
110 if (protocol && (strcmp(dp->d_name, protocol) != 0))
continue;
115 if (strcmp(dp->d_name,
"freeradius") == 0)
continue;
117 file_str = talloc_asprintf(NULL,
"%s/%s", dict_dir, dp->d_name);
119 if (stat(file_str, &stat_buff) == -1) {
130 if ((stat_buff.st_mode & S_IFMT) == S_IFDIR) {
132 struct stat dict_stat_buff;
135 dict_file = talloc_asprintf(NULL,
"%s/dictionary", file_str);
136 ret = stat(dict_file, &dict_stat_buff);
149 DEBUG(
"Loading dictionary: %s/dictionary", file_str);
200 if (!da->flags.is_alias) {
213 printf(
"%s,%s,%s,%d,%s,%s\n",
224 printf(
"%s\t%s\t%s\t%d\t%s\t%s\n",
246 str =
fr_asprintf(NULL,
"%s,%s,%s,%d,%s,%s,%s,%pV",
259 str =
fr_asprintf(NULL,
"%s\t%s\t%s\t%d\t%s\t%s\t%s\t%pV",
280 namespace = dict_attr_namespace(da);
324 char const *start = da->name;
333 if (
mib && da->parent) {
336 len = strlen(da->parent->name);
344 mangle = (strncmp(da->parent->name, da->name, len) == 0);
348 len = strlen(root->name);
349 mangle = (
strncasecmp(root->name, da->name, len) == 0);
352 if (mangle) start += len;
357 for (p = start; *p !=
'\0'; p++) {
358 if ((*p >=
'0') && (*p <=
'9')) {
363 if (islower((
unsigned int) *p)) {
368 if (isupper((
unsigned int) *p)) {
369 if (mangle && (p > start)) {
373 *q++ = tolower((
unsigned int)*p);
388 fprintf(fp,
"%s",
buffer);
419#define CHECK_TYPE(_parent) \
421 if ((parent->type != FR_TYPE_STRUCT) && (parent->type != FR_TYPE_TLV)) { \
422 fprintf(stderr, "%s is not a struct or tlv\n", parent->name); \
425 if (!children_ok(parent)) fr_exit(EXIT_FAILURE); \
440 fprintf(fp,
"/*\n *\t%s\n */\n",
parent->name);
441 fprintf(fp,
"typedef struct {\n");
444 unsigned int length = 0;
458 fprintf(fp,
"\tunsigned int : %u\t", da->flags.length);
460 }
else switch (da->type) {
470 length = da->flags.length;
489 fprintf(fp,
"[%u]", length);
497 fprintf(fp,
"fr_stats_");
501 fprintf(fp,
"_t;\n");
514 fprintf(fp,
"static fr_dict_attr_t const *attr_%s;\n",
parent_name);
517 fprintf(fp,
"static fr_dict_attr_t const *attr_%s_",
parent_name);
528#define ENUM_NAME(_x) [_x] = STRINGIFY(_x)
577 int i, num_elements = 0;
587 fprintf(fp,
"fr_stats_link_t const fr_stats_link_%s_%s = {\n", dict_name,
parent_name);
589 fprintf(fp,
"\t.name = \"fr_stats_%s_%s_t\",\n", dict_name,
parent_name);
590 fprintf(fp,
"\t.root_p = &attr_%s,\n",
parent_name);
591 if (
mib) fprintf(fp,
"\t.mib = \"%s\",\n",
mib);
592 fprintf(fp,
"\t.size = sizeof(fr_stats_%s_%s_t),\n", dict_name,
parent_name);
597 fprintf(fp,
"\t.num_elements = %d,\n", num_elements);
599 fprintf(fp,
"\t.entry = {\n");
606 fprintf(fp,
"\t\t{\n");
607 fprintf(fp,
"\t\t\t.da_p = &attr_%s_",
parent_name);
613 fprintf(fp,
"\t\t\t.offset = offsetof(fr_stats_%s_%s_t, ", dict_name,
parent_name);
617 fprintf(fp,
"\t\t\t.size = %u,\n", da->flags.length);
619 fprintf(fp,
"\t\t},\n");
622 fprintf(fp,
"\t},\n");
623 fprintf(fp,
"};\n\n");
641 fprintf(fp,
"{ .out = &attr_%s, .name = \"%s\", .type = %s, .dict = &dict_%s },\n",
650 fprintf(fp,
", .name = \".%s\", .type = %s, .dict = &dict_%s },\n",
671 fprintf(fp,
"/*\n * fr_stats_%s_%s_instance_t\n */\n", dict_name,
parent_name);
672 fprintf(fp,
"FR_STATS_TYPEDEF(%s_%s);\n\n", dict_name,
parent_name);
674 fprintf(fp,
"extern fr_stats_link_t const fr_stats_link_%s_%s;\n\n", dict_name,
parent_name);
692 if (!da->flags.is_root) {
693 if (low && ((uintptr_t)da < *low)) {
694 *low = (uintptr_t)da;
696 if (high && ((uintptr_t)da > *high)) {
697 *high = (uintptr_t)da;
703 if (
count) (*count)++;
710 len = talloc_array_length(children);
711 for (i = 0; i < len; i++) {
712 for (p = children[i]; p; p = p->next) {
722 if (low) *low = UINTPTR_MAX;
741 {
L(
"fancy"), NULL },
759int main(
int argc,
char *argv[])
761 char const *dict_dir = DICTDIR;
766 bool file_export =
false;
768 char const *protocol = NULL;
787 talloc_set_log_stderr();
792 while ((c = getopt(argc, argv,
"AcfF:ED:M:p:rVxhH")) != -1)
switch (c) {
812 fprintf(stderr,
"Invalid output format '%s'\n", optarg);
865 fr_perror(
"radict - Global context init failed");
873 fr_perror(
"radict - Loading internal dictionary failed");
883 fr_perror(
"radict - Loading dictionaries failed");
889 fr_perror(
"radict - No dictionaries loaded");
896 printf(
"Dictionary,OID,Attribute,ID,Type,Flags\n");
901 printf(
"Dictionary\tOID\tAttribute\tID\tType\tFlags\n");
924 DEBUG2(
"Memory allocd %zu (bytes)", talloc_total_size(*dict_p));
925 DEBUG2(
"Memory spread %zu (bytes)", (
size_t) (high - low));
943 if (argc == 0)
goto finish;
961 DEBUG2(
"Dictionary %s does not contain attribute %s\n",
976 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.
static TALLOC_CTX * autofree
#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)
Registers signal handlers to execute panic_action on fatal signal.
#define fr_exit(_x)
Exit, producing a log message in debug builds.
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_internal_afrom_file(fr_dict_t **out, char const *internal_name, char const *dependent)
(Re-)Initialize the special internal dictionary
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)
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
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.
@ FR_DICT_ATTR_EXT_ENUMV
Enumeration values.
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.
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)
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)
char * fr_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Special version of asprintf which implements custom format specifiers.
static char const * fr_type_to_enum_name[]
int main(int argc, char *argv[])
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.
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 void raddict_export(uint64_t *count, uintptr_t *low, uintptr_t *high, fr_dict_t *dict)
static void da_print_stats_h(FILE *fp, fr_dict_attr_t const *parent)
static bool print_recursive
static fr_dict_t * dicts[255]
static bool print_headers
static char const * length_to_c_type[]
static const bool type_allowed[FR_TYPE_MAX]
static void da_normalize_name(fr_dict_attr_t const *da, char buffer[static FR_DICT_ATTR_MAX_NAME_LEN+1])
static size_t format_table_len
static fr_table_ptr_ordered_t const function_table[]
static size_t function_table_len
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)
#define CHECK_TYPE(_parent)
static void _raddict_export(fr_dict_t const *dict, uint64_t *count, uintptr_t *low, uintptr_t *high, fr_dict_attr_t const *da, unsigned int lvl)
static char const * type_to_c_type[]
@ RADICT_OUT_ATTR_AUTOLOAD
@ RADICT_OUT_BASE_C_DA_DEF
static char const * parent_oid
void(* da_print_func_t)(FILE *fp, fr_dict_attr_t const *da)
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.
#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.
#define talloc_autofree_context
The original function is deprecated, so replace it with our version.
#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)
#define fr_type_is_structural(_x)
@ FR_TYPE_UNION
A union of limited children.
@ FR_TYPE_ATTR
A contains an attribute reference.
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