diff options
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r-- | net/mac80211/scan.c | 74 |
1 files changed, 53 insertions, 21 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 9270771702f..33cd1690137 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -13,6 +13,7 @@ */ #include <linux/if_arp.h> +#include <linux/etherdevice.h> #include <linux/rtnetlink.h> #include <linux/pm_qos.h> #include <net/sch_generic.h> @@ -103,16 +104,35 @@ ieee80211_bss_info_update(struct ieee80211_local *local, cbss->free_priv = ieee80211_rx_bss_free; bss = (void *)cbss->priv; + if (elems->parse_error) { + if (beacon) + bss->corrupt_data |= IEEE80211_BSS_CORRUPT_BEACON; + else + bss->corrupt_data |= IEEE80211_BSS_CORRUPT_PROBE_RESP; + } else { + if (beacon) + bss->corrupt_data &= ~IEEE80211_BSS_CORRUPT_BEACON; + else + bss->corrupt_data &= ~IEEE80211_BSS_CORRUPT_PROBE_RESP; + } + /* save the ERP value so that it is available at association time */ - if (elems->erp_info && elems->erp_info_len >= 1) { + if (elems->erp_info && elems->erp_info_len >= 1 && + (!elems->parse_error || + !(bss->valid_data & IEEE80211_BSS_VALID_ERP))) { bss->erp_value = elems->erp_info[0]; bss->has_erp_value = true; + if (!elems->parse_error) + bss->valid_data |= IEEE80211_BSS_VALID_ERP; } - if (elems->tim) { + if (elems->tim && (!elems->parse_error || + !(bss->valid_data & IEEE80211_BSS_VALID_DTIM))) { struct ieee80211_tim_ie *tim_ie = (struct ieee80211_tim_ie *)elems->tim; bss->dtim_period = tim_ie->dtim_period; + if (!elems->parse_error) + bss->valid_data |= IEEE80211_BSS_VALID_DTIM; } /* If the beacon had no TIM IE, or it was invalid, use 1 */ @@ -120,26 +140,38 @@ ieee80211_bss_info_update(struct ieee80211_local *local, bss->dtim_period = 1; /* replace old supported rates if we get new values */ - srlen = 0; - if (elems->supp_rates) { - clen = IEEE80211_MAX_SUPP_RATES; - if (clen > elems->supp_rates_len) - clen = elems->supp_rates_len; - memcpy(bss->supp_rates, elems->supp_rates, clen); - srlen += clen; - } - if (elems->ext_supp_rates) { - clen = IEEE80211_MAX_SUPP_RATES - srlen; - if (clen > elems->ext_supp_rates_len) - clen = elems->ext_supp_rates_len; - memcpy(bss->supp_rates + srlen, elems->ext_supp_rates, clen); - srlen += clen; + if (!elems->parse_error || + !(bss->valid_data & IEEE80211_BSS_VALID_RATES)) { + srlen = 0; + if (elems->supp_rates) { + clen = IEEE80211_MAX_SUPP_RATES; + if (clen > elems->supp_rates_len) + clen = elems->supp_rates_len; + memcpy(bss->supp_rates, elems->supp_rates, clen); + srlen += clen; + } + if (elems->ext_supp_rates) { + clen = IEEE80211_MAX_SUPP_RATES - srlen; + if (clen > elems->ext_supp_rates_len) + clen = elems->ext_supp_rates_len; + memcpy(bss->supp_rates + srlen, elems->ext_supp_rates, + clen); + srlen += clen; + } + if (srlen) { + bss->supp_rates_len = srlen; + if (!elems->parse_error) + bss->valid_data |= IEEE80211_BSS_VALID_RATES; + } } - if (srlen) - bss->supp_rates_len = srlen; - bss->wmm_used = elems->wmm_param || elems->wmm_info; - bss->uapsd_supported = is_uapsd_supported(elems); + if (!elems->parse_error || + !(bss->valid_data & IEEE80211_BSS_VALID_WMM)) { + bss->wmm_used = elems->wmm_param || elems->wmm_info; + bss->uapsd_supported = is_uapsd_supported(elems); + if (!elems->parse_error) + bss->valid_data |= IEEE80211_BSS_VALID_WMM; + } if (!beacon) bss->last_probe_resp = jiffies; @@ -176,7 +208,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) presp = ieee80211_is_probe_resp(fc); if (presp) { /* ignore ProbeResp to foreign address */ - if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN)) + if (compare_ether_addr(mgmt->da, sdata->vif.addr)) return RX_DROP_MONITOR; presp = true; |