aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/scan.c')
-rw-r--r--net/wireless/scan.c58
1 files changed, 27 insertions, 31 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 0358e12be54b..b5bd58d0f731 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -352,52 +352,48 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *rdev)
352 __cfg80211_bss_expire(rdev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE); 352 __cfg80211_bss_expire(rdev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE);
353} 353}
354 354
355const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len) 355const u8 *cfg80211_find_ie_match(u8 eid, const u8 *ies, int len,
356 const u8 *match, int match_len,
357 int match_offset)
356{ 358{
357 while (len > 2 && ies[0] != eid) { 359 /* match_offset can't be smaller than 2, unless match_len is
360 * zero, in which case match_offset must be zero as well.
361 */
362 if (WARN_ON((match_len && match_offset < 2) ||
363 (!match_len && match_offset)))
364 return NULL;
365
366 while (len >= 2 && len >= ies[1] + 2) {
367 if ((ies[0] == eid) &&
368 (ies[1] + 2 >= match_offset + match_len) &&
369 !memcmp(ies + match_offset, match, match_len))
370 return ies;
371
358 len -= ies[1] + 2; 372 len -= ies[1] + 2;
359 ies += ies[1] + 2; 373 ies += ies[1] + 2;
360 } 374 }
361 if (len < 2) 375
362 return NULL; 376 return NULL;
363 if (len < 2 + ies[1])
364 return NULL;
365 return ies;
366} 377}
367EXPORT_SYMBOL(cfg80211_find_ie); 378EXPORT_SYMBOL(cfg80211_find_ie_match);
368 379
369const u8 *cfg80211_find_vendor_ie(unsigned int oui, int oui_type, 380const u8 *cfg80211_find_vendor_ie(unsigned int oui, int oui_type,
370 const u8 *ies, int len) 381 const u8 *ies, int len)
371{ 382{
372 struct ieee80211_vendor_ie *ie; 383 const u8 *ie;
373 const u8 *pos = ies, *end = ies + len; 384 u8 match[] = { oui >> 16, oui >> 8, oui, oui_type };
374 int ie_oui; 385 int match_len = (oui_type < 0) ? 3 : sizeof(match);
375 386
376 if (WARN_ON(oui_type > 0xff)) 387 if (WARN_ON(oui_type > 0xff))
377 return NULL; 388 return NULL;
378 389
379 while (pos < end) { 390 ie = cfg80211_find_ie_match(WLAN_EID_VENDOR_SPECIFIC, ies, len,
380 pos = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, pos, 391 match, match_len, 2);
381 end - pos);
382 if (!pos)
383 return NULL;
384
385 ie = (struct ieee80211_vendor_ie *)pos;
386
387 /* make sure we can access ie->len */
388 BUILD_BUG_ON(offsetof(struct ieee80211_vendor_ie, len) != 1);
389 392
390 if (ie->len < sizeof(*ie)) 393 if (ie && (ie[1] < 4))
391 goto cont; 394 return NULL;
392 395
393 ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2]; 396 return ie;
394 if (ie_oui == oui &&
395 (oui_type < 0 || ie->oui_type == oui_type))
396 return pos;
397cont:
398 pos += 2 + ie->len;
399 }
400 return NULL;
401} 397}
402EXPORT_SYMBOL(cfg80211_find_vendor_ie); 398EXPORT_SYMBOL(cfg80211_find_vendor_ie);
403 399