diff options
author | Johannes Berg <johannes.berg@intel.com> | 2019-02-07 16:36:33 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2019-02-08 07:51:50 -0500 |
commit | 1c8745f3ec6f46f5fa99dbcdf92381144ae1b37f (patch) | |
tree | 5b5afc6da8efa240c4fe0cc0c72b16ce1bcbdb41 /net/wireless | |
parent | 0b8fb8235be8be99a197e8d948fc0a2df8dc261a (diff) |
cfg80211: use for_each_element() for multi-bssid parsing
Use the new for_each_element() helper here, we cannot use
for_each_subelement() since we have a fixed 1 byte before
the subelements start.
While at it, also fix le16_to_cpup() to be get_unaligned_le16()
since we don't know anything about alignment.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/scan.c | 47 |
1 files changed, 15 insertions, 32 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 531c2e56413f..54feb7741c26 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -1377,9 +1377,9 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, | |||
1377 | struct cfg80211_bss *trans_bss, | 1377 | struct cfg80211_bss *trans_bss, |
1378 | gfp_t gfp) | 1378 | gfp_t gfp) |
1379 | { | 1379 | { |
1380 | const u8 *pos, *subelement, *mbssid_end_pos; | 1380 | const u8 *mbssid_index_ie; |
1381 | const u8 *tmp, *mbssid_index_ie; | 1381 | const struct element *elem, *sub; |
1382 | size_t subie_len, new_ie_len; | 1382 | size_t new_ie_len; |
1383 | u8 new_bssid[ETH_ALEN]; | 1383 | u8 new_bssid[ETH_ALEN]; |
1384 | u8 *new_ie; | 1384 | u8 *new_ie; |
1385 | u16 capability; | 1385 | u16 capability; |
@@ -1390,34 +1390,21 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, | |||
1390 | if (!cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen)) | 1390 | if (!cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen)) |
1391 | return; | 1391 | return; |
1392 | 1392 | ||
1393 | pos = ie; | ||
1394 | |||
1395 | new_ie = kmalloc(IEEE80211_MAX_DATA_LEN, gfp); | 1393 | new_ie = kmalloc(IEEE80211_MAX_DATA_LEN, gfp); |
1396 | if (!new_ie) | 1394 | if (!new_ie) |
1397 | return; | 1395 | return; |
1398 | 1396 | ||
1399 | while (pos < ie + ielen + 2) { | 1397 | for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) { |
1400 | tmp = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, pos, | 1398 | if (elem->datalen < 4) |
1401 | ielen - (pos - ie)); | 1399 | continue; |
1402 | if (!tmp) | 1400 | for_each_element(sub, elem->data + 1, elem->datalen - 1) { |
1403 | break; | 1401 | if (sub->id != 0 || sub->datalen < 4) { |
1404 | |||
1405 | mbssid_end_pos = tmp + tmp[1] + 2; | ||
1406 | /* Skip Element ID, Len, MaxBSSID Indicator */ | ||
1407 | if (tmp[1] < 4) | ||
1408 | break; | ||
1409 | for (subelement = tmp + 3; subelement < mbssid_end_pos - 1; | ||
1410 | subelement += 2 + subelement[1]) { | ||
1411 | subie_len = subelement[1]; | ||
1412 | if (mbssid_end_pos - subelement < 2 + subie_len) | ||
1413 | break; | ||
1414 | if (subelement[0] != 0 || subelement[1] < 4) { | ||
1415 | /* not a valid BSS profile */ | 1402 | /* not a valid BSS profile */ |
1416 | continue; | 1403 | continue; |
1417 | } | 1404 | } |
1418 | 1405 | ||
1419 | if (subelement[2] != WLAN_EID_NON_TX_BSSID_CAP || | 1406 | if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP || |
1420 | subelement[3] != 2) { | 1407 | sub->data[1] != 2) { |
1421 | /* The first element within the Nontransmitted | 1408 | /* The first element within the Nontransmitted |
1422 | * BSSID Profile is not the Nontransmitted | 1409 | * BSSID Profile is not the Nontransmitted |
1423 | * BSSID Capability element. | 1410 | * BSSID Capability element. |
@@ -1428,26 +1415,24 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, | |||
1428 | /* found a Nontransmitted BSSID Profile */ | 1415 | /* found a Nontransmitted BSSID Profile */ |
1429 | mbssid_index_ie = cfg80211_find_ie | 1416 | mbssid_index_ie = cfg80211_find_ie |
1430 | (WLAN_EID_MULTI_BSSID_IDX, | 1417 | (WLAN_EID_MULTI_BSSID_IDX, |
1431 | subelement + 2, subie_len); | 1418 | sub->data, sub->datalen); |
1432 | if (!mbssid_index_ie || mbssid_index_ie[1] < 1 || | 1419 | if (!mbssid_index_ie || mbssid_index_ie[1] < 1 || |
1433 | mbssid_index_ie[2] == 0) { | 1420 | mbssid_index_ie[2] == 0) { |
1434 | /* No valid Multiple BSSID-Index element */ | 1421 | /* No valid Multiple BSSID-Index element */ |
1435 | continue; | 1422 | continue; |
1436 | } | 1423 | } |
1437 | 1424 | ||
1438 | cfg80211_gen_new_bssid(bssid, tmp[2], | 1425 | cfg80211_gen_new_bssid(bssid, elem->data[0], |
1439 | mbssid_index_ie[2], | 1426 | mbssid_index_ie[2], |
1440 | new_bssid); | 1427 | new_bssid); |
1441 | memset(new_ie, 0, IEEE80211_MAX_DATA_LEN); | 1428 | memset(new_ie, 0, IEEE80211_MAX_DATA_LEN); |
1442 | new_ie_len = cfg80211_gen_new_ie(ie, ielen, | 1429 | new_ie_len = cfg80211_gen_new_ie(ie, ielen, sub->data, |
1443 | subelement + 2, | 1430 | sub->datalen, new_ie, |
1444 | subie_len, new_ie, | ||
1445 | gfp); | 1431 | gfp); |
1446 | if (!new_ie_len) | 1432 | if (!new_ie_len) |
1447 | continue; | 1433 | continue; |
1448 | 1434 | ||
1449 | capability = le16_to_cpup((const __le16 *) | 1435 | capability = get_unaligned_le16(sub->data + 2); |
1450 | &subelement[4]); | ||
1451 | bss = cfg80211_inform_single_bss_data(wiphy, data, | 1436 | bss = cfg80211_inform_single_bss_data(wiphy, data, |
1452 | ftype, | 1437 | ftype, |
1453 | new_bssid, tsf, | 1438 | new_bssid, tsf, |
@@ -1460,8 +1445,6 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, | |||
1460 | break; | 1445 | break; |
1461 | cfg80211_put_bss(wiphy, bss); | 1446 | cfg80211_put_bss(wiphy, bss); |
1462 | } | 1447 | } |
1463 | |||
1464 | pos = mbssid_end_pos; | ||
1465 | } | 1448 | } |
1466 | 1449 | ||
1467 | kfree(new_ie); | 1450 | kfree(new_ie); |