24RCSID(
"$Id: 068d1dcc0801bda1a76da2302f1541135824f0ec $")
 
   26#include <freeradius-devel/radius/defs.h> 
   27#include <freeradius-devel/util/conf.h> 
   28#include <freeradius-devel/util/dict_fixup_priv.h> 
   29#include <freeradius-devel/util/file.h> 
   30#include <freeradius-devel/util/rand.h> 
   31#include <freeradius-devel/util/syserror.h> 
   39#define DICT_MAX_ARGV (8) 
   45#define DICT_MAX_STACK (32) 
   52typedef enum CC_HINT(flag_enum) {
 
 
   61#define NEST_ANY (NEST_TOP | NEST_PROTOCOL | NEST_VENDOR | NEST_ATTRIBUTE) 
  105                           char  const *dir_name, 
char const *filename,
 
  106                           char const *src_file, 
int src_line);
 
  108#define CURRENT_FRAME(_dctx)    (&(_dctx)->stack[(_dctx)->stack_depth]) 
  109#define CURRENT_DA(_dctx)       (CURRENT_FRAME(_dctx)->da) 
  110#define CURRENT_FILENAME(_dctx) (CURRENT_FRAME(_dctx)->filename) 
  111#define CURRENT_LINE(_dctx)     (CURRENT_FRAME(_dctx)->line) 
  113#define ASSERT_CURRENT_NEST(_dctx, _nest) fr_assert_msg(CURRENT_FRAME(_dctx)->nest == (_nest), "Expected frame type %s, got %s", \ 
  114                                                fr_table_str_by_value(dict_nest_table, (_nest), "<INVALID>"), fr_table_str_by_value(dict_nest_table, CURRENT_FRAME(_dctx)->nest, "<INVALID>")) 
 
  200                        if (frame->
finalise(dctx) < 0) 
return NULL;
 
  217                if ((frame->
nest & nest) != 0) {
 
 
  239                if (argc >= max_argc) 
break;
 
  249                while ((*str == 
' ') ||
 
 
  273        int unsigned ret = 0;
 
  275        static char const *tab = 
"0123456789";
 
  277        if ((str[0] == 
'0') &&
 
  278            ((str[1] == 
'x') || (str[1] == 
'X'))) {
 
  279                tab = 
"0123456789abcdef";
 
  288                if (*str == 
'.') 
break;
 
  290                c = memchr(tab, tolower((
uint8_t)*str), base);
 
 
  333        dict->root->dict = dict;
 
 
  347        p = strchr(
name, 
'[');
 
  353                q = strchr(p + 1, 
']');
 
  373                if ((length == 0) || (length > UINT16_MAX)) {
 
  381                if (strcmp(
name, 
"octets") == 0) {
 
  384                } 
else if (strcmp(
name, 
"string") == 0) {
 
  387                } 
else if (strcmp(
name, 
"struct") == 0) {
 
  390                } 
else if (strcmp(
name, 
"union") == 0) {
 
  393                } 
else if (strcmp(
name, 
"bit") == 0) {
 
  395                                fr_strerror_const(
"Bit fields can only be defined as a MEMBER of data type 'struct'");
 
  399                        (*da_p)->flags.extra = 1;
 
  404                        } 
else if (length <= 8) {
 
  406                        } 
else if (length <= 16) {
 
  408                        } 
else if (length <= 32) {
 
  410                        } 
else if (length <= 56) { 
 
  424                        (*da_p)->flags.flag_byte_offset = length;
 
  432                (*da_p)->flags.is_known_width = 
true;
 
  433                (*da_p)->flags.length = length;
 
  446        if (dctx->
dict->proto->attr.type_parse &&
 
  447            !dctx->
dict->proto->attr.type_parse(&
type, da_p, 
name)) {
 
 
  484#define FLAG_FUNC(_name) \ 
  485static int dict_flag_##_name(fr_dict_attr_t **da_p, UNUSED char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)\ 
  487        (*da_p)->flags._name = 1; \ 
 
  496                fr_strerror_const(
"'clone=...' references can only be used for 'tlv' and 'struct' types");
 
  509        (*da_p)->flags.is_known_width = 0;
 
 
  546                        fr_strerror_const(
"Attributes defining a 'key' field cannot specify a key reference");
 
  551                        fr_strerror_const(
"The 'key' flag can only be used for attributes of type 'uint8', 'uint16', or 'uint32'");
 
  555                if (da->flags.extra) {
 
  580                fr_strerror_printf(
"Invalid reference for 'key=...'.  Parent %s does not have a child attribute named %s",
 
  581                                   da->parent->name, 
value);
 
  585        if (da->parent != key->parent) {
 
  586                fr_strerror_printf(
"Invalid reference for 'key=...'.  Reference %s does not share a common parent",
 
  592                fr_strerror_printf(
"Invalid reference for 'key=...'.  Reference %s is not a 'key' field",
 
 
  619        if (strcmp(
value, 
"uint8") == 0) {
 
  620                da->flags.is_known_width = 
true;
 
  624        } 
else if (strcmp(
value, 
"uint16") == 0) {
 
  625                da->flags.is_known_width = 
true;
 
  633        da->flags.type_size = 0;
 
 
  649                fr_strerror_const(
"The 'offset' flag can only be used in combination with 'length=uint8' or 'length=uint16'");
 
  653        offset = atoi(
value);
 
  654        if ((offset <= 0) || (offset > 255)) {
 
  658        da->flags.type_size = offset;
 
 
  674                fr_strerror_const(
"The 'precision' flag can only be used with data types 'date' or 'time'");
 
  683        da->flags.flag_time_res = precision;
 
 
  692        if (da->flags.extra) {
 
 
  712        da->flags.secret = 1;
 
  715                fr_strerror_const(
"The 'secret' flag can only be used with data types 'string' or 'octets'");
 
 
  733                fr_strerror_const(
"The 'subtype' flag can only be used with data types 'date' or 'time'");
 
  752                da->flags.length = 2;
 
  756                da->flags.is_unsigned = 
true;
 
  757                da->flags.length = 2;
 
  762                da->flags.length = 4;
 
  766                da->flags.is_unsigned = 
true;
 
  767                da->flags.length = 4;
 
  772                da->flags.length = 8;
 
  776                da->flags.is_unsigned = 
true;
 
  777                da->flags.length = 8;
 
 
  795                { 
L(
"array"),           { .func = dict_flag_array } },
 
  797                { 
L(
"counter"),         { .func = dict_flag_counter } },
 
  799                { 
L(
"internal"),        { .func = dict_flag_internal } },
 
  807                { 
L(
"unsafe"),          { .func = dict_flag_unsafe } },
 
  809        static size_t dict_common_flags_len = 
NUM_ELEMENTS(dict_common_flags);
 
  811        char *p, *next = NULL;
 
  818        for (p = 
name; p && *p != 
'\0' ; p = next) {
 
  827                for (next = p + 1; *next && (*next != 
'=') && (*next != 
','); next++) {
 
  849                for (; *next; next++) {
 
  860                if (!((dctx->dict->proto->attr.flags.table &&
 
  861                       fr_dict_attr_flag_to_parser(&parser, dctx->dict->proto->attr.flags.table,
 
  862                                                   dctx->dict->proto->attr.flags.table_len, key, NULL)) ||
 
  863                       fr_dict_attr_flag_to_parser(&parser, dict_common_flags, dict_common_flags_len, key, NULL))) {
 
 
  896static inline CC_HINT(always_inline)
 
 1004        if (!da->parent) 
return 1;      
 
 1012        if (!dup_name && !dup_num) 
return 1;
 
 1014        found = dup_name ? dup_name : dup_num;
 
 1034                fr_strerror_printf(
"Duplicate attribute name '%s' in namespace '%s'.  Originally defined %s[%d]",
 
 1035                                   da->name, da->parent->name, dup_name->filename, dup_name->line);
 
 1039        fr_strerror_printf(
"Duplicate attribute number %u in parent '%s'.  Originally defined %s[%d]",
 
 1040                                da->attr, da->parent->name, dup_num->filename, dup_num->line);
 
 
 1058        if (da->flags.is_known_width) {
 
 1060                        fr_strerror_printf(
"MEMBERs of %s struct[%u] do not exactly fill the fixed-size structure",
 
 1061                                           da->name, da->flags.length);
 
 
 1103                                    char const *type_name, 
char *flag_name,
 
 1111        if (strncmp(
name, 
"Attr-", 5) == 0) {
 
 1129        da->dict = dctx->
dict;
 
 1141        memcpy(&da->flags, base_flags, 
sizeof(da->flags));
 
 1165        if (flag_name) 
if (dict_process_flag_field(dctx, flag_name, &da) < 0) 
goto error;
 
 
 1179        bool required = 
true;
 
 1182        int src_line = dctx->
line;
 
 1184        char const *filename;
 
 1191        if ((argv[0][8] != 
'\0') && ((argv[0][8] != 
'-') || (argv[0][9] != 
'\0'))) {
 
 1202        required = (argv[0][8] != 
'-');
 
 1208        if (strncmp(pattern, 
"${dictdir}/", 11) == 0) {
 
 1261        dctx->
line = src_line;
 
 
 1269        bool continuation = 
false;
 
 1278        if ((strlen(p) < 3) ||
 
 1282            (p[3] && (p[3] != 
','))) {
 
 1288        type = (int)(p[0] - 
'0');
 
 1289        length = (int)(p[2] - 
'0');
 
 1296        if ((length != 0) && (length != 1) && (length != 2)) {
 
 1308                if ((p[4] != 
'c') ||
 
 1314                continuation = 
true;
 
 1316                if ((
type != 1) || (length != 1)) {
 
 1324        *pcontinuation = continuation;
 
 
 1350        if (strncmp(argv[0], 
"Attr-", 5) == 0) {
 
 1358        if (argv[1][0] == 
'.') {
 
 1364                ref_namespace = dctx->
dict->root;
 
 
 1391        bool                    set_relative_attr;
 
 1400        if ((argc < 3) || (argc > 4)) {
 
 1405#ifdef STATIC_ANALYZER 
 1406        if (!dctx->
dict) 
return -1;
 
 1414        if (argv[1][0] != 
'.') {
 
 1418                if (!frame) 
return -1;
 
 1426                if (strchr(argv[1], 
'.') == 0) {
 
 1434                        if (slen <= 0) 
return -1;
 
 1443                set_relative_attr = (
strcasecmp(argv[2], 
"tlv") == 0);
 
 1447                        fr_strerror_printf(
"No parent attribute reference was set for partial OID %s", argv[1]);
 
 1454                if (slen <= 0) 
return -1;
 
 1456                set_relative_attr = 
false;
 
 1465                fr_strerror_printf(
"Member %s of ATTRIBUTE %s type 'struct' MUST use the \"MEMBER\" keyword",
 
 1489                da->flags.migration_union_key = 
true;
 
 1516                box.vb_uint32 = attr;
 
 1526                                     (argc > 3) ? argv[3] : NULL, base_flags) < 0) {
 
 1531                fr_strerror_const(
"Bit fields can only be defined as a MEMBER of data type 'struct'");
 
 1539                fr_strerror_const(
"ATTRIBUTEs of type 'union' can only be defined as a MEMBER of data type 'struct'");
 
 1546        if (key && (
parent->flags.is_known_width)) {
 
 1547                if (!da->flags.is_known_width) {
 
 1548                        da->flags.is_known_width = 1;
 
 1549                        da->flags.length = 
parent->flags.length;
 
 1551                } 
else if (da->flags.length != 
parent->flags.length) {
 
 1552                        fr_strerror_printf(
"Invalid length %u for struct, the parent union %s has a different length %u",
 
 1558#ifdef WITH_DICTIONARY_WARNINGS 
 1563        if (!vendor && (attr < 256) &&
 
 1564            !strstr(fn, 
"rfc") && !strstr(fn, 
"illegal")) {
 
 1565                fprintf(stderr, 
"WARNING: Illegal attribute %s in %s\n",
 
 1607                        if (
parent->flags.is_root) dctx->
dict->vsa_parent = attr;
 
 
 1674        if (!
fr_cond_assert_msg(frame, 
"Context stack doesn't have an attribute or dictionary " 
 1688                fr_strerror_printf(
"BEGIN %s is not resolvable in current context '%s'", argv[0], frame->
da->name);
 
 
 1741                fr_strerror_printf(
"BEGIN-PROTOCOL cannot be used inside of any other BEGIN/END block.  Previous definition is at %s[%d]",
 
 1757        found->loading = 
true;
 
 
 1798                if (strncmp(argv[1], 
"parent=", 7) != 0) {
 
 1812                                           "Attribute '%s' should be 'vsa' but is '%s'", p,
 
 1819        } 
else if (dctx->
dict->vsa_parent) {
 
 1830        } 
else if (dctx->
dict->string_based) {
 
 1831                vsa_da = dctx->
dict->root;
 
 1834                fr_strerror_printf(
"BEGIN-VENDOR is forbidden for protocol %s - it has no ATTRIBUTE of type 'vsa'",
 
 1835                                   dctx->
dict->root->name);
 
 1841                fr_strerror_printf(
"Nested BEGIN-VENDOR is forbidden.  Previous definition is at %s[%d]",
 
 1852                memset(&flags, 0, 
sizeof(flags));
 
 1855                flags.
length = dctx->
dict->proto->default_type_length;
 
 1865                        (vsa_da->parent->flags.is_root)) {
 
 
 1910        if ((argc < 2) || (argc > 3)) {
 
 1924                fr_strerror_printf(
"Member %s of parent %s type 'struct' MUST use the \"MEMBER\" keyword",
 
 1930                fr_strerror_printf(
"Parent attribute %s is of type 'union', and cannot use DEFINE for children",
 
 1941                                     (argc > 2) ? argv[2] : NULL, base_flags) < 0) {
 
 1961                fr_strerror_const(
"Bit fields can only be defined as a MEMBER of data type 'struct'");
 
 1965#ifdef STATIC_ANALYZER 
 1966        if (!dctx->
dict) 
goto error;
 
 1973        da->flags.name_only = 
true;
 
 
 2058        if (argc == 1) 
return 0;
 
 
 2100        if (found != dctx->
dict) {
 
 2102                                   argv[0], dctx->
dict->root->name);
 
 2114                fr_strerror_printf(
"END-PROTOCOL %s does not match previous BEGIN-PROTOCOL %s", argv[0],
 
 
 2193        if (strncmp(argv[0], 
"Attr-", 5) == 0) {
 
 2198#ifdef STATIC_ANALYZER 
 2199        if (!dctx->
dict) 
goto error;
 
 2207        if (
unlikely(da == NULL)) 
return -1;
 
 2209        da->dict = dctx->
dict;
 
 2214        memcpy(&da->flags, base_flags, 
sizeof(da->flags));
 
 2216        da->flags.name_only = 
true;             
 
 2217        da->flags.internal = 
true;              
 
 2219        flags.is_enum = 
true;           
 
 2232                fr_strerror_const(
"Bit fields can only be defined as a MEMBER of a data type 'struct'");
 
 
 2296                if (strcmp(p, 
"internal") == 0) {
 
 
 2314        if ((argc < 2) || (argc > 3)) {
 
 2320                fr_strerror_printf(
"MEMBER can only be used for ATTRIBUTEs of type 'struct', not for data type %s",
 
 2330                fr_strerror_printf(
"Cannot add MEMBER to 'struct' %s after a variable sized member %s",
 
 2345                                     (argc > 2) ? argv[2] : NULL, base_flags) < 0) {
 
 2349#ifdef STATIC_ANALYZER 
 2350        if (!dctx->
dict) 
goto error;
 
 2382                                da->flags.flag_byte_offset = (da->flags.length + previous->flags.flag_byte_offset) & 0x07;
 
 2385                                if (previous->flags.flag_byte_offset != 0) {
 
 2421                                fr_strerror_printf(
"'struct' %s has a 'length' field %s, and cannot end with a TLV %s",
 
 2499        if (!da->flags.is_known_width) {
 
 2505                        fr_strerror_printf(
"'struct' %s has fixed size %u, but member %s is of unknown size",
 
 2541                        fr_strerror_printf(
"'struct' %s has fixed size %u, but member %s overflows that length",
 
 
 2568        char const                      *
name = argv[0];
 
 2580                char const *key_attr;
 
 2582                if ((argc < 3) || (argc > 4)) {
 
 2589                if (argc == 4) flags = argv[3];
 
 2632                if ((argc < 2) || (argc > 3)) {
 
 2638                if (argc == 3) flags = argv[2];
 
 2673        if (
unlikely(da == NULL)) 
return -1;
 
 2675        da->dict = dctx->
dict;
 
 2688                if (dict_process_flag_field(dctx, flags, &da) < 0) 
goto error;
 
 2694        switch (key->type) {
 
 2696                attr = box.vb_uint8;
 
 2700                attr = box.vb_uint16;
 
 2704                attr = box.vb_uint32;
 
 
 2808        enum_len = strlen(argv[1]);
 
 2840                fr_strerror_printf(
"Invalid VALUE name '%s' for attribute '%s' - the name cannot be an integer", argv[1], da->name);
 
 2856                                     argv[0], strlen(argv[0]),
 
 2857                                     argv[1], strlen(argv[1]),
 
 2858                                     argv[2], strlen(argv[2]), 
parent) < 0) {
 
 2869                fr_strerror_printf(
"Cannot define VALUE for attribute '%s' of data type '%s'", da->name,
 
 2880                                  argv[2], strlen(argv[2]),
 
 
 2905        bool                            continuation = 
false;
 
 2913        if ((argc < 2) || (argc > 3)) {
 
 2946        mutable->type = 
type;
 
 2947        mutable->length = length;
 
 2948        mutable->continuation = continuation;
 
 
 2960        unsigned int    type_size = 0;
 
 2963        bool            require_dl = 
false;
 
 2964        bool            string_based = 
false;
 
 2970                fr_strerror_const(
"PROTOCOL definitions cannot occur inside of any other BEGIN/END block");
 
 2977        if ((argc < 2) || (argc > 3)) {
 
 2978                fr_strerror_const(
"Missing arguments after PROTOCOL.  Expected PROTOCOL <num> <name>");
 
 3011                if (strcmp(argv[2], 
"verify=lib") == 0) {
 
 3016                if (strcmp(argv[2], 
"format=string") == 0) {
 
 3018                        string_based = 
true;
 
 3023                        fr_strerror_printf(
"Invalid format for PROTOCOL.  Expected 'format=', got '%s'", argv[2]);
 
 3028                type_size = strtoul(p, &q, 10);
 
 3029                if (q != (p + strlen(p))) {
 
 3041#ifdef STATIC_ANALYZER 
 3042                if (!dict->root) 
return -1;
 
 3045                if (dict->root->attr != 
value) {
 
 3047                                           dict->root->attr, 
value, dict->root->name);
 
 3052#ifdef STATIC_ANALYZER 
 3053                if (!dict->root || !dict->root->name || !argv[0]) 
return -1;
 
 3056                if (
strcasecmp(dict->root->name, argv[0]) != 0) {
 
 3058                                           dict->root->name, argv[0], dict->root->attr);
 
 3067                if (type_size && (dict->root->flags.type_size != type_size)) {
 
 3068                        fr_strerror_printf(
"Conflicting flags for PROTOCOL \"%s\" (current %d versus new %u)",
 
 3069                                           dict->root->name, dict->root->flags.type_size, type_size);
 
 3086        if ((
dict_dlopen(dict, argv[0]) < 0) && require_dl) {
 
 3100        dict->string_based = string_based;
 
 3102                mutable->flags.type_size = dict->proto->default_type_size;
 
 3103                mutable->flags.length = dict->proto->default_type_length;
 
 3105                mutable->flags.type_size = type_size;
 
 3106                mutable->flags.length = 1; 
 
 
 3129                                    char const *src_file, 
int src_line)
 
 3140        if (
unlikely(!*filename_out)) 
goto oom;
 
 3143                file->src_line = src_line;
 
 3145                if (!
file->src_file) 
goto oom;
 
 
 3158                                        char const *src_file, 
int src_line)
 
 3165                if (
file->src_file && src_file) {
 
 3166                        if (
file->src_line != src_line) 
continue;
 
 3167                        if (strcmp(
file->src_file, src_file) != 0) 
continue;
 
 3170                if (strcmp(
file->filename, filename) == 0) 
return true; 
 
 
 3253                           char const *dir, 
char const *filename,
 
 3254                           char const *src_file, 
int src_line)
 
 3275        char                    filename_buf[256];
 
 3280        struct stat             statbuf;
 
 3293        if ((strlen(dir) + 2 + strlen(filename)) > 
sizeof(filename_buf)) {
 
 3304        if (FR_DIR_IS_RELATIVE(filename)) {
 
 3309                strlcpy(filename_buf, dir, 
sizeof(filename_buf));
 
 3310                p = strrchr(filename_buf, FR_DIR_SEP);
 
 3311                if (p && !p[1]) *p = 
'\0';
 
 3313                snprintf(filename_buf, 
sizeof(filename_buf), 
"%s/%s", dir, filename);
 
 3314                filename = filename_buf;
 
 3327                fr_strerror_printf(
"ERROR - we have a recursive $INCLUDE or load of dictionary %s", filename);
 
 3332        if ((fp = fopen(filename, 
"r")) == NULL) {
 
 3336                        fr_strerror_printf(
"Error reading dictionary: %s[%d]: Couldn't open dictionary '%s': %s",
 
 3346        if (fstat(fileno(fp), &statbuf) < 0) {
 
 3354        if (!S_ISREG(statbuf.st_mode)) {
 
 3366                                   "Refusing to start due to insecure configuration", filename);
 
 3380        while (fgets(buf, 
sizeof(buf), fp) != NULL) {
 
 3381                bool do_begin = 
false;
 
 3383                char **argv_p = argv;
 
 3399                p = strchr(buf, 
'#');
 
 3403                if (argc == 0) 
continue;
 
 3409                        if ((strcmp(argv[0], 
"BEGIN") == 0) ||
 
 3410                            (fr_dict_keyword(&parser, keywords, 
NUM_ELEMENTS(keywords), argv_p[0], NULL))) {
 
 3434                if (fr_dict_keyword(&parser, keywords, 
NUM_ELEMENTS(keywords), argv_p[0], NULL)) {
 
 3442                        if (do_begin && !parser->
begin) {
 
 3446                        if (
unlikely(parser->
parse(dctx, argv_p + 1 , argc - 1, &base_flags) < 0)) 
goto error;
 
 3451                        if (do_begin && 
unlikely(parser->
begin(dctx) < 0)) 
goto error;
 
 3518                        if (frame->
finalise(dctx) < 0) 
goto error;
 
 
 3532                          char const *dir_name, 
char const *filename,
 
 3533                          char const *src_file, 
int src_line)
 
 3538        memset(&dctx, 0, 
sizeof(dctx));
 
 3541        dctx.
stack[0].
da = dict->root;
 
 
 3578        char                    *dict_path = NULL;
 
 3586                fr_strerror_const(
"fr_dict_global_ctx_init() must be called before loading dictionary files");
 
 3599        dict_path = dict_subdir ?
 
 3620        TALLOC_FREE(dict_path);
 
 3687                box.vb_uint8 = p->
value;
 
 
 3714        char            *dict_dir = NULL;
 
 3721                fr_strerror_const(
"fr_dict_global_ctx_init() must be called before loading dictionary files");
 
 3726                fr_strerror_const(
"Internal dictionary must be initialised before loading protocol dictionaries");
 
 3757                dict->loaded = 
true;
 
 3779                if (dict) dict->loading = 
false;
 
 3789                fr_strerror_printf(
"Dictionary \"%s\" missing \"BEGIN-PROTOCOL %s\" declaration", dict_dir, proto_name);
 
 3796        dict->loaded = 
true;
 
 3797        if (dict->proto && dict->proto->init) {
 
 3798                if (dict->proto->init() < 0) 
goto error;
 
 3800        dict->loading = 
false;
 
 3802        dict->dir = talloc_steal(dict, dict_dir);
 
 
 3826                fr_strerror_printf(
"fr_dict_global_ctx_init() must be called before loading dictionary files");
 
 3834        if (!dict) 
return NULL;
 
 
 3860        if (!dir) dir = dict->dir;
 
 3867        if (!dict->vendors_by_name) {
 
 3868                fr_strerror_printf(
"%s: Must initialise dictionary before calling fr_dict_read()", __FUNCTION__);
 
 
 3889        if (argc == 0) 
return 0;
 
 3892        memset(&dctx, 0, 
sizeof(dctx));
 
 3908                                           argv[1], dict->root->name);
 
 3912                if (ret < 0) 
goto error;
 
 3914        } 
else if (
strcasecmp(argv[0], 
"ATTRIBUTE") == 0) {
 
 3919                memset(&base_flags, 0, 
sizeof(base_flags));
 
 3922                                                  argv + 1, argc - 1, &base_flags);
 
 3923                if (ret < 0) 
goto error;
 
 3924        } 
else if (
strcasecmp(argv[0], 
"VENDOR") == 0) {
 
 3926                if (ret < 0) 
goto error;
 
 
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define L(_str)
Helper for initialising arrays of string literals.
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
#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.
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.
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.
int fr_dict_enum_add_name(fr_dict_attr_t *da, char const *name, fr_value_box_t const *value, bool coerce, bool replace)
Add a value name.
char const  * name
Vendor name.
unsigned int is_root
Is root of a dictionary.
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 fr_dict_protocol_reference(fr_dict_attr_t const **da_p, fr_dict_attr_t const *root, fr_sbuff_t *in)
Resolve a reference string to a dictionary 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 *attr))
Locate a fr_dict_attr_t by its name.
fr_dict_attr_t * fr_dict_attr_unconst(fr_dict_attr_t const *da)
Coerce to non-const.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
fr_dict_flag_parse_func_t func
Custom parsing function to convert a flag value string to a C type value.
unsigned int internal
Internal attribute, should not be received in protocol packets, should not be encoded.
fr_slen_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.
#define da_is_bit_field(_da)
@ FLAG_LENGTH_UINT8
string / octets type is prefixed by uint8 of length
@ FLAG_LENGTH_UINT16
string / octets type is prefixed by uint16 of length
@ FLAG_KEY_FIELD
this is a key field for a subsequent struct
@ FLAG_BIT_FIELD
bit field inside of a struct
uint32_t pen
Private enterprise number.
#define da_is_length_field(_da)
uint8_t type_size
Type size for TLVs.
size_t length
Length of length data.
uint16_t length
length of the attribute
char const * fr_dict_global_ctx_dir(void)
@ FR_DICT_ATTR_EXT_REF
Attribute references another attribute and/or dictionary.
@ FR_DICT_ATTR_EXT_KEY
UNION attribute references a key.
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.
bool needs_value
This parsing flag must have a value. Else we error.
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_vendor_t const * fr_dict_vendor_by_num(fr_dict_t const *dict, uint32_t vendor_pen)
Look up a vendor by its PEN.
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.
#define fr_dict_attr_is_key_field(_da)
static int8_t fr_dict_attr_cmp_fields(const fr_dict_attr_t *a, const fr_dict_attr_t *b)
Compare two dictionary attributes by their contents.
Values of the encryption flags.
Protocol specific custom flag definitnion.
#define fr_dict_attr_ref_type(_type)
fr_dict_attr_ref_type_t type
The state of the reference.
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
#define fr_dict_attr_ref_is_unresolved(_type)
@ FR_DICT_ATTR_REF_ENUM
The attribute is an enumeration value.
@ FR_DICT_ATTR_REF_KEY
it is a UNION which has a ref to a key, and children.
@ FR_DICT_ATTR_REF_ALIAS
The attribute is an alias for another attribute.
@ FR_DICT_ATTR_REF_CLONE
The attribute is a "copy" of another attribute.
Attribute extension - Holds a reference to an attribute in another dictionary.
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_ref_aunresolved(fr_dict_attr_t **da_p, char 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.
int dict_fixup_apply(dict_fixup_ctx_t *fctx)
Apply all outstanding fixes to a set of dictionaries.
int dict_fixup_enumv_enqueue(dict_fixup_ctx_t *fctx, char const *filename, int line, char const *attr, size_t attr_len, char const *name, size_t name_len, char const *value, size_t value_len, fr_dict_attr_t const *parent)
Add an enumeration value to an attribute which has not yet been defined.
int dict_fixup_alias_enqueue(dict_fixup_ctx_t *fctx, char const *filename, int line, fr_dict_attr_t *alias_parent, char const *alias, fr_dict_attr_t *ref_parent, char const *ref)
Resolve a group reference.
int dict_fixup_clone_enqueue(dict_fixup_ctx_t *fctx, fr_dict_attr_t *da, char const *ref)
Clone one area of a tree into another.
int dict_fixup_init(TALLOC_CTX *ctx, dict_fixup_ctx_t *fctx)
Initialise a fixup ctx.
int dict_fixup_clone_enum_enqueue(dict_fixup_ctx_t *fctx, fr_dict_attr_t *da, char const *ref)
Clone enumeration values from one attribute to another.
int dict_fixup_vsa_enqueue(dict_fixup_ctx_t *fctx, fr_dict_attr_t *da)
Push a fixup for a VSA.
int dict_fixup_clone(fr_dict_attr_t **dst_p, fr_dict_attr_t const *src)
Clone a dictionary attribute from a ref.
int dict_fixup_group_enqueue(dict_fixup_ctx_t *fctx, fr_dict_attr_t *da, char const *ref)
Resolve a group reference.
TALLOC_CTX * pool
Temporary pool for fixups, reduces holes.
int dict_attr_enum_add_name(fr_dict_attr_t *da, char const *name, fr_value_box_t const *value, bool coerce, bool replace, fr_dict_attr_t const *child_struct)
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.
#define dict_attr_alloc(_ctx, _parent, _name, _attr, _type, _args)
fr_dict_t * dict_alloc(TALLOC_CTX *ctx)
Allocate a new dictionary.
#define INTERNAL_IF_NULL(_dict, _ret)
Set the internal dictionary if none was provided.
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.
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_t * dict_by_protocol_num(unsigned int num)
Internal version of fr_dict_by_protocol_num.
int dict_attr_child_add(fr_dict_attr_t *parent, fr_dict_attr_t *child)
Add a child to a parent.
int dict_vendor_add(fr_dict_t *dict, char const *name, unsigned int num)
Add a vendor to the dictionary.
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.
int dict_attr_finalise(fr_dict_attr_t **da_p, char const *name)
Set remaining fields in a dictionary attribute before insertion.
int dict_attr_num_init(fr_dict_attr_t *da, unsigned int num)
Set the attribute number (if any)
int dict_attr_num_init_name_only(fr_dict_attr_t *da)
Set the attribute number (if any)
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.
fr_dict_t * internal
Magic internal dictionary.
fr_dict_attr_t * dict_attr_alloc_null(TALLOC_CTX *ctx, fr_dict_protocol_t const *dict)
Partial initialisation functions.
int dict_dependent_add(fr_dict_t *dict, char const *dependent)
Record a new dependency on a dictionary.
#define dict_attr_alloc_root(_ctx, _dict, _name, _attr, _args)
int dict_protocol_add(fr_dict_t *dict)
Add a protocol to the global protocol table.
fr_dict_gctx_t * dict_gctx
Top level structure containing global dictionary state.
bool perm_check
Whether we should check dictionary file permissions as they're loaded.
Optional arguments for initialising/allocating attributes.
Entry in the filename list of files associated with this dictionary.
fr_dict_keyword_finalise_t finalise
function to call when popping
static fr_table_num_sorted_t const dict_nest_table[]
static int dict_read_process_include(dict_tokenize_ctx_t *dctx, char **argv, int argc, char const *dir)
dict_nest_t nest
for manual vs automatic begin / end things
static int dict_read_process_common(dict_tokenize_ctx_t *dctx, fr_dict_attr_t **da_p, fr_dict_attr_t const *parent, char const *name, char const *type_name, char *flag_name, fr_dict_attr_flags_t const *base_flags)
static int dict_read_process_attribute(dict_tokenize_ctx_t *dctx, char **argv, int argc, fr_dict_attr_flags_t *base_flags)
int member_num
structure member numbers
static int dict_filename_add(char **filename_out, fr_dict_t *dict, char const *filename, char const *src_file, int src_line)
Maintain a linked list of filenames which we've seen loading this dictionary.
static int dict_process_type_field(dict_tokenize_ctx_t *dctx, char const *name, fr_dict_attr_t **da_p)
static int dict_read_process_alias(dict_tokenize_ctx_t *dctx, char **argv, int argc, UNUSED fr_dict_attr_flags_t *base_flags)
static int _dict_from_file(dict_tokenize_ctx_t *dctx, char const *dir_name, char const *filename, char const *src_file, int src_line)
fr_dict_section_begin_t begin
Can have a BEGIN prefix.
static int dict_attr_allow_dup(fr_dict_attr_t const *da)
Check if this definition is a duplicate, and if it is, whether we should skip it error out.
static int dict_finalise(dict_tokenize_ctx_t *dctx)
static int dict_read_process_member(dict_tokenize_ctx_t *dctx, char **argv, int argc, fr_dict_attr_flags_t *base_flags)
fr_dict_t * fr_dict_alloc(char const *proto_name, unsigned int proto_number)
static int dict_flag_ref(fr_dict_attr_t **da_p, char const *value, UNUSED fr_dict_flag_parser_rule_t const *rule)
static int dict_flag_precision(fr_dict_attr_t **da_p, char const *value, UNUSED fr_dict_flag_parser_rule_t const *rule)
static int dict_read_process_end(dict_tokenize_ctx_t *dctx, char **argv, int argc, UNUSED fr_dict_attr_flags_t *base_flags)
int stack_depth
points to the last used stack frame
ssize_t struct_size
size of the struct.
static int dict_read_process_struct(dict_tokenize_ctx_t *dctx, char **argv, int argc, UNUSED fr_dict_attr_flags_t *base_flags)
Process a STRUCT name attr value.
fr_dict_attr_t const  * struct_is_closed
no more members are allowed
char * filename
current filename
int(* fr_dict_keyword_parse_t)(dict_tokenize_ctx_t *dctx, char **argv, int argc, fr_dict_attr_flags_t *base_flags)
Keyword parser.
static int dict_read_process_vendor(dict_tokenize_ctx_t *dctx, char **argv, int argc, UNUSED fr_dict_attr_flags_t *base_flags)
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_section_begin_t)(dict_tokenize_ctx_t *dctx)
Pushes a new frame onto the top of the stack based on the current frame.
int fr_dict_str_to_argv(char *str, char **argv, int max_argc)
static int dict_read_sscanf_i(unsigned int *pvalue, char const *str)
static int dict_read_process_define(dict_tokenize_ctx_t *dctx, char **argv, int argc, fr_dict_attr_flags_t *base_flags)
static size_t const dict_nest_table_len
static int dict_read_parse_format(char const *format, int *ptype, int *plength, bool *pcontinuation)
static int dict_read_process_begin_vendor(dict_tokenize_ctx_t *dctx, char **argv, int argc, UNUSED fr_dict_attr_flags_t *base_flags)
#define ASSERT_CURRENT_NEST(_dctx, _nest)
static dict_tokenize_frame_t const * dict_dctx_unwind_until(dict_tokenize_ctx_t *dctx, dict_nest_t nest)
Unwind the stack until it points to a particular type of stack frame.
static int dict_from_file(fr_dict_t *dict, char const *dir_name, char const *filename, char const *src_file, int src_line)
fr_dict_attr_t const  * da
the da we care about
fr_dict_attr_t * value_attr
Cache of last attribute to speed up value processing.
static int dict_read_process_protocol(dict_tokenize_ctx_t *dctx, char **argv, int argc, UNUSED fr_dict_attr_flags_t *base_flag)
Register the specified dictionary as a protocol dictionary.
#define FLAG_FUNC(_name)
Define a flag setting function, which sets one bit in a fr_dict_attr_flags_t.
#define CURRENT_LINE(_dctx)
static dict_tokenize_frame_t const * dict_dctx_pop(dict_tokenize_ctx_t *dctx)
Pop the current stack frame.
char * filename
name of the file where we read this entry
static int dict_set_value_attr(dict_tokenize_ctx_t *dctx, fr_dict_attr_t *da)
static int dict_read_process_enum(dict_tokenize_ctx_t *dctx, char **argv, int argc, fr_dict_attr_flags_t *base_flags)
#define CURRENT_FILENAME(_dctx)
static int dict_struct_finalise(dict_tokenize_ctx_t *dctx)
static int dict_flag_offset(fr_dict_attr_t **da_p, char const *value, UNUSED fr_dict_flag_parser_rule_t const *rule)
static int dict_read_process_begin_protocol(dict_tokenize_ctx_t *dctx, char **argv, int argc, UNUSED fr_dict_attr_flags_t *base_flags)
static int dict_flag_key(fr_dict_attr_t **da_p, char const *value, UNUSED fr_dict_flag_parser_rule_t const *rule)
fr_dict_t * dict
Protocol dictionary we're inserting attributes into.
static int dict_begin_protocol(NDEBUG_UNUSED dict_tokenize_ctx_t *dctx)
Process an inline BEGIN PROTOCOL block.
static int dict_flag_clone(fr_dict_attr_t **da_p, char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)
dict_tokenize_frame_t stack[DICT_MAX_STACK]
stack of attributes to track
int line
line number where we read this entry
static bool dict_filename_loaded(fr_dict_t *dict, char const *filename, char const *src_file, int src_line)
See if we have already loaded the file,.
static int dict_flag_enum(fr_dict_attr_t **da_p, char const *value, UNUSED fr_dict_flag_parser_rule_t const *rule)
static dict_tokenize_frame_t const * dict_dctx_unwind(dict_tokenize_ctx_t *dctx)
#define CURRENT_DA(_dctx)
#define DICT_MAX_ARGV
Maximum number of arguments.
static int dict_read_process_value(dict_tokenize_ctx_t *dctx, char **argv, int argc, UNUSED fr_dict_attr_flags_t *base_flags)
Process a value alias.
static dict_tokenize_frame_t const * dict_dctx_find_frame(dict_tokenize_ctx_t *dctx, dict_nest_t nest)
fr_dict_keyword_parser_t value
Value to return from lookup.
static int dict_flag_length(fr_dict_attr_t **da_p, char const *value, UNUSED fr_dict_flag_parser_rule_t const *rule)
static int dict_read_process_end_vendor(dict_tokenize_ctx_t *dctx, char **argv, int argc, UNUSED fr_dict_attr_flags_t *base_flags)
int fr_dict_read(fr_dict_t *dict, char const *dir, char const *filename)
Read supplementary attribute definitions into an existing dictionary.
#define DICT_MAX_STACK
Maximum stack size.
int fr_dict_parse_str(fr_dict_t *dict, char *buf, fr_dict_attr_t const *parent)
static int dict_flag_subtype(fr_dict_attr_t **da_p, char const *value, UNUSED fr_dict_flag_parser_rule_t const *rule)
static int dict_read_process_begin(dict_tokenize_ctx_t *dctx, char **argv, int argc, UNUSED fr_dict_attr_flags_t *base_flags)
int fr_dict_internal_afrom_file(fr_dict_t **out, char const *dict_subdir, char const *dependent)
(Re-)Initialize the special internal dictionary
static int dict_dctx_push(dict_tokenize_ctx_t *dctx, fr_dict_attr_t const *da, dict_nest_t nest)
static int dict_read_process_flags(UNUSED dict_tokenize_ctx_t *dctx, char **argv, int argc, fr_dict_attr_flags_t *base_flags)
static int dict_attr_add_or_fixup(dict_fixup_ctx_t *fixup, fr_dict_attr_t **da_p)
Add an attribute to the dictionary, or add it to a list of attributes to clone later.
int(* fr_dict_keyword_finalise_t)(dict_tokenize_ctx_t *dctx)
#define CURRENT_FRAME(_dctx)
static void dict_attr_location_set(dict_tokenize_ctx_t *dctx, fr_dict_attr_t *da)
fr_dict_attr_t const  * relative_attr
for ".82" instead of "1.2.3.82". only for parents of type "tlv"
static int dict_flag_secret(fr_dict_attr_t **da_p, UNUSED char const *value, UNUSED fr_dict_flag_parser_rule_t const *rule)
fr_table_elem_name_t name
Name of the keyword, e.g. "ATTRIBUTE".
static int dict_read_process_end_protocol(dict_tokenize_ctx_t *dctx, char **argv, int argc, UNUSED fr_dict_attr_flags_t *base_flags)
fr_dict_keyword_parse_t parse
Function to parse the keyword with.
void dict_dctx_debug(dict_tokenize_ctx_t *dctx)
dict_nest_t
This represents explicit BEGIN/END frames pushed onto the stack.
@ NEST_TOP
top of the stack
@ NEST_VENDOR
BEGIN-VENDOR.
@ NEST_PROTOCOL
BEGIN-PROTOCOL.
@ NEST_ATTRIBUTE
BEGIN foo.
static int dict_root_set(fr_dict_t *dict, char const *name, unsigned int proto_number)
Set a new root dictionary attribute.
Parser context for dict_from_file.
static void * fr_dlist_head(fr_dlist_head_t const *list_head)
Return the HEAD item of a list or NULL if the list is empty.
static int fr_dlist_insert_tail(fr_dlist_head_t *list_head, void *ptr)
Insert an item into the tail of a list.
static void * fr_dlist_next(fr_dlist_head_t const *list_head, void const *ptr)
Get the next item in a list.
int fr_globdir_iter_init(char const **filename, char const *dir, char const *pattern, fr_globdir_iter_t *iter)
Initialize an iterator over filenames.
int fr_globdir_iter_next(char const **filename, fr_globdir_iter_t *iter)
Get the next filename.
char const * fr_cwd_strip(char const *filename)
Intended to be used in logging functions to make output more readable.
int fr_globdir_iter_free(fr_globdir_iter_t *iter)
@ FR_TYPE_TIME_DELTA
A period of time measured in nanoseconds.
@ FR_TYPE_TLV
Contains nested attributes.
@ 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_VALUE_BOX
A boxed value.
@ 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_BOOL
A truth value.
@ FR_TYPE_VSA
Vendor-Specific, for RADIUS attribute 26.
@ FR_TYPE_OCTETS
Raw octets.
@ FR_TYPE_GROUP
A grouping of other attributes.
int strncasecmp(char *s1, char *s2, int n)
int strcasecmp(char *s1, char *s2)
static rc_request_t * current
char const  * name
Test name (as specified in the request).
size_t fr_sbuff_adv_past_allowed(fr_sbuff_t *sbuff, size_t len, bool const allowed[static UINT8_MAX+1], fr_sbuff_term_t const *tt)
Wind position past characters in the allowed set.
bool const sbuff_char_class_int[UINT8_MAX+1]
#define FR_SBUFF_IN(_start, _len_or_end)
#define FR_SBUFF_IN_STR(_start)
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
fr_aka_sim_id_type_t type
size_t strlcpy(char *dst, char const *src, size_t siz)
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
char const  * str
Literal string.
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
#define TABLE_TYPE_NAME_FUNC_RPTR(_func, _our_table_type, _our_name, _our_def_type, _our_out_type)
Create a type-specific name-to-value function.
static void const * table_sorted_value_by_str(void const *table, size_t table_len, size_t element_size, char const *name)
Convert a string to a value using a lexicographically sorted table.
fr_table_elem_name_t name
An element in an arbitrarily ordered array of name to num mappings.
An element in a lexicographically sorted array of name to num mappings.
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.
fr_table_num_ordered_t const fr_time_precision_table[]
#define FR_DICTIONARY_FILE
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_printf_push(_fmt,...)
Add a message to an existing stack of messages at the tail.
#define fr_strerror_const_push(_msg)
#define fr_strerror_const(_msg)
fr_table_num_ordered_t const fr_type_table[]
Map data types to names representing those types.
#define fr_type_is_structural(_x)
@ FR_TYPE_VALUE_BOX_CURSOR
cursor over a fr_value_box_t
@ FR_TYPE_UNION
A union of limited children.
@ FR_TYPE_ATTR
A contains an attribute reference.
@ FR_TYPE_PAIR_CURSOR
cursor over a fr_pair_t
#define FR_TYPE_STRUCTURAL
#define fr_type_is_null(_x)
#define fr_type_is_tlv(_x)
#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.
#define fr_type_is_struct(_x)
static fr_type_t fr_type_from_str(char const *type)
Return the constant value representing a type.
int fr_value_box_cast_in_place(TALLOC_CTX *ctx, fr_value_box_t *vb, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv)
Convert one type of fr_value_box_t to another in place.
ssize_t fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, char const *in, size_t inlen, fr_sbuff_unescape_rules_t const *erules)
void fr_value_box_clear(fr_value_box_t *data)
Clear/free any existing value and metadata.
#define FR_VALUE_BOX_INITIALISER_NULL(_vb)
A static initialiser for stack/globally allocated boxes.
#define fr_value_box_init(_vb, _type, _enumv, _tainted)
Initialise a fr_value_box_t.
int format(printf, 5, 0))
static size_t char ** out