summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2015-09-05 19:00:03 +0300
committerJouni Malinen <j@w1.fi>2015-09-05 19:11:02 +0300
commit0e2412d0864f0323e0d560edc024421bfae0b8bd (patch)
tree2a4395fc2acb5f7ef3656815e591b484cd8d1e4f /src
parentec4387f9c92a66e921ee8b71d10807cb36b99697 (diff)
downloadhostap-0e2412d0864f0323e0d560edc024421bfae0b8bd.tar.gz
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>
Diffstat (limited to 'src')
-rw-r--r--src/ap/ap_config.c1
-rw-r--r--src/ap/ap_config.h1
-rw-r--r--src/ap/beacon.c17
-rw-r--r--src/ap/beacon.h3
-rw-r--r--src/ap/ieee802_11.c56
-rw-r--r--src/common/ieee802_11_defs.h1
6 files changed, 72 insertions, 7 deletions
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 96f86517c..75804a069 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -567,6 +567,7 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
#endif /* CONFIG_TESTING_OPTIONS */
os_free(conf->no_probe_resp_if_seen_on);
+ os_free(conf->no_auth_if_seen_on);
os_free(conf);
}
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index d821f273b..5e83cdc3f 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -556,6 +556,7 @@ struct hostapd_bss_config {
int vendor_vht;
char *no_probe_resp_if_seen_on;
+ char *no_auth_if_seen_on;
};
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 651ee744b..85c6ef3cf 100644
--- a/src/ap/beacon.c
+++ b/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;
size_t i, j;
for (i = 0; i < interfaces->count; i++) {
+ struct hostapd_data *hapd = NULL;
+
iface = interfaces->iface[i];
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)
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;
}
diff --git a/src/ap/beacon.h b/src/ap/beacon.h
index 21df9fae8..e183cde25 100644
--- a/src/ap/beacon.h
+++ b/src/ap/beacon.h
@@ -22,5 +22,8 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
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);
+struct hostapd_data *
+sta_track_seen_on(struct hostapd_iface *iface, const u8 *addr,
+ const char *ifname);
#endif /* BEACON_H */
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 2a3041108..78355d660 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -39,6 +39,7 @@
#include "p2p_hostapd.h"
#include "ap_drv_ops.h"
#include "wnm_ap.h"
+#include "hw_features.h"
#include "ieee802_11.h"
#include "dfs.h"
@@ -977,6 +978,61 @@ static void handle_auth(struct hostapd_data *hapd,
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,
&session_timeout,
&acct_interim_interval, &vlan_id,
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 5ac69e647..44530ce3c 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -165,6 +165,7 @@
#define WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ 76
#define WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED 77
#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_QUERY_RESP_OUTSTANDING 95
#define WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL 99