diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 03382d470..f4cd26308 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -1896,6 +1896,8 @@ struct hostapd_config * hostapd_config_read(const char *fname) "ht_capab", line); errors++; } + } else if (os_strcmp(buf, "require_ht") == 0) { + conf->require_ht = atoi(pos); #endif /* CONFIG_IEEE80211N */ } else if (os_strcmp(buf, "max_listen_interval") == 0) { bss->max_listen_interval = atoi(pos); diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 2def33560..6d7263afd 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -408,6 +408,9 @@ wmm_ac_vo_acm=0 # L-SIG TXOP protection support: [LSIG-TXOP-PROT] (disabled if not set) #ht_capab=[HT40-][SHORT-GI-20][SHORT-GI-40] +# Require stations to support HT PHY (reject association if they do not) +#require_ht=1 + ##### IEEE 802.1X-2004 related configuration ################################## # Require IEEE 802.1X authorization diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index ff7e8cf22..8761ad25b 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -387,6 +387,7 @@ struct hostapd_config { u16 ht_capab; int ieee80211n; int secondary_channel; + int require_ht; }; diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c index 9b4c2a9e6..9b0265fd3 100644 --- a/src/ap/hw_features.c +++ b/src/ap/hw_features.c @@ -162,7 +162,8 @@ int hostapd_prepare_rates(struct hostapd_data *hapd, hapd->iface->num_rates++; } - if (hapd->iface->num_rates == 0 || num_basic_rates == 0) { + if ((hapd->iface->num_rates == 0 || num_basic_rates == 0) && + (!hapd->iconf->ieee80211n || !hapd->iconf->require_ht)) { wpa_printf(MSG_ERROR, "No rates remaining in supported/basic " "rate sets (%d,%d).", hapd->iface->num_rates, num_basic_rates); diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index f19c8171e..06fc701eb 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -53,6 +53,8 @@ u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid) *pos++ = WLAN_EID_SUPP_RATES; num = hapd->iface->num_rates; + if (hapd->iconf->ieee80211n && hapd->iconf->require_ht) + num++; if (num > 8) { /* rest of the rates are encoded in Extended supported * rates element */ @@ -70,6 +72,10 @@ u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid) pos++; } + if (hapd->iconf->ieee80211n && hapd->iconf->require_ht && + hapd->iface->num_rates < 8) + *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY; + return pos; } @@ -83,6 +89,8 @@ u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid) return eid; num = hapd->iface->num_rates; + if (hapd->iconf->ieee80211n && hapd->iconf->require_ht) + num++; if (num <= 8) return eid; num -= 8; @@ -101,6 +109,10 @@ u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid) pos++; } + if (hapd->iconf->ieee80211n && hapd->iconf->require_ht && + hapd->iface->num_rates >= 8) + *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY; + return pos; } @@ -667,6 +679,13 @@ static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, elems.ht_capabilities_len); if (resp != WLAN_STATUS_SUCCESS) return resp; + if (hapd->iconf->ieee80211n && hapd->iconf->require_ht && + !(sta->flags & WLAN_STA_HT)) { + hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, + HOSTAPD_LEVEL_INFO, "Station does not support " + "mandatory HT PHY - reject association"); + return WLAN_STATUS_ASSOC_DENIED_NO_HT; + } #endif /* CONFIG_IEEE80211N */ if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems.rsn_ie) { diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 75268947d..a143e4028 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -120,9 +120,10 @@ #define WLAN_STATUS_SUPPORTED_CHANNEL_NOT_VALID 24 /* IEEE 802.11g */ #define WLAN_STATUS_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25 -#define WLAN_STATUS_ASSOC_DENIED_NO_ER_PBCC 26 -#define WLAN_STATUS_ASSOC_DENIED_NO_DSSS_OFDM 27 +#define WLAN_STATUS_ASSOC_DENIED_NO_DSSS_OFDM 26 +#define WLAN_STATUS_ASSOC_DENIED_NO_HT 27 #define WLAN_STATUS_R0KH_UNREACHABLE 28 +#define WLAN_STATUS_ASSOC_DENIED_NO_PCO 29 /* IEEE 802.11w */ #define WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY 30 #define WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31 @@ -545,6 +546,7 @@ struct ieee80211_ht_operation { #define HT_INFO_STBC_PARAM_PCO_ACTIVE ((u16) BIT(10)) #define HT_INFO_STBC_PARAM_PCO_PHASE ((u16) BIT(11)) +#define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127 #define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs) * 00:50:F2 */