From: Johannes Berg <johannes.berg@xxxxxxxxx> The IEs "output" can sometimes combine IEs coming from userspace with IEs generated in the kernel - in particular mac80211 does this for association frames. Add support in this code for the 802.11 IE fragmentation. Signed-off-by: Johannes Berg <johannes.berg@xxxxxxxxx> --- include/linux/ieee80211.h | 1 + net/wireless/util.c | 25 ++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index cfa906f28b7a..2fe22b44b682 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1919,6 +1919,7 @@ enum ieee80211_eid { WLAN_EID_VENDOR_SPECIFIC = 221, WLAN_EID_QOS_PARAMETER = 222, + WLAN_EID_FRAGMENT = 242, }; /* Action category code */ diff --git a/net/wireless/util.c b/net/wireless/util.c index baf7218cec15..f52fbda56467 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1301,6 +1301,25 @@ static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) return false; } +static size_t skip_ie(const u8 *ies, size_t ielen, size_t pos) +{ + /* we assume a validly formed IEs buffer */ + u8 len = ies[pos + 1]; + + pos += 2 + len; + + /* the IE itself must have 255 bytes for fragments to follow */ + if (len < 255) + return pos; + + while (pos < ielen && ies[pos] == WLAN_EID_FRAGMENT) { + len = ies[pos + 1]; + pos += 2 + len; + } + + return pos; +} + size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen, const u8 *ids, int n_ids, const u8 *after_ric, int n_after_ric, @@ -1310,14 +1329,14 @@ size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen, while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) { if (ies[pos] == WLAN_EID_RIC_DATA && n_after_ric) { - pos += 2 + ies[pos + 1]; + pos = skip_ie(ies, ielen, pos); while (pos < ielen && !ieee80211_id_in_list(after_ric, n_after_ric, ies[pos])) - pos += 2 + ies[pos + 1]; + pos = skip_ie(ies, ielen, pos); } else { - pos += 2 + ies[pos + 1]; + pos = skip_ie(ies, ielen, pos); } } -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html