The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
types.c
Go to the documentation of this file.
1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation; either
5  * version 2.1 of the License, or (at your option) any later version.
6  *
7  * This library 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 GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /** Boxed value structures and functions to manipulate them
18  *
19  * @file src/lib/util/types.c
20  *
21  * @copyright 2021 The FreeRADIUS server project
22  */
23 RCSID("$Id: a8f8fd4113d6f4afb6ad2fa0fa0e414603f10024 $")
24 
25 #include <freeradius-devel/util/strerror.h>
26 #include <freeradius-devel/util/types.h>
27 #include <freeradius-devel/util/value.h>
28 
29 /** Map data types to names representing those types
30  */
32  { L("null"), FR_TYPE_NULL },
33  { L("string"), FR_TYPE_STRING },
34  { L("octets"), FR_TYPE_OCTETS },
35 
36  { L("ipaddr"), FR_TYPE_IPV4_ADDR },
37  { L("ipv4addr"), FR_TYPE_IPV4_ADDR },
38  { L("ipv4prefix"), FR_TYPE_IPV4_PREFIX },
39  { L("ipv6addr"), FR_TYPE_IPV6_ADDR },
40  { L("ipv6prefix"), FR_TYPE_IPV6_PREFIX },
41  { L("ifid"), FR_TYPE_IFID },
42  { L("combo-ip"), FR_TYPE_COMBO_IP_ADDR },
43  { L("combo-prefix"), FR_TYPE_COMBO_IP_PREFIX },
44  { L("ether"), FR_TYPE_ETHERNET },
45 
46  { L("bool"), FR_TYPE_BOOL },
47 
48  { L("uint8"), FR_TYPE_UINT8 },
49  { L("uint16"), FR_TYPE_UINT16 },
50  { L("uint32"), FR_TYPE_UINT32 },
51  { L("uint64"), FR_TYPE_UINT64 },
52 
53  { L("int8"), FR_TYPE_INT8 },
54  { L("int16"), FR_TYPE_INT16 },
55  { L("int32"), FR_TYPE_INT32 },
56  { L("int64"), FR_TYPE_INT64 },
57 
58  { L("float32"), FR_TYPE_FLOAT32 },
59  { L("float64"), FR_TYPE_FLOAT64 },
60 
61  { L("date"), FR_TYPE_DATE },
62  { L("time_delta"), FR_TYPE_TIME_DELTA },
63 
64  { L("size"), FR_TYPE_SIZE },
65 
66  { L("tlv"), FR_TYPE_TLV },
67  { L("struct"), FR_TYPE_STRUCT },
68 
69  { L("vsa"), FR_TYPE_VSA },
70  { L("vendor"), FR_TYPE_VENDOR },
71  { L("group"), FR_TYPE_GROUP },
72 
73  /*
74  * Alternative names
75  */
76  { L("cidr"), FR_TYPE_IPV4_PREFIX },
77  { L("byte"), FR_TYPE_UINT8 },
78  { L("short"), FR_TYPE_UINT16 },
79  { L("integer"), FR_TYPE_UINT32 },
80  { L("integer64"), FR_TYPE_UINT64 },
81  { L("decimal"), FR_TYPE_FLOAT64 },
82  { L("signed"), FR_TYPE_INT32 }
83 };
85 
86 /** Table of all the direct mappings between types and C types
87  *
88  * Useful for setting talloc types correctly.
89  */
90 static char const *fr_type_to_c_type[] = {
91  [FR_TYPE_STRING] = "char *",
92  [FR_TYPE_OCTETS] = "uint8_t *",
93 
94  [FR_TYPE_IPV4_ADDR] = "fr_ipaddr_t",
95  [FR_TYPE_IPV4_PREFIX] = "fr_ipaddr_t",
96  [FR_TYPE_IPV6_ADDR] = "fr_ipaddr_t",
97  [FR_TYPE_IPV6_PREFIX] = "fr_ipaddr_t",
98  [FR_TYPE_COMBO_IP_ADDR] = "fr_ipaddr_t",
99  [FR_TYPE_COMBO_IP_PREFIX] = "fr_ipaddr_t",
100  [FR_TYPE_IFID] = "fr_ifid_t",
101  [FR_TYPE_ETHERNET] = "fr_ethernet_t",
102 
103  [FR_TYPE_BOOL] = "bool",
104  [FR_TYPE_UINT8] = "uint8_t",
105  [FR_TYPE_UINT16] = "uint16_t",
106  [FR_TYPE_UINT32] = "uint32_t",
107  [FR_TYPE_UINT64] = "uint64_t",
108 
109  [FR_TYPE_INT8] = "int8_t",
110  [FR_TYPE_INT16] = "int16_t",
111  [FR_TYPE_INT32] = "int32_t",
112  [FR_TYPE_INT64] = "int64_t",
113 
114  [FR_TYPE_FLOAT32] = "float",
115  [FR_TYPE_FLOAT64] = "double",
116 
117  [FR_TYPE_DATE] = "fr_unix_time_t",
118 
119  [FR_TYPE_TIME_DELTA] = "fr_time_delta_t",
120  [FR_TYPE_SIZE] = "size_t",
121  [FR_TYPE_VALUE_BOX] = "fr_value_box_t",
122  [FR_TYPE_VOID] = "void *",
123 
124  [FR_TYPE_MAX] = 0 //!< Ensure array covers all types.
125 };
126 
127 /** Table of all the direct mappings between types and C type sizes
128  *
129  */
130 static size_t const fr_type_to_c_size[] = {
131  [FR_TYPE_STRING] = sizeof(char *),
132  [FR_TYPE_OCTETS] = sizeof(uint8_t *),
133 
134  [FR_TYPE_IPV4_ADDR] = sizeof(fr_ipaddr_t),
135  [FR_TYPE_IPV4_PREFIX] = sizeof(fr_ipaddr_t),
136  [FR_TYPE_IPV6_ADDR] = sizeof(fr_ipaddr_t),
137  [FR_TYPE_IPV6_PREFIX] = sizeof(fr_ipaddr_t),
140  [FR_TYPE_IFID] = sizeof(fr_ifid_t),
141  [FR_TYPE_ETHERNET] = sizeof(fr_ethernet_t),
142 
143  [FR_TYPE_BOOL] = sizeof(bool),
144  [FR_TYPE_UINT8] = sizeof(uint8_t),
145  [FR_TYPE_UINT16] = sizeof(uint16_t),
146  [FR_TYPE_UINT32] = sizeof(uint32_t),
147  [FR_TYPE_UINT64] = sizeof(uint64_t),
148 
149  [FR_TYPE_INT8] = sizeof(int8_t),
150  [FR_TYPE_INT16] = sizeof(int16_t),
151  [FR_TYPE_INT32] = sizeof(int32_t),
152  [FR_TYPE_INT64] = sizeof(int64_t),
153 
154  [FR_TYPE_FLOAT32] = sizeof(float),
155  [FR_TYPE_FLOAT64] = sizeof(double),
156 
157  [FR_TYPE_DATE] = sizeof(fr_unix_time_t),
158 
160  [FR_TYPE_SIZE] = sizeof(size_t),
161  [FR_TYPE_VALUE_BOX] = sizeof(fr_value_box_t),
162  [FR_TYPE_VOID] = sizeof(void *),
163 
164  [FR_TYPE_MAX] = 0 //!< Ensure array covers all types.
165 };
166 
167 #define ARRAY_BEG(_type) { [_type] = true,
168 #define ARRAY_MID(_type) [_type] = true,
169 #define ARRAY_END(_type) [_type] = true }
170 
175 
177 
181 
186 
187 #define O(_x) [FR_TYPE_ ## _x] = true
188 
189 /*
190  * Can we promote [src][dst] -> dst
191  * dst is not octets / string
192  * src and dst are both FR_TYPE_VALUE
193  */
194 static const bool type_cast_table[FR_TYPE_MAX][FR_TYPE_MAX] = {
195  [FR_TYPE_IPV4_ADDR] = {
196  O(IPV4_PREFIX),
197  O(IPV6_ADDR),
198  O(IPV6_PREFIX),
199  O(COMBO_IP_ADDR),
200  O(COMBO_IP_PREFIX),
201  O(UINT32), /* ipv4 addresses are uint32 */
202  },
203  [FR_TYPE_IPV4_PREFIX] = {
204  O(IPV4_ADDR), /* if the prefix is /32 */
205  O(IPV6_ADDR),
206  O(IPV6_PREFIX),
207  O(COMBO_IP_ADDR),
208  O(COMBO_IP_PREFIX)
209  },
210  [FR_TYPE_IPV6_ADDR] = {
211  O(IPV6_PREFIX),
212  O(COMBO_IP_ADDR),
213  O(COMBO_IP_PREFIX)
214  },
215  [FR_TYPE_IPV6_PREFIX] = {
216  O(IPV6_ADDR), /* if the prefix is /128 */
217  O(COMBO_IP_ADDR),
218  O(COMBO_IP_PREFIX)
219  },
221  O(IPV4_ADDR),
222  O(IPV4_PREFIX),
223  O(IPV6_ADDR),
224  O(IPV6_PREFIX),
225  O(COMBO_IP_PREFIX)
226  },
228  O(IPV4_ADDR),
229  O(IPV4_PREFIX),
230  O(IPV6_ADDR),
231  O(IPV6_PREFIX),
232  O(COMBO_IP_ADDR) /* if the prefix is /128 or /32 */
233  },
234 
235  [FR_TYPE_ETHERNET] = {
236  O(UINT64),
237  },
238 
239  [FR_TYPE_UINT64] = {
240  O(ETHERNET),
241  },
242 
243  [FR_TYPE_DATE] = { /* in 2021, dates always have values 2^31 or more */
244  O(UINT32),
245  O(UINT64),
246  O(INT32),
247  O(INT64),
248  O(SIZE),
249  O(FLOAT32),
250  O(FLOAT64),
251  O(TIME_DELTA),
252  },
253 
254  [FR_TYPE_TIME_DELTA] = {
255  O(DATE),
256  },
257 
258  [FR_TYPE_UINT32] = {
259  O(IPV4_ADDR),
260  },
261 
262 };
263 
264 /*
265  * This is different from FR_TYPE_NUMERIC, largely in that it
266  * doesn't include FR_TYPE_DATE. Because we know that dates
267  * always have values 2^31 or greater, so casts exclude some of
268  * the smaller integer types.
269  */
270 static const bool type_is_number[FR_TYPE_MAX] = {
271  O(BOOL), O(SIZE), O(FLOAT32), O(FLOAT64),
272  O(UINT8), O(UINT16), O(UINT32), O(UINT64),
273  O(INT8), O(INT16), O(INT32), O(INT64),
274  O(TIME_DELTA),
275 };
276 
277 /** Return if we're allowed to cast the types.
278  *
279  * @param dst the destination type we wish to cast to
280  * @param src the source type we wish to cast to
281  *
282  */
284 {
285  /*
286  * Invalid casts.
287  */
288  switch (dst) {
289  case FR_TYPE_NON_LEAF:
290  return false;
291 
292  default:
293  break;
294  }
295 
296  switch (src) {
297  case FR_TYPE_NON_LEAF:
298  return false;
299 
300  default:
301  break;
302  }
303 
304  if (src == dst) return true;
305 
306  /*
307  * Anything can be converted to octets or strings.
308  */
309  if (dst == FR_TYPE_OCTETS) return true;
310  if (dst == FR_TYPE_STRING) return true;
311 
312  /*
313  * Strings and octets can be converted to anything. We
314  * do run-time checks on the values to see if they fit.
315  */
316  if (src == FR_TYPE_OCTETS) return true;
317  if (src == FR_TYPE_STRING) return true;
318 
319  /*
320  * Any integer-style thing can be cast to any other
321  * integer-style thing. Mostly. We do run-time checks
322  * on values to see if they fit.
323  */
324  if (type_is_number[src] && type_is_number[dst]) {
325  return true;
326  }
327 
328  /*
329  * That takes care of the simple cases. :( Now to the
330  * complex ones. Instead of masses of if / then / else,
331  * we just use a lookup table.
332  */
333  return type_cast_table[src][dst];
334 }
335 
336 #undef O
337 #define O(_x) [FR_TYPE_ ## _x] = FR_TYPE_ ## _x
338 
339 /** promote (a,b) -> a or b
340  * a/b are not octets / string
341  * a and b are both FR_TYPE_VALUE
342  *
343  * Note that this table can return a type which is _not_ a or b.
344  *
345  * Many lookups of table[a][b] will return b. Some will return a.
346  * Others will return a type which is compatible with both a and b.
347  */
349  [FR_TYPE_IPV4_ADDR] = {
350  O(IPV4_PREFIX),
351  O(IPV6_ADDR),
352  O(IPV6_PREFIX),
354  },
355 
356  [FR_TYPE_IPV4_PREFIX] = {
358  O(IPV4_PREFIX),
360  O(IPV6_PREFIX),
361  },
362 
363  [FR_TYPE_IPV6_ADDR] = {
364  O(IPV6_PREFIX),
365  },
366 
367  [FR_TYPE_IPV6_PREFIX] = {
369  },
370 
371  /* unsigned integers */
372 
373  [FR_TYPE_BOOL] = {
374  O(UINT8),
375  O(UINT16),
376  O(UINT32),
377  O(UINT64),
378  O(INT8),
379  O(INT16),
380  O(INT32),
381  O(INT64),
382  O(SIZE),
383  O(FLOAT32),
384  O(FLOAT64),
385  O(TIME_DELTA),
386  },
387 
388  [FR_TYPE_UINT8] = {
390  O(UINT16),
391  O(UINT32),
392  O(UINT64),
394  O(INT16),
395  O(INT32),
396  O(INT64),
397  O(SIZE),
398  O(FLOAT32),
399  O(FLOAT64),
400  O(TIME_DELTA),
401  },
402 
403  [FR_TYPE_UINT16] = {
406  O(UINT32),
407  O(UINT64),
409  O(INT32),
410  O(INT64),
411  O(SIZE),
412  O(FLOAT32),
413  O(FLOAT64),
414  O(TIME_DELTA),
415  },
416 
417  [FR_TYPE_UINT32] = {
419  O(IPV4_ADDR),
422  O(UINT64),
424  O(INT64),
425  O(SIZE),
426  O(FLOAT32),
427  O(FLOAT64),
428  O(TIME_DELTA),
429  O(DATE),
430  },
431 
432  [FR_TYPE_UINT64] = {
437 
442  O(SIZE),
444  O(FLOAT64),
445  O(TIME_DELTA),
446  O(DATE),
447  },
448 
449  /* signed integers */
450  [FR_TYPE_INT8] = {
452  O(UINT8),
453  O(UINT16),
454  O(UINT32),
455  O(UINT64),
456  O(INT16),
457  O(INT32),
458  O(INT64),
459  O(SIZE),
460  O(FLOAT32),
461  O(FLOAT64),
462  O(TIME_DELTA),
463  },
464 
465  [FR_TYPE_INT16] = {
468  O(UINT16),
469  O(UINT32),
470  O(UINT64),
472  O(INT32),
473  O(INT64),
474  O(SIZE),
475  O(FLOAT32),
476  O(FLOAT64),
477  O(TIME_DELTA),
478  },
479 
480  [FR_TYPE_INT32] = {
484  O(UINT32),
485  O(UINT64),
488  O(INT64),
489  O(SIZE),
490  O(FLOAT32),
491  O(FLOAT64),
492  O(TIME_DELTA),
493  O(DATE),
494  },
495 
496  [FR_TYPE_INT64] = {
500  O(UINT64),
501  O(SIZE),
506  O(FLOAT64),
507  O(TIME_DELTA),
508  O(DATE),
509  },
510 
511  [FR_TYPE_TIME_DELTA] = {
518 
523 
527  },
528 
529  [FR_TYPE_DATE] = {
533 
536 
539  O(TIME_DELTA),
540  },
541 
542  [FR_TYPE_SIZE] = {
553  O(FLOAT64),
555  O(DATE),
556  }
557 };
558 
559 /** Return the promoted type
560  *
561  * We presume that the two types are compatible, as checked by
562  * calling fr_type_cast(). The main difference here is that the two
563  * types don't have any src / dst relationship. Instead, we just
564  * pick one which best suits any value-box comparisons
565  *
566  * Note that this function can return a type which is _not_ a or b.
567  *
568  * @param a type one
569  * @param b type two
570  * @return the promoted type
571  */
573 {
574  if (!fr_type_is_leaf(a) || !fr_type_is_leaf(b)) return FR_TYPE_NULL;
575 
576  if (a == b) return a;
577 
578  /*
579  * string / octets and "type", the un-typed data gets cast to
580  * "type".
581  *
582  * We prefer to cast raw data to real types. We also
583  * prefer to _parse_ strings, and do the type checking on
584  * the real types. That way we have things like: "000" == 0
585  */
586  if (a == FR_TYPE_OCTETS) return b;
587  if (b == FR_TYPE_OCTETS) return a;
588 
589  /*
590  * Check for string after octets, because we want to cast
591  * octets to string, and not vice versa.
592  */
593  if (a == FR_TYPE_STRING) return b;
594  if (b == FR_TYPE_STRING) return a;
595 
596  /*
597  * Otherwise bad things happen. :(
598  */
599  if (unlikely(type_promote_table[a][b] != type_promote_table[b][a])) {
600  fr_strerror_printf("Inverse type mapping inconsistent for a = %s, b = %s",
601  fr_type_to_str(a),
602  fr_type_to_str(b));
603 
604  return FR_TYPE_NULL;
605  }
606 
607  if (unlikely(type_promote_table[a][b] == FR_TYPE_NULL)) {
608  fr_strerror_printf("No type promotions for a = %s, b = %s",
609  fr_type_to_str(a),
610  fr_type_to_str(b));
611  return FR_TYPE_NULL;
612  }
613 
614  /*
615  * That takes care of the simple cases. :( Now to the
616  * complex ones. Instead of masses of if / then / else,
617  * we just use a lookup table.
618  */
619  return type_promote_table[a][b];
620 }
621 
622 /** Allocate an array of a given type
623  *
624  * @param[in] ctx to allocate array in.
625  * @param[in] type array to allocate.
626  * @param[in] count The number of elements to allocate.
627  * @return
628  * - NULL on error.
629  * - A new talloc array.
630  */
631 void **fr_type_array_alloc(TALLOC_CTX *ctx, fr_type_t type, size_t count)
632 {
633  char const *c_type;
634 
635  c_type = fr_type_to_c_type[type];
636  if (c_type == NULL) {
637  fr_strerror_printf("Type %s does not have a C type equivalent", fr_type_to_str(type));
638  return NULL;
639  }
640 
641  return _talloc_zero_array(ctx, fr_type_to_c_size[type], count, c_type);
642  }
#define RCSID(id)
Definition: build.h:444
#define L(_str)
Helper for initialising arrays of string literals.
Definition: build.h:207
#define unlikely(_x)
Definition: build.h:378
#define NUM_ELEMENTS(_t)
Definition: build.h:335
struct value_box_s fr_value_box_t
Definition: dict.h:49
Struct to represent an ethernet address.
Definition: inet.h:45
Struct to represent an interface id.
Definition: inet.h:54
IPv4/6 prefix.
Definition: merged_model.c:272
unsigned short uint16_t
Definition: merged_model.c:31
fr_type_t
Definition: merged_model.c:80
@ 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_MAX
Number of defined data types.
Definition: merged_model.c:130
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
Definition: merged_model.c:81
@ 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_COMBO_IP_PREFIX
IPv4 or IPv6 address prefix depending on length.
Definition: merged_model.c:92
@ FR_TYPE_VALUE_BOX
A boxed value.
Definition: merged_model.c:125
@ 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_VOID
User data.
Definition: merged_model.c:127
@ FR_TYPE_BOOL
A truth value.
Definition: merged_model.c:95
@ 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_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
Definition: merged_model.c:91
@ 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
unsigned int uint32_t
Definition: merged_model.c:33
unsigned char bool
Definition: merged_model.c:19
unsigned char uint8_t
Definition: merged_model.c:30
return count
Definition: module.c:175
fr_aka_sim_id_type_t type
An element in an arbitrarily ordered array of name to num mappings.
Definition: table.h:53
struct fr_time_delta_s fr_time_delta_t
A time delta, a difference in time measured in nanoseconds.
"Unix" time.
Definition: time.h:95
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition: strerror.h:64
#define O(_x)
Definition: types.c:337
fr_table_num_ordered_t const fr_type_table[]
Map data types to names representing those types.
Definition: types.c:31
static char const * fr_type_to_c_type[]
Table of all the direct mappings between types and C types.
Definition: types.c:90
bool const fr_type_structural_except_vsa[FR_TYPE_MAX+1]
Definition: types.c:182
#define ARRAY_MID(_type)
Definition: types.c:168
bool const fr_type_non_leaf[FR_TYPE_MAX+1]
Definition: types.c:185
void ** fr_type_array_alloc(TALLOC_CTX *ctx, fr_type_t type, size_t count)
Allocate an array of a given type.
Definition: types.c:631
bool fr_type_cast(fr_type_t dst, fr_type_t src)
Return if we're allowed to cast the types.
Definition: types.c:283
bool const fr_type_signed[FR_TYPE_MAX+1]
Definition: types.c:174
bool const fr_type_integer[FR_TYPE_MAX+1]
Definition: types.c:172
bool const fr_type_variable_size[FR_TYPE_MAX+1]
Definition: types.c:179
bool const fr_type_numeric[FR_TYPE_MAX+1]
Definition: types.c:173
static fr_type_t type_promote_table[FR_TYPE_MAX][FR_TYPE_MAX]
promote (a,b) -> a or b a/b are not octets / string a and b are both FR_TYPE_VALUE
Definition: types.c:348
bool const fr_type_ip[FR_TYPE_MAX+1]
Definition: types.c:176
static const bool type_is_number[FR_TYPE_MAX]
Definition: types.c:270
bool const fr_type_fixed_size[FR_TYPE_MAX+1]
Definition: types.c:178
#define ARRAY_END(_type)
Definition: types.c:169
bool const fr_type_integer_except_bool[FR_TYPE_MAX+1]
Definition: types.c:171
bool const fr_type_quoted[FR_TYPE_MAX+1]
Definition: types.c:180
bool const fr_type_leaf[FR_TYPE_MAX+1]
Definition: types.c:184
size_t fr_type_table_len
Definition: types.c:84
static size_t const fr_type_to_c_size[]
Table of all the direct mappings between types and C type sizes.
Definition: types.c:130
fr_type_t fr_type_promote(fr_type_t a, fr_type_t b)
Return the promoted type.
Definition: types.c:572
static const bool type_cast_table[FR_TYPE_MAX][FR_TYPE_MAX]
Definition: types.c:194
#define ARRAY_BEG(_type)
Definition: types.c:167
bool const fr_type_structural[FR_TYPE_MAX+1]
Definition: types.c:183
#define FR_TYPE_NON_LEAF_DEF(_beg, _mid, _end)
Types which do not represent leaf values.
Definition: types.h:267
#define FR_TYPE_IP_DEF(_beg, _mid, _end)
Types which can fit in an fr_ipaddr_t.
Definition: types.h:162
#define FR_TYPE_FIXED_SIZE_DEF(_beg, _mid, _end)
Match all fixed length types.
Definition: types.h:176
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
Definition: types.h:433
#define FR_TYPE_STRUCTURAL_EXCEPT_VSA_DEF(_beg, _mid, _end)
Stupid hack for things which produce special error messages for VSAs.
Definition: types.h:214
#define FR_TYPE_NON_LEAF
Definition: types.h:298
#define FR_TYPE_SIGNED_DEF(_beg, _mid, _end)
Signed values.
Definition: types.h:131
#define FR_TYPE_VARIABLE_SIZE_DEF(_beg, _mid, _end)
Match all variable length types.
Definition: types.h:194
#define FR_TYPE_NUMERIC_DEF(_beg, _mid, _end)
Naturally numeric types.
Definition: types.h:148
#define FR_TYPE_INTEGER_EXCEPT_BOOL_DEF(_beg, _mid, _end)
All integer types except bool.
Definition: types.h:101
#define FR_TYPE_LEAF_DEF(_beg, _mid, _end)
Types which represent concrete values.
Definition: types.h:252
#define fr_type_is_leaf(_x)
Definition: types.h:372
#define FR_TYPE_STRUCTURAL_DEF(_beg, _mid, _end)
Match all non value types in case statements.
Definition: types.h:241
#define FR_TYPE_QUOTED_DEF(_beg, _mid, _end)
Types which should be wrapped in double quotes when printed.
Definition: types.h:203
#define FR_TYPE_INTEGER_DEF(_beg, _mid, _end)
Signed or unsigned integers.
Definition: types.h:121