The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
dict_ext_priv.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/** Extensions for dictionary definitions
19 *
20 * @file src/lib/util/dict_ext_priv.h
21 *
22 * @copyright 2020 The FreeRADIUS server project
23 * @copyright 2020 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
24 */
25RCSIDH(dict_ext_priv_h, "$Id: 254fb4c5cadacd24d1be9cb97a86c7ae9628f39e $")
26
27#include <freeradius-devel/util/dict.h>
28#include <freeradius-devel/util/dict_ext.h>
29#include <limits.h>
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35/** @name Add extension structures to attributes
36 *
37 * @{
38 */
39
40/** Allocate an attribute extension of a particular size
41 *
42 */
43static inline void *dict_attr_ext_alloc_size(fr_dict_attr_t **da_p, fr_dict_attr_ext_t ext, size_t ext_len)
44{
45 if (!(*da_p)->flags.is_unknown && unlikely((*da_p)->dict && fr_dict_is_read_only((*da_p)->dict))) {
46 fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root((*da_p)->dict)->name);
47 return NULL;
48 }
49
50 return fr_ext_alloc_size(&fr_dict_attr_ext_def, (void **)da_p, ext, ext_len);
51}
52
53/** Allocate an attribute extension
54 *
55 */
57{
58 if (!(*da_p)->flags.is_unknown && unlikely((*da_p)->dict && fr_dict_is_read_only((*da_p)->dict))) {
59 fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root((*da_p)->dict)->name);
60 return NULL;
61 }
62
63 return fr_ext_alloc_size(&fr_dict_attr_ext_def, (void **)da_p, ext, fr_dict_attr_ext_def.info[ext].min);
64}
65
66/** Return the length of an attribute extension
67 *
68 */
69static inline size_t dict_attr_ext_len(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
70{
71 return fr_ext_len(&fr_dict_attr_ext_def, (void const *)da, ext);
72}
73
74/** Copy a single attribute extension from one attribute to another
75 *
76 */
77static inline void *dict_attr_ext_copy(fr_dict_attr_t **da_out_p, fr_dict_attr_t const *da_in, fr_dict_attr_ext_t ext)
78{
79 if (unlikely((*da_out_p)->dict && fr_dict_is_read_only((*da_out_p)->dict) && !(*da_out_p)->flags.is_unknown)) {
80 fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root((*da_out_p)->dict)->name);
81 return NULL;
82 }
83
84 /*
85 * We might be able to copy things for unknown
86 * attributes. But if the unknown is of type 'octets',
87 * then we can only copy the protocol-specific things.
88 */
89#ifndef NDEBUG
90 if ((*da_out_p)->flags.is_unknown && ((*da_out_p)->type == FR_TYPE_OCTETS)) {
92 }
93#endif
94
95 return fr_ext_copy(&fr_dict_attr_ext_def, (void **)da_out_p, (void const *)da_in, ext);
96}
97
98/** Copy all attribute extensions from one attribute to another
99 *
100 */
101static inline int dict_attr_ext_copy_all(fr_dict_attr_t **da_out_p, fr_dict_attr_t const *da_in)
102{
103 if (unlikely((*da_out_p)->dict && fr_dict_is_read_only((*da_out_p)->dict))) {
104 fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root((*da_out_p)->dict)->name);
105 return -1;
106 }
107
108 return fr_ext_copy_all(&fr_dict_attr_ext_def, (void **)da_out_p, (void const *)da_in);
109}
110
111/** Print extension debug information for attributes
112 *
113 */
114static inline void dict_attr_ext_debug(char const *name, fr_dict_attr_t const *da)
115{
117}
118/** @} */
119
120/** @name Convenience functions for populating attribute extensions
121 *
122 * @{
123 */
124
125static inline int dict_attr_ref_null(fr_dict_attr_t const *da)
126{
128
130 if (unlikely(!ext)) {
131 fr_strerror_printf("Contains no 'ref' extension");
132 return -1;
133 }
134
135 if (unlikely((ext->type & FR_DICT_ATTR_REF_UNRESOLVED) != 0)) {
136 fr_strerror_printf("Contains an resolved 'ref' extension");
137 return -1;
138 }
139
140 ext->type = 0;
141 ext->ref = NULL;
142
143 return 0;
144}
145
147{
149
151 if (unlikely(!ext)) {
153 }
154
155 /*
156 * Check that the attribute ref is unresolved.
157 */
159 fr_strerror_printf("Reference type cannot be unresolved");
160 return -1;
161 }
162
163 ext->type = type;
164 ext->ref = ref;
165
166 return 0;
167}
168
170{
172
174 if (unlikely(!ext)) {
175 fr_strerror_printf("Attribute contains no 'ref' extension");
176 return -1;
177 }
178
179 /*
180 * Check that the attribute ref is unresolved.
181 */
183 fr_strerror_printf("Reference type cannot be unresolved");
184 return -1;
185 }
186
187 ext->type = type;
188 ext->ref = ref;
189
190 return 0;
191}
192
193static inline int dict_attr_ref_resolve(fr_dict_attr_t const *da, fr_dict_attr_t const *ref)
194{
196
198 if (unlikely(!ext)) {
199 fr_strerror_printf("Contains no 'ref' extension");
200 return -1;
201 }
202
203 /*
204 * Check that the attribute ref is unresolved.
205 */
206 if (unlikely(fr_dict_attr_ref_is_unresolved(ext->type) == false)) {
207 fr_strerror_printf("Contains an resolved 'ref' extension");
208 return -1;
209 }
210
212 talloc_free(ext->unresolved);
213 ext->ref = ref;
214
215 return 0;
216}
217
218static inline int dict_attr_ref_aunresolved(fr_dict_attr_t **da_p, char const *ref, fr_dict_attr_ref_type_t type)
219{
221 fr_dict_attr_t *da;
222
224 if (unlikely(!ext)) {
226 if (unlikely(!ext)) return -1;
227 }
228 da = *da_p;
229 if (unlikely(ext->type != 0)) {
230 fr_strerror_printf("Attribute already has a 'ref=...' defined");
231 return -1;
232 }
233 ext->type = type | FR_DICT_ATTR_REF_UNRESOLVED; /* Always unresolved */
234 ext->unresolved = talloc_typed_strdup(da, ref);
235
236 return 0;
237}
238
239static inline int dict_attr_children_set(fr_dict_attr_t const *da, fr_dict_attr_t const **children)
240{
242
244 if (unlikely(!ext)) {
245 fr_strerror_printf("Attribute contains no 'children' extension");
246 return -1;
247 }
248 ext->children = children;
249
250 return 0;
251}
252
253static inline fr_dict_attr_t const **dict_attr_children(fr_dict_attr_t const *da)
254{
256
258 if (unlikely(!ext)) {
259 fr_strerror_printf("Attribute contains no 'children' extension");
260 return NULL;
261 }
262 return ext->children;
263}
264
265/** Return the namespace hash table associated with the attribute
266 *
267 * @param[in] da to return the reference for.
268 * @return
269 * - NULL if no namespace available.
270 * - A pointer to the namespace hash table
271 */
273{
274 fr_dict_attr_t const *ref;
276
277 ref = fr_dict_attr_ref(da);
278 if (unlikely(ref != NULL)) return NULL;
279
281 if (!ext) return NULL;
282
283 return ext->namespace;
284}
285/** @} */
286
287#ifdef __cplusplus
288}
289#endif
#define RCSIDH(h, id)
Definition build.h:486
#define unlikely(_x)
Definition build.h:383
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2407
bool fr_dict_is_read_only(fr_dict_t const *dict)
Definition dict_util.c:2412
fr_dict_attr_ext_t
Extension identifier.
Definition dict.h:166
@ FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC
Protocol specific extensions.
Definition dict.h:175
@ FR_DICT_ATTR_EXT_NAMESPACE
Attribute has its own namespace.
Definition dict.h:174
@ FR_DICT_ATTR_EXT_REF
Attribute references another attribute and/or dictionary.
Definition dict.h:169
@ FR_DICT_ATTR_EXT_CHILDREN
Attribute has children.
Definition dict.h:168
fr_ext_t const fr_dict_attr_ext_def
Holds additional information about extension structures.
Definition dict_ext.c:213
fr_dict_attr_ref_type_t type
The state of the reference.
Definition dict_ext.h:77
fr_dict_attr_t const ** children
Children of this attribute.
Definition dict_ext.h:54
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
Definition dict_ext.h:140
#define fr_dict_attr_ref_is_unresolved(_type)
Definition dict_ext.h:70
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:184
fr_dict_attr_ref_type_t
Definition dict_ext.h:58
@ FR_DICT_ATTR_REF_UNRESOLVED
This flag is combined with the other states to indicate that the reference is unresolved.
Definition dict_ext.h:65
Attribute extension - Holds children for an attribute.
Definition dict_ext.h:52
Attribute extension - Holds a hash table with the names of all children of this attribute.
Definition dict_ext.h:116
Attribute extension - Holds a reference to an attribute in another dictionary.
Definition dict_ext.h:76
static int dict_attr_ref_set(fr_dict_attr_t const *da, fr_dict_attr_t const *ref, fr_dict_attr_ref_type_t type)
static int dict_attr_children_set(fr_dict_attr_t const *da, fr_dict_attr_t const **children)
static fr_hash_table_t * dict_attr_namespace(fr_dict_attr_t const *da)
Return the namespace hash table associated with the attribute.
static size_t dict_attr_ext_len(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
Return the length of an attribute extension.
static int dict_attr_ref_null(fr_dict_attr_t const *da)
static int dict_attr_ref_resolve(fr_dict_attr_t const *da, fr_dict_attr_t const *ref)
static int dict_attr_ref_aunresolved(fr_dict_attr_t **da_p, char const *ref, fr_dict_attr_ref_type_t type)
static int dict_attr_ext_copy_all(fr_dict_attr_t **da_out_p, fr_dict_attr_t const *da_in)
Copy all attribute extensions from one attribute to another.
static void * dict_attr_ext_copy(fr_dict_attr_t **da_out_p, fr_dict_attr_t const *da_in, fr_dict_attr_ext_t ext)
Copy a single attribute extension from one attribute to another.
static fr_dict_attr_t const ** dict_attr_children(fr_dict_attr_t const *da)
static void * dict_attr_ext_alloc_size(fr_dict_attr_t **da_p, fr_dict_attr_ext_t ext, size_t ext_len)
Allocate an attribute extension of a particular size.
static int dict_attr_ref_aset(fr_dict_attr_t **da_p, fr_dict_attr_t const *ref, fr_dict_attr_ref_type_t type)
static void * dict_attr_ext_alloc(fr_dict_attr_t **da_p, fr_dict_attr_ext_t ext)
Allocate an attribute extension.
static void dict_attr_ext_debug(char const *name, fr_dict_attr_t const *da)
Print extension debug information for attributes.
void * fr_ext_copy(fr_ext_t const *def, TALLOC_CTX **chunk_dst, TALLOC_CTX const *chunk_src, int ext)
Copy extension data from one attribute to another.
Definition ext.c:163
size_t fr_ext_len(fr_ext_t const *def, TALLOC_CTX const *chunk, int ext)
Return the length of an extension.
Definition ext.c:131
void fr_ext_debug(fr_ext_t const *def, char const *name, void const *chunk)
Print out all extensions and hexdump their contents.
Definition ext.c:339
int fr_ext_copy_all(fr_ext_t const *def, TALLOC_CTX **chunk_dst, TALLOC_CTX const *chunk_src)
Copy all the extensions from one attribute to another.
Definition ext.c:248
void * fr_ext_alloc_size(fr_ext_t const *def, void **chunk_p, int ext, size_t ext_len)
Add a variable length extension to a talloc chunk.
Definition ext.c:55
size_t min
Minimum size of extension.
Definition ext.h:112
fr_ext_info_t const * info
Additional information about each extension.
Definition ext.h:131
talloc_free(reap)
@ FR_TYPE_OCTETS
Raw octets.
#define fr_assert(_expr)
Definition rad_assert.h:38
static char const * name
fr_aka_sim_id_type_t type
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
Definition talloc.c:445
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition strerror.h:64