/src/freeradius-server/src/freeradius-devel/util/dict.h
Line | Count | Source (jump to first uncovered line) |
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 | | RCSIDH(dict_h, "$Id: 0ad1bda348c50556e9d12359321a6485794c017c $") |
25 | | |
26 | | #ifdef __cplusplus |
27 | | extern "C" { |
28 | | #endif |
29 | | |
30 | | #include <freeradius-devel/build.h> |
31 | | #include <freeradius-devel/missing.h> |
32 | | #include <freeradius-devel/util/dl.h> |
33 | | #include <freeradius-devel/util/ext.h> |
34 | | #include <freeradius-devel/util/rb.h> |
35 | | #include <freeradius-devel/util/sbuff.h> |
36 | | #include <freeradius-devel/util/table.h> |
37 | | #include <freeradius-devel/util/talloc.h> |
38 | | #include <freeradius-devel/util/types.h> |
39 | | |
40 | | #include <stdbool.h> |
41 | | #include <stdint.h> |
42 | | |
43 | | /* |
44 | | * Avoid circular type references. |
45 | | */ |
46 | | typedef struct dict_attr_s fr_dict_attr_t; |
47 | | typedef struct fr_dict fr_dict_t; |
48 | | |
49 | | typedef struct value_box_s fr_value_box_t; |
50 | | |
51 | | /* |
52 | | * Allow public and private versions of the same structures |
53 | | */ |
54 | | #ifdef _CONST |
55 | | # error _CONST can only be defined in the local header |
56 | | #endif |
57 | | #ifndef _DICT_PRIVATE |
58 | | # define _CONST const |
59 | | #else |
60 | | # define _CONST |
61 | | #endif |
62 | | |
63 | | #ifdef WITH_VERIFY_PTR |
64 | 5.24M | # define DA_VERIFY(_x) fr_dict_attr_verify(__FILE__, __LINE__, _x) |
65 | | #else |
66 | | # define DA_VERIFY(_x) fr_cond_assert(_x) |
67 | | #endif |
68 | | |
69 | | typedef struct fr_dict_autoload_talloc_s fr_dict_autoload_talloc_t; |
70 | | |
71 | | /** Values of the encryption flags |
72 | | */ |
73 | | typedef struct { |
74 | | unsigned int is_root : 1; //!< Is root of a dictionary. |
75 | | |
76 | | unsigned int is_unknown : 1; //!< This dictionary attribute is ephemeral |
77 | | ///< and not part of the main dictionary. |
78 | | |
79 | | unsigned int is_raw : 1; //!< This dictionary attribute was constructed |
80 | | ///< from a known attribute to allow the user |
81 | | ///< to assign octets values directly. |
82 | | ///< See .is_unknown to determine if it is |
83 | | ///< ephemeral. |
84 | | unsigned int is_alias : 1; //!< This isn't a real attribute, it's a reference to |
85 | | ///< to one. |
86 | | unsigned int internal : 1; //!< Internal attribute, should not be received |
87 | | ///< in protocol packets, should not be encoded. |
88 | | unsigned int array : 1; //!< Pack multiples into 1 attr. |
89 | | |
90 | | unsigned int is_known_width : 1; //!< is treated as if it has a known width for structs |
91 | | |
92 | | unsigned int has_value : 1; //!< Has a value. |
93 | | |
94 | | unsigned int is_unsigned : 1; //!< hackity hack for dates and time deltas |
95 | | |
96 | | unsigned int counter : 1; //!< integer attribute is actually an impulse / counter |
97 | | |
98 | | unsigned int name_only : 1; //!< this attribute should always be referred to by name, not by number |
99 | | |
100 | | unsigned int secret : 1; //!< this attribute should be omitted in debug mode |
101 | | |
102 | | /* |
103 | | * @todo - if we want to clean these fields up, make |
104 | | * "subtype" and "type_size" both 4-bit bitfields. That |
105 | | * gives us an extra 8 bits for adding new flags, and we |
106 | | * can likely get rid of "extra", in order to save one |
107 | | * more bit. |
108 | | */ |
109 | | unsigned int extra : 1; //!< really "subtype is used by dict, not by protocol" |
110 | | |
111 | | unsigned int local : 1; //!< is a local variable |
112 | | |
113 | | /* |
114 | | * main: extra is set, then this field is is key, bit, or a uint16 length field. |
115 | | * radius: is one of 9 options for flags |
116 | | * dhcp v4/v6: DNS label, or partial DNS label |
117 | | */ |
118 | | uint8_t subtype; //!< protocol-specific values, OR key fields |
119 | | |
120 | | /* |
121 | | * Length in bytes for most attributes. |
122 | | * Length in bits for da_is_bit_field(da) |
123 | | */ |
124 | | uint8_t length; //!< length of the attribute |
125 | | |
126 | | /* |
127 | | * TLVs: 1, 2, or 4. |
128 | | * date / time types: fr_time_res_t, which has 4 possible values. |
129 | | * bit fields: offset in the byte where this bit field ends, which is only |
130 | | * used as a caching mechanism during parsing of the dictionaries. |
131 | | */ |
132 | | uint8_t type_size; //!< For TLV2 and root attributes. |
133 | | } fr_dict_attr_flags_t; |
134 | | |
135 | 23.0k | #define flag_time_res type_size |
136 | 1.04k | #define flag_byte_offset type_size |
137 | | |
138 | | /** subtype values for the dictionary when extra=1 |
139 | | * |
140 | | */ |
141 | | enum { |
142 | | FLAG_EXTRA_NONE = 0, //!< no extra meaning, should be invalid |
143 | | FLAG_KEY_FIELD, //!< this is a key field for a subsequent struct |
144 | | FLAG_BIT_FIELD, //!< bit field inside of a struct |
145 | | FLAG_LENGTH_UINT8, //!< string / octets type is prefixed by uint8 of length |
146 | | FLAG_LENGTH_UINT16, //!< string / octets type is prefixed by uint16 of length |
147 | | }; |
148 | | |
149 | 312k | #define fr_dict_attr_is_key_field(_da) ((_da)->flags.extra && ((_da)->flags.subtype == FLAG_KEY_FIELD)) |
150 | 265k | #define da_is_bit_field(_da) ((_da)->flags.extra && ((_da)->flags.subtype == FLAG_BIT_FIELD)) |
151 | 1.59M | #define da_is_length_field(_da) ((_da)->flags.extra && (((_da)->flags.subtype == FLAG_LENGTH_UINT8) || ((_da)->flags.subtype == FLAG_LENGTH_UINT16))) |
152 | 19.4k | #define da_length_offset(_da) ((_da)->flags.type_size) |
153 | | |
154 | | |
155 | | /** Extension identifier |
156 | | * |
157 | | * @note New extension structures should also be added to the to the appropriate table in dict_ext.c |
158 | | */ |
159 | | typedef enum { |
160 | | FR_DICT_ATTR_EXT_NAME = 0, //!< Name of the attribute. |
161 | | FR_DICT_ATTR_EXT_CHILDREN, //!< Attribute has children. |
162 | | FR_DICT_ATTR_EXT_REF, //!< Attribute references another |
163 | | ///< attribute and/or dictionary. |
164 | | FR_DICT_ATTR_EXT_VENDOR, //!< Cached vendor pointer. |
165 | | FR_DICT_ATTR_EXT_DA_STACK, //!< Cached da stack. |
166 | | FR_DICT_ATTR_EXT_ENUMV, //!< Enumeration values. |
167 | | FR_DICT_ATTR_EXT_NAMESPACE, //!< Attribute has its own namespace. |
168 | | FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC, //!< Protocol specific extensions |
169 | | FR_DICT_ATTR_EXT_MAX |
170 | | } fr_dict_attr_ext_t; |
171 | | |
172 | | /** Dictionary attribute |
173 | | */ |
174 | | struct dict_attr_s { |
175 | | fr_dict_t _CONST* _CONST dict; //!< Dict attribute belongs to. |
176 | | |
177 | | char const *name; //!< Attribute name. |
178 | | size_t name_len; //!< Length of the name. |
179 | | |
180 | | unsigned int attr; //!< Attribute number. |
181 | | unsigned int depth; //!< Depth of nesting for this attribute. |
182 | | |
183 | | unsigned int last_child_attr; //!< highest value of last child attribute. |
184 | | |
185 | | fr_type_t type; //!< Value type. |
186 | | |
187 | | fr_dict_attr_t const *parent; //!< Immediate parent of this attribute. |
188 | | fr_dict_attr_t const *next; //!< Next child in bin. |
189 | | fr_dict_attr_t *fixup; //!< Attribute has been marked up for fixups. |
190 | | |
191 | | fr_dict_attr_flags_t flags; //!< Flags. |
192 | | |
193 | | uint8_t ext[FR_DICT_ATTR_EXT_MAX]; //!< Extensions to the dictionary attribute. |
194 | | } CC_HINT(aligned(FR_EXT_ALIGNMENT)); |
195 | | |
196 | | /** Extension identifier |
197 | | * |
198 | | * @note New extension structures should also be added to the appropriate table in dict_ext.c |
199 | | */ |
200 | | typedef enum { |
201 | | FR_DICT_ENUM_EXT_UNION_REF = 0, //!< Reference to a union/subs-struct. |
202 | | FR_DICT_ENUM_EXT_MAX |
203 | | } fr_dict_enum_ext_t; |
204 | | |
205 | | /** Value of an enumerated attribute |
206 | | * |
207 | | * Maps one of more string values to integers and vice versa. |
208 | | */ |
209 | | typedef struct { |
210 | | char const *name; //!< Enum name. |
211 | | size_t name_len; //!< Allows for efficient name lookups when operating |
212 | | ///< on partial buffers. |
213 | | fr_value_box_t const *value; //!< Enum value (what name maps to). |
214 | | |
215 | | uint8_t ext[FR_DICT_ENUM_EXT_MAX]; //!< Extensions to the dictionary attribute. |
216 | | |
217 | | fr_dict_attr_t const *child_struct[]; //!< for key fields |
218 | | } fr_dict_enum_value_t CC_HINT(aligned(FR_EXT_ALIGNMENT)); |
219 | | |
220 | | /** Private enterprise |
221 | | * |
222 | | * Represents an IANA private enterprise allocation. |
223 | | * |
224 | | * The width of the private enterprise number must be the same for all protocols |
225 | | * so we can represent a vendor with a single struct. |
226 | | */ |
227 | | typedef struct { |
228 | | uint32_t pen; //!< Private enterprise number. |
229 | | bool continuation; //!< we only have one flag for now, for WiMAX |
230 | | size_t type; //!< Length of type data |
231 | | size_t length; //!< Length of length data |
232 | | char const *name; //!< Vendor name. |
233 | | } fr_dict_vendor_t; |
234 | | |
235 | | /** Specifies a value which must be present for the module to function |
236 | | * |
237 | | */ |
238 | | typedef struct { |
239 | | fr_value_box_t const **out; //!< Enumeration value. |
240 | | fr_dict_attr_t const **attr; //!< The protocol dictionary the attribute should |
241 | | ///< be resolved in. ** so it's a compile time |
242 | | ///< constant. |
243 | | char const *name; //!< of the attribute. |
244 | | } fr_dict_enum_autoload_t; |
245 | | |
246 | | /** Specifies an attribute which must be present for the module to function |
247 | | * |
248 | | */ |
249 | | typedef struct { |
250 | | fr_dict_attr_t const **out; //!< Where to write a pointer to the resolved |
251 | | //!< #fr_dict_attr_t. |
252 | | fr_dict_t const **dict; //!< The protocol dictionary the attribute should |
253 | | ///< be resolved in. ** so it's a compile time |
254 | | ///< constant. |
255 | | char const *name; //!< of the attribute. |
256 | | fr_type_t type; //!< of the attribute. Mismatch is a fatal error. |
257 | | } fr_dict_attr_autoload_t; |
258 | | |
259 | | /** Specifies a dictionary which must be loaded/loadable for the module to function |
260 | | * |
261 | | */ |
262 | | typedef struct { |
263 | | fr_dict_t const **out; //!< Where to write a pointer to the loaded/resolved |
264 | | //!< #fr_dict_t. |
265 | | char const *base_dir; //!< Directory structure beneath share. |
266 | | char const *proto; //!< The protocol dictionary name. |
267 | | } fr_dict_autoload_t; |
268 | | |
269 | | /** Errors returned by attribute lookup functions |
270 | | * |
271 | | */ |
272 | | typedef enum { |
273 | | FR_DICT_ATTR_OK = 0, //!< No error. |
274 | | FR_DICT_ATTR_NOTFOUND = -1, //!< Attribute couldn't be found. |
275 | | FR_DICT_ATTR_PROTOCOL_NOTFOUND = -2, //!< Protocol couldn't be found. |
276 | | FR_DICT_ATTR_PARSE_ERROR = -3, //!< Attribute string couldn't be parsed |
277 | | FR_DICT_ATTR_INTERNAL_ERROR = -4, //!< Internal error occurred. |
278 | | FR_DICT_ATTR_OOM = -5, //!< Memory allocation error. |
279 | | FR_DICT_ATTR_NOT_DESCENDENT = -6, //!< Attribute is not a descendent of the parent |
280 | | ///< attribute. |
281 | | FR_DICT_ATTR_NOT_ANCESTOR = -7, //!< Attribute is not an ancestor of the child |
282 | | ///< attribute. |
283 | | FR_DICT_ATTR_NO_CHILDREN = -8, //!< Child lookup in attribute with no children. |
284 | | FR_DICT_ATTR_EINVAL = -9 //!< Invalid arguments. |
285 | | |
286 | | } fr_dict_attr_err_t; |
287 | | |
288 | | typedef bool (*fr_dict_attr_valid_func_t)(fr_dict_t *dict, fr_dict_attr_t const *parent, |
289 | | char const *name, int attr, fr_type_t type, fr_dict_attr_flags_t *flags); |
290 | | |
291 | | /* |
292 | | * Forward declarations to avoid circular references. |
293 | | */ |
294 | | typedef struct pair_list_s fr_pair_list_t; |
295 | | typedef struct fr_dbuff_s fr_dbuff_t; |
296 | | |
297 | | /** A generic interface for decoding packets to fr_pair_ts |
298 | | * |
299 | | * A decoding function should decode a single top level packet from wire format. |
300 | | * |
301 | | * Note that unlike #fr_tp_proto_decode_t, this function is NOT passed an encode_ctx. That is because when we |
302 | | * do cross-protocol encoding, the "outer" protocol has no information it can share with the "inner" protocol. |
303 | | * |
304 | | * @param[in] ctx to allocate new pairs in. |
305 | | * @param[in] vps where new VPs will be added |
306 | | * @param[in] data to decode. |
307 | | * @param[in] data_len The length of the incoming data. |
308 | | * @return |
309 | | * - <= 0 on error. May be the offset (as a negative value) where the error occurred. |
310 | | * - > 0 on success. How many bytes were decoded. |
311 | | */ |
312 | | typedef ssize_t (*fr_dict_attr_decode_func_t)(TALLOC_CTX *ctx, fr_pair_list_t *vps, |
313 | | uint8_t const *data, size_t data_len); |
314 | | |
315 | | /** A generic interface for encoding fr_pair_ts to packets |
316 | | * |
317 | | * An encoding function should encode multiple VPs to a wire format packet |
318 | | * |
319 | | * Note that unlike #fr_tp_proto_encode_t, this function is NOT passed an encode_ctx. That is because when we |
320 | | * do cross-protocol encoding, the "outer" protocol has no information it can share with the "inner" protocol. |
321 | | * |
322 | | * @param[in] vps vps to encode |
323 | | * @param[in] dbuff buffer where data can be written |
324 | | * @return |
325 | | * - <= 0 on error. May be the offset (as a negative value) where the error occurred. |
326 | | * - > 0 on success. How many bytes were encoded |
327 | | */ |
328 | | typedef ssize_t(*fr_dict_attr_encode_func_t)(fr_dbuff_t *dbuff, fr_pair_list_t const *vps); |
329 | | |
330 | | /** Init / free callbacks |
331 | | * |
332 | | * Only for "autoref" usage. |
333 | | */ |
334 | | typedef int (*fr_dict_protocol_init_t)(void); |
335 | | typedef void (*fr_dict_protocol_free_t)(void); |
336 | | |
337 | | |
338 | | /** Protocol-specific callbacks in libfreeradius-PROTOCOL |
339 | | * |
340 | | */ |
341 | | typedef struct { |
342 | | char const *name; //!< name of this protocol |
343 | | int default_type_size; //!< how many octets are in "type" field |
344 | | int default_type_length; //!< how many octets are in "length" field |
345 | | fr_table_num_ordered_t const *subtype_table; //!< for "encrypt=1", etc. |
346 | | size_t subtype_table_len; //!< length of subtype_table |
347 | | fr_dict_attr_valid_func_t attr_valid; //!< validation function for new attributes |
348 | | |
349 | | fr_dict_protocol_init_t init; //!< initialize the library |
350 | | fr_dict_protocol_free_t free; //!< free the library |
351 | | |
352 | | fr_dict_attr_decode_func_t decode; //!< for decoding attributes |
353 | | fr_dict_attr_encode_func_t encode; //!< for encoding attributes |
354 | | } fr_dict_protocol_t; |
355 | | |
356 | | typedef struct fr_dict_gctx_s fr_dict_gctx_t; |
357 | | |
358 | | /* |
359 | | * Dictionary constants |
360 | | */ |
361 | | #define FR_DICT_PROTO_MAX_NAME_LEN (128) //!< Maximum length of a protocol name. |
362 | 37.3k | #define FR_DICT_ENUM_MAX_NAME_LEN (128) //!< Maximum length of a enum value. |
363 | 751 | #define FR_DICT_VENDOR_MAX_NAME_LEN (128) //!< Maximum length of a vendor name. |
364 | 245k | #define FR_DICT_ATTR_MAX_NAME_LEN (128) //!< Maximum length of a attribute name. |
365 | | |
366 | | /** Maximum level of TLV nesting allowed |
367 | | */ |
368 | 13.1M | #define FR_DICT_TLV_NEST_MAX (24) |
369 | | |
370 | | /** Maximum level of da stack caching |
371 | | */ |
372 | 2.08M | #define FR_DICT_DA_STACK_CACHE_MAX (5) |
373 | | |
374 | | /** Maximum TLV stack size |
375 | | * |
376 | | * The additional attributes are to account for |
377 | | * |
378 | | * Root + Vendor + NULL (top frame). |
379 | | * Root + Embedded protocol + Root + Vendor + NULL. |
380 | | * |
381 | | * Code should ensure that it doesn't run off the end of the stack, |
382 | | * as this could be remotely exploitable, using odd nesting. |
383 | | */ |
384 | 13.1M | #define FR_DICT_MAX_TLV_STACK (FR_DICT_TLV_NEST_MAX + 5) |
385 | | |
386 | | /** Characters that are allowed in dictionary attribute names |
387 | | * |
388 | | */ |
389 | | extern bool const fr_dict_attr_allowed_chars[UINT8_MAX + 1]; |
390 | | |
391 | | /** Characters that are allowed in dictionary enumeration value names |
392 | | * |
393 | | */ |
394 | | extern bool const fr_dict_enum_allowed_chars[UINT8_MAX + 1]; |
395 | | |
396 | | /** @name Dictionary structure extensions |
397 | | * |
398 | | * @{ |
399 | | */ |
400 | | #include <freeradius-devel/util/dict_ext.h> |
401 | | /** @} */ |
402 | | |
403 | | /** @name Programmatically create dictionary attributes and values |
404 | | * |
405 | | * @{ |
406 | | */ |
407 | | int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, int attr, |
408 | | fr_type_t type, fr_dict_attr_flags_t const *flags) CC_HINT(nonnull(1,2,3)); |
409 | | |
410 | | int fr_dict_enum_add_name(fr_dict_attr_t *da, char const *name, |
411 | | fr_value_box_t const *value, bool coerce, bool replace); |
412 | | |
413 | | int fr_dict_enum_add_name_next(fr_dict_attr_t *da, char const *name) CC_HINT(nonnull); |
414 | | |
415 | | int fr_dict_str_to_argv(char *str, char **argv, int max_argc); |
416 | | /** @} */ |
417 | | |
418 | | /** @name Unknown ephemeral attributes |
419 | | * |
420 | | * @{ |
421 | | */ |
422 | | fr_dict_attr_t const *fr_dict_unknown_add(fr_dict_t *dict, fr_dict_attr_t const *old) CC_HINT(nonnull); |
423 | | |
424 | | void fr_dict_unknown_free(fr_dict_attr_t const **da); |
425 | | |
426 | | fr_dict_attr_t *fr_dict_unknown_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da); |
427 | | |
428 | | static inline fr_dict_attr_t *fr_dict_unknown_copy(TALLOC_CTX *ctx, fr_dict_attr_t const *da) |
429 | 503k | { |
430 | 503k | fr_assert(da->flags.is_unknown); |
431 | | |
432 | 503k | return fr_dict_unknown_afrom_da(ctx, da); |
433 | 503k | } Unexecuted instantiation: fuzzer_tacacs.c:fr_dict_unknown_copy Unexecuted instantiation: fuzzer_vmps.c:fr_dict_unknown_copy Unexecuted instantiation: fuzzer_tftp.c:fr_dict_unknown_copy Unexecuted instantiation: fuzzer_dns.c:fr_dict_unknown_copy Unexecuted instantiation: fuzzer_dhcpv6.c:fr_dict_unknown_copy Unexecuted instantiation: fuzzer_radius.c:fr_dict_unknown_copy Unexecuted instantiation: fuzzer_util.c:fr_dict_unknown_copy Unexecuted instantiation: fuzzer_dhcpv4.c:fr_dict_unknown_copy Unexecuted instantiation: fuzzer_bfd.c:fr_dict_unknown_copy Unexecuted instantiation: base32.c:fr_dict_unknown_copy Unexecuted instantiation: base64.c:fr_dict_unknown_copy Unexecuted instantiation: calc.c:fr_dict_unknown_copy Unexecuted instantiation: decode.c:fr_dict_unknown_copy Unexecuted instantiation: dict_ext.c:fr_dict_unknown_copy Unexecuted instantiation: dict_fixup.c:fr_dict_unknown_copy Unexecuted instantiation: dict_print.c:fr_dict_unknown_copy Unexecuted instantiation: dict_test.c:fr_dict_unknown_copy Unexecuted instantiation: dict_tokenize.c:fr_dict_unknown_copy dict_unknown.c:fr_dict_unknown_copy Line | Count | Source | 429 | 35.6k | { | 430 | 35.6k | fr_assert(da->flags.is_unknown); | 431 | | | 432 | 35.6k | return fr_dict_unknown_afrom_da(ctx, da); | 433 | 35.6k | } |
Unexecuted instantiation: dict_util.c:fr_dict_unknown_copy Unexecuted instantiation: dict_validate.c:fr_dict_unknown_copy Unexecuted instantiation: dl.c:fr_dict_unknown_copy Unexecuted instantiation: dns.c:fr_dict_unknown_copy Unexecuted instantiation: edit.c:fr_dict_unknown_copy Unexecuted instantiation: encode.c:fr_dict_unknown_copy Unexecuted instantiation: file.c:fr_dict_unknown_copy Unexecuted instantiation: inet.c:fr_dict_unknown_copy Unexecuted instantiation: log.c:fr_dict_unknown_copy Unexecuted instantiation: packet.c:fr_dict_unknown_copy pair.c:fr_dict_unknown_copy Line | Count | Source | 429 | 467k | { | 430 | 467k | fr_assert(da->flags.is_unknown); | 431 | | | 432 | 467k | return fr_dict_unknown_afrom_da(ctx, da); | 433 | 467k | } |
Unexecuted instantiation: pair_inline.c:fr_dict_unknown_copy Unexecuted instantiation: pair_legacy.c:fr_dict_unknown_copy Unexecuted instantiation: pair_print.c:fr_dict_unknown_copy Unexecuted instantiation: pair_tokenize.c:fr_dict_unknown_copy Unexecuted instantiation: print.c:fr_dict_unknown_copy Unexecuted instantiation: proto.c:fr_dict_unknown_copy Unexecuted instantiation: regex.c:fr_dict_unknown_copy Unexecuted instantiation: socket.c:fr_dict_unknown_copy Unexecuted instantiation: stats.c:fr_dict_unknown_copy Unexecuted instantiation: struct.c:fr_dict_unknown_copy Unexecuted instantiation: trie.c:fr_dict_unknown_copy Unexecuted instantiation: types.c:fr_dict_unknown_copy Unexecuted instantiation: uri.c:fr_dict_unknown_copy Unexecuted instantiation: value.c:fr_dict_unknown_copy Unexecuted instantiation: fuzzer.c:fr_dict_unknown_copy Unexecuted instantiation: base.c:fr_dict_unknown_copy Unexecuted instantiation: vmps.c:fr_dict_unknown_copy Unexecuted instantiation: list.c:fr_dict_unknown_copy Unexecuted instantiation: tcp.c:fr_dict_unknown_copy Unexecuted instantiation: abinary.c:fr_dict_unknown_copy Unexecuted instantiation: raw.c:fr_dict_unknown_copy Unexecuted instantiation: udp.c:fr_dict_unknown_copy |
434 | | |
435 | | fr_dict_attr_t *fr_dict_unknown_vendor_afrom_num(TALLOC_CTX *ctx, |
436 | | fr_dict_attr_t const *parent, unsigned int vendor) |
437 | | CC_HINT(nonnull(2)); |
438 | | |
439 | | fr_dict_attr_t *fr_dict_unknown_tlv_afrom_num(TALLOC_CTX *ctx, |
440 | | fr_dict_attr_t const *parent, unsigned int num) |
441 | | CC_HINT(nonnull(2)); |
442 | | |
443 | | fr_dict_attr_t *fr_dict_unknown_attr_afrom_num(TALLOC_CTX *ctx, |
444 | | fr_dict_attr_t const *parent, unsigned int num) |
445 | | CC_HINT(nonnull(2)); |
446 | | |
447 | | fr_dict_attr_t *fr_dict_unknown_attr_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da) |
448 | | CC_HINT(nonnull(2)); |
449 | | |
450 | | |
451 | | fr_slen_t fr_dict_unknown_afrom_oid_substr(TALLOC_CTX *ctx, |
452 | | fr_dict_attr_t const **out, |
453 | | fr_dict_attr_t const *parent, |
454 | | fr_sbuff_t *in) |
455 | | CC_HINT(nonnull(2,3,4)); |
456 | | |
457 | | int fr_dict_attr_unknown_parent_to_known(fr_dict_attr_t *da, fr_dict_attr_t const *parent); |
458 | | |
459 | | fr_dict_attr_t const *fr_dict_attr_unknown_resolve(fr_dict_t const *dict, fr_dict_attr_t const *da); |
460 | | /** @} */ |
461 | | |
462 | | /** @name Attribute comparisons |
463 | | * |
464 | | * @{ |
465 | | */ |
466 | | static inline CC_HINT(nonnull) int8_t fr_dict_attr_cmp(fr_dict_attr_t const *a, fr_dict_attr_t const *b) |
467 | 0 | { |
468 | 0 | int8_t ret; |
469 | 0 |
|
470 | 0 | /* |
471 | 0 | * Comparing unknowns or raws is expensive |
472 | 0 | * because we need to check the lineage. |
473 | 0 | */ |
474 | 0 | if (a->flags.is_unknown | a->flags.is_raw | b->flags.is_unknown | b->flags.is_raw) { |
475 | 0 | ret = CMP(a->depth, b->depth); |
476 | 0 | if (ret != 0) return ret; |
477 | 0 |
|
478 | 0 | ret = CMP(a->attr, b->attr); |
479 | 0 | if (ret != 0) return ret; |
480 | 0 |
|
481 | 0 | ret = (a->parent == NULL) - (b->parent == NULL); |
482 | 0 | if ((ret != 0) || !a->parent) return ret; |
483 | 0 |
|
484 | 0 | return fr_dict_attr_cmp(a->parent, b->parent); |
485 | 0 | } |
486 | 0 |
|
487 | 0 | /* |
488 | 0 | * Comparing knowns is cheap because the |
489 | 0 | * DAs are unique. |
490 | 0 | */ |
491 | 0 | return CMP(a, b); |
492 | 0 | } Unexecuted instantiation: fuzzer_tacacs.c:fr_dict_attr_cmp Unexecuted instantiation: fuzzer_vmps.c:fr_dict_attr_cmp Unexecuted instantiation: fuzzer_tftp.c:fr_dict_attr_cmp Unexecuted instantiation: fuzzer_dns.c:fr_dict_attr_cmp Unexecuted instantiation: fuzzer_dhcpv6.c:fr_dict_attr_cmp Unexecuted instantiation: fuzzer_radius.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_bfd.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: 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: 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: vmps.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: raw.c:fr_dict_attr_cmp Unexecuted instantiation: udp.c:fr_dict_attr_cmp |
493 | | /** @} */ |
494 | | |
495 | | /** @name Debugging functions |
496 | | * |
497 | | * @{ |
498 | | */ |
499 | | void fr_dict_namespace_debug(fr_dict_attr_t const *da); |
500 | | |
501 | | void fr_dict_attr_debug(fr_dict_attr_t const *da); |
502 | | |
503 | | void fr_dict_debug(fr_dict_t const *dict); |
504 | | |
505 | | void fr_dict_export(fr_dict_t const *dict); |
506 | | /** @} */ |
507 | | |
508 | | /** @name Attribute lineage |
509 | | * |
510 | | * @{ |
511 | | */ |
512 | | 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); |
513 | | |
514 | | int fr_dict_oid_component_legacy(unsigned int *out, char const **oid); |
515 | | |
516 | | fr_slen_t fr_dict_attr_flags_print(fr_sbuff_t *out, fr_dict_t const *dict, |
517 | | fr_type_t type, fr_dict_attr_flags_t const *flags); |
518 | | |
519 | | fr_slen_t fr_dict_attr_oid_print(fr_sbuff_t *out, |
520 | | fr_dict_attr_t const *ancestor, fr_dict_attr_t const *da, bool numeric); |
521 | 0 | #define FR_DICT_ATTR_OID_PRINT_RETURN(...) FR_SBUFF_RETURN(fr_dict_attr_oid_print, ##__VA_ARGS__) |
522 | | |
523 | | fr_slen_t fr_dict_attr_by_oid_legacy(fr_dict_t const *dict, fr_dict_attr_t const **parent, |
524 | | unsigned int *attr, char const *oid) CC_HINT(nonnull); |
525 | | |
526 | | fr_slen_t fr_dict_oid_component(fr_dict_attr_err_t *err, |
527 | | fr_dict_attr_t const **out, fr_dict_attr_t const *parent, |
528 | | fr_sbuff_t *in, fr_sbuff_term_t const *tt) |
529 | | CC_HINT(nonnull(2,3,4)); |
530 | | |
531 | | fr_slen_t fr_dict_attr_by_oid_substr(fr_dict_attr_err_t *err, |
532 | | fr_dict_attr_t const **out, fr_dict_attr_t const *parent, |
533 | | fr_sbuff_t *in, fr_sbuff_term_t const *tt) |
534 | | CC_HINT(nonnull(2,3,4)); |
535 | | |
536 | | fr_dict_attr_t const *fr_dict_attr_by_oid(fr_dict_attr_err_t *err, |
537 | | fr_dict_attr_t const *parent, char const *oid) |
538 | | CC_HINT(nonnull(2,3)); |
539 | | |
540 | | bool fr_dict_attr_can_contain(fr_dict_attr_t const *parent, fr_dict_attr_t const *child) CC_HINT(nonnull); |
541 | | |
542 | | /** @} */ |
543 | | |
544 | | /** @name Attribute, vendor and dictionary lookup |
545 | | * |
546 | | * @{ |
547 | | */ |
548 | | |
549 | | /** @hidecallergraph */ |
550 | | fr_dict_attr_t const *fr_dict_root(fr_dict_t const *dict) CC_HINT(nonnull); |
551 | | |
552 | | bool fr_dict_is_read_only(fr_dict_t const *dict); |
553 | | |
554 | | dl_t *fr_dict_dl(fr_dict_t const *dict); |
555 | | |
556 | | fr_slen_t fr_dict_by_protocol_substr(fr_dict_attr_err_t *err, |
557 | | fr_dict_t const **out, fr_sbuff_t *name, fr_dict_t const *dict_def); |
558 | | |
559 | | fr_dict_t const *fr_dict_by_protocol_name(char const *name); |
560 | | |
561 | | fr_dict_t const *fr_dict_by_protocol_num(unsigned int num); |
562 | | |
563 | | fr_dict_protocol_t const *fr_dict_protocol(fr_dict_t const *dict); |
564 | | |
565 | | fr_dict_t const *fr_dict_by_da(fr_dict_attr_t const *da) CC_HINT(nonnull); |
566 | | |
567 | | fr_dict_t const *fr_dict_by_attr_name(fr_dict_attr_t const **found, char const *name); |
568 | | |
569 | | bool fr_dict_compatible(fr_dict_t const *dict1, fr_dict_t const *dict2) CC_HINT(nonnull); |
570 | | |
571 | | /** Return true if this attribute is parented directly off the dictionary root |
572 | | * |
573 | | * @param[in] da to check. |
574 | | * @return |
575 | | * - true if attribute is top level. |
576 | | * - false if attribute is not top level. |
577 | | */ |
578 | | static inline bool fr_dict_attr_is_top_level(fr_dict_attr_t const *da) |
579 | 0 | { |
580 | 0 | if (unlikely(!da) || unlikely(!da->parent)) return false; |
581 | 0 | return da->parent->flags.is_root; |
582 | 0 | } Unexecuted instantiation: fuzzer_tacacs.c:fr_dict_attr_is_top_level Unexecuted instantiation: fuzzer_vmps.c:fr_dict_attr_is_top_level Unexecuted instantiation: fuzzer_tftp.c:fr_dict_attr_is_top_level Unexecuted instantiation: fuzzer_dns.c:fr_dict_attr_is_top_level Unexecuted instantiation: fuzzer_dhcpv6.c:fr_dict_attr_is_top_level Unexecuted instantiation: fuzzer_radius.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_bfd.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: 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: 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: vmps.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: raw.c:fr_dict_attr_is_top_level Unexecuted instantiation: udp.c:fr_dict_attr_is_top_level |
583 | | |
584 | | fr_dict_vendor_t const *fr_dict_vendor_by_da(fr_dict_attr_t const *da); |
585 | | |
586 | | fr_dict_vendor_t const *fr_dict_vendor_by_name(fr_dict_t const *dict, char const *name); |
587 | | |
588 | | fr_dict_vendor_t const *fr_dict_vendor_by_num(fr_dict_t const *dict, uint32_t vendor_pen); |
589 | | |
590 | | fr_dict_attr_t const *fr_dict_vendor_da_by_num(fr_dict_attr_t const *vendor_root, uint32_t vendor_pen); |
591 | | |
592 | | fr_slen_t fr_dict_attr_search_by_qualified_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, |
593 | | fr_dict_t const *dict_def, |
594 | | fr_sbuff_t *name, fr_sbuff_term_t const *tt, |
595 | | bool internal, bool foreign) |
596 | | CC_HINT(nonnull(2, 4)); |
597 | | |
598 | | fr_slen_t fr_dict_attr_search_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, |
599 | | fr_dict_t const *dict_def, |
600 | | fr_sbuff_t *name, fr_sbuff_term_t const *tt, |
601 | | bool internal, bool foreign) |
602 | | CC_HINT(nonnull(2, 4)); |
603 | | |
604 | | fr_slen_t fr_dict_attr_search_by_qualified_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, |
605 | | fr_dict_t const *dict_def, |
606 | | fr_sbuff_t *in, fr_sbuff_term_t const *tt, |
607 | | bool internal, bool foreign) |
608 | | CC_HINT(nonnull(2, 4)); |
609 | | |
610 | | fr_dict_attr_t const *fr_dict_attr_search_by_qualified_oid(fr_dict_attr_err_t *err, |
611 | | fr_dict_t const *dict_def, char const *attr, |
612 | | bool internal, bool foreign) |
613 | | CC_HINT(nonnull(3)); |
614 | | |
615 | | fr_slen_t fr_dict_attr_search_by_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, |
616 | | fr_dict_t const *dict_def, |
617 | | fr_sbuff_t *in, fr_sbuff_term_t const *tt, |
618 | | bool internal, bool foreign) |
619 | | CC_HINT(nonnull(2, 4)); |
620 | | |
621 | | fr_slen_t fr_dict_attr_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, |
622 | | fr_dict_attr_t const *parent, |
623 | | fr_sbuff_t *name, fr_sbuff_term_t const *tt) |
624 | | CC_HINT(nonnull(2,3,4)); |
625 | | |
626 | | fr_dict_attr_t const *fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, |
627 | | char const *attr) |
628 | | CC_HINT(nonnull(2,3)); |
629 | | |
630 | | fr_dict_attr_t const *fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr); |
631 | | |
632 | | fr_dict_enum_value_t *fr_dict_enum_by_value(fr_dict_attr_t const *da, fr_value_box_t const *value); |
633 | | |
634 | | char const *fr_dict_enum_name_by_value(fr_dict_attr_t const *da, fr_value_box_t const *value); |
635 | | |
636 | | fr_dict_enum_value_t *fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len); |
637 | | |
638 | | 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); |
639 | | |
640 | | fr_slen_t fr_dict_enum_name_from_substr(fr_sbuff_t *out, fr_sbuff_parse_error_t *err, |
641 | | fr_sbuff_t *in, fr_sbuff_term_t const *tt); |
642 | | |
643 | | static inline fr_slen_t fr_dict_enum_name_afrom_substr(TALLOC_CTX *ctx, char **out, fr_sbuff_parse_error_t *err, |
644 | | fr_sbuff_t *in, fr_sbuff_term_t const *tt) |
645 | | SBUFF_OUT_TALLOC_FUNC_NO_LEN_DEF(fr_dict_enum_name_from_substr, err, in, tt) |
646 | | /** @} */ |
647 | | |
648 | | /** @name Dictionary and protocol loading |
649 | | * |
650 | | * @{ |
651 | | */ |
652 | | int fr_dict_internal_afrom_file(fr_dict_t **out, char const *internal_name, |
653 | | char const *dependent); |
654 | | |
655 | | int fr_dict_protocol_afrom_file(fr_dict_t **out, char const *proto_name, char const *proto_dir, |
656 | | char const *dependent); |
657 | | |
658 | | fr_dict_t *fr_dict_protocol_alloc(fr_dict_t const *parent); |
659 | | |
660 | | int fr_dict_read(fr_dict_t *dict, char const *dict_dir, char const *filename); |
661 | | /** @} */ |
662 | | |
663 | | /** @name Autoloader interface |
664 | | * |
665 | | * @{ |
666 | | */ |
667 | | int fr_dict_enum_autoload(fr_dict_enum_autoload_t const *to_load); |
668 | | |
669 | | int fr_dict_attr_autoload(fr_dict_attr_autoload_t const *to_load); |
670 | | |
671 | 5.48k | #define fr_dict_autoload(_to_load) _fr_dict_autoload(_to_load, __FILE__) |
672 | | int _fr_dict_autoload(fr_dict_autoload_t const *to_load, char const *dependent); |
673 | | |
674 | 5.48k | #define fr_dict_autofree(_to_free) _fr_dict_autofree(_to_free, __FILE__) |
675 | | int _fr_dict_autofree(fr_dict_autoload_t const *to_free, char const *dependent); |
676 | | |
677 | | #define fr_dict_autoload_talloc(_ctx, _dict_out, _proto) _fr_dict_autoload_talloc(_ctx, _dict_out, _proto, __FILE__) |
678 | | fr_dict_autoload_talloc_t *_fr_dict_autoload_talloc(TALLOC_CTX *ctx, fr_dict_t const **out, char const *proto, char const *dependent); |
679 | | |
680 | | int fr_dl_dict_enum_autoload(dl_t const *module, void *symbol, void *user_ctx); |
681 | | |
682 | | int fr_dl_dict_attr_autoload(dl_t const *module, void *symbol, void *user_ctx); |
683 | | |
684 | | int fr_dl_dict_autoload(dl_t const *module, void *symbol, void *user_ctx); |
685 | | |
686 | | void fr_dl_dict_autofree(dl_t const *module, void *symbol, void *user_ctx); |
687 | | /** @} */ |
688 | | |
689 | | /** @name Allocating and freeing |
690 | | * |
691 | | * @{ |
692 | | */ |
693 | | fr_dict_t *fr_dict_alloc(char const *proto_name, unsigned int proto_number) CC_HINT(nonnull); |
694 | | |
695 | | int fr_dict_dependent_add(fr_dict_t const *dict, char const *dependent) CC_HINT(nonnull); |
696 | | |
697 | | int fr_dict_free(fr_dict_t **dict, char const *dependent) CC_HINT(nonnull); |
698 | | |
699 | | int fr_dict_const_free(fr_dict_t const **dict, char const *dependent) CC_HINT(nonnull); |
700 | | /** @} */ |
701 | | |
702 | | /** @name Global dictionary management |
703 | | * |
704 | | * @{ |
705 | | */ |
706 | | fr_dict_gctx_t *fr_dict_global_ctx_init(TALLOC_CTX *ctx, bool free_at_exit, char const *dict_dir); |
707 | | |
708 | | void fr_dict_global_ctx_perm_check(fr_dict_gctx_t *gctx, bool enable); |
709 | | |
710 | | void fr_dict_global_ctx_set(fr_dict_gctx_t const *gctx); |
711 | | |
712 | | int fr_dict_global_ctx_free(fr_dict_gctx_t const *gctx); |
713 | | |
714 | | int fr_dict_global_ctx_dir_set(char const *dict_dir); |
715 | | |
716 | | void fr_dict_global_ctx_read_only(void); |
717 | | |
718 | | void fr_dict_global_ctx_debug(fr_dict_gctx_t const *gctx); |
719 | | |
720 | | char const *fr_dict_global_ctx_dir(void); |
721 | | |
722 | | typedef struct fr_hash_iter_s fr_dict_global_ctx_iter_t; |
723 | | |
724 | | fr_dict_t *fr_dict_global_ctx_iter_init(fr_dict_global_ctx_iter_t *iter) CC_HINT(nonnull); |
725 | | |
726 | | fr_dict_t *fr_dict_global_ctx_iter_next(fr_dict_global_ctx_iter_t *iter) CC_HINT(nonnull); |
727 | | |
728 | | fr_dict_t *fr_dict_unconst(fr_dict_t const *dict); |
729 | | |
730 | | fr_dict_attr_t *fr_dict_attr_unconst(fr_dict_attr_t const *da); |
731 | | |
732 | | fr_dict_t const *fr_dict_internal(void); |
733 | | |
734 | | /** @} */ |
735 | | |
736 | | /** @name Dictionary testing and validation |
737 | | * |
738 | | * @{ |
739 | | */ |
740 | | int fr_dict_parse_str(fr_dict_t *dict, char *buf, |
741 | | fr_dict_attr_t const *parent); |
742 | | |
743 | | ssize_t fr_dict_valid_name(char const *name, ssize_t len); |
744 | | |
745 | | ssize_t fr_dict_valid_oid_str(char const *name, ssize_t len); |
746 | | |
747 | | fr_dict_attr_t const *fr_dict_attr_iterate_children(fr_dict_attr_t const *parent, fr_dict_attr_t const **prev); |
748 | | |
749 | | typedef int (*fr_dict_walk_t)(fr_dict_attr_t const *da, void *uctx); |
750 | | |
751 | | int fr_dict_walk(fr_dict_attr_t const *da, fr_dict_walk_t callback, void *uctx); |
752 | | |
753 | | void fr_dict_attr_verify(char const *file, int line, fr_dict_attr_t const *da); |
754 | | /** @} */ |
755 | | |
756 | | #undef _CONST |
757 | | |
758 | | #ifdef __cplusplus |
759 | | } |
760 | | #endif |