The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
dict_validate.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 /** Validation framework to allow protocols to set custom validation rules
18  *
19  * @file src/lib/util/dict_validate.c
20  *
21  * @copyright 2019 The FreeRADIUS server project
22  */
23 RCSID("$Id: 312858ec7b631038798ee2c34ca4ced2a0ad3465 $")
24 
25 #include <freeradius-devel/util/dict_priv.h>
26 
27 /** Validate a set of flags
28  *
29  * @param[in] dict of protocol context we're operating in.
30  * If NULL the internal dictionary will be used.
31  * @param[in] parent to add attribute under.
32  * @param[in] name of the attribute.
33  * @param[in] attr number.
34  * @param[in] type of attribute.
35  * @param[in] flags to check in the attribute.
36  * @return
37  * - true if attribute definition is valid.
38  * - false if attribute definition is not valid.
39  */
41  char const *name, int *attr, fr_type_t type, fr_dict_attr_flags_t *flags)
42 {
43  int bit;
44  uint32_t all_flags;
45  uint32_t shift_is_root, shift_internal;
46  uint32_t shift_array, shift_has_value;
47  uint32_t shift_subtype, shift_extra;
48  uint32_t shift_counter;
49  fr_dict_attr_t const *v;
50 
51  /*
52  * Convert the 1-bit fields into bits numbers, so that we
53  * can check them in parallel.
54  */
55  all_flags = 0;
56  bit = -1;
57 
58 #define SET_FLAG(_flag) do { shift_ ## _flag = 1 << ++bit; if (flags->_flag) all_flags |= (1 << bit); } while (0)
59  SET_FLAG(is_root);
60  SET_FLAG(internal);
61  SET_FLAG(array);
62  SET_FLAG(has_value);
63  SET_FLAG(extra);
64  SET_FLAG(counter);
65  SET_FLAG(subtype);
66 
67 #define FORBID_OTHER_FLAGS(_flag) do { if (all_flags & ~shift_ ## _flag) { fr_strerror_printf("The '" STRINGIFY(_flag) "' flag cannot be used with any other flag"); return false; } } while (0)
68 #define ALLOW_FLAG(_flag) do { all_flags &= ~shift_ ## _flag; } while (0)
69 
70  // is_root
71  // is_unknown
72  // internal
73  // array
74  // has_value
75  // extra
76  // encrypt
77  // length
78  // type_size
79 
80  if (flags->is_root) {
81  FORBID_OTHER_FLAGS(is_root);
82  }
83 
84  if (flags->is_unknown) {
85  fr_strerror_const("The 'unknown' flag cannot be set for attributes in the dictionary.");
86  return false;
87  }
88 
89  /*
90  * Only some data types can be in arrays, because we need
91  * to be able to decode the various array members.
92  */
93  if (flags->array) {
94  if (!flags->is_known_width) switch (type) {
95  default:
96  fr_strerror_printf("The 'array' flag cannot be used with attributes of type '%s'",
98  return false;
99 
100  case FR_TYPE_IPV4_ADDR:
101  case FR_TYPE_IPV4_PREFIX:
102  case FR_TYPE_IPV6_ADDR:
103  case FR_TYPE_IPV6_PREFIX:
104  case FR_TYPE_UINT8:
105  case FR_TYPE_UINT16:
106  case FR_TYPE_UINT32:
107  case FR_TYPE_DATE:
108  case FR_TYPE_TIME_DELTA:
109  break;
110 
111  case FR_TYPE_STRING:
112  case FR_TYPE_OCTETS:
113  if (!flags->length) {
114  fr_strerror_const("Variable length attributes cannot be marked as 'array'");
115  return false;
116  }
117 
118  flags->is_known_width = 1;
119  break;
120 
121  case FR_TYPE_STRUCT:
122  /*
123  * If we have arrays of structs, then the structure MUST be known width.
124  */
125  flags->is_known_width = 1;
126  break;
127  }
128 
129  /*
130  * DHCPv6 has arrays of string / octets, prefixed
131  * with a uint16 field of "length". Also, arrays of dns_labels.
132  */
133  ALLOW_FLAG(extra);
134  ALLOW_FLAG(subtype);
135 
137  }
138 
139  /*
140  * 'has_value' should only be set internally. If the
141  * caller sets it, we still sanity check it.
142  */
143  if (flags->has_value) {
144  if (type != FR_TYPE_UINT32) {
145  fr_strerror_printf("The 'has_value' flag can only be used with attributes "
146  "of type 'integer'");
147  return false;
148  }
149 
150  FORBID_OTHER_FLAGS(has_value);
151  }
152 
153  /*
154  * The "extra" flag is a grab-bag of stuff, depending on
155  * the data type.
156  */
157  if (flags->extra) {
158  if ((flags->subtype != FLAG_KEY_FIELD) && (flags->subtype != FLAG_BIT_FIELD) &&
159  (flags->subtype != FLAG_LENGTH_UINT8) && (flags->subtype != FLAG_LENGTH_UINT16)) {
160  fr_strerror_const("The 'key' and 'length' flags cannot be used with any other flags.");
161  return false;
162  }
163 
164  switch (type) {
165  case FR_TYPE_BOOL:
166  case FR_TYPE_UINT8:
167  case FR_TYPE_UINT16:
168  case FR_TYPE_UINT32:
169  case FR_TYPE_UINT64:
170  if ((flags->subtype != FLAG_KEY_FIELD) && (flags->subtype != FLAG_BIT_FIELD)) {
171  fr_strerror_const("Invalid type (not 'key' field or 'bit' field) for extra flag.");
172  return false;
173  }
174 
175  if (parent->type != FR_TYPE_STRUCT) {
176  fr_strerror_const("The 'key' flag can only be used inside of a 'struct'.");
177  return false;
178  }
179 
180  ALLOW_FLAG(extra);
181  ALLOW_FLAG(subtype);
182  break;
183 
184  case FR_TYPE_OCTETS:
185  case FR_TYPE_STRING:
186  if (flags->length != 0) {
187  fr_strerror_const("Cannot use [..] and length=uint...");
188  return false;
189  }
190 
191  /*
192  * We can do arrays of variable-length types, so long as they have a "length="
193  * modifier.
194  *
195  * But any other modifier is foridden, including the use of "length=" outside of
196  * the context of arrays.
197  */
198  if (flags->array) {
199  ALLOW_FLAG(array);
200 
201  if ((flags->subtype != FLAG_LENGTH_UINT8) && (flags->subtype != FLAG_LENGTH_UINT16)) goto invalid_extra;
202  } else if (flags->subtype) {
203  invalid_extra:
204  fr_strerror_const("Invalid type (not 'length=...') for extra flag.");
205  return false;
206  }
207 
208  ALLOW_FLAG(extra);
209  ALLOW_FLAG(subtype);
210  break;
211 
212  case FR_TYPE_STRUCT:
213  if ((flags->subtype != FLAG_LENGTH_UINT8) && (flags->subtype != FLAG_LENGTH_UINT16)) {
214  fr_strerror_const("Invalid type (not 'length=...') for extra flag.");
215  return false;
216  }
217 
218  ALLOW_FLAG(extra);
219  ALLOW_FLAG(subtype);
220  ALLOW_FLAG(array);
221  break;
222 
223  case FR_TYPE_TLV:
224  ALLOW_FLAG(extra);
225  /* @todo - allow arrays of struct? */
226  ALLOW_FLAG(subtype);
227  break;
228 
229  default:
230  fr_strerror_printf("Type %s cannot hold extra flags",
232  return false;
233  }
234 
235  if (((flags->subtype == FLAG_LENGTH_UINT8) || (flags->subtype == FLAG_LENGTH_UINT16)) &&
236  ((type != FR_TYPE_STRING) && (type != FR_TYPE_OCTETS) && (type != FR_TYPE_STRUCT))) {
237  fr_strerror_printf("The 'length' flag cannot be used used with type %s",
239  return false;
240  }
241 
242  FORBID_OTHER_FLAGS(extra);
243  }
244 
245  /*
246  * Force "length" for fixed-size data types which aren't
247  * bit fields. Check / set "length" and "type_size" for
248  * other types.
249  */
250  if (!flags->extra || (flags->subtype != FLAG_BIT_FIELD)) switch (type) {
251  case FR_TYPE_UINT8:
252  case FR_TYPE_BOOL:
253  flags->length = 1;
254  break;
255 
256  case FR_TYPE_UINT16:
257  flags->length = 2;
258  break;
259 
260  case FR_TYPE_DATE:
261  case FR_TYPE_TIME_DELTA:
262  if (!flags->length) flags->length = 4;
263 
264  if ((flags->length != 2) && (flags->length != 4) && (flags->length != 8)) {
265  fr_strerror_printf("Invalid length %u for attribute of type '%s'",
266  flags->length, fr_type_to_str(type));
267  return false;
268  }
269  break;
270 
271  case FR_TYPE_IPV4_ADDR:
272  case FR_TYPE_UINT32:
273  case FR_TYPE_INT32:
274  case FR_TYPE_FLOAT32:
275  flags->length = 4;
276  break;
277 
278  case FR_TYPE_UINT64:
279  case FR_TYPE_FLOAT64:
280  flags->length = 8;
281  break;
282 
283  case FR_TYPE_SIZE:
284  flags->length = sizeof(size_t);
285  break;
286 
287  case FR_TYPE_ETHERNET:
288  flags->length = 6;
289  break;
290 
291  case FR_TYPE_IFID:
292  flags->length = 8;
293  break;
294 
295  case FR_TYPE_IPV6_ADDR:
297  flags->length = 16;
298  break;
299 
300  case FR_TYPE_IPV6_PREFIX:
302  flags->length = 17;
303  break;
304 
305  case FR_TYPE_STRUCT:
306  ALLOW_FLAG(internal);
307  ALLOW_FLAG(array);
308  if (all_flags) {
309  fr_strerror_const("Invalid flag for attribute of type 'struct'");
310  return false;
311  }
312  break;
313 
314  case FR_TYPE_VENDOR:
315  if (parent->type != FR_TYPE_VSA) {
316  fr_strerror_printf("Attributes of type 'vendor' MUST have a parent of type 'vsa' "
317  "instead of '%s'",
318  fr_type_to_str(parent->type));
319  return false;
320  }
321 
322  if (flags->length) {
323  if ((flags->length != 1) &&
324  (flags->length != 2) &&
325  (flags->length != 4)) {
326  fr_strerror_const("The 'length' flag can only be used for attributes of type 'vendor' with lengths of 1,2 or 4");
327  return false;
328  }
329 
330  break;
331  }
332 
333  /*
334  * Set the length / type_size of vendor
335  * attributes from the vendor definition.
336  */
337  flags->type_size = 1;
338  flags->length = 1;
339  if (attr) {
340  fr_dict_vendor_t const *dv;
341 
342  dv = fr_dict_vendor_by_num(dict, *attr);
343  if (dv) {
344  flags->type_size = dv->type;
345  flags->length = dv->length;
346  }
347  }
348  break;
349 
350  case FR_TYPE_TLV:
351  if (flags->length) {
352  if ((flags->length != 1) &&
353  (flags->length != 2) &&
354  (flags->length != 4)) {
355  fr_strerror_const("The 'length' flag can only be used for attributes of type 'tlv' with lengths of 1,2 or 4");
356  return false;
357  }
358 
359  break;
360  }
361 
362  /*
363  * Find an appropriate parent to copy the
364  * TLV-specific fields from.
365  */
366  for (v = parent; v != NULL; v = v->parent) {
367  if ((v->type == FR_TYPE_TLV) || (v->type == FR_TYPE_VENDOR)) {
368  break;
369  }
370  }
371 
372  /*
373  * root is always FR_TYPE_TLV, so we're OK.
374  */
375  if (!v) {
376  fr_strerror_printf("Attributes of type '%s' require a parent attribute",
378  return false;
379  }
380 
381  /*
382  * Over-ride whatever was there before, so we
383  * don't have multiple formats of VSAs.
384  */
385  flags->type_size = v->flags.type_size;
386  flags->length = v->flags.length;
387  break;
388 
389  /*
390  * 'octets[n]' can only be used in a few limited situations.
391  */
392  case FR_TYPE_OCTETS:
393  if (flags->length) {
394  /*
395  * Internal attributes can use octets[n]
396  * MS-MPPE-Keys use octets[18],encrypt=1
397  * EAP-SIM-RAND uses array
398  */
399  ALLOW_FLAG(internal);
400  ALLOW_FLAG(subtype);
401  ALLOW_FLAG(array);
402 
403  if (all_flags) {
404  fr_strerror_const("The 'octets[...]' syntax cannot be used any other flag");
405  return false;
406  }
407 
408  if (flags->length > 253) {
409  fr_strerror_printf("Invalid length %d", flags->length);
410  return false;
411  }
412  }
413  break;
414 
415  case FR_TYPE_NULL:
416  fr_strerror_printf("Attributes of type '%s' cannot be used in dictionaries",
418  return false;
419 
420  default:
421  break;
422  }
423 
424  /*
425  * type_size is used to limit the maximum attribute number, so it's checked first.
426  */
427  if (flags->type_size) {
428  if ((type == FR_TYPE_DATE) || (type == FR_TYPE_TIME_DELTA)) {
429  /*
430  * Allow all time res here
431  */
432  } else if (!flags->extra) {
433  if ((type != FR_TYPE_TLV) && (type != FR_TYPE_VENDOR)) {
434  fr_strerror_const("The 'format=' flag can only be used with attributes of type 'tlv'");
435  return false;
436  }
437 
438  if ((flags->type_size != 1) &&
439  (flags->type_size != 2) &&
440  (flags->type_size != 4)) {
441  fr_strerror_const("The 'format=' flag can only be used with attributes of type size 1,2 or 4");
442  return false;
443  }
444  }
445  }
446 
447  /*
448  * Counters can be time deltas, or unsigned integers.
449  * For other data types, we don't know how to
450  * automatically add two counters.
451  */
452  if (flags->counter) {
454  ALLOW_FLAG(counter);
455  } else {
456  fr_strerror_printf("The 'counter' flag cannot be used with '%s'", fr_type_to_str(type));
457  return false;
458  }
459  }
460 
461  /*
462  * Check flags against the parent attribute.
463  */
464  switch (parent->type) {
465  case FR_TYPE_STRUCT:
466  ALLOW_FLAG(extra);
467  ALLOW_FLAG(subtype);
468 
469  if (parent->flags.is_known_width && !flags->is_known_width && !flags->length) {
470  fr_strerror_const("Variable-sized fields cannot be used within a 'struct' which is 'array'");
471  return false;
472  }
473 
474  if (flags->array) {
475  switch (type) {
476  case FR_TYPE_FIXED_SIZE:
477  ALLOW_FLAG(array);
478  break;
479 
480  default:
481  if (flags->is_known_width) ALLOW_FLAG(array);
482  break;
483  }
484  }
485 
486  if (all_flags) {
487  fr_strerror_const("Invalid flag for attribute inside of a 'struct'");
488  return false;
489  }
490 
491  if (!attr) break;
492 
493  /*
494  * If we have keyed structs, then the first
495  * member can be variable length.
496  *
497  * For subsequent children, have each one check
498  * the previous child.
499  */
500  if (*attr != 1) {
501  int i;
502  fr_dict_attr_t const *sibling;
503 
504  sibling = fr_dict_attr_child_by_num(parent, (*attr) - 1);
505  if (!sibling) {
506  fr_strerror_printf("Child \"%s\" of 'struct' attribute \"%s\" MUST be "
507  "numbered consecutively %u.",
508  name, parent->name, *attr);
509  return false;
510  }
511 
512  /*
513  * Variable sized elements cannot have anything after them in a struct.
514  */
515  if (!sibling->flags.length && !sibling->flags.is_known_width) {
516  fr_strerror_const("No other field can follow a struct MEMBER which is variable sized");
517  return false;
518  }
519 
520  /*
521  * The same goes for arrays.
522  */
523  if (sibling->flags.array) {
524  fr_strerror_const("No other field can follow a struct MEMBER which is 'array'");
525  return false;
526  }
527 
528  /*
529  * Check for bad key fields, or multiple
530  * key fields. Yes, this is O(N^2), but
531  * the structs are small.
532  */
533  if (flags->extra && (flags->subtype == FLAG_KEY_FIELD)) {
534  for (i = 1; i < *attr; i++) {
535  sibling = fr_dict_attr_child_by_num(parent, i);
536  if (!sibling) {
537  fr_strerror_printf("Child %d of 'struct' type attribute %s does not exist.",
538  i, parent->name);
539  return false;
540  }
541 
542  if (!fr_dict_attr_is_key_field(sibling)) continue;
543 
544  fr_strerror_printf("Duplicate key attributes '%s' and '%s' in 'struct' type attribute %s are forbidden",
545  name, sibling->name, parent->name);
546  return false;
547  }
548  }
549  }
550  break;
551 
552  case FR_TYPE_VSA:
553  if ((type != FR_TYPE_VENDOR) && !flags->internal) {
554  fr_strerror_printf("Attributes of type '%s' cannot be children of the 'vsa' type",
556  return false;
557  }
558  break;
559 
560  case FR_TYPE_TLV:
561  case FR_TYPE_VENDOR:
562  break;
563 
564  /*
565  * "key" fields inside of a STRUCT can have
566  * children, even if they are integer data type.
567  */
568  case FR_TYPE_UINT8:
569  case FR_TYPE_UINT16:
570  case FR_TYPE_UINT32:
571  if (fr_dict_attr_is_key_field(parent)) break;
572  FALL_THROUGH;
573 
574  default:
575  fr_strerror_printf("Attributes of type '%s' cannot have child attributes",
576  fr_type_to_str(parent->type));
577  return false;
578  }
579 
580  return true;
581 }
582 
583 
584 /** Validate a new attribute definition
585  *
586  * @todo we need to check length of none vendor attributes.
587  *
588  * @param[in] dict of protocol context we're operating in.
589  * If NULL the internal dictionary will be used.
590  * @param[in] parent to add attribute under.
591  * @param[in] name of the attribute.
592  * @param[in] attr number.
593  * @param[in] type of attribute.
594  * @param[in] flags to set in the attribute.
595  * @return
596  * - true if attribute definition is valid.
597  * - false if attribute definition is not valid.
598  */
600  char const *name, int *attr, fr_type_t type, fr_dict_attr_flags_t *flags)
601 {
602  fr_dict_attr_t const *v;
603  fr_dict_attr_t *mutable;
604 
605  if (!fr_cond_assert(parent)) return false;
606 
607  if (fr_dict_valid_name(name, -1) <= 0) return false;
608 
609  mutable = UNCONST(fr_dict_attr_t *, parent);
610 
611  /******************** sanity check attribute number ********************/
612 
613  /*
614  * The value -1 is the special flag for "self
615  * allocated" numbers. i.e. we want an
616  * attribute, but we don't care what the number
617  * is.
618  */
619  if (*attr == -1) {
620  /*
621  * If we don't care about the number, then this attribute is almost always
622  * an internal one. Unless it's a "name only" attribute for string-based
623  * protocols.
624  *
625  * We can use DEFINE in number-based protocol dictionaries, and the attributes will be
626  * marked up as "internal".
627  */
628  flags->internal |= !flags->name_only | !dict->string_based;
629 
630  v = fr_dict_attr_by_name(NULL, parent, name);
631  if (v) {
633 
634  /*
635  * Exact duplicates are allowed. The caller will take care of
636  * not inserting the duplicate attribute.
637  */
638  if (v->type != type) {
639  fr_strerror_printf("Conflicting type (asked %s, found %s) for re-definition for attribute %s",
640  fr_type_to_str(type), fr_type_to_str(v->type), name);
641  return false;
642  }
643 
644  /*
645  * 'has_value' is set if we define VALUEs for it. But the new definition doesn't
646  * know that yet.
647  */
648  cmp = v->flags;
649  cmp.has_value = 0;
650 
651  if (memcmp(&cmp, flags, sizeof(*flags)) != 0) {
652  fr_strerror_printf("Conflicting flags for re-definition for attribute %s", name);
653  return false;
654  }
655 
656  return true;
657  }
658 
659  *attr = ++mutable->last_child_attr;
660 
661  } else if (*attr < 0) {
662  fr_strerror_printf("ATTRIBUTE number %i is invalid, must be greater than zero", *attr);
663  return false;
664 
665  } else if ((unsigned int) *attr > mutable->last_child_attr) {
666  mutable->last_child_attr = *attr;
667 
668  /*
669  * If the attribute is outside of the bounds of
670  * the type size, then it MUST be an internal
671  * attribute. Set the flag in this attribute, so
672  * that the encoder doesn't have to do complex
673  * checks.
674  */
675  if ((uint64_t) *attr >= (((uint64_t)1) << (8 * parent->flags.type_size))) flags->internal = true;
676  }
677 
678  /*
679  * Initialize the length field, which is needed for the attr_valid() callback.
680  */
682  fr_value_box_t box;
683 
684  fr_value_box_init(&box, type, NULL, false);
685  flags->length = fr_value_box_network_length(&box);
686  }
687 
688  if (type == FR_TYPE_STRUCT) flags->is_known_width |= flags->array;
689 
690  /*
691  * Run protocol-specific validation functions, BEFORE we
692  * do the rest of the checks.
693  */
694  if (dict->attr_valid && !dict->attr_valid(dict, parent, name, *attr, type, flags)) return false;
695 
696  /*
697  * Check the flags, data types, and parent data types and flags.
698  */
699  if (!dict_attr_flags_valid(dict, parent, name, attr, type, flags)) return false;
700 
701  return true;
702 }
static fr_dict_t * dict
Definition: fuzzer.c:46
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition: build.h:165
#define RCSID(id)
Definition: build.h:444
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
Definition: build.h:320
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition: debug.h:137
size_t type
Length of type data.
Definition: dict.h:230
unsigned int name_only
this attribute should always be referred to by name, not by number
Definition: dict.h:98
unsigned int has_value
Has a value.
Definition: dict.h:92
fr_dict_vendor_t const * fr_dict_vendor_by_num(fr_dict_t const *dict, uint32_t vendor_pen)
Look up a vendor by its PEN.
Definition: dict_util.c:2277
unsigned int is_root
Is root of a dictionary.
Definition: dict.h:74
@ FLAG_LENGTH_UINT8
string / octets type is prefixed by uint8 of length
Definition: dict.h:145
@ FLAG_LENGTH_UINT16
string / octets type is prefixed by uint16 of length
Definition: dict.h:146
@ FLAG_KEY_FIELD
this is a key field for a subsequent struct
Definition: dict.h:143
@ FLAG_BIT_FIELD
bit field inside of a struct
Definition: dict.h:144
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
unsigned int array
Pack multiples into 1 attr.
Definition: dict.h:88
unsigned int extra
really "subtype is used by dict, not by protocol"
Definition: dict.h:109
unsigned int internal
Internal attribute, should not be received in protocol packets, should not be encoded.
Definition: dict.h:86
uint8_t type_size
For TLV2 and root attributes.
Definition: dict.h:132
size_t length
Length of length data.
Definition: dict.h:231
unsigned int is_known_width
is treated as if it has a known width for structs
Definition: dict.h:90
ssize_t fr_dict_valid_name(char const *name, ssize_t len)
Definition: dict_util.c:4214
fr_dict_attr_t const * fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr)
Check if a child attribute exists in a parent using an attribute number.
Definition: dict_util.c:2925
#define fr_dict_attr_is_key_field(_da)
Definition: dict.h:149
uint8_t subtype
protocol-specific values, OR key fields
Definition: dict.h:118
uint8_t length
length of the attribute
Definition: dict.h:124
unsigned int counter
integer attribute is actually an impulse / counter
Definition: dict.h:96
unsigned int is_unknown
This dictionary attribute is ephemeral and not part of the main dictionary.
Definition: dict.h:76
Values of the encryption flags.
Definition: merged_model.c:139
Private enterprise.
Definition: dict.h:227
bool dict_attr_flags_valid(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, int *attr, fr_type_t type, fr_dict_attr_flags_t *flags)
Validate a set of flags.
Definition: dict_validate.c:40
#define ALLOW_FLAG(_flag)
#define SET_FLAG(_flag)
#define FORBID_OTHER_FLAGS(_flag)
bool dict_attr_fields_valid(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, int *attr, fr_type_t type, fr_dict_attr_flags_t *flags)
Validate a new attribute definition.
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_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_NULL
Invalid (uninitialised) attribute type.
Definition: merged_model.c:81
@ FR_TYPE_UINT16
16 Bit unsigned integer.
Definition: merged_model.c:98
@ 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_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_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_FLOAT64
Double precision floating point.
Definition: merged_model.c:109
unsigned int uint32_t
Definition: merged_model.c:33
unsigned long int size_t
Definition: merged_model.c:25
static size_t array[MY_ARRAY_SIZE]
static char const * name
fr_aka_sim_id_type_t type
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_strerror_const(_msg)
Definition: strerror.h:223
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_is_variable_size(_x)
Definition: types.h:367
#define fr_type_is_signed(_x)
Definition: types.h:362
#define fr_type_is_leaf(_x)
Definition: types.h:372
#define fr_type_is_integer(_x)
Definition: types.h:360
#define FR_TYPE_FIXED_SIZE
Definition: types.h:290
size_t fr_value_box_network_length(fr_value_box_t const *value)
Get the size of the value held by the fr_value_box_t.
Definition: value.c:1280
#define fr_value_box_init(_vb, _type, _enumv, _tainted)
Initialise a fr_value_box_t.
Definition: value.h:574