The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
dict_test.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /** Common functions for test files which need to programmatically create test dictionaries
18  *
19  * @file src/lib/util/dict_test.c
20  *
21  * @copyright 2021 The FreeRADIUS server project
22  */
23 
24 #include <freeradius-devel/util/dict.h>
25 #include <freeradius-devel/util/dict_priv.h>
26 #include "dict_test.h"
27 
29 
32 
35 
38 
44 
49 
54 
57 
59 
61 
63 
66 
69 
73 
75 
80 
82 
85 
87  /*
88  * Variable length
89  */
90  { .attr = FR_TEST_ATTR_STRING, .da = &fr_dict_attr_test_string, .name = "Test-String", .type = FR_TYPE_STRING },
91  { .attr = FR_TEST_ATTR_OCTETS, .da = &fr_dict_attr_test_octets, .name = "Test-Octets", .type = FR_TYPE_OCTETS },
92 
93  /*
94  * Networking
95  */
96  { .attr = FR_TEST_ATTR_IPV4_ADDR, .da = &fr_dict_attr_test_ipv4_addr, .name = "Test-IPv4-Addr", .type = FR_TYPE_IPV4_ADDR },
97  { .attr = FR_TEST_ATTR_IPV4_PREFIX, .da = &fr_dict_attr_test_ipv4_prefix, .name = "Test-IPv4-Prefix", .type = FR_TYPE_IPV4_PREFIX },
98 
99  { .attr = FR_TEST_ATTR_IPV6_ADDR, .da = &fr_dict_attr_test_ipv6_addr, .name = "Test-IPv6-Addr", .type = FR_TYPE_IPV6_ADDR },
100  { .attr = FR_TEST_ATTR_IPV6_PREFIX, .da = &fr_dict_attr_test_ipv6_prefix, .name = "Test-IPv6-Prefix", .type = FR_TYPE_IPV6_PREFIX },
101 
102  { .attr = FR_TEST_ATTR_IFID, .da = &fr_dict_attr_test_ifid, .name = "Test-IFID", .type = FR_TYPE_IFID },
103  { .attr = FR_TEST_ATTR_ETHERNET, .da = &fr_dict_attr_test_ethernet, .name = "Test-Ethernet", .type = FR_TYPE_ETHERNET },
104 
105  /*
106  * Numeric
107  */
108  { .attr = FR_TEST_ATTR_UINT8, .da = &fr_dict_attr_test_uint8, .name = "Test-Uint8", .type = FR_TYPE_UINT8 },
109  { .attr = FR_TEST_ATTR_UINT16, .da = &fr_dict_attr_test_uint16, .name = "Test-Uint16", .type = FR_TYPE_UINT16 },
110  { .attr = FR_TEST_ATTR_UINT32, .da = &fr_dict_attr_test_uint32, .name = "Test-Uint32", .type = FR_TYPE_UINT32 },
111  { .attr = FR_TEST_ATTR_UINT64, .da = &fr_dict_attr_test_uint64, .name = "Test-Uint64", .type = FR_TYPE_UINT64 },
112 
113  { .attr = FR_TEST_ATTR_INT8, .da = &fr_dict_attr_test_int8, .name = "Test-Int8", .type = FR_TYPE_INT8 },
114  { .attr = FR_TEST_ATTR_INT16, .da = &fr_dict_attr_test_int16, .name = "Test-Int16", .type = FR_TYPE_INT16 },
115  { .attr = FR_TEST_ATTR_INT32, .da = &fr_dict_attr_test_int32, .name = "Test-Int32", .type = FR_TYPE_INT32 },
116  { .attr = FR_TEST_ATTR_INT64, .da = &fr_dict_attr_test_int64, .name = "Test-Int64", .type = FR_TYPE_INT64 },
117 
118  { .attr = FR_TEST_ATTR_FLOAT32, .da = &fr_dict_attr_test_float32, .name = "Test-Float32", .type = FR_TYPE_FLOAT32 },
119  { .attr = FR_TEST_ATTR_FLOAT64, .da = &fr_dict_attr_test_float64, .name = "Test-Float64", .type = FR_TYPE_FLOAT64 },
120 
121  { .attr = FR_TEST_ATTR_DATE, .da = &fr_dict_attr_test_date, .name = "Test-Date", .type = FR_TYPE_DATE },
122 
123  { .attr = FR_TEST_ATTR_TIME_DELTA, .da = &fr_dict_attr_test_date, .name = "Test-Time-Delta", .type = FR_TYPE_TIME_DELTA },
124 
125  { .attr = FR_TEST_ATTR_SIZE, .da = &fr_dict_attr_test_size, .name = "Test-Time-Size", .type = FR_TYPE_SIZE },
126 
127  /*
128  * Grouping
129  */
130  { .attr = FR_TEST_ATTR_TLV, .da = &fr_dict_attr_test_tlv, .name = "Test-TLV", .type = FR_TYPE_TLV },
131  { .attr = FR_TEST_ATTR_TLV_STRING, .parent = &fr_dict_attr_test_tlv, .da = &fr_dict_attr_test_tlv_string, .name = "String", .type = FR_TYPE_STRING },
132 
133  { .attr = FR_TEST_ATTR_STRUCT, .da = &fr_dict_attr_test_struct, .name = "Test-Struct", .type = FR_TYPE_STRUCT },
134  { .attr = 1, .parent = &fr_dict_attr_test_struct, .da = &fr_dict_attr_test_struct_uint32, .name = "uint32", .type = FR_TYPE_UINT32 },
135 
136  { .attr = FR_TEST_ATTR_VSA, .da = &fr_dict_attr_test_vsa, .name = "Test-VSA", .type = FR_TYPE_VSA },
137  { .attr = FR_TEST_ATTR_VENDOR, .parent = &fr_dict_attr_test_vsa, .da = &fr_dict_attr_test_vendor, .name = "Test-Vendor", .type = FR_TYPE_VENDOR },
138  { .attr = FR_TEST_ATTR_VENDOR_STRING, .parent = &fr_dict_attr_test_vendor, .da = &fr_dict_attr_test_vendor_string, .name = "String", .type = FR_TYPE_STRING },
139 
140  { .attr = FR_TEST_ATTR_GROUP, .da = &fr_dict_attr_test_group, .name = "Test-Group", .type = FR_TYPE_GROUP },
141 
142  /*
143  * Deeper nesting
144  */
145  { .attr = FR_TEST_ATTR_NESTED_TOP_TLV, .da = &fr_dict_attr_test_nested_top_tlv, .name = "Test-Nested-Top-TLV", .type = FR_TYPE_TLV },
146  { .attr = FR_TEST_ATTR_NESTED_CHILD_TLV, .parent = &fr_dict_attr_test_nested_top_tlv, .da = &fr_dict_attr_test_nested_child_tlv, .name = "Child-TLV", .type = FR_TYPE_TLV },
149 
150  /*
151  * Enumeration
152  */
153  { .attr = FR_TEST_ATTR_ENUM, .da = &fr_dict_attr_test_enum, .name = "Test-Enum", .type = FR_TYPE_UINT32,
154  .values = (fr_dict_test_attr_value_t[]){
155  { .key = "test123", .val = &enum_test_0},
156  { .key = "test321", .val = &enum_test_1},
157  { .key = NULL, },
158  }
159  },
160  { .attr = FR_TEST_ATTR_INVALID }
161 };
162 
163 /** Add our test attributes to our test dictionary
164  *
165  * @param[in] dict Test dictionary to add.
166  * @param[in] test_defs Test attribute definitions to add.
167  * @param[in] base to add to all attribute numbers.
168  * @param[in] inst number to add to test attribute.
169  * i.e. if the attribute name is "Foo"
170  * the instance number will be appended
171  * to create "Foo-<inst>"
172  * @return
173  * - 0 on success.
174  * - -1 on failure.
175  */
177  unsigned int base, int inst)
178 {
179  fr_dict_test_attr_t const *p;
180  fr_dict_attr_flags_t dict_flags = {};
181 
182  for (p = test_defs; p->attr != FR_TEST_ATTR_INVALID; p++) {
183  fr_dict_attr_t const *parent = p->parent ? *p->parent : fr_dict_root(dict);
184  fr_dict_attr_t const *attr;
185 
186  /*
187  * We only mangle top level attributes
188  */
189  if (!p->parent) {
190  char const *name;
191  char *buff = NULL;
192 
193  if (inst >= 0) {
194  name = buff = talloc_asprintf(NULL, "%s-%u", p->name, (unsigned int)inst);
195  } else {
196  name = p->name;
197  }
198 
199  if (fr_dict_attr_add(dict, parent, name, p->attr + base, p->type, &dict_flags) < 0) {
200  talloc_free(buff);
201  return -1;
202  }
203 
204  attr = fr_dict_attr_by_name(NULL, parent, name);
205  if (!attr) {
206  fr_strerror_printf("Failed adding test attribute \"%s\"", name);
207  talloc_free(buff);
208  return -1;
209  }
210 
211  talloc_free(buff);
212  } else {
213  if (fr_dict_attr_add(dict, parent, p->name, p->attr, p->type, &dict_flags) < 0) return -1;
214 
215  attr = fr_dict_attr_by_name(NULL, parent, p->name);
216  if (!attr) {
217  fr_strerror_printf("Failed adding test attribute \"%s\"", p->name);
218  return -1;
219  }
220  }
221 
222  /* Add the enumeration values */
223  if (p->values) {
225 
226  for (v = p->values;
227  v->key != NULL;
228  v++) fr_dict_enum_add_name(fr_dict_attr_unconst(attr), v->key, v->val, false, false);
229  }
230 
231  *p->da = attr;
232  }
233 
234  return 0;
235 }
236 
237 /** Initialise a test dictionary and add our test_defs to it
238  *
239  * @param[in] ctx to bind the global dictionary ctx lifetim to.
240  * @param[out] dict_p Where to write a pointer to our test dictionary.
241  * May be NULL.
242  * @param[in] test_defs Test attributes. If NULL will default to the
243  * default test attributes.
244  * @return
245  * - 0 on success.
246  * - -1 on failure.
247  */
248 int fr_dict_test_init(TALLOC_CTX *ctx, fr_dict_t **dict_p, fr_dict_test_attr_t const *test_defs)
249 {
250  fr_dict_gctx_t const *our_dict_gctx;
251  fr_dict_t *dict;
252 
253  our_dict_gctx = fr_dict_global_ctx_init(ctx, false, "share/dictionary");
254  if (!our_dict_gctx) return -1;
255 
256  if (!test_defs) test_defs = fr_dict_test_attrs;
257 
258  /*
259  * Set the root name of the dictionary
260  */
261  dict = fr_dict_alloc("test", 42);
262  if (!dict) {
263  error:
264  fr_dict_global_ctx_free(our_dict_gctx);
265  return -1;
266  }
267 
268  if (fr_dict_test_attrs_init(dict, test_defs, 0, 0) < 0) goto error;
269 
270  fr_dict_test = dict;
271 
272  if (dict_p) *dict_p = dict;
273 
274  return 0;
275 }
static fr_dict_t * dict
Definition: fuzzer.c:46
int fr_dict_enum_add_name(fr_dict_attr_t *da, char const *name, fr_value_box_t const *value, bool coerce, bool replace)
Add a value name.
Definition: dict_util.c:1535
fr_dict_attr_t * fr_dict_attr_unconst(fr_dict_attr_t const *da)
Coerce to non-const.
Definition: dict_util.c:4191
fr_dict_attr_t const * fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *attr))
Locate a fr_dict_attr_t by its name.
Definition: dict_util.c:2860
fr_dict_t * fr_dict_alloc(char const *proto_name, unsigned int proto_number)
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition: dict_util.c:1997
int fr_dict_global_ctx_free(fr_dict_gctx_t const *gctx)
Explicitly free all data associated with a global dictionary context.
Definition: dict_util.c:4063
fr_dict_gctx_t * fr_dict_global_ctx_init(TALLOC_CTX *ctx, bool free_at_exit, char const *dict_dir)
Initialise the global protocol hashes.
Definition: dict_util.c:3984
int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, int attr, fr_type_t type, fr_dict_attr_flags_t const *flags))
Add an attribute to the dictionary.
Definition: dict_util.c:1245
Values of the encryption flags.
Definition: merged_model.c:139
fr_dict_attr_t const * fr_dict_attr_test_struct
Definition: dict_test.c:67
fr_dict_attr_t const * fr_dict_attr_test_ethernet
Definition: dict_test.c:42
fr_dict_attr_t const * fr_dict_attr_test_ipv6_addr
Definition: dict_test.c:36
fr_dict_attr_t const * fr_dict_attr_test_tlv_string
Definition: dict_test.c:65
fr_dict_test_attr_t const fr_dict_test_attrs[]
Definition: dict_test.c:86
fr_dict_attr_t const * fr_dict_attr_test_nested_leaf_string
Definition: dict_test.c:78
fr_dict_attr_t const * fr_dict_attr_test_enum
Definition: dict_test.c:81
static fr_value_box_t enum_test_0
Definition: dict_test.c:83
fr_dict_attr_t const * fr_dict_attr_test_time_delta
Definition: dict_test.c:60
fr_dict_t * fr_dict_test
Definition: dict_test.c:28
fr_dict_attr_t const * fr_dict_attr_test_date
Definition: dict_test.c:58
fr_dict_attr_t const * fr_dict_attr_test_combo_ip_prefix
Definition: dict_test.c:41
fr_dict_attr_t const * fr_dict_attr_test_vendor
Definition: dict_test.c:71
fr_dict_attr_t const * fr_dict_attr_test_int32
Definition: dict_test.c:52
fr_dict_attr_t const * fr_dict_attr_test_tlv
Definition: dict_test.c:64
fr_dict_attr_t const * fr_dict_attr_test_uint64
Definition: dict_test.c:48
fr_dict_attr_t const * fr_dict_attr_test_int16
Definition: dict_test.c:51
fr_dict_attr_t const * fr_dict_attr_test_ifid
Definition: dict_test.c:39
fr_dict_attr_t const * fr_dict_attr_test_nested_top_tlv
Definition: dict_test.c:76
fr_dict_attr_t const * fr_dict_attr_test_uint32
Definition: dict_test.c:47
fr_dict_attr_t const * fr_dict_attr_test_vendor_string
Definition: dict_test.c:72
fr_dict_attr_t const * fr_dict_attr_test_int8
Definition: dict_test.c:50
fr_dict_attr_t const * fr_dict_attr_test_ipv6_prefix
Definition: dict_test.c:37
fr_dict_attr_t const * fr_dict_attr_test_octets
Definition: dict_test.c:31
fr_dict_attr_t const * fr_dict_attr_test_ipv4_prefix
Definition: dict_test.c:34
int fr_dict_test_attrs_init(fr_dict_t *dict, fr_dict_test_attr_t const *test_defs, unsigned int base, int inst)
Add our test attributes to our test dictionary.
Definition: dict_test.c:176
fr_dict_attr_t const * fr_dict_attr_test_string
Definition: dict_test.c:30
fr_dict_attr_t const * fr_dict_attr_test_ipv4_addr
Definition: dict_test.c:33
fr_dict_attr_t const * fr_dict_attr_test_nested_child_tlv
Definition: dict_test.c:77
int fr_dict_test_init(TALLOC_CTX *ctx, fr_dict_t **dict_p, fr_dict_test_attr_t const *test_defs)
Initialise a test dictionary and add our test_defs to it.
Definition: dict_test.c:248
fr_dict_attr_t const * fr_dict_attr_test_uint8
Definition: dict_test.c:45
fr_dict_attr_t const * fr_dict_attr_test_float32
Definition: dict_test.c:55
fr_dict_attr_t const * fr_dict_attr_test_group
Definition: dict_test.c:74
fr_dict_attr_t const * fr_dict_attr_test_nested_leaf_int32
Definition: dict_test.c:79
fr_dict_attr_t const * fr_dict_attr_test_struct_uint32
Definition: dict_test.c:68
fr_dict_attr_t const * fr_dict_attr_test_uint16
Definition: dict_test.c:46
fr_dict_attr_t const * fr_dict_attr_test_int64
Definition: dict_test.c:53
fr_dict_attr_t const * fr_dict_attr_test_combo_ip_addr
Definition: dict_test.c:40
fr_dict_attr_t const * fr_dict_attr_test_bool
Definition: dict_test.c:43
static fr_value_box_t enum_test_1
Definition: dict_test.c:84
fr_dict_attr_t const * fr_dict_attr_test_float64
Definition: dict_test.c:56
fr_dict_attr_t const * fr_dict_attr_test_vsa
Definition: dict_test.c:70
fr_dict_attr_t const * fr_dict_attr_test_size
Definition: dict_test.c:62
Functions to create test dictionaries for unit tests.
fr_value_box_t * val
Enumeration value.
Definition: dict_test.h:94
@ FR_TEST_ATTR_INT16
Definition: dict_test.h:58
@ FR_TEST_ATTR_IPV4_PREFIX
Definition: dict_test.h:41
@ FR_TEST_ATTR_IFID
Definition: dict_test.h:44
@ FR_TEST_ATTR_TLV_STRING
Definition: dict_test.h:72
@ FR_TEST_ATTR_TLV
Definition: dict_test.h:71
@ FR_TEST_ATTR_ETHERNET
Definition: dict_test.h:47
@ FR_TEST_ATTR_IPV6_PREFIX
Definition: dict_test.h:43
@ FR_TEST_ATTR_UINT8
Definition: dict_test.h:51
@ FR_TEST_ATTR_NESTED_LEAF_INT32
Definition: dict_test.h:85
@ FR_TEST_ATTR_INT64
Definition: dict_test.h:60
@ FR_TEST_ATTR_VSA
Definition: dict_test.h:76
@ FR_TEST_ATTR_STRING
Definition: dict_test.h:37
@ FR_TEST_ATTR_VENDOR
Definition: dict_test.h:77
@ FR_TEST_ATTR_FLOAT64
Definition: dict_test.h:63
@ FR_TEST_ATTR_STRUCT
Definition: dict_test.h:74
@ FR_TEST_ATTR_VENDOR_STRING
Definition: dict_test.h:78
@ FR_TEST_ATTR_IPV6_ADDR
Definition: dict_test.h:42
@ FR_TEST_ATTR_NESTED_CHILD_TLV
Definition: dict_test.h:83
@ FR_TEST_ATTR_INT32
Definition: dict_test.h:59
@ FR_TEST_ATTR_DATE
Definition: dict_test.h:65
@ FR_TEST_ATTR_NESTED_LEAF_STRING
Definition: dict_test.h:84
@ FR_TEST_ATTR_UINT32
Definition: dict_test.h:53
@ FR_TEST_ATTR_TIME_DELTA
Definition: dict_test.h:67
@ FR_TEST_ATTR_UINT16
Definition: dict_test.h:52
@ FR_TEST_ATTR_OCTETS
Definition: dict_test.h:38
@ FR_TEST_ATTR_ENUM
Definition: dict_test.h:87
@ FR_TEST_ATTR_UINT64
Definition: dict_test.h:54
@ FR_TEST_ATTR_INVALID
Definition: dict_test.h:36
@ FR_TEST_ATTR_FLOAT32
Definition: dict_test.h:62
@ FR_TEST_ATTR_INT8
Definition: dict_test.h:57
@ FR_TEST_ATTR_IPV4_ADDR
Definition: dict_test.h:40
@ FR_TEST_ATTR_NESTED_TOP_TLV
Definition: dict_test.h:82
@ FR_TEST_ATTR_SIZE
Definition: dict_test.h:69
@ FR_TEST_ATTR_GROUP
Definition: dict_test.h:80
fr_dict_test_attr_number_t attr
Attribute number to create.
Definition: dict_test.h:100
fr_dict_attr_t const ** parent
The parent of this attribute.
Definition: dict_test.h:101
fr_dict_test_attr_value_t * values
Array of enumeration values to add to this attribute.
Definition: dict_test.h:105
char const * key
Enumeration name.
Definition: dict_test.h:93
fr_type_t type
What type the attribute.
Definition: dict_test.h:104
fr_dict_attr_t const ** da
Where to write a pointer to this attribute.
Definition: dict_test.h:102
char const * name
What to call this attribute.
Definition: dict_test.h:103
Test enumeration attributes.
Definition: dict_test.h:99
Test enumeration values.
Definition: dict_test.h:92
talloc_free(reap)
@ FR_TYPE_TIME_DELTA
A period of time measured in nanoseconds.
Definition: merged_model.c:113
@ FR_TYPE_FLOAT32
Single precision floating point.
Definition: merged_model.c:108
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
Definition: merged_model.c:86
@ FR_TYPE_INT8
8 Bit signed integer.
Definition: merged_model.c:103
@ FR_TYPE_TLV
Contains nested attributes.
Definition: merged_model.c:118
@ FR_TYPE_ETHERNET
48 Bit Mac-Address.
Definition: merged_model.c:93
@ FR_TYPE_IPV6_PREFIX
IPv6 Prefix.
Definition: merged_model.c:89
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
@ FR_TYPE_UINT16
16 Bit unsigned integer.
Definition: merged_model.c:98
@ FR_TYPE_INT64
64 Bit signed integer.
Definition: merged_model.c:106
@ FR_TYPE_INT16
16 Bit signed integer.
Definition: merged_model.c:104
@ FR_TYPE_DATE
Unix time stamp, always has value >2^31.
Definition: merged_model.c:111
@ FR_TYPE_UINT8
8 Bit unsigned integer.
Definition: merged_model.c:97
@ FR_TYPE_UINT32
32 Bit unsigned integer.
Definition: merged_model.c:99
@ FR_TYPE_STRUCT
like TLV, but without T or L, and fixed-width children
Definition: merged_model.c:119
@ FR_TYPE_INT32
32 Bit signed integer.
Definition: merged_model.c:105
@ FR_TYPE_VENDOR
Attribute that represents a vendor in the attribute tree.
Definition: merged_model.c:122
@ FR_TYPE_UINT64
64 Bit unsigned integer.
Definition: merged_model.c:100
@ FR_TYPE_IPV6_ADDR
128 Bit IPv6 Address.
Definition: merged_model.c:88
@ FR_TYPE_IPV4_PREFIX
IPv4 Prefix.
Definition: merged_model.c:87
@ FR_TYPE_SIZE
Unsigned integer capable of representing any memory address on the local system.
Definition: merged_model.c:115
@ FR_TYPE_VSA
Vendor-Specific, for RADIUS attribute 26.
Definition: merged_model.c:121
@ FR_TYPE_IFID
Interface ID.
Definition: merged_model.c:90
@ FR_TYPE_OCTETS
Raw octets.
Definition: merged_model.c:84
@ FR_TYPE_GROUP
A grouping of other attributes.
Definition: merged_model.c:124
@ FR_TYPE_FLOAT64
Double precision floating point.
Definition: merged_model.c:109
static char const * name
static char buff[sizeof("18446744073709551615")+3]
Definition: size_tests.c:41
eap_aka_sim_process_conf_t * inst
static fr_slen_t parent
Definition: pair.h:844
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition: strerror.h:64
#define FR_VALUE_BOX_INITIALISER(_vb, _type, _field, _val)
A static initialiser for stack/globally allocated boxes.
Definition: value.h:487