1 /*
2 * wpa_supplicant - NAN
3 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4 * Copyright (C) 2025 Intel Corporation
5 *
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
8 */
9
10 #include "includes.h"
11
12 #include "common.h"
13 #include "utils/eloop.h"
14 #include "utils/bitfield.h"
15 #include "common/nan_de.h"
16 #include "common/ieee802_11_common.h"
17 #include "ap/hostapd.h"
18 #include "wpa_supplicant_i.h"
19 #include "driver_i.h"
20 #include "nan/nan.h"
21 #include "config.h"
22 #include "offchannel.h"
23 #include "notify.h"
24 #include "p2p_supplicant.h"
25 #include "pr_supplicant.h"
26 #include "nan_supplicant.h"
27
28 #define DEFAULT_NAN_MASTER_PREF 2
29 #define DEFAULT_NAN_DUAL_BAND 0
30 #define DEFAULT_NAN_SCAN_PERIOD 60
31 #define DEFAULT_NAN_SCAN_DWELL_TIME 150
32 #define DEFAULT_NAN_DISCOVERY_BEACON_INTERVAL 100
33 #define DEFAULT_NAN_LOW_BAND_FREQUENCY 2437
34 #define DEFAULT_NAN_HIGH_BAND_FREQUENCY 5745
35 #define DEFAULT_NAN_RSSI_CLOSE -50
36 #define DEFAULT_NAN_RSSI_MIDDLE -65
37
38 #define NAN_MIN_RSSI_CLOSE -60
39 #define NAN_MIN_RSSI_MIDDLE -75
40
41 #define NAN_AVAIL_ATTR_MAX_LEN 100
42
43 #define DEFAULT_NAN_SUPP_PBM (NAN_PBA_METHOD_OPPORTUNISTIC | \
44 NAN_PBA_METHOD_PIN_DISPLAY | \
45 NAN_PBA_METHOD_PASSPHRASE_DISPLAY | \
46 NAN_PBA_METHOD_QR_DISPLAY | \
47 NAN_PBA_METHOD_NFC_TAG | \
48 NAN_PBA_METHOD_PIN_KEYPAD | \
49 NAN_PBA_METHOD_PASSPHRASE_KEYPAD | \
50 NAN_PBA_METHOD_QR_SCAN | \
51 NAN_PBA_METHOD_NFC_READER)
52
53 #define DEFAULT_NAN_AUTO_ACCEPT_PBM NAN_PBA_METHOD_OPPORTUNISTIC
54
55 #define DEFAULT_NAN_BOOTSTRAP_COMEBACK_TIMEOUT 1024
56
57 /* Default NAN NIK lifetime in seconds - 12 hours */
58 #define NAN_NIK_LIFETIME_DEFAULT 43200
59
60 /* Default NAN idle period in seconds */
61 #define DEFAULT_NAN_MAX_NDL_IDLE_PERIOD 25
62
63 #ifdef CONFIG_NAN
64
get_center(u8 channel,const u8 * center_channels,unsigned int num_chan,int width)65 static int get_center(u8 channel, const u8 *center_channels,
66 unsigned int num_chan, int width)
67 {
68 int span = (width - 20) / 10;
69 unsigned int i;
70
71 for (i = 0; i < num_chan; i++) {
72 if (channel >= center_channels[i] - span &&
73 channel <= center_channels[i] + span)
74 return center_channels[i];
75 }
76
77 return 0;
78 }
79
80
get_center_and_width(int bw,u8 channel,int * width)81 static u8 get_center_and_width(int bw, u8 channel, int *width)
82 {
83 static const u8 nan_160mhz_5ghz_chans[] = { 50, 114, 163 };
84 static const u8 nan_80mhz_5ghz_chans[] =
85 { 42, 58, 106, 122, 138, 155, 171 };
86
87 switch (bw) {
88 case BW20:
89 *width = 20;
90 return channel;
91 case BW40PLUS:
92 case BW40MINUS:
93 *width = 40;
94 return bw == BW40PLUS ? channel + 2 : channel - 2;
95 case BW80:
96 *width = 80;
97 return get_center(channel, nan_80mhz_5ghz_chans,
98 ARRAY_SIZE(nan_80mhz_5ghz_chans), *width);
99 case BW160:
100 *width = 160;
101 return get_center(channel, nan_160mhz_5ghz_chans,
102 ARRAY_SIZE(nan_160mhz_5ghz_chans), *width);
103 default:
104 return 0;
105 }
106
107 return 0;
108 }
109
110
wpas_nan_valid_chan(struct wpa_supplicant * wpa_s,enum hostapd_hw_mode mode,u8 channel,int bw,u8 op_class,u8 * cf1)111 static bool wpas_nan_valid_chan(struct wpa_supplicant *wpa_s,
112 enum hostapd_hw_mode mode,
113 u8 channel, int bw, u8 op_class, u8 *cf1)
114 {
115 struct hostapd_hw_modes *hw_mode;
116 int width, span;
117 u8 c, center;
118
119 hw_mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, mode, false);
120 if (!hw_mode)
121 return false;
122
123 center = get_center_and_width(bw, channel, &width);
124 if (!center)
125 return false;
126
127 if (wpa_s->nan_max_bw && width > wpa_s->nan_max_bw)
128 return false;
129
130 span = (width - 20) / 10;
131 for (c = center - span; c <= center + span; c += 4) {
132 int freq = ieee80211_chan_to_freq(NULL, op_class, c);
133
134 if (freq < 0)
135 return false;
136
137 if (freq_range_list_includes(&wpa_s->nan_disallowed_freqs,
138 freq))
139 return false;
140
141 if (ieee80211_is_dfs(freq, wpa_s->hw.modes,
142 wpa_s->hw.num_modes))
143 return false;
144 }
145
146 /* Wide channels use center */
147 if (width > 40)
148 channel = center;
149
150 *cf1 = center;
151 return verify_channel(hw_mode, op_class, channel, bw) == ALLOWED;
152 }
153
154
wpas_nan_start_cb(void * ctx,const struct nan_cluster_config * config)155 static int wpas_nan_start_cb(void *ctx, const struct nan_cluster_config *config)
156 {
157 struct wpa_supplicant *wpa_s = ctx;
158
159 return wpa_drv_nan_start(wpa_s, config);
160 }
161
162
wpas_nan_update_config_cb(void * ctx,const struct nan_cluster_config * config)163 static int wpas_nan_update_config_cb(void *ctx,
164 const struct nan_cluster_config *config)
165 {
166 struct wpa_supplicant *wpa_s = ctx;
167
168 return wpa_drv_nan_update_config(wpa_s, config);
169 }
170
171
clear_sched_config(struct nan_schedule_config * sched_cfg)172 static void clear_sched_config(struct nan_schedule_config *sched_cfg)
173 {
174 int i;
175
176 for (i = 0; i < sched_cfg->num_channels; i++)
177 wpabuf_free(sched_cfg->channels[i].time_bitmap);
178
179 wpabuf_free(sched_cfg->avail_attr);
180 os_memset(sched_cfg, 0, sizeof(*sched_cfg));
181 }
182
183
wpas_nan_stop_cb(void * ctx)184 static void wpas_nan_stop_cb(void *ctx)
185 {
186 struct wpa_supplicant *wpa_s = ctx;
187 int i;
188
189 for (i = 0; i < MAX_NAN_RADIOS; i++) {
190 if (wpa_s->nan_sched[i].num_channels) {
191 wpa_drv_nan_config_schedule(wpa_s, i + 1, NULL);
192 clear_sched_config(&wpa_s->nan_sched[i]);
193 }
194 }
195
196 wpa_drv_nan_stop(wpa_s);
197 nan_de_set_cluster_id(wpa_s->nan_de, NULL);
198 wpas_notify_nan_stopped(wpa_s);
199 }
200
201
wpas_nan_set_peer_sched_chan(struct wpa_supplicant * wpa_s,const struct nan_peer_schedule * sched,int i,int j,struct nan_schedule_config * sched_cfg)202 static int wpas_nan_set_peer_sched_chan(struct wpa_supplicant *wpa_s,
203 const struct nan_peer_schedule *sched,
204 int i, int j,
205 struct nan_schedule_config *sched_cfg)
206 {
207 const struct nan_map_chan *src_chan = &sched->maps[i].chans[j];
208 struct nan_chan_entry *chan_entry;
209 int ch_idx;
210
211 if (!src_chan->committed)
212 return 0;
213
214 wpa_printf(MSG_DEBUG, " Channel freq=%u, rx_nss=%u",
215 src_chan->chan.freq, src_chan->rx_nss);
216 wpa_hexdump(MSG_DEBUG, " committed_bitmap",
217 src_chan->tbm.bitmap, src_chan->tbm.len);
218
219 ch_idx = sched_cfg->num_channels;
220 sched_cfg->channels[ch_idx].freq = src_chan->chan.freq;
221 sched_cfg->channels[ch_idx].center_freq1 = src_chan->chan.center_freq1;
222 sched_cfg->channels[ch_idx].center_freq2 = src_chan->chan.center_freq2;
223 sched_cfg->channels[ch_idx].bandwidth = src_chan->chan.bandwidth;
224 sched_cfg->channels[ch_idx].rx_nss = src_chan->rx_nss;
225 chan_entry = (struct nan_chan_entry *)
226 sched_cfg->channels[ch_idx].chan_entry;
227
228 if (nan_get_chan_entry(wpa_s->nan, &src_chan->chan, chan_entry)) {
229 wpa_printf(MSG_INFO,
230 "NAN: Failed to get chan entry for freq %d",
231 src_chan->chan.freq);
232 return -1;
233 }
234
235 /* Copy time bitmap */
236 if (src_chan->tbm.len > 0)
237 sched_cfg->channels[ch_idx].time_bitmap =
238 wpabuf_alloc_copy(src_chan->tbm.bitmap,
239 src_chan->tbm.len);
240
241 sched_cfg->num_channels++;
242
243 return 0;
244 }
245
246
wpas_nan_set_peer_schedule_cb(void * ctx,const u8 * nmi_addr,bool new_sta,u16 cdw,u8 sequence_id,u16 max_channel_switch_time,const struct nan_peer_schedule * sched,const struct wpabuf * ulw_elems)247 static int wpas_nan_set_peer_schedule_cb(void *ctx, const u8 *nmi_addr,
248 bool new_sta, u16 cdw, u8 sequence_id,
249 u16 max_channel_switch_time,
250 const struct nan_peer_schedule *sched,
251 const struct wpabuf *ulw_elems)
252 {
253 struct wpa_supplicant *wpa_s = ctx;
254 struct nan_peer_schedule_config peer_sched;
255 int i, j, ret;
256
257 wpa_printf(MSG_DEBUG, "NAN: Set peer schedule - nmi_addr=" MACSTR
258 " new_sta=%d cdw=%u seq_id=%u max_chan_switch_time=%u",
259 MAC2STR(nmi_addr), new_sta, cdw, sequence_id,
260 max_channel_switch_time);
261
262 if (new_sta) {
263 struct hostapd_sta_add_params sta_params;
264
265 wpa_printf(MSG_DEBUG, "NAN: New NMI station");
266 os_memset(&sta_params, 0, sizeof(sta_params));
267 sta_params.addr = nmi_addr;
268 sta_params.flags = WPA_STA_AUTHENTICATED | WPA_STA_ASSOCIATED;
269 sta_params.flags_mask = sta_params.flags;
270 ret = wpa_drv_sta_add(wpa_s, &sta_params);
271 if (ret) {
272 wpa_printf(MSG_INFO, "NAN: Failed to add NMI station");
273 return ret;
274 }
275 }
276
277 os_memset(&peer_sched, 0, sizeof(peer_sched));
278 if (sched) {
279 wpa_printf(MSG_DEBUG, "NAN: Peer schedule info:");
280 wpa_printf(MSG_DEBUG, " n_maps=%u", sched->n_maps);
281
282 for (i = 0; i < sched->n_maps && i < MAX_NUM_NAN_MAPS; i++) {
283 struct nan_schedule_config *sched_cfg =
284 &peer_sched.maps[peer_sched.n_maps].sched;
285
286 wpa_printf(MSG_DEBUG, " Map %d: map_id=%u",
287 i, sched->maps[i].map_id);
288
289 sched_cfg->num_channels = 0;
290
291 for (j = 0; j < sched->maps[i].n_chans &&
292 sched_cfg->num_channels <
293 MAX_NUM_NAN_SCHEDULE_CHANNELS; j++) {
294 if (wpas_nan_set_peer_sched_chan(wpa_s, sched,
295 i, j,
296 sched_cfg) < 0)
297 goto out;
298 }
299
300 /* Only add map if it has channels after filtering */
301 if (sched_cfg->num_channels > 0) {
302 peer_sched.maps[peer_sched.n_maps].map_id =
303 sched->maps[i].map_id;
304 peer_sched.n_maps++;
305 }
306 }
307 }
308
309 ret = wpa_drv_nan_config_peer_schedule(wpa_s, nmi_addr,
310 cdw, sequence_id,
311 max_channel_switch_time,
312 ulw_elems, &peer_sched);
313
314 /* Only print an error without returning, so we attempt to remove
315 * the STA if needed (sched == NULL)
316 */
317 if (ret)
318 wpa_printf(MSG_INFO, "NAN: Failed to configure peer schedule");
319
320 if (!sched && !new_sta) {
321 /* TODO: Should we maybe keep that NMI station? */
322 wpa_printf(MSG_DEBUG, "NAN: Unpair NMI station before removal");
323 nan_pairing_unpair_peer(wpa_s->nan, nmi_addr);
324
325 wpa_printf(MSG_DEBUG, "NAN: Remove NMI station");
326 ret = wpa_drv_sta_remove(wpa_s, nmi_addr);
327 if (ret)
328 wpa_printf(MSG_INFO,
329 "NAN: Failed to remove NMI station");
330 }
331
332 out:
333 /* Free allocated time bitmaps */
334 for (i = 0; i < peer_sched.n_maps; i++) {
335 struct nan_schedule_config *sched_cfg =
336 &peer_sched.maps[i].sched;
337
338 for (j = 0; j < sched_cfg->num_channels; j++) {
339 wpabuf_free(sched_cfg->channels[j].time_bitmap);
340 sched_cfg->channels[j].time_bitmap = NULL;
341 }
342 }
343
344 return ret;
345 }
346
347
348 static void
wpas_nan_ndp_action_notif_cb(void * ctx,struct nan_ndp_action_notif_params * params)349 wpas_nan_ndp_action_notif_cb(void *ctx,
350 struct nan_ndp_action_notif_params *params)
351 {
352 struct wpa_supplicant *wpa_s = ctx;
353
354 if (params->is_request) {
355 wpas_notify_nan_ndp_request(wpa_s, params->ndp_id.peer_nmi,
356 params->ndp_id.init_ndi,
357 params->ndp_id.id,
358 params->publish_inst_id,
359 params->ssi, params->ssi_len,
360 params->csid);
361 } else {
362 wpas_notify_nan_ndp_counter_request(wpa_s,
363 params->ndp_id.peer_nmi,
364 params->ndp_id.init_ndi,
365 params->ndp_id.id,
366 params->ssi,
367 params->ssi_len);
368 }
369 }
370
371
wpas_nan_set_ndi_keys(struct wpa_supplicant * wpa_s,const u8 * ndi_addr,enum nan_cipher_suite_id csid,const u8 * tk,size_t tk_len)372 static int wpas_nan_set_ndi_keys(struct wpa_supplicant *wpa_s,
373 const u8 *ndi_addr,
374 enum nan_cipher_suite_id csid,
375 const u8 *tk, size_t tk_len)
376 {
377 enum wpa_alg alg;
378 u8 rsc[6];
379
380 os_memset(rsc, 0, sizeof(rsc));
381 switch (csid) {
382 case NAN_CS_SK_CCM_128:
383 case NAN_CS_PK_PASN_128:
384 alg = WPA_ALG_CCMP;
385 break;
386 case NAN_CS_SK_GCM_256:
387 case NAN_CS_PK_PASN_256:
388 alg = WPA_ALG_GCMP_256;
389 break;
390 default:
391 wpa_printf(MSG_INFO, "NAN: Unsupported CSID %d for NDI keys",
392 csid);
393 return -1;
394 }
395
396 return wpa_drv_set_key(wpa_s, -1, alg, ndi_addr, 0, 1, rsc, sizeof(rsc),
397 tk, tk_len, KEY_FLAG_PAIRWISE);
398 }
399
400
wpas_nan_remove_ndi_keys(struct wpa_supplicant * wpa_s,const u8 * ndi_addr)401 static int wpas_nan_remove_ndi_keys(struct wpa_supplicant *wpa_s,
402 const u8 *ndi_addr)
403 {
404 return wpa_drv_set_key(wpa_s, -1, WPA_ALG_NONE, ndi_addr, 0, 0,
405 NULL, 0, NULL, 0, KEY_FLAG_PAIRWISE);
406 }
407
408
wpas_nan_remove_ndi_gtk(struct wpa_supplicant * wpa_s,int key_id,const u8 * ndi_addr)409 static int wpas_nan_remove_ndi_gtk(struct wpa_supplicant *wpa_s, int key_id,
410 const u8 *ndi_addr)
411 {
412 return wpa_drv_set_key(wpa_s, -1, WPA_ALG_NONE, ndi_addr, key_id, 0,
413 NULL, 0, NULL, 0, KEY_FLAG_GROUP);
414 }
415
416
wpas_nan_remove_ndi_local_gtk(struct wpa_supplicant * wpa_s)417 static int wpas_nan_remove_ndi_local_gtk(struct wpa_supplicant *wpa_s)
418 {
419 if (!wpa_s->ndi_gtk.gtk.gtk_len)
420 return 0;
421
422 if (wpa_drv_set_key(wpa_s, -1, WPA_ALG_NONE, broadcast_ether_addr,
423 wpa_s->ndi_gtk.id, 0, NULL, 0, NULL, 0,
424 KEY_FLAG_GROUP_TX_DEFAULT)) {
425 wpa_printf(MSG_INFO, "NAN: Failed to remove NDI group TX key");
426 return -1;
427 }
428
429 wpa_s->ndi_gtk.id = 0;
430 os_memset(&wpa_s->ndi_gtk, 0, sizeof(wpa_s->ndi_gtk));
431 return 0;
432 }
433
434
435 static struct wpa_supplicant *
wpas_nan_get_ndi_iface(struct wpa_supplicant * wpa_s,const u8 * ndi_addr)436 wpas_nan_get_ndi_iface(struct wpa_supplicant *wpa_s, const u8 *ndi_addr)
437 {
438 struct wpa_supplicant *ndi_wpa_s;
439
440 for (ndi_wpa_s = wpa_s->global->ifaces; ndi_wpa_s;
441 ndi_wpa_s = ndi_wpa_s->next) {
442 if (ndi_wpa_s->nan_data &&
443 ether_addr_equal(ndi_wpa_s->own_addr, ndi_addr))
444 return ndi_wpa_s;
445 }
446
447 return NULL;
448 }
449
450
wpas_nan_configure_nmi_sta_capa(struct wpa_supplicant * wpa_s,const u8 * nmi_addr)451 static int wpas_nan_configure_nmi_sta_capa(struct wpa_supplicant *wpa_s,
452 const u8 *nmi_addr)
453 {
454 struct hostapd_sta_add_params sta_params;
455 const u8 *ie;
456 u8 *elems;
457 int elems_len;
458
459 elems_len = nan_get_peer_elems(wpa_s->nan, nmi_addr, &elems);
460 if (elems_len < 0) {
461 wpa_printf(MSG_INFO,
462 "NAN: Failed to get peer elems for NMI station");
463 return -1;
464 }
465
466 os_memset(&sta_params, 0, sizeof(sta_params));
467 sta_params.addr = nmi_addr;
468 sta_params.set = 1;
469 sta_params.flags = WPA_STA_AUTHORIZED;
470 sta_params.flags_mask = sta_params.flags;
471
472 ie = get_ie(elems, elems_len, WLAN_EID_HT_CAP);
473 if (!ie) {
474 wpa_printf(MSG_INFO,
475 "NAN: No HT capabilities in peer elems for NMI station");
476 return -1;
477 }
478
479 sta_params.ht_capabilities = (const void *) (ie + 2);
480 ie = get_ie(elems, elems_len, WLAN_EID_VHT_CAP);
481 sta_params.vht_capabilities = ie ? (const void *) (ie + 2) : NULL;
482
483 return wpa_drv_sta_add(wpa_s, &sta_params);
484 }
485
486
wpas_nan_csid_to_wpa_alg(enum nan_cipher_suite_id csid,enum wpa_alg * alg)487 static int wpas_nan_csid_to_wpa_alg(enum nan_cipher_suite_id csid,
488 enum wpa_alg *alg)
489 {
490 switch (csid) {
491 case NAN_CS_NONE:
492 *alg = WPA_ALG_NONE;
493 break;
494 case NAN_CS_SK_CCM_128:
495 case NAN_CS_GTK_CCMP_128:
496 *alg = WPA_ALG_CCMP;
497 break;
498 case NAN_CS_SK_GCM_256:
499 case NAN_CS_GTK_GCMP_256:
500 *alg = WPA_ALG_GCMP_256;
501 break;
502 default:
503 wpa_printf(MSG_INFO, "NAN: Unsupported CSID %d", csid);
504 return -1;
505 }
506
507 return 0;
508 }
509
510
wpas_nan_set_ndi_group_keys(struct wpa_supplicant * wpa_s,struct nan_ndp_connection_params * params)511 static int wpas_nan_set_ndi_group_keys(struct wpa_supplicant *wpa_s,
512 struct nan_ndp_connection_params *params)
513 {
514 enum wpa_alg alg;
515
516 /* Install the local GTK only if not already installed */
517 if (!wpa_s->ndi_gtk.id && params->local_gtk && params->local_gtk->id) {
518 u8 rsc[RSN_PN_LEN];
519
520 if (wpas_nan_csid_to_wpa_alg(params->local_gtk->csid, &alg)) {
521 wpa_printf(MSG_INFO,
522 "NAN: Unsupported CSID %u for local GTK",
523 params->local_gtk->csid);
524 return -1;
525 }
526
527 os_memset(rsc, 0, sizeof(rsc));
528 if (wpa_drv_set_key(wpa_s, -1, alg, broadcast_ether_addr,
529 params->local_gtk->id, 0, rsc, sizeof(rsc),
530 params->local_gtk->gtk.gtk,
531 params->local_gtk->gtk.gtk_len,
532 KEY_FLAG_GROUP_TX_DEFAULT)) {
533 wpa_printf(MSG_INFO,
534 "NAN: Failed to set local GTK for NDI");
535 return -1;
536 }
537
538 os_memcpy(&wpa_s->ndi_gtk, params->local_gtk,
539 sizeof(wpa_s->ndi_gtk));
540 }
541
542 if (params->peer_gtk && params->peer_gtk->id) {
543 if (wpas_nan_csid_to_wpa_alg(params->peer_gtk->csid, &alg)) {
544 wpa_printf(MSG_INFO,
545 "NAN: Unsupported CSID %u for peer GTK",
546 params->peer_gtk->csid);
547 return -1;
548 }
549
550 if (wpa_drv_set_key(wpa_s, -1, alg, params->peer_ndi,
551 params->peer_gtk->id, 0,
552 params->peer_gtk_rsc, RSN_PN_LEN,
553 params->peer_gtk->gtk.gtk,
554 params->peer_gtk->gtk.gtk_len,
555 KEY_FLAG_GROUP_RX)) {
556 wpa_printf(MSG_INFO,
557 "NAN: Failed to set peer GTK for NDI");
558 return -1;
559 }
560 }
561
562 return 0;
563 }
564
565
wpas_nan_add_ndi_sta(struct wpa_supplicant * wpa_s,struct nan_ndp_connection_params * params)566 static int wpas_nan_add_ndi_sta(struct wpa_supplicant *wpa_s,
567 struct nan_ndp_connection_params *params)
568 {
569 u8 tk[WPA_TK_MAX_LEN];
570 size_t tk_len;
571 enum nan_cipher_suite_id csid;
572 struct wpa_supplicant *ndi_wpa_s;
573 struct hostapd_sta_add_params sta_params;
574 const u8 *peer_nmi = params->ndp_id.peer_nmi;
575 const u8 *peer_ndi = params->peer_ndi;
576
577 ndi_wpa_s = wpas_nan_get_ndi_iface(wpa_s, params->local_ndi);
578 if (!ndi_wpa_s) {
579 wpa_printf(MSG_INFO,
580 "NAN: No NDI interface found for " MACSTR,
581 MAC2STR(params->local_ndi));
582 return -1;
583 }
584
585 /* HT/VHT capabilities are configured per NMI station only for
586 * the first NDP. After that it is assumed that capablities are not
587 * changing.
588 */
589 if (params->first_ndp &&
590 wpas_nan_configure_nmi_sta_capa(wpa_s, peer_nmi)) {
591 wpa_printf(MSG_INFO,
592 "NAN: Failed to configure NMI station capabilities");
593 return -1;
594 }
595
596 if (params->new_ndi_sta) {
597 os_memset(&sta_params, 0, sizeof(sta_params));
598 sta_params.addr = peer_ndi;
599 sta_params.nmi_addr = peer_nmi;
600 sta_params.flags = WPA_STA_AUTHENTICATED | WPA_STA_ASSOCIATED;
601
602 /* Set MFP flag early, to prevent races until keys are installed
603 */
604 if (params->install_keys)
605 sta_params.flags |= WPA_STA_MFP;
606 else
607 sta_params.flags |= WPA_STA_AUTHORIZED;
608
609 if (wpa_drv_sta_add(ndi_wpa_s, &sta_params)) {
610 wpa_printf(MSG_INFO,
611 "NAN: Failed to add NDI station for peer "
612 MACSTR, MAC2STR(peer_ndi));
613 return -1;
614 }
615 } else {
616 wpa_printf(MSG_DEBUG,
617 "NAN: NDI station already exists for peer " MACSTR,
618 MAC2STR(peer_ndi));
619 /* Set MFP flag if keys will be installed (security upgrade) */
620 if (params->install_keys &&
621 wpa_drv_sta_set_flags(ndi_wpa_s, peer_ndi, WPA_STA_MFP,
622 WPA_STA_MFP, ~0)) {
623 wpa_printf(MSG_INFO,
624 "NAN: Failed to set MFP flag for peer "
625 MACSTR, MAC2STR(peer_ndi));
626 return -1;
627 }
628 }
629
630 wpa_printf(MSG_DEBUG, "NAN: NDI station for peer " MACSTR " %s",
631 MAC2STR(peer_ndi),
632 params->new_ndi_sta ? "added" : "already exists");
633
634 if (!params->install_keys) {
635 wpa_printf(MSG_DEBUG,
636 "NAN: NDI station %s without keys for peer " MACSTR,
637 params->new_ndi_sta ? "added" : "ready",
638 MAC2STR(peer_ndi));
639 goto out_success;
640 }
641
642 if (nan_peer_get_tk(wpa_s->nan, peer_nmi, peer_ndi, params->local_ndi,
643 tk, &tk_len, &csid)) {
644 wpa_printf(MSG_INFO, "NAN: Failed to get TK for NDI station");
645 goto remove_sta;
646 }
647
648 if (wpas_nan_set_ndi_keys(ndi_wpa_s, peer_ndi, csid, tk, tk_len)) {
649 wpa_printf(MSG_INFO,
650 "NAN: Failed to set NDI keys for peer " MACSTR,
651 MAC2STR(peer_ndi));
652 forced_memzero(tk, tk_len);
653 goto remove_sta;
654 }
655 forced_memzero(tk, tk_len);
656
657 if (wpas_nan_set_ndi_group_keys(ndi_wpa_s, params)) {
658 wpa_printf(MSG_INFO,
659 "NAN: Failed to set NDI group keys for peer "
660 MACSTR, MAC2STR(peer_ndi));
661 wpas_nan_remove_ndi_keys(ndi_wpa_s, peer_ndi);
662 goto remove_sta;
663 }
664
665 if (wpa_drv_sta_set_flags(ndi_wpa_s, peer_ndi, WPA_STA_AUTHORIZED,
666 WPA_STA_AUTHORIZED, ~0)) {
667 wpa_printf(MSG_INFO,
668 "NAN: Failed to set authorize for NDI station");
669 wpas_nan_remove_ndi_keys(ndi_wpa_s, peer_ndi);
670 wpas_nan_remove_ndi_gtk(ndi_wpa_s, params->peer_gtk->id,
671 peer_ndi);
672 goto remove_sta;
673 }
674
675 out_success:
676 ndi_wpa_s->nan_ndi_ndp_refcount++;
677 wpa_printf(MSG_DEBUG,
678 "NAN: NDP refcount incremented to %u (peer_ndi=" MACSTR
679 " peer_nmi=" MACSTR ")",
680 ndi_wpa_s->nan_ndi_ndp_refcount,
681 MAC2STR(peer_ndi), MAC2STR(peer_nmi));
682
683 /* Set operstate UP only when the first NDP is established on this NDI
684 */
685 if (ndi_wpa_s->nan_ndi_ndp_refcount == 1)
686 wpa_drv_set_operstate(ndi_wpa_s, 1);
687
688 return 0;
689
690 remove_sta:
691 /*
692 * Clean up the NDI station if it was newly added for this NDP. For
693 * existing stations, we assume that the caller will tear down other
694 * NDPs with this station on failure as it may be now in some
695 * inconsistent state that is too hard to rollback here.
696 */
697 if (params->new_ndi_sta)
698 wpa_drv_sta_remove(ndi_wpa_s, params->peer_ndi);
699 return -2;
700 }
701
702
wpas_nan_remove_ndi_sta(struct wpa_supplicant * wpa_s,const u8 * local_ndi,const u8 * peer_ndi,bool remove_sta,int gtk_id)703 static void wpas_nan_remove_ndi_sta(struct wpa_supplicant *wpa_s,
704 const u8 *local_ndi,
705 const u8 *peer_ndi,
706 bool remove_sta, int gtk_id)
707 {
708 struct wpa_supplicant *ndi_wpa_s;
709
710 ndi_wpa_s = wpas_nan_get_ndi_iface(wpa_s, local_ndi);
711 if (!ndi_wpa_s) {
712 wpa_printf(MSG_INFO,
713 "NAN: No NDI interface found for " MACSTR,
714 MAC2STR(local_ndi));
715 return;
716 }
717
718 if (!ndi_wpa_s->nan_ndi_ndp_refcount)
719 return;
720
721 ndi_wpa_s->nan_ndi_ndp_refcount--;
722 wpa_printf(MSG_DEBUG, "NAN: NDP refcount decremented to %u (peer_ndi="
723 MACSTR ")", ndi_wpa_s->nan_ndi_ndp_refcount,
724 MAC2STR(peer_ndi));
725
726 /* Only remove the NDI station if no other NDP is using the same
727 * peer NDI address
728 */
729 if (remove_sta) {
730 if (wpa_drv_sta_set_flags(ndi_wpa_s, peer_ndi,
731 WPA_STA_AUTHORIZED, 0,
732 ~WPA_STA_AUTHORIZED))
733 wpa_printf(MSG_DEBUG,
734 "NAN: Failed to clear authorized flag for NDI station");
735
736 wpas_nan_remove_ndi_keys(ndi_wpa_s, peer_ndi);
737 if (gtk_id)
738 wpas_nan_remove_ndi_gtk(ndi_wpa_s, gtk_id, peer_ndi);
739 wpa_drv_sta_remove(ndi_wpa_s, peer_ndi);
740 }
741
742 /* Remove the local GTK and set operstate DORMANT only when the last NDP
743 * is removed from this NDI
744 */
745 if (!ndi_wpa_s->nan_ndi_ndp_refcount) {
746 wpas_nan_remove_ndi_local_gtk(ndi_wpa_s);
747 wpa_drv_set_operstate(ndi_wpa_s, 0);
748 }
749 }
750
751
wpas_nan_ndp_connected_cb(void * ctx,struct nan_ndp_connection_params * params)752 static int wpas_nan_ndp_connected_cb(void *ctx,
753 struct nan_ndp_connection_params *params)
754 {
755 struct wpa_supplicant *wpa_s = ctx;
756 int ret;
757
758 ret = wpas_nan_add_ndi_sta(wpa_s, params);
759 if (ret) {
760 wpa_printf(MSG_INFO,
761 "NAN: Failed to add NDI station for NDP connection");
762 return ret;
763 }
764
765 wpas_notify_nan_ndp_connected(wpa_s, params->ndp_id.peer_nmi,
766 params->ndp_id.id,
767 params->local_ndi, params->peer_ndi,
768 params->ssi, params->ssi_len,
769 params->interface_id);
770
771 return 0;
772 }
773
774
wpas_nan_ndp_disconnected_cb(void * ctx,struct nan_ndp_id * ndp_id,const u8 * local_ndi,const u8 * peer_ndi,enum nan_reason reason,bool locally_generated,bool remove_sta,bool failure,u8 gtk_id)775 static void wpas_nan_ndp_disconnected_cb(void *ctx, struct nan_ndp_id *ndp_id,
776 const u8 *local_ndi,
777 const u8 *peer_ndi,
778 enum nan_reason reason,
779 bool locally_generated,
780 bool remove_sta,
781 bool failure, u8 gtk_id)
782 {
783 struct wpa_supplicant *wpa_s = ctx;
784
785 wpas_nan_remove_ndi_sta(wpa_s, local_ndi, peer_ndi, remove_sta, gtk_id);
786 wpas_notify_nan_ndp_disconnected(wpa_s, ndp_id->peer_nmi,
787 ndp_id->id, local_ndi, peer_ndi,
788 reason, locally_generated, failure);
789 }
790
791
wpas_nan_send_naf_cb(void * ctx,const u8 * dst,const u8 * src,const u8 * cluster_id,struct wpabuf * buf)792 static int wpas_nan_send_naf_cb(void *ctx, const u8 *dst, const u8 *src,
793 const u8 *cluster_id, struct wpabuf *buf)
794 {
795 struct wpa_supplicant *wpa_s = ctx;
796 const u8 *a2;
797 int ret;
798
799 a2 = src ? src : wpa_s->own_addr;
800
801 if (src && !ether_addr_equal(src, wpa_s->own_addr)) {
802 wpa_printf(MSG_DEBUG, "NAN: Use NDI interface for sending NAF");
803
804 wpa_s = wpas_nan_get_ndi_iface(wpa_s, src);
805 if (!wpa_s) {
806 wpa_printf(MSG_DEBUG,
807 "NAN: No NDI interface found for address "
808 MACSTR, MAC2STR(src));
809 wpa_s = ctx;
810 }
811 }
812
813 wpa_printf(MSG_DEBUG, "NAN: Send NAF - dst=" MACSTR " src=" MACSTR
814 " cluster_id=" MACSTR, MAC2STR(dst), MAC2STR(a2),
815 MAC2STR(cluster_id));
816
817 ret = wpa_drv_send_action(wpa_s, 0, 0, dst, a2, cluster_id,
818 wpabuf_head(buf), wpabuf_len(buf), 1);
819 if (ret)
820 wpa_printf(MSG_DEBUG,
821 "NAN: Failed to send sync Action frame (%d)", ret);
822 return ret;
823 }
824
825
nan_chan_info_cmp(const void * a,const void * b)826 static int nan_chan_info_cmp(const void *a, const void *b)
827 {
828 const struct nan_channel_info *chan_a = a;
829 const struct nan_channel_info *chan_b = b;
830
831 return chan_b->pref - chan_a->pref;
832 }
833
834
wpas_nan_get_chans_cb(void * ctx,u8 map_id,struct nan_channels * chans)835 static int wpas_nan_get_chans_cb(void *ctx, u8 map_id,
836 struct nan_channels *chans)
837 {
838 struct wpa_supplicant *wpa_s = ctx;
839 int *shared_freqs = NULL;
840 struct nan_channel_info *chan_list = NULL;
841 unsigned int chan_count = 0;
842 unsigned int chan_capacity = 0;
843 int op;
844
845 wpa_printf(MSG_DEBUG, "NAN: Get channels - map_id=%u", map_id);
846
847 /* Check if override is configured */
848 if (wpa_s->nan_override_potential_avail.n_chans > 0) {
849 wpa_printf(MSG_DEBUG,
850 "NAN: Using override potential availability (%u channels)",
851 wpa_s->nan_override_potential_avail.n_chans);
852
853 chans->n_chans = wpa_s->nan_override_potential_avail.n_chans;
854 chans->chans = os_memdup(
855 wpa_s->nan_override_potential_avail.chans,
856 wpa_s->nan_override_potential_avail.n_chans *
857 sizeof(struct nan_channel_info));
858 if (!chans->chans) {
859 wpa_printf(MSG_INFO,
860 "NAN: Failed to allocate memory for override channels");
861 chans->n_chans = 0;
862 return -1;
863 }
864
865 return 0;
866 }
867
868 /* Allocate one extra element so it will be 0 terminated int_array */
869 shared_freqs = os_calloc(wpa_s->num_multichan_concurrent + 1,
870 sizeof(int));
871 if (!shared_freqs) {
872 wpa_printf(MSG_INFO,
873 "NAN: Failed to allocate memory for shared freqs");
874 goto fail;
875 }
876
877 if (get_shared_radio_freqs(wpa_s, shared_freqs,
878 wpa_s->num_multichan_concurrent,
879 false) < 0) {
880 wpa_printf(MSG_DEBUG, "NAN: Failed to get shared radio freqs");
881 goto fail;
882 }
883
884 /* Iterate through global operating classes */
885 for (op = 0; global_op_class[op].op_class; op++) {
886 const struct oper_class_map *o = &global_op_class[op];
887 int c;
888
889 /* Don't support 80+, 6 GHz, etc. yet */
890 if (o->op_class > 129)
891 continue;
892
893 /* Iterate through channels in this operating class */
894 for (c = o->min_chan; c <= o->max_chan; c += o->inc) {
895 int freq;
896 u8 center;
897 u8 pref;
898
899 /* Don't support 40 MHz channels on 2.4 GHz band */
900 if (o->mode == HOSTAPD_MODE_IEEE80211G && o->bw != BW20)
901 continue;
902
903 if (!wpas_nan_valid_chan(wpa_s, o->mode, c, o->bw,
904 o->op_class, ¢er))
905 continue;
906
907 freq = ieee80211_chan_to_freq(NULL, o->op_class, c);
908 if (freq < 0)
909 continue;
910
911 /* Determine preference based on shared frequencies */
912 if (int_array_includes(shared_freqs, freq))
913 pref = 3;
914 else
915 pref = 1;
916
917 /* Expand channel list if needed */
918 if (chan_count >= chan_capacity) {
919 unsigned int new_capacity = chan_capacity ?
920 chan_capacity * 2 : 16;
921 struct nan_channel_info *new_list;
922
923 new_list = os_realloc_array(
924 chan_list, new_capacity,
925 sizeof(struct nan_channel_info));
926 if (!new_list) {
927 wpa_printf(MSG_INFO,
928 "NAN: Failed to expand channel list");
929 goto fail;
930 }
931 chan_list = new_list;
932 chan_capacity = new_capacity;
933 }
934
935 /* Add channel to list */
936 chan_list[chan_count].op_class = o->op_class;
937 chan_list[chan_count].channel =
938 o->bw == BW80 || o->bw == BW160 ? center : c;
939 chan_list[chan_count].pref = pref;
940 chan_count++;
941 }
942 }
943
944 /* Sort channels by preference (higher preference first) */
945 if (chan_count > 1)
946 qsort(chan_list, chan_count, sizeof(struct nan_channel_info),
947 nan_chan_info_cmp);
948
949 chans->n_chans = chan_count;
950 chans->chans = chan_list;
951
952 os_free(shared_freqs);
953
954 wpa_printf(MSG_DEBUG, "NAN: Get channels completed - found %u channels",
955 chan_count);
956 return 0;
957
958 fail:
959 os_free(shared_freqs);
960 os_free(chan_list);
961 chans->n_chans = 0;
962 chans->chans = NULL;
963 return -1;
964 }
965
966
wpas_nan_is_valid_publish_id_cb(void * ctx,u8 instance_id,u8 * service_id)967 static bool wpas_nan_is_valid_publish_id_cb(void *ctx, u8 instance_id,
968 u8 *service_id)
969 {
970 struct wpa_supplicant *wpa_s = ctx;
971
972 wpa_printf(MSG_DEBUG, "NAN: Check valid publish ID - instance_id=%u",
973 instance_id);
974
975 return nan_de_is_valid_instance_id(wpa_s->nan_de, instance_id, true,
976 service_id);
977 }
978
979
wpas_nan_bootstrap_request_cb(void * ctx,const u8 * peer_nmi,u16 pbm,int handle,u8 requestor_instance_id)980 static void wpas_nan_bootstrap_request_cb(void *ctx, const u8 *peer_nmi,
981 u16 pbm, int handle,
982 u8 requestor_instance_id)
983 {
984 struct wpa_supplicant *wpa_s = ctx;
985
986 wpas_notify_nan_bootstrap_request(wpa_s, peer_nmi, pbm, handle,
987 requestor_instance_id);
988 }
989
990
wpas_nan_bootstrap_completed_cb(void * ctx,const u8 * peer_nmi,u16 pbm,bool success,u8 reason_code,int handle,u8 requestor_instance_id)991 static void wpas_nan_bootstrap_completed_cb(void *ctx, const u8 *peer_nmi,
992 u16 pbm, bool success,
993 u8 reason_code, int handle,
994 u8 requestor_instance_id)
995 {
996 struct wpa_supplicant *wpa_s = ctx;
997
998 if (success)
999 wpas_notify_nan_bootstrap_success(wpa_s, peer_nmi, pbm, handle,
1000 requestor_instance_id);
1001 else
1002 wpas_notify_nan_bootstrap_failure(wpa_s, peer_nmi, pbm,
1003 reason_code, handle,
1004 requestor_instance_id);
1005 }
1006
1007
wpas_nan_schedule_changed_cb(void * ctx,const u8 * peer_nmi)1008 static void wpas_nan_schedule_changed_cb(void *ctx, const u8 *peer_nmi)
1009 {
1010 struct wpa_supplicant *wpa_s = ctx;
1011
1012 wpas_notify_nan_schedule_changed(wpa_s, peer_nmi);
1013 }
1014
1015
wpas_nan_transmit_followup_cb(void * ctx,const u8 * peer_nmi,const struct wpabuf * attrs,int handle,u8 req_instance_id)1016 static int wpas_nan_transmit_followup_cb(void *ctx, const u8 *peer_nmi,
1017 const struct wpabuf *attrs, int handle,
1018 u8 req_instance_id)
1019 {
1020 struct wpa_supplicant *wpa_s = ctx;
1021
1022 if (!wpa_s->nan_de)
1023 return -1;
1024
1025 return nan_de_transmit(wpa_s->nan_de, handle, NULL, NULL,
1026 peer_nmi, req_instance_id, attrs, NULL);
1027 }
1028
1029
wpas_nan_get_service_bootstrap_methods(void * ctx,int handle)1030 static u16 wpas_nan_get_service_bootstrap_methods(void *ctx, int handle)
1031 {
1032 struct wpa_supplicant *wpa_s = ctx;
1033
1034 if (!wpa_s->nan_de)
1035 return 0;
1036
1037 return nan_de_get_service_bootstrap_methods(wpa_s->nan_de, handle);
1038 }
1039
1040
1041 #ifdef CONFIG_PASN
1042
wpas_nan_pasn_send_cb(void * ctx,const u8 * data,size_t data_len)1043 static int wpas_nan_pasn_send_cb(void *ctx, const u8 *data, size_t data_len)
1044 {
1045 struct wpa_supplicant *wpa_s = ctx;
1046
1047 return wpa_drv_send_mlme(wpa_s, data, data_len, 0, 0, 0);
1048 }
1049
1050
wpas_nan_pasn_auth_status_cb(void * ctx,const u8 * peer_addr,int akmp,int cipher,u16 status,struct wpa_ptk * ptk,const u8 * nd_pmk)1051 static int wpas_nan_pasn_auth_status_cb(void *ctx, const u8 *peer_addr,
1052 int akmp, int cipher, u16 status,
1053 struct wpa_ptk *ptk, const u8 *nd_pmk)
1054 {
1055 struct wpa_supplicant *wpa_s = ctx;
1056 enum wpa_alg alg;
1057 u8 seq[6];
1058
1059 wpas_notify_nan_pairing_status(wpa_s, peer_addr, akmp, cipher,
1060 status, nd_pmk);
1061
1062 if (status != WLAN_STATUS_SUCCESS)
1063 return 0;
1064
1065 if (!ptk) {
1066 wpa_printf(MSG_DEBUG,
1067 "NAN: No PTK provided after pairing with peer "
1068 MACSTR, MAC2STR(peer_addr));
1069 return -1;
1070 }
1071
1072 alg = cipher == WPA_CIPHER_CCMP ? WPA_ALG_CCMP : WPA_ALG_GCMP_256;
1073 os_memset(seq, 0, sizeof(seq));
1074 if (wpa_drv_set_key(wpa_s, -1, alg, peer_addr, 0, 1, seq, sizeof(seq),
1075 ptk->tk, ptk->tk_len, KEY_FLAG_PAIRWISE_RX_TX)) {
1076 wpa_printf(MSG_INFO,
1077 "NAN: Failed to install NM-TK for peer " MACSTR,
1078 MAC2STR(peer_addr));
1079 return -1;
1080 }
1081
1082 return 0;
1083 }
1084
1085
wpas_nan_update_pairing_credentials_cb(void * ctx,const u8 * nik,size_t nik_len,int cipher_ver,int nik_lifetime,int akmp,const u8 * npk,size_t npk_len)1086 static int wpas_nan_update_pairing_credentials_cb(void *ctx, const u8 *nik,
1087 size_t nik_len,
1088 int cipher_ver,
1089 int nik_lifetime, int akmp,
1090 const u8 *npk, size_t npk_len)
1091 {
1092 struct wpa_supplicant *wpa_s = ctx;
1093 struct wpa_dev_ik *ik;
1094
1095 if (!nik || cipher_ver != NAN_NIRA_CIPHER_VER_128 ||
1096 nik_len != NAN_NIK_LEN || !npk || !npk_len) {
1097 wpa_printf(MSG_DEBUG, "NAN: Invalid NIK/NPK parameters");
1098 return -1;
1099 }
1100
1101 wpa_hexdump_key(MSG_DEBUG, "NAN: Received NIK", nik, nik_len);
1102 wpa_printf(MSG_DEBUG, "NAN: NIK lifetime=%d cipher_ver=%d",
1103 nik_lifetime, cipher_ver);
1104
1105 /* Check if an identity with the same NIK already exists */
1106 for (ik = wpa_s->conf->identity; ik; ik = ik->next) {
1107 if (nik_len == wpabuf_len(ik->dik) &&
1108 os_memcmp(nik, wpabuf_head(ik->dik), nik_len) == 0) {
1109 wpa_printf(MSG_DEBUG,
1110 "NAN: Remove previous device identity entry for matching NIK");
1111 wpa_config_remove_identity(wpa_s->conf, ik->id);
1112 break;
1113 }
1114 }
1115
1116 /* Create a new device identity entry */
1117 wpa_printf(MSG_DEBUG,
1118 "NAN: Create a new device identity entry for NIK");
1119 ik = wpa_config_add_identity(wpa_s->conf);
1120 if (!ik) {
1121 wpa_printf(MSG_INFO, "NAN: Failed to allocate identity");
1122 return -1;
1123 }
1124
1125 /* Store the NIK as the DIK */
1126 ik->dik = wpabuf_alloc_copy(nik, nik_len);
1127 if (!ik->dik)
1128 goto fail;
1129
1130 /* Store the NPK as the PMK */
1131 ik->pmk = wpabuf_alloc_copy(npk, npk_len);
1132 if (!ik->pmk)
1133 goto fail;
1134
1135 /* Store cipher version and AKMP */
1136 ik->dik_cipher = cipher_ver;
1137 ik->akmp = akmp;
1138
1139 wpa_printf(MSG_INFO, "NAN: Stored NIK as device identity (id=%d)",
1140 ik->id);
1141
1142 /* Notify control interface about received NIK */
1143 wpas_notify_nan_nik_received(wpa_s, nik, nik_len, cipher_ver, akmp,
1144 npk, npk_len, nik_lifetime, ik->id);
1145
1146 return ik->id;
1147
1148 fail:
1149 wpa_printf(MSG_INFO, "NAN: Failed to store NIK as device identity");
1150 wpa_config_remove_identity(wpa_s->conf, ik->id);
1151 return -1;
1152 }
1153
1154
1155 static const struct wpa_dev_ik *
wpas_nan_find_ik_by_nonce_tag(struct wpa_supplicant * wpa_s,const u8 * peer_nmi,const u8 * nonce,const u8 * tag)1156 wpas_nan_find_ik_by_nonce_tag(struct wpa_supplicant *wpa_s, const u8 *peer_nmi,
1157 const u8 *nonce, const u8 *tag)
1158 {
1159 struct wpa_dev_ik *ik;
1160 struct wpabuf *derived_tag;
1161
1162 if (!nonce || !tag) {
1163 wpa_printf(MSG_DEBUG, "NAN: Invalid nonce or tag");
1164 return NULL;
1165 }
1166
1167 wpa_printf(MSG_DEBUG, "NAN: Looking up device identity");
1168 wpa_hexdump(MSG_DEBUG, "NAN: NIRA nonce", nonce, NAN_NIRA_NONCE_LEN);
1169 wpa_hexdump(MSG_DEBUG, "NAN: NIRA tag", tag, NAN_NIRA_TAG_LEN);
1170
1171 /* Iterate over all saved NIKs (stored as device identities) */
1172 for (ik = wpa_s->conf->identity; ik; ik = ik->next) {
1173 /* The device identities saved in the interface configuration
1174 * are not checked to match NIK length and to have a PMK.
1175 * Although other identities are not expected since this is the
1176 * NAN management interface, verify that the DIK matches NIK
1177 * length, that a PMK is stored, and the stored AKMP is valid
1178 * for NAN pairing.
1179 */
1180 if (!ik->dik || wpabuf_len(ik->dik) != NAN_NIK_LEN ||
1181 !ik->pmk ||
1182 (ik->akmp != WPA_KEY_MGMT_SAE &&
1183 ik->akmp != WPA_KEY_MGMT_PASN))
1184 continue;
1185
1186 /* Derive tag from this NIK */
1187 derived_tag =
1188 nan_crypto_derive_nira_tag(wpabuf_head_u8(ik->dik),
1189 NAN_NIK_LEN, peer_nmi,
1190 nonce);
1191 if (!derived_tag)
1192 continue;
1193
1194 /* Compare derived tag with received tag */
1195 if (os_memcmp(wpabuf_head(derived_tag), tag,
1196 NAN_NIRA_TAG_LEN) != 0) {
1197 wpabuf_free(derived_tag);
1198 continue;
1199 }
1200
1201 wpa_printf(MSG_DEBUG,
1202 "NAN: NIRA validation succeeded with NIK id=%d",
1203 ik->id);
1204 wpabuf_free(derived_tag);
1205 return ik;
1206 }
1207
1208 return NULL;
1209 }
1210
1211
wpas_nan_get_npk_akmp_cb(void * ctx,const u8 * peer_nmi,const u8 * nonce,const u8 * tag,int * akmp)1212 static const struct wpabuf * wpas_nan_get_npk_akmp_cb(void *ctx,
1213 const u8 *peer_nmi,
1214 const u8 *nonce,
1215 const u8 *tag, int *akmp)
1216 {
1217 struct wpa_supplicant *wpa_s = ctx;
1218 const struct wpa_dev_ik *ik;
1219
1220 if (!akmp) {
1221 wpa_printf(MSG_DEBUG, "NAN: Invalid akmp pointer");
1222 return NULL;
1223 }
1224
1225 ik = wpas_nan_find_ik_by_nonce_tag(wpa_s, peer_nmi, nonce, tag);
1226 if (ik) {
1227 *akmp = ik->akmp;
1228 wpa_printf(MSG_DEBUG, "NAN: Found NPK for NIK id=%d, akmp=%d",
1229 ik->id, *akmp);
1230 return ik->pmk;
1231 }
1232
1233 wpa_printf(MSG_DEBUG, "NAN: No matching NIK found");
1234 return NULL;
1235 }
1236
1237
1238 static void
wpas_nan_pasn_pairing_request_cb(void * ctx,const u8 * peer_nmi,u8 csid,u8 instance_id,const struct wpa_ie_data * rsn_data)1239 wpas_nan_pasn_pairing_request_cb(void *ctx, const u8 *peer_nmi, u8 csid,
1240 u8 instance_id,
1241 const struct wpa_ie_data *rsn_data)
1242 {
1243 struct wpa_supplicant *wpa_s = ctx;
1244
1245 wpas_notify_nan_pairing_request(wpa_s, peer_nmi, csid, instance_id,
1246 rsn_data->key_mgmt,
1247 !!rsn_data->num_pmkid);
1248 }
1249
1250 #endif /* CONFIG_PASN */
1251
1252
wpas_nan_set_group_key_cb(void * ctx,enum wpa_alg alg,const u8 * addr,int key_idx,const u8 * seq,const u8 * key,size_t key_len,enum key_flag key_flags)1253 static int wpas_nan_set_group_key_cb(void *ctx, enum wpa_alg alg,
1254 const u8 *addr, int key_idx, const u8 *seq,
1255 const u8 *key, size_t key_len,
1256 enum key_flag key_flags)
1257 {
1258 struct wpa_supplicant *wpa_s = ctx;
1259
1260 return wpa_drv_set_key(wpa_s, -1, alg, addr, key_idx, 0,
1261 seq, RSN_PN_LEN, key, key_len, key_flags);
1262 }
1263
1264
wpas_nan_get_seqnum_cb(void * ctx,int key_idx,u8 * seq,const u8 * ndi_addr)1265 static int wpas_nan_get_seqnum_cb(void *ctx, int key_idx, u8 *seq,
1266 const u8 *ndi_addr)
1267 {
1268 struct wpa_supplicant *wpa_s = ctx;
1269
1270 if (ndi_addr) {
1271 wpa_s = wpas_nan_get_ndi_iface(wpa_s, ndi_addr);
1272 if (!wpa_s) {
1273 wpa_printf(MSG_DEBUG,
1274 "NAN: No NDI interface found for address "
1275 MACSTR, MAC2STR(ndi_addr));
1276 return -1;
1277 }
1278
1279 /* If the NDI GTK is not installed yet, RSC is 0 */
1280 if (!wpa_s->ndi_gtk.id) {
1281 os_memset(seq, 0, WPA_KEY_RSC_LEN);
1282 return 0;
1283 }
1284 }
1285
1286 return wpa_drv_get_seqnum(wpa_s, NULL, key_idx, seq);
1287 }
1288
1289
wpas_nan_get_peer_inactivity(void * ctx,const u8 * local_ndi,const u8 * peer_ndi)1290 static int wpas_nan_get_peer_inactivity(void *ctx, const u8 *local_ndi,
1291 const u8 *peer_ndi)
1292 {
1293 struct wpa_supplicant *wpa_s = ctx;
1294
1295 wpa_s = wpas_nan_get_ndi_iface(wpa_s, local_ndi);
1296 if (!wpa_s) {
1297 wpa_printf(MSG_DEBUG,
1298 "NAN: No NDI interface found for address " MACSTR,
1299 MAC2STR(local_ndi));
1300 return -1;
1301 }
1302
1303 return wpa_drv_get_inact_sec(wpa_s, peer_ndi);
1304 }
1305
1306
wpas_nan_init(struct wpa_supplicant * wpa_s)1307 int wpas_nan_init(struct wpa_supplicant *wpa_s)
1308 {
1309 struct nan_config nan;
1310
1311 if (!(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SUPPORT_NAN) ||
1312 !(wpa_s->nan_capa.drv_flags &
1313 WPA_DRIVER_FLAGS_NAN_SUPPORT_SYNC_CONFIG)) {
1314 wpa_printf(MSG_INFO, "NAN: Driver does not support NAN");
1315 return -1;
1316 }
1317
1318 os_memset(&nan, 0, sizeof(nan));
1319 nan.cb_ctx = wpa_s;
1320 os_memcpy(nan.nmi_addr, wpa_s->own_addr, ETH_ALEN);
1321
1322 nan.start = wpas_nan_start_cb;
1323 nan.stop = wpas_nan_stop_cb;
1324 nan.update_config = wpas_nan_update_config_cb;
1325
1326 /* NDP and bootstrapping enabled */
1327 if (wpa_s->nan_capa.drv_flags & WPA_DRIVER_FLAGS_NAN_SUPPORT_NDP) {
1328 #ifdef CONFIG_PASN
1329 wpa_printf(MSG_DEBUG, "NAN: Pairing support enabled");
1330 nan.send_pasn = wpas_nan_pasn_send_cb;
1331 nan.pairing_result_cb = wpas_nan_pasn_auth_status_cb;
1332 nan.update_pairing_credentials =
1333 wpas_nan_update_pairing_credentials_cb;
1334 nan.get_npk_akmp = wpas_nan_get_npk_akmp_cb;
1335 nan.pairing_request = wpas_nan_pasn_pairing_request_cb;
1336 nan.pairing_cfg.pairing_setup = true;
1337 nan.pairing_cfg.npk_caching = true;
1338 nan.pairing_cfg.pairing_verification = true;
1339 nan.pairing_cfg.cipher_suites = NAN_PAIRING_PASN_128 |
1340 NAN_PAIRING_PASN_256;
1341 #endif /* CONFIG_PASN */
1342
1343 wpa_printf(MSG_DEBUG, "NAN: NDP support enabled");
1344
1345 nan.ndp_action_notif = wpas_nan_ndp_action_notif_cb;
1346 nan.ndp_connected = wpas_nan_ndp_connected_cb;
1347 nan.ndp_disconnected = wpas_nan_ndp_disconnected_cb;
1348 nan.send_naf = wpas_nan_send_naf_cb;
1349 nan.get_chans = wpas_nan_get_chans_cb;
1350 nan.is_valid_publish_id = wpas_nan_is_valid_publish_id_cb;
1351 nan.set_peer_schedule = wpas_nan_set_peer_schedule_cb;
1352 nan.set_group_key = wpas_nan_set_group_key_cb;
1353 nan.get_seqnum = wpas_nan_get_seqnum_cb;
1354 nan.schedule_changed = wpas_nan_schedule_changed_cb;
1355
1356 wpa_printf(MSG_DEBUG, "NAN: Bootstrap support enabled");
1357 nan.bootstrap_request = wpas_nan_bootstrap_request_cb;
1358 nan.bootstrap_completed = wpas_nan_bootstrap_completed_cb;
1359 nan.transmit_followup = wpas_nan_transmit_followup_cb;
1360 nan.get_supported_bootstrap_methods =
1361 wpas_nan_get_service_bootstrap_methods;
1362
1363 if (wpa_s->driver->get_inact_sec)
1364 nan.get_peer_inactivity = wpas_nan_get_peer_inactivity;
1365 else
1366 wpa_printf(MSG_DEBUG,
1367 "NAN: Driver does not support getting peer inactivity");
1368
1369 /*
1370 * Set the group security capabilities based on driver support
1371 */
1372 if ((wpa_s->drv_enc & (WPA_DRIVER_CAPA_ENC_CCMP |
1373 WPA_DRIVER_CAPA_ENC_GCMP_256)) &&
1374 (wpa_s->drv_enc & (WPA_DRIVER_CAPA_ENC_BIP |
1375 WPA_DRIVER_CAPA_ENC_BIP_GMAC_256))) {
1376 /*
1377 * By default, use BIP-CMAC-128 cipher suite for
1378 * group keys for maximum compatibility.
1379 */
1380 if (!(wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_BIP))
1381 nan.security_capab |=
1382 NAN_CS_INFO_CAPA_IGTK_USE_NCS_BIP_GMAC_256;
1383
1384 /*
1385 * By default enable only GTK/IGTK support. Beacon
1386 * protection support can be enabled separately
1387 */
1388 nan.security_capab |=
1389 NAN_CS_INFO_CAPA_GTK_SUPP_NO_BIGTK <<
1390 NAN_CS_INFO_CAPA_GTK_SUPP_POS;
1391 }
1392
1393 wpa_printf(MSG_DEBUG, "NAN: security capabilities=0x%02x",
1394 nan.security_capab);
1395 }
1396
1397 nan.dev_capa.cdw_info =
1398 ((1 << NAN_CDW_INFO_2G_POS) & NAN_CDW_INFO_2G_MASK) |
1399 ((1 << NAN_CDW_INFO_5G_POS) & NAN_CDW_INFO_5G_MASK);
1400
1401 /*
1402 * Wi-Fi Aware spec v4.0, Table 80 defines the 2.4 GHz and 5 GHz CDW
1403 * Override Map ID fields as mandatory without any option to indicate
1404 * "applies for all" as in other places in the specification that use
1405 * map_ids. At this stage we don't have a local schedule yet, so we will
1406 * be referencing non-existent map_id.
1407 *
1408 * In case of a single radio devices all maps will be using map_id 1,
1409 * so we can already configure it. Otherwise, we have no choice but to
1410 * leave it unassigned and let this field be updated when the schedule
1411 * is configured.
1412 *
1413 * TODO: Dual radio devices may want to properly query this information
1414 * from the driver/device.
1415 */
1416 if (wpa_s->nan_capa.num_radios == 1) {
1417 nan.dev_capa.cdw_info |= 0x1 << NAN_CDW_INFO_2G_OVERRIDE_POS;
1418 nan.dev_capa.cdw_info |= 0x1 << NAN_CDW_INFO_5G_OVERRIDE_POS;
1419 }
1420
1421 nan.dev_capa.supported_bands = NAN_DEV_CAPA_SBAND_2G;
1422 if (wpa_s->nan_capa.drv_flags &
1423 WPA_DRIVER_FLAGS_NAN_SUPPORT_DUAL_BAND)
1424 nan.dev_capa.supported_bands |= NAN_DEV_CAPA_SBAND_5G;
1425
1426 nan.dev_capa.op_mode = wpa_s->nan_capa.op_modes;
1427 nan.dev_capa.n_antennas = wpa_s->nan_capa.num_antennas;
1428 nan.dev_capa.channel_switch_time =
1429 wpa_s->nan_capa.max_channel_switch_time;
1430 nan.dev_capa.capa = wpa_s->nan_capa.dev_capa;
1431 nan.dev_capa.capa |= NAN_DEV_CAPA_NDPE_ATTR_SUPP;
1432
1433 nan.supported_bootstrap_methods = DEFAULT_NAN_SUPP_PBM;
1434 nan.auto_accept_bootstrap_methods = DEFAULT_NAN_AUTO_ACCEPT_PBM;
1435 nan.bootstrap_comeback_timeout = DEFAULT_NAN_BOOTSTRAP_COMEBACK_TIMEOUT;
1436
1437 if (os_get_random(nan.nik, NAN_NIK_LEN) < 0) {
1438 wpa_printf(MSG_INFO, "NAN: Failed to get random data for NIK");
1439 return -1;
1440 }
1441
1442 nan.nik_lifetime = NAN_NIK_LIFETIME_DEFAULT;
1443 nan.max_ndl_idle_period = DEFAULT_NAN_MAX_NDL_IDLE_PERIOD;
1444
1445 wpa_s->nan = nan_init(&nan);
1446 if (!wpa_s->nan) {
1447 wpa_printf(MSG_INFO, "NAN: Failed to init");
1448 return -1;
1449 }
1450
1451 /* Set the default configuration */
1452 os_memset(&wpa_s->nan_cluster_config, 0,
1453 sizeof(wpa_s->nan_cluster_config));
1454
1455 wpa_s->nan_cluster_config.master_pref = DEFAULT_NAN_MASTER_PREF;
1456 wpa_s->nan_cluster_config.dual_band = DEFAULT_NAN_DUAL_BAND;
1457 os_memset(wpa_s->nan_cluster_config.cluster_id, 0, ETH_ALEN);
1458 wpa_s->nan_cluster_config.scan_period = DEFAULT_NAN_SCAN_PERIOD;
1459 wpa_s->nan_cluster_config.scan_dwell_time = DEFAULT_NAN_SCAN_DWELL_TIME;
1460 wpa_s->nan_cluster_config.discovery_beacon_interval =
1461 DEFAULT_NAN_DISCOVERY_BEACON_INTERVAL;
1462
1463 wpa_s->nan_cluster_config.low_band_cfg.frequency =
1464 DEFAULT_NAN_LOW_BAND_FREQUENCY;
1465 wpa_s->nan_cluster_config.low_band_cfg.rssi_close =
1466 DEFAULT_NAN_RSSI_CLOSE;
1467 wpa_s->nan_cluster_config.low_band_cfg.rssi_middle =
1468 DEFAULT_NAN_RSSI_MIDDLE;
1469 wpa_s->nan_cluster_config.low_band_cfg.awake_dw_interval = true;
1470
1471 wpa_s->nan_cluster_config.high_band_cfg.frequency =
1472 DEFAULT_NAN_HIGH_BAND_FREQUENCY;
1473 wpa_s->nan_cluster_config.high_band_cfg.rssi_close =
1474 DEFAULT_NAN_RSSI_CLOSE;
1475 wpa_s->nan_cluster_config.high_band_cfg.rssi_middle =
1476 DEFAULT_NAN_RSSI_MIDDLE;
1477 wpa_s->nan_cluster_config.high_band_cfg.awake_dw_interval = true;
1478
1479 /* TODO: Optimize this, so that the notification are enabled only when
1480 * needed, i.e., when the DE is configured with unsolicited publish or
1481 * active subscribe
1482 */
1483 wpa_s->nan_cluster_config.enable_dw_notif =
1484 !!(wpa_s->nan_capa.drv_flags &
1485 WPA_DRIVER_FLAGS_NAN_SUPPORT_USERSPACE_DE);
1486
1487 wpa_s->nan_supported_csids = BIT(NAN_CS_SK_CCM_128) |
1488 BIT(NAN_CS_SK_GCM_256);
1489 #ifdef CONFIG_PASN
1490 wpa_s->nan_supported_csids |= BIT(NAN_CS_PK_PASN_128) |
1491 BIT(NAN_CS_PK_PASN_256);
1492 #endif /* CONFIG_PASN */
1493
1494 return 0;
1495 }
1496
1497
wpas_nan_deinit(struct wpa_supplicant * wpa_s)1498 void wpas_nan_deinit(struct wpa_supplicant *wpa_s)
1499 {
1500 int i;
1501
1502 if (!wpa_s || !wpa_s->nan)
1503 return;
1504
1505 for (i = 0; i < MAX_NAN_RADIOS; i++)
1506 clear_sched_config(&wpa_s->nan_sched[i]);
1507
1508 nan_deinit(wpa_s->nan);
1509 os_free(wpa_s->nan_disallowed_freqs.range);
1510 os_memset(&wpa_s->nan_disallowed_freqs, 0,
1511 sizeof(wpa_s->nan_disallowed_freqs));
1512 clear_sched_config(&wpa_s->nan_sched_update.sched);
1513 wpabuf_free(wpa_s->nan_ulw_attr);
1514 wpa_s->nan_ulw_attr = NULL;
1515
1516 os_free(wpa_s->nan_override_potential_avail.chans);
1517 wpa_s->nan_override_potential_avail.chans = NULL;
1518 wpa_s->nan_override_potential_avail.n_chans = 0;
1519
1520 wpa_s->nan = NULL;
1521 }
1522
1523
wpas_nan_ready(struct wpa_supplicant * wpa_s)1524 static bool wpas_nan_ready(struct wpa_supplicant *wpa_s)
1525 {
1526 return wpa_s->nan_mgmt && wpa_s->nan && wpa_s->nan_de &&
1527 wpa_s->wpa_state != WPA_INTERFACE_DISABLED;
1528 }
1529
1530
wpas_nan_ndp_allowed(struct wpa_supplicant * wpa_s)1531 static bool wpas_nan_ndp_allowed(struct wpa_supplicant *wpa_s)
1532 {
1533 return wpas_nan_ready(wpa_s) &&
1534 (wpa_s->nan_capa.drv_flags & WPA_DRIVER_FLAGS_NAN_SUPPORT_NDP);
1535 }
1536
1537
1538 /* Join a cluster using current configuration */
wpas_nan_start(struct wpa_supplicant * wpa_s)1539 int wpas_nan_start(struct wpa_supplicant *wpa_s)
1540 {
1541 if (!wpas_nan_ready(wpa_s))
1542 return -1;
1543
1544 return nan_start(wpa_s->nan, &wpa_s->nan_cluster_config);
1545 }
1546
1547
wpas_nan_stop(struct wpa_supplicant * wpa_s)1548 int wpas_nan_stop(struct wpa_supplicant *wpa_s)
1549 {
1550 if (!wpas_nan_ready(wpa_s))
1551 return -1;
1552
1553 nan_stop(wpa_s->nan);
1554
1555 return 0;
1556 }
1557
1558
wpas_nan_flush(struct wpa_supplicant * wpa_s)1559 void wpas_nan_flush(struct wpa_supplicant *wpa_s)
1560 {
1561 if (!wpas_nan_ready(wpa_s))
1562 return;
1563
1564 nan_flush(wpa_s->nan);
1565 }
1566
1567
wpas_nan_parse_override_potential_avail(struct wpa_supplicant * wpa_s,char * param)1568 static int wpas_nan_parse_override_potential_avail(struct wpa_supplicant *wpa_s,
1569 char *param)
1570 {
1571 struct nan_channel_info *chans = NULL;
1572 unsigned int n_chans = 0, capacity = 0;
1573 char *pos, *end;
1574
1575 /* Empty string clears the override */
1576 if (*param == '\0') {
1577 wpa_printf(MSG_DEBUG,
1578 "NAN: Clearing override potential availability");
1579 goto out;
1580 }
1581
1582 /* Parse format: <op_class:0xbitmap:pref>,... */
1583 pos = param;
1584 while (pos && *pos) {
1585 u8 op_class, pref;
1586 u16 bitmap;
1587 const struct oper_class_map *o = NULL;
1588 int op, idx;
1589
1590 if (sscanf(pos, "%hhu:0x%hx:%hhu", &op_class, &bitmap, &pref) !=
1591 3) {
1592 wpa_printf(MSG_INFO,
1593 "NAN: Invalid override_potential_availability format at '%s'",
1594 pos);
1595 os_free(chans);
1596 return -1;
1597 }
1598
1599 if (!op_class || op_class > 129 || pref > 3) {
1600 wpa_printf(MSG_INFO,
1601 "NAN: Invalid values in override_potential_availability");
1602 os_free(chans);
1603 return -1;
1604 }
1605
1606 /* Find the operating class in global_op_class */
1607 for (op = 0; global_op_class[op].op_class; op++) {
1608 if (global_op_class[op].op_class == op_class) {
1609 o = &global_op_class[op];
1610 break;
1611 }
1612 }
1613
1614 if (!o) {
1615 wpa_printf(MSG_INFO,
1616 "NAN: Unknown operating class %d in override_potential_availability",
1617 op_class);
1618 os_free(chans);
1619 return -1;
1620 }
1621
1622 /* Iterate through bitmap bits */
1623 for (idx = 0; idx < 16 && bitmap; idx++) {
1624 u8 chan, center;
1625
1626 if (!(bitmap & BIT(idx)))
1627 continue;
1628
1629 chan = op_class_idx_to_chan(o, idx);
1630 if (!chan) {
1631 wpa_printf(MSG_INFO,
1632 "NAN: Invalid channel index %d for op_class %d",
1633 idx, op_class);
1634 os_free(chans);
1635 return -1;
1636 }
1637
1638 /*
1639 * Validate the channel. For zero preference only
1640 * check the very basic validity, but accept
1641 * "NOT ALLOWED" channels, as the user might want
1642 * to explicitly mark them as unavailable.
1643 */
1644 if (pref && !wpas_nan_valid_chan(wpa_s, o->mode, chan,
1645 o->bw, o->op_class,
1646 ¢er)) {
1647 wpa_printf(MSG_INFO,
1648 "NAN: Channel %d (op_class %d) is not a valid NAN channel",
1649 chan, op_class);
1650 os_free(chans);
1651 return -1;
1652 }
1653
1654 if (!pref) {
1655 int width;
1656
1657 center = get_center_and_width(o->bw, chan,
1658 &width);
1659 if (!center) {
1660 wpa_printf(MSG_INFO,
1661 "NAN: Invalid channel %d for op_class %d",
1662 chan, op_class);
1663 os_free(chans);
1664 return -1;
1665 }
1666 }
1667
1668 /* Expand array if needed */
1669 if (n_chans >= capacity) {
1670 struct nan_channel_info *new_chans;
1671
1672 capacity = capacity ? capacity * 2 : 4;
1673 new_chans = os_realloc_array(chans, capacity,
1674 sizeof(*chans));
1675 if (!new_chans) {
1676 wpa_printf(MSG_INFO,
1677 "NAN: Memory allocation failed");
1678 os_free(chans);
1679 return -1;
1680 }
1681 chans = new_chans;
1682 }
1683
1684 /* Use center for wide channels */
1685 chans[n_chans].op_class = op_class;
1686 chans[n_chans].channel = (o->bw == BW80 ||
1687 o->bw == BW160) ?
1688 center : chan;
1689 chans[n_chans].pref = pref;
1690 n_chans++;
1691 }
1692
1693 /* Move to next entry */
1694 end = os_strchr(pos, ',');
1695 if (end)
1696 pos = end + 1;
1697 else
1698 break;
1699 }
1700
1701 /* Sort channels by preference (higher preference first) */
1702 if (n_chans > 1)
1703 qsort(chans, n_chans, sizeof(*chans), nan_chan_info_cmp);
1704
1705 out:
1706 /* Free previous configuration */
1707 os_free(wpa_s->nan_override_potential_avail.chans);
1708 wpa_s->nan_override_potential_avail.chans = chans;
1709 wpa_s->nan_override_potential_avail.n_chans = n_chans;
1710 wpa_s->schedule_sequence_id++;
1711
1712 wpa_printf(MSG_DEBUG,
1713 "NAN: Configured %u override potential availability channels",
1714 n_chans);
1715 return 0;
1716 }
1717
1718
wpas_nan_set(struct wpa_supplicant * wpa_s,char * cmd)1719 int wpas_nan_set(struct wpa_supplicant *wpa_s, char *cmd)
1720 {
1721 struct nan_cluster_config *config = &wpa_s->nan_cluster_config;
1722 char *param = os_strchr(cmd, ' ');
1723
1724 if (!param)
1725 return -1;
1726
1727 *param++ = '\0';
1728
1729 #define NAN_PARSE_INT(_str, _min, _max) \
1730 if (os_strcmp(#_str, cmd) == 0) { \
1731 int val = atoi(param); \
1732 \
1733 if (val < (_min) || val > (_max)) { \
1734 wpa_printf(MSG_INFO, \
1735 "NAN: Invalid value for " #_str); \
1736 return -1; \
1737 } \
1738 config->_str = val; \
1739 return 0; \
1740 }
1741
1742 #define NAN_PARSE_BAND(_str) \
1743 if (os_strcmp(#_str, cmd) == 0) { \
1744 int a, b, c, d; \
1745 \
1746 if (sscanf(param, "%d,%d,%d,%d", &a, &b, &c, &d) != \
1747 4) { \
1748 wpa_printf(MSG_DEBUG, \
1749 "NAN: Invalid value for " #_str); \
1750 return -1; \
1751 } \
1752 \
1753 if (a < NAN_MIN_RSSI_CLOSE || \
1754 b < NAN_MIN_RSSI_MIDDLE || \
1755 a <= b) { \
1756 wpa_printf(MSG_DEBUG, \
1757 "NAN: Invalid value for " #_str); \
1758 return -1; \
1759 } \
1760 config->_str.rssi_close = a; \
1761 config->_str.rssi_middle = b; \
1762 config->_str.awake_dw_interval = c; \
1763 config->_str.disable_scan = !!d; \
1764 return 0; \
1765 }
1766
1767 /* 0 and 255 are reserved */
1768 NAN_PARSE_INT(master_pref, 1, 254);
1769 NAN_PARSE_INT(dual_band, 0, 1);
1770 NAN_PARSE_INT(scan_period, 0, 0xffff);
1771 NAN_PARSE_INT(scan_dwell_time, 10, 150);
1772 NAN_PARSE_INT(discovery_beacon_interval, 50, 200);
1773
1774 NAN_PARSE_BAND(low_band_cfg);
1775 NAN_PARSE_BAND(high_band_cfg);
1776
1777 if (os_strcmp("cluster_id", cmd) == 0) {
1778 u8 cluster_id[ETH_ALEN];
1779
1780 if (hwaddr_aton(param, cluster_id) < 0) {
1781 wpa_printf(MSG_INFO, "NAN: Invalid cluster ID");
1782 return -1;
1783 }
1784
1785 if (cluster_id[0] != 0x50 || cluster_id[1] != 0x6f ||
1786 cluster_id[2] != 0x9a || cluster_id[3] != 0x01) {
1787 wpa_printf(MSG_DEBUG, "NAN: Invalid cluster ID format");
1788 return -1;
1789 }
1790
1791 os_memcpy(config->cluster_id, cluster_id, ETH_ALEN);
1792 return 0;
1793 }
1794
1795 if (os_strcmp("max_bw", cmd) == 0) {
1796 wpa_s->nan_max_bw = atoi(param);
1797 return 0;
1798 }
1799
1800 if (os_strcmp("disallowed_freqs", cmd) == 0) {
1801 if (freq_range_list_parse(&wpa_s->nan_disallowed_freqs,
1802 param)) {
1803 wpa_printf(MSG_INFO,
1804 "NAN: Invalid disallowed_freqs value");
1805 return -1;
1806 }
1807
1808 return 0;
1809 }
1810
1811 if (os_strcmp("override_potential_availability", cmd) == 0)
1812 return wpas_nan_parse_override_potential_avail(wpa_s, param);
1813
1814 if (os_strcmp("bootstrap_config", cmd) == 0) {
1815 u16 supported_methods, auto_accept_methods, comeback_timeout;
1816
1817 if (sscanf(param, "%hx,%hx,%hu", &supported_methods,
1818 &auto_accept_methods, &comeback_timeout) != 3) {
1819 wpa_printf(MSG_INFO,
1820 "NAN: Invalid value for boostrap_config");
1821 return -1;
1822 }
1823
1824 return nan_set_bootstrap_configuration(wpa_s->nan,
1825 supported_methods,
1826 auto_accept_methods,
1827 comeback_timeout);
1828 }
1829
1830 #undef NAN_PARSE_INT
1831 #undef NAN_PARSE_BAND
1832
1833 #ifdef CONFIG_PASN
1834 #define NAN_PARSE_PAIRING_BOOL(_str) \
1835 if (os_strcmp(#_str, cmd) == 0) { \
1836 int val = atoi(param); \
1837 \
1838 if (val != 0 && val != 1) { \
1839 wpa_printf(MSG_INFO, \
1840 "NAN: Invalid value for " #_str); \
1841 return -1; \
1842 } \
1843 return nan_pairing_set_##_str(wpa_s->nan, val); \
1844 }
1845
1846 #define NAN_PARSE_PAIRING_INT(_str, _mask) \
1847 if (os_strcmp(#_str, cmd) == 0) { \
1848 unsigned int val = atoi(param); \
1849 \
1850 if ((val & (_mask)) != val) { \
1851 wpa_printf(MSG_INFO, \
1852 "NAN: Invalid value for " #_str); \
1853 return -1; \
1854 } \
1855 return nan_pairing_set_##_str(wpa_s->nan, val); \
1856 }
1857
1858 NAN_PARSE_PAIRING_BOOL(pairing_setup);
1859 NAN_PARSE_PAIRING_BOOL(npk_caching);
1860 NAN_PARSE_PAIRING_BOOL(pairing_verification);
1861 NAN_PARSE_PAIRING_INT(cipher_suites,
1862 NAN_PAIRING_PASN_128 | NAN_PAIRING_PASN_256);
1863 #undef NAN_PARSE_PAIRING_BOOL
1864 #undef NAN_PARSE_PAIRING_INT
1865
1866 if (os_strcmp("nik", cmd) == 0) {
1867 u8 nik[NAN_NIK_LEN];
1868 int res;
1869
1870 /* Parse NIK value (hex string) */
1871 if (hexstr2bin(param, nik, NAN_NIK_LEN) < 0) {
1872 wpa_printf(MSG_INFO, "NAN: Invalid NIK format");
1873 return -1;
1874 }
1875
1876 res = nan_pairing_set_nik(wpa_s->nan, nik, NAN_NIK_LEN);
1877 forced_memzero(nik, NAN_NIK_LEN);
1878 return res;
1879 }
1880
1881 if (os_strcmp("nik_lifetime", cmd) == 0) {
1882 u32 lifetime = atoi(param);
1883
1884 if (lifetime == 0) {
1885 wpa_printf(MSG_INFO, "NAN: Invalid NIK lifetime");
1886 return -1;
1887 }
1888
1889 return nan_pairing_set_nik_lifetime(wpa_s->nan, lifetime);
1890 }
1891 #endif /* CONFIG_PASN */
1892
1893 if (os_strcmp("mgmt_group_cipher", cmd) == 0) {
1894 int cipher;
1895
1896 if (os_strcmp(param, "BIP-CMAC-128") == 0) {
1897 if (!(wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_BIP)) {
1898 wpa_printf(MSG_INFO,
1899 "NAN: BIP-CMAC-128 not supported by the driver");
1900 return -1;
1901 }
1902
1903 cipher = WPA_CIPHER_AES_128_CMAC;
1904 } else if (os_strcmp(param, "BIP-GMAC-256") == 0) {
1905 if (!(wpa_s->drv_enc &
1906 WPA_DRIVER_CAPA_ENC_BIP_GMAC_256)) {
1907 wpa_printf(MSG_INFO,
1908 "NAN: BIP-CMAC-256 not supported by the driver");
1909 return -1;
1910 }
1911
1912 cipher = WPA_CIPHER_BIP_GMAC_256;
1913 } else {
1914 wpa_printf(MSG_INFO,
1915 "NAN: Unsupported mgmt_group_cipher value");
1916 return -1;
1917 }
1918
1919 return nan_set_mgmt_group_cipher(wpa_s->nan, cipher);
1920 }
1921
1922 if (os_strcmp("beacon_prot", cmd) == 0) {
1923 bool val = !!atoi(param);
1924
1925 if (val && !(wpa_s->nan_capa.drv_flags &
1926 WPA_DRIVER_FLAGS_NAN_SUPPORT_BEACON_PROT)) {
1927 wpa_printf(MSG_INFO,
1928 "NAN: Beacon protection not supported by the driver");
1929 return -1;
1930 }
1931
1932 if (nan_set_beacon_prot(wpa_s->nan, val) < 0)
1933 return -1;
1934
1935 return 0;
1936 }
1937
1938 #ifdef CONFIG_TESTING_OPTIONS
1939 if (os_strcmp("tx_mcast_follow_up_prot", cmd) == 0) {
1940 bool val = !!atoi(param);
1941
1942 nan_de_set_tx_mcast_follow_up_prot(wpa_s->nan_de, val);
1943 return 0;
1944 }
1945
1946 if (os_strcmp("force_conditional_sched", cmd) == 0) {
1947 wpa_s->nan_force_conditional_sched = !!atoi(param);
1948 return 0;
1949 }
1950 #endif /* CONFIG_TESTING_OPTIONS */
1951
1952 if (os_strcmp("max_ndl_idle_period", cmd) == 0) {
1953 u16 max_ndl_idle_period = atoi(param) & 0xffff;
1954
1955 return nan_set_max_ndl_idle_period(wpa_s->nan,
1956 max_ndl_idle_period);
1957 }
1958
1959 wpa_printf(MSG_INFO, "NAN: Unknown NAN_SET cmd='%s'", cmd);
1960 return -1;
1961 }
1962
1963
wpas_nan_update_conf(struct wpa_supplicant * wpa_s)1964 int wpas_nan_update_conf(struct wpa_supplicant *wpa_s)
1965 {
1966 if (!wpas_nan_ready(wpa_s))
1967 return -1;
1968
1969 wpa_printf(MSG_DEBUG, "NAN: Update NAN configuration");
1970 return nan_update_config(wpa_s->nan, &wpa_s->nan_cluster_config);
1971 }
1972
1973
nan_select_40mhz_channel(u8 chan,u8 * op_class,int * bw)1974 static u8 nan_select_40mhz_channel(u8 chan, u8 *op_class, int *bw)
1975 {
1976 int op;
1977
1978 for (op = 0; global_op_class[op].op_class; op++) {
1979 const struct oper_class_map *o = &global_op_class[op];
1980 int c;
1981
1982 /* No support for 40 MHz on 2.4 GHz */
1983 if (o->mode != HOSTAPD_MODE_IEEE80211A)
1984 continue;
1985
1986 /* Currently don't support NAN for 80+, 6 GHz, etc. */
1987 if (o->op_class > 129)
1988 continue;
1989
1990 if (o->bw != BW40MINUS && o->bw != BW40PLUS)
1991 continue;
1992
1993 for (c = o->min_chan; c <= o->max_chan; c += o->inc) {
1994 if (c != chan)
1995 continue;
1996
1997 *op_class = o->op_class;
1998 *bw = o->bw;
1999 if (o->bw == BW40MINUS)
2000 return chan - 2;
2001 else
2002 return chan + 2;
2003 }
2004 }
2005
2006 return 0;
2007 }
2008
2009
wpas_nan_select_channel_params(struct wpa_supplicant * wpa_s,int freq,int * center_freq1,int * center_freq2,int * bandwidth)2010 static int wpas_nan_select_channel_params(struct wpa_supplicant *wpa_s,
2011 int freq, int *center_freq1,
2012 int *center_freq2, int *bandwidth)
2013 {
2014 u8 chan, op_class, center;
2015 enum hostapd_hw_mode mode;
2016 int bw;
2017
2018 mode = ieee80211_freq_to_channel_ext(freq, 0, CONF_OPER_CHWIDTH_USE_HT,
2019 &op_class, &chan);
2020 if (mode == NUM_HOSTAPD_MODES) {
2021 wpa_printf(MSG_DEBUG, "NAN: Invalid frequency %d", freq);
2022 return -1;
2023 }
2024
2025 if (!wpas_nan_valid_chan(wpa_s, mode, chan, BW20, op_class, ¢er)) {
2026 wpa_printf(MSG_DEBUG,
2027 "NAN: Channel not valid for NAN (freq = %d)",
2028 freq);
2029 return -1;
2030 }
2031
2032 /* On 2.4 GHz use 20 MHz channels */
2033 if (freq >= 2412 && freq <= 2484)
2034 goto out;
2035
2036 /* TODO: Add support for NAN on other bands */
2037 if (freq < 5180 || freq > 5885) {
2038 wpa_printf(MSG_DEBUG, "NAN: Unsupported frequency %d", freq);
2039 return -1;
2040 }
2041
2042 if (wpas_nan_valid_chan(wpa_s, mode, chan, BW160, 129, ¢er)) {
2043 *center_freq1 = ieee80211_chan_to_freq(NULL, op_class, center);
2044 *center_freq2 = 0;
2045 *bandwidth = 160;
2046 return 0;
2047 }
2048
2049 if (wpas_nan_valid_chan(wpa_s, mode, chan, BW80, 128, ¢er)) {
2050 *center_freq1 = ieee80211_chan_to_freq(NULL, op_class, center);
2051 *center_freq2 = 0;
2052 *bandwidth = 80;
2053 return 0;
2054 }
2055
2056 if (nan_select_40mhz_channel(chan, &op_class, &bw) &&
2057 wpas_nan_valid_chan(wpa_s, mode, center, bw, op_class,
2058 ¢er)) {
2059 *center_freq1 = ieee80211_chan_to_freq(NULL, op_class,
2060 center);
2061 *center_freq2 = 0;
2062 *bandwidth = 40;
2063 return 0;
2064 }
2065
2066 out:
2067 /* Fallback to 20 MHz */
2068 *center_freq1 = freq;
2069 *center_freq2 = 0;
2070 *bandwidth = 20;
2071 return 0;
2072 }
2073
2074
nan_dump_sched_config(const char * title,struct nan_schedule_config * sched_cfg)2075 static void nan_dump_sched_config(const char *title,
2076 struct nan_schedule_config *sched_cfg)
2077 {
2078 int i;
2079
2080 wpa_printf(MSG_DEBUG, "%s: num_channels=%d", title,
2081 sched_cfg->num_channels);
2082 for (i = 0; i < sched_cfg->num_channels; i++) {
2083 wpa_printf(MSG_DEBUG,
2084 " Channel %d: freq=%d center_freq1=%d center_freq2=%d bandwidth=%d time_bitmap_len=%zu",
2085 i + 1,
2086 sched_cfg->channels[i].freq,
2087 sched_cfg->channels[i].center_freq1,
2088 sched_cfg->channels[i].center_freq2,
2089 sched_cfg->channels[i].bandwidth,
2090 wpabuf_len(sched_cfg->channels[i].time_bitmap));
2091 }
2092 }
2093
2094
2095 static void wpas_nan_fill_ndp_schedule(struct wpa_supplicant *wpa_s,
2096 struct nan_schedule *sched);
2097
wpas_nan_update_local_schedule(struct wpa_supplicant * wpa_s)2098 static void wpas_nan_update_local_schedule(struct wpa_supplicant *wpa_s)
2099 {
2100 struct nan_schedule sched;
2101
2102 wpas_nan_fill_ndp_schedule(wpa_s, &sched);
2103 nan_local_sched_update(wpa_s->nan, &sched);
2104 }
2105
2106
2107 /* Parse format NAN_SCHED_CONFIG_MAP map_id=<id> [freq:bitmap_hex]..
2108 * If no bitmaps provided - clear the map */
wpas_nan_sched_config_map(struct wpa_supplicant * wpa_s,const char * cmd)2109 int wpas_nan_sched_config_map(struct wpa_supplicant *wpa_s, const char *cmd)
2110 {
2111 struct nan_schedule_config *sched_cfg = &wpa_s->nan_sched_update.sched;
2112 struct nan_schedule_config old_sched_cfg;
2113 struct nan_schedule sched;
2114 char *token, *context = NULL;
2115 u8 map_id;
2116 char *pos;
2117 int *shared_freqs;
2118 int shared_freqs_count, unused_freqs_count, ret = -1;
2119 struct bitfield *bf_total;
2120 unsigned int expected_bitmap_len;
2121 bool cdw_overwrite_2g = false, cdw_overwrite_5g = false;
2122
2123 if (!wpas_nan_ndp_allowed(wpa_s))
2124 return -1;
2125
2126 if (sched_cfg->deferred) {
2127 wpa_printf(MSG_DEBUG,
2128 "NAN: Previous schedule update is still pending");
2129 return -1;
2130 }
2131
2132 if (os_strncmp(cmd, "map_id=", 7) != 0) {
2133 wpa_printf(MSG_INFO, "NAN: Invalid schedule map format");
2134 return -1;
2135 }
2136
2137 map_id = atoi(cmd + 7);
2138
2139 if (!map_id || map_id >= MAX_NAN_RADIOS) {
2140 wpa_printf(MSG_INFO, "NAN: Invalid map_id %d", map_id);
2141 return -1;
2142 }
2143
2144 if (map_id > wpa_s->nan_capa.num_radios) {
2145 wpa_printf(MSG_INFO,
2146 "NAN: map_id %d exceeds number of supported NAN radios %d",
2147 map_id, wpa_s->nan_capa.num_radios);
2148 return -1;
2149 }
2150
2151 if (!wpa_s->nan_capa.schedule_period ||
2152 !wpa_s->nan_capa.slot_duration) {
2153 wpa_printf(MSG_INFO,
2154 "NAN: Driver doesn't advertise support for NAN scheduling");
2155 return -1;
2156 }
2157
2158 expected_bitmap_len = (wpa_s->nan_capa.schedule_period /
2159 wpa_s->nan_capa.slot_duration + 7) / 8;
2160
2161 os_memset(sched_cfg, 0, sizeof(*sched_cfg));
2162
2163 pos = os_strchr(cmd + 7, ' ');
2164 if (!pos) {
2165 wpa_printf(MSG_INFO,
2166 "NAN: Missing freq:timebitmap pairs - cleanup schedule");
2167 ret = wpa_drv_nan_config_schedule(wpa_s, map_id, sched_cfg);
2168 if (!ret) {
2169 clear_sched_config(&wpa_s->nan_sched[map_id - 1]);
2170 wpas_nan_update_local_schedule(wpa_s);
2171 }
2172
2173 return ret;
2174 }
2175
2176 shared_freqs = os_calloc(wpa_s->num_multichan_concurrent,
2177 sizeof(int));
2178 if (!shared_freqs) {
2179 wpa_printf(MSG_INFO,
2180 "NAN: Failed to allocate memory for shared freqs");
2181 return -1;
2182 }
2183
2184 shared_freqs_count =
2185 get_shared_radio_freqs(wpa_s, shared_freqs,
2186 wpa_s->num_multichan_concurrent,
2187 false);
2188
2189 unused_freqs_count = wpa_s->nan_capa.sched_chans - shared_freqs_count;
2190
2191 bf_total = bitfield_alloc(wpa_s->nan_capa.schedule_period /
2192 wpa_s->nan_capa.slot_duration);
2193 if (!bf_total) {
2194 wpa_printf(MSG_INFO,
2195 "NAN: Failed to allocate bitfield for total schedule");
2196 goto out;
2197 }
2198
2199 /* Parse freq:timebitmap pairs and optional CDW overwrite flags */
2200 pos++;
2201 while ((token = str_token(pos, " ", &context))) {
2202 if (os_strcmp(token, "cdw_overwrite_low_band") == 0) {
2203 cdw_overwrite_2g = true;
2204 continue;
2205 }
2206 if (os_strcmp(token, "cdw_overwrite_high_band") == 0) {
2207 cdw_overwrite_5g = true;
2208 continue;
2209 }
2210 int j, i = sched_cfg->num_channels;
2211 struct bitfield *bf_chan = NULL;
2212 char *colon = os_strchr(token, ':');
2213 struct nan_sched_chan chan;
2214 struct nan_chan_entry *chan_entry;
2215
2216 if (i >= wpa_s->nan_capa.sched_chans) {
2217 wpa_printf(MSG_INFO,
2218 "NAN: Exceeded max channels per radio %u",
2219 wpa_s->nan_capa.sched_chans);
2220 goto out;
2221 }
2222
2223 if (!colon) {
2224 wpa_printf(MSG_INFO,
2225 "NAN: Invalid freq:timebitmap format");
2226 goto out;
2227 }
2228
2229 sched_cfg->channels[i].freq = atoi(token);
2230 if (sched_cfg->channels[i].freq <= 0) {
2231 wpa_printf(MSG_INFO, "NAN: Invalid frequency %d",
2232 sched_cfg->channels[i].freq);
2233 goto out;
2234 }
2235
2236 for (j = 0; j < i; j++) {
2237 if (sched_cfg->channels[j].freq ==
2238 sched_cfg->channels[i].freq) {
2239 wpa_printf(MSG_INFO,
2240 "NAN: Duplicate frequency %d",
2241 sched_cfg->channels[i].freq);
2242 goto out;
2243 }
2244 }
2245
2246 if (wpas_nan_select_channel_params(
2247 wpa_s, sched_cfg->channels[i].freq,
2248 &sched_cfg->channels[i].center_freq1,
2249 &sched_cfg->channels[i].center_freq2,
2250 &sched_cfg->channels[i].bandwidth)) {
2251 wpa_printf(MSG_INFO,
2252 "NAN: Failed to select channel params for freq %d",
2253 sched_cfg->channels[i].freq);
2254 goto out;
2255 }
2256
2257 if (!int_array_includes(shared_freqs,
2258 sched_cfg->channels[i].freq)) {
2259 if (!unused_freqs_count) {
2260 wpa_printf(MSG_INFO,
2261 "NAN: No unused radio frequency available for freq %d",
2262 sched_cfg->channels[i].freq);
2263 goto out;
2264 }
2265
2266 unused_freqs_count--;
2267 }
2268
2269 sched_cfg->channels[i].time_bitmap =
2270 wpabuf_parse_bin(colon + 1);
2271 if (!sched_cfg->channels[i].time_bitmap) {
2272 wpa_printf(MSG_INFO, "NAN: Invalid time bitmap");
2273 goto out;
2274 }
2275
2276 sched_cfg->num_channels++;
2277
2278 if (wpabuf_len(sched_cfg->channels[i].time_bitmap) !=
2279 expected_bitmap_len) {
2280 wpa_printf(MSG_INFO,
2281 "NAN: Invalid bitmap length (%zu) for period=%d, slot length=%d",
2282 wpabuf_len(sched_cfg->channels[i].time_bitmap),
2283 wpa_s->nan_capa.schedule_period,
2284 wpa_s->nan_capa.slot_duration);
2285 goto out;
2286 }
2287
2288 bf_chan = bitfield_alloc_data(
2289 wpabuf_head(sched_cfg->channels[i].time_bitmap),
2290 wpabuf_len(sched_cfg->channels[i].time_bitmap));
2291 if (!bf_chan) {
2292 wpa_printf(MSG_INFO,
2293 "NAN: Failed to allocate bitfield for channel schedule");
2294 goto out;
2295 }
2296
2297 if (bitfield_intersects(bf_total, bf_chan)) {
2298 wpa_printf(MSG_INFO,
2299 "NAN: Overlapping time bitmap detected for freq %d",
2300 sched_cfg->channels[i].freq);
2301 bitfield_free(bf_chan);
2302 goto out;
2303 }
2304
2305 /* Extract RX NSS from upper nibble of num_antennas */
2306 sched_cfg->channels[i].rx_nss =
2307 (wpa_s->nan_capa.num_antennas >> 4) & 0x0f;
2308
2309 bitfield_union_in_place(bf_total, bf_chan);
2310 bitfield_free(bf_chan);
2311
2312 chan.freq = sched_cfg->channels[i].freq;
2313 chan.center_freq1 = sched_cfg->channels[i].center_freq1;
2314 chan.center_freq2 = sched_cfg->channels[i].center_freq2;
2315 chan.bandwidth = sched_cfg->channels[i].bandwidth;
2316 chan_entry = (struct nan_chan_entry *)
2317 &sched_cfg->channels[i].chan_entry;
2318 if (nan_get_chan_entry(wpa_s->nan, &chan, chan_entry)) {
2319 wpa_printf(MSG_INFO,
2320 "NAN: Failed to get channel entry for freq %d",
2321 sched_cfg->channels[i].freq);
2322 goto out;
2323 }
2324 }
2325
2326 sched_cfg->avail_attr = wpabuf_alloc(NAN_AVAIL_ATTR_MAX_LEN);
2327 if (!sched_cfg->avail_attr) {
2328 wpa_printf(MSG_INFO,
2329 "NAN: Failed to allocate memory for Availability attribute");
2330 ret = -1;
2331 goto out;
2332 }
2333
2334 /* Keep previous schedule configuration as we may need to restore it */
2335 os_memcpy(&old_sched_cfg, &wpa_s->nan_sched[map_id - 1],
2336 sizeof(old_sched_cfg));
2337
2338 os_memcpy(&wpa_s->nan_sched[map_id - 1], sched_cfg, sizeof(*sched_cfg));
2339 wpas_nan_fill_ndp_schedule(wpa_s, &sched);
2340
2341 ret = nan_convert_sched_to_avail_attrs(wpa_s->nan,
2342 wpa_s->schedule_sequence_id + 1,
2343 BIT(map_id),
2344 sched.n_chans, sched.chans,
2345 sched_cfg->avail_attr,
2346 false);
2347
2348 /* Restore previous schedule configuration */
2349 os_memcpy(&wpa_s->nan_sched[map_id - 1], &old_sched_cfg,
2350 sizeof(old_sched_cfg));
2351 if (ret < 0) {
2352 wpa_printf(MSG_INFO,
2353 "NAN: Failed to convert schedule to Availability Attributes for map_id %d",
2354 map_id);
2355 goto out;
2356 }
2357
2358 if (nan_has_active_ndp(wpa_s->nan)) {
2359 wpa_printf(MSG_DEBUG, "NAN: Set schedule config as deferred");
2360 sched_cfg->deferred = true;
2361 wpa_s->nan_sched_update.map_id = map_id;
2362 nan_set_sched_update_pending(wpa_s->nan, true);
2363 }
2364
2365 nan_dump_sched_config("NAN: Set schedule config", sched_cfg);
2366 ret = wpa_drv_nan_config_schedule(wpa_s, map_id, sched_cfg);
2367 if (ret < 0) {
2368 wpa_printf(MSG_INFO,
2369 "NAN: Failed to configure NAN schedule map_id %d",
2370 map_id);
2371 os_memcpy(&wpa_s->nan_sched[map_id - 1], &old_sched_cfg,
2372 sizeof(old_sched_cfg));
2373 nan_set_sched_update_pending(wpa_s->nan, false);
2374 goto out;
2375 }
2376
2377 if (!sched_cfg->deferred) {
2378 /* Store the configured schedule */
2379 wpa_s->schedule_sequence_id++;
2380 clear_sched_config(&wpa_s->nan_sched[map_id - 1]);
2381 os_memcpy(&wpa_s->nan_sched[map_id - 1], sched_cfg,
2382 sizeof(*sched_cfg));
2383 os_memset(sched_cfg, 0, sizeof(*sched_cfg));
2384 wpas_nan_update_local_schedule(wpa_s);
2385 }
2386
2387 /* Update CDW overwrite map_id for the specified band */
2388 if (cdw_overwrite_2g || cdw_overwrite_5g)
2389 nan_set_cdw_overwrite(wpa_s->nan,
2390 cdw_overwrite_2g ? map_id : -1,
2391 cdw_overwrite_5g ? map_id : -1);
2392
2393 out:
2394 os_free(bf_total);
2395 os_free(shared_freqs);
2396 if (ret)
2397 clear_sched_config(sched_cfg);
2398
2399 return ret;
2400 }
2401
2402
wpas_nan_build_ndp_elems(struct wpa_supplicant * wpa_s)2403 static struct wpabuf * wpas_nan_build_ndp_elems(struct wpa_supplicant *wpa_s)
2404 {
2405 struct ieee80211_ht_capabilities *ht_cap;
2406 struct ieee80211_vht_capabilities *vht_cap;
2407 size_t len;
2408 struct wpabuf *buf;
2409
2410 /* Include HT and VHT Capability elements */
2411 len = 2 + sizeof(struct ieee80211_ht_capabilities);
2412 if (wpa_s->nan_capa.vht_valid)
2413 len += 2 + sizeof(struct ieee80211_vht_capabilities);
2414
2415 buf = wpabuf_alloc(len);
2416 if (!buf)
2417 return NULL;
2418
2419 wpabuf_put_u8(buf, WLAN_EID_HT_CAP);
2420 wpabuf_put_u8(buf, sizeof(*ht_cap));
2421 ht_cap = wpabuf_put(buf, sizeof(*ht_cap));
2422 ht_cap->ht_capabilities_info = host_to_le16(wpa_s->nan_capa.ht_capab);
2423 ht_cap->a_mpdu_params = wpa_s->nan_capa.ht_ampdu_params;
2424 os_memcpy(ht_cap->supported_mcs_set, wpa_s->nan_capa.ht_mcs_set,
2425 sizeof(ht_cap->supported_mcs_set));
2426
2427 if (!wpa_s->nan_capa.vht_valid)
2428 return buf;
2429
2430 wpabuf_put_u8(buf, WLAN_EID_VHT_CAP);
2431 wpabuf_put_u8(buf, sizeof(*vht_cap));
2432 vht_cap = wpabuf_put(buf, sizeof(*vht_cap));
2433 vht_cap->vht_capabilities_info =
2434 host_to_le32(wpa_s->nan_capa.vht_capab);
2435 os_memcpy(&vht_cap->vht_supported_mcs_set,
2436 wpa_s->nan_capa.vht_mcs_set,
2437 sizeof(vht_cap->vht_supported_mcs_set));
2438
2439 /* TODO: Add HE capabilities */
2440 return buf;
2441 }
2442
2443
2444 static int
wpas_nan_fill_ndp_schedule_chan(struct wpa_supplicant * wpa_s,struct nan_schedule * sched,int map_id,const struct nan_schedule_channel * chan)2445 wpas_nan_fill_ndp_schedule_chan(struct wpa_supplicant *wpa_s,
2446 struct nan_schedule *sched, int map_id,
2447 const struct nan_schedule_channel *chan)
2448 {
2449 struct nan_chan_schedule *chan_sched;
2450 struct nan_time_bitmap *tbm;
2451 const u8 *bitmap_data;
2452 size_t bitmap_len;
2453
2454 /* None of these should happen */
2455 if (!chan->time_bitmap) {
2456 wpa_printf(MSG_INFO,
2457 "NAN: Missing time bitmap for map_id %d freq %d",
2458 map_id + 1, chan->freq);
2459 return -1;
2460 }
2461
2462 bitmap_len = wpabuf_len(chan->time_bitmap);
2463 bitmap_data = wpabuf_head(chan->time_bitmap);
2464 if (bitmap_len > NAN_TIME_BITMAP_MAX_LEN) {
2465 wpa_printf(MSG_INFO,
2466 "NAN: Time bitmap length %zu exceeds maximum %d",
2467 bitmap_len, NAN_TIME_BITMAP_MAX_LEN);
2468 return -1;
2469 }
2470
2471 chan_sched = &sched->chans[sched->n_chans++];
2472 chan_sched->map_id = map_id + 1;
2473 chan_sched->chan.freq = chan->freq;
2474 chan_sched->chan.center_freq1 = chan->center_freq1;
2475 chan_sched->chan.center_freq2 = chan->center_freq2;
2476 chan_sched->chan.bandwidth = chan->bandwidth;
2477
2478 tbm = &chan_sched->committed;
2479 #ifdef CONFIG_TESTING_OPTIONS
2480 if (wpa_s->nan_force_conditional_sched) {
2481 wpa_printf(MSG_DEBUG,
2482 "NAN: Using conditional TBM for schedule channel");
2483 tbm = &chan_sched->conditional;
2484 }
2485 #endif /* CONFIG_TESTING_OPTIONS */
2486
2487 tbm->duration = wpa_s->nan_capa.slot_duration >> 5;
2488 tbm->period = ffs(wpa_s->nan_capa.schedule_period) - 7;
2489 tbm->offset = 0;
2490 tbm->len = bitmap_len;
2491 os_memcpy(tbm->bitmap, bitmap_data, bitmap_len);
2492
2493 wpa_printf(MSG_DEBUG,
2494 "NAN: NDP schedule channel added: map_id=%d freq=%d center_freq1=%d center_freq2=%d bandwidth=%d",
2495 chan_sched->map_id,
2496 chan_sched->chan.freq,
2497 chan_sched->chan.center_freq1,
2498 chan_sched->chan.center_freq2,
2499 chan_sched->chan.bandwidth);
2500
2501 return 0;
2502 }
2503
2504
wpas_nan_fill_ndp_schedule(struct wpa_supplicant * wpa_s,struct nan_schedule * sched)2505 static void wpas_nan_fill_ndp_schedule(struct wpa_supplicant *wpa_s,
2506 struct nan_schedule *sched)
2507 {
2508 int map_id;
2509
2510 os_memset(sched, 0, sizeof(*sched));
2511
2512 /* Fill the NAN schedule structure from the schedule config */
2513 for (map_id = 0; map_id < MAX_NAN_RADIOS; map_id++) {
2514 int i;
2515 struct nan_schedule_config *sched_cfg =
2516 &wpa_s->nan_sched[map_id];
2517
2518 for (i = 0; i < wpa_s->nan_sched[map_id].num_channels; i++) {
2519 struct nan_schedule_channel *chan;
2520
2521 chan = &sched_cfg->channels[i];
2522 if (wpas_nan_fill_ndp_schedule_chan(wpa_s, sched,
2523 map_id, chan)
2524 < 0)
2525 return;
2526 }
2527 }
2528
2529 /* Mark all supported radios - for potential availability */
2530 sched->map_ids_bitmap = (BIT(wpa_s->nan_capa.num_radios) - 1) << 1;
2531 }
2532
2533
wpas_nan_get_ndc_map_id(struct wpa_supplicant * wpa_s,const struct nan_peer_schedule * peer_sched,u8 peer_map_id)2534 static int wpas_nan_get_ndc_map_id(struct wpa_supplicant *wpa_s,
2535 const struct nan_peer_schedule *peer_sched,
2536 u8 peer_map_id)
2537 {
2538 int i;
2539 int freq = nan_get_peer_ndc_freq(wpa_s->nan, peer_sched, peer_map_id);
2540
2541 if (freq < 0) {
2542 wpa_printf(MSG_DEBUG,
2543 "NAN: Failed to get NDC frequency from peer schedule");
2544 return -1;
2545 }
2546
2547 wpa_printf(MSG_DEBUG, "NAN: Peer NDC frequency is %d MHz", freq);
2548
2549 for (i = 0; i < MAX_NAN_RADIOS; i++) {
2550 struct nan_schedule_config *sched_cfg = &wpa_s->nan_sched[i];
2551 int j;
2552
2553 for (j = 0; j < sched_cfg->num_channels; j++) {
2554 if (sched_cfg->channels[j].freq == freq) {
2555 wpa_printf(MSG_DEBUG,
2556 "NAN: Found local NDC map_id %d for peer NDC freq %d",
2557 i + 1, freq);
2558 return i + 1;
2559 }
2560 }
2561 }
2562
2563 return -1;
2564 }
2565
2566
2567
wpas_nan_select_ndc_copy_peers(struct wpa_supplicant * wpa_s,struct nan_ndp_params * ndp)2568 static int wpas_nan_select_ndc_copy_peers(struct wpa_supplicant *wpa_s,
2569 struct nan_ndp_params *ndp)
2570 {
2571 struct nan_peer_schedule peer_sched;
2572 int ret;
2573 u8 map_id;
2574
2575 wpa_printf(MSG_DEBUG, "NAN: NDP CONF - use the NDC from peer");
2576 ret = nan_peer_get_schedule_info(wpa_s->nan, ndp->ndp_id.peer_nmi,
2577 &peer_sched);
2578 if (ret) {
2579 wpa_printf(MSG_DEBUG, "NAN: Failed to get peer schedule info");
2580 return -1;
2581 }
2582
2583 for (map_id = 0; map_id < peer_sched.n_maps; map_id++) {
2584 if (peer_sched.maps[map_id].ndc.len) {
2585 ret = wpas_nan_get_ndc_map_id(wpa_s, &peer_sched,
2586 map_id);
2587 if (ret < 0) {
2588 wpa_printf(MSG_DEBUG,
2589 "NAN: No local NDC map_id found for peer NDC");
2590 return -1;
2591 }
2592
2593 ndp->sched.ndc_map_id = ret;
2594 os_memcpy(&ndp->sched.ndc, &peer_sched.maps[map_id].ndc,
2595 sizeof(ndp->sched.ndc));
2596 return 0;
2597 }
2598 }
2599
2600 wpa_printf(MSG_DEBUG, "NAN: No NDC found in peer schedule");
2601 return -1;
2602 }
2603
2604
wpas_nan_select_ndc(struct wpa_supplicant * wpa_s,struct nan_ndp_params * ndp)2605 static int wpas_nan_select_ndc(struct wpa_supplicant *wpa_s,
2606 struct nan_ndp_params *ndp)
2607 {
2608 struct nan_time_bitmap *tbm;
2609 int i;
2610
2611 /* NDC attribute in request is optional, let the peer decide */
2612 if (ndp->type == NAN_NDP_ACTION_REQ)
2613 return 0;
2614
2615 /* For successfull confirm, copy peer's NDC */
2616 if (ndp->type == NAN_NDP_ACTION_CONF &&
2617 ndp->u.resp.status == NAN_NDP_STATUS_ACCEPTED)
2618 return wpas_nan_select_ndc_copy_peers(wpa_s, ndp);
2619
2620 tbm = &ndp->sched.chans[0].committed;
2621 #ifdef CONFIG_TESTING_OPTIONS
2622 if (wpa_s->nan_force_conditional_sched) {
2623 wpa_printf(MSG_DEBUG,
2624 "NAN: Using conditional TBM for NDC selection");
2625 tbm = &ndp->sched.chans[0].conditional;
2626 }
2627 #endif /* CONFIG_TESTING_OPTIONS */
2628
2629 os_memcpy(&ndp->sched.ndc, tbm, sizeof(ndp->sched.ndc));
2630 os_memset(ndp->sched.ndc.bitmap, 0, sizeof(ndp->sched.ndc.bitmap));
2631 ndp->sched.ndc_map_id = ndp->sched.chans[0].map_id;
2632
2633 /*
2634 * For default NDC channels (6, 149, 44) take the first slot after DW.
2635 * Note that if the slot duration is 16 TUs we need to select the next
2636 * slot after DW. If the first channel is not one of default NDC
2637 * channels, select the first available slot.
2638 */
2639 if (ndp->sched.chans[0].chan.freq == 5745 ||
2640 ndp->sched.chans[0].chan.freq == 5220) {
2641 int dw_bit, byte_idx, bit_in_byte;
2642
2643 dw_bit = 128 / wpa_s->nan_capa.slot_duration;
2644 dw_bit += !!(wpa_s->nan_capa.slot_duration == 16);
2645 byte_idx = dw_bit / 8;
2646 bit_in_byte = dw_bit % 8;
2647
2648 if (tbm->bitmap[byte_idx] & BIT(bit_in_byte)) {
2649 ndp->sched.ndc.bitmap[byte_idx] = BIT(bit_in_byte);
2650 return 0;
2651 }
2652 } else if (ndp->sched.chans[0].chan.freq == 2437 &&
2653 wpa_s->nan_capa.slot_duration == 16) {
2654 if (tbm->bitmap[0] & 0x02) {
2655 ndp->sched.ndc.bitmap[0] = 0x02;
2656 return 0;
2657 }
2658 }
2659
2660 /* For other cases, select the first available slot */
2661 for (i = 0; i < NAN_TIME_BITMAP_MAX_LEN; i++) {
2662 if (tbm->bitmap[i]) {
2663 ndp->sched.ndc.bitmap[i] =
2664 tbm->bitmap[i] & (~tbm->bitmap[i] + 1);
2665 break;
2666 }
2667 }
2668
2669 return 0;
2670 }
2671
2672
wpas_nan_set_ndp_schedule(struct wpa_supplicant * wpa_s,struct nan_ndp_params * ndp)2673 static int wpas_nan_set_ndp_schedule(struct wpa_supplicant *wpa_s,
2674 struct nan_ndp_params *ndp)
2675 {
2676 /* Set schedule for request or successful response */
2677 if (ndp->type != NAN_NDP_ACTION_REQ &&
2678 ndp->u.resp.status == NAN_NDP_STATUS_REJECTED)
2679 return 0;
2680
2681 wpas_nan_fill_ndp_schedule(wpa_s, &ndp->sched);
2682
2683 if (!ndp->sched.n_chans) {
2684 wpa_printf(MSG_DEBUG,
2685 "NAN: No channels configured for NDP schedule");
2686 return -1;
2687 }
2688
2689 /* Set sequence ID */
2690 ndp->sched.sequence_id = wpa_s->schedule_sequence_id;
2691
2692 /* Add additional elements */
2693 ndp->sched.elems = wpas_nan_build_ndp_elems(wpa_s);
2694
2695 /* Mark schedule as valid */
2696 ndp->sched_valid = true;
2697
2698 return wpas_nan_select_ndc(wpa_s, ndp);
2699 }
2700
2701
wpas_nan_parse_password_hex(const char * hexstr)2702 static char * wpas_nan_parse_password_hex(const char *hexstr)
2703 {
2704 size_t len = os_strlen(hexstr);
2705 size_t pwd_len;
2706 char *pwd;
2707 size_t i;
2708
2709 if (!len || len % 2 != 0) {
2710 wpa_printf(MSG_INFO, "NAN: Invalid password hex length: %zu",
2711 len);
2712 return NULL;
2713 }
2714
2715 pwd_len = len / 2;
2716 pwd = os_malloc(pwd_len + 1);
2717 if (!pwd)
2718 return NULL;
2719
2720 if (hexstr2bin(hexstr, (u8 *) pwd, pwd_len) < 0) {
2721 wpa_printf(MSG_INFO, "NAN: Invalid password hex data");
2722 os_free(pwd);
2723 return NULL;
2724 }
2725
2726 /* Reject passwords containing NULL bytes (except the terminator) */
2727 for (i = 0; i < pwd_len; i++) {
2728 if (pwd[i] == '\0') {
2729 wpa_printf(MSG_DEBUG,
2730 "NAN: Decoded password contains embedded NUL byte at offset %zu",
2731 i);
2732 os_free(pwd);
2733 return NULL;
2734 }
2735 }
2736
2737 pwd[pwd_len] = '\0';
2738 return pwd;
2739 }
2740
2741
wpas_nan_fill_nd_pmk(struct wpa_supplicant * wpa_s,struct nan_ndp_params * ndp,int handle,const u8 * publisher_nmi,const char * pwd,const char * pmk)2742 static int wpas_nan_fill_nd_pmk(struct wpa_supplicant *wpa_s,
2743 struct nan_ndp_params *ndp,
2744 int handle,
2745 const u8 *publisher_nmi,
2746 const char *pwd, const char *pmk)
2747 {
2748 u8 service_id[NAN_SERVICE_ID_LEN];
2749
2750 if (ndp->sec.csid < NAN_CS_NONE || ndp->sec.csid >= NAN_CS_MAX) {
2751 wpa_printf(MSG_INFO, "NAN: Invalid CSID value: %d",
2752 ndp->sec.csid);
2753 return -1;
2754 }
2755
2756 /*
2757 * Get service ID from the local handle (subscribe on
2758 * requester and publish on responder)
2759 */
2760 if (!nan_de_is_valid_instance_id(wpa_s->nan_de, handle,
2761 ndp->type == NAN_NDP_ACTION_RESP,
2762 service_id)) {
2763 wpa_printf(MSG_INFO,
2764 "NAN: Invalid service instance handle: %d",
2765 handle);
2766 return -1;
2767 }
2768
2769 /*
2770 * For NDP response (publisher side), check if the requested CSID
2771 * is supported by the service (including open/NAN_CS_NONE).
2772 */
2773 if (ndp->type == NAN_NDP_ACTION_RESP &&
2774 !nan_de_service_supports_csid(wpa_s->nan_de, handle,
2775 ndp->sec.csid)) {
2776 wpa_printf(MSG_DEBUG,
2777 "NAN: CSID %d not supported by service",
2778 ndp->sec.csid);
2779 return -1;
2780 }
2781
2782 if (ndp->sec.csid == NAN_CS_NONE)
2783 return 0;
2784
2785 /* Security parameters are not needed in confirmation */
2786 if (ndp->type == NAN_NDP_ACTION_CONF)
2787 return 0;
2788
2789 if (!(wpa_s->nan_supported_csids & BIT(ndp->sec.csid))) {
2790 wpa_printf(MSG_INFO,
2791 "NAN: Requested CSID %d not supported",
2792 ndp->sec.csid);
2793 return -1;
2794 }
2795
2796 if ((!pwd || os_strlen(pwd) == 0) && (!pmk || os_strlen(pmk) == 0)) {
2797 wpa_printf(MSG_INFO,
2798 "NAN: Password/PMK required for CSID %d",
2799 ndp->sec.csid);
2800 return -1;
2801 }
2802
2803 if (pmk) {
2804 if (os_strlen(pmk) != PMK_LEN * 2) {
2805 wpa_printf(MSG_INFO, "NAN: Invalid PMK length: %zu",
2806 os_strlen(pmk));
2807 return -1;
2808 }
2809
2810 if (hexstr2bin(pmk, ndp->sec.pmk, PMK_LEN) < 0) {
2811 wpa_printf(MSG_INFO, "NAN: Invalid PMK hex data");
2812 return -1;
2813 }
2814
2815 return 0;
2816 }
2817
2818 /* Derive PMK from password */
2819 return nan_crypto_derive_nd_pmk(pwd, service_id, ndp->sec.csid,
2820 publisher_nmi, ndp->sec.pmk);
2821 }
2822
2823
wpas_nan_set_gtk(struct wpa_supplicant * ndi_wpa_s,struct nan_ndp_params * ndp,int gtk_csid)2824 static int wpas_nan_set_gtk(struct wpa_supplicant *ndi_wpa_s,
2825 struct nan_ndp_params *ndp, int gtk_csid)
2826 {
2827 if (ndi_wpa_s->ndi_gtk.gtk.gtk_len) {
2828 if (ndi_wpa_s->ndi_gtk.csid != gtk_csid) {
2829 wpa_printf(MSG_INFO,
2830 "NAN: NDI GTK CSID mismatch (expected %d, got %d)",
2831 gtk_csid, ndi_wpa_s->ndi_gtk.csid);
2832 return -1;
2833 }
2834
2835 os_memcpy(&ndp->sec.gtk, &ndi_wpa_s->ndi_gtk,
2836 sizeof(ndp->sec.gtk));
2837 return 0;
2838 }
2839
2840 ndp->sec.gtk.csid = gtk_csid;
2841 if (gtk_csid == NAN_CS_GTK_GCMP_256 &&
2842 (ndi_wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_GCMP_256)) {
2843 ndp->sec.gtk.gtk.gtk_len = 32;
2844 } else if (gtk_csid == NAN_CS_GTK_CCMP_128 &&
2845 (ndi_wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_CCMP)) {
2846 ndp->sec.gtk.gtk.gtk_len = 16;
2847 } else {
2848 wpa_printf(MSG_INFO,
2849 "NAN: NDI does not support GTK cipher suites");
2850 return -1;
2851 }
2852
2853 if (os_get_random(ndp->sec.gtk.gtk.gtk, ndp->sec.gtk.gtk.gtk_len) < 0) {
2854 wpa_printf(MSG_INFO, "NAN: Failed to generate GTK");
2855 return -1;
2856 }
2857
2858 ndp->sec.gtk.id = 1;
2859
2860 wpa_hexdump_key(MSG_DEBUG, "NAN: Generated new GTK",
2861 ndp->sec.gtk.gtk.gtk, ndp->sec.gtk.gtk.gtk_len);
2862 return 0;
2863 }
2864
2865
2866 /* Command format NAN_NDP_REQUEST handle=<id> ndi=<ifname> peer_nmi=<nmi>
2867 peer_id=<peer_instance_id> ssi=<hexdata> qos=<slots:latency>
2868 [csid = <cipher_suite> <password=<string>|pwd_hex=<hex>|pmk=<hex>>
2869 [gtk_csid=<cipher_suite>]] [interface_id=<hex>] */
wpas_nan_ndp_request(struct wpa_supplicant * wpa_s,char * cmd)2870 int wpas_nan_ndp_request(struct wpa_supplicant *wpa_s, char *cmd)
2871 {
2872 struct nan_ndp_params ndp;
2873 struct wpabuf *ssi_buf = NULL;
2874 char *token, *context = NULL;
2875 char *pos;
2876 const char *pwd = NULL, *pmk = NULL, *pwd_hex = NULL;
2877 char *pwd_decoded = NULL;
2878 int handle = -1;
2879 int ret = -1;
2880 u8 *interface_id = NULL;
2881 struct wpa_supplicant *ndi_wpa_s = NULL;
2882 int gtk_csid = 0;
2883
2884 os_memset(&ndp, 0, sizeof(ndp));
2885
2886 if (!wpas_nan_ndp_allowed(wpa_s))
2887 return -1;
2888
2889 ndp.type = NAN_NDP_ACTION_REQ;
2890 ndp.qos.min_slots = NAN_QOS_MIN_SLOTS_NO_PREF;
2891 ndp.qos.max_latency = NAN_QOS_MAX_LATENCY_NO_PREF;
2892
2893 /* Parse command parameters */
2894 while ((token = str_token(cmd, " ", &context))) {
2895 pos = os_strchr(token, '=');
2896 if (!pos) {
2897 wpa_printf(MSG_INFO,
2898 "NAN: Invalid parameter format: %s",
2899 token);
2900 goto fail;
2901 }
2902 *pos++ = '\0';
2903
2904 if (os_strcmp(token, "handle") == 0) {
2905 handle = atoi(pos);
2906
2907 /* Get service ID from the local handle */
2908 if (!nan_de_is_valid_instance_id(wpa_s->nan_de,
2909 handle, false,
2910 ndp.u.req.service_id))
2911 {
2912 wpa_printf(MSG_INFO,
2913 "NAN: Invalid subscribe handle: %d",
2914 handle);
2915 goto fail;
2916 }
2917 } else if (os_strcmp(token, "ndi") == 0) {
2918 ndi_wpa_s = wpa_supplicant_get_iface(wpa_s->global,
2919 pos);
2920 if (!ndi_wpa_s) {
2921 wpa_printf(MSG_INFO,
2922 "NAN: NDI interface not found: %s",
2923 pos);
2924 goto fail;
2925 }
2926
2927 if (!ndi_wpa_s->nan_data) {
2928 wpa_printf(MSG_INFO,
2929 "NAN: Interface %s is not a NAN data interface",
2930 pos);
2931 goto fail;
2932 }
2933
2934 os_memcpy(ndp.ndp_id.init_ndi, ndi_wpa_s->own_addr,
2935 ETH_ALEN);
2936 } else if (os_strcmp(token, "peer_nmi") == 0) {
2937 if (hwaddr_aton(pos, ndp.ndp_id.peer_nmi) < 0) {
2938 wpa_printf(MSG_INFO,
2939 "NAN: Invalid peer NMI address: %s",
2940 pos);
2941 goto fail;
2942 }
2943
2944 } else if (os_strcmp(token, "peer_id") == 0) {
2945 ndp.u.req.publish_inst_id = atoi(pos);
2946 } else if (os_strcmp(token, "ssi") == 0) {
2947 ssi_buf = wpabuf_parse_bin(pos);
2948 if (!ssi_buf) {
2949 wpa_printf(MSG_INFO,
2950 "NAN: Invalid SSI data: %s", pos);
2951 goto fail;
2952 }
2953
2954 ndp.ssi_len = wpabuf_len(ssi_buf);
2955 ndp.ssi = wpabuf_head(ssi_buf);
2956 } else if (os_strcmp(token, "qos") == 0) {
2957 if (sscanf(pos, "%hhu:%hu",
2958 &ndp.qos.min_slots,
2959 &ndp.qos.max_latency) != 2) {
2960 wpa_printf(MSG_INFO,
2961 "NAN: Invalid QoS parameter: %s",
2962 pos);
2963 goto fail;
2964 }
2965 } else if (os_strcmp(token, "csid") == 0) {
2966 ndp.sec.csid = atoi(pos);
2967 } else if (os_strcmp(token, "password") == 0) {
2968 pwd = pos;
2969 } else if (os_strcmp(token, "pwd_hex") == 0) {
2970 pwd_hex = pos;
2971 } else if (os_strcmp(token, "pmk") == 0) {
2972 pmk = pos;
2973 } else if (os_strcmp(token, "interface_id") == 0) {
2974 os_free(interface_id);
2975 interface_id =
2976 os_malloc(NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN);
2977 if (!interface_id)
2978 goto fail;
2979
2980 if (hexstr2bin(pos, interface_id,
2981 NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN) < 0) {
2982 wpa_printf(MSG_DEBUG,
2983 "NAN: Invalid interface_id hex data: %s",
2984 pos);
2985 goto fail;
2986 }
2987
2988 ndp.interface_id = interface_id;
2989 } else if (os_strcmp(token, "gtk_csid") == 0) {
2990 gtk_csid = atoi(pos);
2991 if (gtk_csid != NAN_CS_GTK_CCMP_128 &&
2992 gtk_csid != NAN_CS_GTK_GCMP_256) {
2993 wpa_printf(MSG_INFO,
2994 "NAN: Invalid GTK CSID value: %d",
2995 gtk_csid);
2996 goto fail;
2997 }
2998 } else {
2999 wpa_printf(MSG_INFO, "NAN: Unknown parameter: %s",
3000 token);
3001 goto fail;
3002 }
3003 }
3004
3005 /* Validate required parameters */
3006 if (handle < 0) {
3007 wpa_printf(MSG_INFO, "NAN: Missing required parameter: handle");
3008 goto fail;
3009 }
3010
3011 if (!ndp.u.req.publish_inst_id) {
3012 wpa_printf(MSG_INFO,
3013 "NAN: Missing required parameter: peer_id");
3014 goto fail;
3015 }
3016
3017 if (is_zero_ether_addr(ndp.ndp_id.init_ndi)) {
3018 wpa_printf(MSG_INFO, "NAN: Missing required parameter: ndi");
3019 goto fail;
3020 }
3021
3022 if (is_zero_ether_addr(ndp.ndp_id.peer_nmi)) {
3023 wpa_printf(MSG_INFO,
3024 "NAN: Missing required parameter: peer_nmi");
3025 goto fail;
3026 }
3027
3028 if ((pmk && pwd) || (pmk && pwd_hex) || (pwd && pwd_hex)) {
3029 wpa_printf(MSG_INFO,
3030 "NAN: Specify only one of password, pwd_hex, or pmk");
3031 goto fail;
3032 }
3033
3034 if (pwd_hex) {
3035 pwd_decoded = wpas_nan_parse_password_hex(pwd_hex);
3036 if (!pwd_decoded)
3037 goto fail;
3038 }
3039
3040 if (wpas_nan_fill_nd_pmk(wpa_s, &ndp, handle, ndp.ndp_id.peer_nmi,
3041 pwd_decoded ? pwd_decoded : pwd, pmk) < 0) {
3042 wpa_printf(MSG_INFO,
3043 "NAN: Failed to derive NDP PMK");
3044 goto fail;
3045 }
3046
3047 if (wpas_nan_set_ndp_schedule(wpa_s, &ndp)) {
3048 wpa_printf(MSG_INFO, "NAN: Failed to set NDP schedule");
3049 goto fail;
3050 }
3051
3052 if (gtk_csid) {
3053 if (ndp.sec.csid == NAN_CS_NONE || !ndi_wpa_s) {
3054 wpa_printf(MSG_INFO,
3055 "NAN: GTK CSID specified without a valid NDP CSID");
3056 goto fail;
3057 }
3058
3059 if (wpas_nan_set_gtk(ndi_wpa_s, &ndp, gtk_csid) < 0) {
3060 wpa_printf(MSG_DEBUG, "NAN: Failed to set NDP GTK");
3061 goto fail;
3062 }
3063 }
3064
3065 wpa_printf(MSG_DEBUG, "NAN: Requesting NDP with peer " MACSTR
3066 " using handle %d", MAC2STR(ndp.ndp_id.peer_nmi),
3067 ndp.u.req.publish_inst_id);
3068 ret = nan_handle_ndp_setup(wpa_s->nan, &ndp);
3069 fail:
3070 wpabuf_free(ndp.sched.elems);
3071 wpabuf_free(ssi_buf);
3072 os_free(interface_id);
3073 str_clear_free(pwd_decoded);
3074
3075 return ret;
3076 }
3077
3078
wpas_nan_ndp_response_set_gtk(struct wpa_supplicant * wpa_s,struct wpa_supplicant * ndi_wpa_s,int handle,struct nan_ndp_params * ndp)3079 int wpas_nan_ndp_response_set_gtk(struct wpa_supplicant *wpa_s,
3080 struct wpa_supplicant *ndi_wpa_s,
3081 int handle, struct nan_ndp_params *ndp)
3082 {
3083 int gtk_csid;
3084
3085 gtk_csid = nan_ndp_requested_gtk_csid(wpa_s->nan, &ndp->ndp_id);
3086 if (!gtk_csid) {
3087 wpa_printf(MSG_DEBUG, "NAN: No GTK requested by peer for NDP");
3088 return 0;
3089 }
3090
3091 if (!nan_de_service_supports_csid(wpa_s->nan_de, handle, gtk_csid)) {
3092 wpa_printf(MSG_DEBUG,
3093 "NAN: Cannot set GTK - CSID %d not supported by service",
3094 gtk_csid);
3095 return -1;
3096 }
3097
3098 return wpas_nan_set_gtk(ndi_wpa_s, ndp, gtk_csid);
3099 }
3100
3101
3102 /* Command format NAN_NDP_RESPONSE accept|reject peer_nmi=<nmi>
3103 [reason_code=<reject_reason>]
3104 [ndi=<ifname> handle=<service_handle> init_ndi=<ndi>
3105 ndp_id=<id> [ssi=<hexdata>] [qos=<slots:latency>]
3106 [csid=<csid> <password=<string>|pwd_hex=<hex>|pmk=<hex>>]]
3107 [interface_id=<hex>] */
wpas_nan_ndp_response(struct wpa_supplicant * wpa_s,char * cmd)3108 int wpas_nan_ndp_response(struct wpa_supplicant *wpa_s, char *cmd)
3109 {
3110 struct nan_ndp_params ndp;
3111 struct wpabuf *ssi_buf = NULL;
3112 char *token, *context = NULL;
3113 char *pos;
3114 const char *pwd = NULL, *pmk = NULL, *pwd_hex = NULL;
3115 char *pwd_decoded = NULL;
3116 int handle = -1;
3117 int ret = -1;
3118 u8 *interface_id = NULL;
3119 struct wpa_supplicant *ndi_wpa_s = NULL;
3120
3121 if (!wpas_nan_ndp_allowed(wpa_s))
3122 return -1;
3123
3124 os_memset(&ndp, 0, sizeof(ndp));
3125
3126 ndp.type = NAN_NDP_ACTION_RESP;
3127 ndp.qos.min_slots = NAN_QOS_MIN_SLOTS_NO_PREF;
3128 ndp.qos.max_latency = NAN_QOS_MAX_LATENCY_NO_PREF;
3129
3130 /* Parse accept/reject status - the first parameter is mandatory */
3131 token = str_token(cmd, " ", &context);
3132 if (!token) {
3133 wpa_printf(MSG_INFO, "NAN: Missing accept/reject parameter");
3134 return -1;
3135 }
3136
3137 if (os_strcmp(token, "accept") == 0) {
3138 ndp.u.resp.status = NAN_NDP_STATUS_ACCEPTED;
3139 } else if (os_strcmp(token, "reject") == 0) {
3140 ndp.u.resp.status = NAN_NDP_STATUS_REJECTED;
3141 } else {
3142 wpa_printf(MSG_INFO, "NAN: Invalid accept/reject parameter: %s",
3143 token);
3144 return -1;
3145 }
3146
3147 /* Parse optional parameters */
3148 while ((token = str_token(cmd, " ", &context))) {
3149 pos = os_strchr(token, '=');
3150 if (!pos) {
3151 wpa_printf(MSG_INFO,
3152 "NAN: Invalid parameter format: %s", token);
3153 goto fail;
3154 }
3155 *pos++ = '\0';
3156
3157 if (os_strcmp(token, "reason_code") == 0) {
3158 ndp.u.resp.reason_code = atoi(pos);
3159 } else if (os_strcmp(token, "ndi") == 0) {
3160 ndi_wpa_s = wpa_supplicant_get_iface(wpa_s->global,
3161 pos);
3162 if (!ndi_wpa_s) {
3163 wpa_printf(MSG_INFO,
3164 "NAN: NDI interface not found: %s",
3165 pos);
3166 goto fail;
3167 }
3168
3169 if (!ndi_wpa_s->nan_data) {
3170 wpa_printf(MSG_INFO,
3171 "NAN: Interface %s is not a NAN data interface",
3172 pos);
3173 goto fail;
3174 }
3175
3176 os_memcpy(ndp.u.resp.resp_ndi, ndi_wpa_s->own_addr,
3177 ETH_ALEN);
3178 } else if (os_strcmp(token, "peer_nmi") == 0) {
3179 if (hwaddr_aton(pos, ndp.ndp_id.peer_nmi) < 0) {
3180 wpa_printf(MSG_INFO,
3181 "NAN: Invalid peer NMI address: %s",
3182 pos);
3183 goto fail;
3184 }
3185 } else if (os_strcmp(token, "ndp_id") == 0) {
3186 ndp.ndp_id.id = atoi(pos);
3187 } else if (os_strcmp(token, "init_ndi") == 0) {
3188 if (hwaddr_aton(pos, ndp.ndp_id.init_ndi) < 0) {
3189 wpa_printf(MSG_INFO,
3190 "NAN: Invalid initiator NDI address: %s",
3191 pos);
3192 goto fail;
3193 }
3194 } else if (os_strcmp(token, "ssi") == 0) {
3195 ssi_buf = wpabuf_parse_bin(pos);
3196 if (!ssi_buf) {
3197 wpa_printf(MSG_INFO,
3198 "NAN: Invalid SSI data: %s", pos);
3199 goto fail;
3200 }
3201
3202 ndp.ssi_len = wpabuf_len(ssi_buf);
3203 ndp.ssi = wpabuf_head(ssi_buf);
3204 } else if (os_strcmp(token, "qos") == 0) {
3205 if (sscanf(pos, "%hhu:%hu",
3206 &ndp.qos.min_slots,
3207 &ndp.qos.max_latency) != 2) {
3208 wpa_printf(MSG_INFO,
3209 "NAN: Invalid QoS parameter: %s",
3210 pos);
3211 goto fail;
3212 }
3213 } else if (os_strcmp(token, "handle") == 0) {
3214 handle = atoi(pos);
3215 } else if (os_strcmp(token, "csid") == 0) {
3216 ndp.sec.csid = atoi(pos);
3217 } else if (os_strcmp(token, "password") == 0) {
3218 pwd = pos;
3219 } else if (os_strcmp(token, "pwd_hex") == 0) {
3220 pwd_hex = pos;
3221 } else if (os_strcmp(token, "pmk") == 0) {
3222 pmk = pos;
3223 } else if (os_strcmp(token, "interface_id") == 0) {
3224 os_free(interface_id);
3225 interface_id =
3226 os_malloc(NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN);
3227 if (!interface_id)
3228 goto fail;
3229
3230 if (hexstr2bin(pos, interface_id,
3231 NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN) < 0) {
3232 wpa_printf(MSG_DEBUG,
3233 "NAN: Invalid interface_id hex data: %s",
3234 pos);
3235 goto fail;
3236 }
3237
3238 ndp.interface_id = interface_id;
3239 } else {
3240 wpa_printf(MSG_DEBUG, "NAN: Unknown parameter: %s",
3241 token);
3242 }
3243 }
3244
3245 /* If we initiated the NDP setup, we are the subscriber */
3246 if (ether_addr_equal(ndp.u.resp.resp_ndi, ndp.ndp_id.init_ndi))
3247 ndp.type = NAN_NDP_ACTION_CONF;
3248
3249 /* Validate required parameters for accept case */
3250 if (ndp.u.resp.status == NAN_NDP_STATUS_ACCEPTED) {
3251 const u8 *publisher_nmi;
3252
3253 if (is_zero_ether_addr(ndp.u.resp.resp_ndi)) {
3254 wpa_printf(MSG_INFO,
3255 "NAN: Missing required parameter for accept: ndi");
3256 goto fail;
3257 }
3258
3259 if (ndp.type == NAN_NDP_ACTION_CONF)
3260 publisher_nmi = ndp.ndp_id.peer_nmi;
3261 else
3262 publisher_nmi = wpa_s->own_addr;
3263
3264 if (handle < 1) {
3265 wpa_printf(MSG_INFO,
3266 "NAN: Missing required parameter for accept: handle");
3267 goto fail;
3268 }
3269
3270 if ((pmk && pwd) || (pmk && pwd_hex) || (pwd && pwd_hex)) {
3271 wpa_printf(MSG_INFO,
3272 "NAN: Specify only one of password, pwd_hex, or pmk");
3273 goto fail;
3274 }
3275
3276 if (pwd_hex) {
3277 pwd_decoded = wpas_nan_parse_password_hex(pwd_hex);
3278 if (!pwd_decoded)
3279 goto fail;
3280 }
3281
3282 if (wpas_nan_fill_nd_pmk(wpa_s, &ndp, handle, publisher_nmi,
3283 pwd_decoded ? pwd_decoded : pwd, pmk)
3284 < 0) {
3285 wpa_printf(MSG_INFO, "NAN: Failed to derive NDP PMK");
3286 goto fail;
3287 }
3288 }
3289
3290 /* Validate common required parameters */
3291 if (is_zero_ether_addr(ndp.ndp_id.peer_nmi)) {
3292 wpa_printf(MSG_INFO,
3293 "NAN: Missing required parameter: peer_nmi");
3294 goto fail;
3295 }
3296
3297 if (is_zero_ether_addr(ndp.ndp_id.init_ndi)) {
3298 wpa_printf(MSG_INFO,
3299 "NAN: Missing required parameter: init_ndi");
3300 goto fail;
3301 }
3302
3303 if (!ndp.ndp_id.id) {
3304 wpa_printf(MSG_INFO,
3305 "NAN: Missing required parameter: ndp_id");
3306 goto fail;
3307 }
3308
3309 if (ndp.u.resp.status == NAN_NDP_STATUS_ACCEPTED && ndi_wpa_s &&
3310 wpas_nan_ndp_response_set_gtk(wpa_s, ndi_wpa_s, handle, &ndp) < 0) {
3311 wpa_printf(MSG_DEBUG,
3312 "NAN: Failed to set GTK for NDP response");
3313 goto fail;
3314 }
3315
3316 wpa_printf(MSG_DEBUG, "NAN: %s NDP response for peer " MACSTR
3317 " ndp_id=%u",
3318 ndp.u.resp.status == NAN_NDP_STATUS_ACCEPTED ?
3319 "Accepting" : "Rejecting",
3320 MAC2STR(ndp.ndp_id.peer_nmi), ndp.ndp_id.id);
3321
3322 if (wpas_nan_set_ndp_schedule(wpa_s, &ndp) < 0) {
3323 wpa_printf(MSG_INFO,
3324 "NAN: Failed to set NDP schedule");
3325 goto fail;
3326 }
3327
3328 ret = nan_handle_ndp_setup(wpa_s->nan, &ndp);
3329 if (ret < 0)
3330 wpa_printf(MSG_INFO, "NAN: Failed to handle NDP response");
3331
3332 fail:
3333 wpabuf_free(ndp.sched.elems);
3334 wpabuf_free(ssi_buf);
3335 os_free(interface_id);
3336 str_clear_free(pwd_decoded);
3337
3338 return ret;
3339 }
3340
3341
3342 /* Format: NAN_NDP_TERMINATE peer_nmi=<nmi> init_ndi=<ndi> ndp_id=<id> */
wpas_nan_ndp_terminate(struct wpa_supplicant * wpa_s,char * cmd)3343 int wpas_nan_ndp_terminate(struct wpa_supplicant *wpa_s, char *cmd)
3344 {
3345 struct nan_ndp_params ndp;
3346 char *token, *context = NULL;
3347 char *pos;
3348
3349 if (!wpas_nan_ndp_allowed(wpa_s))
3350 return -1;
3351
3352 os_memset(&ndp, 0, sizeof(ndp));
3353
3354 ndp.type = NAN_NDP_ACTION_TERM;
3355
3356 /* Parse command parameters */
3357 while ((token = str_token(cmd, " ", &context))) {
3358 pos = os_strchr(token, '=');
3359 if (!pos) {
3360 wpa_printf(MSG_INFO,
3361 "NAN: Invalid parameter format: %s",
3362 token);
3363 return -1;
3364 }
3365 *pos++ = '\0';
3366
3367 if (os_strcmp(token, "peer_nmi") == 0) {
3368 if (hwaddr_aton(pos, ndp.ndp_id.peer_nmi) < 0) {
3369 wpa_printf(MSG_INFO,
3370 "NAN: Invalid peer NMI address: %s",
3371 pos);
3372 return -1;
3373 }
3374 } else if (os_strcmp(token, "init_ndi") == 0) {
3375 if (hwaddr_aton(pos, ndp.ndp_id.init_ndi) < 0) {
3376 wpa_printf(MSG_INFO,
3377 "NAN: Invalid initiator NDI address: %s",
3378 pos);
3379 return -1;
3380 }
3381 } else if (os_strcmp(token, "ndp_id") == 0) {
3382 ndp.ndp_id.id = atoi(pos);
3383 } else {
3384 wpa_printf(MSG_DEBUG, "NAN: Unknown parameter: %s",
3385 token);
3386 }
3387 }
3388
3389 /* Validate required parameters */
3390 if (is_zero_ether_addr(ndp.ndp_id.peer_nmi)) {
3391 wpa_printf(MSG_INFO,
3392 "NAN: Missing required parameter: peer_nmi");
3393 return -1;
3394 }
3395
3396 if (is_zero_ether_addr(ndp.ndp_id.init_ndi)) {
3397 wpa_printf(MSG_INFO,
3398 "NAN: Missing required parameter: init_ndi");
3399 return -1;
3400 }
3401
3402 if (!ndp.ndp_id.id) {
3403 wpa_printf(MSG_INFO,
3404 "NAN: Missing required parameter: ndp_id");
3405 return -1;
3406 }
3407
3408 wpa_printf(MSG_DEBUG, "NAN: Terminating NDP with peer " MACSTR
3409 " init_ndi=" MACSTR " ndp_id=%u",
3410 MAC2STR(ndp.ndp_id.peer_nmi),
3411 MAC2STR(ndp.ndp_id.init_ndi), ndp.ndp_id.id);
3412
3413 return nan_handle_ndp_setup(wpa_s->nan, &ndp);
3414 }
3415
3416
wpas_nan_status(struct wpa_supplicant * wpa_s,char * reply,size_t reply_size)3417 int wpas_nan_status(struct wpa_supplicant *wpa_s, char *reply,
3418 size_t reply_size)
3419 {
3420 char *pos = reply;
3421 char *end = reply + reply_size;
3422 int ret;
3423
3424 if (!wpas_nan_ready(wpa_s))
3425 return -1;
3426
3427 ret = nan_get_status(wpa_s->nan, pos, end - pos);
3428 if (ret > 0)
3429 pos += ret;
3430
3431 ret = nan_de_get_status(wpa_s->nan_de, pos, end - pos);
3432 if (ret > 0)
3433 pos += ret;
3434 return pos - reply;
3435 }
3436
3437
3438 #ifdef CONFIG_PASN
wpas_nan_append_ik_info(char * reply,size_t reply_size,const struct wpa_dev_ik * ik)3439 static int wpas_nan_append_ik_info(char *reply, size_t reply_size,
3440 const struct wpa_dev_ik *ik)
3441 {
3442 char *pos = reply;
3443 char *end = reply + reply_size;
3444
3445 pos += wpa_scnprintf(pos, end - pos, "nik_cipher=%d\n", ik->dik_cipher);
3446 pos += wpa_scnprintf(pos, end - pos, "nik=");
3447 pos += wpa_snprintf_hex(pos, end - pos, wpabuf_head(ik->dik),
3448 wpabuf_len(ik->dik));
3449 pos += wpa_scnprintf(pos, end - pos, "\n");
3450
3451 if (ik->pmk) {
3452 pos += wpa_scnprintf(pos, end - pos, "akmp=%s\n",
3453 wpa_key_mgmt_txt(ik->akmp, WPA_PROTO_RSN));
3454 pos += wpa_scnprintf(pos, end - pos, "npk=");
3455 pos += wpa_snprintf_hex(pos, end - pos, wpabuf_head(ik->pmk),
3456 wpabuf_len(ik->pmk));
3457 pos += wpa_scnprintf(pos, end - pos, "\n");
3458 }
3459
3460 return pos - reply;
3461 }
3462 #endif /* CONFIG_PASN */
3463
3464
3465 /* Format: NAN_PEER_INFO <addr>
3466 * <schedule|potential|capa|bootstrap|pairing> [map_id] */
wpas_nan_peer_info(struct wpa_supplicant * wpa_s,const char * cmd,char * reply,size_t reply_size)3467 int wpas_nan_peer_info(struct wpa_supplicant *wpa_s, const char *cmd,
3468 char *reply, size_t reply_size)
3469 {
3470 u8 addr[ETH_ALEN];
3471 char *pos;
3472 int ret = 0;
3473
3474 if (!wpas_nan_ready(wpa_s))
3475 return -1;
3476
3477 if (hwaddr_aton(cmd, addr) < 0) {
3478 wpa_printf(MSG_INFO, "NAN: Invalid peer address: %s", cmd);
3479 return -1;
3480 }
3481
3482 pos = os_strchr(cmd, ' ');
3483 if (!pos) {
3484 wpa_printf(MSG_INFO, "NAN: Missing info type parameter");
3485 return -1;
3486 }
3487
3488 if (os_strncmp(pos + 1, "schedule", 8) == 0) {
3489 struct nan_peer_schedule sched;
3490
3491 if (nan_peer_get_schedule_info(wpa_s->nan, addr, &sched) < 0) {
3492 wpa_printf(MSG_INFO,
3493 "NAN: Failed to get schedule info for peer "
3494 MACSTR, MAC2STR(addr));
3495 return -1;
3496 }
3497
3498 ret = nan_peer_dump_sched_to_buf(&sched, reply, reply_size);
3499 } else if (os_strncmp(pos + 1, "potential", 9) == 0) {
3500 struct nan_peer_potential_avail pot_avail;
3501
3502 if (nan_peer_get_pot_avail(wpa_s->nan, addr, &pot_avail) < 0) {
3503 wpa_printf(MSG_INFO,
3504 "NAN: Failed to get potential availability for peer "
3505 MACSTR, MAC2STR(addr));
3506 return -1;
3507 }
3508
3509 ret = nan_peer_dump_pot_avail_to_buf(&pot_avail, reply,
3510 reply_size);
3511 } else if (os_strncmp(pos + 1, "capa", 4) == 0) {
3512 int map_id = 0;
3513 const struct nan_device_capabilities *capa;
3514 int written = 0;
3515 char *m;
3516
3517 m = os_strchr(pos + 1, ' ');
3518 if (m)
3519 map_id = atoi(m + 1);
3520
3521 capa = nan_peer_get_device_capabilities(wpa_s->nan, addr,
3522 map_id);
3523 if (!capa) {
3524 wpa_printf(MSG_INFO,
3525 "NAN: Failed to get capabilities for peer "
3526 MACSTR, MAC2STR(addr));
3527 return -1;
3528 }
3529
3530 written += wpa_scnprintf(reply + written, reply_size - written,
3531 "supported_bands=0x%02x\n",
3532 capa->supported_bands);
3533 written += wpa_scnprintf(reply + written, reply_size - written,
3534 "op_modes=0x%04x\n", capa->op_mode);
3535 written += wpa_scnprintf(reply + written, reply_size - written,
3536 "cdw_info=0x%04x\n", capa->cdw_info);
3537 written += wpa_scnprintf(reply + written, reply_size - written,
3538 "n_antennas=%d\n", capa->n_antennas);
3539 written += wpa_scnprintf(reply + written, reply_size - written,
3540 "channel_switch_time=%d\n",
3541 capa->channel_switch_time);
3542 written += wpa_scnprintf(reply + written, reply_size - written,
3543 "capabilities=0x%02x\n", capa->capa);
3544
3545 ret = written;
3546 } else if (os_strncmp(pos + 1, "bootstrap", 9) == 0) {
3547 u16 supported_methods;
3548
3549 if (nan_bootstrap_get_supported_methods(wpa_s->nan, addr,
3550 &supported_methods) <
3551 0) {
3552 wpa_printf(MSG_INFO,
3553 "NAN: Failed to get bootstrap methods for peer "
3554 MACSTR, MAC2STR(addr));
3555 return -1;
3556 }
3557
3558 ret = wpa_scnprintf(reply, reply_size,
3559 "supported_methods=0x%04x\n",
3560 supported_methods);
3561 #ifdef CONFIG_PASN
3562 } else if (os_strncmp(pos + 1, "pairing", 7) == 0) {
3563 const struct nan_pairing_cfg *pairing_cfg;
3564 const struct wpa_dev_ik *ik = NULL;
3565 const u8 *nonce = NULL;
3566 const u8 *tag = NULL;
3567
3568 pairing_cfg = nan_peer_get_pairing_cfg(wpa_s->nan, addr,
3569 &nonce, &tag);
3570 if (!pairing_cfg) {
3571 wpa_printf(MSG_DEBUG,
3572 "NAN: Failed to get pairing config for peer "
3573 MACSTR, MAC2STR(addr));
3574 return -1;
3575 }
3576
3577 ret = wpa_scnprintf(reply, reply_size,
3578 "pairing_setup=%d\n"
3579 "npk_caching=%d\n"
3580 "pairing_verification=%d\n"
3581 "cipher_suites=0x%08x\n",
3582 pairing_cfg->pairing_setup,
3583 pairing_cfg->npk_caching,
3584 pairing_cfg->pairing_verification,
3585 pairing_cfg->cipher_suites);
3586
3587 /* Try to find matching NIK if nonce and tag are available */
3588 if (nonce && tag)
3589 ik = wpas_nan_find_ik_by_nonce_tag(wpa_s, addr, nonce,
3590 tag);
3591
3592 if (ik)
3593 ret += wpas_nan_append_ik_info(reply + ret,
3594 reply_size - ret, ik);
3595 #endif /* CONFIG_PASN */
3596 } else if (os_strncmp(pos + 1, "ndps", 4) == 0) {
3597 ret = nan_peer_dump_ndps_to_buf(wpa_s->nan, addr, reply,
3598 reply_size);
3599 if (ret < 0) {
3600 wpa_printf(MSG_DEBUG,
3601 "NAN: Failed to get NDPs for peer " MACSTR,
3602 MAC2STR(addr));
3603 return -1;
3604 }
3605 } else {
3606 wpa_printf(MSG_INFO, "NAN: Unknown info type: %s", pos + 1);
3607 ret = -1;
3608 }
3609
3610 return ret;
3611 }
3612
3613
3614 /*
3615 * Format: NAN_BOOTSTRAP <peer_nmi> <handle=<id>>
3616 * <req_instance_id=<id>> method=<number> [auth]
3617 */
wpas_nan_bootstrap_request(struct wpa_supplicant * wpa_s,char * cmd)3618 int wpas_nan_bootstrap_request(struct wpa_supplicant *wpa_s, char *cmd)
3619 {
3620 char *pos, *token, *context = NULL;
3621 int handle = 0;
3622 int req_instance_id = 0;
3623 u8 peer_nmi[ETH_ALEN];
3624 u16 bootstrap_method = 0;
3625 bool auth = false;
3626
3627 if (!wpas_nan_ndp_allowed(wpa_s))
3628 return -1;
3629
3630 /* Parse peer address first */
3631 if (hwaddr_aton(cmd, peer_nmi) < 0)
3632 return -1;
3633
3634 /* Move past the peer_mac address */
3635 pos = os_strchr(cmd, ' ');
3636 if (!pos)
3637 return -1;
3638 pos++;
3639
3640 while ((token = str_token(pos, " ", &context))) {
3641 if (sscanf(token, "handle=%i", &handle) == 1)
3642 continue;
3643
3644 if (sscanf(token, "req_instance_id=%i", &req_instance_id) == 1)
3645 continue;
3646
3647 if (os_strncmp(token, "method=", 7) == 0) {
3648 bootstrap_method = atoi(token + 7);
3649 continue;
3650 }
3651
3652 if (os_strcmp(token, "auth") == 0) {
3653 auth = true;
3654 continue;
3655 }
3656
3657 wpa_printf(MSG_INFO,
3658 "CTRL: Invalid NAN_BOOTSTRAP parameter: %s",
3659 token);
3660 return -1;
3661 }
3662
3663 if (!bootstrap_method) {
3664 wpa_printf(MSG_INFO, "CTRL: Missing NAN_BOOTSTRAP method");
3665 return -1;
3666 }
3667
3668 if (handle <= 0) {
3669 wpa_printf(MSG_INFO,
3670 "CTRL: Invalid or missing NAN_BOOTSTRAP handle");
3671 return -1;
3672 }
3673
3674 if (is_zero_ether_addr(peer_nmi)) {
3675 wpa_printf(MSG_INFO,
3676 "CTRL: Invalid or missing NAN_BOOTSTRAP address");
3677 return -1;
3678 }
3679
3680 return nan_bootstrap_request(wpa_s->nan, handle, peer_nmi,
3681 req_instance_id, bootstrap_method, auth);
3682 }
3683
3684
3685 /* Format: NAN_BOOTSTRAP_RESET <peer_nmi> */
wpas_nan_bootstrap_reset(struct wpa_supplicant * wpa_s,char * cmd)3686 int wpas_nan_bootstrap_reset(struct wpa_supplicant *wpa_s, char *cmd)
3687 {
3688 u8 peer_nmi[ETH_ALEN];
3689
3690 if (!wpas_nan_ndp_allowed(wpa_s))
3691 return -1;
3692
3693 if (hwaddr_aton(cmd, peer_nmi) < 0)
3694 return -1;
3695
3696 return nan_bootstrap_peer_reset(wpa_s->nan, peer_nmi);
3697 }
3698
3699
wpas_nan_de_add_extra_attrs(void * ctx,struct wpabuf * buf)3700 static void wpas_nan_de_add_extra_attrs(void *ctx, struct wpabuf *buf)
3701 {
3702 struct wpa_supplicant *wpa_s = ctx;
3703 struct nan_schedule sched;
3704 u32 map_ids = (BIT(wpa_s->nan_capa.num_radios) - 1) << 1;
3705 int i;
3706
3707 if (!wpas_nan_ndp_allowed(wpa_s) || !map_ids)
3708 return;
3709
3710 wpas_nan_fill_ndp_schedule(wpa_s, &sched);
3711 nan_add_dev_capa_attr(wpa_s->nan, buf);
3712 nan_convert_sched_to_avail_attrs(wpa_s->nan,
3713 wpa_s->schedule_sequence_id,
3714 map_ids, sched.n_chans,
3715 sched.chans, buf, true);
3716 nan_pairing_add_attrs(wpa_s->nan, buf);
3717
3718 if (!wpa_s->nan_ulw_attr)
3719 return;
3720
3721 /* Add ULW attribute only if there are committed availability entries */
3722 for (i = 0; i < sched.n_chans; i++) {
3723 if (sched.chans[i].committed.len) {
3724 wpabuf_put_buf(buf, wpa_s->nan_ulw_attr);
3725 break;
3726 }
3727 }
3728 }
3729
3730
wpas_nan_cluster_join(struct wpa_supplicant * wpa_s,const u8 * cluster_id,bool new_cluster)3731 void wpas_nan_cluster_join(struct wpa_supplicant *wpa_s,
3732 const u8 *cluster_id,
3733 bool new_cluster)
3734 {
3735 if (!wpas_nan_ready(wpa_s))
3736 return;
3737
3738 wpas_notify_nan_cluster_join(wpa_s, cluster_id, new_cluster);
3739
3740 nan_de_set_cluster_id(wpa_s->nan_de, cluster_id);
3741 nan_set_cluster_id(wpa_s->nan, cluster_id);
3742 }
3743
3744
wpas_nan_next_dw(struct wpa_supplicant * wpa_s,u32 freq)3745 void wpas_nan_next_dw(struct wpa_supplicant *wpa_s, u32 freq)
3746 {
3747 if (!wpas_nan_ready(wpa_s))
3748 return;
3749
3750 wpa_printf(MSG_DEBUG, "NAN: Next DW notification freq=%d", freq);
3751 nan_de_dw_trigger(wpa_s->nan_de, freq);
3752 }
3753
3754
wpas_nan_sched_update_done(struct wpa_supplicant * wpa_s,const union wpa_event_data * data)3755 void wpas_nan_sched_update_done(struct wpa_supplicant *wpa_s,
3756 const union wpa_event_data *data)
3757 {
3758 u8 map_id = wpa_s->nan_sched_update.map_id;
3759 bool success = data->nan_sched_update_done_info.success;
3760
3761 if (!wpas_nan_ready(wpa_s))
3762 return;
3763
3764 if (!wpa_s->nan_sched_update.sched.deferred) {
3765 wpa_printf(MSG_DEBUG, "NAN: Schedule update not in progress");
3766 return;
3767 }
3768
3769 nan_set_sched_update_pending(wpa_s->nan, false);
3770 wpas_notify_nan_sched_update_done(wpa_s, success);
3771
3772 if (!success) {
3773 clear_sched_config(&wpa_s->nan_sched_update.sched);
3774 wpa_printf(MSG_DEBUG, "NAN: Schedule update failed");
3775 return;
3776 }
3777
3778 clear_sched_config(&wpa_s->nan_sched[map_id - 1]);
3779 os_memcpy(&wpa_s->nan_sched[map_id - 1],
3780 &wpa_s->nan_sched_update.sched,
3781 sizeof(wpa_s->nan_sched_update.sched));
3782 os_memset(&wpa_s->nan_sched_update.sched, 0,
3783 sizeof(wpa_s->nan_sched_update.sched));
3784 wpa_s->schedule_sequence_id++;
3785
3786 wpas_nan_update_local_schedule(wpa_s);
3787 }
3788
3789
wpas_nan_ulw_update(struct wpa_supplicant * wpa_s,const u8 * ulw,size_t ulw_len)3790 void wpas_nan_ulw_update(struct wpa_supplicant *wpa_s,
3791 const u8 *ulw, size_t ulw_len)
3792 {
3793 if (!wpas_nan_ready(wpa_s))
3794 return;
3795
3796 wpabuf_free(wpa_s->nan_ulw_attr);
3797 if (ulw && ulw_len) {
3798 wpa_s->nan_ulw_attr = wpabuf_alloc_copy(ulw, ulw_len);
3799 if (!wpa_s->nan_ulw_attr) {
3800 wpa_printf(MSG_INFO,
3801 "NAN: Failed to allocate ULW attribute buffer");
3802 return;
3803 }
3804
3805 wpa_hexdump(MSG_DEBUG, "NAN: ULW update", ulw, ulw_len);
3806 } else {
3807 wpa_printf(MSG_DEBUG, "NAN: ULW update cleared");
3808 wpa_s->nan_ulw_attr = NULL;
3809 }
3810 }
3811
3812
wpas_nan_chan_evacuation(struct wpa_supplicant * wpa_s,const struct nan_chan_evacuation_info * info)3813 void wpas_nan_chan_evacuation(struct wpa_supplicant *wpa_s,
3814 const struct nan_chan_evacuation_info *info)
3815 {
3816 size_t map_id, i;
3817 int freq = info->freq;
3818
3819 if (!wpas_nan_ready(wpa_s))
3820 return;
3821
3822 wpa_printf(MSG_DEBUG, "NAN: Channel evacuation notification freq=%d",
3823 freq);
3824
3825 for (map_id = 0; map_id < MAX_NAN_RADIOS; map_id++) {
3826 struct nan_schedule_config *sched =
3827 &wpa_s->nan_sched[map_id];
3828
3829 for (i = 0; i < sched->num_channels; i++) {
3830 if (sched->channels[i].freq != freq)
3831 continue;
3832
3833 wpas_notify_nan_chan_evacuation(wpa_s, map_id, freq);
3834 break;
3835 }
3836 }
3837 }
3838
3839
3840 #ifdef CONFIG_PASN
3841
wpas_nan_pasn_update_station(struct wpa_supplicant * wpa_s,const u8 * nmi_addr)3842 static int wpas_nan_pasn_update_station(struct wpa_supplicant *wpa_s,
3843 const u8 *nmi_addr)
3844 {
3845 struct hostapd_sta_add_params params;
3846
3847 os_memset(¶ms, 0, sizeof(params));
3848 params.addr = nmi_addr;
3849 params.flags = WPA_STA_MFP;
3850 params.set = 1;
3851
3852 if (wpa_drv_sta_add(wpa_s, ¶ms) < 0) {
3853 wpa_printf(MSG_INFO, "NAN PASN: Failed to update PASN station "
3854 MACSTR, MAC2STR(nmi_addr));
3855 return -1;
3856 }
3857
3858 return 0;
3859 }
3860
3861
3862 /**
3863 * wpas_nan_pair - Initiate NAN pairing with a peer device
3864 * @wpa_s: Pointer to wpa_supplicant data structure
3865 * @peer_addr: MAC address of the peer device to pair with
3866 * @auth_mode: Authentication mode to use for pairing
3867 * @cipher: Cipher suite to use for the pairing session
3868 * @handle: Handle of the service for which pairing is requested
3869 * @peer_instance_id: Instance ID of the peer service
3870 * @responder: True if the local device is the responder, false if initiator
3871 * @password: Password for PASN authentication
3872 * Returns: 0 on success, -1 on failure
3873 */
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)3874 int wpas_nan_pair(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
3875 u8 auth_mode, int cipher, int handle, u8 peer_instance_id,
3876 bool responder, const char *password)
3877 {
3878 int ret;
3879 struct nan_schedule sched;
3880
3881 if (!wpas_nan_ndp_allowed(wpa_s))
3882 return -1;
3883
3884 wpas_nan_fill_ndp_schedule(wpa_s, &sched);
3885 ret = nan_pairing_initiate_pasn_auth(wpa_s->nan, peer_addr, auth_mode,
3886 cipher, handle, peer_instance_id,
3887 responder, password, &sched);
3888 if (!ret)
3889 ret = wpas_nan_pasn_update_station(wpa_s, peer_addr);
3890 else
3891 wpa_printf(MSG_INFO,
3892 "NAN PASN: Failed to start PASN authentication");
3893
3894 return ret;
3895 }
3896
3897
3898 /*
3899 * Format: NAN_PAIR <peer_nmi> <handle=<id>>
3900 * <peer_instance_id=<id>> <auth=<0|1|2>> <cipher=<CCMP|GCMP-256>>
3901 * [responder] [password=<password>|pwd_hex=<hex>]
3902 */
wpas_nan_pairing_start(struct wpa_supplicant * wpa_s,char * cmd)3903 int wpas_nan_pairing_start(struct wpa_supplicant *wpa_s, char *cmd)
3904 {
3905 char *token, *context = NULL;
3906 u8 addr[ETH_ALEN];
3907 u8 auth_mode = 0;
3908 u8 peer_instance_id = 0;
3909 int handle = 0;
3910 int cipher = WPA_CIPHER_NONE;
3911 char *password = NULL, *password_hex = NULL;
3912 char *password_decoded = NULL;
3913 bool responder = false;
3914 char *pos;
3915
3916 /* Parse peer address first */
3917 if (hwaddr_aton(cmd, addr) < 0)
3918 return -1;
3919
3920 /* Move past the peer_mac address */
3921 pos = os_strchr(cmd, ' ');
3922 if (!pos)
3923 return -1;
3924 pos++;
3925
3926 while ((token = str_token(pos, " ", &context))) {
3927 if (os_strncmp(token, "auth=", 5) == 0) {
3928 auth_mode = atoi(token + 5);
3929 if (auth_mode > 2) {
3930 wpa_printf(MSG_INFO,
3931 "NAN_PAIR: Invalid auth mode: %u",
3932 auth_mode);
3933 return -1;
3934 }
3935 } else if (os_strncmp(token, "handle=", 7) == 0) {
3936 handle = atoi(token + 7);
3937 } else if (os_strncmp(token, "peer_instance_id=", 17) == 0) {
3938 peer_instance_id = atoi(token + 17);
3939 } else if (os_strncmp(token, "cipher=", 7) == 0) {
3940 if (os_strcmp(token + 7, "CCMP") == 0) {
3941 cipher = WPA_CIPHER_CCMP;
3942 } else if (os_strcmp(token + 7, "GCMP-256") == 0) {
3943 cipher = WPA_CIPHER_GCMP_256;
3944 } else {
3945 wpa_printf(MSG_INFO,
3946 "NAN_PAIR: Invalid cipher: '%s'",
3947 token + 7);
3948 return -1;
3949 }
3950 } else if (os_strncmp(token, "responder", 9) == 0) {
3951 responder = true;
3952 } else if (os_strncmp(token, "password=", 9) == 0) {
3953 password = token + 9;
3954 } else if (os_strncmp(token, "pwd_hex=", 8) == 0) {
3955 password_hex = token + 8;
3956 } else {
3957 wpa_printf(MSG_INFO,
3958 "NAN_PAIR: Invalid parameter: '%s'",
3959 token);
3960 return -1;
3961 }
3962 }
3963
3964 if (handle <= 0) {
3965 wpa_printf(MSG_INFO, "NAN_PAIR: missing or invalid handle");
3966 return -1;
3967 }
3968
3969 if (!peer_instance_id) {
3970 wpa_printf(MSG_INFO,
3971 "NAN_PAIR: missing or invalid peer_instance_id");
3972 return -1;
3973 }
3974
3975 if (cipher == WPA_CIPHER_NONE) {
3976 wpa_printf(MSG_INFO, "NAN_PAIR: missing cipher");
3977 return -1;
3978 }
3979
3980 if (password && password_hex) {
3981 wpa_printf(MSG_DEBUG,
3982 "NAN_PAIR: Specify only one of password or pwd_hex");
3983 return -1;
3984 }
3985
3986 if (password_hex) {
3987 password_decoded = wpas_nan_parse_password_hex(password_hex);
3988 if (!password_decoded)
3989 return -1;
3990 }
3991
3992 if (wpas_nan_pair(wpa_s, addr, auth_mode, cipher, handle,
3993 peer_instance_id, responder,
3994 password_decoded ? password_decoded : password) < 0) {
3995 str_clear_free(password_decoded);
3996 wpa_printf(MSG_INFO, "NAN_PAIR: Pairing initiation failed");
3997 return -1;
3998 }
3999
4000 str_clear_free(password_decoded);
4001
4002 return 0;
4003 }
4004
4005
wpas_nan_pasn_auth_tx_status(struct wpa_supplicant * wpa_s,const u8 * data,size_t data_len,bool acked)4006 int wpas_nan_pasn_auth_tx_status(struct wpa_supplicant *wpa_s, const u8 *data,
4007 size_t data_len, bool acked)
4008 {
4009 struct nan_data *nan = wpa_s->nan;
4010
4011 return nan_pairing_pasn_auth_tx_status(nan, data, data_len, acked);
4012 }
4013
4014
wpas_nan_pairing_abort(struct wpa_supplicant * wpa_s,const char * cmd)4015 int wpas_nan_pairing_abort(struct wpa_supplicant *wpa_s, const char *cmd)
4016 {
4017 u8 addr[ETH_ALEN];
4018 struct nan_data *nan = wpa_s->nan;
4019
4020 if (!nan) {
4021 wpa_printf(MSG_INFO, "NAN_PAIR_ABORT: NAN not initialized");
4022 return -1;
4023 }
4024
4025 if (hwaddr_aton(cmd, addr)) {
4026 wpa_printf(MSG_INFO,
4027 "NAN_PAIR_ABORT: Invalid peer address: '%s'", cmd);
4028 return -1;
4029 }
4030
4031 if (nan_pairing_abort(nan, addr) < 0) {
4032 wpa_printf(MSG_INFO,
4033 "NAN_PAIR_ABORT: Abort failed for peer " MACSTR,
4034 MAC2STR(addr));
4035 return -1;
4036 }
4037
4038 return 0;
4039 }
4040
4041
wpas_nan_pasn_auth_rx(struct wpa_supplicant * wpa_s,const struct ieee80211_mgmt * mgmt,size_t len)4042 int wpas_nan_pasn_auth_rx(struct wpa_supplicant *wpa_s,
4043 const struct ieee80211_mgmt *mgmt, size_t len)
4044 {
4045 struct nan_data *nan = wpa_s->nan;
4046
4047 if (!nan || !wpas_nan_ndp_allowed(wpa_s))
4048 return -1;
4049
4050 return nan_pairing_auth_rx(nan, mgmt, len);
4051 }
4052
4053 #endif /* CONFIG_PASN */
4054
4055
wpas_nan_is_peer_paired(struct wpa_supplicant * wpa_s,const u8 * peer_addr)4056 bool wpas_nan_is_peer_paired(struct wpa_supplicant *wpa_s, const u8 *peer_addr)
4057 {
4058 if (!wpa_s->nan)
4059 return false;
4060
4061 return nan_pairing_is_peer_paired(wpa_s->nan, peer_addr);
4062 }
4063
4064 #endif /* CONFIG_NAN */
4065
4066
4067 static const char *
tx_status_result_txt(enum offchannel_send_action_result result)4068 tx_status_result_txt(enum offchannel_send_action_result result)
4069 {
4070 switch (result) {
4071 case OFFCHANNEL_SEND_ACTION_SUCCESS:
4072 return "success";
4073 case OFFCHANNEL_SEND_ACTION_NO_ACK:
4074 return "no-ack";
4075 case OFFCHANNEL_SEND_ACTION_FAILED:
4076 return "failed";
4077 }
4078
4079 return "?";
4080 }
4081
4082
wpas_nan_de_tx_status(struct wpa_supplicant * wpa_s,unsigned int freq,const u8 * dst,const u8 * src,const u8 * bssid,const u8 * data,size_t data_len,enum offchannel_send_action_result result)4083 static void wpas_nan_de_tx_status(struct wpa_supplicant *wpa_s,
4084 unsigned int freq, const u8 *dst,
4085 const u8 *src, const u8 *bssid,
4086 const u8 *data, size_t data_len,
4087 enum offchannel_send_action_result result)
4088 {
4089 if (!wpa_s->nan_de)
4090 return;
4091
4092 wpa_printf(MSG_DEBUG, "NAN: TX status A1=" MACSTR " A2=" MACSTR
4093 " A3=" MACSTR " freq=%d len=%zu result=%s",
4094 MAC2STR(dst), MAC2STR(src), MAC2STR(bssid), freq,
4095 data_len, tx_status_result_txt(result));
4096
4097 nan_de_tx_status(wpa_s->nan_de, freq, dst, data, data_len,
4098 result == OFFCHANNEL_SEND_ACTION_SUCCESS);
4099 }
4100
4101
4102 struct wpas_nan_usd_tx_work {
4103 unsigned int freq;
4104 unsigned int wait_time;
4105 u8 dst[ETH_ALEN];
4106 u8 src[ETH_ALEN];
4107 u8 bssid[ETH_ALEN];
4108 struct wpabuf *buf;
4109 };
4110
4111
wpas_nan_usd_tx_work_free(struct wpas_nan_usd_tx_work * twork)4112 static void wpas_nan_usd_tx_work_free(struct wpas_nan_usd_tx_work *twork)
4113 {
4114 if (!twork)
4115 return;
4116 wpabuf_free(twork->buf);
4117 os_free(twork);
4118 }
4119
4120
wpas_nan_usd_tx_work_done(struct wpa_supplicant * wpa_s)4121 static void wpas_nan_usd_tx_work_done(struct wpa_supplicant *wpa_s)
4122 {
4123 struct wpas_nan_usd_tx_work *twork;
4124
4125 if (!wpa_s->nan_usd_tx_work)
4126 return;
4127
4128 twork = wpa_s->nan_usd_tx_work->ctx;
4129 wpas_nan_usd_tx_work_free(twork);
4130 radio_work_done(wpa_s->nan_usd_tx_work);
4131 wpa_s->nan_usd_tx_work = NULL;
4132 }
4133
4134
wpas_nan_de_tx_send(struct wpa_supplicant * wpa_s,unsigned int freq,unsigned int wait_time,const u8 * dst,const u8 * src,const u8 * bssid,const struct wpabuf * buf)4135 static int wpas_nan_de_tx_send(struct wpa_supplicant *wpa_s, unsigned int freq,
4136 unsigned int wait_time, const u8 *dst,
4137 const u8 *src, const u8 *bssid,
4138 const struct wpabuf *buf)
4139 {
4140 wpa_printf(MSG_DEBUG, "NAN: TX NAN SDF A1=" MACSTR " A2=" MACSTR
4141 " A3=" MACSTR " freq=%d len=%zu",
4142 MAC2STR(dst), MAC2STR(src), MAC2STR(bssid), freq,
4143 wpabuf_len(buf));
4144
4145 return offchannel_send_action(wpa_s, freq, dst, src, bssid,
4146 wpabuf_head(buf), wpabuf_len(buf),
4147 wait_time, wpas_nan_de_tx_status, 1);
4148 }
4149
4150
wpas_nan_usd_start_tx_cb(struct wpa_radio_work * work,int deinit)4151 static void wpas_nan_usd_start_tx_cb(struct wpa_radio_work *work, int deinit)
4152 {
4153 struct wpa_supplicant *wpa_s = work->wpa_s;
4154 struct wpas_nan_usd_tx_work *twork = work->ctx;
4155
4156 if (deinit) {
4157 if (work->started) {
4158 wpa_s->nan_usd_tx_work = NULL;
4159 offchannel_send_action_done(wpa_s);
4160 }
4161 wpas_nan_usd_tx_work_free(twork);
4162 return;
4163 }
4164
4165 wpa_s->nan_usd_tx_work = work;
4166
4167 if (wpas_nan_de_tx_send(wpa_s, twork->freq, twork->wait_time,
4168 twork->dst, twork->src, twork->bssid,
4169 twork->buf) < 0)
4170 wpas_nan_usd_tx_work_done(wpa_s);
4171 }
4172
4173
wpas_nan_de_tx(void * ctx,unsigned int freq,unsigned int wait_time,const u8 * dst,const u8 * src,const u8 * bssid,const struct wpabuf * buf)4174 static int wpas_nan_de_tx(void *ctx, unsigned int freq, unsigned int wait_time,
4175 const u8 *dst, const u8 *src, const u8 *bssid,
4176 const struct wpabuf *buf)
4177 {
4178 struct wpa_supplicant *wpa_s = ctx;
4179 struct wpas_nan_usd_tx_work *twork;
4180
4181 if (!freq && !wait_time) {
4182 int ret;
4183
4184 wpa_printf(MSG_DEBUG, "NAN: SYNC TX NAN SDF A1=" MACSTR " A2="
4185 MACSTR " A3=" MACSTR " len=%zu",
4186 MAC2STR(dst), MAC2STR(src), MAC2STR(bssid),
4187 wpabuf_len(buf));
4188 ret = wpa_drv_send_action(wpa_s, 0, 0, dst, src, bssid,
4189 wpabuf_head(buf), wpabuf_len(buf),
4190 1);
4191 if (ret)
4192 wpa_printf(MSG_DEBUG,
4193 "NAN: Failed to send sync action frame (%d)",
4194 ret);
4195 return ret;
4196 }
4197
4198 if (wpa_s->nan_usd_tx_work || wpa_s->nan_usd_listen_work) {
4199 /* Reuse ongoing radio work */
4200 return wpas_nan_de_tx_send(wpa_s, freq, wait_time, dst, src,
4201 bssid, buf);
4202 }
4203
4204 twork = os_zalloc(sizeof(*twork));
4205 if (!twork)
4206 return -1;
4207 twork->freq = freq;
4208 twork->wait_time = wait_time;
4209 os_memcpy(twork->dst, dst, ETH_ALEN);
4210 os_memcpy(twork->src, src, ETH_ALEN);
4211 os_memcpy(twork->bssid, bssid, ETH_ALEN);
4212 twork->buf = wpabuf_dup(buf);
4213 if (!twork->buf) {
4214 wpas_nan_usd_tx_work_free(twork);
4215 return -1;
4216 }
4217
4218 if (!radio_add_work(wpa_s, freq, "nan-usd-tx", 0,
4219 wpas_nan_usd_start_tx_cb, twork)) {
4220 wpas_nan_usd_tx_work_free(twork);
4221 return -1;
4222 }
4223
4224 return 0;
4225 }
4226
4227
4228 struct wpas_nan_usd_listen_work {
4229 unsigned int freq;
4230 unsigned int duration;
4231 u8 forced_addr[ETH_ALEN];
4232 bool forced_addr_set;
4233 };
4234
4235
wpas_nan_usd_listen_work_done(struct wpa_supplicant * wpa_s)4236 static void wpas_nan_usd_listen_work_done(struct wpa_supplicant *wpa_s)
4237 {
4238 struct wpas_nan_usd_listen_work *lwork;
4239
4240 if (!wpa_s->nan_usd_listen_work)
4241 return;
4242
4243 lwork = wpa_s->nan_usd_listen_work->ctx;
4244 os_free(lwork);
4245 radio_work_done(wpa_s->nan_usd_listen_work);
4246 wpa_s->nan_usd_listen_work = NULL;
4247 }
4248
4249
wpas_nan_usd_remain_on_channel_timeout(void * eloop_ctx,void * timeout_ctx)4250 static void wpas_nan_usd_remain_on_channel_timeout(void *eloop_ctx,
4251 void *timeout_ctx)
4252 {
4253 struct wpa_supplicant *wpa_s = eloop_ctx;
4254 struct wpas_nan_usd_listen_work *lwork = timeout_ctx;
4255
4256 wpas_nan_usd_cancel_remain_on_channel_cb(wpa_s, lwork->freq);
4257 }
4258
4259
wpas_nan_usd_start_listen_cb(struct wpa_radio_work * work,int deinit)4260 static void wpas_nan_usd_start_listen_cb(struct wpa_radio_work *work,
4261 int deinit)
4262 {
4263 struct wpa_supplicant *wpa_s = work->wpa_s;
4264 struct wpas_nan_usd_listen_work *lwork = work->ctx;
4265 unsigned int duration;
4266
4267 if (deinit) {
4268 if (work->started) {
4269 wpa_s->nan_usd_listen_work = NULL;
4270 wpa_drv_cancel_remain_on_channel(wpa_s);
4271 }
4272 os_free(lwork);
4273 return;
4274 }
4275
4276 wpa_s->nan_usd_listen_work = work;
4277
4278 duration = lwork->duration;
4279 if (duration > wpa_s->max_remain_on_chan)
4280 duration = wpa_s->max_remain_on_chan;
4281 wpa_printf(MSG_DEBUG, "NAN: Start listen on %u MHz for %u ms",
4282 lwork->freq, duration);
4283 if (wpa_drv_remain_on_channel(wpa_s, lwork->freq, duration,
4284 (lwork->forced_addr_set &&
4285 (wpa_s->drv_flags2 &
4286 WPA_DRIVER_FLAGS2_ROC_ADDR_FILTER)) ?
4287 lwork->forced_addr : NULL) < 0) {
4288 wpa_printf(MSG_DEBUG,
4289 "NAN: Failed to request the driver to remain on channel (%u MHz) for listen",
4290 lwork->freq);
4291 eloop_cancel_timeout(wpas_nan_usd_remain_on_channel_timeout,
4292 wpa_s, ELOOP_ALL_CTX);
4293 /* Restart the listen state after a delay */
4294 eloop_register_timeout(0, 500,
4295 wpas_nan_usd_remain_on_channel_timeout,
4296 wpa_s, lwork);
4297 wpas_nan_usd_listen_work_done(wpa_s);
4298 return;
4299 }
4300 }
4301
4302
wpas_nan_de_listen(void * ctx,unsigned int freq,unsigned int duration,const u8 * forced_addr)4303 static int wpas_nan_de_listen(void *ctx, unsigned int freq,
4304 unsigned int duration, const u8 *forced_addr)
4305 {
4306 struct wpa_supplicant *wpa_s = ctx;
4307 struct wpas_nan_usd_listen_work *lwork;
4308
4309 lwork = os_zalloc(sizeof(*lwork));
4310 if (!lwork)
4311 return -1;
4312 lwork->freq = freq;
4313 lwork->duration = duration;
4314 if (forced_addr) {
4315 os_memcpy(lwork->forced_addr, forced_addr, ETH_ALEN);
4316 lwork->forced_addr_set = true;
4317 }
4318
4319 if (!radio_add_work(wpa_s, freq, "nan-usd-listen", 0,
4320 wpas_nan_usd_start_listen_cb, lwork)) {
4321 os_free(lwork);
4322 return -1;
4323 }
4324
4325 return 0;
4326 }
4327
4328
4329 static void
wpas_nan_de_discovery_result(void * ctx,struct nan_discovery_result * res)4330 wpas_nan_de_discovery_result(void *ctx, struct nan_discovery_result *res)
4331 {
4332 struct wpa_supplicant *wpa_s = ctx;
4333
4334 wpas_notify_nan_discovery_result(wpa_s, res);
4335 }
4336
4337
wpas_nan_de_replied(void * ctx,int publish_id,const u8 * peer_addr,int peer_subscribe_id,enum nan_service_protocol_type srv_proto_type,const u8 * ssi,size_t ssi_len)4338 static void wpas_nan_de_replied(void *ctx, int publish_id, const u8 *peer_addr,
4339 int peer_subscribe_id,
4340 enum nan_service_protocol_type srv_proto_type,
4341 const u8 *ssi, size_t ssi_len)
4342 {
4343 struct wpa_supplicant *wpa_s = ctx;
4344
4345 wpas_notify_nan_replied(wpa_s, srv_proto_type, publish_id,
4346 peer_subscribe_id, peer_addr, ssi, ssi_len);
4347 }
4348
4349
wpas_nan_de_publish_terminated(void * ctx,int publish_id,enum nan_de_reason reason)4350 static void wpas_nan_de_publish_terminated(void *ctx, int publish_id,
4351 enum nan_de_reason reason)
4352 {
4353 struct wpa_supplicant *wpa_s = ctx;
4354
4355 wpas_notify_nan_publish_terminated(wpa_s, publish_id, reason);
4356 }
4357
4358
wpas_nan_usd_offload_cancel_publish(void * ctx,int publish_id)4359 static void wpas_nan_usd_offload_cancel_publish(void *ctx, int publish_id)
4360 {
4361 struct wpa_supplicant *wpa_s = ctx;
4362
4363 if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD)
4364 wpas_drv_nan_cancel_publish(wpa_s, publish_id);
4365 }
4366
4367
wpas_nan_de_subscribe_terminated(void * ctx,int subscribe_id,enum nan_de_reason reason)4368 static void wpas_nan_de_subscribe_terminated(void *ctx, int subscribe_id,
4369 enum nan_de_reason reason)
4370 {
4371 struct wpa_supplicant *wpa_s = ctx;
4372
4373 wpas_notify_nan_subscribe_terminated(wpa_s, subscribe_id, reason);
4374 }
4375
4376
wpas_nan_usd_offload_cancel_subscribe(void * ctx,int subscribe_id)4377 static void wpas_nan_usd_offload_cancel_subscribe(void *ctx, int subscribe_id)
4378 {
4379 struct wpa_supplicant *wpa_s = ctx;
4380
4381 if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD)
4382 wpas_drv_nan_cancel_subscribe(wpa_s, subscribe_id);
4383 }
4384
4385
wpas_nan_de_receive(void * ctx,int id,int peer_instance_id,const u8 * ssi,size_t ssi_len,const u8 * peer_addr,const u8 * buf,size_t len)4386 static void wpas_nan_de_receive(void *ctx, int id, int peer_instance_id,
4387 const u8 *ssi, size_t ssi_len,
4388 const u8 *peer_addr,
4389 const u8 *buf, size_t len)
4390 {
4391 struct wpa_supplicant *wpa_s = ctx;
4392
4393 #ifdef CONFIG_NAN
4394 if (nan_process_followup(wpa_s->nan, peer_addr, buf, len,
4395 peer_instance_id, id))
4396 return;
4397 #endif /* CONFIG_NAN */
4398
4399 wpas_notify_nan_receive(wpa_s, id, peer_instance_id, peer_addr,
4400 ssi, ssi_len);
4401 }
4402
4403
wpas_nan_de_transmit_req_status(void * ctx,u32 cookie,bool ack)4404 static void wpas_nan_de_transmit_req_status(void *ctx, u32 cookie, bool ack)
4405 {
4406 struct wpa_supplicant *wpa_s = ctx;
4407
4408 wpas_notify_nan_transmit_req_status(wpa_s, cookie, ack);
4409 }
4410
4411
4412 #ifdef CONFIG_P2P
wpas_nan_process_p2p_usd_elems(void * ctx,const u8 * buf,u16 buf_len,const u8 * peer_addr,unsigned int freq)4413 static void wpas_nan_process_p2p_usd_elems(void *ctx, const u8 *buf,
4414 u16 buf_len, const u8 *peer_addr,
4415 unsigned int freq)
4416 {
4417 struct wpa_supplicant *wpa_s = ctx;
4418
4419 wpas_p2p_process_usd_elems(wpa_s, buf, buf_len, peer_addr, freq);
4420 }
4421 #endif /* CONFIG_P2P */
4422
4423
4424 #ifdef CONFIG_PR
wpas_nan_process_pr_usd_elems(void * ctx,const u8 * buf,u16 buf_len,const u8 * peer_addr,unsigned int freq)4425 static void wpas_nan_process_pr_usd_elems(void *ctx, const u8 *buf, u16 buf_len,
4426 const u8 *peer_addr,
4427 unsigned int freq)
4428 {
4429 struct wpa_supplicant *wpa_s = ctx;
4430
4431 wpas_pr_process_usd_elems(wpa_s, buf, buf_len, peer_addr, freq);
4432 }
4433 #endif /* CONFIG_PR */
4434
4435
4436 #if defined(CONFIG_NAN) && defined(CONFIG_PASN)
wpas_nan_is_peer_paired_cb(void * ctx,const u8 * peer_addr)4437 static bool wpas_nan_is_peer_paired_cb(void *ctx, const u8 *peer_addr)
4438 {
4439 struct wpa_supplicant *wpa_s = ctx;
4440
4441 return wpas_nan_is_peer_paired(wpa_s, peer_addr);
4442 }
4443 #endif /* CONFIG_NAN && CONFIG_PASN */
4444
4445
wpas_nan_de_init(struct wpa_supplicant * wpa_s)4446 int wpas_nan_de_init(struct wpa_supplicant *wpa_s)
4447 {
4448 struct nan_callbacks cb;
4449 bool offload = !!(wpa_s->drv_flags2 &
4450 WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD);
4451
4452 os_memset(&cb, 0, sizeof(cb));
4453 cb.ctx = wpa_s;
4454 cb.tx = wpas_nan_de_tx;
4455 cb.listen = wpas_nan_de_listen;
4456 cb.discovery_result = wpas_nan_de_discovery_result;
4457 cb.replied = wpas_nan_de_replied;
4458 cb.publish_terminated = wpas_nan_de_publish_terminated;
4459 cb.subscribe_terminated = wpas_nan_de_subscribe_terminated;
4460 cb.offload_cancel_publish = wpas_nan_usd_offload_cancel_publish;
4461 cb.offload_cancel_subscribe = wpas_nan_usd_offload_cancel_subscribe;
4462 cb.receive = wpas_nan_de_receive;
4463 cb.transmit_req_status = wpas_nan_de_transmit_req_status;
4464 #ifdef CONFIG_P2P
4465 cb.process_p2p_usd_elems = wpas_nan_process_p2p_usd_elems;
4466 #endif /* CONFIG_P2P */
4467 #ifdef CONFIG_PR
4468 cb.process_pr_usd_elems = wpas_nan_process_pr_usd_elems;
4469 #endif /* CONFIG_PR */
4470 #ifdef CONFIG_NAN
4471 cb.add_extra_attrs = wpas_nan_de_add_extra_attrs;
4472 #ifdef CONFIG_PASN
4473 cb.is_peer_paired = wpas_nan_is_peer_paired_cb;
4474 #endif /* CONFIG_PASN */
4475 #endif /* CONFIG_NAN */
4476
4477 wpa_s->nan_de = nan_de_init(wpa_s->own_addr, offload, false,
4478 wpa_s->max_remain_on_chan, &cb);
4479 if (!wpa_s->nan_de)
4480 return -1;
4481 return 0;
4482 }
4483
4484
wpas_nan_de_deinit(struct wpa_supplicant * wpa_s)4485 void wpas_nan_de_deinit(struct wpa_supplicant *wpa_s)
4486 {
4487 eloop_cancel_timeout(wpas_nan_usd_remain_on_channel_timeout,
4488 wpa_s, ELOOP_ALL_CTX);
4489 nan_de_deinit(wpa_s->nan_de);
4490 wpa_s->nan_de = NULL;
4491 }
4492
4493
wpas_nan_de_rx_sdf(struct wpa_supplicant * wpa_s,const u8 * src,const u8 * a3,unsigned int freq,const u8 * buf,size_t len,int rssi)4494 void wpas_nan_de_rx_sdf(struct wpa_supplicant *wpa_s, const u8 *src,
4495 const u8 *a3, unsigned int freq,
4496 const u8 *buf, size_t len, int rssi)
4497 {
4498 bool store_peer;
4499
4500 if (!wpa_s->nan_de)
4501 return;
4502
4503 store_peer = nan_de_rx_sdf(wpa_s->nan_de, src, a3, freq, buf,
4504 len, rssi);
4505
4506 if (!store_peer)
4507 return;
4508
4509 #ifdef CONFIG_NAN
4510 if (!wpas_nan_ready(wpa_s))
4511 return;
4512
4513 nan_add_peer(wpa_s->nan, src, buf, len);
4514 #endif /* CONFIG_NAN */
4515 }
4516
4517
wpas_nan_de_flush(struct wpa_supplicant * wpa_s)4518 void wpas_nan_de_flush(struct wpa_supplicant *wpa_s)
4519 {
4520 if (!wpa_s->nan_de)
4521 return;
4522 nan_de_flush(wpa_s->nan_de);
4523 if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD)
4524 wpas_drv_nan_flush(wpa_s);
4525 }
4526
4527
wpas_nan_publish(struct wpa_supplicant * wpa_s,const char * service_name,enum nan_service_protocol_type srv_proto_type,const struct wpabuf * ssi,struct nan_publish_params * params,bool p2p)4528 int wpas_nan_publish(struct wpa_supplicant *wpa_s, const char *service_name,
4529 enum nan_service_protocol_type srv_proto_type,
4530 const struct wpabuf *ssi,
4531 struct nan_publish_params *params, bool p2p)
4532 {
4533 int publish_id;
4534 struct wpabuf *elems = NULL;
4535 const u8 *addr;
4536
4537 if (!wpa_s->nan_de)
4538 return -1;
4539
4540 if (params->proximity_ranging && !params->solicited) {
4541 wpa_printf(MSG_INFO,
4542 "PR unsolicited publish service discovery not allowed");
4543 return -1;
4544 }
4545
4546 addr = wpa_s->own_addr;
4547
4548 #ifdef CONFIG_NAN
4549 if (params->sync) {
4550 if (!(wpa_s->nan_capa.drv_flags &
4551 WPA_DRIVER_FLAGS_NAN_SUPPORT_USERSPACE_DE)) {
4552 wpa_printf(MSG_INFO,
4553 "NAN: Cannot advertise sync service, driver does not support user space DE");
4554 return -1;
4555 }
4556
4557 if (!wpas_nan_ready(wpa_s)) {
4558 wpa_printf(MSG_INFO,
4559 "NAN: Synchronized support is not enabled");
4560 return -1;
4561 }
4562
4563 if (p2p) {
4564 wpa_printf(MSG_INFO,
4565 "NAN: Sync discovery is not supported for P2P");
4566 return -1;
4567 }
4568
4569 if (params->proximity_ranging) {
4570 wpa_printf(MSG_INFO,
4571 "NAN: Sync discovery is not supported for PR");
4572 return -1;
4573 }
4574 }
4575 #endif /* CONFIG_NAN */
4576
4577 if (p2p) {
4578 elems = wpas_p2p_usd_elems(wpa_s, service_name);
4579 addr = wpa_s->global->p2p_dev_addr;
4580 } else if (params->proximity_ranging) {
4581 const u8 *src = params->forced_addr ?
4582 params->forced_addr : wpa_s->own_addr;
4583
4584 elems = wpas_pr_usd_elems(wpa_s, src);
4585 }
4586
4587 if (params->forced_addr) {
4588 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA)) {
4589 wpa_printf(MSG_INFO, "NAN: Random TA not allowed");
4590 return -1;
4591 }
4592 addr = params->forced_addr;
4593 }
4594
4595 publish_id = nan_de_publish(wpa_s->nan_de, service_name, srv_proto_type,
4596 ssi, elems, params, p2p, addr);
4597 if (publish_id >= 1 && !params->sync &&
4598 (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD) &&
4599 wpas_drv_nan_publish(wpa_s, addr, publish_id, service_name,
4600 nan_de_get_service_id(wpa_s->nan_de,
4601 publish_id),
4602 srv_proto_type, ssi, elems, params,
4603 p2p ? p2p_network_id : nan_network_id) < 0) {
4604 nan_de_cancel_publish(wpa_s->nan_de, publish_id);
4605 publish_id = -1;
4606 }
4607 #ifdef CONFIG_AP
4608 if (publish_id >= 1 && wpa_s->ap_iface && wpa_s->ap_iface->bss[0]) {
4609 wpa_printf(MSG_DEBUG, "NAN: Linking nan_de for AP interface");
4610 wpa_s->ap_iface->bss[0]->nan_de = wpa_s->nan_de;
4611 }
4612 #endif /* CONFIG_AP */
4613
4614 wpabuf_free(elems);
4615 return publish_id;
4616 }
4617
4618
wpas_nan_cancel_publish(struct wpa_supplicant * wpa_s,int publish_id)4619 void wpas_nan_cancel_publish(struct wpa_supplicant *wpa_s, int publish_id)
4620 {
4621 if (!wpa_s->nan_de)
4622 return;
4623 nan_de_cancel_publish(wpa_s->nan_de, publish_id);
4624 if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD)
4625 wpas_drv_nan_cancel_publish(wpa_s, publish_id);
4626 }
4627
4628
wpas_nan_update_publish(struct wpa_supplicant * wpa_s,int publish_id,const struct wpabuf * ssi)4629 int wpas_nan_update_publish(struct wpa_supplicant *wpa_s, int publish_id,
4630 const struct wpabuf *ssi)
4631 {
4632 int ret;
4633
4634 if (!wpa_s->nan_de)
4635 return -1;
4636 ret = nan_de_update_publish(wpa_s->nan_de, publish_id, ssi);
4637 if (ret == 0 && (wpa_s->drv_flags2 &
4638 WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD) &&
4639 wpas_drv_nan_update_publish(wpa_s, publish_id, ssi) < 0)
4640 return -1;
4641 return ret;
4642 }
4643
4644
wpas_nan_usd_unpause_publish(struct wpa_supplicant * wpa_s,int publish_id,u8 peer_instance_id,const u8 * peer_addr)4645 int wpas_nan_usd_unpause_publish(struct wpa_supplicant *wpa_s, int publish_id,
4646 u8 peer_instance_id, const u8 *peer_addr)
4647 {
4648 if (!wpa_s->nan_de)
4649 return -1;
4650 return nan_de_unpause_publish(wpa_s->nan_de, publish_id,
4651 peer_instance_id, peer_addr);
4652 }
4653
4654
wpas_nan_stop_listen(struct wpa_supplicant * wpa_s,int id)4655 static int wpas_nan_stop_listen(struct wpa_supplicant *wpa_s, int id)
4656 {
4657 if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD)
4658 return 0;
4659
4660 if (nan_de_stop_listen(wpa_s->nan_de, id) < 0)
4661 return -1;
4662
4663 if (wpa_s->nan_usd_listen_work) {
4664 wpa_printf(MSG_DEBUG, "NAN: Stop listen operation");
4665 wpa_drv_cancel_remain_on_channel(wpa_s);
4666 wpas_nan_usd_listen_work_done(wpa_s);
4667 }
4668
4669 if (wpa_s->nan_usd_tx_work) {
4670 wpa_printf(MSG_DEBUG, "NAN: Stop TX wait operation");
4671 offchannel_send_action_done(wpa_s);
4672 wpas_nan_usd_tx_work_done(wpa_s);
4673 }
4674
4675 return 0;
4676 }
4677
4678
wpas_nan_usd_publish_stop_listen(struct wpa_supplicant * wpa_s,int publish_id)4679 int wpas_nan_usd_publish_stop_listen(struct wpa_supplicant *wpa_s,
4680 int publish_id)
4681 {
4682 if (!wpa_s->nan_de)
4683 return -1;
4684
4685 wpa_printf(MSG_DEBUG, "NAN: Request to stop listen for publish_id=%d",
4686 publish_id);
4687 return wpas_nan_stop_listen(wpa_s, publish_id);
4688 }
4689
4690
wpas_nan_subscribe(struct wpa_supplicant * wpa_s,const char * service_name,enum nan_service_protocol_type srv_proto_type,const struct wpabuf * ssi,struct nan_subscribe_params * params,bool p2p)4691 int wpas_nan_subscribe(struct wpa_supplicant *wpa_s,
4692 const char *service_name,
4693 enum nan_service_protocol_type srv_proto_type,
4694 const struct wpabuf *ssi,
4695 struct nan_subscribe_params *params, bool p2p)
4696 {
4697 int subscribe_id;
4698 struct wpabuf *elems = NULL;
4699 const u8 *addr;
4700
4701 if (!wpa_s->nan_de)
4702 return -1;
4703
4704 if (params->proximity_ranging && !params->active) {
4705 wpa_printf(MSG_INFO,
4706 "PR passive subscriber service discovery not allowed");
4707 return -1;
4708 }
4709
4710 addr = wpa_s->own_addr;
4711
4712 #ifdef CONFIG_NAN
4713 if (params->sync) {
4714 if (!(wpa_s->nan_capa.drv_flags &
4715 WPA_DRIVER_FLAGS_NAN_SUPPORT_USERSPACE_DE)) {
4716 wpa_printf(MSG_INFO,
4717 "NAN: Cannot subscribe sync, user space DE is not supported");
4718 return -1;
4719 }
4720
4721 if (!wpas_nan_ready(wpa_s)) {
4722 wpa_printf(MSG_INFO, "NAN: Not ready (subscribe)");
4723 return -1;
4724 }
4725
4726 if (p2p) {
4727 wpa_printf(MSG_INFO,
4728 "NAN: Sync discovery is not supported for P2P (subscribe)");
4729 return -1;
4730 }
4731
4732 if (params->proximity_ranging) {
4733 wpa_printf(MSG_INFO,
4734 "NAN: Sync discovery is not supported for PR (subscribe)");
4735 return -1;
4736 }
4737 }
4738 #endif /* CONFIG_NAN */
4739
4740 if (p2p) {
4741 elems = wpas_p2p_usd_elems(wpa_s, service_name);
4742 addr = wpa_s->global->p2p_dev_addr;
4743 } else if (params->proximity_ranging) {
4744 const u8 *src = params->forced_addr ?
4745 params->forced_addr : wpa_s->own_addr;
4746
4747 elems = wpas_pr_usd_elems(wpa_s, src);
4748 }
4749
4750 if (params->forced_addr) {
4751 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA)) {
4752 wpa_printf(MSG_INFO, "NAN: Random TA not allowed");
4753 return -1;
4754 }
4755 addr = params->forced_addr;
4756 }
4757
4758 subscribe_id = nan_de_subscribe(wpa_s->nan_de, service_name,
4759 srv_proto_type, ssi, elems, params,
4760 p2p, addr);
4761 if (subscribe_id >= 1 && !params->sync &&
4762 (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD) &&
4763 wpas_drv_nan_subscribe(wpa_s, addr, subscribe_id, service_name,
4764 nan_de_get_service_id(wpa_s->nan_de,
4765 subscribe_id),
4766 srv_proto_type, ssi, elems, params,
4767 p2p ? p2p_network_id : nan_network_id) < 0) {
4768 nan_de_cancel_subscribe(wpa_s->nan_de, subscribe_id);
4769 subscribe_id = -1;
4770 }
4771 #ifdef CONFIG_AP
4772 if (subscribe_id >= 1 && wpa_s->ap_iface && wpa_s->ap_iface->bss[0]) {
4773 wpa_printf(MSG_DEBUG, "NAN: Linking nan_de for AP interface");
4774 wpa_s->ap_iface->bss[0]->nan_de = wpa_s->nan_de;
4775 }
4776 #endif /* CONFIG_AP */
4777
4778 wpabuf_free(elems);
4779 return subscribe_id;
4780 }
4781
4782
wpas_nan_cancel_subscribe(struct wpa_supplicant * wpa_s,int subscribe_id)4783 void wpas_nan_cancel_subscribe(struct wpa_supplicant *wpa_s,
4784 int subscribe_id)
4785 {
4786 if (!wpa_s->nan_de)
4787 return;
4788 nan_de_cancel_subscribe(wpa_s->nan_de, subscribe_id);
4789 if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD)
4790 wpas_drv_nan_cancel_subscribe(wpa_s, subscribe_id);
4791 }
4792
4793
wpas_nan_usd_subscribe_stop_listen(struct wpa_supplicant * wpa_s,int subscribe_id)4794 int wpas_nan_usd_subscribe_stop_listen(struct wpa_supplicant *wpa_s,
4795 int subscribe_id)
4796 {
4797 if (!wpa_s->nan_de)
4798 return -1;
4799
4800 wpa_printf(MSG_DEBUG, "NAN: Request to stop listen for subscribe_id=%d",
4801 subscribe_id);
4802 return wpas_nan_stop_listen(wpa_s, subscribe_id);
4803 }
4804
4805
wpas_nan_transmit(struct wpa_supplicant * wpa_s,int handle,const struct wpabuf * ssi,const struct wpabuf * elems,const u8 * peer_addr,u8 req_instance_id,u32 * cookie)4806 int wpas_nan_transmit(struct wpa_supplicant *wpa_s, int handle,
4807 const struct wpabuf *ssi, const struct wpabuf *elems,
4808 const u8 *peer_addr, u8 req_instance_id, u32 *cookie)
4809 {
4810 if (!wpa_s->nan_de)
4811 return -1;
4812 return nan_de_transmit(wpa_s->nan_de, handle, ssi, elems, peer_addr,
4813 req_instance_id, NULL, cookie);
4814 }
4815
4816
wpas_nan_usd_remain_on_channel_cb(struct wpa_supplicant * wpa_s,unsigned int freq,unsigned int duration)4817 void wpas_nan_usd_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
4818 unsigned int freq, unsigned int duration)
4819 {
4820 wpas_nan_usd_listen_work_done(wpa_s);
4821
4822 if (wpa_s->nan_de)
4823 nan_de_listen_started(wpa_s->nan_de, freq, duration);
4824 }
4825
4826
wpas_nan_usd_cancel_remain_on_channel_cb(struct wpa_supplicant * wpa_s,unsigned int freq)4827 void wpas_nan_usd_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
4828 unsigned int freq)
4829 {
4830 if (wpa_s->nan_de)
4831 nan_de_listen_ended(wpa_s->nan_de, freq);
4832 }
4833
4834
wpas_nan_usd_tx_wait_expire(struct wpa_supplicant * wpa_s)4835 void wpas_nan_usd_tx_wait_expire(struct wpa_supplicant *wpa_s)
4836 {
4837 wpas_nan_usd_tx_work_done(wpa_s);
4838
4839 if (wpa_s->nan_de)
4840 nan_de_tx_wait_ended(wpa_s->nan_de);
4841 }
4842
4843
wpas_nan_usd_all_freqs(struct wpa_supplicant * wpa_s)4844 int * wpas_nan_usd_all_freqs(struct wpa_supplicant *wpa_s)
4845 {
4846 int i, j;
4847 int *freqs = NULL;
4848
4849 if (!wpa_s->hw.modes)
4850 return NULL;
4851
4852 for (i = 0; i < wpa_s->hw.num_modes; i++) {
4853 struct hostapd_hw_modes *mode = &wpa_s->hw.modes[i];
4854
4855 for (j = 0; j < mode->num_channels; j++) {
4856 struct hostapd_channel_data *chan = &mode->channels[j];
4857
4858 /* All 20 MHz channels on 2.4 and 5 GHz band */
4859 if (chan->freq < 2412 || chan->freq > 5900)
4860 continue;
4861
4862 /* that allow frames to be transmitted */
4863 if (chan->flag & (HOSTAPD_CHAN_DISABLED |
4864 HOSTAPD_CHAN_NO_IR |
4865 HOSTAPD_CHAN_RADAR))
4866 continue;
4867
4868 int_array_add_unique(&freqs, chan->freq);
4869 }
4870 }
4871
4872 return freqs;
4873 }
4874
4875
wpas_nan_usd_state_change_notif(struct wpa_supplicant * wpa_s)4876 void wpas_nan_usd_state_change_notif(struct wpa_supplicant *wpa_s)
4877 {
4878 struct wpa_supplicant *ifs;
4879 unsigned int n_active = 0;
4880 struct nan_de_cfg cfg;
4881
4882 if (!wpa_s->radio)
4883 return;
4884
4885 os_memset(&cfg, 0, sizeof(cfg));
4886
4887 dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
4888 radio_list) {
4889 if (ifs->wpa_state >= WPA_AUTHENTICATING)
4890 n_active++;
4891 }
4892
4893 wpa_printf(MSG_DEBUG,
4894 "NAN: state change notif: n_active=%u, p2p_in_progress=%u",
4895 n_active, wpas_p2p_in_progress(wpa_s));
4896
4897 if (n_active) {
4898 cfg.n_max = 3;
4899
4900 if (!wpas_p2p_in_progress(wpa_s)) {
4901 /* Limit the USD operation on channel to 100 - 300 TUs
4902 * to allow more time for other interfaces.
4903 */
4904 cfg.n_min = 1;
4905 } else {
4906 /* Limit the USD operation on channel to 200 - 300 TUs
4907 * to allow P2P operation to complete.
4908 */
4909 cfg.n_min = 2;
4910 }
4911
4912 /* Each 500 ms suspend USD operation for 300 ms */
4913 cfg.cycle = 500;
4914 cfg.suspend = 300;
4915 }
4916
4917 dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
4918 radio_list) {
4919 if (ifs->nan_de)
4920 nan_de_config(ifs->nan_de, &cfg);
4921 }
4922 }
4923
4924
4925 #ifdef CONFIG_NAN
4926 static struct wpa_supplicant *
wpas_nan_get_mgmt_iface(struct wpa_supplicant * wpa_s)4927 wpas_nan_get_mgmt_iface(struct wpa_supplicant *wpa_s)
4928 {
4929 struct wpa_supplicant *nmi_wpa_s;
4930
4931 for (nmi_wpa_s = wpa_s->global->ifaces; nmi_wpa_s;
4932 nmi_wpa_s = nmi_wpa_s->next) {
4933 if (nmi_wpa_s->nan_mgmt)
4934 return nmi_wpa_s;
4935 }
4936
4937 return wpa_s;
4938 }
4939 #endif /* CONFIG_NAN */
4940
4941
wpas_nan_tx_status(struct wpa_supplicant * wpa_s,const u8 * data,size_t data_len,int acked)4942 int wpas_nan_tx_status(struct wpa_supplicant *wpa_s,
4943 const u8 *data, size_t data_len, int acked)
4944 {
4945 #ifdef CONFIG_NAN
4946 const struct ieee80211_mgmt *mgmt =
4947 (const struct ieee80211_mgmt *) data;
4948
4949 wpa_s = wpas_nan_get_mgmt_iface(wpa_s);
4950
4951 if (wpa_s->nan_de)
4952 nan_de_tx_status(wpa_s->nan_de, 0, mgmt->da, data, data_len,
4953 acked);
4954
4955 if (!wpas_nan_ndp_allowed(wpa_s))
4956 return -1;
4957
4958 wpa_printf(MSG_DEBUG, "NAN: TX status for frame len=%zu acked=%u",
4959 data_len, acked);
4960
4961 if (!nan_tx_status(wpa_s->nan, mgmt->da, data, data_len, acked)) {
4962 wpa_printf(MSG_DEBUG, "NAN: Processed NAF TX status");
4963 return 0;
4964 }
4965 #endif /* CONFIG_NAN */
4966
4967 return -1;
4968 }
4969
4970
4971 #ifdef CONFIG_NAN
wpas_nan_rx_naf(struct wpa_supplicant * wpa_s,const struct ieee80211_mgmt * mgmt,size_t len)4972 void wpas_nan_rx_naf(struct wpa_supplicant *wpa_s,
4973 const struct ieee80211_mgmt *mgmt, size_t len)
4974 {
4975 if (mgmt->u.action.category == WLAN_ACTION_PROTECTED_DUAL) {
4976 wpa_printf(MSG_DEBUG, "NAN: RX NAF: ifname=%s: protected",
4977 wpa_s->ifname);
4978
4979 wpa_s = wpas_nan_get_mgmt_iface(wpa_s);
4980
4981 wpa_printf(MSG_DEBUG, "NAN: RX NAF: Continue processing on %s",
4982 wpa_s->ifname);
4983 }
4984
4985 if (!wpas_nan_ndp_allowed(wpa_s))
4986 return;
4987
4988 nan_action_rx(wpa_s->nan, mgmt, len);
4989 }
4990
4991
wpas_nan_data_interface_removed(struct wpa_supplicant * wpa_s)4992 void wpas_nan_data_interface_removed(struct wpa_supplicant *wpa_s)
4993 {
4994 struct wpa_supplicant *nan_dev_wpas = wpas_nan_get_mgmt_iface(wpa_s);
4995
4996 wpa_printf(MSG_DEBUG,
4997 "NAN: Data interface removed (%s) - terminate NDPs on "
4998 MACSTR, wpa_s->ifname, MAC2STR(wpa_s->own_addr));
4999
5000 if (nan_dev_wpas)
5001 nan_terminate_ndi_ndps(nan_dev_wpas->nan, wpa_s->own_addr);
5002 }
5003 #endif /* CONFIG_NAN */
5004