[PATCH 25/92] NAN: Add control interface for triggering NAN pairing
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Wed Apr 22 05:23:16 PDT 2026
From: Avraham Stern <avraham.stern at intel.com>
Add control interface support for triggering NAN pairing.
Supported parameters are the authentication mode (SAE, PASN or
pairing verification), the cipher to use and the publish ID.
Add wpa_cli support as well.
Signed-off-by: Avraham Stern <avraham.stern at intel.com>
---
wpa_supplicant/ctrl_iface.c | 5 ++
wpa_supplicant/nan_supplicant.c | 90 +++++++++++++++++++++++++++++++++
wpa_supplicant/nan_supplicant.h | 1 +
wpa_supplicant/wpa_cli.c | 12 +++++
4 files changed, 108 insertions(+)
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 690241a6f0..013cc98567 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -14430,6 +14430,11 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
} else if (os_strncmp(buf, "NAN_BOOTSTRAP_RESET ", 20) == 0) {
if (wpas_nan_bootstrap_reset(wpa_s, buf + 20) < 0)
reply_len = -1;
+#ifdef CONFIG_PASN
+ } else if (os_strncmp(buf, "NAN_PAIR ", 9) == 0) {
+ if (wpas_nan_pairing_start(wpa_s, buf + 9) < 0)
+ reply_len = -1;
+#endif /* CONFIG_PASN */
#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 0eb134a247..9c4b532303 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -2575,6 +2575,96 @@ int wpas_nan_pair(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
return ret;
}
+
+
+/*
+ * Format: NAN_PAIR <peer_nmi> <handle=<id>>
+ * <peer_instance_id=<id>> <auth=<0|1|2>> <cipher=<CCMP|GCMP-256>>
+ * [responder] [password=<password>]
+ */
+int wpas_nan_pairing_start(struct wpa_supplicant *wpa_s, char *cmd)
+{
+ char *token, *context = NULL;
+ u8 addr[ETH_ALEN];
+ u8 auth_mode = 0;
+ u8 peer_instance_id = 0;
+ int handle = 0;
+ int cipher = WPA_CIPHER_NONE;
+ char *password = NULL;
+ bool responder = false;
+ char *pos;
+
+ /* Parse peer address first */
+ if (hwaddr_aton(cmd, addr) < 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 (os_strncmp(token, "auth=", 5) == 0) {
+ auth_mode = atoi(token + 5);
+ if (auth_mode > 2) {
+ wpa_printf(MSG_DEBUG,
+ "NAN_PAIR: Invalid auth mode: %u",
+ auth_mode);
+ return -1;
+ }
+ } else if (os_strncmp(token, "handle=", 7) == 0) {
+ handle = atoi(token + 7);
+ } else if (os_strncmp(token, "peer_instance_id=", 17) == 0) {
+ peer_instance_id = atoi(token + 17);
+ } else if (os_strncmp(token, "cipher=", 7) == 0) {
+ if (os_strcmp(token + 7, "CCMP") == 0) {
+ cipher = WPA_CIPHER_CCMP;
+ } else if (os_strcmp(token + 7, "GCMP-256") == 0) {
+ cipher = WPA_CIPHER_GCMP_256;
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "NAN_PAIR: Invalid cipher: '%s'",
+ token + 7);
+ return -1;
+ }
+ } else if (os_strncmp(token, "responder", 9) == 0) {
+ responder = true;
+ } else if (os_strncmp(token, "password=", 9) == 0) {
+ password = token + 9;
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "NAN_PAIR: Invalid parameter: '%s'",
+ token);
+ return -1;
+ }
+ }
+
+ if (handle <= 0) {
+ wpa_printf(MSG_DEBUG,
+ "NAN_PAIR: missing or invalid handle");
+ return -1;
+ }
+
+ if (!peer_instance_id) {
+ wpa_printf(MSG_DEBUG,
+ "NAN_PAIR: missing or invalid peer_instance_id");
+ return -1;
+ }
+
+ if (cipher == WPA_CIPHER_NONE) {
+ wpa_printf(MSG_DEBUG, "NAN_PAIR: missing cipher");
+ return -1;
+ }
+
+ if (wpas_nan_pair(wpa_s, addr, auth_mode, cipher, handle,
+ peer_instance_id, responder, password) < 0) {
+ wpa_printf(MSG_DEBUG, "NAN_PAIR: Pairing initiation failed");
+ return -1;
+ }
+
+ return 0;
+}
#endif /* CONFIG_PASN */
#endif /* CONFIG_NAN */
diff --git a/wpa_supplicant/nan_supplicant.h b/wpa_supplicant/nan_supplicant.h
index 3568366b83..3722b3eab0 100644
--- a/wpa_supplicant/nan_supplicant.h
+++ b/wpa_supplicant/nan_supplicant.h
@@ -39,6 +39,7 @@ int wpas_nan_bootstrap_reset(struct wpa_supplicant *wpa_s, char *cmd);
int wpas_nan_pair(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
u8 auth_mode, int cipher, int handle, u8 peer_instance_id,
bool responder, const char *password);
+int wpas_nan_pairing_start(struct wpa_supplicant *wpa_s, char *cmd);
#endif /* CONFIG_PASN */
#else /* CONFIG_NAN */
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index a4eab29c07..aec6ac2099 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -3469,6 +3469,13 @@ static int wpa_cli_cmd_nan_bootstrap_reset(struct wpa_ctrl *ctrl,
return wpa_cli_cmd(ctrl, "NAN_BOOTSTRAP_RESET", 1, argc, argv);
}
+#ifdef CONFIG_PASN
+static int wpa_cli_cmd_nan_pair_start(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ return wpa_cli_cmd(ctrl, "NAN_PAIR", 5, argc, argv);
+}
+#endif /* CONFIG_PASN */
#endif /* CONFIG_NAN */
@@ -4281,6 +4288,11 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
{ "nan_bootstrap_reset", wpa_cli_cmd_nan_bootstrap_reset, NULL,
cli_cmd_flag_none,
" = <peer_mac> = Reset NAN boostrapping with peer" },
+#ifdef CONFIG_PASN
+ { "nan_pair", wpa_cli_cmd_nan_pair_start, NULL,
+ cli_cmd_flag_none,
+ " = <peer_mac> <handle=<service handle>> <peer_instance_id=<peer requestor id>> <auth=<0|1|2>> <cipher=<CCMP|GCMP-256>> [password=<password>] [responder] = Request or authorize NAN pairing with peer" },
+#endif /* CONFIG_PASN */
#endif /* CONFIG_NAN */
{ "new_random_mac_address", wpa_cli_cmd_generate_new_mac, NULL,
cli_cmd_flag_none, "= Generate new random MAC address" },
--
2.53.0
More information about the Hostap
mailing list