22 RCSID(
"$Id: af14c46e0d104472a393f8602663ea3f5f65f862 $")
24 #include <freeradius-devel/libradius.h>
27 # include <freeradius-devel/dhcp.h>
32 #ifdef HAVE_SYS_STAT_H
33 # include <sys/stat.h>
147 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
148 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
149 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
150 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
151 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
152 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
153 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
154 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
155 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
156 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
157 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
158 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
159 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
160 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
161 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
162 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
170 #define FNV_MAGIC_INIT (0x811c9dc5)
171 #define FNV_MAGIC_PRIME (0x01000193)
173 #ifdef __clang_analyzer__
174 # define INTERNAL_IF_NULL(_dict) do {\
175 if (!_dict) _dict = fr_dict_internal; \
176 if (!_dict) return NULL; \
179 # define INTERNAL_IF_NULL(_dict) if (!_dict) _dict = fr_dict_internal
192 talloc_free(to_free);
200 for (p = name; *p !=
'\0'; p++) {
201 int c = *(
unsigned char const *)p;
202 if (isalpha(c)) c = tolower(c);
205 hash ^= (uint32_t)(c & 0xff);
293 rcode = a->
da - b->
da;
294 if (rcode != 0)
return rcode;
314 rcode = a->
da - b->
da;
315 if (rcode != 0)
return rcode;
329 memcpy(&(this->stat_buf), stat_buf,
sizeof(this->stat_buf));
343 struct stat stat_buf;
355 snprintf(buffer,
sizeof(buffer),
"%s/%s", dir, file);
356 if (stat(buffer, &stat_buf) < 0)
return 0;
365 for (
this = dict->
stat_head;
this != NULL;
this = this->
next) {
366 if (this->stat_buf.st_dev != stat_buf.st_dev)
continue;
367 if (this->stat_buf.st_ino != stat_buf.st_ino)
continue;
372 if (this->stat_buf.st_mtime < stat_buf.st_mtime)
return 0;
418 strcpy(dv->
name, name);
502 bool child_is_struct =
false;
503 bool bin_is_struct =
false;
511 switch (child->
type) {
513 child_is_struct =
true;
520 switch ((*bin)->type) {
522 bin_is_struct =
true;
529 if (child_is_struct && !bin_is_struct)
break;
530 else if (child->
vendor <= (*bin)->vendor)
break;
531 else if (child->
attr <= (*bin)->attr)
break;
536 memcpy(&
this, &bin,
sizeof(
this));
544 char const *
name,
unsigned int vendor,
int attr,
548 size_t namelen = strlen(name);
550 da = (
fr_dict_attr_t *)talloc_zero_array(ctx, uint8_t,
sizeof(*da) + namelen);
557 memcpy(da->
name, name, namelen);
558 da->
name[namelen] =
'\0';
594 namelen = strlen(name);
609 fr_strerror_printf(
"The 'format=' flag can only be used with attributes of type 'tlv'");
616 fr_strerror_printf(
"The 'format=' flag can only be used with attributes of type size 1,2 or 4");
624 static unsigned int max_attr = UINT8_MAX + 1;
631 }
else if (attr <= 0) {
632 fr_strerror_printf(
"ATTRIBUTE number %i is invalid, must be greater than zero", attr);
635 }
else if ((
unsigned int) attr > max_attr) {
645 (attr >= 3000) && (attr < 4000)) {
654 fr_strerror_printf(
"ATTRIBUTE number %i is invalid, must be greater than zero", attr);
665 if ((attr > UINT8_MAX) && !flags.
internal) {
666 if (parent->
flags.
is_root && ((attr >= 0x2b00) && (attr < 0x2d00))) {
670 for (v = parent; v != NULL; v = v->
parent) {
695 fr_strerror_printf(
"The 'virtual' flag can only be used for non-protocol attributes");
705 fr_strerror_printf(
"The 'has_tag' flag can only be used for attributes of type 'integer' "
713 fr_strerror_printf(
"The 'has_tag' flag can only be used with RFC and VSA attributes");
723 if (flags.
encrypt && (flags.
encrypt != FLAG_ENCRYPT_TUNNEL_PASSWORD)) {
734 fr_strerror_printf(
"The 'concat' flag can only be used for attributes of type 'octets'");
765 if ((flags.
length != 1) &&
768 fr_strerror_printf(
"The 'length' flag can only be used with attributes of TLV lengths of 1,2 or 4");
773 fr_strerror_printf(
"The 'length' flag can only be set for attributes of type 'octets'");
784 for (v = parent; v != NULL; v = v->
parent) {
787 if ((v->
attr != 34673) &&
798 fr_int2str(dict_attr_types, type,
"<UNKNOWN>"));
824 "of type 'integer'");
828 if (flags.
encrypt || flags.virtual) {
846 "attributes of type 'string'");
852 "'octets' data types");
857 if (flags.
encrypt > FLAG_ENCRYPT_ASCEND_SECRET) {
866 fr_int2str(dict_attr_types, type,
"<UNKNOWN>"));
872 if (flags.
encrypt == FLAG_ENCRYPT_ASCEND_SECRET)
goto encrypt_fail;
893 fr_int2str(dict_attr_types, type,
"?Unknown?"));
904 "instead of '%s'",
fr_int2str(dict_attr_types, parent->
type,
"?Unknown?"));
912 "'evs', instead of '%s'",
938 for (v = parent; v != NULL; v = v->
parent) {
949 fr_int2str(dict_attr_types, type,
"?Unknown?"));
965 for (v = parent; v != NULL; v = v->
parent) {
973 fr_int2str(dict_attr_types, type,
"?Unknown?"));
984 fr_int2str(dict_attr_types, type,
"?Unknown?"));
1029 "RFC attributes with value >= 241.");
1038 "be RFC attributes with value >= 241.");
1046 if (attr != PW_VENDOR_SPECIFIC) {
1047 fr_strerror_printf(
"Attributes of type 'evs' MUST have attribute code 26, got %i", attr);
1068 vendor = parent->
attr;
1112 v4 = (
fr_dict_attr_t *)talloc_zero_array(dict->
pool, uint8_t,
sizeof(*v4) + namelen);
1116 v6 = (
fr_dict_attr_t *)talloc_zero_array(dict->
pool, uint8_t,
sizeof(*v6) + namelen);
1120 memcpy(v4, n,
sizeof(*v4) + namelen);
1123 memcpy(v6, n,
sizeof(*v6) + namelen);
1142 memcpy(&
mutable, &parent,
sizeof(
mutable));
1180 strcpy(dval->
name, alias);
1181 dval->
value = value;
1209 if (value > UINT8_MAX) {
1212 "VALUEs larger than %i", UINT8_MAX);
1217 if (value > UINT16_MAX) {
1220 "VALUEs larger than %i", UINT16_MAX);
1230 fr_strerror_printf(
"fr_dict_enum_add: VALUEs cannot be defined for attributes of type '%s'",
1243 memset(fixup, 0,
sizeof(*fixup));
1262 memcpy(&tmp, &dval,
sizeof(tmp));
1281 fr_strerror_printf(
"fr_dict_enum_add: Duplicate value name %s for attribute %s", alias,
1309 if (argc >= max_argc)
break;
1319 while ((*str ==
' ') ||
1345 static char const *tab =
"0123456789";
1347 if ((str[0] ==
'0') &&
1348 ((str[1] ==
'x') || (str[1] ==
'X'))) {
1349 tab =
"0123456789abcdef";
1358 if (*str ==
'.')
break;
1360 c = memchr(tab, tolower((
int)*str), base);
1376 unsigned int block_vendor,
char **argv,
int argc)
1380 unsigned int vendor = 0;
1388 if ((argc < 3) || (argc > 4)) {
1396 if (strncmp(argv[0],
"Attr-", 5) == 0) {
1401 memset(&flags, 0,
sizeof(flags));
1406 if (!strchr(argv[1],
'.')) {
1423 vendor = block_vendor;
1432 block_vendor = vendor;
1435 if (strncmp(argv[2],
"octets[", 7) != 0) {
1439 type =
fr_str2int(dict_attr_types, argv[2], -1);
1448 p = strchr(argv[2] + 7,
']');
1461 if ((length == 0) || (length > 253)) {
1473 char *key, *next, *last;
1477 next = strchr(key,
',');
1478 if (next) *(next++) =
'\0';
1484 if ((strcmp(key,
"has_tag") == 0) || (strcmp(key,
"has_tag=1") == 0)) {
1493 }
else if (strncmp(key,
"encrypt=", 8) == 0) {
1494 flags.
encrypt = strtol(key + 8, &last, 0);
1506 }
else if (strncmp(key,
"internal", 9) == 0) {
1509 }
else if (strncmp(key,
"array", 6) == 0) {
1512 }
else if (strncmp(key,
"concat", 7) == 0) {
1515 }
else if (strncmp(key,
"virtual", 8) == 0) {
1522 }
else if ((key == argv[3]) && !next) {
1534 if (!vendor)
goto unknown;
1544 if (key && !*key)
break;
1548 if (block_vendor) vendor = block_vendor;
1550 #ifdef WITH_DICTIONARY_WARNINGS
1555 if (!vendor && (attr < 256) &&
1556 !strstr(fn,
"rfc") && !strstr(fn,
"illegal")) {
1557 fprintf(stderr,
"WARNING: Illegal Attribute %s in %s\n",
1598 bool *pcontinuation)
1602 bool continuation =
false;
1611 if ((strlen(p) < 3) ||
1612 !isdigit((
int)p[0]) ||
1614 !isdigit((
int)p[2]) ||
1615 (p[3] && (p[3] !=
','))) {
1621 type = (int)(p[0] -
'0');
1622 length = (int)(p[2] -
'0');
1624 if ((type != 1) && (type != 2) && (type != 4)) {
1629 if ((length != 0) && (length != 1) && (length != 2)) {
1641 if ((p[4] !=
'c') ||
1647 continuation =
true;
1650 (type != 1) || (length != 1)) {
1658 *pcontinuation = continuation;
1669 bool continuation =
false;
1673 if ((argc < 2) || (argc > 3)) {
1699 }
else if (value == VENDORPEC_USR) {
1703 }
else if (value == VENDORPEC_LUCENT) {
1707 }
else if (value == VENDORPEC_STARENT) {
1721 memcpy(&
mutable, &dv,
sizeof(
mutable));
1723 mutable->type = type;
1724 mutable->length =
length;
1725 mutable->flags = continuation;
1734 char const *src_file,
int src_line)
1737 char dir[256], fn[256];
1741 unsigned int vendor;
1742 unsigned int block_vendor;
1743 struct stat statbuf;
1747 int block_tlv_depth = 0;
1751 if ((strlen(dir_name) + 3 + strlen(filename)) >
sizeof(dir)) {
1763 if (!FR_DIR_IS_RELATIVE(filename)) {
1764 strlcpy(dir, filename,
sizeof(dir));
1765 p = strrchr(dir, FR_DIR_SEP);
1769 strlcat(dir,
"/",
sizeof(dir));
1772 strlcpy(fn, filename,
sizeof(fn));
1774 strlcpy(dir, dir_name,
sizeof(dir));
1775 p = strrchr(dir, FR_DIR_SEP);
1777 if (p[1])
strlcat(dir,
"/",
sizeof(dir));
1779 strlcat(dir,
"/",
sizeof(dir));
1781 strlcat(dir, filename,
sizeof(dir));
1782 p = strrchr(dir, FR_DIR_SEP);
1786 strlcat(dir,
"/",
sizeof(dir));
1789 p = strrchr(filename, FR_DIR_SEP);
1791 snprintf(fn,
sizeof(fn),
"%s%s", dir, p);
1793 snprintf(fn,
sizeof(fn),
"%s%s", dir, filename);
1800 p = strrchr(fn, FR_DIR_SEP);
1810 if ((fp = fopen(fn,
"r")) == NULL) {
1824 if (stat(fn, &statbuf) < 0) {
1829 if (!S_ISREG(statbuf.st_mode)) {
1840 if ((statbuf.st_mode & S_IWOTH) != 0) {
1842 fr_strerror_printf(
"fr_dict_init: Dictionary '%s' is globally writable. Refusing to start "
1843 "due to insecure configuration", fn);
1857 while (fgets(buf,
sizeof(buf), fp) != NULL) {
1872 p = strchr(buf,
'#');
1876 if (argc == 0)
continue;
1900 argv + 1, argc - 1) == -1)
goto error;
1908 if (
dict_read_init(dict, dir, argv[1], fn, line) < 0)
goto error;
1923 if (rcode < 0)
goto error;
1968 block_tlv[block_tlv_depth++] = parent;
1974 if (--block_tlv_depth < 0) {
1995 parent = block_tlv[block_tlv_depth];
1999 if (
strcasecmp(argv[0],
"BEGIN-VENDOR") == 0) {
2023 if (strncmp(argv[2],
"format=", 7) != 0) {
2038 "be 'evs' but is '%s'", p,
2054 memset(&flags, 0,
sizeof(flags));
2056 memcpy(&
mutable, &parent,
sizeof(
mutable));
2070 memset(&flags, 0,
sizeof(flags));
2090 memcpy(&
mutable, &vsa_da,
sizeof(
mutable));
2096 block_vendor = vendor;
2100 if (
strcasecmp(argv[0],
"END-VENDOR") == 0) {
2112 if (vendor != block_vendor) {
2117 parent = dict->
root;
2155 dict->
pool = talloc_pool(dict, (1024 * 1024 * 5));
2164 if (*out == fr_dict_internal) fr_dict_internal = dict;
2170 if (!fr_dict_internal) fr_dict_internal = dict;
2233 for (
this = dict->
value_fixup;
this != NULL;
this = next) {
2239 this->attrstr, this->dval->name);
2250 this->dval->name, a->
name);
2286 if (out) *out = dict;
2314 if (argc == 0)
return 0;
2355 parent = new_parent;
2361 new->flags.is_unknown = 1;
2362 new->parent = parent;
2368 if (new_parent) talloc_steal(
new, parent);
2390 if (!old)
return NULL;
2404 memcpy(&flags, &old->
flags,
sizeof(flags));
2430 if (!da || !*da)
return;
2433 if (!(*da)->flags.is_unknown) {
2437 memcpy(&tmp, &da,
sizeof(*tmp));
2468 memset(&flags, 0,
sizeof(flags));
2476 switch (parent->
type) {
2495 if (parent->
attr == vendor) {
2504 "attributes, not '%s'",
fr_int2str(dict_attr_types, parent->
type,
"?Unknown?"));
2509 new->parent = parent;
2529 char *p = buffer, *end = p + outlen;
2537 depth = ancestor->
depth - 1;
2538 if (tlv_stack[depth] != ancestor) {
2544 len =
snprintf(p, end - p,
"%u", tlv_stack[depth]->attr);
2545 if ((p + len) >= end)
return p - buffer;
2548 for (i = depth + 1; i < (int)da->
depth; i++) {
2549 len =
snprintf(p, end - p,
".%u", tlv_stack[i]->attr);
2550 if ((p + len) >= end)
return p - buffer;
2590 len =
snprintf(p, bufsize,
"Attr-");
2614 unsigned int vendor,
unsigned int attr)
2636 parent = new_parent;
2645 parent = new_parent;
2673 if (new_parent && new_parent->
flags.
is_unknown) talloc_steal(da, new_parent);
2708 unsigned int attr, vendor = 0;
2711 char const *p =
name;
2721 if (vendor_da) memset(vendor_da, 0,
sizeof(*vendor_da));
2722 if (da) memset(da, 0,
sizeof(*da));
2729 num = strtoul(p + 7, &q, 10);
2730 if (!num || (num >= UINT_MAX)) {
2750 if ((
size_t)(q - p) >=
sizeof(buffer)) {
2756 memcpy(buffer, p, (q - p));
2757 buffer[q - p] =
'\0';
2794 fr_strerror_printf(
"Invalid text following vendor definition in attribute name '%s'", name);
2810 num = strtoul(p + 5, &q, 10);
2811 if (!num || (num >= UINT_MAX)) {
2828 if (((vendor != 0) && (*p !=
'\0')) ||
2829 ((vendor == 0) && *p && (*p !=
'.'))) {
2851 switch (child->
type) {
2861 num = strtoul(p + 1, &q, 10);
2862 if (!num || (num >= UINT_MAX)) {
2869 if (*q !=
'.')
goto invalid;
2902 }
else if (vendor_da) {
2903 vendor_da->
attr = vendor;
2905 vendor_da->
parent = parent;
2919 if (*p ==
'.')
if (
fr_dict_attr_by_oid(dict, &parent, &vendor, &attr, p + 1) < 0)
return -1;
3041 if (!name || !*name)
return -1;
3048 for (p = *name; fr_dict_attr_allowed_chars[(int)*p] || (*p ==
'.') || (*p ==
'-'); p++);
3059 strlcpy(buffer, *name, len + 1);
3070 char *p = out, *end = p + outlen;
3075 #define FLAG_SET(_flag) \
3078 p += strlcpy(p, STRINGIFY(_flag)",", end - p);\
3079 if (p >= end) return;\
3096 if (p >= end)
return;
3101 if (p >= end)
return;
3104 if (!out[0])
return;
3110 if (out[len - 1] ==
',') out[len - 1] =
'\0';
3143 name =
"LONG EXTENDED";
3151 printf(
"%u%.*s%s \"%s\" vendor: %x (%u), num: %x (%u), type: %s, flags: %s\n", da->
depth, depth,
3152 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t", name, da->
name,
3156 if (da->
children)
for (i = 0; i < talloc_array_length(da->
children); i++) {
3179 if (!a || !b)
return NULL;
3183 if (is_ancestor && (b->
depth <= a->
depth))
return NULL;
3190 for (p_a = a, i = a->
depth - b->
depth; p_a && (i > 0); p_a = p_a->
parent, i--);
3193 for (p_b = b, i = b->
depth - a->
depth; p_b && (i > 0); p_b = p_b->
parent, i--);
3199 while (p_a && p_b) {
3200 if (p_a == p_b)
return p_a;
3219 char const *p = *oid;
3225 num = strtoul(p, &q, 10);
3226 if ((p == q) || (num == ULONG_MAX)) {
3235 *out = (
unsigned int)num;
3264 unsigned int *vendor,
unsigned int *attr,
char const *oid)
3266 char const *p = oid;
3267 unsigned int num = 0;
3294 if (((*parent)->flags.is_root) && !*vendor && (num == PW_VENDOR_SPECIFIC)) {
3321 if (slen <= 0)
return slen - (p - oid);
3360 if (slen <= 0)
return slen - (p - oid);
3361 return slen + (p - oid);
3391 if (!name)
return 0;
3453 if (!name || !*name)
return NULL;
3462 for (p = *name; fr_dict_attr_allowed_chars[(int)*p]; p++);
3498 if (!name)
return NULL;
3528 if (!parent)
return NULL;
3531 if (!parent)
return NULL;
3574 if (!parent->
children)
return NULL;
3579 switch (parent->
type) {
3591 if ((child->
attr & 0xff) > talloc_array_length(parent->
children))
return NULL;
3595 if (!bin)
return NULL;
3596 if (bin == child)
return bin;
3615 if (!parent->
children)
return NULL;
3620 switch (parent->
type) {
3632 if ((attr & 0xff) > talloc_array_length(parent->
children))
return NULL;
3634 bin = parent->
children[attr & 0xff];
3636 if (!bin)
return NULL;
3637 if (bin->
attr == attr)
return bin;
3664 dval.
name[0] =
'\0';
3671 if (dv) dval.
da = dv->
da;
3708 if (!name)
return NULL;
3713 my_dv->
name[0] =
'\0';
3720 if (dv) my_dv->
da = dv->
da;
3734 for (p = (uint8_t
const *)name; *p !=
'\0'; p++) {
3735 if (!fr_dict_attr_allowed_chars[*p]) {
3738 fr_snprint(buff,
sizeof(buff), (
char const *)p, 1,
'\'');
3741 return -(p - (uint8_t
const *)name);
3754 FR_FAULT_LOG(
"CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t pointer was NULL", file, line);
3763 FR_FAULT_LOG(
"CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t %s vendor: %i, attr %i: "
3764 "Is not root, but depth is 0",
3772 FR_FAULT_LOG(
"CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t %s vendor: %i, attr %i: "
3773 "Indicated depth (%u) greater than TLV stack depth (%u)",
3780 for (da_p = da; da_p; da_p = da_p->
next) (
void) talloc_get_type_abort(da_p,
fr_dict_attr_t);
3782 for (i = da->
depth, da_p = da; (i >= 0) && da; i--, da_p = da_p->
parent) {
3783 if (i != (
int)da_p->
depth) {
3784 FR_FAULT_LOG(
"CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t %s vendor: %i, attr %i: "
3785 "Depth out of sequence, expected %i, got %u",
3795 FR_FAULT_LOG(
"CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t top of hierarchy was not at depth 0",
fr_dict_attr_t const * fr_dict_attr_child_by_da(fr_dict_attr_t const *parent, fr_dict_attr_t const *child)
Check if a child attribute exists in a parent using a pointer (da)
const size_t dict_attr_sizes[PW_TYPE_MAX][2]
Map data types to min / max data sizes.
void fr_dict_print(fr_dict_attr_t const *da, int depth)
int fr_hash_table_insert(fr_hash_table_t *ht, void const *data)
fr_dict_attr_t const * fr_dict_attr_by_name(fr_dict_t *dict, char const *name)
Locate a fr_dict_attr_t by its name.
Time value (struct timeval), only for config items.
void * fr_hash_table_finddata(fr_hash_table_t *ht, void const *data)
unsigned int array
Pack multiples into 1 attr.
fr_dict_attr_t const * fr_dict_unknown_add(fr_dict_t *dict, fr_dict_attr_t const *old)
Converts an unknown to a known by adding it to the internal dictionaries.
void fr_dict_verify(char const *file, int line, fr_dict_attr_t const *da)
#define PW_TYPE_STRUCTURAL
Match all non value types in case statements.
fr_dict_attr_t const ** children
Children of this attribute.
uint32_t fr_hash(void const *, size_t)
static int dict_read_process_attribute(fr_dict_t *dict, fr_dict_attr_t const *parent, unsigned int block_vendor, char **argv, int argc)
Ascend binary format a packed data structure.
static int dict_read_sscanf_i(char const *str, unsigned int *pvalue)
void fr_rand_seed(void const *, size_t)
Seed the random number generator.
static int dict_read_parse_format(char const *format, unsigned int *pvalue, int *ptype, int *plength, bool *pcontinuation)
WiMAX IPv4 or IPv6 address depending on length.
uint8_t length
length of the attribute
fr_dict_attr_t const * da
Dictionary attribute enum is associated with.
fr_hash_table_t * vendors_by_name
Lookup vendor by name.
fr_dict_attr_t * root
Root attribute of this dictionary.
size_t length
Length of length data.
struct value_fixup_t value_fixup_t
static int dict_attr_name_cmp(void const *one, void const *two)
static uint32_t dict_attr_combo_hash(void const *data)
static int dict_stat_check(fr_dict_t *dict, char const *dir, char const *file)
See if any dictionaries have changed.
int fr_hash_table_replace(fr_hash_table_t *ht, void const *data)
#define FR_DICT_MAX_TLV_STACK
Maximum TLV stack size.
static fr_dict_attr_t * fr_dict_attr_alloc(TALLOC_CTX *ctx, char const *name, unsigned int vendor, int attr, PW_TYPE type, fr_dict_attr_flags_t flags)
unsigned int is_pointer
data is a pointer
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Number of defined data types.
Values of the encryption flags.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Long extended attribute space attribute.
fr_dict_enum_t * fr_dict_enum_by_da(fr_dict_t *dict, fr_dict_attr_t const *da, int value)
Lookup the structure representing an enum value in a fr_dict_attr_t.
fr_dict_attr_t const * fr_dict_attr_by_name_substr(fr_dict_t *dict, char const **name)
Look up a dictionary attribute by a name embedded in another string.
int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, int attr, PW_TYPE type, fr_dict_attr_flags_t flags)
Add an attribute to the dictionary.
unsigned int depth
Depth of nesting for this attribute.
int fr_dict_unknown_vendor_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const **out, fr_dict_attr_t const *parent, unsigned int vendor)
Build an unknown vendor, parented by a VSA or EVS attribute.
fr_hash_table_t * values_by_da
Lookup an attribute enum value by integer value.
fr_dict_attr_flags_t flags
Flags.
int fr_dict_vendor_by_name(fr_dict_t *dict, char const *name)
Look up a vendor by its name.
size_t fr_snprint(char *out, size_t outlen, char const *in, ssize_t inlen, char quote)
Escape any non printable or non-UTF8 characters in the input string.
static unsigned int hash(char const *username, unsigned int tablesize)
WiMAX IPv4 or IPv6 address prefix depending on length.
fr_dict_attr_t * fr_dict_unknown_afrom_fields(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int vendor, unsigned int attr)
Allocates an unknown attribute.
uint32_t fr_hash_update(void const *data, size_t size, uint32_t hash)
Vendors and attribute names.
ssize_t fr_dict_attr_by_oid(fr_dict_t *dict, fr_dict_attr_t const **parent, unsigned int *vendor, unsigned int *attr, char const *oid)
Get the leaf attribute of an OID string.
int fr_str2int(FR_NAME_NUMBER const *table, char const *name, int def)
char const * fr_dict_enum_name_by_da(fr_dict_t *dict, fr_dict_attr_t const *da, int value)
Lookup the name of an enum value in a fr_dict_attr_t.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
static uint32_t dict_hash_name(char const *name)
unsigned int is_unknown
Attribute number or vendor is unknown.
int fr_dict_str_to_argv(char *str, char **argv, int max_argc)
static uint32_t dict_attr_name_hash(void const *data)
value_fixup_t * value_fixup
int fr_dict_init(TALLOC_CTX *ctx, fr_dict_t **out, char const *dir, char const *fn, char const *name)
(re)initialize a protocol dictionary
fr_hash_table_t * attributes_combo
Lookup variants of polymorphic attributes.
Double precision floating point.
int fr_dict_enum_add(fr_dict_t *dict, char const *attr, char const *alias, int value)
#define FR_FAULT_LOG(fmt,...)
int fr_dict_unknown_from_suboid(fr_dict_t *dict, fr_dict_attr_t *vendor_da, fr_dict_attr_t *da, fr_dict_attr_t const *parent, char const **name)
Create a dictionary attribute by name embedded in another string.
unsigned int attr
Attribute number.
static uint32_t dict_enum_name_hash(void const *data)
char attrstr[FR_DICT_ATTR_MAX_NAME_LEN]
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.
const FR_NAME_NUMBER dict_attr_types[]
Map data types to names representing those types.
fr_dict_attr_t const * fr_dict_parent_common(fr_dict_attr_t const *a, fr_dict_attr_t const *b, bool is_ancestor)
Find a common ancestor that two TLV type attributes share.
static fr_dict_attr_t * fr_dict_unknown_acopy(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Copy a known or unknown attribute to produce an unknown attribute.
static int dict_attr_combo_cmp(void const *one, void const *two)
unsigned int vendor
Vendor that defines this attribute.
void fr_dict_unknown_free(fr_dict_attr_t const **da)
Free dynamically allocated (unknown attributes)
fr_dict_attr_t const * parent
Immediate parent of this attribute.
#define FR_DICT_ATTR_SIZE
Maximum dictionary attribute size.
fr_dict_attr_t const * fr_dict_unknown_afrom_oid(TALLOC_CTX *ctx, fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name)
Create a fr_dict_attr_t from an ASCII attribute and value.
int fr_dict_unknown_from_fields(fr_dict_attr_t *da, fr_dict_attr_t const *parent, unsigned int vendor, unsigned int attr)
Initialises an unknown attribute.
enum attr_flags::@0 encrypt
Attribute that represents a vendor in the attribute tree.
static uint32_t dict_vendor_name_hash(void const *data)
unsigned int is_root
Is root of a dictionary.
unsigned int concat
concatenate multiple instances
struct dict_stat_t * next
int fr_dict_oid_component(unsigned int *out, char const **oid)
Process a single OID component.
Invalid (uninitialised) attribute type.
static int dict_enum_name_cmp(void const *one, void const *two)
unsigned int internal
Internal attribute, should not be received in protocol packets, should not be encoded.
char const * fr_strerror(void)
Get the last library error.
int strcasecmp(char *s1, char *s2)
int fr_dict_unknown_from_oid(fr_dict_t *dict, fr_dict_attr_t *vendor_da, fr_dict_attr_t *da, fr_dict_attr_t const *parent, char const *name)
Initialise a fr_dict_attr_t from an ASCII attribute and value.
int fr_dict_read(fr_dict_t *dict, char const *dir, char const *filename)
fr_hash_table_t * values_by_name
Lookup an attribute enum value by name.
fr_dict_attr_t const * next
Next child in bin.
fr_dict_enum_t * fr_dict_enum_by_name(fr_dict_t *dict, fr_dict_attr_t const *da, char const *name)
Vendor-Specific, for RADIUS attribute 26.
#define FR_DICT_ENUM_MAX_NAME_LEN
char name[1]
Attribute name.
static void fr_dict_snprint_flags(char *out, size_t outlen, fr_dict_attr_flags_t flags)
static int dict_enum_value_cmp(void const *one, void const *two)
static uint32_t dict_enum_value_hash(void const *data)
Extended attribute space attribute.
struct value_fixup_t * next
static int dict_read_process_value(fr_dict_t *dict, char **argv, int argc)
fr_hash_table_t * vendors_by_num
Lookup vendor by PEN.
int strncasecmp(char *s1, char *s2, int n)
static void hash_pool_free(void *to_free)
static int dict_vendor_name_cmp(void const *one, void const *two)
fr_hash_table_t * fr_hash_table_create(TALLOC_CTX *ctx, fr_hash_table_hash_t hashNode, fr_hash_table_cmp_t cmpNode, fr_hash_table_free_t freeNode)
fr_dict_attr_t const * fr_dict_attr_by_num(fr_dict_t *dict, unsigned int vendor, unsigned int attr)
Lookup a fr_dict_attr_t by its vendor and attribute numbers.
unsigned int vendorpec
Private enterprise number.
fr_dict_attr_t const * fr_dict_attr_by_type(fr_dict_t *dict, unsigned int vendor, unsigned int attr, PW_TYPE type)
Lookup a attribute by its its vendor and attribute numbers and data type.
void fr_strerror_printf(char const *,...) CC_HINT(format(printf
static void concat(char *out, char *in1, char *in2, int l1, int l2)
unsigned int has_tag
Tagged attribute.
int fr_hash_table_walk(fr_hash_table_t *ht, fr_hash_table_walk_t callback, void *ctx)
fr_dict_t * fr_dict_internal
Internal server dictionary.
#define FR_DICT_TLV_NEST_MAX
Maximum level of TLV nesting allowed.
int fr_dict_parse_str(fr_dict_t *dict, char *buf, fr_dict_attr_t const *parent, unsigned int vendor)
#define DHCP_MAGIC_VENDOR
size_t type
Length of type data.
static int hash_null_callback(UNUSED void *ctx, UNUSED void *data)
#define FR_DICT_VENDOR_MAX_NAME_LEN
const int fr_dict_attr_allowed_chars[256]
struct dict_stat_t dict_stat_t
size_t strlcpy(char *dst, char const *src, size_t siz)
char const * fr_int2str(FR_NAME_NUMBER const *table, int number, char const *def)
uint8_t type_size
for TLV2, size of the type
static uint32_t dict_vendor_value_hash(void const *data)
static int dict_vendor_value_cmp(void const *one, void const *two)
String of printable characters.
Contains nested attributes.
size_t dict_print_attr_oid(char *buffer, size_t outlen, fr_dict_attr_t const *ancestor, fr_dict_attr_t const *da)
Build the tlv_stack for the specified DA and encode the path in OID form.
TALLOC_CTX * pool
Talloc memory pool to reduce mallocs.
void fr_proto_tlv_stack_build(fr_dict_attr_t const **tlv_stack, fr_dict_attr_t const *da)
int fr_dict_valid_name(char const *name)
static void dict_stat_add(fr_dict_t *dict, struct stat const *stat_buf)
Add an entry to the list of stat buffers.
static int dict_read_init(fr_dict_t *dict, char const *dir_name, char const *filename, char const *src_file, int src_line)
#define FR_DICT_ATTR_MAX_NAME_LEN
static int dict_read_process_vendor(fr_dict_t *dict, char **argv, int argc)
Value of an enumerated attribute.
PW_TYPE
Internal data types used within libfreeradius.
fr_hash_table_t * attributes_by_name
Allow attribute lookup by unique name.
#define INTERNAL_IF_NULL(_dict)
static int fr_dict_attr_child_add(fr_dict_attr_t *parent, fr_dict_attr_t *child)
Add a child to a parent.
Extended attribute, vendor specific.
int fr_dict_vendor_add(fr_dict_t *dict, char const *name, unsigned int num)
Add a vendor to the dictionary.
fr_dict_vendor_t const * fr_dict_vendor_by_num(fr_dict_t *dict, int vendorpec)
Look up a vendor by its PEN.
unsigned int has_value
Has a value.
size_t strlcat(char *dst, char const *src, size_t siz)