Coverage Report

Created: 2025-12-31 06:18

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