enhanced radius message handling functions

This commit is contained in:
hyung-hwan 2021-08-13 03:43:46 +00:00
parent 09f9dd8f51
commit 0e85526d95
5 changed files with 865 additions and 288 deletions

View File

@ -167,8 +167,27 @@ typedef int (*hio_rad_attr_walker_t) (
void* ctx void* ctx
); );
enum hio_rad_attr_type_t #define HIO_RAD_ATTR_IS_SHORT_EXTENDED(attrtype) ((attrtype) >= HIO_RAD_ATTR_EXTENDED_1 && (attrtype) <= HIO_RAD_ATTR_EXTENDED_4)
#define HIO_RAD_ATTR_IS_LONG_EXTENDED(attrtype) ((attrtype) >= HIO_RAD_ATTR_EXTENDED_5 && (attrtype) <= HIO_RAD_ATTR_EXTENDED_6)
#define HIO_RAD_ATTR_IS_EXTENDED(attrtype) ((attrtype) >= HIO_RAD_ATTR_EXTENDED_1 && (attrtype) <= HIO_RAD_ATTR_EXTENDED_6)
/* The attribute code is an attribute type encoded in 2 byte integer. */
#define HIO_RAD_ATTR_CODE_MAKE(hi,lo) ((hio_uint16_t)((hi) & 0xFF) << 8 | ((lo) & 0xFF))
#define HIO_RAD_ATTR_CODE_HI(attrtype) (((attrtype) >> 8) & 0xFF)
#define HIO_RAD_ATTR_CODE_LO(attrtype) ((attrtype) & 0xFF)
#define HIO_RAD_ATTR_CODE_EXTENDED_1(lo) HIO_RAD_ATTR_CODE_MAKE(HIO_RAD_ATTR_EXTENDED_1, lo)
#define HIO_RAD_ATTR_CODE_EXTENDED_2(lo) HIO_RAD_ATTR_CODE_MAKE(HIO_RAD_ATTR_EXTENDED_2, lo)
#define HIO_RAD_ATTR_CODE_EXTENDED_3(lo) HIO_RAD_ATTR_CODE_MAKE(HIO_RAD_ATTR_EXTENDED_3, lo)
#define HIO_RAD_ATTR_CODE_EXTENDED_4(lo) HIO_RAD_ATTR_CODE_MAKE(HIO_RAD_ATTR_EXTENDED_4, lo)
#define HIO_RAD_ATTR_CODE_EXTENDED_5(lo) HIO_RAD_ATTR_CODE_MAKE(HIO_RAD_ATTR_EXTENDED_5, lo)
#define HIO_RAD_ATTR_CODE_EXTENDED_6(lo) HIO_RAD_ATTR_CODE_MAKE(HIO_RAD_ATTR_EXTENDED_6, lo)
enum hio_rad_attr_code_t
{ {
/* -----------------------------------------------------------
* 1 byte attribute types. they can be used as a code or a type
* ----------------------------------------------------------- */
HIO_RAD_ATTR_USER_NAME = 1, /* string */ HIO_RAD_ATTR_USER_NAME = 1, /* string */
HIO_RAD_ATTR_USER_PASSWORD = 2, /* string encrypted */ HIO_RAD_ATTR_USER_PASSWORD = 2, /* string encrypted */
HIO_RAD_ATTR_NAS_IP_ADDRESS = 4, /* ipaddr */ HIO_RAD_ATTR_NAS_IP_ADDRESS = 4, /* ipaddr */
@ -195,7 +214,7 @@ enum hio_rad_attr_type_t
HIO_RAD_ATTR_NAS_PORT_TYPE = 61, /* integer */ HIO_RAD_ATTR_NAS_PORT_TYPE = 61, /* integer */
HIO_RAD_ATTR_ACCT_INTERIM_INTERVAL = 85, /* integer */ HIO_RAD_ATTR_ACCT_INTERIM_INTERVAL = 85, /* integer */
HIO_RAD_ATTR_NAS_PORT_ID = 87, /* string */ HIO_RAD_ATTR_NAS_PORT_ID = 87, /* string */
HIO_RAD_ATTR_FRAMED_IPV6_PREFIX = 97, /* ipv6prefix */ HIO_RAD_ATTR_FRAMED_IPV6_PREFIX = 97, /* ipv6prefix */
HIO_RAD_ATTR_EXTENDED_1 = 241, HIO_RAD_ATTR_EXTENDED_1 = 241,
HIO_RAD_ATTR_EXTENDED_2 = 242, HIO_RAD_ATTR_EXTENDED_2 = 242,
@ -203,11 +222,14 @@ enum hio_rad_attr_type_t
HIO_RAD_ATTR_EXTENDED_4 = 244, HIO_RAD_ATTR_EXTENDED_4 = 244,
HIO_RAD_ATTR_EXTENDED_5 = 245, /* long extended */ HIO_RAD_ATTR_EXTENDED_5 = 245, /* long extended */
HIO_RAD_ATTR_EXTENDED_6 = 246, /* long extended */ HIO_RAD_ATTR_EXTENDED_6 = 246, /* long extended */
/* -----------------------------------------------------------
* 2-byte attribute codes. represented extended attributes.
* ----------------------------------------------------------- */
HIO_RAD_ATTR_CODE_FRAG_STATUS = HIO_RAD_ATTR_CODE_EXTENDED_1(1),
HIO_RAD_ATTR_CODE_PROXY_STATE_LENGTH = HIO_RAD_ATTR_CODE_EXTENDED_1(2),
}; };
#define HIO_RAD_ATTR_IS_SHORT_EXTENDED(attrtype) ((attrtype) >= HIO_RAD_ATTR_EXTENDED_1 && (attrtype) <= HIO_RAD_ATTR_EXTENDED_4)
#define HIO_RAD_ATTR_IS_LONG_EXTENDED(attrtype) ((attrtype) >= HIO_RAD_ATTR_EXTENDED_5 && (attrtype) <= HIO_RAD_ATTR_EXTENDED_6)
#define HIO_RAD_ATTR_IS_EXTENDED(attrtype) ((attrtype) >= HIO_RAD_ATTR_EXTENDED_1 && (attrtype) <= HIO_RAD_ATTR_EXTENDED_6)
enum hio_rad_attr_acct_status_type_t enum hio_rad_attr_acct_status_type_t
{ {
@ -252,80 +274,98 @@ enum hio_rad_attr_nas_port_type_t
/* TODO: more types */ /* TODO: more types */
}; };
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
#endif #endif
/* ----------------------------------------------------------- /* ----------------------------------------------------------------------- */
* RARIUS MESSAGE FUNCTIONS
* ----------------------------------------------------------- */
HIO_EXPORT void hio_rad_initialize ( HIO_EXPORT void hio_rad_initialize (
hio_rad_hdr_t* hdr, hio_rad_hdr_t* hdr,
hio_rad_code_t code, hio_rad_code_t code,
hio_uint8_t id hio_uint8_t id
); );
HIO_EXPORT hio_rad_attr_hdr_t* hio_rad_find_attribute (
hio_rad_hdr_t* hdr,
hio_uint8_t attrtype,
int index
);
HIO_EXPORT hio_rad_vsattr_hdr_t* hio_rad_find_vsattr (
hio_rad_hdr_t* hdr,
hio_uint32_t vendor,
hio_uint8_t attrtype,
int index
);
HIO_EXPORT hio_rad_xvsattr_hdr_t* hio_rad_find_extended_vsattr (
hio_rad_hdr_t* hdr,
hio_uint32_t vendor,
hio_uint8_t xtype,
hio_uint8_t attrtype,
int index
);
HIO_EXPORT hio_rad_attr_hdr_t* hio_rad_find_vendor_specific_attribute (
hio_rad_hdr_t* hdr,
hio_uint32_t vendor,
hio_uint8_t id,
int index
);
HIO_EXPORT int hio_rad_walk_attributes ( HIO_EXPORT int hio_rad_walk_attributes (
const hio_rad_hdr_t* hdr, const hio_rad_hdr_t* hdr,
hio_rad_attr_walker_t walker, hio_rad_attr_walker_t walker,
void* ctx void* ctx
); );
HIO_EXPORT int hio_rad_insert_attribute (
hio_rad_hdr_t* auth, /* ----------------------------------------------------------------------- */
int max,
HIO_EXPORT hio_rad_attr_hdr_t* hio_rad_find_attr (
hio_rad_hdr_t* hdr,
hio_uint16_t attrcode,
int index
);
HIO_EXPORT hio_rad_vsattr_hdr_t* hio_rad_find_vsattr (
hio_rad_hdr_t* hdr,
hio_uint32_t vendor,
hio_uint16_t attrcode,
int index
);
HIO_EXPORT int hio_rad_delete_attr (
hio_rad_hdr_t* hdr,
hio_uint16_t attrcode,
int index
);
HIO_EXPORT int hio_rad_delete_vsattr (
hio_rad_hdr_t* hdr,
hio_uint32_t vendor,
hio_uint16_t attrcode,
int index
);
HIO_EXPORT hio_rad_attr_hdr_t* hio_rad_insert_attr (
hio_rad_hdr_t* auth,
int max,
hio_uint16_t attrcode,
const void* ptr,
hio_uint16_t len
);
HIO_EXPORT hio_rad_vsattr_hdr_t* hio_rad_insert_vsattr (
hio_rad_hdr_t* auth,
int max,
hio_uint32_t vendor,
hio_uint16_t attrcode,
const void* ptr,
hio_uint16_t len
);
/* ----------------------------------------------------------------------- */
HIO_EXPORT hio_rad_attr_hdr_t* hio_rad_find_attribute (
hio_rad_hdr_t* hdr,
hio_uint8_t attrtype,
int index
);
HIO_EXPORT hio_rad_xattr_hdr_t* hio_rad_find_extended_attribute (
hio_rad_hdr_t* hdr,
hio_uint8_t xtype,
hio_uint8_t attrtype,
int index
);
HIO_EXPORT hio_rad_vsattr_hdr_t* hio_rad_find_vendor_specific_attribute (
hio_rad_hdr_t* hdr,
hio_uint32_t vendor,
hio_uint8_t id, hio_uint8_t id,
const void* ptr, int index
hio_uint8_t len
); );
HIO_EXPORT int hio_rad_insert_vendor_specific_attribute ( HIO_EXPORT hio_rad_xvsattr_hdr_t* hio_rad_find_extended_vendor_specific_attribute (
hio_rad_hdr_t* auth, hio_rad_hdr_t* hdr,
int max,
hio_uint32_t vendor, hio_uint32_t vendor,
hio_uint8_t xtype,
hio_uint8_t attrtype, hio_uint8_t attrtype,
const void* ptr, int index
hio_uint8_t len
);
HIO_EXPORT int hio_rad_insert_extended_vendor_specific_attribute (
hio_rad_hdr_t* auth,
int max,
hio_uint32_t vendor,
hio_uint8_t xtype, /* HIO_RAD_ATTR_EXTENDED_X */
hio_uint8_t attrtype,
const void* ptr,
hio_uint8_t len,
hio_uint8_t lxflags
); );
HIO_EXPORT int hio_rad_delete_attribute ( HIO_EXPORT int hio_rad_delete_attribute (
@ -334,6 +374,13 @@ HIO_EXPORT int hio_rad_delete_attribute (
int index int index
); );
HIO_EXPORT int hio_rad_delete_extended_attribute (
hio_rad_hdr_t* auth,
hio_uint8_t xtype,
hio_uint8_t attrtype,
int index
);
HIO_EXPORT int hio_rad_delete_vendor_specific_attribute ( HIO_EXPORT int hio_rad_delete_vendor_specific_attribute (
hio_rad_hdr_t* auth, hio_rad_hdr_t* auth,
hio_uint32_t vendor, hio_uint32_t vendor,
@ -349,7 +396,46 @@ HIO_EXPORT int hio_rad_delete_extended_vendor_specific_attribute (
int index int index
); );
HIO_EXPORT int hio_rad_insert_attribute_with_bcstr ( HIO_EXPORT hio_rad_attr_hdr_t* hio_rad_insert_attribute (
hio_rad_hdr_t* auth,
int max,
hio_uint8_t id,
const void* ptr,
hio_uint8_t len
);
HIO_EXPORT hio_rad_xattr_hdr_t* hio_rad_insert_extended_attribute (
hio_rad_hdr_t* auth,
int max,
hio_uint8_t xtype,
hio_uint8_t attrtype,
const void* ptr,
hio_uint8_t len,
hio_uint8_t lxflags
);
HIO_EXPORT hio_rad_vsattr_hdr_t* hio_rad_insert_vendor_specific_attribute (
hio_rad_hdr_t* auth,
int max,
hio_uint32_t vendor,
hio_uint8_t attrtype,
const void* ptr,
hio_uint8_t len
);
HIO_EXPORT hio_rad_xvsattr_hdr_t* hio_rad_insert_extended_vendor_specific_attribute (
hio_rad_hdr_t* auth,
int max,
hio_uint32_t vendor,
hio_uint8_t xtype, /* HIO_RAD_ATTR_EXTENDED_X */
hio_uint8_t attrtype,
const void* ptr,
hio_uint8_t len,
hio_uint8_t lxflags
);
HIO_EXPORT hio_rad_attr_hdr_t* hio_rad_insert_attribute_with_bcstr (
hio_rad_hdr_t* auth, hio_rad_hdr_t* auth,
int max, int max,
hio_uint32_t vendor, /* in host-byte order */ hio_uint32_t vendor, /* in host-byte order */
@ -357,7 +443,7 @@ HIO_EXPORT int hio_rad_insert_attribute_with_bcstr (
const hio_bch_t* value const hio_bch_t* value
); );
HIO_EXPORT int hio_rad_insert_attribute_ucstr ( HIO_EXPORT hio_rad_attr_hdr_t* hio_rad_insert_attribute_ucstr (
hio_rad_hdr_t* auth, hio_rad_hdr_t* auth,
int max, int max,
hio_uint32_t vendor, /* in host-byte order */ hio_uint32_t vendor, /* in host-byte order */
@ -365,7 +451,7 @@ HIO_EXPORT int hio_rad_insert_attribute_ucstr (
const hio_uch_t* value const hio_uch_t* value
); );
HIO_EXPORT int hio_rad_insert_attribute_with_bchars ( HIO_EXPORT hio_rad_attr_hdr_t* hio_rad_insert_attribute_with_bchars (
hio_rad_hdr_t* auth, hio_rad_hdr_t* auth,
int max, int max,
hio_uint32_t vendor, /* in host-byte order */ hio_uint32_t vendor, /* in host-byte order */
@ -374,7 +460,7 @@ HIO_EXPORT int hio_rad_insert_attribute_with_bchars (
hio_uint8_t length hio_uint8_t length
); );
HIO_EXPORT int hio_rad_insert_attribute_with_uchars ( HIO_EXPORT hio_rad_attr_hdr_t* hio_rad_insert_attribute_with_uchars (
hio_rad_hdr_t* auth, hio_rad_hdr_t* auth,
int max, int max,
hio_uint32_t vendor, /* in host-byte order */ hio_uint32_t vendor, /* in host-byte order */
@ -383,7 +469,7 @@ HIO_EXPORT int hio_rad_insert_attribute_with_uchars (
hio_uint8_t length hio_uint8_t length
); );
HIO_EXPORT int hio_rad_insert_uint32_attribute ( HIO_EXPORT hio_rad_attr_hdr_t* hio_rad_insert_uint32_attribute (
hio_rad_hdr_t* auth, hio_rad_hdr_t* auth,
int max, int max,
hio_uint32_t vendor, /* in host-byte order */ hio_uint32_t vendor, /* in host-byte order */
@ -391,43 +477,47 @@ HIO_EXPORT int hio_rad_insert_uint32_attribute (
hio_uint32_t value /* in host-byte order */ hio_uint32_t value /* in host-byte order */
); );
HIO_EXPORT int hio_rad_insert_ipv6prefix_attribute ( HIO_EXPORT hio_rad_attr_hdr_t* hio_rad_insert_ipv6prefix_attribute (
hio_rad_hdr_t* auth, hio_rad_hdr_t* auth,
int max, int max,
hio_uint32_t vendor, /* in host-byte order */ hio_uint32_t vendor, /* in host-byte order */
hio_uint8_t id, hio_uint8_t id,
hio_uint8_t prefix_bits, hio_uint8_t prefix_bits,
const hio_ip6ad_t* value const hio_ip6ad_t* value
); );
HIO_EXPORT int hio_rad_insert_giga_attribute ( #if (HIO_SIZEOF_UINT64_T > 0)
hio_rad_hdr_t* auth, HIO_EXPORT hio_rad_attr_hdr_t* hio_rad_insert_giga_attribute (
int max, hio_rad_hdr_t* auth,
hio_uint32_t vendor, int max,
int low_id, hio_uint32_t vendor,
int high_id, int low_id,
hio_uint64_t value int high_id,
hio_uint64_t value
); );
#endif
/* ----------------------------------------------------------------------- */
HIO_EXPORT int hio_rad_set_user_password ( HIO_EXPORT int hio_rad_set_user_password (
hio_rad_hdr_t* auth, hio_rad_hdr_t* auth,
int max, int max,
const hio_bch_t* password, const hio_bch_t* password,
const hio_bch_t* secret const hio_bch_t* secret
); );
HIO_EXPORT void hio_rad_fill_authenticator ( HIO_EXPORT void hio_rad_fill_authenticator (
hio_rad_hdr_t* auth hio_rad_hdr_t* auth
); );
HIO_EXPORT void hio_rad_copy_authenticator ( HIO_EXPORT void hio_rad_copy_authenticator (
hio_rad_hdr_t* dst, hio_rad_hdr_t* dst,
const hio_rad_hdr_t* src const hio_rad_hdr_t* src
); );
HIO_EXPORT int hio_rad_set_authenticator ( HIO_EXPORT int hio_rad_set_authenticator (
hio_rad_hdr_t* req, hio_rad_hdr_t* req,
const hio_bch_t* secret const hio_bch_t* secret
); );
/* /*

View File

@ -33,10 +33,10 @@
void hio_rad_initialize (hio_rad_hdr_t* hdr, hio_rad_code_t code, hio_uint8_t id) void hio_rad_initialize (hio_rad_hdr_t* hdr, hio_rad_code_t code, hio_uint8_t id)
{ {
HIO_MEMSET (hdr, 0, sizeof(*hdr)); HIO_MEMSET (hdr, 0, HIO_SIZEOF(*hdr));
hdr->code = code; hdr->code = code;
hdr->id = id; hdr->id = id;
hdr->length = hio_hton16(sizeof(*hdr)); hdr->length = hio_hton16(HIO_SIZEOF(*hdr));
} }
static HIO_INLINE void xor (void* p, void* q, int length) static HIO_INLINE void xor (void* p, void* q, int length)
@ -51,11 +51,9 @@ static void fill_authenticator_randomly (void* authenticator, int length)
{ {
hio_uint8_t* v = (hio_uint8_t*)authenticator; hio_uint8_t* v = (hio_uint8_t*)authenticator;
int total = 0; int total = 0;
#if defined(__linux)
int fd; int fd;
fd = open("/dev/urandom", O_RDONLY, 0); /* Linux: get *real* random numbers */ fd = open("/dev/urandom", O_RDONLY, 0);
if (fd >= 0) if (fd >= 0)
{ {
while (total < length) while (total < length)
@ -66,7 +64,6 @@ static void fill_authenticator_randomly (void* authenticator, int length)
} }
close (fd); close (fd);
} }
#endif
if (total < length) if (total < length)
{ {
@ -86,6 +83,60 @@ static void fill_authenticator_randomly (void* authenticator, int length)
} }
} }
int hio_rad_walk_attributes (const hio_rad_hdr_t* hdr, hio_rad_attr_walker_t walker, void* ctx)
{
int totlen, rem;
hio_rad_attr_hdr_t* attr;
totlen = hio_ntoh16(hdr->length);
if (totlen < HIO_SIZEOF(*hdr)) return -1;
rem = totlen - HIO_SIZEOF(*hdr);
attr = (hio_rad_attr_hdr_t*)(hdr + 1);
while (rem >= HIO_SIZEOF(*attr))
{
/* sanity checks */
if (rem < attr->length) return -1;
if (attr->length < HIO_SIZEOF(*attr))
{
/* attribute length cannot be less than the header size.
* the packet could be corrupted... */
return -1;
}
rem -= attr->length;
if (attr->type == HIO_RAD_ATTR_VENDOR_SPECIFIC)
{
hio_rad_vsattr_hdr_t* vsattr;
int val_len;
if (attr->length < HIO_SIZEOF(*vsattr)) return -1;
vsattr = (hio_rad_vsattr_hdr_t*)attr;
val_len = (int)vsattr->length - HIO_SIZEOF(*vsattr);
if ((int)vsattr->vs.length != val_len + HIO_SIZEOF(vsattr->vs)) return -1;
/* if this vendor happens to be 0, walker can't tell
* if it is vendor specific or not because 0 is passed in
* for non-VSAs. but i don't care. in reality,
* 0 is reserved in IANA enterpirse number assignments.
* (http://www.iana.org/assignments/enterprise-numbers) */
if (walker(hdr, hio_ntoh32(vsattr->vendor), &vsattr->vs, ctx) <= -1) return -1;
}
else
{
if (walker(hdr, 0, attr, ctx) <= -1) return -1;
}
attr = (hio_rad_attr_hdr_t*)((hio_uint8_t*) attr + attr->length);
}
return 0;
}
/* ---------------------------------------------------------------- */
static hio_rad_attr_hdr_t* find_attribute (hio_rad_attr_hdr_t* attr, int* len, hio_uint8_t attrtype) static hio_rad_attr_hdr_t* find_attribute (hio_rad_attr_hdr_t* attr, int* len, hio_uint8_t attrtype)
{ {
int rem = *len; int rem = *len;
@ -189,7 +240,7 @@ hio_rad_attr_hdr_t* hio_rad_find_attribute (hio_rad_hdr_t* hdr, hio_uint8_t attr
return HIO_NULL; return HIO_NULL;
} }
hio_rad_attr_hdr_t* hio_rad_find_extended_attribute (hio_rad_hdr_t* hdr, hio_uint8_t xtype, hio_uint8_t attrtype, int index) hio_rad_xattr_hdr_t* hio_rad_find_extended_attribute (hio_rad_hdr_t* hdr, hio_uint8_t xtype, hio_uint8_t attrtype, int index)
{ {
hio_rad_attr_hdr_t *attr = (hio_rad_attr_hdr_t*)(hdr + 1); hio_rad_attr_hdr_t *attr = (hio_rad_attr_hdr_t*)(hdr + 1);
@ -199,7 +250,7 @@ hio_rad_attr_hdr_t* hio_rad_find_extended_attribute (hio_rad_hdr_t* hdr, hio_uin
attr = find_extended_attribute(attr, &len, xtype, attrtype); attr = find_extended_attribute(attr, &len, xtype, attrtype);
while (attr) while (attr)
{ {
if (index <= 0) return attr; if (index <= 0) return (hio_rad_xattr_hdr_t*)attr;
index--; index--;
attr = find_extended_attribute((hio_rad_attr_hdr_t*)((hio_uint8_t*)attr + attr->length), &len, xtype, attrtype); attr = find_extended_attribute((hio_rad_attr_hdr_t*)((hio_uint8_t*)attr + attr->length), &len, xtype, attrtype);
} }
@ -208,7 +259,7 @@ hio_rad_attr_hdr_t* hio_rad_find_extended_attribute (hio_rad_hdr_t* hdr, hio_uin
return HIO_NULL; return HIO_NULL;
} }
hio_rad_vsattr_hdr_t* hio_rad_find_vsattr (hio_rad_hdr_t* hdr, hio_uint32_t vendor, hio_uint8_t attrtype, int index) hio_rad_vsattr_hdr_t* hio_rad_find_vendor_specific_attribute (hio_rad_hdr_t* hdr, hio_uint32_t vendor, hio_uint8_t attrtype, int index)
{ {
hio_rad_attr_hdr_t *attr = (hio_rad_attr_hdr_t*)(hdr+1); hio_rad_attr_hdr_t *attr = (hio_rad_attr_hdr_t*)(hdr+1);
@ -246,7 +297,8 @@ hio_rad_vsattr_hdr_t* hio_rad_find_vsattr (hio_rad_hdr_t* hdr, hio_uint32_t vend
return HIO_NULL; return HIO_NULL;
} }
hio_rad_xvsattr_hdr_t* hio_rad_find_extended_vsattr (hio_rad_hdr_t* hdr, hio_uint32_t vendor, hio_uint8_t xtype, hio_uint8_t attrtype, int index)
hio_rad_xvsattr_hdr_t* hio_rad_find_extended_vendor_specific_attribute (hio_rad_hdr_t* hdr, hio_uint32_t vendor, hio_uint8_t xtype, hio_uint8_t attrtype, int index)
{ {
hio_rad_attr_hdr_t *attr = (hio_rad_attr_hdr_t*)(hdr+1); hio_rad_attr_hdr_t *attr = (hio_rad_attr_hdr_t*)(hdr+1);
@ -309,115 +361,7 @@ hio_rad_xvsattr_hdr_t* hio_rad_find_extended_vsattr (hio_rad_hdr_t* hdr, hio_uin
return HIO_NULL; return HIO_NULL;
} }
hio_rad_attr_hdr_t* hio_rad_find_vendor_specific_attribute (hio_rad_hdr_t* hdr, hio_uint32_t vendor, hio_uint8_t attrtype, int index) /* ---------------------------------------------------------------- */
{
hio_rad_vsattr_hdr_t* vsattr;
vsattr = hio_rad_find_vsattr(hdr, vendor, attrtype, index);
return vsattr? &vsattr->vs: HIO_NULL;
}
int hio_rad_walk_attributes (const hio_rad_hdr_t* hdr, hio_rad_attr_walker_t walker, void* ctx)
{
int totlen, rem;
hio_rad_attr_hdr_t* attr;
totlen = hio_ntoh16(hdr->length);
if (totlen < HIO_SIZEOF(*hdr)) return -1;
rem = totlen - HIO_SIZEOF(*hdr);
attr = (hio_rad_attr_hdr_t*)(hdr + 1);
while (rem >= HIO_SIZEOF(*attr))
{
/* sanity checks */
if (rem < attr->length) return -1;
if (attr->length < HIO_SIZEOF(*attr))
{
/* attribute length cannot be less than the header size.
* the packet could be corrupted... */
return -1;
}
rem -= attr->length;
if (attr->type == HIO_RAD_ATTR_VENDOR_SPECIFIC)
{
hio_rad_vsattr_hdr_t* vsattr;
int val_len;
if (attr->length < HIO_SIZEOF(*vsattr)) return -1;
vsattr = (hio_rad_vsattr_hdr_t*)attr;
val_len = (int)vsattr->length - HIO_SIZEOF(*vsattr);
if ((int)vsattr->vs.length != val_len + HIO_SIZEOF(vsattr->vs)) return -1;
/* if this vendor happens to be 0, walker can't tell
* if it is vendor specific or not because 0 is passed in
* for non-VSAs. but i don't care. in reality,
* 0 is reserved in IANA enterpirse number assignments.
* (http://www.iana.org/assignments/enterprise-numbers) */
if (walker(hdr, hio_ntoh32(vsattr->vendor), &vsattr->vs, ctx) <= -1) return -1;
}
else
{
if (walker(hdr, 0, attr, ctx) <= -1) return -1;
}
attr = (hio_rad_attr_hdr_t*)((hio_uint8_t*) attr + attr->length);
}
return 0;
}
int hio_rad_insert_attribute (
hio_rad_hdr_t* auth, int max,
hio_uint8_t id, const void* ptr, hio_uint8_t len)
{
hio_rad_attr_hdr_t* attr;
int auth_len = hio_ntoh16(auth->length);
int new_auth_len;
/*if (len > HIO_RAD_MAX_ATTR_VALUE_LEN) return -1;*/
if (len > HIO_RAD_MAX_ATTR_VALUE_LEN) len = HIO_RAD_MAX_ATTR_VALUE_LEN;
new_auth_len = auth_len + len + HIO_SIZEOF(*attr);
if (new_auth_len > max) return -1;
attr = (hio_rad_attr_hdr_t*)((hio_uint8_t*)auth + auth_len);
attr->type = id;
attr->length = new_auth_len - auth_len;
HIO_MEMCPY (attr + 1, ptr, len);
auth->length = hio_hton16(new_auth_len);
return 0;
}
int hio_rad_insert_vendor_specific_attribute (
hio_rad_hdr_t* auth, int max,
hio_uint32_t vendor, hio_uint8_t attrtype, const void* ptr, hio_uint8_t len)
{
hio_rad_vsattr_hdr_t* vsattr;
int auth_len = hio_ntoh16(auth->length);
int new_auth_len;
/*if (len > HIO_RAD_MAX_VSATTR_VALUE_LEN) return -1;*/
if (len > HIO_RAD_MAX_VSATTR_VALUE_LEN) len = HIO_RAD_MAX_VSATTR_VALUE_LEN;
new_auth_len = auth_len + HIO_SIZEOF(*vsattr) + len;
if (new_auth_len > max) return -1;
vsattr = (hio_rad_vsattr_hdr_t*)((hio_uint8_t*)auth + auth_len);
vsattr->type = HIO_RAD_ATTR_VENDOR_SPECIFIC;
vsattr->length = new_auth_len - auth_len;
vsattr->vendor = hio_hton32(vendor);
vsattr->vs.type = attrtype;
vsattr->vs.length = HIO_SIZEOF(vsattr->vs) + len;
HIO_MEMCPY (vsattr + 1, ptr, len);
auth->length = hio_hton16(new_auth_len);
return 0;
}
static int delete_attribute (hio_rad_hdr_t* auth, hio_rad_attr_hdr_t* attr) static int delete_attribute (hio_rad_hdr_t* auth, hio_rad_attr_hdr_t* attr)
{ {
@ -444,12 +388,21 @@ int hio_rad_delete_attribute (hio_rad_hdr_t* auth, hio_uint8_t attrtype, int ind
return (delete_attribute(auth, attr) <= -1)? -1: 1; return (delete_attribute(auth, attr) <= -1)? -1: 1;
} }
int hio_rad_delete_extended_attribute (hio_rad_hdr_t* auth, hio_uint8_t xtype, hio_uint8_t attrtype, int index)
{
hio_rad_xattr_hdr_t* attr;
attr = hio_rad_find_extended_attribute(auth, xtype, attrtype, index);
if (!attr) return 0; /* not found */
return (delete_attribute(auth, (hio_rad_attr_hdr_t*)attr) <= -1)? -1: 1;
}
int hio_rad_delete_vendor_specific_attribute ( int hio_rad_delete_vendor_specific_attribute (
hio_rad_hdr_t* auth, hio_uint32_t vendor, hio_uint8_t attrtype, int index) hio_rad_hdr_t* auth, hio_uint32_t vendor, hio_uint8_t attrtype, int index)
{ {
hio_rad_vsattr_hdr_t* vsattr; hio_rad_vsattr_hdr_t* vsattr;
vsattr = hio_rad_find_vsattr(auth, vendor, attrtype, 0); vsattr = hio_rad_find_vendor_specific_attribute(auth, vendor, attrtype, 0);
if (!vsattr) return 0; /* not found */ if (!vsattr) return 0; /* not found */
return (delete_attribute(auth, (hio_rad_attr_hdr_t*)vsattr) <= -1)? -1: 1; return (delete_attribute(auth, (hio_rad_attr_hdr_t*)vsattr) <= -1)? -1: 1;
} }
@ -459,76 +412,225 @@ int hio_rad_delete_extended_vendor_specific_attribute (
{ {
hio_rad_xvsattr_hdr_t* xvsattr; hio_rad_xvsattr_hdr_t* xvsattr;
xvsattr = hio_rad_find_extended_vsattr(auth, vendor, xtype, attrtype, 0); xvsattr = hio_rad_find_extended_vendor_specific_attribute(auth, vendor, xtype, attrtype, 0);
if (!xvsattr) return 0; /* not found */ if (!xvsattr) return 0; /* not found */
return (delete_attribute(auth, (hio_rad_attr_hdr_t*)xvsattr) <= -1)? -1: 1; return (delete_attribute(auth, (hio_rad_attr_hdr_t*)xvsattr) <= -1)? -1: 1;
} }
int hio_rad_insert_attribute_with_bcstr ( /* ---------------------------------------------------------------- */
hio_rad_attr_hdr_t* hio_rad_insert_attribute (
hio_rad_hdr_t* auth, int max,
hio_uint8_t attrtype, const void* ptr, hio_uint8_t len)
{
hio_rad_attr_hdr_t* attr;
int auth_len = hio_ntoh16(auth->length);
int new_auth_len;
/*if (len > HIO_RAD_MAX_ATTR_VALUE_LEN) return HIO_NULL;*/
if (len > HIO_RAD_MAX_ATTR_VALUE_LEN) len = HIO_RAD_MAX_ATTR_VALUE_LEN;
new_auth_len = auth_len + HIO_SIZEOF(*attr) + len;
if (new_auth_len > max) return HIO_NULL;
attr = (hio_rad_attr_hdr_t*)((hio_uint8_t*)auth + auth_len);
attr->type = attrtype;
attr->length = new_auth_len - auth_len;
HIO_MEMCPY (attr + 1, ptr, len);
auth->length = hio_hton16(new_auth_len);
return attr;
}
hio_rad_xattr_hdr_t* hio_rad_insert_extended_attribute (
hio_rad_hdr_t* auth, int max, hio_uint8_t xtype,
hio_uint8_t attrtype, const void* ptr, hio_uint8_t len, hio_uint8_t lxflags)
{
hio_rad_xattr_hdr_t* xattr;
int auth_len = hio_ntoh16(auth->length);
int new_auth_len, maxvallen, hdrlen;
if (HIO_RAD_ATTR_IS_SHORT_EXTENDED(xtype))
{
maxvallen = HIO_RAD_MAX_XATTR_VALUE_LEN;
hdrlen = HIO_SIZEOF(hio_rad_xattr_hdr_t);
}
else if (HIO_RAD_ATTR_IS_LONG_EXTENDED(xtype))
{
maxvallen = HIO_RAD_MAX_LXATTR_VALUE_LEN;
hdrlen = HIO_SIZEOF(hio_rad_lxattr_hdr_t);
}
else return HIO_NULL;
/*if (len > maxvallen) return HIO_NULL;*/
if (len > maxvallen) len = maxvallen;
new_auth_len = auth_len + hdrlen + len;
if (new_auth_len > max) return HIO_NULL;
xattr = (hio_rad_xattr_hdr_t*)((hio_uint8_t*)auth + auth_len);
xattr->type = xtype;
xattr->length = new_auth_len - auth_len;
if (HIO_RAD_ATTR_IS_LONG_EXTENDED(xtype))
{
hio_rad_lxattr_hdr_t* lxattr;
lxattr = (hio_rad_lxattr_hdr_t*)xattr;
lxattr->xtype = attrtype;
lxattr->xflags = lxflags;
HIO_MEMCPY (lxattr + 1, ptr, len);
}
else
{
xattr->xtype = attrtype;
HIO_MEMCPY (xattr + 1, ptr, len);
}
auth->length = hio_hton16(new_auth_len);
return xattr;
}
hio_rad_vsattr_hdr_t* hio_rad_insert_vendor_specific_attribute (
hio_rad_hdr_t* auth, int max,
hio_uint32_t vendor, hio_uint8_t attrtype, const void* ptr, hio_uint8_t len)
{
hio_rad_vsattr_hdr_t* vsattr;
int auth_len = hio_ntoh16(auth->length);
int new_auth_len;
/*if (len > HIO_RAD_MAX_VSATTR_VALUE_LEN) return HIO_NULL;*/
if (len > HIO_RAD_MAX_VSATTR_VALUE_LEN) len = HIO_RAD_MAX_VSATTR_VALUE_LEN;
new_auth_len = auth_len + HIO_SIZEOF(*vsattr) + len;
if (new_auth_len > max) return HIO_NULL;
vsattr = (hio_rad_vsattr_hdr_t*)((hio_uint8_t*)auth + auth_len);
vsattr->type = HIO_RAD_ATTR_VENDOR_SPECIFIC;
vsattr->length = new_auth_len - auth_len;
vsattr->vendor = hio_hton32(vendor);
vsattr->vs.type = attrtype;
vsattr->vs.length = HIO_SIZEOF(vsattr->vs) + len;
HIO_MEMCPY (vsattr + 1, ptr, len);
auth->length = hio_hton16(new_auth_len);
return vsattr;
}
hio_rad_xvsattr_hdr_t* hio_rad_insert_extended_vendor_specific_attribute (
hio_rad_hdr_t* auth, int max, hio_uint32_t vendor, hio_uint8_t xtype,
hio_uint8_t attrtype, const void* ptr, hio_uint8_t len, hio_uint8_t lxflags)
{
/* RFC6929 */
hio_rad_xvsattr_hdr_t* xvsattr;
int auth_len = hio_ntoh16(auth->length);
int new_auth_len, maxvallen, hdrlen;
if (HIO_RAD_ATTR_IS_SHORT_EXTENDED(xtype))
{
maxvallen = HIO_RAD_MAX_XVSATTR_VALUE_LEN;
hdrlen = HIO_SIZEOF(hio_rad_xvsattr_hdr_t);
}
else if (HIO_RAD_ATTR_IS_LONG_EXTENDED(xtype))
{
maxvallen = HIO_RAD_MAX_LXVSATTR_VALUE_LEN;
hdrlen = HIO_SIZEOF(hio_rad_lxvsattr_hdr_t);
}
else return HIO_NULL;
/*if (len > maxvallen) return HIO_NULL;*/
if (len > maxvallen) len = HIO_RAD_MAX_XVSATTR_VALUE_LEN;
new_auth_len = auth_len + hdrlen + len;
if (new_auth_len > max) return HIO_NULL;
xvsattr = (hio_rad_xvsattr_hdr_t*)((hio_uint8_t*)auth + auth_len);
xvsattr->type = xtype;
xvsattr->length = new_auth_len - auth_len;
xvsattr->xtype = HIO_RAD_ATTR_VENDOR_SPECIFIC;
xvsattr->vendor = hio_hton32(vendor);
if (HIO_RAD_ATTR_IS_LONG_EXTENDED(xtype))
{
/* this function is still low-level. it doesn't handle continuation of big data */
hio_rad_lxvsattr_hdr_t* lxvsattr;
lxvsattr = (hio_rad_lxvsattr_hdr_t*)xvsattr;
lxvsattr->lxvs.type = attrtype;
lxvsattr->lxvs.flags = lxflags;
lxvsattr->lxvs.length = len + HIO_SIZEOF(lxvsattr->lxvs);
HIO_MEMCPY (lxvsattr + 1, ptr, len);
}
else
{
xvsattr->xvs.type = attrtype;
xvsattr->xvs.length = len + HIO_SIZEOF(xvsattr->xvs);
HIO_MEMCPY (xvsattr + 1, ptr, len);
}
auth->length = hio_hton16(new_auth_len);
return xvsattr;
}
/* ---------------------------------------------------------------- */
hio_rad_attr_hdr_t* hio_rad_insert_attribute_with_bcstr (
hio_rad_hdr_t* auth, int max, hio_uint32_t vendor, hio_rad_hdr_t* auth, int max, hio_uint32_t vendor,
hio_uint8_t id, const hio_bch_t* value) hio_uint8_t id, const hio_bch_t* value)
{ {
return (vendor == 0)? return (vendor == 0)?
hio_rad_insert_attribute(auth, max, id, value, hio_count_bcstr(value)): hio_rad_insert_attribute(auth, max, id, value, hio_count_bcstr(value)):
hio_rad_insert_vendor_specific_attribute(auth, max, vendor, id, value, hio_count_bcstr(value)); (hio_rad_attr_hdr_t*)hio_rad_insert_vendor_specific_attribute(auth, max, vendor, id, value, hio_count_bcstr(value));
} }
int hio_rad_insert_attribute_with_ucstr ( hio_rad_attr_hdr_t* hio_rad_insert_attribute_with_ucstr (
hio_rad_hdr_t* auth, int max, hio_uint32_t vendor, hio_rad_hdr_t* auth, int max, hio_uint32_t vendor,
hio_uint8_t id, const hio_uch_t* value) hio_uint8_t id, const hio_uch_t* value)
{ {
int n;
hio_oow_t bcslen, ucslen; hio_oow_t bcslen, ucslen;
hio_bch_t bcsval[HIO_RAD_MAX_ATTR_VALUE_LEN + 1]; hio_bch_t bcsval[HIO_RAD_MAX_ATTR_VALUE_LEN + 1];
bcslen = HIO_COUNTOF(bcsval); bcslen = HIO_COUNTOF(bcsval);
if (hio_conv_ucstr_to_utf8(value, &ucslen, bcsval, &bcslen) <= -1) return -1; if (hio_conv_ucstr_to_utf8(value, &ucslen, bcsval, &bcslen) <= -1) return HIO_NULL;
n = (vendor == 0)? return (vendor == 0)?
hio_rad_insert_attribute(auth, max, id, bcsval, bcslen): hio_rad_insert_attribute(auth, max, id, bcsval, bcslen):
hio_rad_insert_vendor_specific_attribute(auth, max, vendor, id, bcsval, bcslen); (hio_rad_attr_hdr_t*)hio_rad_insert_vendor_specific_attribute(auth, max, vendor, id, bcsval, bcslen);
return n;
} }
int hio_rad_insert_attribute_with_bchars ( hio_rad_attr_hdr_t* hio_rad_insert_attribute_with_bchars (
hio_rad_hdr_t* auth, int max, hio_uint32_t vendor, hio_rad_hdr_t* auth, int max, hio_uint32_t vendor,
hio_uint8_t id, const hio_bch_t* value, hio_uint8_t length) hio_uint8_t id, const hio_bch_t* value, hio_uint8_t length)
{ {
return (vendor == 0)? return (vendor == 0)?
hio_rad_insert_attribute(auth, max, id, value, length): hio_rad_insert_attribute(auth, max, id, value, length):
hio_rad_insert_vendor_specific_attribute(auth, max, vendor, id, value, length); (hio_rad_attr_hdr_t*)hio_rad_insert_vendor_specific_attribute(auth, max, vendor, id, value, length);
} }
int hio_rad_insert_attribute_with_uchars ( hio_rad_attr_hdr_t* hio_rad_insert_attribute_with_uchars (
hio_rad_hdr_t* auth, int max, hio_uint32_t vendor, hio_rad_hdr_t* auth, int max, hio_uint32_t vendor,
hio_uint8_t id, const hio_uch_t* value, hio_uint8_t length) hio_uint8_t id, const hio_uch_t* value, hio_uint8_t length)
{ {
int n;
hio_oow_t bcslen, ucslen; hio_oow_t bcslen, ucslen;
hio_bch_t bcsval[HIO_RAD_MAX_ATTR_VALUE_LEN]; hio_bch_t bcsval[HIO_RAD_MAX_ATTR_VALUE_LEN];
ucslen = length; ucslen = length;
bcslen = HIO_COUNTOF(bcsval); bcslen = HIO_COUNTOF(bcsval);
if (hio_conv_uchars_to_utf8(value, &ucslen, bcsval, &bcslen) <= -1) return -1; if (hio_conv_uchars_to_utf8(value, &ucslen, bcsval, &bcslen) <= -1) return HIO_NULL;
n = (vendor == 0)? return (vendor == 0)?
hio_rad_insert_attribute(auth, max, id, bcsval, bcslen): hio_rad_insert_attribute(auth, max, id, bcsval, bcslen):
hio_rad_insert_vendor_specific_attribute(auth, max, vendor, id, bcsval, bcslen); (hio_rad_attr_hdr_t*)hio_rad_insert_vendor_specific_attribute(auth, max, vendor, id, bcsval, bcslen);
return n;
} }
int hio_rad_insert_uint32_attribute ( hio_rad_attr_hdr_t* hio_rad_insert_uint32_attribute (
hio_rad_hdr_t* auth, int max, hio_uint32_t vendor, hio_uint8_t id, hio_uint32_t value) hio_rad_hdr_t* auth, int max, hio_uint32_t vendor, hio_uint8_t id, hio_uint32_t value)
{ {
hio_uint32_t val = hio_hton32(value); hio_uint32_t val = hio_hton32(value);
return (vendor == 0)? return (vendor == 0)?
hio_rad_insert_attribute(auth, max, id, &val, HIO_SIZEOF(val)): hio_rad_insert_attribute(auth, max, id, &val, HIO_SIZEOF(val)):
hio_rad_insert_vendor_specific_attribute(auth, max, vendor, id, &val, HIO_SIZEOF(val)); (hio_rad_attr_hdr_t*)hio_rad_insert_vendor_specific_attribute(auth, max, vendor, id, &val, HIO_SIZEOF(val));
} }
int hio_rad_insert_ipv6prefix_attribute ( hio_rad_attr_hdr_t* hio_rad_insert_ipv6prefix_attribute (
hio_rad_hdr_t* auth, int max, hio_uint32_t vendor, hio_uint8_t id, hio_rad_hdr_t* auth, int max, hio_uint32_t vendor, hio_uint8_t id,
hio_uint8_t prefix_bits, const hio_ip6ad_t* value) hio_uint8_t prefix_bits, const hio_ip6ad_t* value)
{ {
@ -544,7 +646,7 @@ int hio_rad_insert_ipv6prefix_attribute (
if (prefix_bits > 128) prefix_bits = 128; if (prefix_bits > 128) prefix_bits = 128;
HIO_MEMSET (&ipv6prefix, 0, sizeof(ipv6prefix)); HIO_MEMSET (&ipv6prefix, 0, HIO_SIZEOF(ipv6prefix));
ipv6prefix.bits = prefix_bits; ipv6prefix.bits = prefix_bits;
for (i = 0, j = 0; i < prefix_bits; i += 8, j++) for (i = 0, j = 0; i < prefix_bits; i += 8, j++)
@ -571,98 +673,197 @@ int hio_rad_insert_ipv6prefix_attribute (
return (vendor == 0)? return (vendor == 0)?
hio_rad_insert_attribute(auth, max, id, &ipv6prefix, j + 2): hio_rad_insert_attribute(auth, max, id, &ipv6prefix, j + 2):
hio_rad_insert_vendor_specific_attribute(auth, max, vendor, id, &ipv6prefix, j + 2); (hio_rad_attr_hdr_t*)hio_rad_insert_vendor_specific_attribute(auth, max, vendor, id, &ipv6prefix, j + 2);
} }
int hio_rad_insert_giga_attribute ( #if (HIO_SIZEOF_UINT64_T > 0)
hio_rad_attr_hdr_t* hio_rad_insert_giga_attribute (
hio_rad_hdr_t* auth, int max, hio_uint32_t vendor, int low_id, int high_id, hio_uint64_t value) hio_rad_hdr_t* auth, int max, hio_uint32_t vendor, int low_id, int high_id, hio_uint64_t value)
{ {
hio_rad_attr_hdr_t* hdr;
hio_uint32_t low; hio_uint32_t low;
low = value & HIO_TYPE_MAX(hio_uint32_t); low = value & HIO_TYPE_MAX(hio_uint32_t);
low = hio_hton32(low); low = hio_hton32(low);
if (vendor == 0) if (vendor == 0)
{ {
if (hio_rad_insert_attribute(auth, max, low_id, &low, HIO_SIZEOF(low)) <= -1) return -1; hdr = hio_rad_insert_attribute(auth, max, low_id, &low, HIO_SIZEOF(low));
if (!hdr) return HIO_NULL;
if (value > HIO_TYPE_MAX(hio_uint32_t)) if (value > HIO_TYPE_MAX(hio_uint32_t))
{ {
hio_uint32_t high; hio_uint32_t high;
high = value >> (HIO_SIZEOF(hio_uint32_t) * 8); high = value >> (HIO_SIZEOF(hio_uint32_t) * 8);
high = hio_hton32(high); high = hio_hton32(high);
if (hio_rad_insert_attribute(auth, max, high_id, &high, HIO_SIZEOF(high)) <= -1) return -1; if (!hio_rad_insert_attribute(auth, max, high_id, &high, HIO_SIZEOF(high))) return HIO_NULL;
} }
} }
else else
{ {
if (hio_rad_insert_vendor_specific_attribute(auth, max, vendor, low_id, &low, HIO_SIZEOF(low)) <= -1) return -1; hdr = (hio_rad_attr_hdr_t*)hio_rad_insert_vendor_specific_attribute(auth, max, vendor, low_id, &low, HIO_SIZEOF(low));
if (!hdr) return HIO_NULL;
if (value > HIO_TYPE_MAX(hio_uint32_t)) if (value > HIO_TYPE_MAX(hio_uint32_t))
{ {
hio_uint32_t high; hio_uint32_t high;
high = value >> (HIO_SIZEOF(hio_uint32_t) * 8); high = value >> (HIO_SIZEOF(hio_uint32_t) * 8);
high = hio_hton32(high); high = hio_hton32(high);
if (hio_rad_insert_vendor_specific_attribute(auth, max, vendor, high_id, &high, HIO_SIZEOF(high)) <= -1) return -1; if (!hio_rad_insert_vendor_specific_attribute(auth, max, vendor, high_id, &high, HIO_SIZEOF(high))) return HIO_NULL;
} }
} }
return 0; return hdr;
} }
#endif
int hio_rad_insert_extended_vendor_specific_attribute ( /* -----------------------------------------------------------------------
hio_rad_hdr_t* auth, int max, hio_uint32_t vendor, hio_uint8_t xtype, * HIGH-LEVEL ATTRIBUTE FUNCTIONS
hio_uint8_t attrtype, const void* ptr, hio_uint8_t len, hio_uint8_t lxflags) * ----------------------------------------------------------------------- */
hio_rad_attr_hdr_t* hio_rad_find_attr (hio_rad_hdr_t* hdr, hio_uint16_t attrcode, int index)
{ {
/* RFC6929 */ hio_uint8_t hi, lo;
hio_rad_xvsattr_hdr_t* xvsattr;
int auth_len = hio_ntoh16(auth->length);
int new_auth_len, maxvallen, hdrlen;
if (HIO_RAD_ATTR_IS_SHORT_EXTENDED(xtype)) hi = HIO_RAD_ATTR_CODE_HI(attrcode);
lo = HIO_RAD_ATTR_CODE_LO(attrcode);
if (!hi)
{ {
maxvallen = HIO_RAD_MAX_XVSATTR_VALUE_LEN; return hio_rad_find_attribute(hdr, lo, index);
hdrlen = HIO_SIZEOF(hio_rad_xvsattr_hdr_t);
} }
else if (HIO_RAD_ATTR_IS_LONG_EXTENDED(xtype)) else if (HIO_RAD_ATTR_IS_EXTENDED(hi))
{ {
maxvallen = HIO_RAD_MAX_LXVSATTR_VALUE_LEN; /* both short and long */
hdrlen = HIO_SIZEOF(hio_rad_lxvsattr_hdr_t); return (hio_rad_attr_hdr_t*)hio_rad_find_extended_attribute(hdr, hi, lo, index);
}
else return -1;
/*if (len > maxvallen) return -1;*/
if (len > maxvallen) len = HIO_RAD_MAX_XVSATTR_VALUE_LEN;
new_auth_len = auth_len + hdrlen + len;
if (new_auth_len > max) return -1;
xvsattr = (hio_rad_xvsattr_hdr_t*)((hio_uint8_t*)auth + auth_len);
xvsattr->type = xtype;
xvsattr->length = new_auth_len - auth_len;
xvsattr->xtype = HIO_RAD_ATTR_VENDOR_SPECIFIC;
xvsattr->vendor = hio_hton32(vendor);
if (HIO_RAD_ATTR_IS_LONG_EXTENDED(xtype))
{
/* this function is still low-level. it doesn't handle continuation of big data */
hio_rad_lxvsattr_hdr_t* lxvsattr;
lxvsattr = (hio_rad_lxvsattr_hdr_t*)xvsattr;
lxvsattr->lxvs.type = attrtype;
lxvsattr->lxvs.flags = lxflags;
lxvsattr->lxvs.length = len + HIO_SIZEOF(lxvsattr->lxvs);
HIO_MEMCPY (lxvsattr + 1, ptr, len);
}
else
{
xvsattr->xvs.type = attrtype;
xvsattr->xvs.length = len + HIO_SIZEOF(xvsattr->xvs);
HIO_MEMCPY (xvsattr + 1, ptr, len);
} }
auth->length = hio_hton16(new_auth_len); /* attribute code out of range */
return 0; return HIO_NULL;
} }
hio_rad_vsattr_hdr_t* hio_rad_find_vsattr (hio_rad_hdr_t* hdr, hio_uint32_t vendor, hio_uint16_t attrcode, int index)
{
hio_uint8_t hi, lo;
hi = HIO_RAD_ATTR_CODE_HI(attrcode);
lo = HIO_RAD_ATTR_CODE_LO(attrcode);
if (!hi)
{
return hio_rad_find_vendor_specific_attribute(hdr, vendor, lo, index);
}
else if (HIO_RAD_ATTR_IS_EXTENDED(hi))
{
/* both short and long */
return (hio_rad_vsattr_hdr_t*)hio_rad_find_extended_vendor_specific_attribute(hdr, vendor, hi, lo, index);
}
/* attribute code out of range */
return HIO_NULL;
}
int hio_rad_delete_attr (hio_rad_hdr_t* hdr, hio_uint16_t attrcode, int index)
{
hio_uint8_t hi, lo;
hi = HIO_RAD_ATTR_CODE_HI(attrcode);
lo = HIO_RAD_ATTR_CODE_LO(attrcode);
if (!hi)
{
return hio_rad_delete_attribute(hdr, lo, index);
}
else if (HIO_RAD_ATTR_IS_EXTENDED(hi))
{
/* both short and long */
return hio_rad_delete_extended_attribute(hdr, hi, lo, index);
}
/* attribute code out of range */
return -2;
}
int hio_rad_delete_vsattr (hio_rad_hdr_t* hdr, hio_uint32_t vendor, hio_uint16_t attrcode, int index)
{
hio_uint8_t hi, lo;
hi = HIO_RAD_ATTR_CODE_HI(attrcode);
lo = HIO_RAD_ATTR_CODE_LO(attrcode);
if (!hi)
{
return hio_rad_delete_vendor_specific_attribute(hdr, vendor, lo, index);
}
else if (HIO_RAD_ATTR_IS_EXTENDED(hi))
{
/* both short and long */
return hio_rad_delete_extended_vendor_specific_attribute(hdr, vendor, hi, lo, index);
}
/* attribute code out of range */
return -2;
}
hio_rad_attr_hdr_t* hio_rad_insert_attr (hio_rad_hdr_t* auth, int max, hio_uint16_t attrcode, const void* ptr, hio_uint16_t len)
{
hio_uint8_t hi, lo;
hi = HIO_RAD_ATTR_CODE_HI(attrcode);
lo = HIO_RAD_ATTR_CODE_LO(attrcode);
if (!hi)
{
/* classical attribute */
return hio_rad_insert_attribute(auth, max, lo, ptr, len);
}
else if (HIO_RAD_ATTR_IS_SHORT_EXTENDED(hi))
{
return (hio_rad_attr_hdr_t*)hio_rad_insert_extended_attribute(auth, max, hi, lo, ptr, len, 0);
}
else if (HIO_RAD_ATTR_IS_LONG_EXTENDED(hi))
{
/* TODO: mutliple attributes if data is long */
return (hio_rad_attr_hdr_t*)hio_rad_insert_extended_attribute(auth, max, hi, lo, ptr, len, 0);
}
/* attribute code out of range */
return HIO_NULL;
}
hio_rad_vsattr_hdr_t* hio_rad_insert_vsattr (hio_rad_hdr_t* auth, int max, hio_uint32_t vendor, hio_uint16_t attrcode, const void* ptr, hio_uint16_t len)
{
hio_uint8_t hi, lo;
hi = HIO_RAD_ATTR_CODE_HI(attrcode);
lo = HIO_RAD_ATTR_CODE_LO(attrcode);
if (!hi)
{
/* classical attribute */
return hio_rad_insert_vendor_specific_attribute(auth, max, vendor, lo, ptr, len);
}
else if (HIO_RAD_ATTR_IS_SHORT_EXTENDED(hi))
{
return (hio_rad_vsattr_hdr_t*)hio_rad_insert_extended_vendor_specific_attribute(auth, max, vendor, hi, lo, ptr, len, 0);
}
else if (HIO_RAD_ATTR_IS_LONG_EXTENDED(hi))
{
/* TODO: if len is greater than the maxm add multiple extended attributes with continuation */
return (hio_rad_vsattr_hdr_t*)hio_rad_insert_extended_vendor_specific_attribute(auth, max, vendor, hi, lo, ptr, len, 0);
}
/* attribute code out of range */
return HIO_NULL;
}
/* -----------------------------------------------------------------------
* UTILITY FUNCTIONS
* ----------------------------------------------------------------------- */
#define PASS_BLKSIZE HIO_RAD_MAX_AUTHENTICATOR_LEN #define PASS_BLKSIZE HIO_RAD_MAX_AUTHENTICATOR_LEN
#define ALIGN(x,factor) ((((x) + (factor) - 1) / (factor)) * (factor)) #define ALIGN(x,factor) ((((x) + (factor) - 1) / (factor)) * (factor))
@ -727,7 +928,7 @@ int hio_rad_set_user_password (hio_rad_hdr_t* auth, int max, const hio_bch_t* pa
if (n <= -1) goto oops; if (n <= -1) goto oops;
if (n == 0) break; if (n == 0) break;
} }
if (hio_rad_insert_attribute(auth, max, HIO_RAD_ATTR_USER_PASSWORD, hashed, padlen) <= -1) goto oops; if (!hio_rad_insert_attribute(auth, max, HIO_RAD_ATTR_USER_PASSWORD, hashed, padlen)) goto oops;
return 0; return 0;

View File

@ -17,7 +17,7 @@ check_SCRIPTS =
##noinst_SCRIPTS = $(check_SCRIPTS) ##noinst_SCRIPTS = $(check_SCRIPTS)
EXTRA_DIST = $(check_SCRIPTS) EXTRA_DIST = $(check_SCRIPTS)
check_PROGRAMS = t-001 t-002 check_PROGRAMS = t-001 t-002 t-003
t_001_SOURCES = t-001.c t.h t_001_SOURCES = t-001.c t.h
t_001_CPPFLAGS = $(CPPFLAGS_COMMON) t_001_CPPFLAGS = $(CPPFLAGS_COMMON)
@ -31,6 +31,12 @@ t_002_CFLAGS = $(CFLAGS_COMMON)
t_002_LDFLAGS = $(LDFLAGS_COMMON) t_002_LDFLAGS = $(LDFLAGS_COMMON)
t_002_LDADD = $(LIBADD_COMMON) t_002_LDADD = $(LIBADD_COMMON)
t_003_SOURCES = t-003.c t.h
t_003_CPPFLAGS = $(CPPFLAGS_COMMON)
t_003_CFLAGS = $(CFLAGS_COMMON)
t_003_LDFLAGS = $(LDFLAGS_COMMON)
t_003_LDADD = $(LIBADD_COMMON)
TESTS = $(check_PROGRAMS) $(check_SCRIPTS) TESTS = $(check_PROGRAMS) $(check_SCRIPTS)

View File

@ -87,7 +87,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = : POST_UNINSTALL = :
build_triplet = @build@ build_triplet = @build@
host_triplet = @host@ host_triplet = @host@
check_PROGRAMS = t-001$(EXEEXT) t-002$(EXEEXT) check_PROGRAMS = t-001$(EXEEXT) t-002$(EXEEXT) t-003$(EXEEXT)
TESTS = $(check_PROGRAMS) $(am__EXEEXT_1) TESTS = $(check_PROGRAMS) $(am__EXEEXT_1)
subdir = t subdir = t
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@ -122,6 +122,12 @@ t_002_DEPENDENCIES = $(am__DEPENDENCIES_2)
t_002_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ t_002_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(t_002_CFLAGS) $(CFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(t_002_CFLAGS) $(CFLAGS) \
$(t_002_LDFLAGS) $(LDFLAGS) -o $@ $(t_002_LDFLAGS) $(LDFLAGS) -o $@
am_t_003_OBJECTS = t_003-t-003.$(OBJEXT)
t_003_OBJECTS = $(am_t_003_OBJECTS)
t_003_DEPENDENCIES = $(am__DEPENDENCIES_2)
t_003_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(t_003_CFLAGS) $(CFLAGS) \
$(t_003_LDFLAGS) $(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@) AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false am__v_P_0 = false
@ -138,7 +144,7 @@ DEFAULT_INCLUDES =
depcomp = $(SHELL) $(top_srcdir)/ac/depcomp depcomp = $(SHELL) $(top_srcdir)/ac/depcomp
am__maybe_remake_depfiles = depfiles am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/t_001-t-001.Po \ am__depfiles_remade = ./$(DEPDIR)/t_001-t-001.Po \
./$(DEPDIR)/t_002-t-002.Po ./$(DEPDIR)/t_002-t-002.Po ./$(DEPDIR)/t_003-t-003.Po
am__mv = mv -f am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@ -158,8 +164,8 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 = am__v_CCLD_1 =
SOURCES = $(t_001_SOURCES) $(t_002_SOURCES) SOURCES = $(t_001_SOURCES) $(t_002_SOURCES) $(t_003_SOURCES)
DIST_SOURCES = $(t_001_SOURCES) $(t_002_SOURCES) DIST_SOURCES = $(t_001_SOURCES) $(t_002_SOURCES) $(t_003_SOURCES)
am__can_run_installinfo = \ am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \ case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \ n|no|NO) false;; \
@ -553,6 +559,11 @@ t_002_CPPFLAGS = $(CPPFLAGS_COMMON)
t_002_CFLAGS = $(CFLAGS_COMMON) t_002_CFLAGS = $(CFLAGS_COMMON)
t_002_LDFLAGS = $(LDFLAGS_COMMON) t_002_LDFLAGS = $(LDFLAGS_COMMON)
t_002_LDADD = $(LIBADD_COMMON) t_002_LDADD = $(LIBADD_COMMON)
t_003_SOURCES = t-003.c t.h
t_003_CPPFLAGS = $(CPPFLAGS_COMMON)
t_003_CFLAGS = $(CFLAGS_COMMON)
t_003_LDFLAGS = $(LDFLAGS_COMMON)
t_003_LDADD = $(LIBADD_COMMON)
all: all-am all: all-am
.SUFFIXES: .SUFFIXES:
@ -604,6 +615,10 @@ t-002$(EXEEXT): $(t_002_OBJECTS) $(t_002_DEPENDENCIES) $(EXTRA_t_002_DEPENDENCIE
@rm -f t-002$(EXEEXT) @rm -f t-002$(EXEEXT)
$(AM_V_CCLD)$(t_002_LINK) $(t_002_OBJECTS) $(t_002_LDADD) $(LIBS) $(AM_V_CCLD)$(t_002_LINK) $(t_002_OBJECTS) $(t_002_LDADD) $(LIBS)
t-003$(EXEEXT): $(t_003_OBJECTS) $(t_003_DEPENDENCIES) $(EXTRA_t_003_DEPENDENCIES)
@rm -f t-003$(EXEEXT)
$(AM_V_CCLD)$(t_003_LINK) $(t_003_OBJECTS) $(t_003_LDADD) $(LIBS)
mostlyclean-compile: mostlyclean-compile:
-rm -f *.$(OBJEXT) -rm -f *.$(OBJEXT)
@ -612,6 +627,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_001-t-001.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_001-t-001.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_002-t-002.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_002-t-002.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_003-t-003.Po@am__quote@ # am--include-marker
$(am__depfiles_remade): $(am__depfiles_remade):
@$(MKDIR_P) $(@D) @$(MKDIR_P) $(@D)
@ -671,6 +687,20 @@ t_002-t-002.obj: t-002.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(t_002_CPPFLAGS) $(CPPFLAGS) $(t_002_CFLAGS) $(CFLAGS) -c -o t_002-t-002.obj `if test -f 't-002.c'; then $(CYGPATH_W) 't-002.c'; else $(CYGPATH_W) '$(srcdir)/t-002.c'; fi` @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(t_002_CPPFLAGS) $(CPPFLAGS) $(t_002_CFLAGS) $(CFLAGS) -c -o t_002-t-002.obj `if test -f 't-002.c'; then $(CYGPATH_W) 't-002.c'; else $(CYGPATH_W) '$(srcdir)/t-002.c'; fi`
t_003-t-003.o: t-003.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(t_003_CPPFLAGS) $(CPPFLAGS) $(t_003_CFLAGS) $(CFLAGS) -MT t_003-t-003.o -MD -MP -MF $(DEPDIR)/t_003-t-003.Tpo -c -o t_003-t-003.o `test -f 't-003.c' || echo '$(srcdir)/'`t-003.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/t_003-t-003.Tpo $(DEPDIR)/t_003-t-003.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t-003.c' object='t_003-t-003.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(t_003_CPPFLAGS) $(CPPFLAGS) $(t_003_CFLAGS) $(CFLAGS) -c -o t_003-t-003.o `test -f 't-003.c' || echo '$(srcdir)/'`t-003.c
t_003-t-003.obj: t-003.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(t_003_CPPFLAGS) $(CPPFLAGS) $(t_003_CFLAGS) $(CFLAGS) -MT t_003-t-003.obj -MD -MP -MF $(DEPDIR)/t_003-t-003.Tpo -c -o t_003-t-003.obj `if test -f 't-003.c'; then $(CYGPATH_W) 't-003.c'; else $(CYGPATH_W) '$(srcdir)/t-003.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/t_003-t-003.Tpo $(DEPDIR)/t_003-t-003.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t-003.c' object='t_003-t-003.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(t_003_CPPFLAGS) $(CPPFLAGS) $(t_003_CFLAGS) $(CFLAGS) -c -o t_003-t-003.obj `if test -f 't-003.c'; then $(CYGPATH_W) 't-003.c'; else $(CYGPATH_W) '$(srcdir)/t-003.c'; fi`
mostlyclean-libtool: mostlyclean-libtool:
-rm -f *.lo -rm -f *.lo
@ -884,6 +914,13 @@ t-002.log: t-002$(EXEEXT)
--log-file $$b.log --trs-file $$b.trs \ --log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT) "$$tst" $(AM_TESTS_FD_REDIRECT)
t-003.log: t-003$(EXEEXT)
@p='t-003$(EXEEXT)'; \
b='t-003'; \
$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
.test.log: .test.log:
@p='$<'; \ @p='$<'; \
$(am__set_b); \ $(am__set_b); \
@ -979,6 +1016,7 @@ clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
distclean: distclean-am distclean: distclean-am
-rm -f ./$(DEPDIR)/t_001-t-001.Po -rm -f ./$(DEPDIR)/t_001-t-001.Po
-rm -f ./$(DEPDIR)/t_002-t-002.Po -rm -f ./$(DEPDIR)/t_002-t-002.Po
-rm -f ./$(DEPDIR)/t_003-t-003.Po
-rm -f Makefile -rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \ distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags distclean-tags
@ -1026,6 +1064,7 @@ installcheck-am:
maintainer-clean: maintainer-clean-am maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/t_001-t-001.Po -rm -f ./$(DEPDIR)/t_001-t-001.Po
-rm -f ./$(DEPDIR)/t_002-t-002.Po -rm -f ./$(DEPDIR)/t_002-t-002.Po
-rm -f ./$(DEPDIR)/t_003-t-003.Po
-rm -f Makefile -rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic maintainer-clean-am: distclean-am maintainer-clean-generic

241
hio/t/t-003.c Normal file
View File

@ -0,0 +1,241 @@
#include <hio-rad.h>
#include <stdio.h>
#include "t.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main ()
{
{
hio_uint8_t buf[10240];
hio_rad_hdr_t* hdr = buf;
int i, j, n, exptotlen;
struct
{
int index; /* index among same attributes */
int vendor;
int attrcode;
void* ptr;
int len;
} data[] = {
{ 0, 0, HIO_RAD_ATTR_REPLY_MESSAGE, "reply message", 13 },
{ 1, 0, HIO_RAD_ATTR_REPLY_MESSAGE, "reply message 2", 15 },
{ 0, 10415, 1, "470010171566423", 15 },
{ 0, 10415, 8, "imsi-mcc-mnc", 12 },
{ 0, 4329, 5, "ssid", 4 },
{ 0, 0, HIO_RAD_ATTR_NAS_IDENTIFIER, "nas identifier", 14 },
{ 1, 10415, 8, "imsi-mcc-mnc-2", 14 },
/* Frag-Status 241.1 integer. */
{ 0, 0, HIO_RAD_ATTR_CODE_EXTENDED_1(1), "\x02", 1 },
{ 1, 0, HIO_RAD_ATTR_CODE_EXTENDED_1(1), "\x01", 1 },
{ 2, 0, HIO_RAD_ATTR_CODE_EXTENDED_1(1), "\x00", 1 },
/* Proxy-State-Length 241.2 integer. */
{ 0, 0, HIO_RAD_ATTR_CODE_EXTENDED_1(2), "\xFF", 1 },
{ 3, 0, HIO_RAD_ATTR_CODE_EXTENDED_1(1), "\x03", 1 },
{ 1, 0, HIO_RAD_ATTR_CODE_EXTENDED_1(2), "\xDD", 1 },
{ 0, 6527, HIO_RAD_ATTR_CODE_EXTENDED_1(2), "evs attribute", 13 },
{ 1, 6527, HIO_RAD_ATTR_CODE_EXTENDED_1(2), "evs attribute 2", 15 },
{ 0, 8888, HIO_RAD_ATTR_CODE_EXTENDED_4(444), "evs attribute", 13 },
{ 2, 0, HIO_RAD_ATTR_REPLY_MESSAGE, "reply message 3", 15 },
};
hio_rad_initialize (buf, HIO_RAD_ACCESS_REQUEST, 255);
T_ASSERT1 (hdr->code == HIO_RAD_ACCESS_REQUEST, "hdr->code not ok");
T_ASSERT1 (hdr->id == 255, "hdr->id not ok");
exptotlen = HIO_SIZEOF(*hdr);
T_ASSERT1 (hdr->length == HIO_CONST_HTON16(HIO_SIZEOF(*hdr)), "hdr->length not ok");
for (i = 0; i < HIO_COUNTOF(data); i++)
{
if (data[i].vendor)
{
hio_rad_vsattr_hdr_t* vsattr;
hio_rad_xvsattr_hdr_t* xvsattr;
hio_rad_lxvsattr_hdr_t* lxvsattr;
vsattr = hio_rad_insert_vsattr(hdr, HIO_SIZEOF(buf), data[i].vendor, data[i].attrcode, data[i].ptr, data[i].len);
T_ASSERT1 (vsattr != HIO_NULL, "attribute insertion failure");
T_ASSERT1 (hio_ntoh16(hdr->length) == exptotlen + vsattr->length, "hdr->length not ok after attribute insertion");
if (HIO_RAD_ATTR_IS_LONG_EXTENDED(vsattr->type))
{
exptotlen += HIO_SIZEOF(*lxvsattr);
lxvsattr = vsattr;
T_ASSERT1 (lxvsattr->length == HIO_SIZEOF(*lxvsattr) + data[i].len, "wrong attribute length");
}
else if (HIO_RAD_ATTR_IS_SHORT_EXTENDED(vsattr->type))
{
exptotlen += HIO_SIZEOF(*xvsattr);
xvsattr = vsattr;
T_ASSERT1 (xvsattr->length == HIO_SIZEOF(*xvsattr) + data[i].len, "wrong attribute length");
}
else
{
exptotlen += HIO_SIZEOF(*vsattr);
T_ASSERT1 (vsattr->length == HIO_SIZEOF(*vsattr) + data[i].len, "wrong attribute length");
}
}
else
{
hio_rad_attr_hdr_t* attr;
hio_rad_xattr_hdr_t* xattr;
hio_rad_lxattr_hdr_t* lxattr;
attr = hio_rad_insert_attr(hdr, HIO_SIZEOF(buf), data[i].attrcode, data[i].ptr, data[i].len);
T_ASSERT1 (attr != HIO_NULL, "attribute insertion failure");
T_ASSERT1 (hio_ntoh16(hdr->length) == exptotlen + attr->length, "hdr->length not ok after attribute insertion");
if (HIO_RAD_ATTR_IS_LONG_EXTENDED(attr->type))
{
exptotlen += HIO_SIZEOF(*lxattr);
lxattr = attr;
T_ASSERT1 (lxattr->length == HIO_SIZEOF(*lxattr) + data[i].len, "wrong attribute length");
}
else if (HIO_RAD_ATTR_IS_SHORT_EXTENDED(attr->type))
{
exptotlen += HIO_SIZEOF(*xattr);
xattr = attr;
T_ASSERT1 (xattr->length == HIO_SIZEOF(*xattr) + data[i].len, "wrong attribute length");
}
else
{
exptotlen += HIO_SIZEOF(*attr);
T_ASSERT1 (attr->length == HIO_SIZEOF(*attr) + data[i].len, "wrong attribute length");
}
}
T_ASSERT1 (hio_comp_bchars((hio_uint8_t*)hdr + hio_ntoh16(hdr->length) - data[i].len, data[i].len, data[i].ptr, data[i].len, 0) == 0, "wrong attribute value");
exptotlen += data[i].len;
T_ASSERT1 (hio_ntoh16(hdr->length) == exptotlen, "hdr->length not ok after attribute insertion");
for (j = 0; j < HIO_COUNTOF(data); j++)
{
if (data[j].vendor)
{
hio_rad_vsattr_hdr_t* vsattr;
vsattr = hio_rad_find_vsattr(hdr, data[j].vendor, data[j].attrcode, data[j].index);
if (j <= i)
{
void* val_ptr;
int val_len;
T_ASSERT1 (vsattr != HIO_NULL, "find failure");
if (HIO_RAD_ATTR_IS_SHORT_EXTENDED(vsattr->type))
{
hio_rad_xvsattr_hdr_t* xvsattr = (hio_rad_xvsattr_hdr_t*)vsattr;
T_ASSERT1 (hio_ntoh32(xvsattr->vendor) == data[j].vendor, "wrong vendor code");
T_ASSERT1 (xvsattr->type == HIO_RAD_ATTR_CODE_HI(data[j].attrcode), "wrong attribute base");
T_ASSERT1 (xvsattr->length == HIO_SIZEOF(*xvsattr) + data[j].len, "wrong attribute length");
T_ASSERT1 (xvsattr->xvs.type == HIO_RAD_ATTR_CODE_LO(data[j].attrcode), "wrong vendor-specific attribute type");
T_ASSERT1 (xvsattr->xvs.length == HIO_SIZEOF(xvsattr->xvs) + data[j].len, "wrong attribute length");
val_ptr = xvsattr + 1;
val_len = xvsattr->xvs.length - HIO_SIZEOF(xvsattr->xvs);
}
else if (HIO_RAD_ATTR_IS_LONG_EXTENDED(vsattr->type))
{
hio_rad_lxvsattr_hdr_t* lxvsattr = (hio_rad_lxvsattr_hdr_t*)vsattr;
T_ASSERT1 (hio_ntoh32(lxvsattr->vendor) == data[j].vendor, "wrong vendor code");
T_ASSERT1 (lxvsattr->type == HIO_RAD_ATTR_CODE_HI(data[j].attrcode), "wrong attribute base");
T_ASSERT1 (lxvsattr->length == HIO_SIZEOF(*lxvsattr) + data[j].len, "wrong attribute length");
T_ASSERT1 (lxvsattr->lxvs.type == HIO_RAD_ATTR_CODE_LO(data[j].attrcode), "wrong vendor-specific attribute type");
T_ASSERT1 (lxvsattr->lxvs.length == HIO_SIZEOF(lxvsattr->lxvs) + data[j].len, "wrong attribute length");
val_ptr = lxvsattr + 1;
val_len = lxvsattr->lxvs.length - HIO_SIZEOF(lxvsattr->lxvs);
}
else
{
T_ASSERT1 (hio_ntoh32(vsattr->vendor) == data[j].vendor, "wrong vendor code");
T_ASSERT1 (vsattr->type == HIO_RAD_ATTR_VENDOR_SPECIFIC, "wrong attribute type");
T_ASSERT1 (vsattr->length == HIO_SIZEOF(*vsattr) + data[j].len, "wrong attribute length");
T_ASSERT1 (vsattr->vs.type == data[j].attrcode, "wrong vendor-specific attribute type");
T_ASSERT1 (vsattr->vs.length == HIO_SIZEOF(vsattr->vs) + data[j].len, "wrong attribute length");
val_ptr = vsattr + 1;
val_len = vsattr->vs.length - HIO_SIZEOF(vsattr->vs);
}
T_ASSERT1 (hio_comp_bchars(val_ptr, val_len, data[j].ptr, data[j].len, 0) == 0, "wrong attribute value");
}
else
{
T_ASSERT1 (vsattr == HIO_NULL, "find failure");
}
}
else
{
hio_rad_attr_hdr_t* attr;
attr = hio_rad_find_attr(hdr, data[j].attrcode, data[j].index);
if (j <= i)
{
void* val_ptr;
int val_len;
T_ASSERT1 (attr != HIO_NULL, "find failure");
if (HIO_RAD_ATTR_IS_SHORT_EXTENDED(attr->type))
{
hio_rad_xattr_hdr_t* xattr = (hio_rad_xattr_hdr_t*)attr;
T_ASSERT1 (HIO_RAD_ATTR_CODE_HI(data[j].attrcode) == xattr->type, "wrong extended attribute base");
T_ASSERT1 (HIO_RAD_ATTR_CODE_LO(data[j].attrcode) == xattr->xtype, "wrong extended attribute type");
T_ASSERT1 (xattr->length == HIO_SIZEOF(*xattr) + data[j].len, "wrong attribute length");
val_ptr = xattr + 1;
val_len = xattr->length - HIO_SIZEOF(*xattr);
}
else if (HIO_RAD_ATTR_IS_LONG_EXTENDED(attr->type))
{
hio_rad_lxattr_hdr_t* lxattr = (hio_rad_lxattr_hdr_t*)attr;
T_ASSERT1 (HIO_RAD_ATTR_CODE_HI(data[j].attrcode) == lxattr->type, "wrong long extended attribute base");
T_ASSERT1 (HIO_RAD_ATTR_CODE_LO(data[j].attrcode) == lxattr->xtype, "wrong long extended attribute type");
T_ASSERT1 (lxattr->length == HIO_SIZEOF(*lxattr) + data[j].len, "wrong attribute length");
val_ptr = lxattr + 1;
val_len = lxattr->length - HIO_SIZEOF(*lxattr);
}
else
{
T_ASSERT1 (attr->type == data[j].attrcode, "wrong attribute type");
T_ASSERT1 (attr->length == HIO_SIZEOF(*attr) + data[j].len, "wrong attribute length");
val_ptr = attr + 1;
val_len = attr->length - HIO_SIZEOF(*attr);
}
T_ASSERT1 (hio_comp_bchars(val_ptr, val_len, data[j].ptr, data[j].len, 0) == 0, "wrong attribute value");
}
else
{
T_ASSERT1 (attr == HIO_NULL, "find failure");
}
}
}
}
#if 1
{
int s = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in sin;
memset (&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr("192.168.1.1");
sin.sin_port = HIO_CONST_HTON16(1812);
sendto (s, hdr, hio_ntoh16(hdr->length), 0, &sin, sizeof(sin));
}
#endif
}
return 0;
oops:
return -1;
}