[PATCH 67/92] NAN: Send and receive only protected SDF frames if peer is paired

Andrei Otcheretianski andrei.otcheretianski at intel.com
Wed Apr 22 05:23:58 PDT 2026


From: Avraham Stern <avraham.stern at intel.com>

All SDF frames to a paired peer should be protected. Change the
category of SDF frames from public action to dual protected public
action when sending them to a paired peer.
In addition, drop unicast unprotected public action frames from a
paired peer.

Signed-off-by: Avraham Stern <avraham.stern at intel.com>
---
 src/common/nan_de.c             | 12 ++++++++----
 src/common/nan_de.h             |  1 +
 wpa_supplicant/events.c         |  6 ++++++
 wpa_supplicant/nan_supplicant.c | 22 ++++++++++++++++++++++
 wpa_supplicant/nan_supplicant.h |  7 +++++++
 5 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/src/common/nan_de.c b/src/common/nan_de.c
index 4959ccd7fb..f3a28b6e28 100644
--- a/src/common/nan_de.c
+++ b/src/common/nan_de.c
@@ -247,14 +247,18 @@ static void nan_de_unpause_state(struct nan_de_service *srv)
 	srv->sel_peer_id = 0;
 }
 
-
-static struct wpabuf * nan_de_alloc_sdf(size_t len)
+static struct wpabuf *nan_de_alloc_sdf(struct nan_de *de, const u8 *dst,
+				       size_t len)
 {
 	struct wpabuf *buf;
+	u8 category = WLAN_ACTION_PUBLIC;
+
+	if (de->cb.is_peer_paired && de->cb.is_peer_paired(de->cb.ctx, dst))
+		category = WLAN_ACTION_PROTECTED_DUAL;
 
 	buf = wpabuf_alloc(2 + 4 + len);
 	if (buf) {
-		wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC);
+		wpabuf_put_u8(buf, category);
 		wpabuf_put_u8(buf, WLAN_PA_VENDOR_SPECIFIC);
 		wpabuf_put_be32(buf, NAN_SDF_VENDOR_TYPE);
 	}
@@ -372,7 +376,7 @@ static void nan_de_tx_sdf(struct nan_de *de, struct nan_de_service *srv,
 		       list_len * (sizeof(struct nan_sec_ctxt) + PMKID_LEN);
 	}
 
-	buf = nan_de_alloc_sdf(len);
+	buf = nan_de_alloc_sdf(de, dst, len);
 	if (!buf)
 		return;
 
diff --git a/src/common/nan_de.h b/src/common/nan_de.h
index b9801c2536..705ddc1836 100644
--- a/src/common/nan_de.h
+++ b/src/common/nan_de.h
@@ -69,6 +69,7 @@ struct nan_callbacks {
 				     u16 buf_len, const u8 *peer_addr,
 				     unsigned int freq);
 	void (*add_extra_attrs)(void *ctx, struct wpabuf *buf);
+	bool (*is_peer_paired)(void *ctx, const u8 *addr);
 };
 
 bool nan_de_is_nan_network_id(const u8 *addr);
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 8ee53ae9aa..ad7f72b8cd 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -5952,6 +5952,12 @@ static void wpas_event_rx_mgmt_action(struct wpa_supplicant *wpa_s,
 	if ((category == WLAN_ACTION_PUBLIC ||
 	     category == WLAN_ACTION_PROTECTED_DUAL) &&
 	    plen >= 5 && payload[0] == WLAN_PA_VENDOR_SPECIFIC) {
+		/* Drop unprotected unicast frames from paired peers */
+		if (category == WLAN_ACTION_PUBLIC &&
+		    !is_multicast_ether_addr(mgmt->da) &&
+		    wpas_nan_is_peer_paired(wpa_s, mgmt->sa))
+			return;
+
 		if  (WPA_GET_BE32(&payload[1]) == NAN_SDF_VENDOR_TYPE) {
 			payload += 5;
 			plen -= 5;
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index 43c7a9c1ae..49eca9e2c4 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -2947,6 +2947,15 @@ int wpas_nan_pasn_auth_rx(struct wpa_supplicant *wpa_s,
 	return nan_pairing_auth_rx(nan, mgmt, len);
 }
 #endif /* CONFIG_PASN */
+
+
+bool wpas_nan_is_peer_paired(struct wpa_supplicant *wpa_s, const u8 *peer_addr)
+{
+	if (!wpa_s->nan)
+		return false;
+
+	return nan_pairing_is_peer_paired(wpa_s->nan, peer_addr);
+}
 #endif /* CONFIG_NAN */
 
 
@@ -3310,6 +3319,16 @@ static void wpas_nan_process_pr_usd_elems(void *ctx, const u8 *buf, u16 buf_len,
 #endif /* CONFIG_PR */
 
 
+#if defined(CONFIG_NAN) && defined(CONFIG_PASN)
+static bool wpas_nan_is_peer_paired_cb(void *ctx, const u8 *peer_addr)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+
+	return wpas_nan_is_peer_paired(wpa_s, peer_addr);
+}
+#endif /* CONFIG_NAN && CONFIG_PASN */
+
+
 int wpas_nan_de_init(struct wpa_supplicant *wpa_s)
 {
 	struct nan_callbacks cb;
@@ -3335,6 +3354,9 @@ int wpas_nan_de_init(struct wpa_supplicant *wpa_s)
 #endif /* CONFIG_PR */
 #ifdef CONFIG_NAN
 	cb.add_extra_attrs = wpas_nan_de_add_extra_attrs;
+#ifdef CONFIG_PASN
+	cb.is_peer_paired = wpas_nan_is_peer_paired_cb;
+#endif /* CONFIG_PASN */
 #endif /* CONFIG_NAN */
 
 	wpa_s->nan_de = nan_de_init(wpa_s->own_addr, offload, false,
diff --git a/wpa_supplicant/nan_supplicant.h b/wpa_supplicant/nan_supplicant.h
index 794515bcfb..1e5196bca0 100644
--- a/wpa_supplicant/nan_supplicant.h
+++ b/wpa_supplicant/nan_supplicant.h
@@ -34,6 +34,7 @@ int wpas_nan_peer_info(struct wpa_supplicant *wpa_s, const char *cmd,
 		       char *reply, size_t reply_size);
 int wpas_nan_bootstrap_request(struct wpa_supplicant *wpa_s, char *cmd);
 int wpas_nan_bootstrap_reset(struct wpa_supplicant *wpa_s, char *cmd);
+bool wpas_nan_is_peer_paired(struct wpa_supplicant *wpa_s, const u8 *peer_addr);
 
 #ifdef CONFIG_PASN
 int wpas_nan_pair(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
@@ -91,6 +92,12 @@ static inline void wpas_nan_rx_naf(struct wpa_supplicant *wpa_s,
 				   const struct ieee80211_mgmt *mgmt,
 				   size_t len)
 {}
+
+static inline bool wpas_nan_is_peer_paired(struct wpa_supplicant *wpa_s,
+					  const u8 *peer_addr)
+{
+	return false;
+}
 #endif /* CONFIG_NAN */
 
 struct nan_subscribe_params;
-- 
2.53.0




More information about the Hostap mailing list