aboutsummaryrefslogtreecommitdiffstats
path: root/src/ap/ap_drv_ops.c
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2016-06-10 18:30:03 (GMT)
committerJouni Malinen <j@w1.fi>2016-06-10 18:44:49 (GMT)
commit78a36327652673fa182395011420c3151e1e03e8 (patch)
tree65019c0f7e6cfe7eedf3ebda985fa9c16963eca1 /src/ap/ap_drv_ops.c
parentc86bef2913a6aa9947d45e8d28bb0539c2d5c25c (diff)
downloadhostap-78a36327652673fa182395011420c3151e1e03e8.zip
hostap-78a36327652673fa182395011420c3151e1e03e8.tar.gz
hostap-78a36327652673fa182395011420c3151e1e03e8.tar.bz2
hostapd: Fix Public Action frame addressing (BSSID field)
IEEE Std 802.11-2012, 10.19 (Public Action frame addressing) specifies that the wildcard BSSID value is used in Public Action frames that are transmitted to a STA that is not a member of the same BSS. hostapd used to use the actual BSSID value for all such frames regardless of whether the destination STA is a member of the BSS. Fix this by using the wildcard BSSID in cases the destination STA is not a member of the BSS. Leave group addressed case as-is (i.e., the actual BSSID), since both values are accepted. No such frames are currently used, though. This version is still using the AP BSSID value in the Address 3 field for GAS response frames when replying to a GAS request with AP BSSID instead of Wildcard BSSID. This is left as a workaround to avoid interoperability issues with deployed STA implementations that are still using the non-compliant address and that might be unable to process the standard compliant case. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Diffstat (limited to 'src/ap/ap_drv_ops.c')
-rw-r--r--src/ap/ap_drv_ops.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index e4fd0c5..532b72f 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -675,6 +675,36 @@ int hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
unsigned int wait, const u8 *dst, const u8 *data,
size_t len)
{
+ const u8 *bssid;
+ const u8 wildcard_bssid[ETH_ALEN] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
+
+ if (hapd->driver == NULL || hapd->driver->send_action == NULL)
+ return 0;
+ bssid = hapd->own_addr;
+ if (!is_multicast_ether_addr(dst) &&
+ len > 0 && data[0] == WLAN_ACTION_PUBLIC) {
+ struct sta_info *sta;
+
+ /*
+ * Public Action frames to a STA that is not a member of the BSS
+ * shall use wildcard BSSID value.
+ */
+ sta = ap_get_sta(hapd, dst);
+ if (!sta || !(sta->flags & WLAN_STA_ASSOC))
+ bssid = wildcard_bssid;
+ }
+ return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst,
+ hapd->own_addr, bssid, data, len, 0);
+}
+
+
+int hostapd_drv_send_action_addr3_ap(struct hostapd_data *hapd,
+ unsigned int freq,
+ unsigned int wait, const u8 *dst,
+ const u8 *data, size_t len)
+{
if (hapd->driver == NULL || hapd->driver->send_action == NULL)
return 0;
return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst,