aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/encoding/payloads/eap_payload.c
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2012-08-23 09:06:47 +0200
committerTobias Brunner <tobias@strongswan.org>2012-08-31 11:40:28 +0200
commit576490ab099bbbfa1bd90969b1d68c37d33eedeb (patch)
tree22d9b12a6a9a1f77be15e9793c2f919e03ac7558 /src/libcharon/encoding/payloads/eap_payload.c
parentcc4eec56f73ef54386badc8732b1867cbe05b47f (diff)
downloadstrongswan-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.c82
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,
},