40#include <radcli/radcli.h>
41#include <radcli/radcli2.h>
50void radcli2_priv_dict_free(rc_handle *rh)
52 struct radcli_dict_attr *a, *atmp;
53 struct radcli_dict_value *v, *vtmp;
54 struct radcli_dict_vendor *w, *wtmp;
55 struct radcli_dict_flags *fl, *fltmp;
56 struct radcli_dict_gigawords *gw, *gwtmp;
57 struct radcli_dict *d = rh->dict;
73 HASH_ITER(hh_name, d->attrs_by_name, a, atmp) {
74#ifndef __clang_analyzer__
75 HASH_DELETE(hh_name, d->attrs_by_name, a);
76 HASH_DELETE(hh_id, d->attrs_by_id, a);
81 HASH_ITER(hh_name, d->values_by_name, v, vtmp) {
82#ifndef __clang_analyzer__
83 HASH_DELETE(hh_name, d->values_by_name, v);
84 HASH_DELETE(hh_attr, d->values_by_attr, v);
85 HASH_DELETE(hh_attr_name, d->values_by_attr_name, v);
90 HASH_ITER(hh_name, d->vendors_by_name, w, wtmp) {
91#ifndef __clang_analyzer__
92 HASH_DELETE(hh_name, d->vendors_by_name, w);
93 HASH_DELETE(hh_pec, d->vendors_by_pec, w);
98 HASH_ITER(hh, d->flags_by_attr_id, fl, fltmp) {
99#ifndef __clang_analyzer__
100 HASH_DELETE(hh, d->flags_by_attr_id, fl);
104 HASH_ITER(hh, d->gigawords_by_attr_id, gw, gwtmp) {
105#ifndef __clang_analyzer__
106 HASH_DELETE(hh, d->gigawords_by_attr_id, gw);
124struct radcli_dict_attr *radcli_dict_attr_by_name(rc_handle
const *rh,
const char *name)
130 char key[RC_DICT2_KEY_LEN] = {0};
131 struct radcli_dict_attr *out;
133 if (rh == NULL || rh->dict == NULL || name == NULL)
136 dict2_lc(key,
sizeof(key), name);
137 HASH_FIND(hh_name, rh->dict->attrs_by_name, key, strlen(key), out);
149struct radcli_dict_attr *radcli_dict_attr_by_id(rc_handle
const *rh, uint64_t value)
151 struct radcli_dict_attr *out;
153 if (rh == NULL || rh->dict == NULL)
156 HASH_FIND(hh_id, rh->dict->attrs_by_id, &value,
sizeof(value), out);
168struct radcli_dict_value *radcli_dict_value_by_name(rc_handle
const *rh,
const char *name)
174 char key[RC_DICT2_KEY_LEN] = {0};
175 struct radcli_dict_value *out;
177 if (rh == NULL || rh->dict == NULL || name == NULL)
180 dict2_lc(key,
sizeof(key), name);
181 HASH_FIND(hh_name, rh->dict->values_by_name, key, strlen(key), out);
193struct radcli_dict_value *radcli_dict_value_by_attr(rc_handle
const *rh,
const char *attrname, uint32_t value)
195 struct radcli_dict_value_key key;
196 struct radcli_dict_value *out;
198 if (rh == NULL || rh->dict == NULL || attrname == NULL)
201 memset(&key, 0,
sizeof(key));
202 dict2_lc(key.attrname_key,
sizeof(key.attrname_key), attrname);
205 HASH_FIND(hh_attr, rh->dict->values_by_attr, &key,
sizeof(key), out);
217struct radcli_dict_value *radcli_dict_value_by_attr_name(rc_handle
const *rh,
const char *attrname,
const char *name)
219 struct radcli_dict_value_name_key key;
220 struct radcli_dict_value *out;
222 if (rh == NULL || rh->dict == NULL || attrname == NULL || name == NULL)
225 memset(&key, 0,
sizeof(key));
226 dict2_lc(key.attrname_key,
sizeof(key.attrname_key), attrname);
227 dict2_lc(key.name_key,
sizeof(key.name_key), name);
229 HASH_FIND(hh_attr_name, rh->dict->values_by_attr_name, &key,
sizeof(key), out);
240struct radcli_dict_vendor *radcli_dict_vendor_by_name(rc_handle
const *rh,
const char *name)
246 char key[RC_DICT2_KEY_LEN] = {0};
247 struct radcli_dict_vendor *out;
249 if (rh == NULL || rh->dict == NULL || name == NULL)
252 dict2_lc(key,
sizeof(key), name);
253 HASH_FIND(hh_name, rh->dict->vendors_by_name, key, strlen(key), out);
264struct radcli_dict_vendor *radcli_dict_vendor_by_pec(rc_handle
const *rh, uint32_t pec)
266 struct radcli_dict_vendor *out;
268 if (rh == NULL || rh->dict == NULL)
271 HASH_FIND(hh_pec, rh->dict->vendors_by_pec, &pec,
sizeof(pec), out);
283struct radcli_dict_flags *radcli_dict_flags_by_id(rc_handle
const *rh, uint64_t attr_id)
285 struct radcli_dict_flags *out;
287 if (rh == NULL || rh->dict == NULL)
290 HASH_FIND(hh, rh->dict->flags_by_attr_id, &attr_id,
sizeof(attr_id), out);
302struct radcli_dict_gigawords *radcli_dict_gigawords_by_id(rc_handle
const *rh, uint64_t attr_id)
304 struct radcli_dict_gigawords *out;
306 if (rh == NULL || rh->dict == NULL)
309 HASH_FIND(hh, rh->dict->gigawords_by_attr_id, &attr_id,
sizeof(attr_id), out);
321struct radcli_dict_attr *radcli_dict_attr_gigawords(rc_handle
const *rh,
const struct radcli_dict_attr *octets)
323 struct radcli_dict_gigawords *gw;
325 if (rh == NULL || octets == NULL)
328 gw = radcli_dict_gigawords_by_id(rh, octets->value);
332 return radcli_dict_attr_by_id(rh, gw->gigawords_attrid);
342DICT_ATTR *radcli_dict_attr_to_legacy(
struct radcli_dict_attr *a)
347 if (a->legacy == NULL) {
348 a->legacy = malloc(
sizeof(*a->legacy));
349 if (a->legacy == NULL) {
350 rc_log(LOG_CRIT,
"radcli_dict_attr_to_legacy: out of memory");
353 strlcpy(a->legacy->name, a->name,
sizeof(a->legacy->name));
354 a->legacy->value = a->value;
355 a->legacy->type = radcli_dict_type_to_legacy(a->type);
356 a->legacy->next = NULL;
368DICT_VALUE *radcli_dict_value_to_legacy(
struct radcli_dict_value *v)
373 if (v->legacy == NULL) {
374 v->legacy = malloc(
sizeof(*v->legacy));
375 if (v->legacy == NULL) {
376 rc_log(LOG_CRIT,
"radcli_dict_value_to_legacy: out of memory");
379 strlcpy(v->legacy->attrname, v->attrname,
sizeof(v->legacy->attrname));
380 strlcpy(v->legacy->name, v->name,
sizeof(v->legacy->name));
381 v->legacy->value = v->value;
382 v->legacy->next = NULL;
394DICT_VENDOR *radcli_dict_vendor_to_legacy(
struct radcli_dict_vendor *v)
399 if (v->legacy == NULL) {
400 v->legacy = malloc(
sizeof(*v->legacy));
401 if (v->legacy == NULL) {
402 rc_log(LOG_CRIT,
"radcli_dict_vendor_to_legacy: out of memory");
405 strlcpy(v->legacy->vendorname, v->name,
sizeof(v->legacy->vendorname));
406 v->legacy->vendorpec = v->pec;
407 v->legacy->next = NULL;
446 case PW_TYPE_INTEGER:
452 case PW_TYPE_IPV6ADDR:
454 case PW_TYPE_IPV6PREFIX:
463 case PW_TYPE_MAX + 1:
468 case PW_TYPE_MAX + 2:
473 case PW_TYPE_MAX + 3:
488#define RADCLI_OID_MAX_COMPONENTS 5
499static int parse_oid(
const char *oid, uint32_t comp[RADCLI_OID_MAX_COMPONENTS])
504 if (oid == NULL || *oid ==
'\0')
511 if (n >= RADCLI_OID_MAX_COMPONENTS)
515 v = strtoul(p, &end, 10);
516 if (end == p || (v == ULONG_MAX && errno == ERANGE))
518#if ULONG_MAX > UINT32_MAX
523 comp[n++] = (uint32_t)v;
544 if (ctx == NULL || name == NULL)
546 return (
const radcli_attr_def *)radcli_dict_attr_by_name((rc_handle
const *)ctx, name);
568 return (
const radcli_attr_def *)radcli_dict_attr_by_id((rc_handle
const *)ctx,
569 RADCLI_VENDOR_ATTR_SET(attrid, vendor));
588 uint32_t comp[RADCLI_OID_MAX_COMPONENTS];
594 n = parse_oid(oid, comp);
601 if (n == 3 && comp[0] == PW_VENDOR_SPECIFIC)
617 const struct radcli_dict_attr *a = (
const struct radcli_dict_attr *)def;
618 return a ? a->name : NULL;
626 const struct radcli_dict_attr *a = (
const struct radcli_dict_attr *)def;
627 return dict_type_to_radcli(a ? a->type : PW_TYPE_STRING);
640 const struct radcli_dict_attr *a = (
const struct radcli_dict_attr *)def;
641 uint32_t vendor, attrid;
646 vendor = VENDOR(a->value);
647 attrid = ATTRID(a->value);
650 return snprintf(buf, buflen,
"%u", attrid);
651 return snprintf(buf, buflen,
"26.%u.%u", vendor, attrid);
675 const char *name, uint32_t *out)
677 const struct radcli_dict_attr *a = (
const struct radcli_dict_attr *)def;
678 const struct radcli_dict_value *v;
680 if (ctx == NULL || a == NULL || name == NULL || out == NULL)
683 v = radcli_dict_value_by_attr_name((rc_handle
const *)ctx, a->name, name);
const radcli_attr_def * radcli_dict_lookup(const radcli_ctx *ctx, const char *name)
Look up a dictionary attribute by its canonical name.
const radcli_attr_def * radcli_dict_lookup_num(const radcli_ctx *ctx, uint32_t attrid, uint32_t vendor)
Look up a dictionary attribute by its legacy numeric ID and vendor.
const char * radcli_attr_def_name(const radcli_attr_def *def)
Return an attribute definition's canonical name.
const radcli_attr_def * radcli_dict_lookup_oid(const radcli_ctx *ctx, const char *oid)
Look up a dictionary attribute by RFC 6929 §2.7 OID notation.
radcli_attr_type radcli_attr_def_type(const radcli_attr_def *def)
Return an attribute definition's wire type.
int radcli_attr_def_oid(const radcli_attr_def *def, char *buf, size_t buflen)
Render an attribute definition's RFC 6929 §2.7 OID notation.
int radcli_dict_lookup_value(const radcli_ctx *ctx, const radcli_attr_def *def, const char *name, uint32_t *out)
Resolve a dictionary VALUE by name, scoped to one attribute.