The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
dict_ext.h
Go to the documentation of this file.
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_ext.h
21  *
22  * @copyright 2020 The FreeRADIUS server project
23  * @copyright 2020 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
24  */
25 RCSIDH(dict_ext_h, "$Id: 7ab2e4e7e3bc8020de1e9603b7d265d563b639cf $")
26 
27 #include <freeradius-devel/util/dict.h>
28 #include <freeradius-devel/util/ext.h>
29 #include <freeradius-devel/util/hash.h>
30 
31 #include <limits.h>
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 extern fr_ext_t const fr_dict_attr_ext_def;
38 extern fr_ext_t const fr_dict_enum_ext_def;
39 
40 /** Attribute extension - Holds children for an attribute
41  *
42  * Children are possible for:
43  *
44  * #FR_TYPE_TLV, #FR_TYPE_VENDOR, #FR_TYPE_VSA, #FR_TYPE_STRUCT
45  *
46  * *or* where the parent->parent->type is
47  * #FR_TYPE_STRUCT, and "parent" is a "key"
48  * field. Note that these attributes therefore
49  * cannot have VALUEs, as the child defines their
50  * VALUE. See dict_attr_can_have_children() for details.
51  */
52 typedef struct {
53  fr_hash_table_t *child_by_name; //!< Namespace at this level in the hierarchy.
54  fr_dict_attr_t const **children; //!< Children of this attribute.
56 
57 /** Attribute extension - Holds a reference to an attribute in another dictionary
58  *
59  */
60 typedef struct {
61  fr_dict_attr_t const *ref; //!< reference, only for #FR_TYPE_GROUP
63 
64 /** Attribute extension - Cached vendor pointer
65  *
66  */
67 typedef struct {
68  fr_dict_attr_t const *vendor; //!< ancestor which has type #FR_TYPE_VENDOR
70 
71 /** Attribute extension - Stack of dictionary attributes that describe the path back to the root of the dictionary
72  *
73  */
74 typedef struct {
75  bool unused; //!< Zero length arrays are apparently GNU extensions
76  ///< and we're not allowed to have structs with a
77  ///< single variable array as its member.
78  ///< We'll likely want to store something else here
79  ///< at some point, so we just have a dummy field to
80  ///< avoid changing all the code.
81  fr_dict_attr_t const *da_stack[]; //!< Stack of dictionary attributes
83 
84 /** Attribute extension - Holds enumeration values
85  *
86  */
87 typedef struct {
88  size_t max_name_len; //!< maximum length of a name
89  fr_hash_table_t *value_by_name; //!< Lookup an enumeration value by name
90  fr_hash_table_t *name_by_value; //!< Lookup a name by value
92 
93 /** Attribute extension - Holds a hash table with the names of all children of this attribute
94  *
95  */
96 typedef struct {
97  fr_hash_table_t *namespace; //!< Lookup a child by name
99 
100 /** Enum extension - Sub-struct or union pointer
101  *
102  */
103 typedef struct {
104  fr_dict_attr_t const *union_ref; //!< The union da this value points into.
106 
107 /** @name Add extension structures to attributes
108  *
109  * @{
110  */
111 
112 /* Retrieve an extension structure for a dictionary attribute
113  *
114  * @param[in] da to retrieve structure from.
115  * @param[in] ext to retrieve.
116  * @return
117  * - NULL if the extension wasn't found.
118  * - A pointer to the start of the extension.
119  */
120 static inline void *fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
121 {
122  if (!da->ext[ext]) return NULL;
123 
124  return fr_ext_ptr(da, da->ext[ext], fr_dict_attr_ext_def.info[ext].has_hdr);
125 }
126 
127 /** Return whether a da has a given extension or not
128  *
129  * @param[in] da to check for extensions.
130  * @param[in] ext to check.
131  * @return
132  * - true if the da has the specified extension.
133  * - false if the da does not have the specified extension
134  */
135 static inline bool fr_dict_attr_has_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
136 {
137  return (da->ext[ext] > 0);
138 }
139 
140 /** Return the cached da stack (if any) associated with an attribute
141  *
142  * @param[in] da to return cached da stack for.
143  * @return
144  * - NULL if no da stack available.
145  * - The cached da stack on success.
146  */
147 static inline fr_dict_attr_t const **fr_dict_attr_da_stack(fr_dict_attr_t const *da)
148 {
150 
152  if (!ext) return NULL;
153 
154  return ext->da_stack;
155 }
156 
157 /** Return the reference associated with a group type attribute
158  *
159  * @param[in] da to return the reference for.
160  * @return
161  * - NULL if no reference available.
162  * - A pointer to the attribute being referenced.
163  */
164 static inline fr_dict_attr_t const *fr_dict_attr_ref(fr_dict_attr_t const *da)
165 {
167 
169  if (!ext) return NULL;
170 
171  return ext->ref;
172 }
173 
174 /** Return the vendor number for an attribute
175  *
176  * @param[in] da The dictionary attribute to find the
177  * vendor for.
178  * @return
179  * - 0 this isn't a vendor specific attribute.
180  * - The vendor PEN.
181  */
183 {
185 
186  if (da->type == FR_TYPE_VENDOR) return da->attr;
187 
189  if (!ext || !ext->vendor) return 0;
190 
191  return ext->vendor->attr;
192 }
193 
194 /** Return the vendor da for an attribute
195  *
196  * @param[in] da The dictionary attribute to find the
197  * vendor for.
198  * @return
199  * - 0 this isn't a vendor specific attribute.
200  * - The vendor PEN.
201  */
203 {
205 
206  if (da->type == FR_TYPE_VENDOR) return da;
207 
209  if (!ext) return NULL;
210 
211  return ext->vendor;
212 }
213 
214 /** @} */
215 
216 void fr_dict_attr_ext_debug(fr_dict_attr_t const *da);
217 
218 #ifdef __cplusplus
219 }
220 #endif
#define RCSIDH(h, id)
Definition: build.h:445
fr_dict_attr_ext_t
Extension identifier.
Definition: dict.h:159
@ FR_DICT_ATTR_EXT_DA_STACK
Cached da stack.
Definition: dict.h:165
@ FR_DICT_ATTR_EXT_REF
Attribute references another attribute and/or dictionary.
Definition: dict.h:162
@ FR_DICT_ATTR_EXT_VENDOR
Cached vendor pointer.
Definition: dict.h:164
static fr_dict_attr_t const * fr_dict_vendor_da_by_da(fr_dict_attr_t const *da)
Return the vendor da for an attribute.
Definition: dict_ext.h:202
fr_ext_t const fr_dict_attr_ext_def
Holds additional information about extension structures.
Definition: dict_ext.c:160
size_t max_name_len
maximum length of a name
Definition: dict_ext.h:88
fr_ext_t const fr_dict_enum_ext_def
Holds additional information about extension structures.
Definition: dict_ext.c:221
fr_dict_attr_t const * vendor
ancestor which has type FR_TYPE_VENDOR
Definition: dict_ext.h:68
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
Definition: dict_ext.h:120
static fr_dict_attr_t const ** fr_dict_attr_da_stack(fr_dict_attr_t const *da)
Return the cached da stack (if any) associated with an attribute.
Definition: dict_ext.h:147
fr_hash_table_t * name_by_value
Lookup a name by value.
Definition: dict_ext.h:90
fr_dict_attr_t const ** children
Children of this attribute.
Definition: dict_ext.h:54
static fr_dict_attr_t const * fr_dict_attr_ref(fr_dict_attr_t const *da)
Return the reference associated with a group type attribute.
Definition: dict_ext.h:164
fr_hash_table_t * value_by_name
Lookup an enumeration value by name.
Definition: dict_ext.h:89
void fr_dict_attr_ext_debug(fr_dict_attr_t const *da)
Definition: dict_ext.c:213
fr_dict_attr_t const * da_stack[]
Stack of dictionary attributes.
Definition: dict_ext.h:81
fr_hash_table_t * child_by_name
Namespace at this level in the hierarchy.
Definition: dict_ext.h:53
bool unused
Zero length arrays are apparently GNU extensions and we're not allowed to have structs with a single ...
Definition: dict_ext.h:75
static bool fr_dict_attr_has_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
Return whether a da has a given extension or not.
Definition: dict_ext.h:135
fr_dict_attr_t const * union_ref
The union da this value points into.
Definition: dict_ext.h:104
static uint32_t fr_dict_vendor_num_by_da(fr_dict_attr_t const *da)
Return the vendor number for an attribute.
Definition: dict_ext.h:182
fr_dict_attr_t const * ref
reference, only for FR_TYPE_GROUP
Definition: dict_ext.h:61
Attribute extension - Holds children for an attribute.
Definition: dict_ext.h:52
Attribute extension - Stack of dictionary attributes that describe the path back to the root of the d...
Definition: dict_ext.h:74
Attribute extension - Holds enumeration values.
Definition: dict_ext.h:87
Attribute extension - Holds a hash table with the names of all children of this attribute.
Definition: dict_ext.h:96
Attribute extension - Holds a reference to an attribute in another dictionary.
Definition: dict_ext.h:60
Attribute extension - Cached vendor pointer.
Definition: dict_ext.h:67
Enum extension - Sub-struct or union pointer.
Definition: dict_ext.h:103
static void * fr_ext_ptr(TALLOC_CTX const *chunk, size_t offset, bool has_hdr)
Return a pointer to an extension in a chunk.
Definition: ext.h:150
bool has_hdr
Additional metadata should be allocated before the extension data to record the exact length of the e...
Definition: ext.h:113
fr_ext_info_t const * info
Additional information about each extension.
Definition: ext.h:131
Structure to define a set of extensions.
Definition: ext.h:126
@ FR_TYPE_VENDOR
Attribute that represents a vendor in the attribute tree.
Definition: merged_model.c:122
unsigned int uint32_t
Definition: merged_model.c:33