diff options
author | Tobias Brunner <tobias@strongswan.org> | 2012-08-23 09:06:47 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2012-08-31 11:40:28 +0200 |
commit | 576490ab099bbbfa1bd90969b1d68c37d33eedeb (patch) | |
tree | 22d9b12a6a9a1f77be15e9793c2f919e03ac7558 /src/libcharon/encoding/payloads/eap_payload.c | |
parent | cc4eec56f73ef54386badc8732b1867cbe05b47f (diff) | |
download | strongswan-576490ab099bbbfa1bd90969b1d68c37d33eedeb.tar.bz2 strongswan-576490ab099bbbfa1bd90969b1d68c37d33eedeb.tar.xz |
Added method to enumerate EAP types contained in an EAP-Nak
Diffstat (limited to 'src/libcharon/encoding/payloads/eap_payload.c')
-rw-r--r-- | src/libcharon/encoding/payloads/eap_payload.c | 82 |
1 files changed, 71 insertions, 11 deletions
diff --git a/src/libcharon/encoding/payloads/eap_payload.c b/src/libcharon/encoding/payloads/eap_payload.c index 855504fe0..dd2e25795 100644 --- a/src/libcharon/encoding/payloads/eap_payload.c +++ b/src/libcharon/encoding/payloads/eap_payload.c @@ -219,28 +219,87 @@ METHOD(eap_payload_t, get_identifier, u_int8_t, return 0; } +/** + * Get the current type at the given offset into this->data. + * @return the new offset or 0 if failed + */ +static size_t extract_type(private_eap_payload_t *this, size_t offset, + eap_type_t *type, u_int32_t *vendor) +{ + if (this->data.len > offset) + { + *vendor = 0; + *type = this->data.ptr[offset]; + if (*type != EAP_EXPANDED) + { + return offset + 1; + } + if (this->data.len >= offset + 8) + { + *vendor = untoh32(this->data.ptr + offset) & 0x00FFFFFF; + *type = untoh32(this->data.ptr + offset + 4); + return offset + 8; + } + } + return 0; +} + METHOD(eap_payload_t, get_type, eap_type_t, private_eap_payload_t *this, u_int32_t *vendor) { eap_type_t type; *vendor = 0; - if (this->data.len > 4) + if (extract_type(this, 4, &type, vendor)) { - type = this->data.ptr[4]; - if (type != EAP_EXPANDED) - { - return type; - } - if (this->data.len >= 12) - { - *vendor = untoh32(this->data.ptr + 4) & 0x00FFFFFF; - return untoh32(this->data.ptr + 8); - } + return type; } return 0; } +/** + * Type enumerator + */ +typedef struct { + /** public interface */ + enumerator_t public; + /** payload */ + private_eap_payload_t *payload; + /** current offset in the data */ + size_t offset; +} type_enumerator_t; + +METHOD(enumerator_t, enumerate_types, bool, + type_enumerator_t *this, eap_type_t *type, u_int32_t *vendor) +{ + this->offset = extract_type(this->payload, this->offset, type, vendor); + return this->offset; +} + +METHOD(eap_payload_t, get_types, enumerator_t*, + private_eap_payload_t *this) +{ + type_enumerator_t *enumerator; + eap_type_t type; + u_int32_t vendor; + size_t offset; + + offset = extract_type(this, 4, &type, &vendor); + if (offset && type == EAP_NAK) + { + INIT(enumerator, + .public = { + .enumerate = (void*)_enumerate_types, + .destroy = (void*)free, + }, + .payload = this, + .offset = offset, + ); + return &enumerator->public; + } + return enumerator_create_empty(); +} + METHOD(eap_payload_t, is_expanded, bool, private_eap_payload_t *this) { @@ -278,6 +337,7 @@ eap_payload_t *eap_payload_create() .get_code = _get_code, .get_identifier = _get_identifier, .get_type = _get_type, + .get_types = _get_types, .is_expanded = _is_expanded, .destroy = _destroy, }, |