added an experimental function qse_rad_insert_extended_vendor_specific_attribute() to support EVS. yet a lot of wors are to be done to support tag, extended, long-extended, tlv
This commit is contained in:
		| @ -30,6 +30,8 @@ | ||||
| #include <qse/types.h> | ||||
| #include <qse/macros.h> | ||||
|  | ||||
| /* TODO: extended, long-extended, tlv, evs */ | ||||
|  | ||||
| enum qse_raddic_opt_t | ||||
| { | ||||
| 	QSE_RADDIC_TRAIT | ||||
| @ -182,7 +184,7 @@ typedef struct qse_raddic_const_t qse_raddic_const_t; | ||||
| struct qse_raddic_const_t | ||||
| { | ||||
| 	qse_uint32_t             attr;     /* vendor + attribute-value */ | ||||
| 	qse_raddic_const_value_t value; | ||||
| 	qse_uintmax_t            value; | ||||
| 	qse_raddic_const_t*      nextc; | ||||
| 	qse_char_t               name[1]; | ||||
| }; | ||||
| @ -190,7 +192,7 @@ struct qse_raddic_const_t | ||||
| typedef struct qse_raddic_vendor_t qse_raddic_vendor_t; | ||||
| struct qse_raddic_vendor_t | ||||
| { | ||||
| 	int                  vendorpec; | ||||
| 	unsigned int         vendorpec; | ||||
| 	int                  type; | ||||
| 	int                  length; | ||||
| 	int                  flags; | ||||
| @ -265,13 +267,13 @@ QSE_EXPORT qse_raddic_vendor_t* qse_raddic_findvendorbyname ( | ||||
|  | ||||
| QSE_EXPORT qse_raddic_vendor_t* qse_raddic_findvendorbyvalue ( | ||||
| 	qse_raddic_t*     dic, | ||||
| 	int               vendorpec | ||||
| 	unsigned int      vendorpec | ||||
| ); | ||||
|  | ||||
| QSE_EXPORT qse_raddic_vendor_t* qse_raddic_addvendor ( | ||||
| 	qse_raddic_t*     dic, | ||||
| 	const qse_char_t* name, | ||||
| 	int               vendorpec | ||||
| 	unsigned int      vendorpec | ||||
| ); | ||||
|  | ||||
| QSE_EXPORT int qse_raddic_deletevendorbyname ( | ||||
| @ -281,7 +283,7 @@ QSE_EXPORT int qse_raddic_deletevendorbyname ( | ||||
|  | ||||
| QSE_EXPORT int qse_raddic_deletevendorbyvalue ( | ||||
| 	qse_raddic_t*     dic, | ||||
| 	int               vendorpec | ||||
| 	unsigned int      vendorpec | ||||
| ); | ||||
|  | ||||
|  | ||||
| @ -298,9 +300,9 @@ QSE_EXPORT qse_raddic_attr_t* qse_raddic_findattrbyvalue ( | ||||
| QSE_EXPORT qse_raddic_attr_t* qse_raddic_addattr ( | ||||
| 	qse_raddic_t*                  dic, | ||||
| 	const qse_char_t*              name, | ||||
| 	int                            vendor, | ||||
| 	unsigned int                   vendor, | ||||
| 	qse_raddic_attr_type_t         type, | ||||
| 	int                            value, | ||||
| 	unsigned int                   value, | ||||
| 	const qse_raddic_attr_flags_t* flags | ||||
| ); | ||||
|  | ||||
| @ -324,14 +326,14 @@ QSE_EXPORT qse_raddic_const_t* qse_raddic_findconstbyname ( | ||||
| QSE_EXPORT qse_raddic_const_t* qse_raddic_findconstbyvalue ( | ||||
| 	qse_raddic_t*      dic, | ||||
| 	qse_uint32_t       attr, | ||||
| 	const qse_raddic_const_value_t* value | ||||
| 	qse_uintmax_t      value | ||||
| ); | ||||
|  | ||||
| QSE_EXPORT qse_raddic_const_t* qse_raddic_addconst ( | ||||
| 	qse_raddic_t*      dic, | ||||
| 	const qse_char_t*  name, | ||||
| 	const qse_char_t*  attrstr, | ||||
| 	const qse_raddic_const_value_t* value | ||||
| 	qse_uintmax_t      value | ||||
| ); | ||||
|  | ||||
| QSE_EXPORT int qse_raddic_deleteconstbyname ( | ||||
| @ -343,7 +345,7 @@ QSE_EXPORT int qse_raddic_deleteconstbyname ( | ||||
| QSE_EXPORT int qse_raddic_deleteconstbyvalue ( | ||||
| 	qse_raddic_t*     dic, | ||||
| 	qse_uint32_t      attr, | ||||
| 	const qse_raddic_const_value_t* value | ||||
| 	qse_uintmax_t     value | ||||
| ); | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -27,6 +27,8 @@ | ||||
| #ifndef _QSE_RAD_RADMSG_H_ | ||||
| #define _QSE_RAD_RADMSG_H_ | ||||
|  | ||||
| /* TODO: tag, extended, long-extended, tlv, evs */ | ||||
|  | ||||
| #include <qse/types.h> | ||||
| #include <qse/macros.h> | ||||
| #include <qse/cmn/ipad.h> | ||||
| @ -56,12 +58,18 @@ typedef enum qse_rad_code_t qse_rad_code_t; | ||||
| #define QSE_RAD_MAX_AUTHENTICATOR_LEN 16 | ||||
| #define QSE_RAD_MAX_ATTR_VALUE_LEN  (QSE_TYPE_MAX(qse_uint8_t) - QSE_SIZEOF(qse_rad_attr_hdr_t)) | ||||
| #define QSE_RAD_MAX_VSATTR_VALUE_LEN (QSE_TYPE_MAX(qse_uint8_t) - QSE_SIZEOF(qse_rad_attr_hdr_t) - QSE_SIZEOF(qse_rad_vsattr_hdr_t)) | ||||
| #define QSE_RAD_MAX_EXTVSATTR_VALUE_LEN (QSE_TYPE_MAX(qse_uint8_t) - QSE_SIZEOF(qse_rad_extvsattr_hdr_t)) | ||||
|  | ||||
|  | ||||
| typedef struct qse_rad_hdr_t qse_rad_hdr_t; | ||||
| typedef struct qse_rad_attr_hdr_t qse_rad_attr_hdr_t; | ||||
| typedef struct qse_rad_vsattr_hdr_t qse_rad_vsattr_hdr_t; | ||||
| typedef struct qse_rad_attr_int_t qse_rad_attr_int_t; | ||||
| typedef struct qse_rad_extvsattr_hdr_t qse_rad_extvsattr_hdr_t; /* evs */ | ||||
|  | ||||
| typedef struct qse_rad_attr_uint32_t qse_rad_attr_uint32_t; | ||||
| #if (QSE_SIZEOF_UINT64_T > 0) | ||||
| typedef struct qse_rad_attr_uint64_t qse_rad_attr_uint64_t; | ||||
| #endif | ||||
|  | ||||
| #include <qse/pack1.h> | ||||
| struct qse_rad_hdr_t  | ||||
| @ -80,16 +88,34 @@ struct qse_rad_attr_hdr_t | ||||
|  | ||||
| struct qse_rad_vsattr_hdr_t | ||||
| { | ||||
| 	qse_uint8_t  id; | ||||
| 	qse_uint8_t  length; | ||||
| 	qse_uint8_t  id; /* type */ | ||||
| 	qse_uint8_t  length; /* length */ | ||||
| 	qse_uint32_t vendor; /* in network-byte order */ | ||||
| }; | ||||
|  | ||||
| struct qse_rad_attr_int_t | ||||
| struct qse_rad_extvsattr_hdr_t | ||||
| { | ||||
| 	qse_uint8_t id; /* one of 241-244 */ | ||||
| 	qse_uint8_t length; | ||||
| 	qse_uint8_t xid;  /* extended type. 26 for evs */ | ||||
| 	qse_uint32_t vendor; /* in network-byte order */ | ||||
| 	qse_uint8_t evsid; | ||||
| }; | ||||
|  | ||||
| struct qse_rad_attr_uint32_t | ||||
| { | ||||
| 	qse_rad_attr_hdr_t hdr; | ||||
| 	qse_uint32_t val; | ||||
| }; | ||||
|  | ||||
| #if (QSE_SIZEOF_UINT64_T > 0) | ||||
| struct qse_rad_attr_uint64_t | ||||
| { | ||||
| 	qse_rad_attr_hdr_t hdr; | ||||
| 	qse_uint64_t val; | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| #include <qse/unpack.h> | ||||
|  | ||||
|  | ||||
| @ -266,7 +292,7 @@ QSE_EXPORT int qse_rad_insert_wide_string_attribute_with_length ( | ||||
| 	qse_uint8_t        length | ||||
| ); | ||||
|  | ||||
| QSE_EXPORT int qse_rad_insert_integer_attribute ( | ||||
| QSE_EXPORT int qse_rad_insert_uint32_attribute ( | ||||
| 	qse_rad_hdr_t*     auth,  | ||||
| 	int                max, | ||||
| 	qse_uint32_t       vendor, /* in host-byte order */ | ||||
| @ -292,6 +318,18 @@ QSE_EXPORT int qse_rad_insert_giga_attribute ( | ||||
| 	qse_uint64_t      value | ||||
| ); | ||||
|  | ||||
| QSE_EXPORT int qse_rad_insert_extended_vendor_specific_attribute ( | ||||
| 	qse_rad_hdr_t*  auth, | ||||
| 	int             max, | ||||
| 	qse_uint8_t     base, /* one of 241-244 */ | ||||
| 	qse_uint32_t    vendor, | ||||
| 	qse_uint8_t     attrid,  | ||||
| 	const void*     ptr, | ||||
| 	qse_uint8_t     len | ||||
| ); | ||||
|  | ||||
| /* TODO: QSE_EXPORT int qse_rad_delete_extended_vendor_specific_attribute () */ | ||||
|  | ||||
| QSE_EXPORT int qse_rad_set_user_password ( | ||||
| 	qse_rad_hdr_t*      auth, | ||||
| 	int                 max, | ||||
| @ -329,7 +367,6 @@ QSE_EXPORT int qse_rad_verify_response ( | ||||
| 	const qse_mchar_t*     secret | ||||
| ); | ||||
|  | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
| @ -62,6 +62,8 @@ struct const_fixup_t | ||||
| { | ||||
| 	const_fixup_t*        next; | ||||
| 	qse_raddic_const_t*   dval; | ||||
| 	qse_size_t            line; | ||||
| 	qse_char_t*           fn; | ||||
| 	qse_char_t            attrstr[1]; | ||||
| }; | ||||
|  | ||||
| @ -341,13 +343,10 @@ static int dict_const_value_cmp (qse_htl_t* htl, const void* one, const void* tw | ||||
| 	if (a->attr < b->attr) return -1; | ||||
| 	if (a->attr > b->attr) return 1; | ||||
|  | ||||
| 	if (a->value.type != b->value.type) return -2; /* cannot really compare */ | ||||
| 	if (a->value < b->value) return -1; | ||||
| 	if (a->value > b->value) return 1; | ||||
|  | ||||
| 	/* this function actuall requires to check equality. | ||||
| 	 * it doesn't have to return greaterness or lessness. | ||||
| 	 * it also assumes that the unused space in the 'value'  | ||||
| 	 * union field is all initialized to zero */ | ||||
| 	return QSE_MEMCMP(&a->value, &b->value, QSE_SIZEOF(a->value)); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* -------------------------------------------------------------------------- */ | ||||
| @ -555,7 +554,7 @@ qse_raddic_vendor_t* qse_raddic_findvendorbyname (qse_raddic_t* dic, const qse_c | ||||
| /* | ||||
|  *	Return the vendor struct based on the PEC. | ||||
|  */ | ||||
| qse_raddic_vendor_t* qse_raddic_findvendorbyvalue (qse_raddic_t* dic, int vendorpec) | ||||
| qse_raddic_vendor_t* qse_raddic_findvendorbyvalue (qse_raddic_t* dic, unsigned int vendorpec) | ||||
| { | ||||
| 	qse_htl_node_t* np; | ||||
| 	qse_raddic_vendor_t dv; | ||||
| @ -564,13 +563,13 @@ qse_raddic_vendor_t* qse_raddic_findvendorbyvalue (qse_raddic_t* dic, int vendor | ||||
| 	np = qse_htl_search (&dic->vendors_byvalue, &dv); | ||||
| 	if (!np)  | ||||
| 	{ | ||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ENOENT, QSE_T("cannot find a vendor of value %d"), vendorpec); | ||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ENOENT, QSE_T("cannot find a vendor of value %u"), vendorpec); | ||||
| 		return QSE_NULL; | ||||
| 	} | ||||
| 	return (qse_raddic_vendor_t*)np->data; | ||||
| } | ||||
|  | ||||
| qse_raddic_vendor_t* qse_raddic_addvendor (qse_raddic_t* dic, const qse_char_t* name, int vendorpec) | ||||
| qse_raddic_vendor_t* qse_raddic_addvendor (qse_raddic_t* dic, const qse_char_t* name, unsigned int vendorpec) | ||||
| { | ||||
| 	qse_size_t length; | ||||
| 	qse_raddic_vendor_t* dv, * old_dv; | ||||
| @ -578,7 +577,7 @@ qse_raddic_vendor_t* qse_raddic_addvendor (qse_raddic_t* dic, const qse_char_t* | ||||
|  | ||||
| 	if (vendorpec <= 0 || vendorpec > 65535)  | ||||
| 	{ | ||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_EINVAL, QSE_T("vendor value %d out of accepted range"), vendorpec); | ||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_EINVAL, QSE_T("vendor value %u out of accepted range"), vendorpec); | ||||
| 		return QSE_NULL; | ||||
| 	} | ||||
|  | ||||
| @ -678,7 +677,7 @@ int qse_raddic_deletevendorbyname (qse_raddic_t* dic, const qse_char_t* name) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int qse_raddic_deletevendorbyvalue (qse_raddic_t* dic, int vendorpec) | ||||
| int qse_raddic_deletevendorbyvalue (qse_raddic_t* dic, unsigned int vendorpec) | ||||
| { | ||||
| 	qse_raddic_vendor_t* dv; | ||||
|  | ||||
| @ -734,21 +733,21 @@ qse_raddic_attr_t* qse_raddic_findattrbyvalue (qse_raddic_t* dic, qse_uint32_t a | ||||
| 	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, qse_raddic_attr_type_t type, int value, const qse_raddic_attr_flags_t* flags) | ||||
| qse_raddic_attr_t* qse_raddic_addattr (qse_raddic_t* dic, const qse_char_t* name, unsigned int vendor, qse_raddic_attr_type_t type, unsigned 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)  | ||||
| 	if (vendor < 0 || vendor > 65535u)  | ||||
| 	{ | ||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_EINVAL, QSE_T("vendor %d out of accepted range"), vendor); | ||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_EINVAL, QSE_T("vendor %u out of accepted range"), vendor); | ||||
| 		return QSE_NULL; /* 0 is allowed to mean no vendor */ | ||||
| 	} | ||||
| 	if (value < 0 || value > 65535)   | ||||
| 	if (value < 0 || value > 65535u)   | ||||
| 	{ | ||||
| 		/* the upper bound is not 255 because there are vendors defining values in 16-bit format */ | ||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_EINVAL, QSE_T("attribute value %d out of accepted range"), value); | ||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_EINVAL, QSE_T("attribute value %u out of accepted range"), value); | ||||
| 		return QSE_NULL; | ||||
| 	} | ||||
|  | ||||
| @ -915,13 +914,13 @@ qse_raddic_const_t* qse_raddic_findconstbyname (qse_raddic_t* dic, qse_uint32_t | ||||
| 	return (qse_raddic_const_t*)np->data; | ||||
| } | ||||
|  | ||||
| qse_raddic_const_t* qse_raddic_findconstbyvalue (qse_raddic_t* dic, qse_uint32_t attr, const  qse_raddic_const_value_t* value) | ||||
| qse_raddic_const_t* qse_raddic_findconstbyvalue (qse_raddic_t* dic, qse_uint32_t attr, qse_uintmax_t value) | ||||
| { | ||||
| 	qse_htl_node_t* np; | ||||
| 	qse_raddic_const_t dval; | ||||
|  | ||||
| 	dval.attr = attr; | ||||
| 	dval.value = *value; | ||||
| 	dval.value = value; | ||||
| 	np = qse_htl_search (&dic->consts_byvalue, &dval); | ||||
| 	if (!np) | ||||
| 	{ | ||||
| @ -931,12 +930,64 @@ qse_raddic_const_t* qse_raddic_findconstbyvalue (qse_raddic_t* dic, qse_uint32_t | ||||
| 	return (qse_raddic_const_t*)np->data; | ||||
| } | ||||
|  | ||||
| qse_raddic_const_t* qse_raddic_addconst (qse_raddic_t* dic, const qse_char_t* name, const qse_char_t* attrstr, const qse_raddic_const_value_t* value) | ||||
| static qse_raddic_const_t* __add_const (qse_raddic_t* dic, qse_raddic_const_t* dval) | ||||
| { | ||||
| 	qse_htl_node_t* np; | ||||
| 	qse_raddic_const_t* old_dval; | ||||
|  | ||||
| 	/* return an existing item or insert a new item */ | ||||
| 	np = qse_htl_ensert(&dic->consts_byname, dval); | ||||
| 	if (!np || np->data != dval) | ||||
| 	{ | ||||
| 		/* insertion failure or existing item found */ | ||||
| 		if (!np)  | ||||
| 		{ | ||||
| 			qse_raddic_seterrnum (dic, QSE_RADDIC_ENOMEM); | ||||
| 		} | ||||
| 		else  | ||||
| 		{ | ||||
| 			if ((dic->opt.trait & QSE_RADDIC_ALLOW_DUPLICATE_CONST) &&  | ||||
| 			    ((qse_raddic_const_t*)np->data)->value == dval->value)  | ||||
| 			{ | ||||
| 				QSE_MMGR_FREE (dic->mmgr, dval); | ||||
| 				return np->data; | ||||
| 			} | ||||
| 			qse_raddic_seterrfmt (dic, QSE_RADDIC_EEXIST, QSE_T("existing constant %s"), dval->name); | ||||
| 		} | ||||
|  | ||||
| 		QSE_MMGR_FREE (dic->mmgr, dval); | ||||
| 		return QSE_NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* attempt to update the lookup table by value */ | ||||
| 	np = qse_htl_upyank(&dic->consts_byvalue, dval, (void**)&old_dval); | ||||
| 	if (np) | ||||
| 	{ | ||||
| 		/* updated the existing item successfully.  | ||||
| 		 * link the old item to the current item */ | ||||
| 		QSE_ASSERT (np->data == dval); | ||||
| 		QSE_ASSERT (dval->value == old_dval->value); | ||||
| 		dval->nextc = old_dval; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* update failure, this entry must be new. try insertion */ | ||||
| 		if (!qse_htl_insert (&dic->consts_byvalue, dval)) | ||||
| 		{ | ||||
| 			qse_raddic_seterrnum (dic, QSE_RADDIC_ENOMEM); | ||||
| 			qse_htl_delete (&dic->consts_byname, dval); | ||||
| 			return QSE_NULL; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return dval; | ||||
| } | ||||
|  | ||||
| static qse_raddic_const_t* add_const (qse_raddic_t* dic, const qse_char_t* name, const qse_char_t* attrstr, qse_uintmax_t value, const qse_char_t* fn, qse_size_t line) | ||||
| { | ||||
| 	qse_size_t length; | ||||
| 	qse_raddic_const_t* dval, * old_dval; | ||||
| 	qse_raddic_const_t* dval; | ||||
| 	qse_raddic_attr_t* dattr; | ||||
| 	qse_htl_node_t* np; | ||||
|  | ||||
| 	length = qse_strlen(name); | ||||
|  | ||||
| @ -949,7 +1000,7 @@ qse_raddic_const_t* qse_raddic_addconst (qse_raddic_t* dic, const qse_char_t* na | ||||
| 	} | ||||
|  | ||||
| 	qse_strcpy(dval->name, name); | ||||
| 	dval->value = *value; | ||||
| 	dval->value = value; | ||||
| 	dval->nextc = QSE_NULL; | ||||
|  | ||||
| 	/* | ||||
| @ -972,27 +1023,48 @@ qse_raddic_const_t* qse_raddic_addconst (qse_raddic_t* dic, const qse_char_t* na | ||||
| 	 */ | ||||
| 	if (dattr)  | ||||
| 	{ | ||||
| #if 0 | ||||
| 		if (dattr->type != value->type) | ||||
| 		{ | ||||
| 			qse_raddic_seterrfmt (dic, QSE_RADDIC_EINVAL, QSE_T("conflicts between attribute type and constant value")); | ||||
| 			qse_raddic_seterrfmt (dic, QSE_RADDIC_EINVAL, QSE_T("conflicts between attribute type(%d) and constant value type(%d)"), (int)dattr->type, (int)value->type); | ||||
| 			return QSE_NULL; | ||||
| 		} | ||||
| #endif | ||||
|  | ||||
| 		dval->attr = dattr->attr; | ||||
|  | ||||
| #if 0 | ||||
| 		/* | ||||
| 		 * Enforce valid values | ||||
| 		 * Don't worry about fixups... | ||||
| 		 */ | ||||
| 		switch (dattr->type)  | ||||
| 		{ | ||||
| 			case QSE_RADDIC_ATTR_TYPE_BYTE: | ||||
| 				if (value < 0 || value > 255) goto wrong_value;  | ||||
| 			case QSE_RADDIC_ATTR_TYPE_UINT8: | ||||
| 				if (value < QSE_TYPE_MIN(qse_uint8_t) || value > QSE_TYPE_MAX(qse_uint8_t)) goto wrong_value;  | ||||
| 				break; | ||||
|  | ||||
| 			case QSE_RADDIC_ATTR_TYPE_SHORT: | ||||
| 				if (value < 0 || value > 65535)  goto wrong_value; | ||||
| 			case QSE_RADDIC_ATTR_TYPE_UINT16: | ||||
| 				if (value < QSE_TYPE_MIN(qse_uint16_t) || value > QSE_TYPE_MAX(qse_uint16_t))  goto wrong_value; | ||||
| 				break; | ||||
|  | ||||
| 			case QSE_RADDIC_ATTR_TYPE_UINT32: | ||||
| 				if (value < QSE_TYPE_MIN(qse_uint32_t) || value > QSE_TYPE_MAX(qse_uint32_t))  goto wrong_value; | ||||
| 				break; | ||||
|  | ||||
| 			case QSE_RADDIC_ATTR_TYPE_UINT64: | ||||
| 				if (value < QSE_TYPE_MIN(qse_uint64_t) || value > QSE_TYPE_MAX(qse_uint64_t))  goto wrong_value; | ||||
| 				break; | ||||
|  | ||||
| 			case QSE_RADDIC_ATTR_TYPE_INT8: | ||||
| 				if (value < QSE_TYPE_MIN(qse_int8_t) || value > QSE_TYPE_MAX(qse_int8_t)) goto wrong_value;  | ||||
| 				break; | ||||
|  | ||||
| 			case QSE_RADDIC_ATTR_TYPE_INT16: | ||||
| 				if (value < QSE_TYPE_MIN(qse_int16_t) || value > QSE_TYPE_MAX(qse_int16_t))  goto wrong_value; | ||||
| 				break; | ||||
|  | ||||
| 			case QSE_RADDIC_ATTR_TYPE_INT32: | ||||
| 				if (value < QSE_TYPE_MIN(qse_int32_t) || value > QSE_TYPE_MAX(qse_int32_t))  goto wrong_value; | ||||
| 				break; | ||||
|  | ||||
| 			case QSE_RADDIC_ATTR_TYPE_INT64: | ||||
| 				if (value < QSE_TYPE_MIN(qse_int64_t) || value > QSE_TYPE_MAX(qse_int64_t))  goto wrong_value; | ||||
| 				break; | ||||
|  | ||||
| 				/* | ||||
| @ -1000,25 +1072,29 @@ qse_raddic_const_t* qse_raddic_addconst (qse_raddic_t* dic, const qse_char_t* na | ||||
| 				 *	of dictionary.cablelabs | ||||
| 				 */ | ||||
| 			case QSE_RADDIC_ATTR_TYPE_OCTETS: | ||||
| 			case QSE_RADDIC_ATTR_TYPE_INTEGER: | ||||
| 				break; | ||||
|  | ||||
| 			default: /* cannot define VALUE for other types */ | ||||
| 			wrong_value: | ||||
| 				qse_raddic_seterrfmt (dic, QSE_RADDIC_EINVAL, QSE_T("value %d for a constant %s not allowed for an attribute %s for type %d"), value, name, attrstr, (int)dattr->type); | ||||
| 				qse_raddic_seterrfmt (dic, QSE_RADDIC_EINVAL, QSE_T("value %jd for a constant %s not allowed for an attribute %s of type %d"), value, name, attrstr, (int)dattr->type); | ||||
| 				QSE_MMGR_FREE (dic->mmgr, dval); | ||||
| 				return QSE_NULL; | ||||
| 		} | ||||
| #endif | ||||
|  | ||||
| 		dattr->flags.has_value = 1; | ||||
| 	}  | ||||
| 	else | ||||
| 	{ | ||||
| 		if (dic->opt.trait & QSE_RADDIC_ALLOW_CONST_WITHOUT_ATTR) | ||||
| 		if (fn && (dic->opt.trait & QSE_RADDIC_ALLOW_CONST_WITHOUT_ATTR)) | ||||
| 		{ | ||||
| 			const_fixup_t* fixup; | ||||
| 			qse_size_t attrstrlen, fnlen; | ||||
|  | ||||
| 			fixup = QSE_MMGR_ALLOC(dic->mmgr, QSE_SIZEOF(*fixup) + (qse_strlen(attrstr) * QSE_SIZEOF(*attrstr))); | ||||
| 			attrstrlen = qse_strlen(attrstr); | ||||
| 			fnlen = qse_strlen(fn); | ||||
|  | ||||
| 			/* TODO: don't copy fn again and again */ | ||||
| 			fixup = QSE_MMGR_ALLOC(dic->mmgr, QSE_SIZEOF(*fixup) + ((attrstrlen + fnlen + 1) * QSE_SIZEOF(*attrstr))); | ||||
| 			if (!fixup) | ||||
| 			{ | ||||
| 				qse_raddic_seterrnum (dic, QSE_RADDIC_ENOMEM); | ||||
| @ -1030,6 +1106,10 @@ qse_raddic_const_t* qse_raddic_addconst (qse_raddic_t* dic, const qse_char_t* na | ||||
| 			qse_strcpy (fixup->attrstr, attrstr); | ||||
| 			fixup->dval = dval; | ||||
| 			fixup->next = dic->const_fixup; | ||||
| 			fixup->line = line; | ||||
| 			fixup->fn = fixup->attrstr + attrstrlen + 1; | ||||
| 			qse_strcpy (fixup->fn, fn); /* TODO: don't copy fn again and again */ | ||||
|  | ||||
| 			dic->const_fixup = fixup; | ||||
|  | ||||
| 			return dval; /* this is not complete */ | ||||
| @ -1042,52 +1122,12 @@ qse_raddic_const_t* qse_raddic_addconst (qse_raddic_t* dic, const qse_char_t* na | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* return an existing item or insert a new item */ | ||||
| 	np = qse_htl_ensert(&dic->consts_byname, dval); | ||||
| 	if (!np || np->data != dval) | ||||
| 	{ | ||||
| 		/* insertion failure or existing item found */ | ||||
| 		if (!np)  | ||||
| 		{ | ||||
| 			qse_raddic_seterrnum (dic, QSE_RADDIC_ENOMEM); | ||||
| 		} | ||||
| 		else  | ||||
| 		{ | ||||
| 			if ((dic->opt.trait & QSE_RADDIC_ALLOW_DUPLICATE_CONST) &&  | ||||
| 			    QSE_MEMCMP(&((qse_raddic_const_t*)np->data)->value, &dval->value, QSE_SIZEOF(dval->value)) == 0)  | ||||
| 			{ | ||||
| 				QSE_MMGR_FREE (dic->mmgr, dval); | ||||
| 				return np->data; | ||||
| 			} | ||||
| 			qse_raddic_seterrfmt (dic, QSE_RADDIC_EEXIST, QSE_T("existing constant %s"), name); | ||||
| 	return __add_const(dic, dval); | ||||
| } | ||||
|  | ||||
| 		QSE_MMGR_FREE (dic->mmgr, dval); | ||||
| 		return QSE_NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* attempt to update the lookup table by value */ | ||||
| 	np = qse_htl_upyank(&dic->consts_byvalue, dval, (void**)&old_dval); | ||||
| 	if (np) | ||||
| qse_raddic_const_t* qse_raddic_addconst (qse_raddic_t* dic, const qse_char_t* name, const qse_char_t* attrstr, qse_uintmax_t value) | ||||
| { | ||||
| 		/* updated the existing item successfully.  | ||||
| 		 * link the old item to the current item */ | ||||
| 		QSE_ASSERT (np->data == dval); | ||||
| 		QSE_ASSERT (QSE_MEMCMP(&dval->value, &old_dval->value, QSE_SIZEOF(dval->value)) == 0); | ||||
| 		dval->nextc = old_dval; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* update failure, this entry must be new. try insertion */ | ||||
| 		if (!qse_htl_insert (&dic->consts_byvalue, dval)) | ||||
| 		{ | ||||
| 			qse_raddic_seterrnum (dic, QSE_RADDIC_ENOMEM); | ||||
| 			qse_htl_delete (&dic->consts_byname, dval); | ||||
| 			return QSE_NULL; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return dval; | ||||
| 	return add_const (dic, name, attrstr, value, QSE_NULL, 0); | ||||
| } | ||||
|  | ||||
| int qse_raddic_deleteconstbyname (qse_raddic_t* dic, qse_uint32_t attr, const qse_char_t* name) | ||||
| @ -1098,7 +1138,7 @@ int qse_raddic_deleteconstbyname (qse_raddic_t* dic, qse_uint32_t attr, const qs | ||||
| 	if (!dv) return -1; | ||||
|  | ||||
| 	QSE_ASSERT (attr == dv->attr); | ||||
| 	dv2 = qse_raddic_findconstbyvalue(dic, attr, &dv->value); | ||||
| 	dv2 = qse_raddic_findconstbyvalue(dic, attr, dv->value); | ||||
| 	QSE_ASSERT (dv2 != QSE_NULL); | ||||
|  | ||||
| 	if (dv != dv2) | ||||
| @ -1106,7 +1146,7 @@ int qse_raddic_deleteconstbyname (qse_raddic_t* dic, qse_uint32_t attr, const qs | ||||
| 		qse_raddic_const_t* x, * y; | ||||
|  | ||||
| 		QSE_ASSERT (qse_strcasecmp(dv->name, dv2->name) != 0); | ||||
| 		QSE_ASSERT (QSE_MEMCMP (&dv->value, &dv2->value, QSE_SIZEOF(dv->value)) == 0); | ||||
| 		QSE_ASSERT (dv->value ==dv2->value); | ||||
| 		QSE_ASSERT (dv->attr == dv2->attr); | ||||
|  | ||||
| 		/* when the constibute of the given name is not the first one | ||||
| @ -1138,7 +1178,7 @@ int qse_raddic_deleteconstbyname (qse_raddic_t* dic, qse_uint32_t attr, const qs | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int qse_raddic_deleteconstbyvalue (qse_raddic_t* dic, qse_uint32_t attr, const qse_raddic_const_value_t* value) | ||||
| int qse_raddic_deleteconstbyvalue (qse_raddic_t* dic, qse_uint32_t attr, qse_uintmax_t value) | ||||
| { | ||||
| 	qse_raddic_const_t* dv; | ||||
|  | ||||
| @ -1197,6 +1237,29 @@ static int sscanf_i (qse_raddic_t* dic, const qse_char_t* str, int* pvalue) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int sscanf_ui (qse_raddic_t* dic, const qse_char_t* str, qse_uintmax_t* pvalue) | ||||
| { | ||||
| 	qse_uintmax_t v; | ||||
| 	const qse_char_t* end; | ||||
|  | ||||
| 	if (!QSE_ISDIGIT(*str) && *str != QSE_T('+'))  | ||||
| 	{ | ||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("invalid unsigned number - %s"), str); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	QSE_STRTONUM (v, str, &end, 0); | ||||
|  | ||||
| 	if (*end != '\0') | ||||
| 	{ | ||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("invalid unsigned number - %s"), str); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	*pvalue = v; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int sscanf_ui32 (qse_raddic_t* dic, const qse_char_t* str, qse_uint32_t* pvalue, qse_uint32_t* pvalue2) | ||||
| { | ||||
| 	qse_long_t v, v2; | ||||
| @ -1239,8 +1302,8 @@ static int process_attribute ( | ||||
| 	qse_raddic_t* dic, const qse_char_t* fn, const qse_size_t line, | ||||
| 	int block_vendor, qse_raddic_attr_t* block_tlv, qse_char_t** argv, int argc) | ||||
| { | ||||
| 	int vendor = 0; | ||||
| 	unsigned int value; | ||||
| 	unsigned int vendor = 0; | ||||
| 	qse_uintmax_t value; | ||||
| 	int type; | ||||
| 	qse_raddic_attr_flags_t flags; | ||||
| 	qse_char_t* p; | ||||
| @ -1257,7 +1320,7 @@ static int process_attribute ( | ||||
| 	/* | ||||
| 	 *	Validate all entries | ||||
| 	 */ | ||||
| 	if (sscanf_i(dic, argv[1], &value) <= -1)  | ||||
| 	if (sscanf_ui(dic, argv[1], &value) <= -1 || value > QSE_TYPE_MAX(qse_uint16_t))  | ||||
| 	{ | ||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: invalid attribute value  %s"), fn, line, argv[1]); | ||||
| 		return -1; | ||||
| @ -1326,7 +1389,7 @@ static int process_attribute ( | ||||
| 				   Currently valid is just type 2, | ||||
| 				   Tunnel-Password style, which can only | ||||
| 				   be applied to strings. */ | ||||
| 				unsigned int ev; | ||||
| 				int ev; | ||||
| 				if (sscanf_i(dic, key + 8, &ev) <= -1 || ev < QSE_RADDIC_ATTR_FLAG_ENCRYPT_NONE || ev > QSE_RADDIC_ATTR_FLAG_ENCRYPT_OTHER) | ||||
| 				{ | ||||
| 					qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR,  QSE_T("%s[%zd] invalid option %s"), fn, line, key); | ||||
| @ -1427,9 +1490,8 @@ static int process_attribute ( | ||||
|  | ||||
| static int process_constant(qse_raddic_t* dic, const qse_char_t* fn, const qse_size_t line, qse_char_t** argv, int argc) | ||||
| { | ||||
| 	qse_raddic_const_value_t value; | ||||
| 	qse_uintmax_t value; | ||||
| 	int n; | ||||
| 	qse_uint32_t v1, v2; | ||||
|  | ||||
| 	if (argc != 3)  | ||||
| 	{ | ||||
| @ -1446,27 +1508,17 @@ static int process_constant(qse_raddic_t* dic, const qse_char_t* fn, const qse_s | ||||
| 	 *	Validate all entries | ||||
| 	 */ | ||||
|  | ||||
| 	if ((n = sscanf_ui32(dic, argv[2], &v1, &v2)) <= -1) | ||||
| 	if ((n = sscanf_ui(dic, argv[2], &value)) <= -1) | ||||
| 	{ | ||||
| 		qse_strcpy (dic->errmsg2, dic->errmsg); | ||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: invalid constant value - %s"), fn, line, dic->errmsg2); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	QSE_MEMSET (&value, 0, QSE_SIZEOF(value)); | ||||
| 	value.type = QSE_RADDIC_ATTR_TYPE_UINT32; | ||||
| 	value.u.ui32 = v1; | ||||
| 	if (n >= 1) | ||||
| 	{ | ||||
| 		value.type = QSE_RADDIC_ATTR_TYPE_FLOAT64; | ||||
| 		value.u.f64 = (qse_flt_t)v1 + ((qse_flt_t)v2 / (pow(10, n))); /* TOOD: XXXXXXXXXXXXX device a way to prepresent this */ | ||||
| 	} | ||||
| 	value.type = (n == 0)? QSE_RADDIC_ATTR_TYPE_UINT32: QSE_RADDIC_ATTR_TYPE_FLOAT64; | ||||
|  | ||||
| 	if (qse_raddic_addconst(dic, argv[1], argv[0], &value) == QSE_NULL)  | ||||
| 	if (add_const(dic, argv[1], argv[0], value, fn, line) == QSE_NULL)  | ||||
| 	{ | ||||
| 		qse_strcpy (dic->errmsg2, dic->errmsg); | ||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: cannot add a constant - %s"), fn, line, dic->errmsg2); | ||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: cannot add a constant \"%s\" - %s"), fn, line, argv[1], dic->errmsg2); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| @ -1765,7 +1817,7 @@ static int load_file (qse_raddic_t* dic, const qse_char_t* fn, const qse_char_t* | ||||
| 			vendor = qse_raddic_findvendorbyname(dic, argv[1]); | ||||
| 			if (!vendor)  | ||||
| 			{ | ||||
| 				qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: unknown vendor %s"), fname, line, argv[1]); | ||||
| 				qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: unknown vendor \"%s\""), fname, line, argv[1]); | ||||
| 				goto oops; | ||||
| 			} | ||||
|  | ||||
| @ -1784,7 +1836,6 @@ static int load_file (qse_raddic_t* dic, const qse_char_t* fn, const qse_char_t* | ||||
| 		 */ | ||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd] invalid keyword \"%s\""), fname, line, argv[0]); | ||||
| 		goto oops; | ||||
| 		 | ||||
| 	} | ||||
|  | ||||
| 	qse_sio_close (sio); | ||||
| @ -1799,5 +1850,36 @@ oops: | ||||
|  | ||||
| int qse_raddic_load (qse_raddic_t* dic, const qse_char_t* file) | ||||
| { | ||||
| 	return load_file (dic, file, QSE_NULL, 0); | ||||
| 	int n; | ||||
|  | ||||
| 	n = load_file (dic, file, QSE_NULL, 0); | ||||
|  | ||||
| 	while (dic->const_fixup) | ||||
| 	{ | ||||
| 		qse_raddic_attr_t* attr; | ||||
| 		const_fixup_t* fixup = dic->const_fixup; | ||||
| 		dic->const_fixup = dic->const_fixup->next; | ||||
|  | ||||
| 		if (n >= 0) | ||||
| 		{ | ||||
| 			attr = qse_raddic_findattrbyname (dic, fixup->attrstr); | ||||
| 			if (attr) | ||||
| 			{ | ||||
| 				fixup->dval->attr = attr->attr; | ||||
| 				attr->flags.has_value = 1; | ||||
| 				if (__add_const(dic, fixup->dval) != QSE_NULL) goto fixed; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: constant \"%s\" defined for an unknown attribute \"%s\""), fixup->fn, fixup->line, fixup->dval->name, fixup->attrstr); | ||||
| 				n = -1; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		QSE_MMGR_FREE (dic->mmgr, fixup->dval); | ||||
| 	fixed: | ||||
| 		QSE_MMGR_FREE (dic->mmgr, fixup); | ||||
| 	} | ||||
|  | ||||
| 	return n; | ||||
| } | ||||
|  | ||||
| @ -368,7 +368,7 @@ int qse_rad_insert_wide_string_attribute_with_length ( | ||||
| 	return n; | ||||
| } | ||||
|  | ||||
| int qse_rad_insert_integer_attribute ( | ||||
| int qse_rad_insert_uint32_attribute ( | ||||
| 	qse_rad_hdr_t* auth, int max, qse_uint32_t vendor, qse_uint8_t id, qse_uint32_t value) | ||||
| { | ||||
| 	qse_uint32_t val = qse_hton32(value); | ||||
| @ -458,6 +458,41 @@ int qse_rad_insert_giga_attribute ( | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| int qse_rad_insert_extended_vendor_specific_attribute ( | ||||
| 	qse_rad_hdr_t* auth, int max, qse_uint8_t base, qse_uint32_t vendor, | ||||
| 	qse_uint8_t attrid, const void* ptr, qse_uint8_t len) | ||||
| { | ||||
| 	/* RFC6929 */ | ||||
| 	qse_rad_extvsattr_hdr_t* attr; | ||||
| 	int auth_len = qse_ntoh16(auth->length); | ||||
| 	int new_auth_len; | ||||
|  | ||||
| 	if (base < 241 && base > 244) return -1; | ||||
| /* TODO: for 245 and 246, switch to long-extended format */ | ||||
|  | ||||
| 	/*if (len > QSE_RAD_MAX_EXTVSATTR_VALUE_LEN) return -1;*/ | ||||
| 	if (len > QSE_RAD_MAX_EXTVSATTR_VALUE_LEN) len = QSE_RAD_MAX_EXTVSATTR_VALUE_LEN; | ||||
| 	new_auth_len = auth_len + len + QSE_SIZEOF(*attr); | ||||
|  | ||||
| 	if (new_auth_len > max) return -1; | ||||
|  | ||||
| 	attr = (qse_rad_extvsattr_hdr_t*) ((char*)auth + auth_len); | ||||
| 	attr->id = base; | ||||
| 	attr->length = new_auth_len - auth_len; | ||||
| 	attr->xid = QSE_RAD_ATTR_VENDOR_SPECIFIC; | ||||
| 	attr->vendor = qse_hton32(vendor); | ||||
| 	attr->evsid = attrid; | ||||
|  | ||||
| 	/* no special header for the evs-value */ | ||||
| 	QSE_MEMCPY (attr + 1, ptr, len); | ||||
|  | ||||
| 	auth->length = qse_hton16(new_auth_len); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| #define PASS_BLKSIZE QSE_RAD_MAX_AUTHENTICATOR_LEN | ||||
| #define ALIGN(x,factor) ((((x) + (factor) - 1) / (factor)) * (factor)) | ||||
|  | ||||
|  | ||||
| @ -4,14 +4,23 @@ | ||||
| #include <qse/si/sio.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #if 0 | ||||
| #include <qse/rad/radmsg.h> | ||||
| #include <sys/socket.h> | ||||
| #include <netinet/in.h> | ||||
| #include <unistd.h> | ||||
| #endif | ||||
|  | ||||
| #define R(f) \ | ||||
| 	do { \ | ||||
| 		qse_printf (QSE_T("== %s ==\n"), QSE_T(#f)); \ | ||||
| 		if (f() == -1) return -1; \ | ||||
| 		if (f() == -1) goto oops; \ | ||||
| 	} while (0) | ||||
|  | ||||
| #define FAIL(msg) qse_printf(QSE_T("FAILURE in %hs line %d - %s\n"), __func__, __LINE__, msg) | ||||
| #define _assert(test,msg) do { if (!(test)) { FAIL(msg); return -1; } } while(0) | ||||
| #define FAIL2(msg1,msg2) qse_printf(QSE_T("FAILURE in %hs line %d - %s - %s\n"), __func__, __LINE__, msg1, msg2) | ||||
| #define _assert(test,msg) do { if (!(test)) { FAIL(msg); goto oops; } } while(0) | ||||
| #define _assert2(test,msg1,msg2) do { if (!(test)) { FAIL2(msg1,msg2); goto oops; } } while(0) | ||||
| #define _verify(test) do { int r=test(); tests_run++; if(r) return r; } while(0) | ||||
|  | ||||
| static int test1 () | ||||
| @ -165,6 +174,10 @@ static int test1 () | ||||
|  | ||||
| 	qse_raddic_close (dic); | ||||
| 	return 0; | ||||
|  | ||||
| oops: | ||||
| 	if (dic) qse_raddic_close (dic); | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -300,7 +313,7 @@ static int test2 () | ||||
| 			_assert (qse_strcasecmp(attr->name, tmp) == 0, QSE_T("wrong attr name")); | ||||
|  | ||||
| 			attr = qse_raddic_findattrbyname (dic, tmpx); | ||||
| 			_assert (attr == QSE_NULL, QSE_T("errorneous search success")); | ||||
| 			_assert (attr == QSE_NULL, QSE_T("erroneous search success")); | ||||
|  | ||||
| 			attr = qse_raddic_findattrbyname (dic, tmpy); | ||||
| 			_assert (attr != QSE_NULL, QSE_T("unable to add an attribute")); | ||||
| @ -324,13 +337,13 @@ static int test2 () | ||||
| 	{ | ||||
| 		int n; | ||||
| 		n = qse_raddic_deleteattrbyvalue (dic, QSE_RADDIC_ATTR_MAKE(0, 0)); | ||||
| 		_assert (n == 0, QSE_T("errorneous deletion failure by value")); | ||||
| 		_assert (n == 0, QSE_T("erroneous deletion failure by value")); | ||||
|  | ||||
| 		n = qse_raddic_deleteattrbyvalue (dic, QSE_RADDIC_ATTR_MAKE(0, 0)); | ||||
| 		_assert (n == 0, QSE_T("errorneous deletion failure by value")); | ||||
| 		_assert (n == 0, QSE_T("erroneous deletion failure by value")); | ||||
|  | ||||
| 		n = qse_raddic_deleteattrbyvalue (dic, QSE_RADDIC_ATTR_MAKE(0, 0)); | ||||
| 		_assert (n <= -1, QSE_T("errorneous deletion success by value")); | ||||
| 		_assert (n <= -1, QSE_T("erroneous deletion success by value")); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -339,17 +352,12 @@ static int test2 () | ||||
| 		for (i = 1; i <= 255; i++) | ||||
| 		{ | ||||
| 			qse_char_t constr[64], attrstr[64]; | ||||
| 			qse_raddic_const_value_t v; | ||||
|  | ||||
| 			memset (&v, 0, QSE_SIZEOF(v)); | ||||
| 			v.type = QSE_RADDIC_ATTR_TYPE_UINT32; | ||||
| 			v.u.ui32 = 10; | ||||
|  | ||||
| 			qse_strxfmt(attrstr, QSE_COUNTOF(attrstr), QSE_T("test-%d-%d"), j, i); | ||||
| 			qse_strxfmt(constr, QSE_COUNTOF(constr), QSE_T("const-%d-%d"), j, i); | ||||
| 			con = qse_raddic_addconst (dic, constr, attrstr, &v); | ||||
| 			_assert (con != QSE_NULL, QSE_T("unable to add an constant")); | ||||
| 			_assert (con->value.type == QSE_RADDIC_ATTR_TYPE_UINT32 || con->value.u.ui32 == 10, QSE_T("wrong constant value")); | ||||
| 			con = qse_raddic_addconst (dic, constr, attrstr, 10); | ||||
| 			_assert2 (con != QSE_NULL, QSE_T("unable to add an constant"), qse_raddic_geterrmsg(dic)); | ||||
| 			_assert (con->value == 10, QSE_T("wrong constant value")); | ||||
| 			_assert (qse_strcasecmp(con->name, constr) == 0, QSE_T("wrong constant name")); | ||||
| 		} | ||||
| 	} | ||||
| @ -359,55 +367,46 @@ static int test2 () | ||||
| 		for (i = 1; i <= 255; i++) | ||||
| 		{ | ||||
| 			qse_char_t constr[64]; | ||||
| 			qse_raddic_const_value_t v; | ||||
|  | ||||
| 			memset (&v, 0, QSE_SIZEOF(v)); | ||||
| 			v.type = QSE_RADDIC_ATTR_TYPE_UINT32; | ||||
| 			v.u.ui32 = 10; | ||||
|  | ||||
| 			qse_strxfmt(constr, QSE_COUNTOF(constr), QSE_T("const-%d-%d"), j, i); | ||||
|  | ||||
| 			con = qse_raddic_findconstbyname (dic, QSE_RADDIC_ATTR_MAKE(j, i), constr); | ||||
| 			_assert (con != QSE_NULL, QSE_T("unable to find an constant")); | ||||
| 			_assert (con->attr == QSE_RADDIC_ATTR_MAKE(j, i), QSE_T("wrong constant value")); | ||||
| 			_assert (con->value.type == QSE_RADDIC_ATTR_TYPE_UINT32 || con->value.u.ui32 == 10, QSE_T("wrong constant value")); | ||||
| 			_assert (con->value == 10, QSE_T("wrong constant value")); | ||||
|  | ||||
| 			con = qse_raddic_findconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(j, i), &v); | ||||
| 			con = qse_raddic_findconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(j, i), 10); | ||||
| 			_assert (con != QSE_NULL, QSE_T("unable to find an constant")); | ||||
| 			_assert (con->value.type == QSE_RADDIC_ATTR_TYPE_UINT32 || con->value.u.ui32 == 10, QSE_T("wrong constant value")); | ||||
| 			_assert (con->value == 10, QSE_T("wrong constant value")); | ||||
| 			_assert (con->attr == QSE_RADDIC_ATTR_MAKE(j, i), QSE_T("wrong constant value")); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	{ | ||||
| 		int n; | ||||
| 		qse_raddic_const_value_t v; | ||||
|  | ||||
| 		memset (&v, 0, QSE_SIZEOF(v)); | ||||
| 		v.type = QSE_RADDIC_ATTR_TYPE_UINT32; | ||||
|  | ||||
| 		n = qse_raddic_deleteconstbyname (dic, QSE_RADDIC_ATTR_MAKE(1,1), QSE_T("const-1-1")); | ||||
| 		_assert (n == 0, QSE_T("errorneous constant deletion failure")); | ||||
| 		_assert (n == 0, QSE_T("erroneous constant deletion failure")); | ||||
|  | ||||
| 		n = qse_raddic_deleteconstbyname (dic, QSE_RADDIC_ATTR_MAKE(1,1), QSE_T("const-1-1")); | ||||
| 		_assert (n <= -1, QSE_T("errorneous constant deletion success")); | ||||
| 		_assert (n <= -1, QSE_T("erroneous constant deletion success")); | ||||
|  | ||||
| 		v.u.ui32 = 20; | ||||
| 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), &v); | ||||
| 		_assert (n <= -1, QSE_T("errorneous constant deletion success")); | ||||
| 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), 20); | ||||
| 		_assert (n <= -1, QSE_T("erroneous constant deletion success")); | ||||
|  | ||||
| 		v.u.ui32 = 10; | ||||
| 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), &v); | ||||
| 		_assert (n == 0, QSE_T("errorneous constant deletion success")); | ||||
| 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), 10); | ||||
| 		_assert (n == 0, QSE_T("erroneous constant deletion success")); | ||||
|  | ||||
| 		v.u.ui32 = 10; | ||||
| 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), &v); | ||||
| 		_assert (n <= -1, QSE_T("errorneous constant deletion success")); | ||||
| 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), 10); | ||||
| 		_assert (n <= -1, QSE_T("erroneous constant deletion success")); | ||||
| 	} | ||||
|  | ||||
| 	qse_raddic_close (dic); | ||||
| 	return 0; | ||||
|  | ||||
| oops: | ||||
| 	if (dic) qse_raddic_close (dic); | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| static int test3 () | ||||
| @ -424,25 +423,60 @@ static int test3 () | ||||
| 	n = qse_raddic_setopt (dic, QSE_RADDIC_TRAIT, &trait); | ||||
| 	_assert (n == 0, QSE_T("cannot set trait")); | ||||
|  | ||||
| 	n = qse_raddic_load (dic, QSE_T("fr2/dictionary")); | ||||
| 	_assert (n == 0, qse_raddic_geterrmsg(dic)); | ||||
| 	n = qse_raddic_load (dic, QSE_T("fr/dictionary")); | ||||
| 	_assert2 (n == 0, QSE_T("unabled to load dictionary"), qse_raddic_geterrmsg(dic)); | ||||
|  | ||||
| 	v = qse_raddic_findvendorbyname (dic, QSE_T("cisco")); | ||||
| 	_assert (v && v->vendorpec == 9, "wrong vendor value"); | ||||
|  | ||||
| 	c = qse_raddic_findconstbyname (dic, QSE_RADDIC_ATTR_MAKE(0,49), QSE_T("Reauthentication-Failure")); | ||||
| 	_assert (c && c->value.type == QSE_RADDIC_ATTR_TYPE_UINT32 && c->value.u.ui32 == 20, QSE_T("wrong constant value")); | ||||
| 	_assert (c && c->value == 20, QSE_T("wrong constant value")); | ||||
|  | ||||
| 	qse_raddic_close (dic); | ||||
| 	return 0; | ||||
|  | ||||
| oops: | ||||
| 	if (dic) qse_raddic_close (dic); | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| static int test10() | ||||
| { | ||||
| 	struct sockaddr_in sin; | ||||
| 	int s; | ||||
| 	char buf[10000]; | ||||
|  | ||||
| 	if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return -1; | ||||
|  | ||||
| 	memset (&sin, 0, sizeof(sin)); | ||||
| 	sin.sin_family = AF_INET; | ||||
| 	sin.sin_addr.s_addr = inet_addr("192.168.1.2"); | ||||
| 	sin.sin_port = htons(1812); | ||||
|  | ||||
| 	qse_rad_initialize (buf, QSE_RAD_ACCESS_REQUEST, 99); | ||||
| 	qse_rad_insert_extended_vendor_specific_attribute (buf, sizeof(buf), 243, 12345, 5, "xxxxxx", 6); | ||||
|  | ||||
| 	sendto (s, buf, ntohs(((qse_rad_hdr_t*)buf)->length), 0, &sin, sizeof(sin)); | ||||
|  | ||||
| 	close (s); | ||||
| 	return 0; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| int main () | ||||
| { | ||||
| 	qse_open_stdsios ();  | ||||
|  | ||||
| 	R (test1); | ||||
| 	R (test2); | ||||
| 	R (test3); | ||||
|  | ||||
| #if 0 | ||||
| 	R (test10); | ||||
| #endif | ||||
|  | ||||
| oops: | ||||
| 	qse_close_stdsios (); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user