mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-17 17:31:27 +00:00
279 lines
9.5 KiB
Diff
279 lines
9.5 KiB
Diff
From 427d9ffc462dd1e76d03334d477864b7a33afc05 Mon Sep 17 00:00:00 2001
|
|
From: Aloka Dixit <alokad@codeaurora.org>
|
|
Date: Sat, 3 Oct 2020 15:41:11 -0700
|
|
Subject: [PATCH] hostapd: Hidden SSID support in multiple BSSID IE
|
|
|
|
Hidden nontransmitted BSSID profiles will be included in the beacons and
|
|
probe responses but SSID value will be removed or set to all zeros
|
|
depending on the configured value of 'ignore_broadcast_ssid'.
|
|
If complete profiles are omited, clients cannot stay connected to the AP.
|
|
|
|
For unicast probe requests with SSID set to a hidden nontransmitted BSSID
|
|
profile, complete SSID is included in the probe response.
|
|
This patch adds a new input parameter in related functions, pointer to
|
|
hostapd_data for nontransmitted profiles, to differentiate this case.
|
|
|
|
Signed-off-by: Aloka Dixit <alokad@codeaurora.org>
|
|
---
|
|
src/ap/beacon.c | 24 +++++++++++--------
|
|
src/ap/ieee802_11.c | 56 +++++++++++++++++++++++++++++++++------------
|
|
src/ap/ieee802_11.h | 7 ++++--
|
|
3 files changed, 62 insertions(+), 25 deletions(-)
|
|
|
|
--- a/src/ap/beacon.c
|
|
+++ b/src/ap/beacon.c
|
|
@@ -432,12 +432,16 @@ static u8 * hostapd_gen_probe_resp(struc
|
|
const struct ieee80211_mgmt *req,
|
|
int is_p2p, size_t *resp_len)
|
|
{
|
|
+ struct hostapd_data *hidden = NULL;
|
|
struct ieee80211_mgmt *resp;
|
|
u8 *pos, *epos, *csa_pos, *ext_cap_pos;
|
|
size_t buflen;
|
|
|
|
- if (hapd->iconf->multiple_bssid)
|
|
+ if (hapd->iconf->multiple_bssid &&
|
|
+ hapd != hostapd_get_primary_bss(hapd)) {
|
|
+ hidden = hapd;
|
|
hapd = hostapd_get_primary_bss(hapd);
|
|
+ }
|
|
|
|
#define MAX_PROBERESP_LEN 768
|
|
buflen = MAX_PROBERESP_LEN;
|
|
@@ -476,7 +480,7 @@ static u8 * hostapd_gen_probe_resp(struc
|
|
buflen += hostapd_eid_owe_trans_len(hapd);
|
|
buflen += hostapd_eid_dpp_cc_len(hapd);
|
|
if (hapd->iconf->multiple_bssid)
|
|
- buflen += hostapd_eid_multiple_bssid_len(hapd);
|
|
+ buflen += hostapd_eid_multiple_bssid_len(hapd, hidden, 0);
|
|
|
|
resp = os_zalloc(buflen);
|
|
if (resp == NULL)
|
|
@@ -502,9 +506,21 @@ static u8 * hostapd_gen_probe_resp(struc
|
|
|
|
pos = resp->u.probe_resp.variable;
|
|
*pos++ = WLAN_EID_SSID;
|
|
- *pos++ = hapd->conf->ssid.ssid_len;
|
|
- os_memcpy(pos, hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len);
|
|
- pos += hapd->conf->ssid.ssid_len;
|
|
+ if (hapd->iconf->multiple_bssid && hidden &&
|
|
+ hapd->conf->ignore_broadcast_ssid == 2) {
|
|
+ /* clear the data, but keep the correct length of the SSID */
|
|
+ *pos++ = hapd->conf->ssid.ssid_len;
|
|
+ os_memset(pos, 0, hapd->conf->ssid.ssid_len);
|
|
+ pos += hapd->conf->ssid.ssid_len;
|
|
+ } else if (hapd->iconf->multiple_bssid && hidden &&
|
|
+ hapd->conf->ignore_broadcast_ssid) {
|
|
+ *pos++ = 0; /* empty SSID */
|
|
+ } else {
|
|
+ *pos++ = hapd->conf->ssid.ssid_len;
|
|
+ os_memcpy(pos, hapd->conf->ssid.ssid,
|
|
+ hapd->conf->ssid.ssid_len);
|
|
+ pos += hapd->conf->ssid.ssid_len;
|
|
+ }
|
|
|
|
/* Supported rates */
|
|
pos = hostapd_eid_supp_rates(hapd, pos);
|
|
@@ -535,7 +551,8 @@ static u8 * hostapd_gen_probe_resp(struc
|
|
pos = hostapd_get_mde(hapd, pos, epos - pos);
|
|
|
|
if (hapd->iconf->multiple_bssid)
|
|
- pos = hostapd_eid_multiple_bssid(hapd, pos, epos, 0, NULL, 0, 0, 0);
|
|
+ pos = hostapd_eid_multiple_bssid(hapd, hidden, pos, epos, 0,
|
|
+ NULL, 0, 0, 0);
|
|
|
|
/* eCSA IE */
|
|
csa_pos = hostapd_eid_ecsa(hapd, pos);
|
|
@@ -847,10 +864,6 @@ void handle_probe_req(struct hostapd_dat
|
|
ssi_signal < hapd->iconf->rssi_ignore_probe_request)
|
|
return;
|
|
|
|
- if (hapd->iconf->multiple_bssid &&
|
|
- hapd != hostapd_get_primary_bss(hapd))
|
|
- return;
|
|
-
|
|
if (len < IEEE80211_HDRLEN)
|
|
return;
|
|
ie = ((const u8 *) mgmt) + IEEE80211_HDRLEN;
|
|
@@ -1079,6 +1092,10 @@ void handle_probe_req(struct hostapd_dat
|
|
wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO, RX_PROBE_REQUEST "sa=" MACSTR
|
|
" signal=%d", MAC2STR(mgmt->sa), ssi_signal);
|
|
|
|
+ if (hapd->iconf->multiple_bssid &&
|
|
+ hapd != hostapd_get_primary_bss(hapd) && res != EXACT_SSID_MATCH)
|
|
+ return;
|
|
+
|
|
resp = hostapd_gen_probe_resp(hapd, mgmt, elems.p2p != NULL,
|
|
&resp_len);
|
|
if (resp == NULL)
|
|
@@ -1756,7 +1773,7 @@ int ieee802_11_build_ap_params(struct ho
|
|
}
|
|
|
|
if (hapd->iconf->multiple_bssid) {
|
|
- int len = hostapd_eid_multiple_bssid_len(hapd);
|
|
+ int len = hostapd_eid_multiple_bssid_len(hapd, NULL, 1);
|
|
u8 *end;
|
|
|
|
params->multiple_bssid_index = hostapd_get_bss_index(hapd);
|
|
@@ -1764,7 +1781,8 @@ int ieee802_11_build_ap_params(struct ho
|
|
params->multiple_bssid_ies = os_zalloc(len);
|
|
if (params->multiple_bssid_ies == NULL)
|
|
return -1;
|
|
- end = hostapd_eid_multiple_bssid(hapd, params->multiple_bssid_ies,
|
|
+ end = hostapd_eid_multiple_bssid(hapd, NULL,
|
|
+ params->multiple_bssid_ies,
|
|
params->multiple_bssid_ies + len,
|
|
1, params->multiple_bssid_ie_offsets,
|
|
¶ms->multiple_bssid_ie_count,
|
|
--- a/src/ap/ieee802_11.c
|
|
+++ b/src/ap/ieee802_11.c
|
|
@@ -6988,24 +6988,35 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct
|
|
|
|
|
|
static int hostapd_eid_multiple_bssid_chunk_len(struct hostapd_data *hapd,
|
|
- int *count)
|
|
+ struct hostapd_data *hidden,
|
|
+ int *count,
|
|
+ u8 is_beacon)
|
|
{
|
|
/* ID + size + count */
|
|
int i, len = 3, nontx_profile_len;
|
|
size_t ies_len = 0;
|
|
struct hostapd_data *bss;
|
|
+ struct hostapd_bss_config *conf;
|
|
|
|
for (i = *count; i < hapd->iface->num_bss; i++) {
|
|
bss = hapd->iface->bss[i];
|
|
+ conf = bss->conf;
|
|
|
|
/*
|
|
* Sublement ID: 1 byte
|
|
* Length: 1 byte
|
|
* Nontransmitted capabilities: 4 bytes
|
|
- * Multiple BSSID Index Element: 5 bytes
|
|
- * SSID element: 2 + variable
|
|
+ * SSID element: 2 bytes
|
|
+ * Multiple BSSID Index Element: 3 bytes (+2 bytes in beacons)
|
|
*/
|
|
- nontx_profile_len = 13 + bss->conf->ssid.ssid_len;
|
|
+ nontx_profile_len = 11;
|
|
+
|
|
+ if (!conf->ignore_broadcast_ssid ||
|
|
+ conf->ignore_broadcast_ssid == 2 || bss == hidden)
|
|
+ nontx_profile_len += conf->ssid.ssid_len;
|
|
+
|
|
+ if (is_beacon)
|
|
+ nontx_profile_len += 2;
|
|
|
|
if (wpa_auth_get_wpa_ie(bss->wpa_auth, &ies_len))
|
|
nontx_profile_len += ies_len;
|
|
@@ -7023,21 +7034,27 @@ multiple_bssid_too_big:
|
|
}
|
|
|
|
|
|
-int hostapd_eid_multiple_bssid_len(struct hostapd_data *hapd)
|
|
+int hostapd_eid_multiple_bssid_len(struct hostapd_data *hapd,
|
|
+ struct hostapd_data *hidden,
|
|
+ u8 is_beacon)
|
|
{
|
|
int count = 1, len = 0;
|
|
|
|
while (count < hapd->iface->num_bss)
|
|
- len += hostapd_eid_multiple_bssid_chunk_len(hapd, &count);
|
|
+ len += hostapd_eid_multiple_bssid_chunk_len(hapd, hidden,
|
|
+ &count, is_beacon);
|
|
|
|
return len;
|
|
}
|
|
|
|
|
|
static u8 * hostapd_eid_multiple_bssid_chunk(struct hostapd_data *hapd,
|
|
+ struct hostapd_data *hidden,
|
|
u8 *eid, u8 *end, int *count,
|
|
u8 is_beacon, u8 *dtim_offset[])
|
|
{
|
|
+ struct hostapd_data *bss;
|
|
+ struct hostapd_bss_config *conf;
|
|
u8 *size_offset, *num_offset;
|
|
int i;
|
|
|
|
@@ -7046,7 +7063,8 @@ static u8 * hostapd_eid_multiple_bssid_c
|
|
num_offset = eid++;
|
|
|
|
for (i = *count; i < hapd->iface->num_bss; i++) {
|
|
- struct hostapd_data *bss = hapd->iface->bss[i];
|
|
+ bss = hapd->iface->bss[i];
|
|
+ conf = bss->conf;
|
|
u8 *bss_size_offset, *index_size_offset, *pos = eid;
|
|
u16 capab_info;
|
|
|
|
@@ -7060,16 +7078,24 @@ static u8 * hostapd_eid_multiple_bssid_c
|
|
eid += sizeof(capab_info);
|
|
|
|
*eid++ = WLAN_EID_SSID;
|
|
- *eid++ = bss->conf->ssid.ssid_len;
|
|
- os_memcpy(eid, bss->conf->ssid.ssid, bss->conf->ssid.ssid_len);
|
|
- eid += bss->conf->ssid.ssid_len;
|
|
+ if (!conf->ignore_broadcast_ssid || bss == hidden) {
|
|
+ *eid++ = conf->ssid.ssid_len;
|
|
+ os_memcpy(eid, conf->ssid.ssid, conf->ssid.ssid_len);
|
|
+ eid += conf->ssid.ssid_len;
|
|
+ } else if (conf->ignore_broadcast_ssid == 2) {
|
|
+ *eid++ = conf->ssid.ssid_len;
|
|
+ os_memset(eid, 0, conf->ssid.ssid_len);
|
|
+ eid += conf->ssid.ssid_len;
|
|
+ } else {
|
|
+ *eid++ = 0;
|
|
+ }
|
|
|
|
*eid++ = WLAN_EID_MULTIPLE_BSSID_INDEX;
|
|
index_size_offset = eid++;
|
|
*eid++ = i;
|
|
if (is_beacon) {
|
|
dtim_offset[i] = eid;
|
|
- *eid++ = bss->conf->dtim_period;
|
|
+ *eid++ = conf->dtim_period;
|
|
*eid++ = 0xFF;
|
|
}
|
|
*index_size_offset = (eid - index_size_offset) - 1;
|
|
@@ -7095,7 +7121,8 @@ multiple_bssid_too_big:
|
|
}
|
|
|
|
|
|
-u8 * hostapd_eid_multiple_bssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
|
|
+u8 * hostapd_eid_multiple_bssid(struct hostapd_data *hapd,
|
|
+ struct hostapd_data *hidden, u8 *eid, u8 *end,
|
|
u8 is_beacon, u8 **eid_offsets, int *eid_count,
|
|
int eid_max, u8 ema_beacon)
|
|
{
|
|
@@ -7114,8 +7141,9 @@ u8 * hostapd_eid_multiple_bssid(struct h
|
|
eid_offsets[*eid_count] = eid;
|
|
*eid_count = *eid_count + 1;
|
|
}
|
|
- eid = hostapd_eid_multiple_bssid_chunk(hapd, eid, end, &count,
|
|
- is_beacon, dtim_offset);
|
|
+ eid = hostapd_eid_multiple_bssid_chunk(hapd, hidden, eid, end,
|
|
+ &count, is_beacon,
|
|
+ dtim_offset);
|
|
}
|
|
|
|
if (!eid_count || !(*eid_count)) {
|
|
--- a/src/ap/ieee802_11.h
|
|
+++ b/src/ap/ieee802_11.h
|
|
@@ -119,10 +119,13 @@ u8 * hostapd_eid_time_zone(struct hostap
|
|
int hostapd_update_time_adv(struct hostapd_data *hapd);
|
|
void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr);
|
|
u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid);
|
|
-u8 * hostapd_eid_multiple_bssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
|
|
+u8 * hostapd_eid_multiple_bssid(struct hostapd_data *hapd,
|
|
+ struct hostapd_data *hidden, u8 *eid, u8 *end,
|
|
u8 is_beacon, u8 **eid_offsets, int *eid_count,
|
|
int eid_max, u8 ema_beacon);
|
|
-int hostapd_eid_multiple_bssid_len(struct hostapd_data *hapd);
|
|
+int hostapd_eid_multiple_bssid_len(struct hostapd_data *hapd,
|
|
+ struct hostapd_data *hidden,
|
|
+ u8 is_beacon);
|
|
u8 * hostapd_eid_reduced_neighbor_report(struct hostapd_data *hapd, u8 *eid);
|
|
size_t hostapd_eid_reduced_neighbor_report_len(struct hostapd_data *hapd);
|
|
int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta);
|