struct ieee80211_2040_intol_chan_report *ic_report;
int is_ht_allowed = 1;
int i;
- const u8 *data = ((const u8 *) mgmt) + IEEE80211_HDRLEN + 1;
+ const u8 *start = (const u8 *) mgmt;
+ const u8 *data = start + IEEE80211_HDRLEN + 2;
hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG, "hostapd_public_action - action=%d",
if (!(iface->conf->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
return;
- if (len < IEEE80211_HDRLEN + 1)
+ if (len < IEEE80211_HDRLEN + 2 + sizeof(*bc_ie))
return;
- data++;
- bc_ie = (struct ieee80211_2040_bss_coex_ie *) &data[0];
- ic_report = (struct ieee80211_2040_intol_chan_report *)
- (&data[0] + sizeof(*bc_ie));
+ bc_ie = (struct ieee80211_2040_bss_coex_ie *) data;
+ if (bc_ie->element_id != WLAN_EID_20_40_BSS_COEXISTENCE ||
+ bc_ie->length < 1) {
+ wpa_printf(MSG_DEBUG, "Unexpected IE (%u,%u) in coex report",
+ bc_ie->element_id, bc_ie->length);
+ return;
+ }
+ if (len < IEEE80211_HDRLEN + 2 + 2 + bc_ie->length)
+ return;
+ data += 2 + bc_ie->length;
+ wpa_printf(MSG_DEBUG, "20/40 BSS Coexistence Information field: 0x%x",
+ bc_ie->coex_param);
if (bc_ie->coex_param & WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ) {
hostapd_logger(hapd, mgmt->sa,
HOSTAPD_MODULE_IEEE80211,
is_ht_allowed = 0;
}
- if (ic_report &&
- (ic_report->element_id == WLAN_EID_20_40_BSS_INTOLERANT)) {
+ if (start + len - data >= 3 &&
+ data[0] == WLAN_EID_20_40_BSS_INTOLERANT && data[1] >= 1) {
+ u8 ielen = data[1];
+
+ if (ielen > start + len - data - 2)
+ return;
+ ic_report = (struct ieee80211_2040_intol_chan_report *) data;
+ wpa_printf(MSG_DEBUG,
+ "20/40 BSS Intolerant Channel Report: Operating Class %u",
+ ic_report->op_class);
+
/* Go through the channel report to find any BSS there in the
* affected channel range */
- for (i = 0; i < ic_report->length - 1; i++) {
- if (is_40_allowed(iface, ic_report->variable[i]))
+ for (i = 0; i < ielen - 1; i++) {
+ u8 chan = ic_report->variable[i];
+
+ if (is_40_allowed(iface, chan))
continue;
hostapd_logger(hapd, mgmt->sa,
HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG,
"20_40_INTOLERANT channel %d reported",
- ic_report->variable[i]);
+ chan);
is_ht_allowed = 0;
- break;
}
}
+ wpa_printf(MSG_DEBUG, "is_ht_allowed=%d num_sta_ht40_intolerant=%d",
+ is_ht_allowed, iface->num_sta_ht40_intolerant);
if (!is_ht_allowed &&
(iface->drv_flags & WPA_DRIVER_FLAGS_HT_2040_COEX)) {
NULL);
eloop_register_timeout(delay_time, 0, ap_ht2040_timeout,
hapd->iface, NULL);
+ wpa_printf(MSG_DEBUG,
+ "Reschedule HT 20/40 timeout to occur in %u seconds",
+ delay_time);
}
}
}