added qse_raddic_addattr(), qse_raddic_deleteattrbyname(), qes_raddic_deleteattrbyvalue(), qse_raddic_findattrbyname(), qse_raddic_findattrbyvalue()

This commit is contained in:
hyung-hwan 2017-12-11 10:02:49 +00:00
parent c9bbd3c993
commit 80ade41ea9
3 changed files with 479 additions and 84 deletions

View File

@ -30,21 +30,21 @@
#include <qse/types.h> #include <qse/types.h>
#include <qse/macros.h> #include <qse/macros.h>
#define QSE_RAD_ATTR_TYPE_STRING 0 #define QSE_RADDIC_ATTR_TYPE_STRING 0
#define QSE_RAD_ATTR_TYPE_INTEGER 1 #define QSE_RADDIC_ATTR_TYPE_INTEGER 1
#define QSE_RAD_ATTR_TYPE_IPADDR 2 #define QSE_RADDIC_ATTR_TYPE_IPADDR 2
#define QSE_RAD_ATTR_TYPE_DATE 3 #define QSE_RADDIC_ATTR_TYPE_DATE 3
#define QSE_RAD_ATTR_TYPE_ABINARY 4 #define QSE_RADDIC_ATTR_TYPE_ABINARY 4
#define QSE_RAD_ATTR_TYPE_OCTETS 5 #define QSE_RADDIC_ATTR_TYPE_OCTETS 5
#define QSE_RAD_ATTR_TYPE_IFID 6 #define QSE_RADDIC_ATTR_TYPE_IFID 6
#define QSE_RAD_ATTR_TYPE_IPV6ADDR 7 #define QSE_RADDIC_ATTR_TYPE_IPV6ADDR 7
#define QSE_RAD_ATTR_TYPE_IPV6PREFIX 8 #define QSE_RADDIC_ATTR_TYPE_IPV6PREFIX 8
#define QSE_RAD_ATTR_TYPE_BYTE 9 #define QSE_RADDIC_ATTR_TYPE_BYTE 9
#define QSE_RAD_ATTR_TYPE_SHORT 10 #define QSE_RADDIC_ATTR_TYPE_SHORT 10
#define QSE_RAD_ATTR_TYPE_ETHERNET 11 #define QSE_RADDIC_ATTR_TYPE_ETHERNET 11
#define QSE_RAD_ATTR_TYPE_SIGNED 12 #define QSE_RADDIC_ATTR_TYPE_SIGNED 12
#define QSE_RAD_ATTR_TYPE_COMBO_IP 13 #define QSE_RADDIC_ATTR_TYPE_COMBO_IP 13
#define QSE_RAD_ATTR_TYPE_TLV 14 #define QSE_RADDIC_ATTR_TYPE_TLV 14
struct qse_raddic_attr_flags_t struct qse_raddic_attr_flags_t
{ {
@ -63,16 +63,16 @@ struct qse_raddic_attr_flags_t
}; };
typedef struct qse_raddic_attr_flags_t qse_raddic_attr_flags_t; typedef struct qse_raddic_attr_flags_t qse_raddic_attr_flags_t;
typedef struct qse_raddic_attr_t qse_raddic_attr_t;
struct qse_raddic_attr_t struct qse_raddic_attr_t
{ {
int attr; int attr;
int type; int type;
int vendor; int vendor;
qse_raddic_attr_flags_t flags; qse_raddic_attr_flags_t flags;
qse_raddic_attr_t* nexta;
qse_char_t name[1]; qse_char_t name[1];
}; };
typedef struct qse_raddic_attr_t qse_raddic_attr_t;
struct qse_raddic_value_t struct qse_raddic_value_t
{ {
@ -93,9 +93,12 @@ struct qse_raddic_vendor_t
qse_char_t name[1]; qse_char_t name[1];
}; };
typedef struct qse_raddic_t qse_raddic_t; typedef struct qse_raddic_t qse_raddic_t;
#define QSE_RADDIC_ATTR_MAKE(vendor,value) ((((vendor) & 0xFFFF) << 8) | (value))
#define QSE_RADDIC_ATTR_VENDOR(attr) (((attr) >> 8) & 0xFFFF);
#define QSE_RADDIC_ATTR_VALUE(attr) ((attr) & 0xFF)
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
#endif #endif
@ -122,7 +125,7 @@ QSE_EXPORT qse_raddic_vendor_t* qse_raddic_findvendorbyvalue (
QSE_EXPORT qse_raddic_vendor_t* qse_raddic_addvendor ( QSE_EXPORT qse_raddic_vendor_t* qse_raddic_addvendor (
qse_raddic_t* dic, qse_raddic_t* dic,
const qse_char_t* name, const qse_char_t* name,
int value int vendorpec
); );
QSE_EXPORT int qse_raddic_deletevendorbyname ( QSE_EXPORT int qse_raddic_deletevendorbyname (
@ -132,7 +135,39 @@ QSE_EXPORT int qse_raddic_deletevendorbyname (
QSE_EXPORT int qse_raddic_deletevendorbyvalue ( QSE_EXPORT int qse_raddic_deletevendorbyvalue (
qse_raddic_t* dic, qse_raddic_t* dic,
int value int vendorpec
);
QSE_EXPORT qse_raddic_attr_t* qse_raddic_findattrbyname (
qse_raddic_t* dic,
const qse_char_t* name
);
QSE_EXPORT qse_raddic_attr_t* qse_raddic_findattrbyvalue (
qse_raddic_t* dic,
int attr
);
QSE_EXPORT qse_raddic_attr_t* qse_raddic_addattr (
qse_raddic_t* dic,
const qse_char_t* name,
int vendor,
int type,
int value,
const qse_raddic_attr_flags_t* flags
);
QSE_EXPORT int qse_raddic_deleteattrbyname (
qse_raddic_t* dic,
const qse_char_t* name
);
QSE_EXPORT int qse_raddic_deleteattrbyvalue (
qse_raddic_t* dic,
int attr
); );
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@ -58,12 +58,13 @@ struct qse_raddic_t
qse_htl_t vendors_byname; qse_htl_t vendors_byname;
qse_htl_t vendors_byvalue; qse_htl_t vendors_byvalue;
qse_htl_t attributes_byname; qse_htl_t attrs_byname;
qse_htl_t attributes_byvalue; qse_htl_t attrs_byvalue;
qse_htl_t values_byvalue; qse_htl_t values_byvalue;
qse_htl_t values_byname; qse_htl_t values_byname;
qse_raddic_attr_t *last_attr; qse_raddic_attr_t* last_attr;
qse_raddic_attr_t* base_attrs[256];
}; };
@ -76,24 +77,26 @@ struct name_id_t
static const name_id_t type_table[] = static const name_id_t type_table[] =
{ {
{ "integer", QSE_RAD_ATTR_TYPE_INTEGER }, { "integer", QSE_RADDIC_ATTR_TYPE_INTEGER },
{ "string", QSE_RAD_ATTR_TYPE_STRING }, { "string", QSE_RADDIC_ATTR_TYPE_STRING },
{ "ipaddr", QSE_RAD_ATTR_TYPE_IPADDR }, { "ipaddr", QSE_RADDIC_ATTR_TYPE_IPADDR },
{ "date", QSE_RAD_ATTR_TYPE_DATE }, { "date", QSE_RADDIC_ATTR_TYPE_DATE },
{ "abinary", QSE_RAD_ATTR_TYPE_ABINARY }, { "abinary", QSE_RADDIC_ATTR_TYPE_ABINARY },
{ "octets", QSE_RAD_ATTR_TYPE_OCTETS }, { "octets", QSE_RADDIC_ATTR_TYPE_OCTETS },
{ "ifid", QSE_RAD_ATTR_TYPE_IFID }, { "ifid", QSE_RADDIC_ATTR_TYPE_IFID },
{ "ipv6addr", QSE_RAD_ATTR_TYPE_IPV6ADDR }, { "ipv6addr", QSE_RADDIC_ATTR_TYPE_IPV6ADDR },
{ "ipv6prefix", QSE_RAD_ATTR_TYPE_IPV6PREFIX }, { "ipv6prefix", QSE_RADDIC_ATTR_TYPE_IPV6PREFIX },
{ "byte", QSE_RAD_ATTR_TYPE_BYTE }, { "byte", QSE_RADDIC_ATTR_TYPE_BYTE },
{ "short", QSE_RAD_ATTR_TYPE_SHORT }, { "short", QSE_RADDIC_ATTR_TYPE_SHORT },
{ "ether", QSE_RAD_ATTR_TYPE_ETHERNET }, { "ether", QSE_RADDIC_ATTR_TYPE_ETHERNET },
{ "combo-ip", QSE_RAD_ATTR_TYPE_COMBO_IP }, { "combo-ip", QSE_RADDIC_ATTR_TYPE_COMBO_IP },
{ "tlv", QSE_RAD_ATTR_TYPE_TLV }, { "tlv", QSE_RADDIC_ATTR_TYPE_TLV },
{ "signed", QSE_RAD_ATTR_TYPE_SIGNED }, { "signed", QSE_RADDIC_ATTR_TYPE_SIGNED },
{ QSE_NULL, 0 } { QSE_NULL, 0 }
}; };
/* -------------------------------------------------------------------------- */
static qse_uint32_t dict_vendor_name_hash (qse_htl_t* htl, const void *data) static qse_uint32_t dict_vendor_name_hash (qse_htl_t* htl, const void *data)
{ {
return qse_strcasehash32(((const qse_raddic_vendor_t*)data)->name); return qse_strcasehash32(((const qse_raddic_vendor_t*)data)->name);
@ -135,6 +138,57 @@ static int dict_vendor_value_cmp (qse_htl_t* htl, const void* one, const void* t
return a->vendorpec - b->vendorpec; return a->vendorpec - b->vendorpec;
} }
/* -------------------------------------------------------------------------- */
static qse_uint32_t dict_attr_name_hash (qse_htl_t* htl, const void *data)
{
return qse_strcasehash32(((const qse_raddic_attr_t*)data)->name);
}
static int dict_attr_name_cmp (qse_htl_t* htl, const void* one, const void* two)
{
const qse_raddic_attr_t* a = one;
const qse_raddic_attr_t* b = two;
return qse_strcasecmp(a->name, b->name);
}
static void dict_attr_name_free (qse_htl_t* htl, void* data)
{
QSE_MMGR_FREE (htl->mmgr, data);
}
static qse_uint32_t dict_attr_name_hetero_hash (qse_htl_t* htl, const void* one)
{
return qse_strcasehash32((const qse_char_t*)one);
}
static int dict_attr_name_hetero_cmp (qse_htl_t* htl, const void* one, const void* two)
{
const qse_raddic_attr_t* b = two;
return qse_strcasecmp((const qse_char_t*)one, b->name);
}
static qse_uint32_t dict_attr_value_hash (qse_htl_t* htl, const void* data)
{
const qse_raddic_attr_t* v = (const qse_raddic_attr_t*)data;
qse_uint32_t hv;
hv = qse_genhash32(&v->vendor, QSE_SIZEOF(v->vendor));
return qse_genhash32_update(&v->attr, QSE_SIZEOF(v->attr), hv);
}
static int dict_attr_value_cmp (qse_htl_t* htl, const void* one, const void* two)
{
const qse_raddic_attr_t *a = one;
const qse_raddic_attr_t *b = two;
if (a->vendor < b->vendor) return -1;
if (a->vendor > b->vendor) return -1;
return a->attr - b->attr;
}
/* -------------------------------------------------------------------------- */
int qse_raddic_init (qse_raddic_t* dic, qse_mmgr_t* mmgr) int qse_raddic_init (qse_raddic_t* dic, qse_mmgr_t* mmgr)
{ {
QSE_MEMSET (dic, 0, QSE_SIZEOF(*dic)); QSE_MEMSET (dic, 0, QSE_SIZEOF(*dic));
@ -142,8 +196,8 @@ int qse_raddic_init (qse_raddic_t* dic, qse_mmgr_t* mmgr)
qse_htl_init (&dic->vendors_byname, mmgr, 1); qse_htl_init (&dic->vendors_byname, mmgr, 1);
qse_htl_init (&dic->vendors_byvalue, mmgr, 1); qse_htl_init (&dic->vendors_byvalue, mmgr, 1);
qse_htl_init (&dic->attributes_byname, mmgr, 1); qse_htl_init (&dic->attrs_byname, mmgr, 1);
qse_htl_init (&dic->attributes_byvalue, mmgr, 1); qse_htl_init (&dic->attrs_byvalue, mmgr, 1);
qse_htl_init (&dic->values_byname, mmgr, 1); qse_htl_init (&dic->values_byname, mmgr, 1);
qse_htl_init (&dic->values_byvalue, mmgr, 1); qse_htl_init (&dic->values_byvalue, mmgr, 1);
@ -155,6 +209,15 @@ int qse_raddic_init (qse_raddic_t* dic, qse_mmgr_t* mmgr)
qse_htl_setcomper (&dic->vendors_byvalue, dict_vendor_value_cmp); qse_htl_setcomper (&dic->vendors_byvalue, dict_vendor_value_cmp);
/* no freeer for dic->vendors_byvalue */ /* no freeer for dic->vendors_byvalue */
qse_htl_sethasher (&dic->attrs_byname, dict_attr_name_hash);
qse_htl_setcomper (&dic->attrs_byname, dict_attr_name_cmp);
qse_htl_setfreeer (&dic->attrs_byname, dict_attr_name_free);
qse_htl_sethasher (&dic->attrs_byvalue, dict_attr_value_hash);
qse_htl_setcomper (&dic->attrs_byvalue, dict_attr_value_cmp);
/* no freeer for dic->attrs_byvalue */
return 0; return 0;
} }
@ -162,8 +225,8 @@ void qse_raddic_fini (qse_raddic_t* dic)
{ {
qse_htl_fini (&dic->vendors_byname); qse_htl_fini (&dic->vendors_byname);
qse_htl_fini (&dic->vendors_byvalue); qse_htl_fini (&dic->vendors_byvalue);
qse_htl_fini (&dic->attributes_byname); qse_htl_fini (&dic->attrs_byname);
qse_htl_fini (&dic->attributes_byvalue); qse_htl_fini (&dic->attrs_byvalue);
qse_htl_fini (&dic->values_byvalue); qse_htl_fini (&dic->values_byvalue);
qse_htl_fini (&dic->values_byname); qse_htl_fini (&dic->values_byname);
} }
@ -192,6 +255,7 @@ void qse_raddic_close (qse_raddic_t* dic)
QSE_MMGR_FREE (dic->mmgr, dic); QSE_MMGR_FREE (dic->mmgr, dic);
} }
/* -------------------------------------------------------------------------- */
qse_raddic_vendor_t* qse_raddic_findvendorbyname (qse_raddic_t* dic, const qse_char_t* name) qse_raddic_vendor_t* qse_raddic_findvendorbyname (qse_raddic_t* dic, const qse_char_t* name)
{ {
qse_htl_node_t* np; qse_htl_node_t* np;
@ -214,13 +278,13 @@ qse_raddic_vendor_t* qse_raddic_findvendorbyvalue (qse_raddic_t* dic, int vendor
return (qse_raddic_vendor_t*)np->data; return (qse_raddic_vendor_t*)np->data;
} }
qse_raddic_vendor_t* qse_raddic_addvendor (qse_raddic_t* dic, const qse_char_t* name, int value) qse_raddic_vendor_t* qse_raddic_addvendor (qse_raddic_t* dic, const qse_char_t* name, int vendorpec)
{ {
qse_size_t length; qse_size_t length;
qse_raddic_vendor_t* dv, * old_dv; qse_raddic_vendor_t* dv, * old_dv;
qse_htl_node_t* np; qse_htl_node_t* np;
if (value >= 65535) return QSE_NULL; if (vendorpec <= 0 || vendorpec > 65535) return QSE_NULL;
length = qse_strlen(name); length = qse_strlen(name);
@ -229,7 +293,7 @@ qse_raddic_vendor_t* qse_raddic_addvendor (qse_raddic_t* dic, const qse_char_t*
if (dv == QSE_NULL) return QSE_NULL; if (dv == QSE_NULL) return QSE_NULL;
qse_strcpy(dv->name, name); qse_strcpy(dv->name, name);
dv->vendorpec = value; dv->vendorpec = vendorpec;
dv->type = dv->length = 1; /* defaults */ dv->type = dv->length = 1; /* defaults */
dv->nextv = QSE_NULL; dv->nextv = QSE_NULL;
@ -310,11 +374,11 @@ int qse_raddic_deletevendorbyname (qse_raddic_t* dic, const qse_char_t* name)
return 0; return 0;
} }
int qse_raddic_deletevendorbyvalue (qse_raddic_t* dic, int value) int qse_raddic_deletevendorbyvalue (qse_raddic_t* dic, int vendorpec)
{ {
qse_raddic_vendor_t* dv; qse_raddic_vendor_t* dv;
dv = qse_raddic_findvendorbyvalue(dic, value); dv = qse_raddic_findvendorbyvalue(dic, vendorpec);
if (!dv) return -1; if (!dv) return -1;
if (dv->nextv) if (dv->nextv)
@ -333,6 +397,162 @@ int qse_raddic_deletevendorbyvalue (qse_raddic_t* dic, int value)
return 0; return 0;
} }
/* -------------------------------------------------------------------------- */
qse_raddic_attr_t* qse_raddic_findattrbyname (qse_raddic_t* dic, const qse_char_t* name)
{
qse_htl_node_t* np;
np = qse_htl_heterosearch (&dic->attrs_byname, name, dict_attr_name_hetero_hash, dict_attr_name_hetero_cmp);
if (!np) return QSE_NULL;
return (qse_raddic_attr_t*)np->data;
}
qse_raddic_attr_t* qse_raddic_findattrbyvalue (qse_raddic_t* dic, int attr)
{
qse_htl_node_t* np;
qse_raddic_attr_t dv;
/* simple cache lookup for basic attributes */
if (attr >= 0 && attr <= 255) return dic->base_attrs[attr];
dv.attr = attr;
dv.vendor = QSE_RADDIC_ATTR_VENDOR(attr);
np = qse_htl_search (&dic->attrs_byvalue, &dv);
if (!np) return QSE_NULL;
return (qse_raddic_attr_t*)np->data;
}
qse_raddic_attr_t* qse_raddic_addattr (qse_raddic_t* dic, const qse_char_t* name, int vendor, int type, int value, const qse_raddic_attr_flags_t* flags)
{
qse_size_t length;
qse_raddic_attr_t* dv, * old_dv;
qse_htl_node_t* np;
if (vendor < 0 || vendor > 65535) return QSE_NULL; /* 0 is allowed to mean no vendor */
if (value < 0 || value > 255) return QSE_NULL;
length = qse_strlen(name);
if (vendor > 0)
{
/* TODO: validation ... */
}
/* no +1 for the terminating null because dv->name is char[1] */
dv = QSE_MMGR_ALLOC(dic->mmgr, QSE_SIZEOF(*dv) + (length * QSE_SIZEOF(*name)));
if (dv == QSE_NULL) return QSE_NULL;
qse_strcpy(dv->name, name);
dv->attr = QSE_RADDIC_ATTR_MAKE(vendor, value);
dv->vendor = vendor;
dv->type = type;
dv->flags = *flags;
dv->nexta = QSE_NULL;
/* return an existing item or insert a new item */
np = qse_htl_ensert(&dic->attrs_byname, dv);
if (!np || np->data != dv)
{
/* insertion failure or existing item found */
QSE_MMGR_FREE (dic->mmgr, dv);
return QSE_NULL;
}
/* attempt to update the lookup table by value */
np = qse_htl_upyank(&dic->attrs_byvalue, dv, (void**)&old_dv);
if (np)
{
/* updated the existing item successfully.
* link the old item to the current item */
QSE_ASSERT (np->data == dv);
QSE_ASSERT (dv->attr == old_dv->attr);
dv->nexta = old_dv;
}
else
{
/* update failure, this entry must be new. try insertion */
if (!qse_htl_insert (&dic->attrs_byvalue, dv))
{
qse_htl_delete (&dic->attrs_byname, dv);
return QSE_NULL;
}
}
if (vendor == 0) dic->base_attrs[value] = dv; /* cache base attributes */
return dv;
}
int qse_raddic_deleteattrbyname (qse_raddic_t* dic, const qse_char_t* name)
{
qse_raddic_attr_t* dv, * dv2;
dv = qse_raddic_findattrbyname(dic, name);
if (!dv) return -1;
dv2 = qse_raddic_findattrbyvalue(dic, dv->attr);
QSE_ASSERT (dv2 != QSE_NULL);
if (dv != dv2)
{
qse_raddic_attr_t* x, * y;
QSE_ASSERT (qse_strcasecmp(dv->name, dv2->name) != 0);
QSE_ASSERT (dv->attr == dv2->attr);
QSE_ASSERT (dv->vendor == dv2->vendor);
/* when the attr of the given name is not the first one
* referenced by value, i need to unlink the attr from the
* attr chains with the same ID */
x = dv2;
y = QSE_NULL;
while (x)
{
if (x == dv)
{
if (y) y->nexta = x->nexta;
break;
}
y = x;
x = x->nexta;
}
}
else
{
/* this is the only attr with the attr ID. i can
* safely remove it from the lookup table by value */
qse_htl_delete (&dic->attrs_byvalue, dv);
}
/* delete the attr from the lookup table by name */
qse_htl_delete (&dic->attrs_byname, dv);
return 0;
}
int qse_raddic_deleteattrbyvalue (qse_raddic_t* dic, int attr)
{
qse_raddic_attr_t* dv;
dv = qse_raddic_findattrbyvalue(dic, attr);
if (!dv) return -1;
if (dv->nexta)
{
qse_htl_update (&dic->attrs_byvalue, dv->nexta);
}
else
{
/* this is the only attr with the attr ID. i can
* safely remove it from the lookup table by value */
qse_htl_delete (&dic->attrs_byvalue, dv);
}
/* delete the attr from the lookup table by name */
qse_htl_delete (&dic->attrs_byname, dv);
return 0;
}
/* -------------------------------------------------------------------------- */
#if 0 // XXX #if 0 // XXX
/* /*
* Get an attribute by its numerical value. * Get an attribute by its numerical value.
@ -488,7 +708,7 @@ int dict_addvalue(qse_raddic_t* dic, const qse_char_t* namestr, const qse_char_t
*/ */
switch (dattr->type) switch (dattr->type)
{ {
case QSE_RAD_ATTR_TYPE_BYTE: case QSE_RADDIC_ATTR_TYPE_BYTE:
if (value > 255) if (value > 255)
{ {
fr_pool_free(dval); fr_pool_free(dval);
@ -496,7 +716,7 @@ int dict_addvalue(qse_raddic_t* dic, const qse_char_t* namestr, const qse_char_t
return -1; return -1;
} }
break; break;
case QSE_RAD_ATTR_TYPE_SHORT: case QSE_RADDIC_ATTR_TYPE_SHORT:
if (value > 65535) if (value > 65535)
{ {
fr_pool_free(dval); fr_pool_free(dval);
@ -509,8 +729,8 @@ int dict_addvalue(qse_raddic_t* dic, const qse_char_t* namestr, const qse_char_t
* Allow octets for now, because * Allow octets for now, because
* of dictionary.cablelabs * of dictionary.cablelabs
*/ */
case QSE_RAD_ATTR_TYPE_OCTETS: case QSE_RADDIC_ATTR_TYPE_OCTETS:
case QSE_RAD_ATTR_TYPE_INTEGER: case QSE_RADDIC_ATTR_TYPE_INTEGER:
break; break;
default: default:
@ -839,7 +1059,7 @@ static int load_file (qse_raddic_t* dic, const qse_char_t *dir, const qse_char_t
goto oops; goto oops;
} }
if (da->type != QSE_RAD_ATTR_TYPE_TLV) if (da->type != QSE_RADDIC_ATTR_TYPE_TLV)
{ {
fr_strerror_printf("dict_init: %s[%d]: attribute %s is not of type tlv", fn, line, argv[1]); fr_strerror_printf("dict_init: %s[%d]: attribute %s is not of type tlv", fn, line, argv[1]);
goto oops; goto oops;
@ -980,21 +1200,21 @@ typedef struct value_fixup_t {
static value_fixup_t *value_fixup = QSE_NULL; static value_fixup_t *value_fixup = QSE_NULL;
static const FR_NAME_NUMBER type_table[] = { static const FR_NAME_NUMBER type_table[] = {
{ "integer", QSE_RAD_ATTR_TYPE_INTEGER }, { "integer", QSE_RADDIC_ATTR_TYPE_INTEGER },
{ "string", QSE_RAD_ATTR_TYPE_STRING }, { "string", QSE_RADDIC_ATTR_TYPE_STRING },
{ "ipaddr", QSE_RAD_ATTR_TYPE_IPADDR }, { "ipaddr", QSE_RADDIC_ATTR_TYPE_IPADDR },
{ "date", QSE_RAD_ATTR_TYPE_DATE }, { "date", QSE_RADDIC_ATTR_TYPE_DATE },
{ "abinary", QSE_RAD_ATTR_TYPE_ABINARY }, { "abinary", QSE_RADDIC_ATTR_TYPE_ABINARY },
{ "octets", QSE_RAD_ATTR_TYPE_OCTETS }, { "octets", QSE_RADDIC_ATTR_TYPE_OCTETS },
{ "ifid", QSE_RAD_ATTR_TYPE_IFID }, { "ifid", QSE_RADDIC_ATTR_TYPE_IFID },
{ "ipv6addr", QSE_RAD_ATTR_TYPE_IPV6ADDR }, { "ipv6addr", QSE_RADDIC_ATTR_TYPE_IPV6ADDR },
{ "ipv6prefix", QSE_RAD_ATTR_TYPE_IPV6PREFIX }, { "ipv6prefix", QSE_RADDIC_ATTR_TYPE_IPV6PREFIX },
{ "byte", QSE_RAD_ATTR_TYPE_BYTE }, { "byte", QSE_RADDIC_ATTR_TYPE_BYTE },
{ "short", QSE_RAD_ATTR_TYPE_SHORT }, { "short", QSE_RADDIC_ATTR_TYPE_SHORT },
{ "ether", QSE_RAD_ATTR_TYPE_ETHERNET }, { "ether", QSE_RADDIC_ATTR_TYPE_ETHERNET },
{ "combo-ip", QSE_RAD_ATTR_TYPE_COMBO_IP }, { "combo-ip", QSE_RADDIC_ATTR_TYPE_COMBO_IP },
{ "tlv", QSE_RAD_ATTR_TYPE_TLV }, { "tlv", QSE_RADDIC_ATTR_TYPE_TLV },
{ "signed", QSE_RAD_ATTR_TYPE_SIGNED }, { "signed", QSE_RADDIC_ATTR_TYPE_SIGNED },
{ QSE_NULL, 0 } { QSE_NULL, 0 }
}; };
@ -1564,11 +1784,11 @@ static int process_attribute (
flags.array = 1; flags.array = 1;
switch (type) { switch (type) {
case QSE_RAD_ATTR_TYPE_IPADDR: case QSE_RADDIC_ATTR_TYPE_IPADDR:
case QSE_RAD_ATTR_TYPE_BYTE: case QSE_RADDIC_ATTR_TYPE_BYTE:
case QSE_RAD_ATTR_TYPE_SHORT: case QSE_RADDIC_ATTR_TYPE_SHORT:
case QSE_RAD_ATTR_TYPE_INTEGER: case QSE_RADDIC_ATTR_TYPE_INTEGER:
case QSE_RAD_ATTR_TYPE_DATE: case QSE_RADDIC_ATTR_TYPE_DATE:
break; break;
default: default:
@ -1599,8 +1819,8 @@ static int process_attribute (
* Only string, octets, and integer can be tagged. * Only string, octets, and integer can be tagged.
*/ */
switch (type) { switch (type) {
case QSE_RAD_ATTR_TYPE_STRING: case QSE_RADDIC_ATTR_TYPE_STRING:
case QSE_RAD_ATTR_TYPE_INTEGER: case QSE_RADDIC_ATTR_TYPE_INTEGER:
break; break;
default: default:
@ -1612,7 +1832,7 @@ static int process_attribute (
} }
} }
if (type == QSE_RAD_ATTR_TYPE_TLV) { if (type == QSE_RADDIC_ATTR_TYPE_TLV) {
flags.has_tlv = 1; flags.has_tlv = 1;
} }
@ -2098,7 +2318,7 @@ static int my_dict_init(const char *dir, const char *fn,
return -1; return -1;
} }
if (da->type != QSE_RAD_ATTR_TYPE_TLV) { if (da->type != QSE_RADDIC_ATTR_TYPE_TLV) {
fr_strerror_printf( fr_strerror_printf(
"dict_init: %s[%d]: attribute %s is not of type tlv", "dict_init: %s[%d]: attribute %s is not of type tlv",
fn, line, argv[1]); fn, line, argv[1]);

View File

@ -17,6 +17,7 @@ static int test1 ()
{ {
qse_raddic_t* dic; qse_raddic_t* dic;
qse_raddic_vendor_t* vendor, * v; qse_raddic_vendor_t* vendor, * v;
qse_raddic_attr_t* attr, * a;
int i; int i;
dic = qse_raddic_open (QSE_MMGR_GETDFL(), 0); dic = qse_raddic_open (QSE_MMGR_GETDFL(), 0);
@ -47,7 +48,7 @@ static int test1 ()
#define COUNT1 600 #define COUNT1 600
#define COUNT2 700 #define COUNT2 700
for (i = 0; i < COUNT1; i++) for (i = 1; i < COUNT1; i++)
{ {
qse_char_t tmp[64]; qse_char_t tmp[64];
qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test%d"), i); qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test%d"), i);
@ -57,7 +58,7 @@ static int test1 ()
_assert (qse_strcasecmp(vendor->name, tmp) == 0, "wrong vendor name"); _assert (qse_strcasecmp(vendor->name, tmp) == 0, "wrong vendor name");
} }
for (i = 0; i < COUNT1; i++) for (i = 1; i < COUNT1; i++)
{ {
qse_char_t tmp[64]; qse_char_t tmp[64];
qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test%d"), i); qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test%d"), i);
@ -67,7 +68,7 @@ static int test1 ()
_assert (qse_strcasecmp(vendor->name, tmp) == 0, "wrong vendor name"); _assert (qse_strcasecmp(vendor->name, tmp) == 0, "wrong vendor name");
} }
for (i = 0; i < COUNT1; i++) for (i = 1; i < COUNT1; i++)
{ {
qse_char_t tmp[64]; qse_char_t tmp[64];
qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test%d"), i); qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test%d"), i);
@ -120,7 +121,7 @@ static int test1 ()
} }
} }
for (i = 0; i < COUNT1; i++) for (i = 1; i < COUNT1; i++)
{ {
qse_char_t tmp[64]; qse_char_t tmp[64];
int n; int n;
@ -130,7 +131,7 @@ static int test1 ()
_assert (n == 0, "unable to delete a vendor"); _assert (n == 0, "unable to delete a vendor");
} }
for (i = 0; i < COUNT1; i++) for (i = 1; i < COUNT1; i++)
{ {
qse_char_t tmp[64]; qse_char_t tmp[64];
qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test%d"), i); qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test%d"), i);
@ -146,7 +147,7 @@ static int test1 ()
_assert (v != QSE_NULL && v->vendorpec == i, "unable to add a vendor"); _assert (v != QSE_NULL && v->vendorpec == i, "unable to add a vendor");
} }
for (i = 0; i < COUNT1; i++) for (i = 1; i < COUNT1; i++)
{ {
int n; int n;
n = qse_raddic_deletevendorbyvalue (dic, i); n = qse_raddic_deletevendorbyvalue (dic, i);
@ -166,10 +167,149 @@ static int test1 ()
return 0; return 0;
} }
static int test2 ()
{
qse_raddic_t* dic;
qse_raddic_attr_t* attr, * v;
qse_raddic_attr_flags_t f;
int i, j;
dic = qse_raddic_open (QSE_MMGR_GETDFL(), 0);
_assert (dic != QSE_NULL, "unable to create a radius dictionary");
for (j = 0; j < 100; j++)
{
for (i = 0; i <= 255; i++)
{
qse_char_t tmp[64];
qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test%d-%d"), j, i);
attr = qse_raddic_addattr (dic, tmp, j, QSE_RADDIC_ATTR_TYPE_STRING, i, &f);
_assert (attr != QSE_NULL, "unable to add an attribute");
_assert (attr->attr == QSE_RADDIC_ATTR_MAKE(j, i), "wrong attr value");
_assert (qse_strcasecmp(attr->name, tmp) == 0, "wrong attr name");
}
}
for (j = 0; j < 100; j++)
{
for (i = 0; i <= 255; i++)
{
qse_char_t tmp[64];
qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test%d-%d"), j, i);
attr = qse_raddic_findattrbyname (dic, tmp);
_assert (attr != QSE_NULL, "unable to add an attribute");
_assert (attr->attr == QSE_RADDIC_ATTR_MAKE(j, i), "wrong attr value");
_assert (qse_strcasecmp(attr->name, tmp) == 0, "wrong attr name");
}
}
#if 0
for (i = 0; i < COUNT1; i++)
{
qse_char_t tmp[64];
qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test%d"), i);
attr = qse_raddic_findattrbyvalue (dic, i);
_assert (attr != QSE_NULL, "unable to find an attribute");
_assert (attr->attr == i, "wrong attr value");
_assert (qse_strcasecmp(attr->name, tmp) == 0, "wrong attr name");
}
for (i = COUNT1; i < COUNT2; i++)
{
qse_char_t tmp[64];
qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test%d"), i);
attr = qse_raddic_addattr (dic, tmp, COUNT1);
// insert different items with the same value
_assert (attr != QSE_NULL, "unable to add an attribute");
_assert (attr->attr == COUNT1, "wrong attr value");
_assert (qse_strcasecmp(attr->name, tmp) == 0, "wrong attr name");
v = qse_raddic_findattrbyvalue (dic, COUNT1);
_assert (attr == v, "unable to find a last added attr by value");
}
for (i = COUNT1; i < COUNT2 - 1; i++)
{
qse_char_t tmp[64];
int n;
qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test%d"), i);
n = qse_raddic_deleteattrbyname (dic, tmp);
_assert (n == 0, "unable to delete an attribute");
v = qse_raddic_findattrbyname (dic, tmp);
_assert (v == QSE_NULL, "attr found errorenously");
if (i == COUNT2 - 1)
{
v = qse_raddic_findattrbyvalue (dic, COUNT1);
_assert (v == QSE_NULL, "attr of COUNT1 found errorenously");
}
else
{
qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test%d"), i + 1);
v = qse_raddic_findattrbyname (dic, tmp);
_assert (v != QSE_NULL && v->attr == COUNT1 && qse_strcasecmp(tmp, v->name) == 0, "unable to find an expected attr");
v = qse_raddic_findattrbyvalue (dic, COUNT1);
_assert (v != QSE_NULL && v->attr == COUNT1, "unable to find the attr of COUNT1");
}
}
for (i = 0; i < COUNT1; i++)
{
qse_char_t tmp[64];
int n;
qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test%d"), i);
n = qse_raddic_deleteattrbyname (dic, tmp);
_assert (n == 0, "unable to delete an attribute");
}
for (i = 0; i < COUNT1; i++)
{
qse_char_t tmp[64];
qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test%d"), i);
v = qse_raddic_addattr (dic, tmp, i);
_assert (v != QSE_NULL && v->attr == i, "unable to add an attribute");
qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("testx%d"), i);
v = qse_raddic_addattr (dic, tmp, i);
_assert (v != QSE_NULL && v->attr == i, "unable to add an attribute");
qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("testy%d"), i);
v = qse_raddic_addattr (dic, tmp, i);
_assert (v != QSE_NULL && v->attr == i, "unable to add an attribute");
}
for (i = 0; i < COUNT1; i++)
{
int n;
n = qse_raddic_deleteattrbyvalue (dic, i);
_assert (n == 0, "unable to delete an attribute by value");
n = qse_raddic_deleteattrbyvalue (dic, i);
_assert (n == 0, "unable to delete an attribute by value");
n = qse_raddic_deleteattrbyvalue (dic, i);
_assert (n == 0, "unable to delete an attribute by value");
n = qse_raddic_deleteattrbyvalue (dic, i);
_assert (n <= -1, "erroreneously successful attr deletion by value");
}
#endif
qse_raddic_close (dic);
return 0;
}
int main () int main ()
{ {
qse_open_stdsios (); qse_open_stdsios ();
R (test1); R (test1);
R (test2);
qse_close_stdsios (); qse_close_stdsios ();
return 0; return 0;
} }