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/types.h> | ||||||
| #include <qse/macros.h> | #include <qse/macros.h> | ||||||
|  |  | ||||||
|  | /* TODO: extended, long-extended, tlv, evs */ | ||||||
|  |  | ||||||
| enum qse_raddic_opt_t | enum qse_raddic_opt_t | ||||||
| { | { | ||||||
| 	QSE_RADDIC_TRAIT | 	QSE_RADDIC_TRAIT | ||||||
| @ -182,7 +184,7 @@ typedef struct qse_raddic_const_t qse_raddic_const_t; | |||||||
| struct qse_raddic_const_t | struct qse_raddic_const_t | ||||||
| { | { | ||||||
| 	qse_uint32_t             attr;     /* vendor + attribute-value */ | 	qse_uint32_t             attr;     /* vendor + attribute-value */ | ||||||
| 	qse_raddic_const_value_t value; | 	qse_uintmax_t            value; | ||||||
| 	qse_raddic_const_t*      nextc; | 	qse_raddic_const_t*      nextc; | ||||||
| 	qse_char_t               name[1]; | 	qse_char_t               name[1]; | ||||||
| }; | }; | ||||||
| @ -190,7 +192,7 @@ struct qse_raddic_const_t | |||||||
| typedef struct qse_raddic_vendor_t qse_raddic_vendor_t; | typedef struct qse_raddic_vendor_t qse_raddic_vendor_t; | ||||||
| struct qse_raddic_vendor_t | struct qse_raddic_vendor_t | ||||||
| { | { | ||||||
| 	int                  vendorpec; | 	unsigned int         vendorpec; | ||||||
| 	int                  type; | 	int                  type; | ||||||
| 	int                  length; | 	int                  length; | ||||||
| 	int                  flags; | 	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_EXPORT qse_raddic_vendor_t* qse_raddic_findvendorbyvalue ( | ||||||
| 	qse_raddic_t*     dic, | 	qse_raddic_t*     dic, | ||||||
| 	int               vendorpec | 	unsigned int      vendorpec | ||||||
| ); | ); | ||||||
|  |  | ||||||
| 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               vendorpec | 	unsigned int      vendorpec | ||||||
| ); | ); | ||||||
|  |  | ||||||
| QSE_EXPORT int qse_raddic_deletevendorbyname ( | QSE_EXPORT int qse_raddic_deletevendorbyname ( | ||||||
| @ -281,7 +283,7 @@ 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               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_EXPORT qse_raddic_attr_t* qse_raddic_addattr ( | ||||||
| 	qse_raddic_t*                  dic, | 	qse_raddic_t*                  dic, | ||||||
| 	const qse_char_t*              name, | 	const qse_char_t*              name, | ||||||
| 	int                            vendor, | 	unsigned int                   vendor, | ||||||
| 	qse_raddic_attr_type_t         type, | 	qse_raddic_attr_type_t         type, | ||||||
| 	int                            value, | 	unsigned int                   value, | ||||||
| 	const qse_raddic_attr_flags_t* flags | 	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_EXPORT qse_raddic_const_t* qse_raddic_findconstbyvalue ( | ||||||
| 	qse_raddic_t*      dic, | 	qse_raddic_t*      dic, | ||||||
| 	qse_uint32_t       attr, | 	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_EXPORT qse_raddic_const_t* qse_raddic_addconst ( | ||||||
| 	qse_raddic_t*      dic, | 	qse_raddic_t*      dic, | ||||||
| 	const qse_char_t*  name, | 	const qse_char_t*  name, | ||||||
| 	const qse_char_t*  attrstr, | 	const qse_char_t*  attrstr, | ||||||
| 	const qse_raddic_const_value_t* value | 	qse_uintmax_t      value | ||||||
| ); | ); | ||||||
|  |  | ||||||
| QSE_EXPORT int qse_raddic_deleteconstbyname ( | QSE_EXPORT int qse_raddic_deleteconstbyname ( | ||||||
| @ -343,7 +345,7 @@ QSE_EXPORT int qse_raddic_deleteconstbyname ( | |||||||
| QSE_EXPORT int qse_raddic_deleteconstbyvalue ( | QSE_EXPORT int qse_raddic_deleteconstbyvalue ( | ||||||
| 	qse_raddic_t*     dic, | 	qse_raddic_t*     dic, | ||||||
| 	qse_uint32_t      attr, | 	qse_uint32_t      attr, | ||||||
| 	const qse_raddic_const_value_t* value | 	qse_uintmax_t     value | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -27,6 +27,8 @@ | |||||||
| #ifndef _QSE_RAD_RADMSG_H_ | #ifndef _QSE_RAD_RADMSG_H_ | ||||||
| #define _QSE_RAD_RADMSG_H_ | #define _QSE_RAD_RADMSG_H_ | ||||||
|  |  | ||||||
|  | /* TODO: tag, extended, long-extended, tlv, evs */ | ||||||
|  |  | ||||||
| #include <qse/types.h> | #include <qse/types.h> | ||||||
| #include <qse/macros.h> | #include <qse/macros.h> | ||||||
| #include <qse/cmn/ipad.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_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_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_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_hdr_t qse_rad_hdr_t; | ||||||
| typedef struct qse_rad_attr_hdr_t qse_rad_attr_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_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> | #include <qse/pack1.h> | ||||||
| struct qse_rad_hdr_t  | struct qse_rad_hdr_t  | ||||||
| @ -80,16 +88,34 @@ struct qse_rad_attr_hdr_t | |||||||
|  |  | ||||||
| struct qse_rad_vsattr_hdr_t | struct qse_rad_vsattr_hdr_t | ||||||
| { | { | ||||||
| 	qse_uint8_t  id; | 	qse_uint8_t  id; /* type */ | ||||||
| 	qse_uint8_t  length; | 	qse_uint8_t  length; /* length */ | ||||||
| 	qse_uint32_t vendor; /* in network-byte order */ | 	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_rad_attr_hdr_t hdr; | ||||||
| 	qse_uint32_t val; | 	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> | #include <qse/unpack.h> | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -266,7 +292,7 @@ QSE_EXPORT int qse_rad_insert_wide_string_attribute_with_length ( | |||||||
| 	qse_uint8_t        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,  | 	qse_rad_hdr_t*     auth,  | ||||||
| 	int                max, | 	int                max, | ||||||
| 	qse_uint32_t       vendor, /* in host-byte order */ | 	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_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_EXPORT int qse_rad_set_user_password ( | ||||||
| 	qse_rad_hdr_t*      auth, | 	qse_rad_hdr_t*      auth, | ||||||
| 	int                 max, | 	int                 max, | ||||||
| @ -329,7 +367,6 @@ QSE_EXPORT int qse_rad_verify_response ( | |||||||
| 	const qse_mchar_t*     secret | 	const qse_mchar_t*     secret | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -62,6 +62,8 @@ struct const_fixup_t | |||||||
| { | { | ||||||
| 	const_fixup_t*        next; | 	const_fixup_t*        next; | ||||||
| 	qse_raddic_const_t*   dval; | 	qse_raddic_const_t*   dval; | ||||||
|  | 	qse_size_t            line; | ||||||
|  | 	qse_char_t*           fn; | ||||||
| 	qse_char_t            attrstr[1]; | 	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->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. | 	return 0; | ||||||
| 	 * 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)); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* -------------------------------------------------------------------------- */ | /* -------------------------------------------------------------------------- */ | ||||||
| @ -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. |  *	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_htl_node_t* np; | ||||||
| 	qse_raddic_vendor_t dv; | 	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); | 	np = qse_htl_search (&dic->vendors_byvalue, &dv); | ||||||
| 	if (!np)  | 	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_NULL; | ||||||
| 	} | 	} | ||||||
| 	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 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_size_t length; | ||||||
| 	qse_raddic_vendor_t* dv, * old_dv; | 	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)  | 	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; | 		return QSE_NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -678,7 +677,7 @@ 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 vendorpec) | int qse_raddic_deletevendorbyvalue (qse_raddic_t* dic, unsigned int vendorpec) | ||||||
| { | { | ||||||
| 	qse_raddic_vendor_t* dv; | 	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; | 	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_size_t length; | ||||||
| 	qse_raddic_attr_t* dv, * old_dv; | 	qse_raddic_attr_t* dv, * old_dv; | ||||||
| 	qse_htl_node_t* np; | 	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 */ | 		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 */ | 		/* 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; | 		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; | 	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_htl_node_t* np; | ||||||
| 	qse_raddic_const_t dval; | 	qse_raddic_const_t dval; | ||||||
|  |  | ||||||
| 	dval.attr = attr; | 	dval.attr = attr; | ||||||
| 	dval.value = *value; | 	dval.value = value; | ||||||
| 	np = qse_htl_search (&dic->consts_byvalue, &dval); | 	np = qse_htl_search (&dic->consts_byvalue, &dval); | ||||||
| 	if (!np) | 	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; | 	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_size_t length; | ||||||
| 	qse_raddic_const_t* dval, * old_dval; | 	qse_raddic_const_t* dval; | ||||||
| 	qse_raddic_attr_t* dattr; | 	qse_raddic_attr_t* dattr; | ||||||
| 	qse_htl_node_t* np; |  | ||||||
|  |  | ||||||
| 	length = qse_strlen(name); | 	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); | 	qse_strcpy(dval->name, name); | ||||||
| 	dval->value = *value; | 	dval->value = value; | ||||||
| 	dval->nextc = QSE_NULL; | 	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 (dattr)  | ||||||
| 	{ | 	{ | ||||||
|  | #if 0 | ||||||
| 		if (dattr->type != value->type) | 		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; | 			return QSE_NULL; | ||||||
| 		} | 		} | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 		dval->attr = dattr->attr; | 		dval->attr = dattr->attr; | ||||||
|  |  | ||||||
| #if 0 |  | ||||||
| 		/* |  | ||||||
| 		 * Enforce valid values |  | ||||||
| 		 * Don't worry about fixups... |  | ||||||
| 		 */ |  | ||||||
| 		switch (dattr->type)  | 		switch (dattr->type)  | ||||||
| 		{ | 		{ | ||||||
| 			case QSE_RADDIC_ATTR_TYPE_BYTE: | 			case QSE_RADDIC_ATTR_TYPE_UINT8: | ||||||
| 				if (value < 0 || value > 255) goto wrong_value;  | 				if (value < QSE_TYPE_MIN(qse_uint8_t) || value > QSE_TYPE_MAX(qse_uint8_t)) goto wrong_value;  | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 			case QSE_RADDIC_ATTR_TYPE_SHORT: | 			case QSE_RADDIC_ATTR_TYPE_UINT16: | ||||||
| 				if (value < 0 || value > 65535)  goto wrong_value; | 				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; | 				break; | ||||||
|  |  | ||||||
| 				/* | 				/* | ||||||
| @ -1000,25 +1072,29 @@ qse_raddic_const_t* qse_raddic_addconst (qse_raddic_t* dic, const qse_char_t* na | |||||||
| 				 *	of dictionary.cablelabs | 				 *	of dictionary.cablelabs | ||||||
| 				 */ | 				 */ | ||||||
| 			case QSE_RADDIC_ATTR_TYPE_OCTETS: | 			case QSE_RADDIC_ATTR_TYPE_OCTETS: | ||||||
| 			case QSE_RADDIC_ATTR_TYPE_INTEGER: |  | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 			default: /* cannot define VALUE for other types */ | 			default: /* cannot define VALUE for other types */ | ||||||
| 			wrong_value: | 			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); | 				QSE_MMGR_FREE (dic->mmgr, dval); | ||||||
| 				return QSE_NULL; | 				return QSE_NULL; | ||||||
| 		} | 		} | ||||||
| #endif |  | ||||||
| 		dattr->flags.has_value = 1; | 		dattr->flags.has_value = 1; | ||||||
| 	}  | 	}  | ||||||
| 	else | 	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; | 			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) | 			if (!fixup) | ||||||
| 			{ | 			{ | ||||||
| 				qse_raddic_seterrnum (dic, QSE_RADDIC_ENOMEM); | 				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); | 			qse_strcpy (fixup->attrstr, attrstr); | ||||||
| 			fixup->dval = dval; | 			fixup->dval = dval; | ||||||
| 			fixup->next = dic->const_fixup; | 			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; | 			dic->const_fixup = fixup; | ||||||
|  |  | ||||||
| 			return dval; /* this is not complete */ | 			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 */ | 	return __add_const(dic, dval); | ||||||
| 	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); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| 		QSE_MMGR_FREE (dic->mmgr, dval); | 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) | ||||||
| 		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.  | 	return add_const (dic, name, attrstr, value, QSE_NULL, 0); | ||||||
| 		 * 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; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| int qse_raddic_deleteconstbyname (qse_raddic_t* dic, qse_uint32_t attr, const qse_char_t* name) | 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; | 	if (!dv) return -1; | ||||||
|  |  | ||||||
| 	QSE_ASSERT (attr == dv->attr); | 	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); | 	QSE_ASSERT (dv2 != QSE_NULL); | ||||||
|  |  | ||||||
| 	if (dv != dv2) | 	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_raddic_const_t* x, * y; | ||||||
|  |  | ||||||
| 		QSE_ASSERT (qse_strcasecmp(dv->name, dv2->name) != 0); | 		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); | 		QSE_ASSERT (dv->attr == dv2->attr); | ||||||
|  |  | ||||||
| 		/* when the constibute of the given name is not the first one | 		/* 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; | 	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; | 	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; | 	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) | 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; | 	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, | 	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 block_vendor, qse_raddic_attr_t* block_tlv, qse_char_t** argv, int argc) | ||||||
| { | { | ||||||
| 	int vendor = 0; | 	unsigned int vendor = 0; | ||||||
| 	unsigned int value; | 	qse_uintmax_t value; | ||||||
| 	int type; | 	int type; | ||||||
| 	qse_raddic_attr_flags_t flags; | 	qse_raddic_attr_flags_t flags; | ||||||
| 	qse_char_t* p; | 	qse_char_t* p; | ||||||
| @ -1257,7 +1320,7 @@ static int process_attribute ( | |||||||
| 	/* | 	/* | ||||||
| 	 *	Validate all entries | 	 *	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]); | 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: invalid attribute value  %s"), fn, line, argv[1]); | ||||||
| 		return -1; | 		return -1; | ||||||
| @ -1326,7 +1389,7 @@ static int process_attribute ( | |||||||
| 				   Currently valid is just type 2, | 				   Currently valid is just type 2, | ||||||
| 				   Tunnel-Password style, which can only | 				   Tunnel-Password style, which can only | ||||||
| 				   be applied to strings. */ | 				   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) | 				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); | 					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) | 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; | 	int n; | ||||||
| 	qse_uint32_t v1, v2; |  | ||||||
|  |  | ||||||
| 	if (argc != 3)  | 	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 | 	 *	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_strcpy (dic->errmsg2, dic->errmsg); | ||||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: invalid constant value - %s"), fn, line, dic->errmsg2); | 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: invalid constant value - %s"), fn, line, dic->errmsg2); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	QSE_MEMSET (&value, 0, QSE_SIZEOF(value)); | 	if (add_const(dic, argv[1], argv[0], value, fn, line) == QSE_NULL)  | ||||||
| 	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)  |  | ||||||
| 	{ | 	{ | ||||||
| 		qse_strcpy (dic->errmsg2, dic->errmsg); | 		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; | 		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]); | 			vendor = qse_raddic_findvendorbyname(dic, argv[1]); | ||||||
| 			if (!vendor)  | 			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; | 				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]); | 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd] invalid keyword \"%s\""), fname, line, argv[0]); | ||||||
| 		goto oops; | 		goto oops; | ||||||
| 		 |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	qse_sio_close (sio); | 	qse_sio_close (sio); | ||||||
| @ -1799,5 +1850,36 @@ oops: | |||||||
|  |  | ||||||
| int qse_raddic_load (qse_raddic_t* dic, const qse_char_t* file) | 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; | 	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_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); | 	qse_uint32_t val = qse_hton32(value); | ||||||
| @ -458,6 +458,41 @@ int qse_rad_insert_giga_attribute ( | |||||||
| 	return 0; | 	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 PASS_BLKSIZE QSE_RAD_MAX_AUTHENTICATOR_LEN | ||||||
| #define ALIGN(x,factor) ((((x) + (factor) - 1) / (factor)) * (factor)) | #define ALIGN(x,factor) ((((x) + (factor) - 1) / (factor)) * (factor)) | ||||||
|  |  | ||||||
|  | |||||||
| @ -4,14 +4,23 @@ | |||||||
| #include <qse/si/sio.h> | #include <qse/si/sio.h> | ||||||
| #include <string.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) \ | #define R(f) \ | ||||||
| 	do { \ | 	do { \ | ||||||
| 		qse_printf (QSE_T("== %s ==\n"), QSE_T(#f)); \ | 		qse_printf (QSE_T("== %s ==\n"), QSE_T(#f)); \ | ||||||
| 		if (f() == -1) return -1; \ | 		if (f() == -1) goto oops; \ | ||||||
| 	} while (0) | 	} while (0) | ||||||
|  |  | ||||||
| #define FAIL(msg) qse_printf(QSE_T("FAILURE in %hs line %d - %s\n"), __func__, __LINE__, msg) | #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) | #define _verify(test) do { int r=test(); tests_run++; if(r) return r; } while(0) | ||||||
|  |  | ||||||
| static int test1 () | static int test1 () | ||||||
| @ -165,6 +174,10 @@ static int test1 () | |||||||
|  |  | ||||||
| 	qse_raddic_close (dic); | 	qse_raddic_close (dic); | ||||||
| 	return 0; | 	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")); | 			_assert (qse_strcasecmp(attr->name, tmp) == 0, QSE_T("wrong attr name")); | ||||||
|  |  | ||||||
| 			attr = qse_raddic_findattrbyname (dic, tmpx); | 			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); | 			attr = qse_raddic_findattrbyname (dic, tmpy); | ||||||
| 			_assert (attr != QSE_NULL, QSE_T("unable to add an attribute")); | 			_assert (attr != QSE_NULL, QSE_T("unable to add an attribute")); | ||||||
| @ -324,13 +337,13 @@ static int test2 () | |||||||
| 	{ | 	{ | ||||||
| 		int n; | 		int n; | ||||||
| 		n = qse_raddic_deleteattrbyvalue (dic, QSE_RADDIC_ATTR_MAKE(0, 0)); | 		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)); | 		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)); | 		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++) | 		for (i = 1; i <= 255; i++) | ||||||
| 		{ | 		{ | ||||||
| 			qse_char_t constr[64], attrstr[64]; | 			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(attrstr, QSE_COUNTOF(attrstr), QSE_T("test-%d-%d"), j, i); | ||||||
| 			qse_strxfmt(constr, QSE_COUNTOF(constr), QSE_T("const-%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); | 			con = qse_raddic_addconst (dic, constr, attrstr, 10); | ||||||
| 			_assert (con != QSE_NULL, QSE_T("unable to add an constant")); | 			_assert2 (con != QSE_NULL, QSE_T("unable to add an constant"), qse_raddic_geterrmsg(dic)); | ||||||
| 			_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 (qse_strcasecmp(con->name, constr) == 0, QSE_T("wrong constant name")); | 			_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++) | 		for (i = 1; i <= 255; i++) | ||||||
| 		{ | 		{ | ||||||
| 			qse_char_t constr[64]; | 			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); | 			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); | 			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 != 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->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 != 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")); | 			_assert (con->attr == QSE_RADDIC_ATTR_MAKE(j, i), QSE_T("wrong constant value")); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	{ | 	{ | ||||||
| 		int n; | 		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")); | 		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")); | 		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), 20); | ||||||
| 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), &v); | 		_assert (n <= -1, QSE_T("erroneous constant deletion success")); | ||||||
| 		_assert (n <= -1, QSE_T("errorneous constant deletion success")); |  | ||||||
|  |  | ||||||
| 		v.u.ui32 = 10; | 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), 10); | ||||||
| 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), &v); | 		_assert (n == 0, QSE_T("erroneous constant deletion success")); | ||||||
| 		_assert (n == 0, QSE_T("errorneous constant deletion success")); |  | ||||||
|  |  | ||||||
| 		v.u.ui32 = 10; | 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), 10); | ||||||
| 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), &v); | 		_assert (n <= -1, QSE_T("erroneous constant deletion success")); | ||||||
| 		_assert (n <= -1, QSE_T("errorneous constant deletion success")); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	qse_raddic_close (dic); | 	qse_raddic_close (dic); | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
|  | oops: | ||||||
|  | 	if (dic) qse_raddic_close (dic); | ||||||
|  | 	return -1; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int test3 () | static int test3 () | ||||||
| @ -424,25 +423,60 @@ static int test3 () | |||||||
| 	n = qse_raddic_setopt (dic, QSE_RADDIC_TRAIT, &trait); | 	n = qse_raddic_setopt (dic, QSE_RADDIC_TRAIT, &trait); | ||||||
| 	_assert (n == 0, QSE_T("cannot set trait")); | 	_assert (n == 0, QSE_T("cannot set trait")); | ||||||
|  |  | ||||||
| 	n = qse_raddic_load (dic, QSE_T("fr2/dictionary")); | 	n = qse_raddic_load (dic, QSE_T("fr/dictionary")); | ||||||
| 	_assert (n == 0, qse_raddic_geterrmsg(dic)); | 	_assert2 (n == 0, QSE_T("unabled to load dictionary"), qse_raddic_geterrmsg(dic)); | ||||||
|  |  | ||||||
| 	v = qse_raddic_findvendorbyname (dic, QSE_T("cisco")); | 	v = qse_raddic_findvendorbyname (dic, QSE_T("cisco")); | ||||||
| 	_assert (v && v->vendorpec == 9, "wrong vendor value"); | 	_assert (v && v->vendorpec == 9, "wrong vendor value"); | ||||||
|  |  | ||||||
| 	c = qse_raddic_findconstbyname (dic, QSE_RADDIC_ATTR_MAKE(0,49), QSE_T("Reauthentication-Failure")); | 	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); | 	qse_raddic_close (dic); | ||||||
| 	return 0; | 	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 () | int main () | ||||||
| { | { | ||||||
| 	qse_open_stdsios ();  | 	qse_open_stdsios ();  | ||||||
|  |  | ||||||
| 	R (test1); | 	R (test1); | ||||||
| 	R (test2); | 	R (test2); | ||||||
| 	R (test3); | 	R (test3); | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
|  | 	R (test10); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | oops: | ||||||
| 	qse_close_stdsios (); | 	qse_close_stdsios (); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user