38DICT_ATTR *
rc_dict_addattr(rc_handle *rh,
char const * namestr, uint32_t value,
int type, uint32_t vendorspec)
42 if (strlen (namestr) > RC_NAME_LENGTH)
44 rc_log(LOG_ERR,
"rc_dict_addattr: invalid attribute length");
50 rc_log(LOG_ERR,
"rc_dict_addattr: invalid attribute type");
55 if ((attr = malloc(
sizeof (DICT_ATTR))) == NULL)
57 rc_log(LOG_CRIT,
"rc_dict_addattr: out of memory");
61 strlcpy(attr->
name, namestr,
sizeof(attr->
name));
62 attr->
value = RADCLI_VENDOR_ATTR_SET(value, vendorspec);
66 attr->next = rh->dictionary_attributes;
67 rh->dictionary_attributes = attr;
81DICT_VALUE *
rc_dict_addval(rc_handle *rh,
char const * attrstr,
char const * namestr, uint32_t value)
85 if (strlen(attrstr) > RC_NAME_LENGTH)
87 rc_log(LOG_ERR,
"rc_dict_addval: invalid attribute length");
91 if (strlen(namestr) > RC_NAME_LENGTH)
93 rc_log(LOG_ERR,
"rc_dict_addval: invalid name length");
98 if ((dval = malloc(
sizeof (DICT_VALUE))) == NULL)
100 rc_log(LOG_CRIT,
"rc_dict_addval: out of memory");
103 strlcpy(dval->attrname, attrstr,
sizeof(dval->attrname));
104 strlcpy(dval->name, namestr,
sizeof(dval->name));
108 dval->next = rh->dictionary_values;
109 rh->dictionary_values = dval;
126 if (strlen(namestr) > RC_NAME_LENGTH)
128 rc_log(LOG_ERR,
"rc_dict_addvend: invalid vendor name length");
133 dvend = malloc(
sizeof(DICT_VENDOR));
136 rc_log(LOG_CRIT,
"rc_dict_init: out of memory");
139 strlcpy(dvend->vendorname, namestr,
sizeof(dvend->vendorname));
140 dvend->vendorpec = vendorspec;
143 dvend->next = rh->dictionary_vendors;
144 rh->dictionary_vendors = dvend;
159static int is_unsigned_decimal(
char const *s)
163 for (; *s !=
'\0'; s++) {
164 if (!isdigit((
unsigned char) *s))
170static int rc_dict_init(rc_handle *rh, FILE *dictfd,
char const *filename)
172 char namestr[AUTH_ID_LEN];
173 char valstr[AUTH_ID_LEN];
174 char attrstr[AUTH_ID_LEN];
175 char typestr[AUTH_ID_LEN];
176 char optstr[AUTH_ID_LEN];
177 char ifilename[RC_MAX(1024, PATH_MAX)] = {0};
189 unsigned attr_vendorspec = 0;
190 const char *pfilename = filename;
192 if (pfilename == NULL)
194 pfilename =
"memory";
197 while (getline (&buffer, &bufsize, dictfd) != -1)
202 if (*buffer ==
'#' || *buffer ==
'\0' || *buffer ==
'\n' || \
209 cp = strchr(buffer,
'#');
215 tok = strtok_r(buffer,
" \t\r\n", &saveptr);
221 if (strcmp (tok,
"ATTRIBUTE") == 0)
223 char *name_t, *val_t, *type_t, *opt_t;
226 name_t = strtok_r(NULL,
" \t\r\n", &saveptr);
227 val_t = strtok_r(NULL,
" \t\r\n", &saveptr);
228 type_t = strtok_r(NULL,
" \t\r\n", &saveptr);
229 opt_t = strtok_r(NULL,
" \t\r\n", &saveptr);
230 if (name_t == NULL || val_t == NULL || type_t == NULL)
233 "rc_dict_init: invalid attribute on line %d of "
234 "dictionary %s", line_no, pfilename);
244 if (strlen (name_t) > RC_NAME_LENGTH)
247 "rc_dict_init: invalid name length on line %d of "
248 "dictionary %s", line_no, pfilename);
252 strlcpy(namestr, name_t,
sizeof(namestr));
253 strlcpy(valstr, val_t,
sizeof(valstr));
254 strlcpy(typestr, type_t,
sizeof(typestr));
257 strlcpy(optstr, opt_t,
sizeof(optstr));
264 if (!is_unsigned_decimal (valstr))
267 "rc_dict_init: invalid value on line %d of dictionary %s",
271 value = atoi (valstr);
273 if (strcmp (typestr,
"string") == 0)
277 else if (strcmp (typestr,
"integer") == 0)
281 else if (strcmp (typestr,
"ipaddr") == 0)
285 else if (strcmp (typestr,
"ipv4addr") == 0)
289 else if (strcmp (typestr,
"ipv6addr") == 0)
293 else if (strcmp (typestr,
"ipv6prefix") == 0)
297 else if (strcmp (typestr,
"date") == 0)
304 "rc_dict_init: invalid type on line %d of dictionary %s",
310 if (optstr[0] !=
'\0') {
312 for (cp1 = optstr; cp1 != NULL; cp1 = cp) {
313 cp = strchr(cp1,
',');
318 if (strncmp(cp1,
"vendor=", 7) == 0)
323 "rc_dict_init: unknown Vendor-Id %s on line %d of "
324 "dictionary %s", cp1, line_no, pfilename);
331 if ((attr = malloc (
sizeof (DICT_ATTR))) == NULL)
333 rc_log(LOG_CRIT,
"rc_dict_init: out of memory");
336 strlcpy (attr->
name, namestr,
sizeof(attr->
name));
340 attr->
value = RADCLI_VENDOR_ATTR_SET(value, dvend->vendorpec);
342 attr->
value = RADCLI_VENDOR_ATTR_SET(value, attr_vendorspec);
346 attr->next = rh->dictionary_attributes;
347 rh->dictionary_attributes = attr;
349 else if (strcmp (tok,
"VALUE") == 0)
351 char *attr_t, *name_t, *val_t;
354 attr_t = strtok_r(NULL,
" \t\r\n", &saveptr);
355 name_t = strtok_r(NULL,
" \t\r\n", &saveptr);
356 val_t = strtok_r(NULL,
" \t\r\n", &saveptr);
357 if (attr_t == NULL || name_t == NULL || val_t == NULL)
360 "rc_dict_init: invalid value entry on line %d of "
361 "dictionary %s", line_no, pfilename);
368 if (strlen (attr_t) > RC_NAME_LENGTH)
371 "rc_dict_init: invalid attribute length on line %d of "
372 "dictionary %s", line_no, pfilename);
376 if (strlen (name_t) > RC_NAME_LENGTH)
379 "rc_dict_init: invalid name length on line %d of "
380 "dictionary %s", line_no, pfilename);
384 strlcpy(attrstr, attr_t,
sizeof(attrstr));
385 strlcpy(namestr, name_t,
sizeof(namestr));
386 strlcpy(valstr, val_t,
sizeof(valstr));
388 if (!is_unsigned_decimal (valstr))
391 "rc_dict_init: invalid value on line %d of dictionary %s",
395 value = atoi (valstr);
398 if ((dval = malloc (
sizeof (DICT_VALUE))) == NULL)
400 rc_log(LOG_CRIT,
"rc_dict_init: out of memory");
403 strlcpy (dval->attrname, attrstr,
sizeof(dval->attrname));
404 strlcpy (dval->name, namestr,
sizeof(dval->name));
408 dval->next = rh->dictionary_values;
409 rh->dictionary_values = dval;
411 else if ((filename != NULL) &&
412 (strcmp (tok,
"$INCLUDE") == 0))
421 path_t = strtok_r(NULL,
" \t\r\n", &saveptr);
425 "rc_dict_init: invalid include entry on line %d of "
426 "dictionary %s", line_no, pfilename);
429 strlcpy(ifilename, path_t,
sizeof(ifilename));
431 if (path_t[0] !=
'/') {
432 cp = strrchr(filename,
'/');
435 strlcpy(ifilename, filename,
sizeof(ifilename));
436 strlcat(ifilename,
"/",
sizeof(ifilename));
437 strlcat(ifilename, path_t,
sizeof(ifilename));
446 else if (strcmp (tok,
"END-VENDOR") == 0)
450 else if (strcmp (tok,
"BEGIN-VENDOR") == 0)
456 name_t = strtok_r(NULL,
" \t\r\n", &saveptr);
460 "rc_dict_init: invalid Vendor-Id on line %d of "
461 "dictionary %s", line_no, pfilename);
468 "rc_dict_init: unknown Vendor %s on line %d of "
469 "dictionary %s", name_t, line_no, pfilename);
473 attr_vendorspec = v->vendorpec;
475 else if (strcmp (tok,
"VENDOR") == 0)
477 char *name_t, *val_t;
480 name_t = strtok_r(NULL,
" \t\r\n", &saveptr);
481 val_t = strtok_r(NULL,
" \t\r\n", &saveptr);
482 if (name_t == NULL || val_t == NULL)
485 "rc_dict_init: invalid Vendor-Id on line %d of "
486 "dictionary %s", line_no, pfilename);
491 if (strlen (name_t) > RC_NAME_LENGTH)
494 "rc_dict_init: invalid attribute length on line %d of "
495 "dictionary %s", line_no, pfilename);
499 strlcpy(attrstr, name_t,
sizeof(attrstr));
500 strlcpy(valstr, val_t,
sizeof(valstr));
502 if (!is_unsigned_decimal (valstr))
505 "rc_dict_init: invalid Vendor-Id on line %d of "
506 "dictionary %s", line_no, pfilename);
509 value = atoi (valstr);
512 dvend = malloc(
sizeof(DICT_VENDOR));
515 rc_log(LOG_CRIT,
"rc_dict_init: out of memory");
518 strlcpy (dvend->vendorname, attrstr,
sizeof(dvend->vendorname));
519 dvend->vendorpec = value;
522 dvend->next = rh->dictionary_vendors;
523 rh->dictionary_vendors = dvend;
549 if (rh->first_dict_read != NULL && strcmp(filename, rh->first_dict_read) == 0)
552 if ((dictfd = fopen (filename,
"r")) == NULL)
554 rc_log(LOG_ERR,
"rc_read_dictionary couldn't open dictionary %s: %s",
555 filename, strerror(errno));
559 ret_val = rc_dict_init(rh, dictfd, filename);
563 if (rh->first_dict_read == NULL)
564 rh->first_dict_read = strdup(filename);
584 if ((dictfd = fmemopen ((
void *)buf, size,
"r")) == NULL)
586 rc_log(LOG_ERR,
"rc_read_dictionary_from_buffer failed to read "
587 "input buffer %s", strerror(errno));
591 ret_val = rc_dict_init(rh, dictfd, NULL);
608 attr = rh->dictionary_attributes;
611 if (attr->
value == attribute)
631 attr = rh->dictionary_attributes;
634 if (strcasecmp (attr->
name, attrname) == 0)
653 val = rh->dictionary_values;
656 if (strcasecmp (val->name, valname) == 0)
675 for (vend = rh->dictionary_vendors; vend != NULL; vend = vend->next)
676 if (strcasecmp(vend->vendorname, vendorname) == 0)
691 for (vend = rh->dictionary_vendors; vend != NULL; vend = vend->next)
692 if (vend->vendorpec == vendorspec)
704DICT_VALUE *
rc_dict_getval(rc_handle
const *rh, uint32_t value,
char const *attrname)
708 val = rh->dictionary_values;
711 if (strcasecmp (val->attrname, attrname) == 0 &&
727 DICT_ATTR *attr, *nattr;
728 DICT_VALUE *val, *nval;
729 DICT_VENDOR *vend, *nvend;
731 for (attr = rh->dictionary_attributes; attr != NULL; attr = nattr) {
735 for (val = rh->dictionary_values; val != NULL; val = nval) {
739 for (vend = rh->dictionary_vendors; vend != NULL; vend = nvend) {
743 rh->dictionary_attributes = NULL;
744 rh->dictionary_values = NULL;
745 rh->dictionary_vendors = NULL;
DICT_VALUE * rc_dict_getval(rc_handle const *rh, uint32_t value, char const *attrname)
Get DICT_VALUE based on attribute name and integer value number.
DICT_ATTR * rc_dict_addattr(rc_handle *rh, char const *namestr, uint32_t value, int type, uint32_t vendorspec)
Add attribute to dictionary.
DICT_VENDOR * rc_dict_findvend(rc_handle const *rh, char const *vendorname)
Lookup a DICT_VENDOR by its name.
int rc_read_dictionary_from_buffer(rc_handle *rh, char const *buf, size_t size)
Initialize the dictionary from Buffer.
DICT_VALUE * rc_dict_findval(rc_handle const *rh, char const *valname)
Lookup a DICT_VALUE by its name.
int rc_read_dictionary(rc_handle *rh, char const *filename)
Initialize the dictionary.
DICT_VENDOR * rc_dict_getvend(rc_handle const *rh, uint32_t vendorspec)
Lookup a DICT_VENDOR by its IANA number.
DICT_ATTR * rc_dict_getattr(rc_handle const *rh, uint64_t attribute)
Lookup a DICT_ATTR by attribute number.
void rc_dict_free(rc_handle *rh)
Frees the allocated dictionary.
DICT_VALUE * rc_dict_addval(rc_handle *rh, char const *attrstr, char const *namestr, uint32_t value)
Add value to dictionary.
DICT_VENDOR * rc_dict_addvend(rc_handle *rh, char const *namestr, uint32_t vendorspec)
Add vendor to dictionary.
DICT_ATTR * rc_dict_findattr(rc_handle const *rh, char const *attrname)
Lookup a DICT_ATTR by its name.
@ PW_TYPE_IPADDR
The attribute is an IPv4 address in host-byte order.
@ PW_TYPE_IPV6ADDR
The attribute is an 128-bit IPv6 address.
@ PW_TYPE_MAX
Maximum number of types (last+1)
@ PW_TYPE_IPV6PREFIX
The attribute is an IPv6 prefix; the lvalue will indicate its size.
@ PW_TYPE_INTEGER
The attribute is a 32-bit integer.
@ PW_TYPE_DATE
The attribute contains a 32-bit number indicating the seconds since epoch.
@ PW_TYPE_STRING
The attribute is a printable string.
Public API of the radcli library.
rc_attr_type type
string, int, etc..
uint64_t value
attribute index and vendor number; use VENDOR() and ATTRID() to separate.
char name[RC_NAME_LENGTH+1]
attribute name.