[RFC 12/13] wpa_supplicant: Support NAN_BOOTSTRAP command

Andrei Otcheretianski andrei.otcheretianski at intel.com
Tue Dec 23 03:57:24 PST 2025


Add support for handling the following NAN bootstrap commands over
the control interface:

- NAN Bootstrap request: used to request start or authorize a
  bootstrap flow with a given peer.
- NAN Bootstrap reset: used to request to stop bootstrap with a
  given peer and to reset the bootstrap state for the given peer.

Add the corresponding support to 'wpa_cli' as well.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 wpa_supplicant/ctrl_iface.c     |  6 +++
 wpa_supplicant/nan_supplicant.c | 87 +++++++++++++++++++++++++++++++++
 wpa_supplicant/nan_supplicant.h |  3 ++
 wpa_supplicant/wpa_cli.c        | 19 ++++++-
 4 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 7648602b6b..005f309301 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -14372,6 +14372,12 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
 	} else if (os_strncmp(buf, "NAN_PEER_INFO ", 14) == 0) {
 		reply_len = wpas_nan_peer_info(wpa_s, buf + 14, reply,
 					       reply_size);
+	} else if (os_strncmp(buf, "NAN_BOOTSTRAP ", 14) == 0) {
+		if (wpas_nan_bootstrap_request(wpa_s, buf + 14) < 0)
+			reply_len = -1;
+	} else if (os_strncmp(buf, "NAN_BOOTSTRAP_RESET ", 20) == 0) {
+		if (wpas_nan_bootstrap_reset(wpa_s, buf + 20) < 0)
+			reply_len = -1;
 #endif /* CONFIG_NAN */
 	} else {
 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index 6dd847bb92..10e2d93e7d 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -2340,6 +2340,93 @@ int wpas_nan_peer_info(struct wpa_supplicant *wpa_s, const char *cmd,
 }
 
 
+/*
+ * Format: NAN_BOOTSTRAP <peer_nmi> <handle=<id>>
+ *     <req_instance_id=<id>> method=<number> [auth]
+ */
+int wpas_nan_bootstrap_request(struct wpa_supplicant *wpa_s, char *cmd)
+{
+	char *pos, *token, *context = NULL;
+	int handle = 0;
+	int req_instance_id = 0;
+	u8 peer_nmi[ETH_ALEN];
+	u16 bootstrap_method = 0;
+	bool auth = false;
+
+	if (!wpas_nan_ready(wpa_s))
+		return -1;
+
+	/* Parse peer address first */
+	if (hwaddr_aton(cmd, peer_nmi) < 0)
+		return -1;
+
+	/* Move past the peer_mac address */
+	pos = os_strchr(cmd, ' ');
+	if (!pos)
+		return -1;
+	pos++;
+
+	while ((token = str_token(pos, " ", &context))) {
+		if (sscanf(token, "handle=%i", &handle) == 1)
+			continue;
+
+		if (sscanf(token, "req_instance_id=%i", &req_instance_id) == 1)
+			continue;
+
+		if (os_strncmp(token, "method=", 7) == 0) {
+			bootstrap_method = atoi(token + 7);
+			continue;
+		}
+
+		if (os_strcmp(token, "auth") == 0) {
+			auth = true;
+			continue;
+		}
+
+		wpa_printf(MSG_INFO,
+			   "CTRL: Invalid NAN_BOOTSTRAP parameter: %s",
+			   token);
+		return -1;
+	}
+
+	if (!bootstrap_method) {
+		wpa_printf(MSG_INFO,
+			   "CTRL: Missing NAN_BOOTSTRAP method");
+		return -1;
+	}
+
+	if (handle <= 0) {
+		wpa_printf(MSG_INFO,
+			   "CTRL: Invalid or missing NAN_BOOTSTRAP handle");
+		return -1;
+	}
+
+	if (is_zero_ether_addr(peer_nmi)) {
+		wpa_printf(MSG_INFO,
+			   "CTRL: Invalid or missing NAN_BOOTSTRAP address");
+		return -1;
+	}
+
+	return nan_bootstrap_request(wpa_s->nan, handle, peer_nmi,
+				     req_instance_id, bootstrap_method, auth);
+}
+
+
+/* Format: NAN_BOOTSTRAP_RESET <peer_nmi> */
+int wpas_nan_bootstrap_reset(struct wpa_supplicant *wpa_s, char *cmd)
+{
+	u8 peer_nmi[ETH_ALEN];
+
+	if (!wpas_nan_ready(wpa_s))
+		return -1;
+
+	if (hwaddr_aton(cmd, peer_nmi) < 0)
+		return -1;
+
+	return nan_bootstrap_peer_reset(wpa_s->nan, peer_nmi);
+}
+
+
 static void wpas_nan_de_add_extra_attrs(void *ctx, struct wpabuf *buf)
 {
 	struct wpa_supplicant *wpa_s = ctx;
diff --git a/wpa_supplicant/nan_supplicant.h b/wpa_supplicant/nan_supplicant.h
index 6ff78e939c..437f341785 100644
--- a/wpa_supplicant/nan_supplicant.h
+++ b/wpa_supplicant/nan_supplicant.h
@@ -32,6 +32,9 @@ int wpas_nan_ndp_response(struct wpa_supplicant *wpa_s, char *cmd);
 int wpas_nan_ndp_terminate(struct wpa_supplicant *wpa_s, char *cmd);
 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);
+
 #else /* CONFIG_NAN */
 
 static inline int wpas_nan_init(struct wpa_supplicant *wpa_s)
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 17aa0bd13d..420311f2f5 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -3418,7 +3418,6 @@ static int wpa_cli_cmd_nan_update_conf(struct wpa_ctrl *ctrl, int argc,
 	return wpa_cli_cmd(ctrl, "NAN_UPDATE_CONF", 0, argc, argv);
 }
 
-
 static int wpa_cli_cmd_nan_sched_config_map(struct wpa_ctrl *ctrl, int argc,
 					     char *argv[])
 {
@@ -3453,6 +3452,18 @@ static int wpa_cli_cmd_nan_peer_info(struct wpa_ctrl *ctrl, int argc,
 	return wpa_cli_cmd(ctrl, "NAN_PEER_INFO", 2, argc, argv);
 }
 
+static int wpa_cli_cmd_nan_bootstrap(struct wpa_ctrl *ctrl, int argc,
+				     char *argv[])
+{
+	return wpa_cli_cmd(ctrl, "NAN_BOOTSTRAP", 4, argc, argv);
+}
+
+static int wpa_cli_cmd_nan_bootstrap_reset(struct wpa_ctrl *ctrl,
+					   int argc, char *argv[])
+{
+	return wpa_cli_cmd(ctrl, "NAN_BOOTSTRAP_RESET", 1, argc, argv);
+}
+
 #endif /* CONFIG_NAN */
 
 
@@ -4253,6 +4264,12 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
 	  cli_cmd_flag_none, "peer_nmi=<nmi> init_ndi=<ndi> ndp_id=<id> = Terminate NAN data path" },
 	{ "nan_peer_info", wpa_cli_cmd_nan_peer_info, NULL,
 	  cli_cmd_flag_none, "<addr> <schedule|potential|capa> [map_id] = Get NAN peer information" },
+	{ "nan_bootstrap", wpa_cli_cmd_nan_bootstrap, NULL,
+	  cli_cmd_flag_none,
+	  " = <peer_mac> <handle=<service handle>> <req_instance_id=<peer requestor id>> <method=<Bootstrap method>> [auth] = Request or authorize NAN boostrapping with peer" },
+	{ "nan_bootstrap_reset", wpa_cli_cmd_nan_bootstrap_reset, NULL,
+	  cli_cmd_flag_none,
+	  " = <peer_mac> = Reset NAN boostrapping with peer" },
 #endif /* CONFIG_NAN */
 	{ "new_random_mac_address", wpa_cli_cmd_generate_new_mac, NULL,
 	  cli_cmd_flag_none, "= Generate new random MAC address" },
-- 
2.49.0




More information about the Hostap mailing list