diff --git a/hostapd/config.c b/hostapd/config.c index 428045350..57fbb750f 100644 --- a/hostapd/config.c +++ b/hostapd/config.c @@ -178,6 +178,8 @@ static void hostapd_config_defaults_bss(struct hostapd_bss_config *bss) bss->radius_server_auth_port = 1812; bss->ap_max_inactivity = AP_MAX_INACTIVITY; bss->eapol_version = EAPOL_VERSION; + + bss->max_listen_interval = 65535; } @@ -1927,6 +1929,8 @@ struct hostapd_config * hostapd_config_read(const char *fname) } else if (os_strcmp(buf, "ieee80211w") == 0) { bss->ieee80211w = atoi(pos); #endif /* CONFIG_IEEE80211W */ + } else if (os_strcmp(buf, "max_listen_interval") == 0) { + bss->max_listen_interval = atoi(pos); } else { printf("Line %d: unknown configuration item '%s'\n", line, buf); diff --git a/hostapd/config.h b/hostapd/config.h index 8f7777e28..4a7b24b3a 100644 --- a/hostapd/config.h +++ b/hostapd/config.h @@ -262,6 +262,13 @@ struct hostapd_bss_config { struct hostapd_vlan *vlan, *vlan_tail; macaddr bssid; + + /* + * Maximum listen interval that STAs can use when associating with this + * BSS. If a STA tries to use larger value, the association will be + * denied with status code 51. + */ + u16 max_listen_interval; }; diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 539da4524..3c9fc6557 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -371,6 +371,9 @@ wme_ac_vo_acm=0 # default: do not control from hostapd (80211.o defaults to 1=enabled) #bridge_packets=1 +# Maximum allowed Listen Interval (how many Beacon periods STAs are allowed to +# remain asleep). Default: 65535 (no limit apart from field size) +#max_listen_interval=100 ##### IEEE 802.1X-2004 related configuration ################################## diff --git a/hostapd/ieee802_11.c b/hostapd/ieee802_11.c index e9a674f09..388b19d03 100644 --- a/hostapd/ieee802_11.c +++ b/hostapd/ieee802_11.c @@ -855,6 +855,15 @@ static void handle_assoc(struct hostapd_data *hapd, goto fail; } + if (listen_interval > hapd->conf->max_listen_interval) { + hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, + HOSTAPD_LEVEL_DEBUG, + "Too large Listen Interval (%d)", + listen_interval); + resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE; + goto fail; + } + if (reassoc) { os_memcpy(sta->previous_ap, mgmt->u.reassoc_req.current_ap, ETH_ALEN); diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 82902174e..f7c47d982 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -112,9 +112,9 @@ #define WLAN_STATUS_PWR_CAPABILITY_NOT_VALID 23 #define WLAN_STATUS_SUPPORTED_CHANNEL_NOT_VALID 24 /* 802.11g */ -#define WLAN_STATUS_ASSOC_DENOED_NO_SHORT_SLOT_TIME 25 -#define WLAN_STATUS_ASSOC_DENOED_NO_ER_PBCC 26 -#define WLAN_STATUS_ASSOC_DENOED_NO_DSSS_OFDM 27 +#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 /* IEEE 802.11i */ #define WLAN_STATUS_INVALID_IE 40 #define WLAN_STATUS_GROUP_CIPHER_NOT_VALID 41 @@ -123,6 +123,11 @@ #define WLAN_STATUS_UNSUPPORTED_RSN_IE_VERSION 44 #define WLAN_STATUS_INVALID_RSN_IE_CAPAB 45 #define WLAN_STATUS_CIPHER_REJECTED_PER_POLICY 46 +#define WLAN_STATUS_TS_NOT_CREATED 47 +#define WLAN_STATUS_DIRECT_LINK_NOT_ALLOWED 48 +#define WLAN_STATUS_DEST_STA_NOT_PRESENT 49 +#define WLAN_STATUS_DEST_STA_NOT_QOS_STA 50 +#define WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE 51 /* IEEE 802.11r */ #define WLAN_STATUS_INVALID_FT_ACTION_FRAME_COUNT 52 #define WLAN_STATUS_EXPECTED_RESOURCE_REQ_FT 53