diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c index cece78f75..40bbd08e9 100644 --- a/src/common/ieee802_11_common.c +++ b/src/common/ieee802_11_common.c @@ -199,7 +199,7 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen, } -static int ieee802_11_parse_mle(const u8 *pos, size_t elen, +static int ieee802_11_parse_mle(const u8 *pos, size_t elen, size_t **total_len, struct ieee802_11_elems *elems, int show_errors) { @@ -209,22 +209,27 @@ static int ieee802_11_parse_mle(const u8 *pos, size_t elen, case MULTI_LINK_CONTROL_TYPE_BASIC: elems->basic_mle = pos; elems->basic_mle_len = elen; + *total_len = &elems->basic_mle_len; break; case MULTI_LINK_CONTROL_TYPE_PROBE_REQ: elems->probe_req_mle = pos; elems->probe_req_mle_len = elen; + *total_len = &elems->probe_req_mle_len; break; case MULTI_LINK_CONTROL_TYPE_RECONF: elems->reconf_mle = pos; elems->reconf_mle_len = elen; + *total_len = &elems->reconf_mle_len; break; case MULTI_LINK_CONTROL_TYPE_TDLS: elems->tdls_mle = pos; elems->tdls_mle_len = elen; + *total_len = &elems->tdls_mle_len; break; case MULTI_LINK_CONTROL_TYPE_PRIOR_ACCESS: elems->prior_access_mle = pos; elems->prior_access_mle_len = elen; + *total_len = &elems->prior_access_mle_len; break; default: if (show_errors) { @@ -378,7 +383,8 @@ static int ieee802_11_parse_extension(const u8 *pos, size_t elen, case WLAN_EID_EXT_MULTI_LINK: if (elen < 2) break; - if (ieee802_11_parse_mle(pos, elen, elems, show_errors)) + if (ieee802_11_parse_mle(pos, elen, &total_len, elems, + show_errors)) return -1; break; default: @@ -2844,3 +2850,40 @@ const u8 * get_basic_mle_mld_addr(const u8 *buf, size_t len) return &buf[mld_addr_pos]; } + + +struct wpabuf * ieee802_11_defrag_mle(struct ieee802_11_elems *elems, u8 type) +{ + const u8 *data; + size_t len; + + switch (type) { + case MULTI_LINK_CONTROL_TYPE_BASIC: + data = elems->basic_mle; + len = elems->basic_mle_len; + break; + case MULTI_LINK_CONTROL_TYPE_PROBE_REQ: + data = elems->probe_req_mle; + len = elems->probe_req_mle_len; + break; + case MULTI_LINK_CONTROL_TYPE_RECONF: + data = elems->reconf_mle; + len = elems->reconf_mle_len; + break; + case MULTI_LINK_CONTROL_TYPE_TDLS: + data = elems->tdls_mle; + len = elems->tdls_mle_len; + break; + case MULTI_LINK_CONTROL_TYPE_PRIOR_ACCESS: + data = elems->prior_access_mle; + len = elems->prior_access_mle_len; + break; + default: + wpa_printf(MSG_DEBUG, + "Defragmentation not supported for Multi-Link element type=%u", + type); + return NULL; + } + + return ieee802_11_defrag_data(data, len, true); +} diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h index d3453da25..0d258dfb8 100644 --- a/src/common/ieee802_11_common.h +++ b/src/common/ieee802_11_common.h @@ -164,11 +164,11 @@ struct ieee802_11_elems { u8 pasn_params_len; u8 eht_capabilities_len; u8 eht_operation_len; - u8 basic_mle_len; - u8 probe_req_mle_len; - u8 reconf_mle_len; - u8 tdls_mle_len; - u8 prior_access_mle_len; + size_t basic_mle_len; + size_t probe_req_mle_len; + size_t reconf_mle_len; + size_t tdls_mle_len; + size_t prior_access_mle_len; struct mb_ies_info mb_ies; @@ -341,6 +341,7 @@ struct wpabuf * ieee802_11_defrag_data(const u8 *data, size_t len, bool ext_elem); struct wpabuf * ieee802_11_defrag(struct ieee802_11_elems *elems, u8 eid, u8 eid_ext); +struct wpabuf * ieee802_11_defrag_mle(struct ieee802_11_elems *elems, u8 type); const u8 * get_ml_ie(const u8 *ies, size_t len, u8 type); const u8 * get_basic_mle_mld_addr(const u8 *buf, size_t len);