Coverage Report

Created: 2025-12-14 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/freeradius-server/src/freeradius-devel/util/dict.h
Line
Count
Source
1
#pragma once
2
/*
3
 *  This program is free software; you can redistribute it and/or modify
4
 *  it under the terms of the GNU General Public License as published by
5
 *  the Free Software Foundation; either version 2 of the License, or
6
 *  (at your option) any later version.
7
 *
8
 *  This program is distributed in the hope that it will be useful,
9
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 *  GNU General Public License for more details.
12
 *
13
 *  You should have received a copy of the GNU General Public License
14
 *  along with this program; if not, write to the Free Software
15
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16
 */
17
18
/** Multi-protocol AVP dictionary API
19
 *
20
 * @file src/lib/util/dict.h
21
 *
22
 * @copyright 2015 The FreeRADIUS server project
23
 */
24
25
RCSIDH(dict_h, "$Id: 02e89b74f24f0ad31083c673e63833b9d1cbc3ed $")
26
27
#ifdef __cplusplus
28
extern "C" {
29
#endif
30
31
#include <freeradius-devel/build.h>
32
#include <freeradius-devel/missing.h>
33
#include <freeradius-devel/util/dl.h>
34
#include <freeradius-devel/util/ext.h>
35
#include <freeradius-devel/util/hash.h>
36
#include <freeradius-devel/util/rb.h>
37
#include <freeradius-devel/util/sbuff.h>
38
#include <freeradius-devel/util/table.h>
39
#include <freeradius-devel/util/talloc.h>
40
#include <freeradius-devel/util/types.h>
41
42
#include <stdbool.h>
43
#include <stdint.h>
44
45
/*
46
 *  Avoid circular type references.
47
 */
48
typedef struct dict_attr_s fr_dict_attr_t;
49
typedef struct fr_dict_s fr_dict_t;
50
51
typedef struct value_box_s fr_value_box_t;
52
53
/*
54
 *  Allow public and private versions of the same structures
55
 */
56
#ifdef _CONST
57
#  error _CONST can only be defined in the local header
58
#endif
59
#ifndef _DICT_PRIVATE
60
#  define _CONST const
61
#else
62
#  define _CONST
63
#endif
64
65
#ifdef WITH_VERIFY_PTR
66
13.7M
#  define DA_VERIFY(_x)   fr_dict_attr_verify(__FILE__, __LINE__, _x)
67
#else
68
#  define DA_VERIFY(_x)   fr_cond_assert(_x)
69
#endif
70
71
typedef struct dict_tokenize_ctx_s dict_tokenize_ctx_t;
72
typedef struct fr_dict_autoload_talloc_s fr_dict_autoload_talloc_t;
73
74
/** Values of the encryption flags
75
 */
76
typedef struct {
77
  unsigned int    is_root : 1;      //!< Is root of a dictionary.
78
79
  unsigned int    is_unknown : 1;     //!< This dictionary attribute is ephemeral
80
                ///< and not part of the main dictionary.
81
82
  unsigned int    is_raw : 1;     //!< This dictionary attribute was constructed
83
                ///< from a known attribute to allow the user
84
                ///< to assign octets values directly.
85
                ///< See .is_unknown to determine if it is
86
                ///< ephemeral.
87
  unsigned int    is_alias : 1;     //!< This isn't a real attribute, it's a reference to
88
                ///< to one.
89
  unsigned int    has_alias : 1;      //!< this attribute has an alias.
90
  unsigned int    internal : 1;     //!< Internal attribute, should not be received
91
                ///< in protocol packets, should not be encoded.
92
  unsigned int    array : 1;      //!< Pack multiples into 1 attr.
93
94
  unsigned int    is_known_width : 1;   //!< is treated as if it has a known width for structs
95
96
  unsigned int    has_value : 1;      //!< Has a value.
97
98
  unsigned int    is_unsigned : 1;          //!< hackity hack for dates and time deltas
99
100
  unsigned int    counter : 1;          //!< integer attribute is actually an impulse / counter
101
102
  unsigned int    name_only : 1;      //!< this attribute should always be referred to by name.
103
                ///< A number will be allocated, but the allocation scheme
104
                ///< will depend on the parent, and definition type, and
105
                ///< may not be stable in all instances.
106
107
  unsigned int    secret : 1;     //!< this attribute should be omitted in debug mode
108
109
  unsigned int    unsafe : 1;           //!< e.g. Cleartext-Password
110
111
  unsigned int    is_ref_target : 1;    //!< is the target of a ref, and cannot be moved.
112
113
  /*
114
   *  @todo - if we want to clean these fields up, make
115
   *  "subtype" and "type_size" both 4-bit bitfields.  That
116
   *  gives us an extra 8 bits for adding new flags, and we
117
   *  can likely get rid of "extra", in order to save one
118
   *  more bit.
119
   */
120
  unsigned int    extra : 1;      //!< really "subtype is used by dict, not by protocol"
121
122
  unsigned int    local : 1;          //!< is a local variable
123
124
  unsigned int    has_fixup : 1;      //! needs a fixup during dictionary parsing
125
126
  /*
127
   *  main: extra is set, then this field is is key, bit, or a uint16 length field.
128
   *  radius: is one of 9 options for flags
129
   *  dhcp v4/v6: DNS label, or partial DNS label
130
   */
131
  uint8_t     subtype;      //!< protocol-specific values, OR key fields
132
133
  /*
134
   *  TLVs: Number of bytes in the "type" field for TLVs (typically 1, 2, or 4)
135
   *
136
   *  da_is_bit_field(da): offset in the byte where this bit
137
   *    field ends.  This is only used as a caching mechanism
138
   *    during parsing of the dictionaries.
139
   *
140
   *  time/time_delta: fr_time_res_t, which has 4 possible values.
141
   *
142
   *  otherwise: unused.
143
   */
144
  uint8_t     type_size;      //!< Type size for TLVs
145
146
  /*
147
   *  da_is_bit_field(da): Length of the field in bits.
148
   *
149
   *  TLV: Number of bytes in the "length" field
150
   *
151
   *  otherwise: Length in bytes
152
   */
153
  uint16_t          length;       //!< length of the attribute
154
} fr_dict_attr_flags_t;
155
156
51.4k
#define flag_time_res type_size
157
1.40k
#define flag_byte_offset type_size
158
159
/** subtype values for the dictionary when extra=1
160
 *
161
 */
162
enum {
163
  FLAG_EXTRA_NONE = 0,        //!< no extra meaning, should be invalid
164
  FLAG_KEY_FIELD,         //!< this is a key field for a subsequent struct
165
  FLAG_BIT_FIELD,               //!< bit field inside of a struct
166
  FLAG_LENGTH_UINT8,        //!< string / octets type is prefixed by uint8 of length
167
  FLAG_LENGTH_UINT16,       //!< string / octets type is prefixed by uint16 of length
168
};
169
170
550k
#define fr_dict_attr_is_key_field(_da) ((_da)->flags.extra && ((_da)->flags.subtype == FLAG_KEY_FIELD))
171
609k
#define da_is_bit_field(_da) ((_da)->flags.extra && ((_da)->flags.subtype == FLAG_BIT_FIELD))
172
161k
#define da_is_length_field(_da) ((_da)->flags.extra && (((_da)->flags.subtype == FLAG_LENGTH_UINT8) || ((_da)->flags.subtype == FLAG_LENGTH_UINT16)))
173
4.83M
#define da_is_length_field8(_da) ((_da)->flags.extra && ((_da)->flags.subtype == FLAG_LENGTH_UINT8))
174
4.78M
#define da_is_length_field16(_da) ((_da)->flags.extra && ((_da)->flags.subtype == FLAG_LENGTH_UINT16))
175
47.5k
#define da_length_offset(_da) ((_da)->flags.type_size)
176
177
/** Extension identifier
178
 *
179
 * @note New extension structures should also be added to the to the appropriate table in dict_ext.c
180
 */
181
typedef enum {
182
  FR_DICT_ATTR_EXT_NAME = 0,        //!< Name of the attribute.
183
  FR_DICT_ATTR_EXT_CHILDREN,        //!< Attribute has children.
184
  FR_DICT_ATTR_EXT_REF,         //!< Attribute references another
185
                ///< attribute and/or dictionary.
186
  FR_DICT_ATTR_EXT_KEY,         //!< UNION attribute references a key
187
  FR_DICT_ATTR_EXT_VENDOR,        //!< Cached vendor pointer.
188
  FR_DICT_ATTR_EXT_DA_STACK,        //!< Cached da stack.
189
  FR_DICT_ATTR_EXT_ENUMV,         //!< Enumeration values.
190
  FR_DICT_ATTR_EXT_NAMESPACE,       //!< Attribute has its own namespace.
191
  FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC,     //!< Protocol specific extensions
192
  FR_DICT_ATTR_EXT_MAX
193
} fr_dict_attr_ext_t;
194
195
/** Dictionary attribute
196
 */
197
struct dict_attr_s {
198
  fr_dict_t _CONST* _CONST dict;        //!< Dict attribute belongs to.
199
200
  char const    *name;        //!< Attribute name.
201
  size_t      name_len;     //!< Length of the name.
202
203
  unsigned int    attr;       //!< Attribute number.
204
  unsigned int    depth;        //!< Depth of nesting for this attribute.
205
206
  unsigned int    last_child_attr;    //!< highest value of last child attribute.
207
208
  fr_type_t   type;       //!< Value type.
209
210
  fr_dict_attr_t const  *parent;      //!< Immediate parent of this attribute.
211
  fr_dict_attr_t const  *next;        //!< Next child in bin.
212
213
  fr_dict_attr_flags_t  flags;        //!< Flags.
214
215
  struct {
216
    bool      attr_set : 1;   //!< Attribute number has been set.
217
                //!< We need the full range of values 0-UINT32_MAX
218
                ///< so we can't use any attr values to indicate
219
                ///< "unsetness".
220
221
    bool      finalised : 1;    //!< Attribute definition is complete and modifications
222
                ///< that would change the address of the memory chunk
223
                ///< of the attribute are no longer permitted.
224
  } state;
225
226
  char const    *filename;      //!< Where the attribute was defined.
227
                ///< this buffer's lifetime is bound to the
228
                ///< fr_dict_t.
229
  int     line;       //!< Line number where the attribute was defined.
230
231
  uint8_t     ext[FR_DICT_ATTR_EXT_MAX];  //!< Extensions to the dictionary attribute.
232
} CC_HINT(aligned(FR_EXT_ALIGNMENT));
233
234
/** Extension identifier
235
 *
236
 * @note New extension structures should also be added to the appropriate table in dict_ext.c
237
 */
238
typedef enum {
239
  FR_DICT_ENUM_EXT_ATTR_REF = 0,        //!< Reference to a child attribute associated with this key value
240
  FR_DICT_ENUM_EXT_MAX
241
} fr_dict_enum_ext_t;
242
243
/** Enum extension - Sub-struct or union pointer
244
 *
245
 */
246
typedef struct {
247
  fr_dict_attr_t const  *da;        //!< the child structure referenced by this value of key
248
} fr_dict_enum_ext_attr_ref_t;
249
250
/** Value of an enumerated attribute
251
 *
252
 * Maps one of more string values to integers and vice versa.
253
 */
254
typedef struct {
255
  char const    *name;        //!< Enum name.
256
  size_t      name_len;     //!< Allows for efficient name lookups when operating
257
                ///< on partial buffers.
258
  fr_value_box_t const  *value;       //!< Enum value (what name maps to).
259
260
  uint8_t     ext[FR_DICT_ENUM_EXT_MAX];  //!< Extensions to the dictionary attribute.
261
} fr_dict_enum_value_t CC_HINT(aligned(FR_EXT_ALIGNMENT));
262
263
/** Private enterprise
264
 *
265
 * Represents an IANA private enterprise allocation.
266
 *
267
 * The width of the private enterprise number must be the same for all protocols
268
 * so we can represent a vendor with a single struct.
269
 */
270
typedef struct {
271
  uint32_t    pen;        //!< Private enterprise number.
272
  bool      continuation;     //!< we only have one flag for now, for WiMAX
273
  size_t      type;         //!< Length of type data
274
  size_t      length;       //!< Length of length data
275
  char const    *name;        //!< Vendor name.
276
} fr_dict_vendor_t;
277
278
/** Specifies a value which must be present for the module to function
279
 *
280
 */
281
typedef struct {
282
  fr_value_box_t const  **out;        //!< Enumeration value.
283
  fr_dict_attr_t const  **attr;       //!< The protocol dictionary the attribute should
284
                ///< be resolved in. ** so it's a compile time
285
                ///< constant.
286
  char const    *name;        //!< of the attribute.
287
} fr_dict_enum_autoload_t;
288
289
/** Specifies an attribute which must be present for the module to function
290
 *
291
 */
292
typedef struct {
293
  fr_dict_attr_t const  **out;        //!< Where to write a pointer to the resolved
294
                //!< #fr_dict_attr_t.
295
  fr_dict_t const   **dict;       //!< The protocol dictionary the attribute should
296
                ///< be resolved in. ** so it's a compile time
297
                ///< constant.
298
  char const    *name;        //!< of the attribute.
299
  fr_type_t   type;       //!< of the attribute.  Mismatch is a fatal error.
300
} fr_dict_attr_autoload_t;
301
302
/** Specifies a dictionary which must be loaded/loadable for the module to function
303
 *
304
 */
305
typedef struct {
306
  fr_dict_t const   **out;        //!< Where to write a pointer to the loaded/resolved
307
                //!< #fr_dict_t.
308
  char const    *base_dir;      //!< Directory structure beneath share.
309
  char const    *proto;       //!< The protocol dictionary name.
310
} fr_dict_autoload_t;
311
312
0
#define DICT_AUTOLOAD_TERMINATOR { .out = NULL }
313
314
315
/** Errors returned by attribute lookup functions
316
 *
317
 */
318
typedef enum {
319
  FR_DICT_ATTR_OK     = 0,      //!< No error.
320
  FR_DICT_ATTR_NOTFOUND   = -1,     //!< Attribute couldn't be found.
321
  FR_DICT_ATTR_PROTOCOL_NOTFOUND  = -2,     //!< Protocol couldn't be found.
322
  FR_DICT_ATTR_PARSE_ERROR  = -3,     //!< Attribute string couldn't be parsed
323
  FR_DICT_ATTR_INTERNAL_ERROR = -4,     //!< Internal error occurred.
324
  FR_DICT_ATTR_OOM    = -5,     //!< Memory allocation error.
325
  FR_DICT_ATTR_NOT_DESCENDENT = -6,     //!< Attribute is not a descendent of the parent
326
                ///< attribute.
327
  FR_DICT_ATTR_NOT_ANCESTOR = -7,     //!< Attribute is not an ancestor of the child
328
                ///< attribute.
329
  FR_DICT_ATTR_NO_CHILDREN  = -8,     //!< Child lookup in attribute with no children.
330
  FR_DICT_ATTR_EINVAL   = -9      //!< Invalid arguments.
331
332
} fr_dict_attr_err_t;
333
334
typedef bool (*fr_dict_attr_valid_func_t)(fr_dict_attr_t *da);
335
typedef bool (*fr_dict_attr_type_parse_t)(fr_type_t *type, fr_dict_attr_t **da_p, char const *name);
336
337
/*
338
 *  Forward declarations to avoid circular references.
339
 */
340
typedef struct pair_list_s fr_pair_list_t;
341
typedef struct fr_dbuff_s fr_dbuff_t;
342
343
/** A generic interface for decoding packets to fr_pair_ts
344
 *
345
 * A decoding function should decode a single top level packet from wire format.
346
 *
347
 * Note that unlike #fr_tp_proto_decode_t, this function is NOT passed an encode_ctx.  That is because when we
348
 * do cross-protocol encoding, the "outer" protocol has no information it can share with the "inner" protocol.
349
 *
350
 * @param[in] ctx   to allocate new pairs in.
351
 * @param[in] vps   where new VPs will be added
352
 * @param[in] data    to decode.
353
 * @param[in] data_len    The length of the incoming data.
354
 * @return
355
 *  - <= 0 on error.  May be the offset (as a negative value) where the error occurred.
356
 *  - > 0 on success.  How many bytes were decoded.
357
 */
358
typedef ssize_t (*fr_dict_attr_decode_func_t)(TALLOC_CTX *ctx, fr_pair_list_t *vps,
359
                uint8_t const *data, size_t data_len);
360
361
/** A generic interface for encoding fr_pair_ts to packets
362
 *
363
 * An encoding function should encode multiple VPs to a wire format packet
364
 *
365
 * Note that unlike #fr_tp_proto_encode_t, this function is NOT passed an encode_ctx.  That is because when we
366
 * do cross-protocol encoding, the "outer" protocol has no information it can share with the "inner" protocol.
367
 *
368
 * @param[in] vps   vps to encode
369
 * @param[in] dbuff   buffer where data can be written
370
 * @return
371
 *  - <= 0 on error.  May be the offset (as a negative value) where the error occurred.
372
 *  - > 0 on success.  How many bytes were encoded
373
 */
374
typedef ssize_t(*fr_dict_attr_encode_func_t)(fr_dbuff_t *dbuff, fr_pair_list_t const *vps);
375
376
/** Init / free callbacks
377
 *
378
 *  Only for "autoref" usage.
379
 */
380
typedef int (*fr_dict_protocol_init_t)(void);
381
typedef void (*fr_dict_protocol_free_t)(void);
382
383
typedef struct fr_dict_flag_parser_rule_s fr_dict_flag_parser_rule_t;
384
385
/** Custom protocol-specific flag parsing function
386
 *
387
 * @note This function should be used to implement table based flag parsing.
388
 *
389
 * @param[in] da_p  we're currently populating
390
 * @param[in] value flag value to parse.
391
 * @param[in] rule  How to parse the flag.
392
 */
393
typedef int (*fr_dict_flag_parse_func_t)(fr_dict_attr_t **da_p, UNUSED char const *value, UNUSED fr_dict_flag_parser_rule_t const *rule);
394
395
struct fr_dict_flag_parser_rule_s {
396
  fr_dict_flag_parse_func_t func;       //!< Custom parsing function to convert a flag value string to a C type value.
397
  void        *uctx;        //!< Use context to pass to the custom parsing function.
398
  bool        needs_value;      //!< This parsing flag must have a value.  Else we error.
399
};
400
401
/** Copy custom flags from one attribute to another
402
 *
403
 * @param[out] da_to    attribute to copy to.  Use for the talloc_ctx for any heap allocated flag values.
404
 * @param[out] flags_to   protocol specific flags struct to copy to.
405
 * @param[in] flags_from  protocol specific flags struct to copy from.
406
 * @return
407
 *  - 0 on success.
408
 *  - -1 on error.
409
 */
410
typedef int (*fr_dict_flags_copy_func_t)(fr_dict_attr_t *da_to, void *flags_to, void *flags_from);
411
412
/** Compare the protocol specific flags struct from two attributes
413
 *
414
 * @param[in] da_a  first attribute to compare.
415
 * @param[in] da_b  second attribute to compare.
416
 * @return
417
 *  - 0 if the flags are equal.
418
 *  - < 0 if da_a < da_b.
419
 *  - > 0 if da_a > da_b.
420
 */
421
 typedef int (*fr_dict_flags_cmp_func_t)(fr_dict_attr_t const *da_a, fr_dict_attr_t const *da_b);
422
423
/** Protocol specific custom flag definitnion
424
 *
425
 */
426
typedef struct  {
427
  fr_table_elem_name_t    name;       //!< Name of the flag
428
  fr_dict_flag_parser_rule_t  value;        //!< Function and context to parse the flag.
429
} fr_dict_flag_parser_t;
430
431
/** Define a flag setting function, which sets one bit in a fr_dict_attr_flags_t
432
 *
433
 * This is here, because AFAIK there's no completely portable way to get the bit
434
 * offset of a bit field in a structure.
435
 */
436
#define FR_DICT_ATTR_FLAG_FUNC(_struct, _name) \
437
420
static int dict_flag_##_name(fr_dict_attr_t **da_p, UNUSED char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)\
438
420
{ \
439
420
  _struct *flags = fr_dict_attr_ext(*da_p, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC); \
440
420
  flags->_name = 1; \
441
420
  return 0; \
442
420
}
base.c:dict_flag_dns_label
Line
Count
Source
437
152
static int dict_flag_##_name(fr_dict_attr_t **da_p, UNUSED char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)\
438
152
{ \
439
152
  _struct *flags = fr_dict_attr_ext(*da_p, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC); \
440
152
  flags->_name = 1; \
441
152
  return 0; \
442
152
}
base.c:dict_flag_partial_dns_label
Line
Count
Source
437
4
static int dict_flag_##_name(fr_dict_attr_t **da_p, UNUSED char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)\
438
4
{ \
439
4
  _struct *flags = fr_dict_attr_ext(*da_p, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC); \
440
4
  flags->_name = 1; \
441
4
  return 0; \
442
4
}
base.c:dict_flag_exists
Line
Count
Source
437
36
static int dict_flag_##_name(fr_dict_attr_t **da_p, UNUSED char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)\
438
36
{ \
439
36
  _struct *flags = fr_dict_attr_ext(*da_p, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC); \
440
36
  flags->_name = 1; \
441
36
  return 0; \
442
36
}
Unexecuted instantiation: base.c:dict_flag_dns_label_uncompressed
base.c:dict_flag_abinary
Line
Count
Source
437
20
static int dict_flag_##_name(fr_dict_attr_t **da_p, UNUSED char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)\
438
20
{ \
439
20
  _struct *flags = fr_dict_attr_ext(*da_p, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC); \
440
20
  flags->_name = 1; \
441
20
  return 0; \
442
20
}
base.c:dict_flag_concat
Line
Count
Source
437
16
static int dict_flag_##_name(fr_dict_attr_t **da_p, UNUSED char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)\
438
16
{ \
439
16
  _struct *flags = fr_dict_attr_ext(*da_p, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC); \
440
16
  flags->_name = 1; \
441
16
  return 0; \
442
16
}
base.c:dict_flag_extended
Line
Count
Source
437
16
static int dict_flag_##_name(fr_dict_attr_t **da_p, UNUSED char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)\
438
16
{ \
439
16
  _struct *flags = fr_dict_attr_ext(*da_p, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC); \
440
16
  flags->_name = 1; \
441
16
  return 0; \
442
16
}
base.c:dict_flag_has_tag
Line
Count
Source
437
168
static int dict_flag_##_name(fr_dict_attr_t **da_p, UNUSED char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)\
438
168
{ \
439
168
  _struct *flags = fr_dict_attr_ext(*da_p, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC); \
440
168
  flags->_name = 1; \
441
168
  return 0; \
442
168
}
base.c:dict_flag_long_extended
Line
Count
Source
437
8
static int dict_flag_##_name(fr_dict_attr_t **da_p, UNUSED char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)\
438
8
{ \
439
8
  _struct *flags = fr_dict_attr_ext(*da_p, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC); \
440
8
  flags->_name = 1; \
441
8
  return 0; \
442
8
}
443
444
/** conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
445
 *
446
 * @param[in] _struct   containing the field to write the result to.
447
 * @param[in] _field    to write the flag to
448
 */
449
#  define FR_DICT_PROTOCOL_FLAG(_struct, _field)  \
450
  .type = FR_CTYPE_TO_TYPE((((_struct *)NULL)->_field)), \
451
  .offset = offsetof(_struct, _field)
452
453
/** Protocol-specific callbacks in libfreeradius-PROTOCOL
454
 *
455
 */
456
typedef struct {
457
  char const      *name;        //!< name of this protocol
458
459
  int       default_type_size;    //!< how many octets are in "type" field
460
  int       default_type_length;    //!< how many octets are in "length" field
461
462
  struct {
463
          /** Custom flags for this protocol
464
     */
465
    struct {
466
      fr_dict_flag_parser_t const *table;     //!< Flags for this protocol, an array of fr_dict_flag_parser_t
467
      size_t        table_len;    //!< Length of protocol_flags table.
468
469
      size_t        len;      //!< Length of the protocol specific flags structure.
470
                    ///< This is used to allocate a FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC
471
                    ///< extension of the specified length.
472
473
      fr_dict_flags_copy_func_t copy;     //!< Copy protocol-specific flags from one attribute to another.
474
                    ///< Called when copying attributes.
475
476
      fr_dict_flags_cmp_func_t  cmp;      //!< Compare protocol-specific flags from two attributes.
477
                    ///< Called when comparing attributes by their fields.
478
    } flags;
479
480
    fr_dict_attr_type_parse_t type_parse;   //!< parse unknown type names
481
    fr_dict_attr_valid_func_t   valid;      //!< Validation function to ensure that
482
                  ///< new attributes are valid.
483
  } attr;
484
485
  fr_dict_protocol_init_t   init;       //!< initialize the library
486
  fr_dict_protocol_free_t   free;       //!< free the library
487
488
  fr_dict_attr_decode_func_t  decode;       //!< for decoding attributes.  Used for implementing foreign
489
                  ///< protocol attributes.
490
  fr_dict_attr_encode_func_t  encode;       //!< for encoding attributes.  Used for implementing foreign
491
                  ///< protocol attributes.
492
} fr_dict_protocol_t;
493
494
typedef struct fr_dict_gctx_s fr_dict_gctx_t;
495
496
/*
497
 *  Dictionary constants
498
 */
499
#define FR_DICT_PROTO_MAX_NAME_LEN  (128)       //!< Maximum length of a protocol name.
500
38.3k
#define FR_DICT_ENUM_MAX_NAME_LEN (128)        //!< Maximum length of a enum value.
501
810
#define FR_DICT_VENDOR_MAX_NAME_LEN (128)        //!< Maximum length of a vendor name.
502
58.9k
#define FR_DICT_ATTR_MAX_NAME_LEN (128)        //!< Maximum length of a attribute name.
503
504
/** Maximum level of TLV nesting allowed
505
 */
506
25.6M
#define FR_DICT_TLV_NEST_MAX    (24)
507
508
/** Maximum level of da stack caching
509
 */
510
6.09M
#define FR_DICT_DA_STACK_CACHE_MAX  (5)
511
512
/** Maximum TLV stack size
513
 *
514
 * The additional attributes are to account for
515
 *
516
 * Root + Vendor + NULL (top frame).
517
 * Root + Embedded protocol + Root + Vendor + NULL.
518
 *
519
 * Code should ensure that it doesn't run off the end of the stack,
520
 * as this could be remotely exploitable, using odd nesting.
521
 */
522
25.6M
#define FR_DICT_MAX_TLV_STACK   (FR_DICT_TLV_NEST_MAX + 5)
523
524
/** Characters allowed in a single dictionary attribute name
525
 *
526
 */
527
extern bool const fr_dict_attr_allowed_chars[UINT8_MAX + 1];
528
529
/** Characters allowed in a nested dictionary attribute name
530
 *
531
 */
532
extern bool const fr_dict_attr_nested_allowed_chars[UINT8_MAX + 1];
533
534
/** Characters that are allowed in dictionary enumeration value names
535
 *
536
 */
537
extern bool const fr_dict_enum_allowed_chars[UINT8_MAX + 1];
538
539
/** @name Dictionary structure extensions
540
 *
541
 * @{
542
 */
543
#include <freeradius-devel/util/dict_ext.h>
544
/** @} */
545
546
/** @name Programmatically create dictionary attributes and values
547
 *
548
 * @{
549
 */
550
int       fr_dict_attr_add_initialised(fr_dict_attr_t *da) CC_HINT(nonnull);
551
552
int     fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, unsigned int attr,
553
           fr_type_t type, fr_dict_attr_flags_t const *flags) CC_HINT(nonnull(1,2,3));
554
555
int     fr_dict_attr_add_name_only(fr_dict_t *dict, fr_dict_attr_t const *parent,
556
               char const *name, fr_type_t type, fr_dict_attr_flags_t const *flags) CC_HINT(nonnull(1,2,3));
557
558
int     fr_dict_enum_add_name(fr_dict_attr_t *da, char const *name,
559
                fr_value_box_t const *value, bool coerce, bool replace);
560
561
int     fr_dict_enum_add_name_next(fr_dict_attr_t *da, char const *name) CC_HINT(nonnull);
562
563
int     fr_dict_str_to_argv(char *str, char **argv, int max_argc);
564
565
int     fr_dict_attr_acopy_local(fr_dict_attr_t const *dst, fr_dict_attr_t const *src) CC_HINT(nonnull);
566
567
int     fr_dict_attr_set_group(fr_dict_attr_t **da_p) CC_HINT(nonnull);
568
/** @} */
569
570
/** @name Dict accessors
571
 *
572
 * @{
573
 */
574
fr_dict_protocol_t const *fr_dict_protocol(fr_dict_t const *dict);
575
/** @} */
576
577
/** @name Unknown ephemeral attributes
578
 *
579
 * @{
580
 */
581
fr_dict_attr_t    *fr_dict_attr_unknown_alloc(TALLOC_CTX *ctx, fr_dict_attr_t const *da, fr_type_t type) CC_HINT(nonnull(2));
582
583
fr_dict_attr_t const  *fr_dict_attr_unknown_add(fr_dict_t *dict, fr_dict_attr_t const *old) CC_HINT(nonnull);
584
585
void      fr_dict_attr_unknown_free(fr_dict_attr_t const **da);
586
587
fr_dict_attr_t    *fr_dict_attr_unknown_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da) CC_HINT(nonnull(2));
588
589
static inline fr_dict_attr_t *fr_dict_attr_unknown_copy(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
590
2.32M
{
591
2.32M
  fr_assert(da->flags.is_unknown);
592
593
2.32M
  return fr_dict_attr_unknown_afrom_da(ctx, da);
594
2.32M
}
Unexecuted instantiation: fuzzer_dhcpv6.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: fuzzer_util.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: fuzzer_dhcpv4.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: fuzzer_cbor.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: fuzzer_der.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: fuzzer_dns.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: fuzzer_tacacs.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: fuzzer_bfd.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: fuzzer_radius.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: fuzzer_tftp.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: fuzzer_vmps.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: base32.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: base64.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: calc.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: cbor.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: decode.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: dict_ext.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: dict_fixup.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: dict_print.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: dict_test.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: dict_tokenize.c:fr_dict_attr_unknown_copy
dict_unknown.c:fr_dict_attr_unknown_copy
Line
Count
Source
590
30.4k
{
591
30.4k
  fr_assert(da->flags.is_unknown);
592
593
30.4k
  return fr_dict_attr_unknown_afrom_da(ctx, da);
594
30.4k
}
Unexecuted instantiation: dict_util.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: dict_validate.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: dl.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: dns.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: edit.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: encode.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: timer.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: file.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: inet.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: log.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: packet.c:fr_dict_attr_unknown_copy
pair.c:fr_dict_attr_unknown_copy
Line
Count
Source
590
2.29M
{
591
2.29M
  fr_assert(da->flags.is_unknown);
592
593
2.29M
  return fr_dict_attr_unknown_afrom_da(ctx, da);
594
2.29M
}
Unexecuted instantiation: pair_inline.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: pair_legacy.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: pair_print.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: pair_tokenize.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: print.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: proto.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: regex.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: socket.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: stats.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: struct.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: trie.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: types.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: uri.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: value.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: fuzzer.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: base.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: raw.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: udp.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: list.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: tcp.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: abinary.c:fr_dict_attr_unknown_copy
Unexecuted instantiation: vmps.c:fr_dict_attr_unknown_copy
595
596
fr_dict_attr_t    *fr_dict_attr_unknown_typed_afrom_num_raw(TALLOC_CTX *ctx,
597
                  fr_dict_attr_t const *parent,
598
                  unsigned int num, fr_type_t type, bool raw)
599
                  CC_HINT(nonnull(2));
600
601
static inline CC_HINT(nonnull(2)) fr_dict_attr_t *fr_dict_attr_unknown_typed_afrom_num(TALLOC_CTX *ctx,
602
                           fr_dict_attr_t const *parent,
603
                           unsigned int num, fr_type_t type)
604
26.0k
{
605
26.0k
  return fr_dict_attr_unknown_typed_afrom_num_raw(ctx, parent, num, type, false);
606
26.0k
}
Unexecuted instantiation: fuzzer_dhcpv6.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: fuzzer_util.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: fuzzer_dhcpv4.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: fuzzer_cbor.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: fuzzer_der.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: fuzzer_dns.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: fuzzer_tacacs.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: fuzzer_bfd.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: fuzzer_radius.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: fuzzer_tftp.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: fuzzer_vmps.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: base32.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: base64.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: calc.c:fr_dict_attr_unknown_typed_afrom_num
cbor.c:fr_dict_attr_unknown_typed_afrom_num
Line
Count
Source
604
21.5k
{
605
  return fr_dict_attr_unknown_typed_afrom_num_raw(ctx, parent, num, type, false);
606
21.5k
}
Unexecuted instantiation: dict_ext.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: dict_fixup.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: dict_print.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: dict_test.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: dict_tokenize.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: dict_unknown.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: dict_util.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: dict_validate.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: dl.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: dns.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: edit.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: encode.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: timer.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: file.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: inet.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: log.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: packet.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: pair.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: pair_inline.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: pair_legacy.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: pair_print.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: pair_tokenize.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: print.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: proto.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: regex.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: socket.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: stats.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: struct.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: trie.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: types.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: uri.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: value.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: fuzzer.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: base.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: raw.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: udp.c:fr_dict_attr_unknown_typed_afrom_num
decode.c:fr_dict_attr_unknown_typed_afrom_num
Line
Count
Source
604
4.49k
{
605
  return fr_dict_attr_unknown_typed_afrom_num_raw(ctx, parent, num, type, false);
606
4.49k
}
Unexecuted instantiation: list.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: tcp.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: abinary.c:fr_dict_attr_unknown_typed_afrom_num
Unexecuted instantiation: vmps.c:fr_dict_attr_unknown_typed_afrom_num
607
608
609
static inline CC_HINT(nonnull(2)) fr_dict_attr_t *fr_dict_attr_unknown_vendor_afrom_num(TALLOC_CTX *ctx,
610
                      fr_dict_attr_t const *parent,
611
                      unsigned int vendor)
612
6.84k
{
613
6.84k
  return fr_dict_attr_unknown_typed_afrom_num_raw(ctx, parent, vendor, FR_TYPE_VENDOR, false);
614
6.84k
}
Unexecuted instantiation: fuzzer_dhcpv6.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: fuzzer_util.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: fuzzer_dhcpv4.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: fuzzer_cbor.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: fuzzer_der.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: fuzzer_dns.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: fuzzer_tacacs.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: fuzzer_bfd.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: fuzzer_radius.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: fuzzer_tftp.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: fuzzer_vmps.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: base32.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: base64.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: calc.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: cbor.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: dict_ext.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: dict_fixup.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: dict_print.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: dict_test.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: dict_tokenize.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: dict_unknown.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: dict_util.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: dict_validate.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: dl.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: dns.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: edit.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: encode.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: timer.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: file.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: inet.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: log.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: packet.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: pair.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: pair_inline.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: pair_legacy.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: pair_print.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: pair_tokenize.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: print.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: proto.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: regex.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: socket.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: stats.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: struct.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: trie.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: types.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: uri.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: value.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: fuzzer.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: base.c:fr_dict_attr_unknown_vendor_afrom_num
decode.c:fr_dict_attr_unknown_vendor_afrom_num
Line
Count
Source
612
6.84k
{
613
  return fr_dict_attr_unknown_typed_afrom_num_raw(ctx, parent, vendor, FR_TYPE_VENDOR, false);
614
6.84k
}
Unexecuted instantiation: raw.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: udp.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: list.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: tcp.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: abinary.c:fr_dict_attr_unknown_vendor_afrom_num
Unexecuted instantiation: vmps.c:fr_dict_attr_unknown_vendor_afrom_num
615
616
static inline CC_HINT(nonnull(2)) fr_dict_attr_t *fr_dict_attr_unknown_raw_afrom_num(TALLOC_CTX *ctx,
617
                         fr_dict_attr_t const *parent,
618
                         unsigned int attr)
619
3.56M
{
620
3.56M
  return fr_dict_attr_unknown_typed_afrom_num_raw(ctx, parent, attr, FR_TYPE_OCTETS, true);
621
3.56M
}
Unexecuted instantiation: fuzzer_dhcpv6.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: fuzzer_util.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: fuzzer_dhcpv4.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: fuzzer_cbor.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: fuzzer_der.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: fuzzer_dns.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: fuzzer_tacacs.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: fuzzer_bfd.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: fuzzer_radius.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: fuzzer_tftp.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: fuzzer_vmps.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: base32.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: base64.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: calc.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: cbor.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: dict_ext.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: dict_fixup.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: dict_print.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: dict_test.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: dict_tokenize.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: dict_unknown.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: dict_util.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: dict_validate.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: dl.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: dns.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: edit.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: encode.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: timer.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: file.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: inet.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: log.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: packet.c:fr_dict_attr_unknown_raw_afrom_num
pair.c:fr_dict_attr_unknown_raw_afrom_num
Line
Count
Source
619
1.38M
{
620
  return fr_dict_attr_unknown_typed_afrom_num_raw(ctx, parent, attr, FR_TYPE_OCTETS, true);
621
1.38M
}
Unexecuted instantiation: pair_inline.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: pair_legacy.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: pair_print.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: pair_tokenize.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: print.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: proto.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: regex.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: socket.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: stats.c:fr_dict_attr_unknown_raw_afrom_num
struct.c:fr_dict_attr_unknown_raw_afrom_num
Line
Count
Source
619
4.33k
{
620
  return fr_dict_attr_unknown_typed_afrom_num_raw(ctx, parent, attr, FR_TYPE_OCTETS, true);
621
4.33k
}
Unexecuted instantiation: trie.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: types.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: uri.c:fr_dict_attr_unknown_raw_afrom_num
value.c:fr_dict_attr_unknown_raw_afrom_num
Line
Count
Source
619
9.03k
{
620
  return fr_dict_attr_unknown_typed_afrom_num_raw(ctx, parent, attr, FR_TYPE_OCTETS, true);
621
9.03k
}
Unexecuted instantiation: fuzzer.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: base.c:fr_dict_attr_unknown_raw_afrom_num
decode.c:fr_dict_attr_unknown_raw_afrom_num
Line
Count
Source
619
2.16M
{
620
  return fr_dict_attr_unknown_typed_afrom_num_raw(ctx, parent, attr, FR_TYPE_OCTETS, true);
621
2.16M
}
Unexecuted instantiation: raw.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: udp.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: list.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: tcp.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: abinary.c:fr_dict_attr_unknown_raw_afrom_num
Unexecuted instantiation: vmps.c:fr_dict_attr_unknown_raw_afrom_num
622
623
static inline CC_HINT(nonnull(2)) fr_dict_attr_t *fr_dict_attr_unknown_afrom_oid(TALLOC_CTX *ctx,
624
                         fr_dict_attr_t const *parent,
625
                         fr_sbuff_t *in, fr_type_t type)
626
0
{
627
0
  uint32_t    num;
628
0
  fr_sbuff_parse_error_t  sberr;
629
630
0
  fr_sbuff_out(&sberr, &num, in);
631
0
  if (sberr != FR_SBUFF_PARSE_OK) return NULL;
632
633
0
  return fr_dict_attr_unknown_typed_afrom_num_raw(ctx, parent, num, type, true);
634
0
}
Unexecuted instantiation: fuzzer_dhcpv6.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: fuzzer_util.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: fuzzer_dhcpv4.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: fuzzer_cbor.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: fuzzer_der.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: fuzzer_dns.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: fuzzer_tacacs.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: fuzzer_bfd.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: fuzzer_radius.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: fuzzer_tftp.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: fuzzer_vmps.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: base32.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: base64.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: calc.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: cbor.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: decode.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: dict_ext.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: dict_fixup.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: dict_print.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: dict_test.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: dict_tokenize.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: dict_unknown.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: dict_util.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: dict_validate.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: dl.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: dns.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: edit.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: encode.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: timer.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: file.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: inet.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: log.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: packet.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: pair.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: pair_inline.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: pair_legacy.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: pair_print.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: pair_tokenize.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: print.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: proto.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: regex.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: socket.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: stats.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: struct.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: trie.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: types.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: uri.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: value.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: fuzzer.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: base.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: raw.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: udp.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: list.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: tcp.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: abinary.c:fr_dict_attr_unknown_afrom_oid
Unexecuted instantiation: vmps.c:fr_dict_attr_unknown_afrom_oid
635
636
static inline CC_HINT(nonnull(2)) fr_dict_attr_t *fr_dict_attr_unknown_raw_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
637
112k
{
638
112k
  return fr_dict_attr_unknown_alloc(ctx, da, FR_TYPE_OCTETS);
639
112k
}
Unexecuted instantiation: fuzzer_dhcpv6.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: fuzzer_util.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: fuzzer_dhcpv4.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: fuzzer_cbor.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: fuzzer_der.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: fuzzer_dns.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: fuzzer_tacacs.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: fuzzer_bfd.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: fuzzer_radius.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: fuzzer_tftp.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: fuzzer_vmps.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: base32.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: base64.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: calc.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: cbor.c:fr_dict_attr_unknown_raw_afrom_da
decode.c:fr_dict_attr_unknown_raw_afrom_da
Line
Count
Source
637
112k
{
638
112k
  return fr_dict_attr_unknown_alloc(ctx, da, FR_TYPE_OCTETS);
639
112k
}
Unexecuted instantiation: dict_ext.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: dict_fixup.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: dict_print.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: dict_test.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: dict_tokenize.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: dict_unknown.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: dict_util.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: dict_validate.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: dl.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: dns.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: edit.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: encode.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: timer.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: file.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: inet.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: log.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: packet.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: pair.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: pair_inline.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: pair_legacy.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: pair_print.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: pair_tokenize.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: print.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: proto.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: regex.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: socket.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: stats.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: struct.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: trie.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: types.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: uri.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: value.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: fuzzer.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: base.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: raw.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: udp.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: list.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: tcp.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: abinary.c:fr_dict_attr_unknown_raw_afrom_da
Unexecuted instantiation: vmps.c:fr_dict_attr_unknown_raw_afrom_da
640
641
642
fr_slen_t   fr_dict_attr_unknown_afrom_oid_substr(TALLOC_CTX *ctx,
643
                    fr_dict_attr_t const **out,
644
                    fr_dict_attr_t const *parent,
645
                    fr_sbuff_t *in, fr_type_t type)
646
                    CC_HINT(nonnull(2,3,4));
647
648
int     fr_dict_attr_unknown_parent_to_known(fr_dict_attr_t *da, fr_dict_attr_t const *parent);
649
650
fr_dict_attr_t const  *fr_dict_attr_unknown_resolve(fr_dict_t const *dict, fr_dict_attr_t const *da);
651
/** @} */
652
653
/** @name Attribute comparisons
654
 *
655
 * @{
656
 */
657
int8_t      fr_dict_attr_ordered_cmp(fr_dict_attr_t const *a, fr_dict_attr_t const *b);
658
659
static inline CC_HINT(nonnull) int8_t fr_dict_attr_cmp(fr_dict_attr_t const *a, fr_dict_attr_t const *b)
660
428k
{
661
428k
  int8_t ret;
662
663
  /*
664
   *  Comparing unknowns or raws is expensive
665
   *  because we need to check the lineage.
666
   */
667
428k
  if (a->flags.is_unknown | a->flags.is_raw | b->flags.is_unknown | b->flags.is_raw) {
668
135k
    ret = CMP(a->depth, b->depth);
669
135k
    if (ret != 0) return ret;
670
671
135k
    ret = CMP(a->attr, b->attr);
672
135k
    if (ret != 0) return ret;
673
674
52.1k
    ret = (a->parent == NULL) - (b->parent == NULL);
675
52.1k
    if ((ret != 0) || !a->parent) return ret;
676
677
52.1k
    return fr_dict_attr_cmp(a->parent, b->parent);
678
52.1k
  }
679
680
  /*
681
   *  Comparing knowns is cheap because the
682
   *  DAs are unique.
683
   */
684
292k
  return CMP(a, b);
685
428k
}
Unexecuted instantiation: fuzzer_dhcpv6.c:fr_dict_attr_cmp
Unexecuted instantiation: fuzzer_util.c:fr_dict_attr_cmp
Unexecuted instantiation: fuzzer_dhcpv4.c:fr_dict_attr_cmp
Unexecuted instantiation: fuzzer_cbor.c:fr_dict_attr_cmp
Unexecuted instantiation: fuzzer_der.c:fr_dict_attr_cmp
Unexecuted instantiation: fuzzer_dns.c:fr_dict_attr_cmp
Unexecuted instantiation: fuzzer_tacacs.c:fr_dict_attr_cmp
Unexecuted instantiation: fuzzer_bfd.c:fr_dict_attr_cmp
Unexecuted instantiation: fuzzer_radius.c:fr_dict_attr_cmp
Unexecuted instantiation: fuzzer_tftp.c:fr_dict_attr_cmp
Unexecuted instantiation: fuzzer_vmps.c:fr_dict_attr_cmp
Unexecuted instantiation: base32.c:fr_dict_attr_cmp
Unexecuted instantiation: base64.c:fr_dict_attr_cmp
Unexecuted instantiation: calc.c:fr_dict_attr_cmp
Unexecuted instantiation: cbor.c:fr_dict_attr_cmp
Unexecuted instantiation: decode.c:fr_dict_attr_cmp
Unexecuted instantiation: dict_ext.c:fr_dict_attr_cmp
Unexecuted instantiation: dict_fixup.c:fr_dict_attr_cmp
Unexecuted instantiation: dict_print.c:fr_dict_attr_cmp
Unexecuted instantiation: dict_test.c:fr_dict_attr_cmp
Unexecuted instantiation: dict_tokenize.c:fr_dict_attr_cmp
Unexecuted instantiation: dict_unknown.c:fr_dict_attr_cmp
Unexecuted instantiation: dict_util.c:fr_dict_attr_cmp
Unexecuted instantiation: dict_validate.c:fr_dict_attr_cmp
Unexecuted instantiation: dl.c:fr_dict_attr_cmp
Unexecuted instantiation: dns.c:fr_dict_attr_cmp
Unexecuted instantiation: edit.c:fr_dict_attr_cmp
Unexecuted instantiation: encode.c:fr_dict_attr_cmp
Unexecuted instantiation: timer.c:fr_dict_attr_cmp
Unexecuted instantiation: file.c:fr_dict_attr_cmp
Unexecuted instantiation: inet.c:fr_dict_attr_cmp
Unexecuted instantiation: log.c:fr_dict_attr_cmp
Unexecuted instantiation: packet.c:fr_dict_attr_cmp
Unexecuted instantiation: pair.c:fr_dict_attr_cmp
Unexecuted instantiation: pair_inline.c:fr_dict_attr_cmp
Unexecuted instantiation: pair_legacy.c:fr_dict_attr_cmp
Unexecuted instantiation: pair_print.c:fr_dict_attr_cmp
Unexecuted instantiation: pair_tokenize.c:fr_dict_attr_cmp
Unexecuted instantiation: print.c:fr_dict_attr_cmp
Unexecuted instantiation: proto.c:fr_dict_attr_cmp
Unexecuted instantiation: regex.c:fr_dict_attr_cmp
Unexecuted instantiation: socket.c:fr_dict_attr_cmp
Unexecuted instantiation: stats.c:fr_dict_attr_cmp
Unexecuted instantiation: struct.c:fr_dict_attr_cmp
Unexecuted instantiation: trie.c:fr_dict_attr_cmp
Unexecuted instantiation: types.c:fr_dict_attr_cmp
Unexecuted instantiation: uri.c:fr_dict_attr_cmp
Unexecuted instantiation: value.c:fr_dict_attr_cmp
Unexecuted instantiation: fuzzer.c:fr_dict_attr_cmp
Unexecuted instantiation: base.c:fr_dict_attr_cmp
base.c:fr_dict_attr_cmp
Line
Count
Source
660
428k
{
661
428k
  int8_t ret;
662
663
  /*
664
   *  Comparing unknowns or raws is expensive
665
   *  because we need to check the lineage.
666
   */
667
428k
  if (a->flags.is_unknown | a->flags.is_raw | b->flags.is_unknown | b->flags.is_raw) {
668
135k
    ret = CMP(a->depth, b->depth);
669
135k
    if (ret != 0) return ret;
670
671
135k
    ret = CMP(a->attr, b->attr);
672
135k
    if (ret != 0) return ret;
673
674
52.1k
    ret = (a->parent == NULL) - (b->parent == NULL);
675
52.1k
    if ((ret != 0) || !a->parent) return ret;
676
677
52.1k
    return fr_dict_attr_cmp(a->parent, b->parent);
678
52.1k
  }
679
680
  /*
681
   *  Comparing knowns is cheap because the
682
   *  DAs are unique.
683
   */
684
292k
  return CMP(a, b);
685
428k
}
Unexecuted instantiation: raw.c:fr_dict_attr_cmp
Unexecuted instantiation: udp.c:fr_dict_attr_cmp
Unexecuted instantiation: list.c:fr_dict_attr_cmp
Unexecuted instantiation: tcp.c:fr_dict_attr_cmp
Unexecuted instantiation: abinary.c:fr_dict_attr_cmp
Unexecuted instantiation: vmps.c:fr_dict_attr_cmp
686
687
/** Compare two dictionary attributes by their contents
688
 *
689
 * @param[in] a First attribute to compare.
690
 * @param[in] b Second attribute to compare.
691
 * @return
692
 *  - 0 if the attributes are equal.
693
 *  - -1 if a < b.
694
 *  - +1 if a > b.
695
 */
696
static inline CC_HINT(nonnull) int8_t fr_dict_attr_cmp_fields(const fr_dict_attr_t *a, const fr_dict_attr_t *b)
697
0
{
698
0
  int8_t ret;
699
0
  fr_dict_protocol_t const *a_proto = fr_dict_protocol(a->dict);
700
701
  /*
702
   *  Technically this isn't a property of the attribute
703
   *  but we need them to be the same to be able to
704
   *  compare protocol specific flags successfully.
705
   */
706
0
  ret = CMP(a_proto, fr_dict_protocol(b->dict));
707
0
  if (ret != 0) return ret;
708
709
0
  ret = CMP(a->attr, b->attr);
710
0
  if (ret != 0) return ret;
711
712
0
  ret = CMP(a->parent, b->parent);
713
0
  if (ret != 0) return ret;
714
715
0
  ret = CMP(fr_dict_vendor_num_by_da(a), fr_dict_vendor_num_by_da(b));
716
0
  if (ret != 0) return ret;
717
718
  /*
719
   *  Compare protocol specific flags
720
   */
721
0
  if (a_proto->attr.flags.cmp && (ret = a_proto->attr.flags.cmp(a, b))) return ret;
722
723
0
  return CMP(memcmp(&a->flags, &b->flags, sizeof(a->flags)), 0);
724
0
}
Unexecuted instantiation: fuzzer_dhcpv6.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: fuzzer_util.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: fuzzer_dhcpv4.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: fuzzer_cbor.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: fuzzer_der.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: fuzzer_dns.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: fuzzer_tacacs.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: fuzzer_bfd.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: fuzzer_radius.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: fuzzer_tftp.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: fuzzer_vmps.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: base32.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: base64.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: calc.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: cbor.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: decode.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: dict_ext.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: dict_fixup.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: dict_print.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: dict_test.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: dict_tokenize.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: dict_unknown.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: dict_util.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: dict_validate.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: dl.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: dns.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: edit.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: encode.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: timer.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: file.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: inet.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: log.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: packet.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: pair.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: pair_inline.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: pair_legacy.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: pair_print.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: pair_tokenize.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: print.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: proto.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: regex.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: socket.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: stats.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: struct.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: trie.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: types.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: uri.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: value.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: fuzzer.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: base.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: raw.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: udp.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: list.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: tcp.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: abinary.c:fr_dict_attr_cmp_fields
Unexecuted instantiation: vmps.c:fr_dict_attr_cmp_fields
725
/** @} */
726
727
/** @name Debugging functions
728
 *
729
 * @{
730
 */
731
void      fr_dict_namespace_debug(FILE *fp, fr_dict_attr_t const *da);
732
733
void      fr_dict_attr_debug(FILE *fp, fr_dict_attr_t const *da);
734
735
void      fr_dict_debug(FILE *fp, fr_dict_t const *dict);
736
737
void      fr_dict_export(FILE *fp, fr_dict_t const *dict);
738
739
void      fr_dict_alias_export(FILE *fp, fr_dict_attr_t const *parent);
740
/** @} */
741
742
/** @name Attribute lineage
743
 *
744
 * @{
745
 */
746
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);
747
748
int     fr_dict_oid_component_legacy(unsigned int *out, char const **oid);
749
750
fr_slen_t   fr_dict_attr_flags_print(fr_sbuff_t *out, fr_dict_t const *dict,
751
             fr_type_t type, fr_dict_attr_flags_t const *flags);
752
753
fr_slen_t   fr_dict_attr_oid_print(fr_sbuff_t *out,
754
                 fr_dict_attr_t const *ancestor, fr_dict_attr_t const *da, bool numeric);
755
0
#define     FR_DICT_ATTR_OID_PRINT_RETURN(...) FR_SBUFF_RETURN(fr_dict_attr_oid_print, ##__VA_ARGS__)
756
757
fr_slen_t   fr_dict_attr_by_oid_legacy(fr_dict_t const *dict, fr_dict_attr_t const **parent,
758
                     unsigned int *attr, char const *oid) CC_HINT(nonnull);
759
760
fr_slen_t   fr_dict_oid_component(fr_dict_attr_err_t *err,
761
                fr_dict_attr_t const **out, fr_dict_attr_t const *parent,
762
                fr_sbuff_t *in, fr_sbuff_term_t const *tt)
763
                CC_HINT(nonnull(2,3,4));
764
765
fr_slen_t   fr_dict_attr_by_oid_substr(fr_dict_attr_err_t *err,
766
               fr_dict_attr_t const **out, fr_dict_attr_t const *parent,
767
               fr_sbuff_t *in, fr_sbuff_term_t const *tt)
768
               CC_HINT(nonnull(2,3,4));
769
770
fr_dict_attr_t const  *fr_dict_attr_by_oid(fr_dict_attr_err_t *err,
771
               fr_dict_attr_t const *parent, char const *oid)
772
               CC_HINT(nonnull(2,3));
773
774
bool      fr_dict_attr_can_contain(fr_dict_attr_t const *parent, fr_dict_attr_t const *child) CC_HINT(nonnull);
775
776
/** @} */
777
778
/** @name Attribute, vendor and dictionary lookup
779
 *
780
 * @{
781
 */
782
783
/** @hidecallergraph */
784
fr_dict_attr_t const  *fr_dict_root(fr_dict_t const *dict) CC_HINT(nonnull);
785
786
bool      fr_dict_is_read_only(fr_dict_t const *dict);
787
788
dl_t      *fr_dict_dl(fr_dict_t const *dict);
789
790
fr_slen_t   fr_dict_by_protocol_substr(fr_dict_attr_err_t *err,
791
               fr_dict_t const **out, fr_sbuff_t *name, fr_dict_t const *dict_def);
792
793
fr_dict_t const   *fr_dict_by_protocol_name(char const *name);
794
795
fr_dict_t const   *fr_dict_by_protocol_num(unsigned int num);
796
797
fr_dict_attr_t const  *fr_dict_unlocal(fr_dict_attr_t const *da) CC_HINT(nonnull);
798
799
fr_dict_t const   *fr_dict_proto_dict(fr_dict_t const *dict) CC_HINT(nonnull);
800
801
fr_dict_t const   *fr_dict_by_da(fr_dict_attr_t const *da) CC_HINT(nonnull);
802
803
fr_dict_t const   *fr_dict_by_attr_name(fr_dict_attr_t const **found, char const *name);
804
805
bool      fr_dict_compatible(fr_dict_t const *dict1, fr_dict_t const *dict2) CC_HINT(nonnull);
806
807
/** Return true if this attribute is parented directly off the dictionary root
808
 *
809
 * @param[in] da    to check.
810
 * @return
811
 *  - true if attribute is top level.
812
 *  - false if attribute is not top level.
813
 */
814
static inline bool fr_dict_attr_is_top_level(fr_dict_attr_t const *da)
815
0
{
816
0
  if (unlikely(!da) || unlikely(!da->parent)) return false;
817
0
  return da->parent->flags.is_root;
818
0
}
Unexecuted instantiation: fuzzer_dhcpv6.c:fr_dict_attr_is_top_level
Unexecuted instantiation: fuzzer_util.c:fr_dict_attr_is_top_level
Unexecuted instantiation: fuzzer_dhcpv4.c:fr_dict_attr_is_top_level
Unexecuted instantiation: fuzzer_cbor.c:fr_dict_attr_is_top_level
Unexecuted instantiation: fuzzer_der.c:fr_dict_attr_is_top_level
Unexecuted instantiation: fuzzer_dns.c:fr_dict_attr_is_top_level
Unexecuted instantiation: fuzzer_tacacs.c:fr_dict_attr_is_top_level
Unexecuted instantiation: fuzzer_bfd.c:fr_dict_attr_is_top_level
Unexecuted instantiation: fuzzer_radius.c:fr_dict_attr_is_top_level
Unexecuted instantiation: fuzzer_tftp.c:fr_dict_attr_is_top_level
Unexecuted instantiation: fuzzer_vmps.c:fr_dict_attr_is_top_level
Unexecuted instantiation: base32.c:fr_dict_attr_is_top_level
Unexecuted instantiation: base64.c:fr_dict_attr_is_top_level
Unexecuted instantiation: calc.c:fr_dict_attr_is_top_level
Unexecuted instantiation: cbor.c:fr_dict_attr_is_top_level
Unexecuted instantiation: decode.c:fr_dict_attr_is_top_level
Unexecuted instantiation: dict_ext.c:fr_dict_attr_is_top_level
Unexecuted instantiation: dict_fixup.c:fr_dict_attr_is_top_level
Unexecuted instantiation: dict_print.c:fr_dict_attr_is_top_level
Unexecuted instantiation: dict_test.c:fr_dict_attr_is_top_level
Unexecuted instantiation: dict_tokenize.c:fr_dict_attr_is_top_level
Unexecuted instantiation: dict_unknown.c:fr_dict_attr_is_top_level
Unexecuted instantiation: dict_util.c:fr_dict_attr_is_top_level
Unexecuted instantiation: dict_validate.c:fr_dict_attr_is_top_level
Unexecuted instantiation: dl.c:fr_dict_attr_is_top_level
Unexecuted instantiation: dns.c:fr_dict_attr_is_top_level
Unexecuted instantiation: edit.c:fr_dict_attr_is_top_level
Unexecuted instantiation: encode.c:fr_dict_attr_is_top_level
Unexecuted instantiation: timer.c:fr_dict_attr_is_top_level
Unexecuted instantiation: file.c:fr_dict_attr_is_top_level
Unexecuted instantiation: inet.c:fr_dict_attr_is_top_level
Unexecuted instantiation: log.c:fr_dict_attr_is_top_level
Unexecuted instantiation: packet.c:fr_dict_attr_is_top_level
Unexecuted instantiation: pair.c:fr_dict_attr_is_top_level
Unexecuted instantiation: pair_inline.c:fr_dict_attr_is_top_level
Unexecuted instantiation: pair_legacy.c:fr_dict_attr_is_top_level
Unexecuted instantiation: pair_print.c:fr_dict_attr_is_top_level
Unexecuted instantiation: pair_tokenize.c:fr_dict_attr_is_top_level
Unexecuted instantiation: print.c:fr_dict_attr_is_top_level
Unexecuted instantiation: proto.c:fr_dict_attr_is_top_level
Unexecuted instantiation: regex.c:fr_dict_attr_is_top_level
Unexecuted instantiation: socket.c:fr_dict_attr_is_top_level
Unexecuted instantiation: stats.c:fr_dict_attr_is_top_level
Unexecuted instantiation: struct.c:fr_dict_attr_is_top_level
Unexecuted instantiation: trie.c:fr_dict_attr_is_top_level
Unexecuted instantiation: types.c:fr_dict_attr_is_top_level
Unexecuted instantiation: uri.c:fr_dict_attr_is_top_level
Unexecuted instantiation: value.c:fr_dict_attr_is_top_level
Unexecuted instantiation: fuzzer.c:fr_dict_attr_is_top_level
Unexecuted instantiation: base.c:fr_dict_attr_is_top_level
Unexecuted instantiation: raw.c:fr_dict_attr_is_top_level
Unexecuted instantiation: udp.c:fr_dict_attr_is_top_level
Unexecuted instantiation: list.c:fr_dict_attr_is_top_level
Unexecuted instantiation: tcp.c:fr_dict_attr_is_top_level
Unexecuted instantiation: abinary.c:fr_dict_attr_is_top_level
Unexecuted instantiation: vmps.c:fr_dict_attr_is_top_level
819
820
fr_dict_vendor_t const  *fr_dict_vendor_by_da(fr_dict_attr_t const *da);
821
822
fr_dict_vendor_t const  *fr_dict_vendor_by_name(fr_dict_t const *dict, char const *name);
823
824
fr_dict_vendor_t const  *fr_dict_vendor_by_num(fr_dict_t const *dict, uint32_t vendor_pen);
825
826
fr_dict_attr_t const  *fr_dict_vendor_da_by_num(fr_dict_attr_t const *vendor_root, uint32_t vendor_pen);
827
828
fr_slen_t   fr_dict_attr_search_by_qualified_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out,
829
                     fr_dict_t const *dict_def,
830
                     fr_sbuff_t *name, fr_sbuff_term_t const *tt,
831
                     bool internal, bool foreign)
832
                     CC_HINT(nonnull(2, 4));
833
834
fr_slen_t   fr_dict_attr_search_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out,
835
                   fr_dict_t const *dict_def,
836
                 fr_sbuff_t *name, fr_sbuff_term_t const *tt,
837
                 bool internal, bool foreign)
838
                 CC_HINT(nonnull(2, 4));
839
840
fr_slen_t   fr_dict_attr_search_by_qualified_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out,
841
                        fr_dict_t const *dict_def,
842
                    fr_sbuff_t *in, fr_sbuff_term_t const *tt,
843
                    bool internal, bool foreign)
844
                    CC_HINT(nonnull(2, 4));
845
846
fr_dict_attr_t const  *fr_dict_attr_search_by_qualified_oid(fr_dict_attr_err_t *err,
847
                          fr_dict_t const *dict_def, char const *attr,
848
                          bool internal, bool foreign)
849
                    CC_HINT(nonnull(3));
850
851
fr_slen_t   fr_dict_attr_search_by_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out,
852
                fr_dict_t const *dict_def,
853
                fr_sbuff_t *in, fr_sbuff_term_t const *tt,
854
                bool internal, bool foreign)
855
                CC_HINT(nonnull(2, 4));
856
857
fr_slen_t   fr_dict_attr_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out,
858
                fr_dict_attr_t const *parent,
859
                fr_sbuff_t *name, fr_sbuff_term_t const *tt)
860
                CC_HINT(nonnull(2,3,4));
861
862
fr_dict_attr_t const  *fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent,
863
                char const *attr)
864
                CC_HINT(nonnull(2,3));
865
866
fr_dict_attr_t const  *fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr);
867
868
typedef fr_hash_iter_t fr_dict_enum_iter_t; /* Alias this in case we want to change it in future */
869
870
fr_dict_enum_value_t const *fr_dict_enum_iter_init(fr_dict_attr_t const *da, fr_dict_enum_iter_t *iter);
871
872
fr_dict_enum_value_t const *fr_dict_enum_iter_next(fr_dict_attr_t const *da, fr_dict_enum_iter_t *iter);
873
874
fr_dict_enum_value_t const *fr_dict_enum_by_value(fr_dict_attr_t const *da, fr_value_box_t const *value);
875
876
char const    *fr_dict_enum_name_by_value(fr_dict_attr_t const *da, fr_value_box_t const *value);
877
878
fr_dict_enum_value_t const *fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len);
879
880
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);
881
882
fr_slen_t   fr_dict_enum_name_from_substr(fr_sbuff_t *out, fr_sbuff_parse_error_t *err,
883
                  fr_sbuff_t *in, fr_sbuff_term_t const *tt);
884
885
static inline fr_slen_t fr_dict_enum_name_afrom_substr(TALLOC_CTX *ctx, char **out, fr_sbuff_parse_error_t *err,
886
                   fr_sbuff_t *in, fr_sbuff_term_t const *tt)
887
      SBUFF_OUT_TALLOC_FUNC_NO_LEN_DEF(fr_dict_enum_name_from_substr, err, in, tt)
888
/** @} */
889
890
/** @name Dictionary and protocol loading
891
 *
892
 * @{
893
 */
894
int     fr_dict_internal_afrom_file(fr_dict_t **out, char const *internal_name,
895
                char const *dependent);
896
897
int     fr_dict_protocol_afrom_file(fr_dict_t **out, char const *proto_name, char const *proto_dir,
898
                char const *dependent);
899
900
fr_dict_t   *fr_dict_protocol_alloc(fr_dict_t const *parent);
901
902
int     fr_dict_protocol_reference(fr_dict_attr_t const **da_p, fr_dict_attr_t const *root, fr_sbuff_t *in);
903
904
int     fr_dict_read(fr_dict_t *dict, char const *dict_dir, char const *filename);
905
/** @} */
906
907
/** @name Autoloader interface
908
 *
909
 * @{
910
 */
911
int     fr_dict_enum_autoload(fr_dict_enum_autoload_t const *to_load);
912
913
int     fr_dict_attr_autoload(fr_dict_attr_autoload_t const *to_load);
914
915
962
#define     fr_dict_autoload(_to_load) _fr_dict_autoload(_to_load, __FILE__)
916
int     _fr_dict_autoload(fr_dict_autoload_t const *to_load, char const *dependent);
917
918
954
#define     fr_dict_autofree(_to_free) _fr_dict_autofree(_to_free, __FILE__)
919
int     _fr_dict_autofree(fr_dict_autoload_t const *to_free, char const *dependent);
920
921
#define     fr_dict_autoload_talloc(_ctx, _dict_out, _proto) _fr_dict_autoload_talloc(_ctx, _dict_out, _proto, __FILE__)
922
fr_dict_autoload_talloc_t *_fr_dict_autoload_talloc(TALLOC_CTX *ctx, fr_dict_t const **out, char const *proto, char const *dependent);
923
924
int     fr_dl_dict_enum_autoload(dl_t const *module, void *symbol, void *user_ctx);
925
926
int     fr_dl_dict_attr_autoload(dl_t const *module, void *symbol, void *user_ctx);
927
928
int     fr_dl_dict_autoload(dl_t const *module, void *symbol, void *user_ctx);
929
930
void      fr_dl_dict_autofree(dl_t const *module, void *symbol, void *user_ctx);
931
/** @} */
932
933
/** @name Allocating and freeing
934
 *
935
 * @{
936
 */
937
fr_dict_t     *fr_dict_alloc(char const *proto_name, unsigned int proto_number) CC_HINT(nonnull);
938
939
int     fr_dict_dependent_add(fr_dict_t const *dict, char const *dependent) CC_HINT(nonnull);
940
941
int     fr_dict_free(fr_dict_t **dict, char const *dependent) CC_HINT(nonnull);
942
943
int     fr_dict_const_free(fr_dict_t const **dict, char const *dependent) CC_HINT(nonnull);
944
/** @} */
945
946
/** @name Global dictionary management
947
 *
948
 * @{
949
 */
950
fr_dict_gctx_t    *fr_dict_global_ctx_init(TALLOC_CTX *ctx, bool free_at_exit, char const *dict_dir);
951
952
void      fr_dict_global_ctx_perm_check(fr_dict_gctx_t *gctx, bool enable);
953
954
void      fr_dict_global_ctx_set(fr_dict_gctx_t const *gctx);
955
956
int     fr_dict_global_ctx_free(fr_dict_gctx_t const *gctx);
957
958
int     fr_dict_global_ctx_dir_set(char const *dict_dir);
959
960
void      fr_dict_global_ctx_read_only(void);
961
962
void      fr_dict_gctx_debug(FILE *fp, fr_dict_gctx_t const *gctx);
963
964
char const    *fr_dict_global_ctx_dir(void);
965
966
typedef struct fr_hash_iter_s fr_dict_global_ctx_iter_t;
967
968
fr_dict_t   *fr_dict_global_ctx_iter_init(fr_dict_global_ctx_iter_t *iter) CC_HINT(nonnull);
969
970
fr_dict_t   *fr_dict_global_ctx_iter_next(fr_dict_global_ctx_iter_t *iter) CC_HINT(nonnull);
971
972
fr_dict_t   *fr_dict_unconst(fr_dict_t const *dict);
973
974
fr_dict_attr_t    *fr_dict_attr_unconst(fr_dict_attr_t const *da);
975
976
fr_dict_t const   *fr_dict_internal(void);
977
978
/** @} */
979
980
/** @name Dictionary testing and validation
981
 *
982
 * @{
983
 */
984
void      dict_dctx_debug(dict_tokenize_ctx_t *dctx);
985
986
int     fr_dict_parse_str(fr_dict_t *dict, char *buf,
987
            fr_dict_attr_t const *parent);
988
989
ssize_t     fr_dict_valid_name(char const *name, ssize_t len);
990
991
ssize_t     fr_dict_valid_oid_str(char const *name, ssize_t len);
992
993
fr_dict_attr_t const  *fr_dict_attr_iterate_children(fr_dict_attr_t const *parent, fr_dict_attr_t const **prev);
994
995
typedef int   (*fr_dict_walk_t)(fr_dict_attr_t const *da, void *uctx);
996
997
int     fr_dict_walk(fr_dict_attr_t const *da, fr_dict_walk_t callback, void *uctx);
998
999
void      fr_dict_attr_verify(char const *file, int line, fr_dict_attr_t const *da);
1000
/** @} */
1001
1002
#undef _CONST
1003
1004
#ifdef __cplusplus
1005
}
1006
#endif