wlan-ap-Telecominfraproject/feeds/wifi-ax/hostapd/patches/e00-010-hidden-SSID-support-in-multiple-BSSID-IE.patch
Felix Fietkau 5b397d54ce wifi-ax: backport hostapd reload support
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2023-08-31 16:08:34 +02:00

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,
&params->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);