3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-12-21 03:32:42 +01:00

ie: add ie_tlv_extract_wsc_payload

This commit is contained in:
Denis Kenzior 2015-07-09 14:19:43 -05:00
parent a76918e15c
commit 3442736869
2 changed files with 99 additions and 0 deletions

View File

@ -75,6 +75,102 @@ bool ie_tlv_iter_next(struct ie_tlv_iter *iter)
return true; return true;
} }
/*
* Concatenate all vendor IEs with a given OUI + type.
*
* Returns a newly allocated buffer with the contents of the matching ies
* copied into it. @out_len is set to the overall size of the contents.
* If no matching elements were found, NULL is returned and @out_len is
* set to -ENOENT.
*/
static void *ie_tlv_vendor_ie_concat(const unsigned char oui[],
unsigned char type,
const unsigned char *ies,
unsigned int len,
ssize_t *out_len)
{
struct ie_tlv_iter iter;
const unsigned char *data;
unsigned int ie_len;
unsigned int concat_len = 0;
unsigned char *ret;
ie_tlv_iter_init(&iter, ies, len);
while (ie_tlv_iter_next(&iter)) {
if (ie_tlv_iter_get_tag(&iter) != IE_TYPE_VENDOR_SPECIFIC)
continue;
ie_len = ie_tlv_iter_get_length(&iter);
if (ie_len < 4)
continue;
data = ie_tlv_iter_get_data(&iter);
if (memcmp(data, oui, 3))
continue;
if (data[3] != type)
continue;
concat_len += ie_len - 4;
}
if (concat_len == 0) {
if (out_len)
*out_len = -ENOENT;
return NULL;
}
ie_tlv_iter_init(&iter, ies, len);
ret = l_malloc(concat_len);
concat_len = 0;
while (ie_tlv_iter_next(&iter)) {
if (ie_tlv_iter_get_tag(&iter) != IE_TYPE_VENDOR_SPECIFIC)
continue;
ie_len = ie_tlv_iter_get_length(&iter);
if (ie_len < 4)
continue;
data = ie_tlv_iter_get_data(&iter);
if (memcmp(data, oui, 3))
continue;
if (data[3] != type)
continue;
memcpy(ret + concat_len, data + 4, ie_len - 4);
concat_len += ie_len - 4;
}
if (out_len)
*out_len = concat_len;
return ret;
}
/*
* Wi-Fi Simple Configuration v2.0.5, Section 8.2:
* "There may be more than one instance of the Wi-Fi Simple Configuration
* Information Element in a single 802.11 management frame. If multiple
* Information Elements are present, the Wi-Fi Simple Configuration data
* consists of the concatenation of the Data components of those Information
* Elements (the order of these elements in the original packet shall be
* preserved when concatenating Data components)."
*/
void *ie_tlv_extract_wsc_payload(const unsigned char *ies, unsigned int len,
ssize_t *out_len)
{
static unsigned char oui[3] = { 0x00, 0x50, 0xf2 };
return ie_tlv_vendor_ie_concat(oui, 0x04, ies, len, out_len);
}
#define TLV_HEADER_LEN 2 #define TLV_HEADER_LEN 2
static bool ie_tlv_builder_init_recurse(struct ie_tlv_builder *builder, static bool ie_tlv_builder_init_recurse(struct ie_tlv_builder *builder,

View File

@ -249,6 +249,9 @@ static inline const unsigned char *ie_tlv_iter_get_data(
return iter->data; return iter->data;
} }
void *ie_tlv_extract_wsc_payload(const unsigned char *ies, unsigned int len,
ssize_t *out_len);
uint32_t ie_rsn_cipher_suite_to_cipher(enum ie_rsn_cipher_suite suite); uint32_t ie_rsn_cipher_suite_to_cipher(enum ie_rsn_cipher_suite suite);
bool ie_tlv_iter_next(struct ie_tlv_iter *iter); bool ie_tlv_iter_next(struct ie_tlv_iter *iter);
bool ie_tlv_builder_init(struct ie_tlv_builder *builder); bool ie_tlv_builder_init(struct ie_tlv_builder *builder);