Browse Source

Add option to reject authentication on 2.4 GHz from dualband STA

The new no_auth_if_seen_on=<ifname> parameter can now be used to
configure hostapd to reject authentication from a station that was seen
on another radio.

This can be used with enabled track_sta_max_num configuration on another
interface controlled by the same hostapd process to reject
authentication attempts from a station that has been detected to be
capable of operating on another band, e.g., to try to reduce likelihood
of the station selecting a 2.4 GHz BSS when the AP operates both a 2.4
GHz and 5 GHz BSS concurrently.

Note: Enabling this can cause connectivity issues and increase latency for
connecting with the AP.

Signed-off-by: Jouni Malinen <j@w1.fi>
Jouni Malinen 9 years ago
parent
commit
0e2412d086

+ 3 - 0
hostapd/config_file.c

@@ -3406,6 +3406,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 	} else if (os_strcmp(buf, "no_probe_resp_if_seen_on") == 0) {
 	} else if (os_strcmp(buf, "no_probe_resp_if_seen_on") == 0) {
 		os_free(bss->no_probe_resp_if_seen_on);
 		os_free(bss->no_probe_resp_if_seen_on);
 		bss->no_probe_resp_if_seen_on = os_strdup(pos);
 		bss->no_probe_resp_if_seen_on = os_strdup(pos);
+	} else if (os_strcmp(buf, "no_auth_if_seen_on") == 0) {
+		os_free(bss->no_auth_if_seen_on);
+		bss->no_auth_if_seen_on = os_strdup(pos);
 	} else {
 	} else {
 		wpa_printf(MSG_ERROR,
 		wpa_printf(MSG_ERROR,
 			   "Line %d: unknown configuration item '%s'",
 			   "Line %d: unknown configuration item '%s'",

+ 13 - 0
hostapd/hostapd.conf

@@ -1304,6 +1304,19 @@ own_ip_addr=127.0.0.1
 # discovering the AP.
 # discovering the AP.
 #no_probe_resp_if_seen_on=wlan1
 #no_probe_resp_if_seen_on=wlan1
 
 
+# Reject authentication from a station that was seen on another radio.
+# Default: Disabled
+#
+# This can be used with enabled track_sta_max_num configuration on another
+# interface controlled by the same hostapd process to reject authentication
+# attempts from a station that has been detected to be capable of operating on
+# another band, e.g., to try to reduce likelihood of the station selecting a
+# 2.4 GHz BSS when the AP operates both a 2.4 GHz and 5 GHz BSS concurrently.
+#
+# Note: Enabling this can cause connectivity issues and increase latency for
+# connecting with the AP.
+#no_auth_if_seen_on=wlan1
+
 ##### Wi-Fi Protected Setup (WPS) #############################################
 ##### Wi-Fi Protected Setup (WPS) #############################################
 
 
 # WPS state
 # WPS state

+ 1 - 0
src/ap/ap_config.c

@@ -567,6 +567,7 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
 #endif /* CONFIG_TESTING_OPTIONS */
 #endif /* CONFIG_TESTING_OPTIONS */
 
 
 	os_free(conf->no_probe_resp_if_seen_on);
 	os_free(conf->no_probe_resp_if_seen_on);
+	os_free(conf->no_auth_if_seen_on);
 
 
 	os_free(conf);
 	os_free(conf);
 }
 }

+ 1 - 0
src/ap/ap_config.h

@@ -556,6 +556,7 @@ struct hostapd_bss_config {
 	int vendor_vht;
 	int vendor_vht;
 
 
 	char *no_probe_resp_if_seen_on;
 	char *no_probe_resp_if_seen_on;
+	char *no_auth_if_seen_on;
 };
 };
 
 
 
 

+ 10 - 7
src/ap/beacon.c

@@ -622,26 +622,29 @@ static void sta_track_add(struct hostapd_iface *iface, const u8 *addr)
 }
 }
 
 
 
 
-static int sta_track_seen_on(struct hostapd_iface *iface, const u8 *addr,
-			     const char *ifname)
+struct hostapd_data *
+sta_track_seen_on(struct hostapd_iface *iface, const u8 *addr,
+		  const char *ifname)
 {
 {
 	struct hapd_interfaces *interfaces = iface->interfaces;
 	struct hapd_interfaces *interfaces = iface->interfaces;
 	size_t i, j;
 	size_t i, j;
 
 
 	for (i = 0; i < interfaces->count; i++) {
 	for (i = 0; i < interfaces->count; i++) {
+		struct hostapd_data *hapd = NULL;
+
 		iface = interfaces->iface[i];
 		iface = interfaces->iface[i];
 		for (j = 0; j < iface->num_bss; j++) {
 		for (j = 0; j < iface->num_bss; j++) {
-			struct hostapd_data *hapd = iface->bss[j];
-
+			hapd = iface->bss[j];
 			if (os_strcmp(ifname, hapd->conf->iface) == 0)
 			if (os_strcmp(ifname, hapd->conf->iface) == 0)
 				break;
 				break;
+			hapd = NULL;
 		}
 		}
 
 
-		if (j < iface->num_bss && sta_track_get(iface, addr))
-			return 1;
+		if (hapd && sta_track_get(iface, addr))
+			return hapd;
 	}
 	}
 
 
-	return 0;
+	return NULL;
 }
 }
 
 
 
 

+ 3 - 0
src/ap/beacon.h

@@ -22,5 +22,8 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 			       struct wpa_driver_ap_params *params);
 			       struct wpa_driver_ap_params *params);
 void ieee802_11_free_ap_params(struct wpa_driver_ap_params *params);
 void ieee802_11_free_ap_params(struct wpa_driver_ap_params *params);
 void sta_track_expire(struct hostapd_iface *iface, int force);
 void sta_track_expire(struct hostapd_iface *iface, int force);
+struct hostapd_data *
+sta_track_seen_on(struct hostapd_iface *iface, const u8 *addr,
+		  const char *ifname);
 
 
 #endif /* BEACON_H */
 #endif /* BEACON_H */

+ 56 - 0
src/ap/ieee802_11.c

@@ -39,6 +39,7 @@
 #include "p2p_hostapd.h"
 #include "p2p_hostapd.h"
 #include "ap_drv_ops.h"
 #include "ap_drv_ops.h"
 #include "wnm_ap.h"
 #include "wnm_ap.h"
+#include "hw_features.h"
 #include "ieee802_11.h"
 #include "ieee802_11.h"
 #include "dfs.h"
 #include "dfs.h"
 
 
@@ -977,6 +978,61 @@ static void handle_auth(struct hostapd_data *hapd,
 		goto fail;
 		goto fail;
 	}
 	}
 
 
+	if (hapd->conf->no_auth_if_seen_on) {
+		struct hostapd_data *other;
+
+		other = sta_track_seen_on(hapd->iface, mgmt->sa,
+					  hapd->conf->no_auth_if_seen_on);
+		if (other) {
+			u8 *pos;
+			u32 info;
+			u8 op_class, channel, phytype;
+
+			wpa_printf(MSG_DEBUG, "%s: Reject authentication from "
+				   MACSTR " since STA has been seen on %s",
+				   hapd->conf->iface, MAC2STR(mgmt->sa),
+				   hapd->conf->no_auth_if_seen_on);
+
+			resp = WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION;
+			pos = &resp_ies[0];
+			*pos++ = WLAN_EID_NEIGHBOR_REPORT;
+			*pos++ = 13;
+			os_memcpy(pos, other->own_addr, ETH_ALEN);
+			pos += ETH_ALEN;
+			info = 0; /* TODO: BSSID Information */
+			WPA_PUT_LE32(pos, info);
+			pos += 4;
+			if (other->iconf->hw_mode == HOSTAPD_MODE_IEEE80211AD)
+				phytype = 8; /* dmg */
+			else if (other->iconf->ieee80211ac)
+				phytype = 9; /* vht */
+			else if (other->iconf->ieee80211n)
+				phytype = 7; /* ht */
+			else if (other->iconf->hw_mode ==
+				 HOSTAPD_MODE_IEEE80211A)
+				phytype = 4; /* ofdm */
+			else if (other->iconf->hw_mode ==
+				 HOSTAPD_MODE_IEEE80211G)
+				phytype = 6; /* erp */
+			else
+				phytype = 5; /* hrdsss */
+			if (ieee80211_freq_to_channel_ext(
+				    hostapd_hw_get_freq(other,
+							other->iconf->channel),
+				    other->iconf->secondary_channel,
+				    other->iconf->ieee80211ac,
+				    &op_class, &channel) == NUM_HOSTAPD_MODES) {
+				op_class = 0;
+				channel = other->iconf->channel;
+			}
+			*pos++ = op_class;
+			*pos++ = channel;
+			*pos++ = phytype;
+			resp_ies_len = pos - &resp_ies[0];
+			goto fail;
+		}
+	}
+
 	res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len,
 	res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len,
 				      &session_timeout,
 				      &session_timeout,
 				      &acct_interim_interval, &vlan_id,
 				      &acct_interim_interval, &vlan_id,

+ 1 - 0
src/common/ieee802_11_defs.h

@@ -165,6 +165,7 @@
 #define WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ 76
 #define WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ 76
 #define WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED 77
 #define WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED 77
 #define WLAN_STATUS_TRANSMISSION_FAILURE 79
 #define WLAN_STATUS_TRANSMISSION_FAILURE 79
+#define WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION 82
 #define WLAN_STATUS_PENDING_ADMITTING_FST_SESSION 86
 #define WLAN_STATUS_PENDING_ADMITTING_FST_SESSION 86
 #define WLAN_STATUS_QUERY_RESP_OUTSTANDING 95
 #define WLAN_STATUS_QUERY_RESP_OUTSTANDING 95
 #define WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL 99
 #define WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL 99