[PATCH 1/2] hostapd: add support for unicast beacons

Raphaël Mélotte raphael.melotte at mind.be
Thu Jan 5 12:09:44 PST 2023


In some specific scenarios where a BSS is used for a single station,
it can be useful to be able to configure beacons as unicast instead of
broadcast.

Add a new configuration parameter, 'beacon_da'. When set, its value is
used as the destination address for beacon frames. If unset, set to
zero, or to the broadcast address, the behavior remains the same as
before (i.e. beacons are broadcasted).

Signed-off-by: Raphaël Mélotte <raphael.melotte at mind.be>
---
 hostapd/config_file.c | 6 ++++++
 hostapd/ctrl_iface.c  | 8 ++++++++
 hostapd/hostapd.conf  | 3 +++
 src/ap/ap_config.h    | 1 +
 src/ap/beacon.c       | 7 ++++++-
 5 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 76f9cf831..8eeab92c8 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -3404,6 +3404,12 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 				   line);
 			return 1;
 		}
+	} else if (os_strcmp(buf, "beacon_da") == 0) {
+		if (hwaddr_aton(pos, bss->beacon_da)) {
+			wpa_printf(MSG_ERROR, "Line %d: invalid beacon_da item",
+				   line);
+			return 1;
+		}
 	} else if (os_strcmp(buf, "use_driver_iface_addr") == 0) {
 		conf->use_driver_iface_addr = atoi(pos);
 	} else if (os_strcmp(buf, "ieee80211w") == 0) {
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 464dfc8ee..1ba643bf0 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -983,6 +983,14 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
 		return pos - buf;
 	pos += ret;
 
+	if (!is_zero_ether_addr(hapd->conf->beacon_da)) {
+		ret = os_snprintf(pos, end - pos, "beacon_da=" MACSTR "\n",
+				  MAC2STR(hapd->conf->beacon_da));
+		if (os_snprintf_error(end - pos, ret))
+			return pos - buf;
+		pos += ret;
+	}
+
 	if ((hapd->conf->config_id)) {
 		ret = os_snprintf(pos, end - pos, "config_id=%s\n",
 				  hapd->conf->config_id);
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index c5e74a6a2..c1a71d68e 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -94,6 +94,9 @@ ssid=test
 # UTF-8 SSID: Whether the SSID is to be interpreted using UTF-8 encoding
 #utf8_ssid=1
 
+# Destination address for beacon frames (defaults to broadcast)
+#beacon_da=ff:ff:ff:ff:ff:ff
+
 # Country code (ISO/IEC 3166-1). Used to set regulatory domain.
 # Set as needed to indicate country in which device is operating.
 # This can limit available channels and transmit power.
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 1631cf2aa..03ad4bed7 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -471,6 +471,7 @@ struct hostapd_bss_config {
 	struct hostapd_vlan *vlan;
 
 	macaddr bssid;
+	macaddr beacon_da;
 
 	/*
 	 * Maximum listen interval that STAs can use when associating with this
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index dbc6b062b..0f69a31a3 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -1678,7 +1678,12 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 	head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
 					   WLAN_FC_STYPE_BEACON);
 	head->duration = host_to_le16(0);
-	os_memset(head->da, 0xff, ETH_ALEN);
+	if (is_zero_ether_addr(hapd->conf->beacon_da) ||
+	    is_broadcast_ether_addr(hapd->conf->beacon_da))
+		os_memset(head->da, 0xff, ETH_ALEN);
+	else {
+		os_memcpy(head->da, hapd->conf->beacon_da, ETH_ALEN);
+	}
 
 	os_memcpy(head->sa, hapd->own_addr, ETH_ALEN);
 	os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN);
-- 
2.38.1




More information about the Hostap mailing list