mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-19 02:11:28 +00:00
186 lines
5.3 KiB
Diff
186 lines
5.3 KiB
Diff
From 150f656623fa2d2ea09072b11fcd9bc3d5100fbf Mon Sep 17 00:00:00 2001
|
|
From: John Crispin <john@phrozen.org>
|
|
Date: Wed, 3 Jun 2020 17:04:01 +0200
|
|
Subject: [PATCH 804/820] multiple_bssid: add the new IE
|
|
|
|
For multiple bssid to work we need to add a new IE to the beacon and probe
|
|
responses that includes the information on the non-transmitting BSSs. If
|
|
all the information does not fit into the 255 bytes, we need to split it
|
|
up over multiple IEs of the same type.
|
|
|
|
Signed-off-by: John Crispin <john@phrozen.org>
|
|
---
|
|
src/ap/ieee802_11.c | 114 +++++++++++++++++++++++++++++++++++
|
|
src/ap/ieee802_11.h | 5 ++
|
|
src/common/ieee802_11_defs.h | 2 +
|
|
3 files changed, 121 insertions(+)
|
|
|
|
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
|
|
index b91640070..06286378f 100644
|
|
--- a/src/ap/ieee802_11.c
|
|
+++ b/src/ap/ieee802_11.c
|
|
@@ -6,6 +6,7 @@
|
|
* See README for more details.
|
|
*/
|
|
|
|
+#include <math.h>
|
|
#include "utils/includes.h"
|
|
|
|
#ifndef CONFIG_NATIVE_WINDOWS
|
|
@@ -5617,4 +5618,117 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
|
|
return eid;
|
|
}
|
|
|
|
+
|
|
+static int hostapd_eid_multiple_bssid_chunk_len(struct hostapd_data *hapd,
|
|
+ int *count)
|
|
+{
|
|
+ /* ID + size + count */
|
|
+ int i, len = 3;
|
|
+
|
|
+ for (i = *count; i < hapd->iface->num_bss; i++) {
|
|
+ struct hostapd_data *bss = hapd->iface->bss[i];
|
|
+ /* 11 mbssid + ssid len + 32 RSN */
|
|
+ int ssid_len = 11 + bss->conf->ssid.ssid_len + 32;
|
|
+
|
|
+ if (len + ssid_len > 255) {
|
|
+ goto multiple_bssid_too_big;
|
|
+ }
|
|
+ len += ssid_len;
|
|
+ }
|
|
+
|
|
+multiple_bssid_too_big:
|
|
+ *count = i;
|
|
+
|
|
+ return len;
|
|
+}
|
|
+
|
|
+
|
|
+int hostapd_eid_multiple_bssid_len(struct hostapd_data *hapd)
|
|
+{
|
|
+ int count = 1, len = 0;
|
|
+
|
|
+ while (count < hapd->iface->num_bss)
|
|
+ len += hostapd_eid_multiple_bssid_chunk_len(hapd, &count);
|
|
+
|
|
+ return len;
|
|
+}
|
|
+
|
|
+
|
|
+static u8 * hostapd_eid_multiple_bssid_chunk(struct hostapd_data *hapd,
|
|
+ u8 *eid, u8 *end, int *count,
|
|
+ u8 is_beacon)
|
|
+{
|
|
+ u8 *size_offset, *num_offset, num = 0;
|
|
+ int i;
|
|
+
|
|
+ *eid++ = WLAN_EID_MULTIPLE_BSSID;
|
|
+ size_offset = eid++;
|
|
+ num_offset = eid++;
|
|
+
|
|
+ for (i = *count; i < hapd->iface->num_bss; i++) {
|
|
+ struct hostapd_data *bss = hapd->iface->bss[i];
|
|
+ u8 *bss_size_offset, *index_size_offset, *pos = eid;
|
|
+ u16 capab_info;
|
|
+
|
|
+ *eid++ = WLAN_EID_SUBELEMENT_NONTRANSMITTED_BSSID_PROFILE;
|
|
+ bss_size_offset = eid++;
|
|
+
|
|
+ *eid++ = WLAN_EID_NONTRANSMITTED_BSSID_CAPA;
|
|
+ *eid++ = sizeof(capab_info);
|
|
+ capab_info = host_to_le16(hostapd_own_capab_info(bss));
|
|
+ os_memcpy(eid, (const void*)&capab_info, sizeof(capab_info));
|
|
+ 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;
|
|
+
|
|
+ *eid++ = WLAN_EID_MULTIPLE_BSSID_INDEX;
|
|
+ index_size_offset = eid++;
|
|
+ *eid++ = i;
|
|
+ if (is_beacon) {
|
|
+ *eid++ = bss->conf->dtim_period;
|
|
+ *eid++ = 0xFF;
|
|
+ }
|
|
+ *index_size_offset = (eid - index_size_offset) - 1;
|
|
+
|
|
+ eid = hostapd_get_rsne(bss, eid, end - eid);
|
|
+ *bss_size_offset = (eid - bss_size_offset) - 1;
|
|
+
|
|
+ if ((eid - size_offset) - 1 > 255) {
|
|
+ eid = pos;
|
|
+ goto multiple_bssid_too_big;
|
|
+ }
|
|
+ num++;
|
|
+ }
|
|
+
|
|
+multiple_bssid_too_big:
|
|
+ *count = i;
|
|
+ *num_offset = (u8)ceil(log2(hapd->iface->num_bss));
|
|
+ if (*num_offset < 1)
|
|
+ *num_offset = 1;
|
|
+ *size_offset = (eid - size_offset) - 1;
|
|
+
|
|
+ return eid;
|
|
+}
|
|
+
|
|
+
|
|
+u8 * hostapd_eid_multiple_bssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
|
|
+ u8 is_beacon, u8 **eid_offsets, int *eid_count,
|
|
+ int eid_max)
|
|
+{
|
|
+ int count = 1;
|
|
+
|
|
+ while (count < hapd->iface->num_bss) {
|
|
+ if (eid_offsets && *eid_count < eid_max) {
|
|
+ eid_offsets[*eid_count] = eid;
|
|
+ *eid_count = *eid_count + 1;
|
|
+ }
|
|
+ eid = hostapd_eid_multiple_bssid_chunk(hapd, eid, end, &count,
|
|
+ is_beacon);
|
|
+ }
|
|
+ return eid;
|
|
+}
|
|
+
|
|
#endif /* CONFIG_NATIVE_WINDOWS */
|
|
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
|
|
index ea8c60846..11fd1245c 100644
|
|
--- a/src/ap/ieee802_11.h
|
|
+++ b/src/ap/ieee802_11.h
|
|
@@ -119,6 +119,10 @@ u8 * hostapd_eid_time_zone(struct hostapd_data *hapd, u8 *eid);
|
|
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 is_beacon, u8 **eid_offsets, int *eid_count,
|
|
+ int eid_max);
|
|
+int hostapd_eid_multiple_bssid_len(struct hostapd_data *hapd);
|
|
|
|
int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta);
|
|
#ifdef CONFIG_SAE
|
|
@@ -194,5 +198,6 @@ int get_tx_parameters(struct sta_info *sta, int ap_max_chanwidth,
|
|
|
|
void auth_sae_process_commit(void *eloop_ctx, void *user_ctx);
|
|
u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len);
|
|
+u8 * hostapd_get_rsne(struct hostapd_data *hapd, u8 *pos, size_t len);
|
|
|
|
#endif /* IEEE802_11_H */
|
|
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
|
|
index 4d3037eee..7d1287763 100644
|
|
--- a/src/common/ieee802_11_defs.h
|
|
+++ b/src/common/ieee802_11_defs.h
|
|
@@ -452,6 +452,8 @@
|
|
#define WLAN_EID_RSNX 244
|
|
#define WLAN_EID_EXTENSION 255
|
|
|
|
+#define WLAN_EID_SUBELEMENT_NONTRANSMITTED_BSSID_PROFILE 0
|
|
+
|
|
/* Element ID Extension (EID 255) values */
|
|
#define WLAN_EID_EXT_ASSOC_DELAY_INFO 1
|
|
#define WLAN_EID_EXT_FILS_REQ_PARAMS 2
|
|
--
|
|
2.25.1
|
|
|