1 /*
2 * Wi-Fi Aware - NAN module
3 * Copyright (C) 2025 Intel Corporation
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "includes.h"
10 #include "common.h"
11 #include "utils/eloop.h"
12 #include "utils/bitfield.h"
13 #include "common/ieee802_11_common.h"
14 #include "pasn/pasn_common.h"
15 #include "nan.h"
16 #include "nan_i.h"
17
18 #define NAN_MAX_PEERS 32
19 #define NAN_MAX_NAF_LEN 1024
20
21 #define NAN_NDP_SETUP_TIMEOUT_LONG 30
22 #define NAN_NDP_SETUP_TIMEOUT_SHORT 2
23
24 static void nan_peer_state_timeout(void *eloop_ctx, void *timeout_ctx);
25 static void nan_idle_period_timeout(void *eloop_ctx, void *timeout_ctx);
26 static void nan_ndp_disconnected(struct nan_data *nan, struct nan_peer *peer,
27 enum nan_reason reason,
28 bool locally_generated);
29 static void nan_set_peer_timeout(struct nan_data *nan, struct nan_peer *peer,
30 unsigned int sec, unsigned int usec);
31 static int nan_action_send(struct nan_data *nan, struct nan_peer *peer,
32 enum nan_subtype subtype);
33
34
nan_init(const struct nan_config * cfg)35 struct nan_data * nan_init(const struct nan_config *cfg)
36 {
37 struct nan_data *nan;
38
39 if (!cfg->start || !cfg->stop)
40 return NULL;
41
42 nan = os_zalloc(sizeof(*nan));
43 if (!nan)
44 return NULL;
45
46 if (cfg->pairing_cfg.pairing_verification &&
47 nan_nira_get_tag_nonce(cfg, nan->nira_nonce, nan->nira_tag) < 0) {
48 wpa_printf(MSG_INFO, "NAN: Failed to get NIRA tag and nonce");
49 os_free(nan);
50 return NULL;
51 }
52
53 nan->cfg = os_memdup(cfg, sizeof(*cfg));
54 if (!nan->cfg) {
55 os_free(nan);
56 return NULL;
57 }
58
59 #ifdef CONFIG_PASN
60 nan->initiator_pmksa = pasn_initiator_pmksa_cache_init();
61 nan->responder_pmksa = pasn_responder_pmksa_cache_init();
62 if (!nan->initiator_pmksa || !nan->responder_pmksa) {
63 wpa_printf(MSG_INFO,
64 "NAN: Failed to initialize PASN PMKSA cache");
65 nan_deinit(nan);
66 return NULL;
67 }
68 #endif /* CONFIG_PASN */
69
70 dl_list_init(&nan->peer_list);
71
72 wpa_printf(MSG_DEBUG, "NAN: Initialized");
73
74 return nan;
75 }
76
77
nan_peer_flush_avail(struct nan_peer_info * info)78 static void nan_peer_flush_avail(struct nan_peer_info *info)
79 {
80 nan_flush_avail_entries(&info->avail_entries);
81 }
82
83
nan_peer_flush_dev_capa(struct nan_peer_info * info)84 static void nan_peer_flush_dev_capa(struct nan_peer_info *info)
85 {
86 struct nan_dev_capa_entry *cur, *next;
87
88 dl_list_for_each_safe(cur, next, &info->dev_capa,
89 struct nan_dev_capa_entry, list) {
90 dl_list_del(&cur->list);
91 os_free(cur);
92 }
93 }
94
95
nan_peer_flush_elem_container(struct nan_peer_info * info)96 static void nan_peer_flush_elem_container(struct nan_peer_info *info)
97 {
98 struct nan_elem_container_entry *cur, *next;
99
100 dl_list_for_each_safe(cur, next, &info->element_container,
101 struct nan_elem_container_entry, list) {
102 dl_list_del(&cur->list);
103 os_free(cur);
104 }
105 }
106
107
nan_peer_flush_ulw(struct nan_peer_info * info)108 static void nan_peer_flush_ulw(struct nan_peer_info *info)
109 {
110 struct nan_ulw_entry *cur, *next;
111
112 dl_list_for_each_safe(cur, next, &info->ulw,
113 struct nan_ulw_entry, list) {
114 dl_list_del(&cur->list);
115 os_free(cur);
116 }
117 }
118
119
120 static struct wpabuf *
nan_peer_build_ulw_attrs(const struct nan_peer_info * info)121 nan_peer_build_ulw_attrs(const struct nan_peer_info *info)
122 {
123 struct nan_ulw_entry *entry;
124 struct wpabuf *buf;
125 size_t len = 0;
126
127 if (dl_list_empty(&info->ulw))
128 return NULL;
129
130 dl_list_for_each(entry, &info->ulw, struct nan_ulw_entry, list)
131 len += NAN_ATTR_HDR_LEN + entry->len;
132
133 buf = wpabuf_alloc(len);
134 if (!buf) {
135 wpa_printf(MSG_INFO,
136 "NAN: Failed to allocate buffer for ULW attributes");
137 return NULL;
138 }
139
140 dl_list_for_each(entry, &info->ulw, struct nan_ulw_entry, list) {
141 wpabuf_put_u8(buf, NAN_ATTR_UNALIGNED_SCHEDULE);
142 wpabuf_put_le16(buf, entry->len);
143 wpabuf_put_data(buf, entry->data, entry->len);
144 }
145
146 return buf;
147 }
148
149
nan_ndp_setup_stop(struct nan_data * nan,struct nan_peer * peer)150 static void nan_ndp_setup_stop(struct nan_data *nan, struct nan_peer *peer)
151 {
152 eloop_cancel_timeout(nan_peer_state_timeout, nan, peer);
153 nan_ndp_setup_reset(nan, peer);
154
155 /* Need to also remove the NDL if no active NDPs */
156 if (dl_list_empty(&peer->ndps))
157 nan_ndl_reset(nan, peer);
158 }
159
160
nan_peer_flush_sec(struct nan_peer_info * info)161 static void nan_peer_flush_sec(struct nan_peer_info *info)
162 {
163 struct nan_peer_sec_info_entry *cur, *next;
164
165 dl_list_for_each_safe(cur, next, &info->sec,
166 struct nan_peer_sec_info_entry, list) {
167 dl_list_del(&cur->list);
168 bin_clear_free(cur, sizeof(*cur));
169 }
170 }
171
172
nan_peer_del_sec_entry(struct nan_peer_info * info,const u8 * peer_ndi)173 static void nan_peer_del_sec_entry(struct nan_peer_info *info,
174 const u8 *peer_ndi)
175 {
176 struct nan_peer_sec_info_entry *cur, *next;
177
178 dl_list_for_each_safe(cur, next, &info->sec,
179 struct nan_peer_sec_info_entry, list) {
180 if (!ether_addr_equal(cur->peer_ndi, peer_ndi))
181 continue;
182
183 wpa_printf(MSG_DEBUG,
184 "NAN: Removing sec entry for peer_ndi=" MACSTR
185 " local_ndi=" MACSTR,
186 MAC2STR(peer_ndi), MAC2STR(cur->local_ndi));
187 dl_list_del(&cur->list);
188 bin_clear_free(cur, sizeof(*cur));
189 }
190 }
191
192
nan_remove_group_keys(struct nan_data * nan,struct nan_peer * peer)193 static void nan_remove_group_keys(struct nan_data *nan, struct nan_peer *peer)
194 {
195 if (peer->igtk_id) {
196 if (nan->cfg->set_group_key(nan->cfg->cb_ctx, WPA_ALG_NONE,
197 peer->nmi_addr, peer->igtk_id, NULL,
198 NULL, 0, KEY_FLAG_GROUP))
199 wpa_printf(MSG_DEBUG,
200 "NAN: Failed to clear Rx IGTK for peer "
201 MACSTR, MAC2STR(peer->nmi_addr));
202 peer->igtk_id = 0;
203 }
204
205 if (peer->bigtk_id) {
206 if (nan->cfg->set_group_key(nan->cfg->cb_ctx, WPA_ALG_NONE,
207 peer->nmi_addr, peer->bigtk_id,
208 NULL, NULL, 0, KEY_FLAG_GROUP))
209 wpa_printf(MSG_DEBUG,
210 "NAN: Failed to clear Rx BIGTK for peer "
211 MACSTR, MAC2STR(peer->nmi_addr));
212 peer->bigtk_id = 0;
213 }
214 }
215
216
nan_del_peer(struct nan_data * nan,struct nan_peer * peer)217 static void nan_del_peer(struct nan_data *nan, struct nan_peer *peer)
218 {
219 if (!peer)
220 return;
221
222 wpa_printf(MSG_DEBUG, "NAN: Removing peer: " MACSTR,
223 MAC2STR(peer->nmi_addr));
224
225 if (!dl_list_empty(&peer->ndps)) {
226 struct nan_ndp *ndp, *tndp;
227
228 /* TODO: tear down active NDPs */
229 wpa_printf(MSG_DEBUG,
230 "NAN: Peer delete while there are active NDPs");
231
232 dl_list_for_each_safe(ndp, tndp, &peer->ndps,
233 struct nan_ndp, list) {
234 dl_list_del(&ndp->list);
235 os_free(ndp);
236 }
237 }
238
239 if (peer->ndp_setup.ndp) {
240 wpa_printf(MSG_DEBUG,
241 "NAN: Peer delete while NDP setup is WIP");
242 nan_ndp_setup_stop(nan, peer);
243 }
244
245 wpabuf_free(peer->bootstrap.npba);
246 peer->bootstrap.npba = NULL;
247 nan_bootstrap_reset(nan, peer);
248 dl_list_del(&peer->list);
249 nan_peer_flush_avail(&peer->info);
250 nan_peer_flush_ulw(&peer->info);
251 nan_peer_flush_dev_capa(&peer->info);
252 nan_peer_flush_elem_container(&peer->info);
253 nan_remove_group_keys(nan, peer);
254
255 nan_ndl_reset(nan, peer);
256 nan_peer_flush_sec(&peer->info);
257 eloop_cancel_timeout(nan_peer_state_timeout, nan, peer);
258 nan_pairing_deinit_peer(peer);
259 os_free(peer);
260 }
261
262
nan_peer_clear_all(struct nan_data * nan)263 static void nan_peer_clear_all(struct nan_data *nan)
264 {
265 struct nan_peer *peer, *n_peer;
266
267 dl_list_for_each_safe(peer, n_peer, &nan->peer_list,
268 struct nan_peer, list)
269 nan_del_peer(nan, peer);
270 }
271
272
nan_deinit(struct nan_data * nan)273 void nan_deinit(struct nan_data *nan)
274 {
275 wpa_printf(MSG_DEBUG, "NAN: Deinit");
276
277 nan_stop(nan);
278 nan_flush(nan);
279
280 #ifdef CONFIG_PASN
281 pasn_initiator_pmksa_cache_deinit(nan->initiator_pmksa);
282 pasn_responder_pmksa_cache_deinit(nan->responder_pmksa);
283 #endif /* CONFIG_PASN */
284 wpabuf_free(nan->sched.elems);
285 os_free(nan->cfg);
286 os_free(nan);
287 }
288
289
nan_gen_igtk(struct nan_data * nan)290 static int nan_gen_igtk(struct nan_data *nan)
291 {
292 u8 tsc[RSN_PN_LEN];
293 enum wpa_alg alg;
294 int cipher;
295
296 if (((nan->cfg->security_capab & NAN_CS_INFO_CAPA_GTK_SUPP_MASK) >>
297 NAN_CS_INFO_CAPA_GTK_SUPP_POS) == NAN_CS_INFO_CAPA_GTK_SUPP_NONE)
298 return 0;
299
300 if (nan->cfg->security_capab &
301 NAN_CS_INFO_CAPA_IGTK_USE_NCS_BIP_GMAC_256) {
302 alg = WPA_ALG_BIP_GMAC_256;
303 cipher = WPA_CIPHER_BIP_GMAC_256;
304 } else {
305 alg = WPA_ALG_BIP_CMAC_128;
306 cipher = WPA_CIPHER_AES_128_CMAC;
307 }
308
309 nan->igtk.igtk_len = wpa_cipher_key_len(cipher);
310 nan->igtk_id = 4;
311 if (os_get_random(nan->igtk.igtk, nan->igtk.igtk_len) < 0)
312 return -1;
313 os_memset(tsc, 0, sizeof(tsc));
314 if (nan->cfg->set_group_key(nan->cfg->cb_ctx, alg, broadcast_ether_addr,
315 nan->igtk_id, tsc, nan->igtk.igtk,
316 nan->igtk.igtk_len,
317 KEY_FLAG_GROUP_TX_DEFAULT) < 0) {
318 wpa_printf(MSG_INFO, "NAN: Failed to install own IGTK");
319 return -1;
320 }
321
322 wpa_hexdump_key(MSG_DEBUG, "NAN: New own IGTK", nan->igtk.igtk,
323 nan->igtk.igtk_len);
324 return 0;
325 }
326
327
nan_gen_bigtk(struct nan_data * nan)328 static int nan_gen_bigtk(struct nan_data *nan)
329 {
330 u8 tsc[RSN_PN_LEN];
331 enum wpa_alg alg;
332 int cipher;
333
334 if (((nan->cfg->security_capab & NAN_CS_INFO_CAPA_GTK_SUPP_MASK) >>
335 NAN_CS_INFO_CAPA_GTK_SUPP_POS) != NAN_CS_INFO_CAPA_GTK_SUPP_ALL) {
336 wpa_printf(MSG_DEBUG, "NAN: BIGTK not supported");
337 return 0;
338 }
339
340 if (nan->cfg->security_capab &
341 NAN_CS_INFO_CAPA_IGTK_USE_NCS_BIP_GMAC_256) {
342 alg = WPA_ALG_BIP_GMAC_256;
343 cipher = WPA_CIPHER_BIP_GMAC_256;
344 } else {
345 alg = WPA_ALG_BIP_CMAC_128;
346 cipher = WPA_CIPHER_AES_128_CMAC;
347 }
348
349 nan->bigtk.bigtk_len = wpa_cipher_key_len(cipher);
350 nan->bigtk_id = 6;
351 if (os_get_random(nan->bigtk.bigtk, nan->bigtk.bigtk_len) < 0)
352 return -1;
353 os_memset(tsc, 0, sizeof(tsc));
354 if (nan->cfg->set_group_key(nan->cfg->cb_ctx, alg, broadcast_ether_addr,
355 nan->bigtk_id, tsc, nan->bigtk.bigtk,
356 nan->bigtk.bigtk_len,
357 KEY_FLAG_GROUP_TX_DEFAULT) < 0) {
358 wpa_printf(MSG_INFO, "NAN: Failed to install own BIGTK");
359 return -1;
360 }
361
362 wpa_hexdump_key(MSG_DEBUG, "NAN: New own BIGTK", nan->bigtk.bigtk,
363 nan->bigtk.bigtk_len);
364 return 0;
365 }
366
367
nan_start(struct nan_data * nan,const struct nan_cluster_config * config)368 int nan_start(struct nan_data *nan, const struct nan_cluster_config *config)
369 {
370 int ret;
371
372 wpa_printf(MSG_DEBUG, "NAN: Starting/joining NAN cluster");
373
374 if (nan->nan_started) {
375 wpa_printf(MSG_DEBUG, "NAN: Already started");
376 return -1;
377 }
378
379 ret = nan->cfg->start(nan->cfg->cb_ctx, config);
380 if (ret) {
381 wpa_printf(MSG_DEBUG, "NAN: Failed to start - ret=%d", ret);
382 return ret;
383 }
384 nan->nan_started = 1;
385
386 if (nan_gen_igtk(nan) < 0 || nan_gen_bigtk(nan) < 0) {
387 nan_stop(nan);
388 return -1;
389 }
390
391 return 0;
392 }
393
394
nan_update_config(struct nan_data * nan,const struct nan_cluster_config * config)395 int nan_update_config(struct nan_data *nan,
396 const struct nan_cluster_config *config)
397 {
398 int ret;
399
400 wpa_printf(MSG_DEBUG, "NAN: Update configuration");
401
402 if (!nan->nan_started) {
403 wpa_printf(MSG_DEBUG, "NAN: Not started yet");
404 return -1;
405 }
406
407 ret = nan->cfg->update_config(nan->cfg->cb_ctx, config);
408 if (ret)
409 wpa_printf(MSG_DEBUG, "NAN: Failed to update config. ret=%d",
410 ret);
411
412 return ret;
413 }
414
415
nan_set_cdw_overwrite(struct nan_data * nan,int map_id_2g,int map_id_5g)416 void nan_set_cdw_overwrite(struct nan_data *nan, int map_id_2g, int map_id_5g)
417 {
418 u16 cdw_info;
419
420 if (!nan)
421 return;
422
423 cdw_info = nan->cfg->dev_capa.cdw_info;
424
425 if (map_id_2g >= 0) {
426 cdw_info &= ~NAN_CDW_INFO_2G_OVERRIDE_MASK;
427 cdw_info |= ((map_id_2g << NAN_CDW_INFO_2G_OVERRIDE_POS) &
428 NAN_CDW_INFO_2G_OVERRIDE_MASK);
429 }
430
431 if (map_id_5g >= 0) {
432 cdw_info &= ~NAN_CDW_INFO_5G_OVERRIDE_MASK;
433 cdw_info |= ((map_id_5g << NAN_CDW_INFO_5G_OVERRIDE_POS) &
434 NAN_CDW_INFO_5G_OVERRIDE_MASK);
435 }
436
437 wpa_printf(MSG_DEBUG, "NAN: Updated cdw_info=0x%04x", cdw_info);
438 nan->cfg->dev_capa.cdw_info = cdw_info;
439 }
440
441
nan_flush(struct nan_data * nan)442 void nan_flush(struct nan_data *nan)
443 {
444 wpa_printf(MSG_DEBUG, "NAN: Reset internal state");
445
446 nan_peer_clear_all(nan);
447 wpabuf_free(nan->sched.elems);
448 os_memset(&nan->sched, 0, sizeof(nan->sched));
449 }
450
451
nan_stop(struct nan_data * nan)452 void nan_stop(struct nan_data *nan)
453 {
454 wpa_printf(MSG_DEBUG, "NAN: Stopping");
455
456 if (!nan->nan_started) {
457 wpa_printf(MSG_DEBUG, "NAN: Already stopped");
458 return;
459 }
460
461 eloop_cancel_timeout(nan_idle_period_timeout, nan, NULL);
462
463 if (nan->igtk.igtk_len) {
464 if (nan->cfg->set_group_key(nan->cfg->cb_ctx, WPA_ALG_NONE,
465 NULL, nan->igtk_id, NULL, NULL,
466 0, KEY_FLAG_GROUP))
467 wpa_printf(MSG_DEBUG, "NAN: Failed to clear own IGTK");
468
469 nan->igtk.igtk_len = 0;
470 nan->igtk_id = 0;
471 }
472
473 if (nan->bigtk.bigtk_len) {
474 if (nan->cfg->set_group_key(nan->cfg->cb_ctx, WPA_ALG_NONE,
475 NULL, nan->bigtk_id, NULL, NULL,
476 0, KEY_FLAG_GROUP))
477 wpa_printf(MSG_DEBUG, "NAN: Failed to clear own BIGTK");
478
479 nan->bigtk.bigtk_len = 0;
480 nan->bigtk_id = 0;
481 }
482
483 /* Even though NAN is stopping, flush internal state */
484 nan_flush(nan);
485 nan->nan_started = 0;
486 nan->cfg->stop(nan->cfg->cb_ctx);
487 }
488
489
nan_get_peer(struct nan_data * nan,const u8 * addr)490 struct nan_peer * nan_get_peer(struct nan_data *nan, const u8 *addr)
491 {
492 struct nan_peer *peer;
493
494 dl_list_for_each(peer, &nan->peer_list, struct nan_peer, list) {
495 if (ether_addr_equal(peer->nmi_addr, addr))
496 return peer;
497 }
498
499 return NULL;
500 }
501
502
503 /*
504 * nan_parse_tbm - Parse NAN Time Bitmap attribute
505 *
506 * @nan: NAN module context from nan_init()
507 * @tbm: On return would hold the parsed time bitmap
508 * @buf: Buffer holding the time bitmap
509 * @buf_len: Length of &buf
510 * Return 0 on success; otherwise -1
511 */
nan_parse_tbm(struct nan_data * nan,struct nan_time_bitmap * tbm,const u8 * buf,u16 buf_len)512 static int nan_parse_tbm(struct nan_data *nan, struct nan_time_bitmap *tbm,
513 const u8 *buf, u16 buf_len)
514 {
515 u32 period;
516 u16 ctrl;
517 const struct nan_tbm *bm;
518 u8 duration_bit;
519
520 if (buf_len < sizeof(*bm)) {
521 wpa_printf(MSG_DEBUG, "NAN: Too short time bitmap length (%u)",
522 buf_len);
523 return -1;
524 }
525
526 bm = (const struct nan_tbm *) buf;
527 if (!bm->len || bm->len + sizeof(*bm) > buf_len) {
528 wpa_printf(MSG_DEBUG, "NAN: Invalid tbm length (%hu)",
529 bm->len);
530 return -1;
531 }
532
533 if (bm->len > sizeof(tbm->bitmap)) {
534 wpa_printf(MSG_DEBUG,
535 "NAN: tbm len=%hu exceeds supported len=%zu",
536 bm->len, sizeof(tbm->bitmap));
537 return -1;
538 }
539
540 ctrl = le_to_host16(bm->ctrl);
541
542 duration_bit = BITS(ctrl, NAN_TIME_BM_CTRL_BIT_DURATION_MASK,
543 NAN_TIME_BM_CTRL_BIT_DURATION_POS);
544
545 if (duration_bit > NAN_TIME_BM_CTRL_BIT_DURATION_128_TU) {
546 wpa_printf(MSG_DEBUG, "NAN: Invalid time bitmap duration");
547 return -1;
548 }
549
550 tbm->duration = duration_bit;
551
552 tbm->period = BITS(ctrl, NAN_TIME_BM_CTRL_PERIOD_MASK,
553 NAN_TIME_BM_CTRL_PERIOD_POS);
554 if (tbm->period) {
555 period = BIT(6 + tbm->period);
556 } else {
557 wpa_printf(MSG_DEBUG,
558 "NAN: Bitmap with period=0 is not supported");
559 return -1;
560 }
561
562 tbm->offset = BITS(ctrl, NAN_TIME_BM_CTRL_START_OFFSET_MASK,
563 NAN_TIME_BM_CTRL_START_OFFSET_POS);
564
565 if (bm->len * 8 * BIT(4 + tbm->duration) > period) {
566 wpa_printf(MSG_DEBUG,
567 "NAN: tbm is longer than the repeat period");
568 return -1;
569 }
570
571 if (tbm->offset * 16 > period) {
572 wpa_printf(MSG_DEBUG,
573 "NAN: tbm offset %u exceeds period %u",
574 tbm->offset, period);
575 return -1;
576 }
577
578 tbm->len = bm->len;
579 os_memcpy(tbm->bitmap, bm->bitmap, tbm->len);
580 return 0;
581 }
582
583
584 /*
585 * nan_parse_band_chan_list - Parse NAN Band/Channel List entry
586 *
587 * @nan: NAN module context from nan_init()
588 * @entry: On return would hold the parsed band/channel list
589 * @list: Buffer holding the band/channel list
590 * @len: Length of &list
591 * Return 0 on success; otherwise -1
592 */
nan_parse_band_chan_list(struct nan_data * nan,struct nan_avail_entry * entry,const struct nan_band_chan_list * list,u16 len)593 static int nan_parse_band_chan_list(struct nan_data *nan,
594 struct nan_avail_entry *entry,
595 const struct nan_band_chan_list *list,
596 u16 len)
597 {
598 u8 band_chan_size, i;
599 bool non_cont;
600 const u8 *pos;
601
602 if (len < sizeof(*list)) {
603 wpa_printf(MSG_DEBUG,
604 "NAN: Too short channel/band list=%hu", len);
605 return -1;
606 }
607
608 entry->band_chan_type = list->ctrl & NAN_BAND_CHAN_CTRL_TYPE;
609 entry->n_band_chan = BITS(list->ctrl,
610 NAN_BAND_CHAN_CTRL_NUM_ENTRIES_MASK,
611 NAN_BAND_CHAN_CTRL_NUM_ENTRIES_POS);
612
613 len -= sizeof(*list);
614 pos = list->entries;
615
616 if (entry->band_chan_type == NAN_TYPE_BAND) {
617 if (!len || !entry->n_band_chan || len < entry->n_band_chan) {
618 wpa_printf(MSG_DEBUG,
619 "NAN: Truncated band list. len=%u, band_chan=%u",
620 len, entry->n_band_chan);
621 return -1;
622 }
623
624 entry->band_chan = os_zalloc(sizeof(*entry->band_chan) *
625 entry->n_band_chan);
626 if (!entry->band_chan) {
627 wpa_printf(MSG_DEBUG,
628 "NAN: Failed to allocate band list");
629 return -1;
630 }
631
632 for (i = 0; i < entry->n_band_chan; i++)
633 entry->band_chan[i].u.band_id = pos[i];
634
635 return 0;
636 }
637
638 non_cont = list->ctrl & NAN_BAND_CHAN_CTRL_NON_CONT_BW;
639 band_chan_size = non_cont ? NAN_CHAN_ENTRY_80P80_LEN :
640 NAN_CHAN_ENTRY_MIN_LEN;
641
642 if (len < entry->n_band_chan * band_chan_size) {
643 wpa_printf(MSG_DEBUG, "NAN: Truncated channel list");
644 return -1;
645 }
646
647 entry->band_chan = os_zalloc(sizeof(*entry->band_chan) *
648 entry->n_band_chan);
649 if (!entry->band_chan) {
650 wpa_printf(MSG_DEBUG, "NAN: Failed to allocate channel list");
651 return -1;
652 }
653
654 for (i = 0; i < entry->n_band_chan; i++) {
655 struct nan_band_chan *curr = &entry->band_chan[i];
656 const struct nan_chan_entry *chan =
657 (const struct nan_chan_entry *) pos;
658
659 curr->u.chan.op_class = chan->op_class;
660 curr->u.chan.chan_bitmap = chan->chan_bitmap;
661 curr->u.chan.pri_chan_bitmap = chan->pri_chan_bitmap;
662 if (non_cont)
663 curr->u.chan.aux_chan_bitmap = chan->aux_chan_bitmap;
664
665 pos += band_chan_size;
666 }
667
668 return 0;
669 }
670
671
672 /*
673 * nan_split_avail_entry - Split an availability entry
674 *
675 * @nan: NAN module context from nan_init()
676 * @entry: Original entry to split
677 * Returns a newly allocated potential entry on success, otherwise NULL.
678 *
679 * The function expects an availability entry which is both
680 * committed/conditional and potential and has more than one channel entry. It
681 * splits the original entry such that:
682 *
683 * - The original entry is only committed/conditional with one channel entry
684 * - A new potential entry with the rest of the channels specified in the
685 * original entry.
686 */
687 static struct nan_avail_entry *
nan_split_avail_entry(struct nan_data * nan,struct nan_avail_entry * entry)688 nan_split_avail_entry(struct nan_data *nan,
689 struct nan_avail_entry *entry)
690 {
691 struct nan_avail_entry *pot;
692 struct nan_band_chan *tmp;
693
694 wpa_printf(MSG_DEBUG,
695 "NAN: Split Committed/Conditional and potential entry");
696
697 pot = os_zalloc(sizeof(*pot));
698 if (!pot) {
699 wpa_printf(MSG_DEBUG,
700 "NAN: Failed to allocate availability entry");
701 return NULL;
702 }
703
704 pot->map_id = entry->map_id;
705 pot->type = NAN_AVAIL_ENTRY_CTRL_TYPE_POTENTIAL;
706 pot->preference = entry->preference;
707 pot->utilization = entry->utilization;
708 pot->rx_nss = entry->rx_nss;
709
710 dl_list_init(&pot->list);
711
712 pot->tbm.duration = entry->tbm.duration;
713 pot->tbm.period = entry->tbm.period;
714 pot->tbm.offset = entry->tbm.offset;
715 pot->tbm.len = entry->tbm.len;
716
717 os_memcpy(pot->tbm.bitmap, entry->tbm.bitmap, pot->tbm.len);
718
719 pot->band_chan_type = entry->band_chan_type;
720 pot->n_band_chan = entry->n_band_chan - 1;
721 pot->band_chan = os_zalloc(sizeof(*pot->band_chan) *
722 pot->n_band_chan);
723 if (!pot->band_chan) {
724 wpa_printf(MSG_DEBUG,
725 "NAN: Failed to allocate channel list: potential");
726 os_free(pot);
727 return NULL;
728 }
729
730 os_memcpy(pot->band_chan, &entry->band_chan[1],
731 sizeof(*pot->band_chan) * pot->n_band_chan);
732
733 tmp = entry->band_chan;
734
735 /* Clear potential from the original entry */
736 entry->type &= ~NAN_AVAIL_ENTRY_CTRL_TYPE_POTENTIAL;
737 entry->band_chan = os_memdup(tmp, sizeof(*entry->band_chan));
738 if (!entry->band_chan) {
739 wpa_printf(MSG_DEBUG,
740 "NAN: Failed to allocate channel list: committed");
741 os_free(pot->band_chan);
742 os_free(pot);
743 return NULL;
744 }
745
746 entry->n_band_chan = 1;
747
748 os_free(tmp);
749 return pot;
750 }
751
752
753 /*
754 * nan_parse_avail_entry - Parse a NAN availability entry
755 *
756 * @nan: NAN module context from nan_init()
757 * @peer_info: Peer info where the parsed entry would be added
758 * @avail_entry: Pointer to the availability entry
759 * @entry_len: Length of the availability entry
760 * @map_id: Map ID of the availability attribute that this entry belongs to
761 * Returns: 0 on success, -1 on failure, or 0 to skip the entry
762 */
nan_parse_avail_entry(struct nan_data * nan,struct nan_peer_info * peer_info,const struct nan_avail_ent * avail_entry,u16 entry_len,u8 map_id)763 static int nan_parse_avail_entry(struct nan_data *nan,
764 struct nan_peer_info *peer_info,
765 const struct nan_avail_ent *avail_entry,
766 u16 entry_len, u8 map_id)
767 {
768 struct nan_avail_entry *entry;
769 const u8 *pos;
770 u16 ctrl, len;
771 u8 type, preference, utilization;
772
773 if (entry_len < MIN_AVAIL_ENTRY_LEN) {
774 wpa_printf(MSG_DEBUG,
775 "NAN: Too short availability entry len=%hu",
776 entry_len);
777 return -1;
778 }
779
780 ctrl = le_to_host16(avail_entry->ctrl);
781
782 type = ctrl & NAN_AVAIL_ENTRY_CTRL_TYPE_MASK;
783 if (!type ||
784 ((type & NAN_AVAIL_ENTRY_CTRL_TYPE_COMMITTED) &&
785 (type & NAN_AVAIL_ENTRY_CTRL_TYPE_COND))) {
786 wpa_printf(MSG_DEBUG, "NAN: Invalid entry type=0x%x", type);
787 return -1;
788 }
789
790 preference = BITS(ctrl, NAN_AVAIL_ENTRY_CTRL_USAGE_PREF_MASK,
791 NAN_AVAIL_ENTRY_CTRL_USAGE_PREF_POS);
792 utilization = BITS(ctrl, NAN_AVAIL_ENTRY_CTRL_UTIL_MASK,
793 NAN_AVAIL_ENTRY_CTRL_UTIL_POS);
794
795 if (utilization > NAN_AVAIL_ENTRY_CTRL_UTIL_MAX &&
796 utilization != NAN_AVAIL_ENTRY_CTRL_UTIL_UNKNOWN) {
797 wpa_printf(MSG_DEBUG, "NAN: Invalid tbm utilization");
798 return -1;
799 }
800
801 wpa_printf(MSG_DEBUG,
802 "NAN: Avail entry: map_id=%u, ctrl=0x%04x, entry_len=%u, type=0x%x, pref=0x%x",
803 map_id, ctrl, entry_len, type, preference);
804
805 entry = os_zalloc(sizeof(*entry));
806 if (!entry) {
807 wpa_printf(MSG_DEBUG,
808 "NAN: Failed to allocate availability entry");
809 return -1;
810 }
811
812 entry->map_id = map_id;
813 entry->type = type;
814 entry->preference = preference;
815 entry->utilization = utilization;
816 dl_list_init(&entry->list);
817
818 entry->rx_nss = BITS(ctrl, NAN_AVAIL_ENTRY_CTRL_RX_NSS_MASK,
819 NAN_AVAIL_ENTRY_CTRL_RX_NSS_POS);
820 if (!entry->rx_nss) {
821 wpa_printf(MSG_DEBUG,
822 "NAN: Avail entry with rx_nss=0. Override to 1");
823 entry->rx_nss = 1;
824 }
825
826 len = entry_len - MIN_AVAIL_ENTRY_LEN;
827 pos = avail_entry->optional;
828
829 if (ctrl & NAN_AVAIL_ENTRY_CTRL_TBM_PRESENT) {
830 wpa_printf(MSG_DEBUG,
831 "NAN: Availability entry: Time bitmap is set");
832
833 if (len < sizeof(struct nan_tbm)) {
834 wpa_printf(MSG_DEBUG,
835 "NAN: Time bitmap set: length too short");
836 goto out;
837 }
838
839 if (nan_parse_tbm(nan, &entry->tbm, pos, len))
840 goto out;
841
842 pos += entry->tbm.len + sizeof(struct nan_tbm);
843 len -= entry->tbm.len + sizeof(struct nan_tbm);
844 } else {
845 entry->tbm.len = 0;
846 os_memset(entry->tbm.bitmap, 0, sizeof(entry->tbm.bitmap));
847 }
848
849 if (nan_parse_band_chan_list(nan, entry,
850 (const struct nan_band_chan_list *) pos,
851 len))
852 goto out;
853
854 /*
855 * An entry with committed/conditional can either have a single channel
856 * entry, or multiple channel entries. The latter case is allowed only
857 * if the entry is also potential, in which case the first channel entry
858 * belongs to the committed entry and the other channels are potential.
859 */
860 if (entry->type & (NAN_AVAIL_ENTRY_CTRL_TYPE_COMMITTED |
861 NAN_AVAIL_ENTRY_CTRL_TYPE_COND)) {
862 if (entry->band_chan_type != NAN_TYPE_CHANNEL) {
863 wpa_printf(MSG_DEBUG,
864 "NAN: Committed/cond avail entry with band");
865 goto out;
866 }
867
868 if (entry->n_band_chan < 1) {
869 wpa_printf(MSG_DEBUG,
870 "NAN: Committed/cond avail entry: no channels");
871 goto out;
872 }
873
874 if (entry->n_band_chan > 1) {
875 struct nan_avail_entry *pot_avail;
876
877 if (!(entry->type &
878 NAN_AVAIL_ENTRY_CTRL_TYPE_POTENTIAL)) {
879 wpa_printf(MSG_DEBUG,
880 "NAN: Committed/cond avail entry: %u chans",
881 entry->n_band_chan);
882 goto out;
883 }
884
885 pot_avail = nan_split_avail_entry(nan, entry);
886 if (!pot_avail)
887 goto out;
888
889 dl_list_add(&peer_info->avail_entries,
890 &pot_avail->list);
891 } else {
892 /*
893 * Committed/conditional with single channel entry.
894 * Clear the potential in case that it is set.
895 */
896 entry->type &= ~NAN_AVAIL_ENTRY_CTRL_TYPE_POTENTIAL;
897 }
898 }
899
900 dl_list_add(&peer_info->avail_entries, &entry->list);
901 return 0;
902
903 out:
904 nan_del_avail_entry(entry);
905 return -1;
906 }
907
908
909 /*
910 * nan_parse_avail_attr - Parse NAN Availability attribute
911 *
912 * @nan: NAN module context from nan_init()
913 * @peer_info: Peer info where the parsed entries would be added
914 * @avail_attr: Pointer to the availability attribute
915 *
916 * Parse availability attribute as defined in Wi-Fi Aware Specification
917 * v4.0, section 9.5.17.1.
918 */
nan_parse_avail_attr(struct nan_data * nan,struct nan_peer_info * peer_info,const struct nan_avail * avail_attr,u16 attr_len)919 static int nan_parse_avail_attr(struct nan_data *nan,
920 struct nan_peer_info *peer_info,
921 const struct nan_avail *avail_attr,
922 u16 attr_len)
923 {
924 u8 map_id;
925 const u8 *entries;
926 u16 ctrl, entries_len;
927
928 wpa_printf(MSG_DEBUG, "NAN: Parse avail attr: len=%u", attr_len);
929 if (attr_len < sizeof(*avail_attr))
930 return -1;
931
932 ctrl = le_to_host16(avail_attr->ctrl);
933 map_id = ctrl & NAN_AVAIL_CTRL_MAP_ID_MASK;
934
935 entries = avail_attr->optional;
936 entries_len = attr_len - sizeof(*avail_attr);
937 if (!entries_len) {
938 wpa_printf(MSG_DEBUG,
939 "NAN: Availability attribute without any entries");
940 return -1;
941 }
942
943 while (entries_len > 2) {
944 u16 entry_len = WPA_GET_LE16(entries);
945 const struct nan_avail_ent *avail_entry =
946 (const struct nan_avail_ent *) entries;
947
948 if (entry_len + 2 > entries_len) {
949 wpa_printf(MSG_DEBUG,
950 "NAN: Truncated availability entry");
951 return -1;
952 }
953
954 if (nan_parse_avail_entry(nan, peer_info, avail_entry,
955 entry_len, map_id))
956 return -1;
957
958 entries += entry_len + 2;
959 entries_len -= entry_len + 2;
960 }
961
962 if (entries_len) {
963 wpa_printf(MSG_DEBUG,
964 "NAN: Availability entries list truncated");
965 return -1;
966 }
967
968 return 0;
969 }
970
971
nan_peer_dump_info(struct nan_data * nan,struct nan_peer_info * info)972 static void nan_peer_dump_info(struct nan_data *nan, struct nan_peer_info *info)
973 {
974 struct nan_avail_entry *entry;
975
976 wpa_printf(MSG_DEBUG,
977 "NAN: info: seen=%lu.%lu, seq_id=%u",
978 info->last_seen.sec, info->last_seen.usec,
979 info->seq_id);
980
981 dl_list_for_each(entry, &info->avail_entries, struct nan_avail_entry,
982 list) {
983 unsigned int i;
984
985 wpa_printf(MSG_DEBUG,
986 "NAN: entry: map_id=%u, type=0x%x, pref=%u, util=%u",
987 entry->map_id, entry->type, entry->preference,
988 entry->utilization);
989 wpa_printf(MSG_DEBUG,
990 "NAN: entry: band_channel_type=%u, n_band_chan=%u",
991 entry->band_chan_type, entry->n_band_chan);
992
993 for (i = 0; i < entry->n_band_chan; i++) {
994 struct nan_band_chan *bc = &entry->band_chan[i];
995
996 if (entry->type == NAN_TYPE_BAND)
997 wpa_printf(MSG_DEBUG,
998 "NAN: band: %u", bc->u.band_id);
999 else
1000 wpa_printf(MSG_DEBUG,
1001 "NAN: channel: oc=%u, cbtm=0x%x, pcbtm=0x%x",
1002 bc->u.chan.op_class,
1003 bc->u.chan.chan_bitmap,
1004 bc->u.chan.pri_chan_bitmap);
1005 }
1006 }
1007 }
1008
1009
nan_peer_dump(struct nan_data * nan,struct nan_peer * peer)1010 static void nan_peer_dump(struct nan_data *nan, struct nan_peer *peer)
1011 {
1012 wpa_printf(MSG_DEBUG,
1013 "NAN: peer: " MACSTR " last_seen=%lu.%lu",
1014 MAC2STR(peer->nmi_addr), peer->last_seen.sec,
1015 peer->last_seen.usec);
1016
1017 nan_peer_dump_info(nan, &peer->info);
1018 }
1019
1020
nan_peer_disconnect_all_ndps(struct nan_data * nan,struct nan_peer * peer)1021 static void nan_peer_disconnect_all_ndps(struct nan_data *nan,
1022 struct nan_peer *peer)
1023 {
1024 struct nan_ndp *ndp, *tmp;
1025 u8 *local_ndi = NULL, *peer_ndi = NULL;
1026 struct nan_ndp_id ndp_id;
1027
1028 if (peer->ndp_setup.ndp)
1029 nan_ndp_disconnected(nan, peer, NAN_REASON_UNSPECIFIED_REASON,
1030 false);
1031
1032 dl_list_for_each_safe(ndp, tmp, &peer->ndps, struct nan_ndp, list) {
1033 if (ndp->initiator) {
1034 local_ndi = ndp->init_ndi;
1035 peer_ndi = ndp->resp_ndi;
1036 } else {
1037 local_ndi = ndp->resp_ndi;
1038 peer_ndi = ndp->init_ndi;
1039 }
1040
1041 os_memcpy(&ndp_id.peer_nmi, peer->nmi_addr, ETH_ALEN);
1042 os_memcpy(ndp_id.init_ndi, ndp->init_ndi, ETH_ALEN);
1043 ndp_id.id = ndp->ndp_id;
1044
1045 peer->ndp_setup.ndp = ndp;
1046 peer->ndp_setup.state = NAN_NDP_STATE_DONE;
1047 peer->ndp_setup.status = NAN_NDP_STATUS_REJECTED;
1048 peer->ndp_setup.reason = NAN_REASON_UNSPECIFIED_REASON;
1049 nan_action_send(nan, peer, NAN_SUBTYPE_DATA_PATH_TERMINATION);
1050 peer->ndp_setup.ndp = NULL;
1051
1052 dl_list_del(&ndp->list);
1053 nan_ndp_terminated(nan, peer, &ndp_id, local_ndi, peer_ndi,
1054 NAN_REASON_UNSPECIFIED_REASON,
1055 ndp->gtk_id);
1056 os_free(ndp);
1057 }
1058 }
1059
1060
nan_peer_update_schedule(struct nan_data * nan,struct nan_peer * peer,struct nan_schedule * sched)1061 static void nan_peer_update_schedule(struct nan_data *nan,
1062 struct nan_peer *peer,
1063 struct nan_schedule *sched)
1064 {
1065 struct bitfield *common_bf;
1066 int ret = -1;
1067
1068 common_bf = nan_peer_schedule_intersection(nan, peer, sched);
1069 if (common_bf && nan_ndl_meets_qos(nan, peer, common_bf) &&
1070 nan_ndl_validate_peer_avail(nan, peer))
1071 ret = nan_configure_peer_schedule(nan, peer, sched);
1072 else
1073 wpa_printf(MSG_DEBUG, "NAN: New peer schedule breaks NDL");
1074
1075 if (ret)
1076 nan_peer_disconnect_all_ndps(nan, peer);
1077 else if (nan->cfg->schedule_changed)
1078 nan->cfg->schedule_changed(nan->cfg->cb_ctx, peer->nmi_addr);
1079
1080 bitfield_free(common_bf);
1081 }
1082
1083
1084 /*
1085 * Update the old peer info with information from the new peer info.
1086 * Information that is available in the old peer info but is not available
1087 * in the new peer info will not be changed.
1088 * Peer schedule may be updated if the peer availabilty or ULW changed.
1089 */
nan_merge_peer_info(struct nan_data * nan,struct nan_peer * peer,struct nan_peer_info * old,struct nan_peer_info * new)1090 static void nan_merge_peer_info(struct nan_data *nan, struct nan_peer *peer,
1091 struct nan_peer_info *old,
1092 struct nan_peer_info *new)
1093 {
1094 bool schedule_changed = false;
1095
1096 if (!dl_list_empty(&new->avail_entries)) {
1097 struct nan_avail_entry *avail, *tmp;
1098
1099 nan_peer_flush_avail(old);
1100 dl_list_init(&old->avail_entries);
1101
1102 dl_list_for_each_safe(avail, tmp, &new->avail_entries,
1103 struct nan_avail_entry, list) {
1104 dl_list_del(&avail->list);
1105 dl_list_add(&old->avail_entries, &avail->list);
1106 }
1107 old->seq_id = new->seq_id;
1108 schedule_changed = true;
1109 }
1110
1111 if (!dl_list_empty(&new->ulw)) {
1112 struct nan_ulw_entry *entry, *tmp;
1113
1114 nan_peer_flush_ulw(old);
1115 dl_list_init(&old->ulw);
1116
1117 dl_list_for_each_safe(entry, tmp, &new->ulw,
1118 struct nan_ulw_entry, list) {
1119 dl_list_del(&entry->list);
1120 dl_list_add(&old->ulw, &entry->list);
1121 }
1122
1123 schedule_changed = true;
1124 }
1125
1126 old->last_seen = new->last_seen;
1127
1128 if (schedule_changed && peer->ndl &&
1129 peer->ndl->state == NAN_NDL_STATE_DONE)
1130 nan_peer_update_schedule(nan, peer, &nan->sched);
1131 }
1132
1133
nan_avail_info(struct nan_data * nan,struct nan_peer * peer,struct nan_attrs * attrs,struct nan_peer_info * info)1134 static int nan_avail_info(struct nan_data *nan, struct nan_peer *peer,
1135 struct nan_attrs *attrs, struct nan_peer_info *info)
1136 {
1137 const struct nan_avail *avail_attr;
1138 const struct nan_attrs_entry *attr;
1139
1140 attr = dl_list_first(&attrs->avail, struct nan_attrs_entry, list);
1141 if (!attr)
1142 return 0;
1143
1144 avail_attr = (const struct nan_avail *) attr->ptr;
1145
1146 /*
1147 * The sequence ID may wrap around, so if the received sequence iD is
1148 * much smaller than the sequence ID of the last update, assume it has
1149 * wrapped around and accept the new schedule. Otherwise, ignore it as
1150 * an old schedule.
1151 */
1152 if (!dl_list_empty(&peer->info.avail_entries) &&
1153 peer->info.seq_id >= avail_attr->seq_id &&
1154 peer->info.seq_id - avail_attr->seq_id < 128) {
1155 wpa_printf(MSG_DEBUG,
1156 "NAN: Ignore peer avail update: seq_id=%hhu, seq_id=%hhu",
1157 avail_attr->seq_id, peer->info.seq_id);
1158 return 0;
1159 }
1160
1161 info->seq_id = avail_attr->seq_id;
1162
1163 dl_list_for_each(attr, &attrs->avail, struct nan_attrs_entry, list) {
1164 avail_attr = (const struct nan_avail *) attr->ptr;
1165
1166 if (avail_attr->seq_id != info->seq_id) {
1167 wpa_printf(MSG_DEBUG,
1168 "NAN: Not all avail attributes have the same seq_id");
1169 goto out;
1170 }
1171
1172 if (nan_parse_avail_attr(nan, info, avail_attr, attr->len))
1173 goto out;
1174 }
1175
1176 return 0;
1177 out:
1178 nan_peer_flush_avail(info);
1179 return -1;
1180 }
1181
1182
nan_get_dev_capa_entry(struct nan_peer * peer,u8 map_id)1183 static struct nan_dev_capa_entry * nan_get_dev_capa_entry(struct nan_peer *peer,
1184 u8 map_id)
1185 {
1186 struct nan_dev_capa_entry *entry;
1187
1188 dl_list_for_each(entry, &peer->info.dev_capa,
1189 struct nan_dev_capa_entry, list) {
1190 if (entry->map_id == map_id)
1191 return entry;
1192 }
1193
1194 return NULL;
1195 }
1196
1197
nan_parse_peer_device_capa_attr(struct nan_data * nan,struct nan_peer * peer,const struct nan_attrs_entry * attr)1198 static void nan_parse_peer_device_capa_attr(struct nan_data *nan,
1199 struct nan_peer *peer,
1200 const struct nan_attrs_entry *attr)
1201 {
1202 const struct nan_device_capa *capa;
1203 struct nan_dev_capa_entry *entry;
1204
1205 capa = (const struct nan_device_capa *) attr->ptr;
1206
1207 /* See if we already have an entry for this map ID */
1208 entry = nan_get_dev_capa_entry(peer, capa->map_id);
1209 if (!entry) {
1210 entry = os_zalloc(sizeof(*entry));
1211 if (!entry) {
1212 wpa_printf(MSG_INFO,
1213 "NAN: Failed to allocate device capability entry");
1214 return;
1215 }
1216
1217 dl_list_init(&entry->list);
1218 dl_list_add(&peer->info.dev_capa, &entry->list);
1219 }
1220
1221 entry->map_id = capa->map_id;
1222 entry->capa.cdw_info = le_to_host16(capa->cdw_info);
1223 entry->capa.supported_bands = capa->supported_bands;
1224 entry->capa.op_mode = capa->op_mode;
1225 entry->capa.n_antennas = capa->ant;
1226 entry->capa.channel_switch_time =
1227 le_to_host16(capa->channel_switch_time);
1228 entry->capa.capa = capa->capa;
1229 }
1230
1231
nan_parse_peer_device_capa(struct nan_data * nan,struct nan_peer * peer,const struct nan_attrs * attrs)1232 static void nan_parse_peer_device_capa(struct nan_data *nan,
1233 struct nan_peer *peer,
1234 const struct nan_attrs *attrs)
1235 {
1236 const struct nan_attrs_entry *attr;
1237
1238 dl_list_for_each(attr, &attrs->dev_capa, struct nan_attrs_entry, list)
1239 nan_parse_peer_device_capa_attr(nan, peer, attr);
1240 }
1241
1242
nan_parse_peer_elem_container_attr(struct nan_data * nan,struct nan_peer * peer,const struct nan_attrs_entry * attr)1243 static void nan_parse_peer_elem_container_attr(
1244 struct nan_data *nan, struct nan_peer *peer,
1245 const struct nan_attrs_entry *attr)
1246 {
1247 struct nan_elem_container_entry *entry, *next;
1248 u8 map_id = *attr->ptr;
1249
1250 /* Guarantee that there is only a single entry for each map ID */
1251 dl_list_for_each_safe(entry, next, &peer->info.element_container,
1252 struct nan_elem_container_entry, list) {
1253 if (entry->map_id == map_id) {
1254 dl_list_del(&entry->list);
1255 os_free(entry);
1256 break;
1257 }
1258 }
1259
1260 entry = os_zalloc(sizeof(*entry) + attr->len - 1);
1261 if (!entry) {
1262 wpa_printf(MSG_DEBUG,
1263 "NAN: Failed to allocate element container entry");
1264 return;
1265 }
1266
1267 dl_list_init(&entry->list);
1268 dl_list_add(&peer->info.element_container, &entry->list);
1269
1270 entry->map_id = map_id;
1271 entry->len = attr->len - 1;
1272 os_memcpy(entry->data, attr->ptr + 1, entry->len);
1273 }
1274
1275
nan_parse_peer_elem_container(struct nan_data * nan,struct nan_peer * peer,const struct nan_attrs * attrs)1276 static void nan_parse_peer_elem_container(struct nan_data *nan,
1277 struct nan_peer *peer,
1278 const struct nan_attrs *attrs)
1279 {
1280 const struct nan_attrs_entry *attr;
1281
1282 dl_list_for_each(attr, &attrs->element_container,
1283 struct nan_attrs_entry, list)
1284 nan_parse_peer_elem_container_attr(nan, peer, attr);
1285 }
1286
1287
nan_parse_peer_ulw(const struct nan_attrs * attrs,const struct nan_peer_info * cur_info,struct nan_peer_info * info)1288 static int nan_parse_peer_ulw(const struct nan_attrs *attrs,
1289 const struct nan_peer_info *cur_info,
1290 struct nan_peer_info *info)
1291 {
1292 struct nan_ulw_entry *cur;
1293 struct nan_attrs_entry *attr;
1294 u8 max_seq_id = 0;
1295 bool max_seq_id_valid = false;
1296
1297 if (dl_list_empty(&attrs->ulw))
1298 return 0;
1299
1300 dl_list_for_each(cur, &cur_info->ulw, struct nan_ulw_entry, list) {
1301 const struct nan_unaligned_sched *ulw;
1302
1303 ulw = (const struct nan_unaligned_sched *) cur->data;
1304 if (!max_seq_id_valid || ulw->seq_id > max_seq_id) {
1305 max_seq_id = ulw->seq_id;
1306 max_seq_id_valid = true;
1307 }
1308 }
1309
1310 dl_list_for_each(attr, &attrs->ulw, struct nan_attrs_entry, list) {
1311 struct nan_ulw_entry *entry;
1312 const struct nan_unaligned_sched *ulw =
1313 (const struct nan_unaligned_sched *) attr->ptr;
1314
1315 if (max_seq_id_valid && ulw->seq_id <= max_seq_id) {
1316 wpa_printf(MSG_DEBUG,
1317 "NAN: Skip old ULW entry with seq_id=%u",
1318 ulw->seq_id);
1319 continue;
1320 }
1321
1322 entry = os_zalloc(sizeof(*entry) + attr->len);
1323 if (!entry) {
1324 wpa_printf(MSG_INFO,
1325 "NAN: Failed to allocate ULW entry");
1326 nan_peer_flush_ulw(info);
1327 return -1;
1328 }
1329
1330 dl_list_init(&entry->list);
1331 dl_list_add(&info->ulw, &entry->list);
1332
1333 entry->len = attr->len;
1334 os_memcpy(entry->data, attr->ptr, entry->len);
1335 }
1336
1337 return 0;
1338 }
1339
1340
nan_parse_peer_dev_capa_ext(struct nan_data * nan,struct nan_peer * peer,struct nan_attrs * attrs)1341 void nan_parse_peer_dev_capa_ext(struct nan_data *nan, struct nan_peer *peer,
1342 struct nan_attrs *attrs)
1343 {
1344 if (!attrs->dev_capa_ext || attrs->dev_capa_ext_len <= 1)
1345 return;
1346
1347 peer->pairing.pairing_cfg.pairing_setup = attrs->dev_capa_ext[1] &
1348 NAN_DEV_CAPA_EXT_INFO_1_PAIRING_SETUP;
1349 peer->pairing.pairing_cfg.npk_caching = attrs->dev_capa_ext[1] &
1350 NAN_DEV_CAPA_EXT_INFO_1_NPK_NIK_CACHING;
1351 }
1352
1353
nan_parse_npba(struct nan_data * nan,struct nan_peer * peer,struct nan_attrs * attrs)1354 static void nan_parse_npba(struct nan_data *nan, struct nan_peer *peer,
1355 struct nan_attrs *attrs)
1356 {
1357 const u8 *npba = attrs->npba;
1358 u8 type;
1359
1360 if (!attrs->npba || attrs->npba_len < 5)
1361 return;
1362
1363 /* Skip the dialog token and get the type */
1364 type = npba[1] & NAN_PBA_TYPE_MASK;
1365 if (type != NAN_PBA_TYPE_ADVERTISE)
1366 return;
1367
1368 peer->bootstrap.supported_methods = WPA_GET_LE16(npba + 3);
1369
1370 wpa_printf(MSG_DEBUG, "NAN: Peer supports bootstrap methods: 0x%04x",
1371 peer->bootstrap.supported_methods);
1372 }
1373
1374
nan_parse_nira(struct nan_data * nan,struct nan_peer * peer,struct nan_attrs * attrs)1375 static void nan_parse_nira(struct nan_data *nan, struct nan_peer *peer,
1376 struct nan_attrs *attrs)
1377 {
1378 const u8 *pos;
1379
1380 if (!attrs->nira)
1381 return;
1382
1383 peer->pairing.pairing_cfg.pairing_verification = true;
1384
1385 pos = attrs->nira + 1;
1386 os_memcpy(peer->pairing.nonce, pos, NAN_NIRA_NONCE_LEN);
1387 pos += NAN_NIRA_NONCE_LEN;
1388 os_memcpy(peer->pairing.tag, pos, NAN_NIRA_TAG_LEN);
1389 peer->pairing.nonce_tag_valid = true;
1390 }
1391
1392
1393 /*
1394 * nan_parse_device_attrs - Parse device attributes and build availability info
1395 *
1396 * @nan: NAN module context from nan_init()
1397 * @peer: NAN peer
1398 * @attrs_data: Buffer holding the device attributes
1399 * @attrs_len: Length of &attrs_data in octets
1400 * Return 0 on success; -1 otherwise.
1401 */
nan_parse_device_attrs(struct nan_data * nan,struct nan_peer * peer,const u8 * attrs_data,size_t attrs_len)1402 int nan_parse_device_attrs(struct nan_data *nan, struct nan_peer *peer,
1403 const u8 *attrs_data, size_t attrs_len)
1404 {
1405 struct nan_peer_info info;
1406 struct nan_attrs attrs;
1407 int ret;
1408
1409 os_memset(&info, 0, sizeof(info));
1410 dl_list_init(&info.avail_entries);
1411 dl_list_init(&info.ulw);
1412 os_get_reltime(&info.last_seen);
1413
1414 if (nan_parse_attrs(nan, attrs_data, attrs_len, &attrs)) {
1415 wpa_printf(MSG_DEBUG,
1416 "NAN: Failed to parse peer " MACSTR " attributes",
1417 MAC2STR(peer->nmi_addr));
1418 return -1;
1419 }
1420
1421 if (nan_avail_info(nan, peer, &attrs, &info)) {
1422 ret = -1;
1423 goto out;
1424 }
1425
1426 if (nan_parse_peer_ulw(&attrs, &peer->info, &info)) {
1427 ret = -1;
1428 goto out;
1429 }
1430
1431 nan_merge_peer_info(nan, peer, &peer->info, &info);
1432 nan_parse_peer_device_capa(nan, peer, &attrs);
1433 nan_parse_peer_elem_container(nan, peer, &attrs);
1434 nan_parse_peer_dev_capa_ext(nan, peer, &attrs);
1435 nan_parse_npba(nan, peer, &attrs);
1436 nan_parse_nira(nan, peer, &attrs);
1437
1438 nan_peer_dump(nan, peer);
1439 ret = 0;
1440 out:
1441 nan_peer_flush_avail(&info);
1442 nan_peer_flush_ulw(&info);
1443 nan_attrs_clear(nan, &attrs);
1444 return ret;
1445 }
1446
1447
nan_alloc_peer(struct nan_data * nan)1448 static struct nan_peer * nan_alloc_peer(struct nan_data *nan)
1449 {
1450 struct nan_peer *peer, *oldest = NULL;
1451 size_t count = 0;
1452
1453 dl_list_for_each(peer, &nan->peer_list, struct nan_peer, list) {
1454 count++;
1455
1456 /* Do not expire peers that we have NDPs with */
1457 if (!dl_list_empty(&peer->ndps) || peer->ndp_setup.ndp)
1458 continue;
1459
1460 if (!oldest ||
1461 os_reltime_before(&peer->last_seen, &oldest->last_seen))
1462 oldest = peer;
1463 }
1464
1465 if (count >= NAN_MAX_PEERS) {
1466 if (!oldest) {
1467 wpa_printf(MSG_DEBUG,
1468 "NAN: Cannot remove any of the peers");
1469 return NULL;
1470 }
1471
1472 wpa_printf(MSG_DEBUG,
1473 "NAN: Remove peer=" MACSTR " to make room",
1474 MAC2STR(oldest->nmi_addr));
1475
1476 nan_del_peer(nan, oldest);
1477 }
1478
1479 peer = os_zalloc(sizeof(*peer));
1480 if (!peer)
1481 return NULL;
1482
1483 dl_list_init(&peer->info.avail_entries);
1484 dl_list_init(&peer->info.ulw);
1485 dl_list_init(&peer->info.dev_capa);
1486 dl_list_init(&peer->info.element_container);
1487 dl_list_init(&peer->info.sec);
1488
1489 dl_list_add(&nan->peer_list, &peer->list);
1490 dl_list_init(&peer->ndps);
1491 return peer;
1492 }
1493
1494
nan_add_peer(struct nan_data * nan,const u8 * addr,const u8 * device_attrs,size_t device_attrs_len)1495 int nan_add_peer(struct nan_data *nan, const u8 *addr,
1496 const u8 *device_attrs, size_t device_attrs_len)
1497 {
1498 struct nan_peer *peer;
1499
1500 /* Allow adding peer devices even if NAN was not started, to support
1501 * discovery during USD, etc. */
1502 if (!nan)
1503 return -1;
1504
1505 if (!device_attrs || !device_attrs_len) {
1506 wpa_printf(MSG_DEBUG,
1507 "NAN: Ignore add_peer with no device attributes");
1508 return -1;
1509 }
1510
1511 peer = nan_get_peer(nan, addr);
1512 if (!peer) {
1513 peer = nan_alloc_peer(nan);
1514 if (!peer)
1515 return -1;
1516
1517 os_memcpy(peer->nmi_addr, addr, ETH_ALEN);
1518 }
1519
1520 nan_parse_device_attrs(nan, peer, device_attrs, device_attrs_len);
1521
1522 os_get_reltime(&peer->last_seen);
1523 return 0;
1524 }
1525
1526
nan_action_build_header(struct nan_data * nan,struct nan_peer * peer,struct wpabuf * buf,enum nan_subtype subtype)1527 static void nan_action_build_header(struct nan_data *nan, struct nan_peer *peer,
1528 struct wpabuf *buf,
1529 enum nan_subtype subtype)
1530 {
1531 u8 category = WLAN_ACTION_PUBLIC;
1532
1533 if (nan_pairing_is_peer_paired(nan, peer->nmi_addr) ||
1534 !dl_list_empty(&peer->info.sec))
1535 category = WLAN_ACTION_PROTECTED_DUAL;
1536
1537 wpabuf_put_u8(buf, category);
1538 wpabuf_put_u8(buf, WLAN_PA_VENDOR_SPECIFIC);
1539 wpabuf_put_be24(buf, OUI_WFA);
1540 wpabuf_put_u8(buf, NAN_NAF_OUI_TYPE);
1541 wpabuf_put_u8(buf, subtype);
1542 }
1543
1544
nan_action_build(struct nan_data * nan,struct nan_peer * peer,enum nan_subtype subtype,struct wpabuf * buf)1545 static int nan_action_build(struct nan_data *nan, struct nan_peer *peer,
1546 enum nan_subtype subtype, struct wpabuf *buf)
1547 {
1548 int ret;
1549
1550 wpa_printf(MSG_DEBUG, "NAN: Build NAF");
1551
1552 nan_action_build_header(nan, peer, buf, subtype);
1553
1554 nan_add_dev_capa_attr(nan, buf);
1555 nan_add_dev_capa_ext_attr(nan, buf);
1556
1557 ret = nan_ndp_add_ndp_attr(nan, peer, buf);
1558 if (ret)
1559 return ret;
1560
1561 ret = nan_sec_add_attrs(nan, peer, subtype, buf);
1562 if (ret)
1563 return ret;
1564
1565 ret = nan_ndl_add_avail_attrs(nan, peer, buf);
1566 if (ret)
1567 return ret;
1568
1569 ret = nan_ndl_add_ndc_attr(nan, peer, buf);
1570 if (ret)
1571 return ret;
1572
1573 ret = nan_ndl_add_ndl_attr(nan, peer, buf);
1574 if (ret)
1575 return ret;
1576
1577 ret = nan_ndl_add_qos_attr(nan, peer, buf);
1578 if (ret)
1579 return ret;
1580
1581 nan_ndl_add_elem_container_attr(nan, peer, buf);
1582
1583 wpa_printf(MSG_DEBUG, "NAN: Build NAF: Done");
1584
1585 return 0;
1586 }
1587
1588
nan_action_send(struct nan_data * nan,struct nan_peer * peer,enum nan_subtype subtype)1589 static int nan_action_send(struct nan_data *nan, struct nan_peer *peer,
1590 enum nan_subtype subtype)
1591 {
1592 struct wpabuf *buf;
1593 struct nan_peer_sec_info_entry *cur, *next;
1594 const u8 *src, *dst;
1595 int ret;
1596
1597 buf = wpabuf_alloc(NAN_MAX_NAF_LEN);
1598 if (!buf)
1599 return -1;
1600
1601 ret = nan_action_build(nan, peer, subtype, buf);
1602 if (ret)
1603 goto out;
1604
1605 ret = nan_sec_pre_tx(nan, peer, buf);
1606 if (ret)
1607 goto out;
1608
1609 if (!nan->cfg->send_naf)
1610 goto out;
1611
1612 /*
1613 * By default, the NAN management interface is used for the NAF
1614 * transmission. However, when pairing was not established with the peer
1615 * and there is a secure NDP with the peer, need to use the NDIs so that
1616 * the NAF would be sent in a secure manner
1617 */
1618 src = NULL;
1619 dst = peer->nmi_addr;
1620
1621 if (!(peer->pairing.flags & NAN_PAIRING_FLAG_PAIRED)) {
1622 dl_list_for_each_safe(cur, next, &peer->info.sec,
1623 struct nan_peer_sec_info_entry, list) {
1624 src = cur->local_ndi;
1625 dst = cur->peer_ndi;
1626 break;
1627 }
1628 }
1629
1630 ret = nan->cfg->send_naf(nan->cfg->cb_ctx, dst, src,
1631 nan->cluster_id, buf);
1632 out:
1633 wpa_printf(MSG_DEBUG, "NAN: send_naf: ret=%d", ret);
1634 wpabuf_free(buf);
1635 return ret;
1636 }
1637
1638
nan_ndp_supported(struct nan_data * nan)1639 static bool nan_ndp_supported(struct nan_data *nan)
1640 {
1641 if (nan->cfg->ndp_action_notif && nan->cfg->ndp_connected &&
1642 nan->cfg->ndp_disconnected &&
1643 nan->cfg->send_naf && nan->cfg->get_chans &&
1644 nan->cfg->is_valid_publish_id &&
1645 nan->cfg->set_peer_schedule)
1646 return true;
1647
1648 wpa_printf(MSG_DEBUG, "NAN: NDP operations are not supported");
1649 return false;
1650 }
1651
1652
1653 static void
1654 nan_peer_get_committed_avail(const struct nan_data *nan,
1655 const struct nan_peer *peer,
1656 const struct nan_schedule *local_sched,
1657 struct nan_peer_schedule *sched);
1658
1659
nan_configure_peer_schedule(struct nan_data * nan,struct nan_peer * peer,const struct nan_schedule * local_sched)1660 int nan_configure_peer_schedule(struct nan_data *nan, struct nan_peer *peer,
1661 const struct nan_schedule *local_sched)
1662 {
1663 int ret;
1664 struct nan_dev_capa_entry *cur;
1665 struct nan_device_capabilities *capa = NULL;
1666 struct nan_peer_schedule sched;
1667 struct bitfield *common_bf;
1668 struct wpabuf *ulw_elems;
1669
1670 wpa_printf(MSG_DEBUG, "NAN: Configure peer schedule for " MACSTR,
1671 MAC2STR(peer->nmi_addr));
1672
1673 if (nan->sched_update_pending) {
1674 wpa_printf(MSG_DEBUG,
1675 "NAN: Skip peer schedule config - local schedule update pending");
1676 return 0;
1677 }
1678
1679 os_memset(&sched, 0, sizeof(sched));
1680 common_bf = nan_peer_schedule_intersection(nan, peer, local_sched);
1681 if (common_bf)
1682 nan_peer_get_committed_avail(nan, peer, local_sched, &sched);
1683 else
1684 wpa_printf(MSG_DEBUG,
1685 "NAN: Cannot configure peer schedule since there is no intersection");
1686
1687 bitfield_free(common_bf);
1688
1689 dl_list_for_each(cur, &peer->info.dev_capa,
1690 struct nan_dev_capa_entry, list) {
1691 /*
1692 * Take the first one, as both CDW and channel switch time are
1693 * identical across all attributes
1694 */
1695 capa = &cur->capa;
1696 break;
1697 }
1698
1699 if (!capa) {
1700 wpa_printf(MSG_DEBUG,
1701 "NAN: Cannot configure peer NMI STA - no device capabilities");
1702 return -1;
1703 }
1704
1705 ulw_elems = nan_peer_build_ulw_attrs(&peer->info);
1706
1707 ret = nan->cfg->set_peer_schedule(nan->cfg->cb_ctx, peer->nmi_addr,
1708 !peer->configured, capa->cdw_info,
1709 peer->info.seq_id,
1710 capa->channel_switch_time, &sched,
1711 ulw_elems);
1712 wpabuf_free(ulw_elems);
1713 if (ret) {
1714 wpa_printf(MSG_DEBUG, "NAN: Failed to set peer schedule");
1715 return ret;
1716 }
1717
1718 peer->configured = true;
1719 return 0;
1720 }
1721
1722
nan_clear_peer_schedule(struct nan_data * nan,struct nan_peer * peer)1723 int nan_clear_peer_schedule(struct nan_data *nan, struct nan_peer *peer)
1724 {
1725 int ret;
1726
1727 wpa_printf(MSG_DEBUG, "NAN: Clear peer schedule, peer->configured=%d",
1728 peer->configured);
1729
1730 if (!peer->configured)
1731 return 0;
1732
1733 ret = nan->cfg->set_peer_schedule(nan->cfg->cb_ctx, peer->nmi_addr,
1734 false, 0, peer->info.seq_id, 0, NULL,
1735 NULL);
1736 if (ret)
1737 wpa_printf(MSG_DEBUG, "NAN: Failed to clear peer schedule");
1738
1739 peer->configured = false;
1740 return 0;
1741 }
1742
1743
1744 /**
1745 * nan_process_followup - Process a received NAN Follow-up Action frame
1746 * @nan: NAN module context from nan_init()
1747 * @addr: Source address of the received frame
1748 * @buf: Buffer containing the received frame
1749 * @len: Length of the received frame in octets
1750 * @req_instance_id: Instance ID of the request that triggered this followup
1751 * @handle: Service handle of the service associated with this followup
1752 * Returns: true if the frame was processed successfully, false on failure
1753 */
nan_process_followup(struct nan_data * nan,const u8 * addr,const u8 * buf,size_t len,u8 req_instance_id,int handle)1754 bool nan_process_followup(struct nan_data *nan, const u8 *addr, const u8 *buf,
1755 size_t len, u8 req_instance_id, int handle)
1756 {
1757 struct nan_attrs attrs;
1758 bool ret = false;
1759
1760 if (nan_parse_attrs(nan, buf, len, &attrs)) {
1761 wpa_printf(MSG_DEBUG,
1762 "NAN: Follow-up: Failed parsing attributes");
1763 return false;
1764 }
1765
1766 if (attrs.npba && attrs.npba_len)
1767 ret = nan_bootstrap_handle_rx(nan, addr, attrs.npba,
1768 attrs.npba_len, buf, len, handle,
1769 req_instance_id);
1770 #ifdef CONFIG_PASN
1771 else if (attrs.shared_key_desc)
1772 ret = nan_pairing_followup_rx(nan, addr,
1773 (const struct nan_shared_key *)
1774 attrs.shared_key_desc,
1775 attrs.shared_key_desc_len);
1776 #endif /* CONFIG_PASN */
1777
1778 nan_attrs_clear(nan, &attrs);
1779 return ret;
1780 }
1781
1782
nan_peer_state_timeout(void * eloop_ctx,void * timeout_ctx)1783 static void nan_peer_state_timeout(void *eloop_ctx, void *timeout_ctx)
1784 {
1785 struct nan_data *nan = eloop_ctx;
1786 struct nan_peer *peer = timeout_ctx;
1787
1788 wpa_printf(MSG_DEBUG, "NAN: Timeout expired: " MACSTR,
1789 MAC2STR(peer->nmi_addr));
1790
1791 if (!peer->ndp_setup.ndp)
1792 return;
1793
1794 /* If we already sent termination just disconnect */
1795 if (peer->ndp_setup.state == NAN_NDP_STATE_DONE &&
1796 peer->ndp_setup.status == NAN_NDP_STATUS_REJECTED) {
1797 wpa_printf(MSG_DEBUG,
1798 "NAN: Timeout (NDP setup is done), disconnecting");
1799 nan_ndp_disconnected(nan, peer, NAN_REASON_UNSPECIFIED_REASON,
1800 true);
1801 return;
1802 }
1803
1804 /*
1805 * Send NDP Termination to notify the peer about the timeout.
1806 * Prepare the state for building a termination frame.
1807 */
1808 wpa_printf(MSG_DEBUG,
1809 "NAN: NDP: state: %u --> %u (timeout termination)",
1810 peer->ndp_setup.state, NAN_NDP_STATE_DONE);
1811
1812 peer->ndp_setup.state = NAN_NDP_STATE_DONE;
1813 peer->ndp_setup.status = NAN_NDP_STATUS_REJECTED;
1814 peer->ndp_setup.reason = NAN_REASON_UNSPECIFIED_REASON;
1815
1816 if (nan_action_send(nan, peer, NAN_SUBTYPE_DATA_PATH_TERMINATION)) {
1817 wpa_printf(MSG_DEBUG,
1818 "NAN: Failed to send termination on timeout");
1819 nan_ndp_disconnected(nan, peer, NAN_REASON_UNSPECIFIED_REASON,
1820 true);
1821 return;
1822 }
1823
1824 /*
1825 * Termination frame sent successfully. Set a short timeout to wait
1826 * for TX status. The TX status handler (nan_tx_status) will call
1827 * nan_ndp_disconnected().
1828 */
1829 nan_set_peer_timeout(nan, peer, NAN_NDP_SETUP_TIMEOUT_SHORT, 0);
1830 }
1831
1832
nan_set_peer_timeout(struct nan_data * nan,struct nan_peer * peer,unsigned int sec,unsigned int usec)1833 static void nan_set_peer_timeout(struct nan_data *nan, struct nan_peer *peer,
1834 unsigned int sec, unsigned int usec)
1835 {
1836 wpa_printf(MSG_DEBUG, "NAN: Set timeout: " MACSTR " %u.%06u sec",
1837 MAC2STR(peer->nmi_addr), sec, usec);
1838
1839 eloop_cancel_timeout(nan_peer_state_timeout, nan, peer);
1840 eloop_register_timeout(sec, usec, nan_peer_state_timeout, nan, peer);
1841 }
1842
1843
nan_ndp_action_notif(struct nan_data * nan,struct nan_peer * peer)1844 static void nan_ndp_action_notif(struct nan_data *nan, struct nan_peer *peer)
1845 {
1846 struct nan_ndp_action_notif_params notify;
1847
1848 os_memset(¬ify, 0, sizeof(notify));
1849
1850 os_memcpy(notify.ndp_id.peer_nmi, peer->nmi_addr, ETH_ALEN);
1851 os_memcpy(notify.ndp_id.init_ndi, peer->ndp_setup.ndp->init_ndi,
1852 ETH_ALEN);
1853 notify.ndp_id.id = peer->ndp_setup.ndp->ndp_id;
1854 notify.publish_inst_id = peer->ndp_setup.publish_inst_id;
1855
1856 notify.is_request = peer->ndp_setup.state == NAN_NDP_STATE_REQ_RECV;
1857 notify.ndp_status = peer->ndp_setup.status;
1858
1859 if (peer->ndl)
1860 notify.ndl_status = peer->ndl->status;
1861 else
1862 notify.ndl_status = NAN_NDL_STATUS_REJECTED;
1863
1864 notify.ssi = peer->ndp_setup.ssi;
1865 notify.ssi_len = peer->ndp_setup.ssi_len;
1866
1867 if (peer->ndp_setup.sec.present) {
1868 notify.csid = peer->ndp_setup.sec.i_csid;
1869 notify.pmkid = peer->ndp_setup.sec.i_pmkid;
1870 } else {
1871 notify.csid = NAN_CS_NONE;
1872 notify.pmkid = NULL;
1873 }
1874
1875 wpa_printf(MSG_DEBUG,
1876 "NAN: NDP action notification peer=" MACSTR
1877 ", ndp_status=%u, ndl_status=%u",
1878 MAC2STR(peer->nmi_addr), notify.ndp_status,
1879 notify.ndl_status);
1880
1881 if (nan->cfg->ndp_action_notif)
1882 nan->cfg->ndp_action_notif(nan->cfg->cb_ctx, ¬ify);
1883 nan_set_peer_timeout(nan, peer, NAN_NDP_SETUP_TIMEOUT_LONG, 0);
1884 }
1885
1886
nan_peer_ndi_in_use(struct nan_peer * peer,const u8 * peer_ndi)1887 static bool nan_peer_ndi_in_use(struct nan_peer *peer, const u8 *peer_ndi)
1888 {
1889 struct nan_ndp *ndp;
1890
1891 dl_list_for_each(ndp, &peer->ndps, struct nan_ndp, list) {
1892 if (ndp->initiator) {
1893 if (ether_addr_equal(ndp->resp_ndi, peer_ndi))
1894 return true;
1895 } else {
1896 if (ether_addr_equal(ndp->init_ndi, peer_ndi))
1897 return true;
1898 }
1899 }
1900
1901 return false;
1902 }
1903
1904
nan_terminate_ndps_for_ndi(struct nan_data * nan,struct nan_peer * peer,const u8 * peer_ndi)1905 static void nan_terminate_ndps_for_ndi(struct nan_data *nan,
1906 struct nan_peer *peer,
1907 const u8 *peer_ndi)
1908 {
1909 struct nan_ndp *ndp, *tndp, *curr_ndp;
1910
1911 curr_ndp = peer->ndp_setup.ndp;
1912
1913 dl_list_for_each_safe(ndp, tndp, &peer->ndps, struct nan_ndp, list) {
1914 const u8 *ndp_peer_ndi = ndp->initiator ?
1915 ndp->resp_ndi : ndp->init_ndi;
1916
1917 if (!ether_addr_equal(ndp_peer_ndi, peer_ndi))
1918 continue;
1919
1920 dl_list_del(&ndp->list);
1921
1922 /* Temporarily set the NDP being disconnected */
1923 peer->ndp_setup.ndp = ndp;
1924 nan_ndp_disconnected(nan, peer, NAN_REASON_UNSPECIFIED_REASON,
1925 true);
1926 }
1927
1928 /* Restore the current NDP */
1929 peer->ndp_setup.ndp = curr_ndp;
1930 }
1931
1932
nan_handle_idle_period(struct nan_data * nan)1933 static void nan_handle_idle_period(struct nan_data *nan)
1934 {
1935 struct nan_peer *peer;
1936 int next_timeout = 0;
1937
1938 eloop_cancel_timeout(nan_idle_period_timeout, nan, NULL);
1939
1940 if (!nan->cfg->get_peer_inactivity || !nan->cfg->max_ndl_idle_period)
1941 return;
1942
1943 wpa_printf(MSG_DEBUG,
1944 "NAN: Handle idle period timeout: max_idle_period=%d sec",
1945 nan->cfg->max_ndl_idle_period);
1946
1947 dl_list_for_each(peer, &nan->peer_list, struct nan_peer, list) {
1948 int peer_inactive = -1;
1949 struct nan_ndp *pndp;
1950
1951 if (dl_list_empty(&peer->ndps) || !peer->ndl)
1952 continue;
1953
1954 wpa_printf(MSG_DEBUG, "NAN: Check idle period for peer=" MACSTR,
1955 MAC2STR(peer->nmi_addr));
1956
1957 /* Find the minimal inactive time over all NDPs */
1958 dl_list_for_each(pndp, &peer->ndps, struct nan_ndp, list) {
1959 const u8 *local_ndi, *peer_ndi;
1960 int inactive;
1961
1962 if (pndp->initiator) {
1963 local_ndi = pndp->init_ndi;
1964 peer_ndi = pndp->resp_ndi;
1965 } else {
1966 local_ndi = pndp->resp_ndi;
1967 peer_ndi = pndp->init_ndi;
1968 }
1969
1970 inactive =
1971 nan->cfg->get_peer_inactivity(nan->cfg->cb_ctx,
1972 local_ndi,
1973 peer_ndi);
1974 wpa_printf(MSG_DEBUG,
1975 "NAN: local=" MACSTR ", peer" MACSTR
1976 " : inactivity=%d sec",
1977 MAC2STR(local_ndi), MAC2STR(peer_ndi),
1978 inactive);
1979
1980 if (inactive < 0)
1981 continue;
1982
1983 /*
1984 * peer_inactive would eventually hold the minimal
1985 * inactive time over all <local NDI, peer NDI> couples
1986 */
1987 if (peer_inactive == -1 || inactive < peer_inactive)
1988 peer_inactive = inactive;
1989 }
1990
1991 wpa_printf(MSG_DEBUG, "NAN: Peer " MACSTR
1992 " has been inactive for %d seconds",
1993 MAC2STR(peer->nmi_addr), peer_inactive);
1994
1995 if (peer_inactive >= nan->cfg->max_ndl_idle_period) {
1996 wpa_printf(MSG_DEBUG, "NAN: Peer " MACSTR
1997 " has been inactive for too long, removing NDPs",
1998 MAC2STR(peer->nmi_addr));
1999 nan_peer_del_all_ndps(nan, peer->nmi_addr);
2000 continue;
2001 }
2002
2003 if (peer_inactive == -1)
2004 peer_inactive = 0;
2005
2006 if (!next_timeout ||
2007 next_timeout >
2008 nan->cfg->max_ndl_idle_period - peer_inactive)
2009 next_timeout =
2010 nan->cfg->max_ndl_idle_period - peer_inactive;
2011 }
2012
2013 wpa_printf(MSG_DEBUG, "NAN: Next idle period timeout in %d seconds",
2014 next_timeout);
2015
2016 if (next_timeout)
2017 eloop_register_timeout(next_timeout, 0,
2018 nan_idle_period_timeout, nan, NULL);
2019 }
2020
2021
nan_idle_period_timeout(void * eloop_ctx,void * timeout_ctx)2022 static void nan_idle_period_timeout(void *eloop_ctx, void *timeout_ctx)
2023 {
2024 nan_handle_idle_period(eloop_ctx);
2025 }
2026
2027
nan_ndp_connected(struct nan_data * nan,struct nan_peer * peer)2028 static int nan_ndp_connected(struct nan_data *nan, struct nan_peer *peer)
2029 {
2030 struct nan_ndp_connection_params params;
2031 int ret;
2032
2033 os_memset(¶ms, 0, sizeof(params));
2034
2035 wpa_printf(MSG_DEBUG, "NAN: NDP connected notification peer=" MACSTR,
2036 MAC2STR(peer->nmi_addr));
2037
2038 os_memcpy(params.ndp_id.peer_nmi, peer->nmi_addr, ETH_ALEN);
2039 os_memcpy(params.ndp_id.init_ndi, peer->ndp_setup.ndp->init_ndi,
2040 ETH_ALEN);
2041 params.ndp_id.id = peer->ndp_setup.ndp->ndp_id;
2042 params.ssi = peer->ndp_setup.ssi;
2043 params.ssi_len = peer->ndp_setup.ssi_len;
2044
2045 if (peer->ndp_setup.peer_interface_id_valid) {
2046 wpa_printf(MSG_DEBUG,
2047 "NAN: NDP connected with peer interface id");
2048
2049 params.interface_id = peer->ndp_setup.peer_interface_id;
2050 }
2051
2052 if (peer->ndp_setup.ndp->initiator) {
2053 params.local_ndi = peer->ndp_setup.ndp->init_ndi;
2054 params.peer_ndi = peer->ndp_setup.ndp->resp_ndi;
2055 } else {
2056 params.local_ndi = peer->ndp_setup.ndp->resp_ndi;
2057 params.peer_ndi = peer->ndp_setup.ndp->init_ndi;
2058 }
2059
2060 params.install_keys = nan_sec_ndp_store_keys(nan, peer,
2061 params.peer_ndi,
2062 params.local_ndi);
2063 params.first_ndp = dl_list_empty(&peer->ndps);
2064
2065 if (peer->ndp_setup.sec.local_gtk.csid != NAN_CS_NONE)
2066 params.local_gtk = &peer->ndp_setup.sec.local_gtk;
2067
2068 peer->ndp_setup.ndp->gtk_id = peer->ndp_setup.sec.peer_gtk.id;
2069 if (peer->ndp_setup.sec.peer_gtk.id) {
2070 params.peer_gtk = &peer->ndp_setup.sec.peer_gtk;
2071 params.peer_gtk_rsc = peer->ndp_setup.sec.peer_gtk_rsc;
2072 }
2073
2074 params.new_ndi_sta = !nan_peer_ndi_in_use(peer, params.peer_ndi);
2075 if (nan->cfg->ndp_connected) {
2076 ret = nan->cfg->ndp_connected(nan->cfg->cb_ctx, ¶ms);
2077 if (ret) {
2078 wpa_printf(MSG_DEBUG,
2079 "NAN: NDP connected notification failed ret=%d",
2080 ret);
2081 if (ret == -2)
2082 nan_terminate_ndps_for_ndi(nan, peer,
2083 params.peer_ndi);
2084
2085 return ret;
2086 }
2087 }
2088
2089 /* Move the NDP to the list of tracked NDPs */
2090 dl_list_add(&peer->ndps, &peer->ndp_setup.ndp->list);
2091 peer->ndp_setup.ndp = NULL;
2092
2093 nan_ndp_setup_stop(nan, peer);
2094 nan_handle_idle_period(nan);
2095
2096 return 0;
2097 }
2098
2099
nan_ndp_disconnected(struct nan_data * nan,struct nan_peer * peer,enum nan_reason reason,bool locally_generated)2100 static void nan_ndp_disconnected(struct nan_data *nan, struct nan_peer *peer,
2101 enum nan_reason reason,
2102 bool locally_generated)
2103 {
2104 const u8 *local_ndi, *peer_ndi;
2105 struct nan_ndp_id ndp_id;
2106 bool remove_sta, fail;
2107
2108 os_memset(&ndp_id, 0, sizeof(ndp_id));
2109
2110 wpa_printf(MSG_DEBUG,
2111 "NAN: NDP disconnected notification peer=" MACSTR,
2112 MAC2STR(peer->nmi_addr));
2113
2114 os_memcpy(ndp_id.peer_nmi, peer->nmi_addr, ETH_ALEN);
2115 os_memcpy(ndp_id.init_ndi, peer->ndp_setup.ndp->init_ndi, ETH_ALEN);
2116 ndp_id.id = peer->ndp_setup.ndp->ndp_id;
2117
2118 if (peer->ndp_setup.ndp->initiator) {
2119 local_ndi = peer->ndp_setup.ndp->init_ndi;
2120 peer_ndi = peer->ndp_setup.ndp->resp_ndi;
2121 } else {
2122 local_ndi = peer->ndp_setup.ndp->resp_ndi;
2123 peer_ndi = peer->ndp_setup.ndp->init_ndi;
2124 }
2125
2126 /*
2127 * Remove the NDI station only if no other NDP is using the same
2128 * peer NDI address. The disconnecting NDP is in ndp_setup.ndp
2129 * (not in peer->ndps), so checking peer->ndps is sufficient.
2130 */
2131 remove_sta = !nan_peer_ndi_in_use(peer, peer_ndi);
2132
2133 /* Remove sec entry if no other NDP is using this peer NDI */
2134 if (remove_sta)
2135 nan_peer_del_sec_entry(&peer->info, peer_ndi);
2136
2137 /*
2138 * NAN_NDP_STATE_NONE means the NDP was not in progress, thus
2139 * the failure flag should be false.
2140 */
2141 fail = peer->ndp_setup.state != NAN_NDP_STATE_NONE;
2142
2143 if (nan->cfg->ndp_disconnected)
2144 nan->cfg->ndp_disconnected(nan->cfg->cb_ctx, &ndp_id,
2145 local_ndi, peer_ndi, reason,
2146 locally_generated, remove_sta,
2147 fail, peer->ndp_setup.ndp->gtk_id);
2148
2149 nan_ndp_setup_stop(nan, peer);
2150 }
2151
2152
2153 /**
2154 * nan_action_rx_ndp - Process a received NAN Data Path Action Frame
2155 * @nan: NAN module context from nan_init()
2156 * @peer: NAN peer
2157 * @msg: Parsed NAN message
2158 * @resp_oui: OUI subtype to use in case a response is needed
2159 * Returns: 0 on success; -1 on failure.
2160 */
nan_action_rx_ndp(struct nan_data * nan,struct nan_peer * peer,struct nan_msg * msg,enum nan_subtype resp_oui)2161 static int nan_action_rx_ndp(struct nan_data *nan, struct nan_peer *peer,
2162 struct nan_msg *msg, enum nan_subtype resp_oui)
2163 {
2164 int ret;
2165
2166 ret = nan_ndp_handle_ndp_attr(nan, peer, msg);
2167 if (ret) {
2168 if (ret > 0)
2169 ret = 0;
2170 return ret;
2171 }
2172
2173 /*
2174 * NDP request: Also process the NDL/NDC/QoS attributes and store the
2175 * data without actually scheduling. Send an indication to the
2176 * encapsulating logic.
2177 */
2178 if (peer->ndp_setup.state == NAN_NDP_STATE_REQ_RECV) {
2179 wpa_printf(MSG_DEBUG, "NAN: NDP request");
2180
2181 ret = nan_ndl_handle_ndl_attr(nan, peer, msg);
2182 if (ret || !peer->ndl) {
2183 nan_ndp_setup_stop(nan, peer);
2184 return -1;
2185 }
2186
2187 if (peer->ndl->status == NAN_NDL_STATUS_REJECTED) {
2188 nan_ndp_setup_failure(nan, peer,
2189 NAN_REASON_NDL_UNACCEPTABLE,
2190 false);
2191 if (peer->ndl->send_naf_on_error)
2192 nan_action_send(nan, peer, resp_oui);
2193 nan_ndp_setup_stop(nan, peer);
2194 } else {
2195 nan_ndp_action_notif(nan, peer);
2196 }
2197 return 0;
2198 }
2199
2200 /*
2201 * NDP was rejected by the peer. Clear the ongoing setup and send an
2202 * event. There is no need to send an NAF in this case.
2203 */
2204 if (peer->ndp_setup.status == NAN_NDP_STATUS_REJECTED) {
2205 wpa_printf(MSG_DEBUG, "NAN: NAF: NDP rejected");
2206
2207 nan_ndp_disconnected(nan, peer, peer->ndp_setup.reason, false);
2208 return 0;
2209 }
2210
2211 /*
2212 * NDP state machine is either done or continued, need to trigger NDL
2213 * state machine.
2214 */
2215 ret = nan_ndl_handle_ndl_attr(nan, peer, msg);
2216 if (ret || !peer->ndl)
2217 return ret;
2218
2219 if (peer->ndl->status == NAN_NDL_STATUS_REJECTED) {
2220 enum nan_reason reason = peer->ndl->reason;
2221
2222 if (reason == NAN_REASON_RESERVED)
2223 reason = NAN_REASON_UNSPECIFIED_REASON;
2224
2225 wpa_printf(MSG_DEBUG,
2226 "NAN: NAF: NDL rejected(ret=%d, reason=%u)",
2227 ret, reason);
2228
2229 /* NDL handling failure on local side */
2230 if (peer->ndl->send_naf_on_error) {
2231 nan_ndp_setup_failure(nan, peer, reason, 0);
2232 ret = nan_action_send(nan, peer, resp_oui);
2233 }
2234
2235 nan_ndp_disconnected(nan, peer, reason, false);
2236 return 0;
2237 }
2238
2239 if (peer->ndl->status == NAN_NDL_STATUS_CONTINUED) {
2240 wpa_printf(MSG_DEBUG, "NAN: NAF: NDL continues");
2241 nan_ndp_action_notif(nan, peer);
2242 return 0;
2243 }
2244
2245 /* Both state machines are done */
2246 if (peer->ndp_setup.state == NAN_NDP_STATE_DONE &&
2247 peer->ndl->state == NAN_NDL_STATE_DONE) {
2248 wpa_printf(MSG_DEBUG, "NAN: NAF: NDP setup done");
2249 if (nan_configure_peer_schedule(nan, peer, &nan->sched) ||
2250 nan_ndp_connected(nan, peer))
2251 nan_ndp_disconnected(nan, peer,
2252 NAN_REASON_UNSPECIFIED_REASON,
2253 true);
2254 return 0;
2255 }
2256
2257 wpa_printf(MSG_DEBUG, "NAN: NAF: NDP setup continues");
2258 ret = nan_action_send(nan, peer, resp_oui);
2259 if (ret) {
2260 wpa_printf(MSG_DEBUG,
2261 "NAN: NAF: Failed to send NAF. Resetting..");
2262 nan_ndp_disconnected(nan, peer, NAN_REASON_UNSPECIFIED_REASON,
2263 true);
2264 }
2265
2266 nan_set_peer_timeout(nan, peer, NAN_NDP_SETUP_TIMEOUT_SHORT, 0);
2267
2268 return 0;
2269 }
2270
2271
2272 /*
2273 * nan_action_substitute_src - Substitute the source address in the NAF if
2274 * it matches an NDI of an existing NDP
2275 *
2276 * @nan: NAN module context from nan_init()
2277 * @mgmt: Pointer to the IEEE 802.11 management frame
2278 * @len: Length of the management frame in octets
2279 *
2280 * NAFs can be sent and received on NDIs. In such cases, the source address
2281 * in the 802.11 header would be the NDI address. This function checks if
2282 * the source address matches any known NDI address and if so, substitutes
2283 * it with the NMI address of the corresponding peer.
2284 */
nan_action_substitute_src(struct nan_data * nan,const struct ieee80211_mgmt * mgmt,size_t len)2285 static void nan_action_substitute_src(struct nan_data *nan,
2286 const struct ieee80211_mgmt *mgmt,
2287 size_t len)
2288 {
2289 struct nan_peer *peer;
2290
2291 /* If the peer is known, nothing needs to be changed */
2292 peer = nan_get_peer(nan, mgmt->sa);
2293 if (peer)
2294 return;
2295
2296 /*
2297 * Find a peer with which we have an NDI that matches the source address
2298 * in the frame, and if found, substitute the frames source address with
2299 * the peer NMI
2300 */
2301 dl_list_for_each(peer, &nan->peer_list, struct nan_peer, list) {
2302 struct nan_ndp *pndp;
2303
2304 /* When a peer is paired, NAFs are not allowed on NDIs */
2305 if (peer->pairing.flags & NAN_PAIRING_FLAG_PAIRED)
2306 continue;
2307
2308 dl_list_for_each(pndp, &peer->ndps, struct nan_ndp, list) {
2309 const u8 *addr;
2310
2311 if (pndp->initiator)
2312 addr = pndp->resp_ndi;
2313 else
2314 addr = pndp->init_ndi;
2315
2316 if (os_memcmp(addr, mgmt->sa, ETH_ALEN))
2317 continue;
2318
2319 wpa_printf(MSG_DEBUG,
2320 "NAN: NAF from=" MACSTR " Received on NDI=" MACSTR,
2321 MAC2STR(peer->nmi_addr), MAC2STR(mgmt->sa));
2322
2323 os_memcpy((void *)mgmt->sa, peer->nmi_addr, ETH_ALEN);
2324 }
2325 }
2326
2327 wpa_printf(MSG_DEBUG,
2328 "NAN: NAF from unknown peer=" MACSTR,
2329 MAC2STR(mgmt->sa));
2330 }
2331
2332
2333 /*
2334 * nan_action_rx - Process a received NAN Action Frame
2335 * @nan: NAN module context from nan_init()
2336 * @mgmt: Pointer to the IEEE 802.11 Management frame
2337 * @len: Length of the Management frame in octets
2338 * Return 0 on success; -1 on failure.
2339 */
nan_action_rx(struct nan_data * nan,const struct ieee80211_mgmt * mgmt,size_t len)2340 int nan_action_rx(struct nan_data *nan, const struct ieee80211_mgmt *mgmt,
2341 size_t len)
2342 {
2343 struct nan_msg msg;
2344 struct nan_peer *peer;
2345 enum nan_subtype resp_oui = NAN_SUBTYPE_INVALID;
2346 int ret;
2347
2348 if (!nan_ndp_supported(nan))
2349 return -1;
2350
2351 nan_action_substitute_src(nan, mgmt, len);
2352
2353 /* Parse the NAF and validate its general structure */
2354
2355 ret = nan_parse_naf(nan, mgmt, len, &msg);
2356 if (ret)
2357 return ret;
2358
2359 ret = nan_add_peer(nan, mgmt->sa, mgmt->u.action.u.naf.variable,
2360 len - IEEE80211_MIN_ACTION_LEN(naf));
2361 if (ret)
2362 wpa_printf(MSG_DEBUG, "NAN: Failed to parse peer from NAF");
2363
2364 peer = nan_get_peer(nan, mgmt->sa);
2365 if (!peer) {
2366 wpa_printf(MSG_DEBUG,
2367 "NAN: Failed to get a peer that was just added");
2368 goto done;
2369 }
2370
2371 wpa_printf(MSG_DEBUG, "NAN: NAF: oui_subtype=%u", msg.oui_subtype);
2372
2373 switch (msg.oui_subtype) {
2374 case NAN_SUBTYPE_DATA_PATH_REQUEST:
2375 resp_oui = NAN_SUBTYPE_DATA_PATH_RESPONSE;
2376 break;
2377 case NAN_SUBTYPE_DATA_PATH_RESPONSE:
2378 resp_oui = NAN_SUBTYPE_DATA_PATH_CONFIRM;
2379 break;
2380 case NAN_SUBTYPE_DATA_PATH_CONFIRM:
2381 resp_oui = NAN_SUBTYPE_DATA_PATH_KEY_INSTALL;
2382 break;
2383 case NAN_SUBTYPE_DATA_PATH_KEY_INSTALL:
2384 case NAN_SUBTYPE_DATA_PATH_TERMINATION:
2385 break;
2386 case NAN_SUBTYPE_RANGING_REQUEST:
2387 case NAN_SUBTYPE_RANGING_RESPONSE:
2388 case NAN_SUBTYPE_RANGING_TERMINATION:
2389 case NAN_SUBTYPE_RANGING_REPORT:
2390 case NAN_SUBTYPE_SCHEDULE_REQUEST:
2391 case NAN_SUBTYPE_SCHEDULE_RESPONSE:
2392 case NAN_SUBTYPE_SCHEDULE_CONFIRM:
2393 case NAN_SUBTYPE_SCHEDULE_UPDATE_NOTIF:
2394 ret = 0;
2395 goto done;
2396 default:
2397 ret = -1;
2398 goto done;
2399 }
2400
2401 ret = nan_action_rx_ndp(nan, peer, &msg, resp_oui);
2402 done:
2403 nan_attrs_clear(nan, &msg.attrs);
2404 return ret;
2405 }
2406
2407
2408 /*
2409 * nan_publish_instance_id_valid - Check if instance ID is a valid publish ID
2410 * @nan: NAN module context from nan_init()
2411 * @instance_id: Instance ID to check
2412 * @service_id: On return, holds the service ID if the instance ID is valid
2413 * Returns: true if there is a local publish service ID with the given instance
2414 * ID; false otherwise
2415 */
nan_publish_instance_id_valid(struct nan_data * nan,u8 instance_id,u8 * service_id)2416 bool nan_publish_instance_id_valid(struct nan_data *nan, u8 instance_id,
2417 u8 *service_id)
2418 {
2419 if (!nan->cfg->is_valid_publish_id) {
2420 wpa_printf(MSG_INFO,
2421 "NAN: is_valid_publish_id callback not defined");
2422 return false;
2423 }
2424
2425 return nan->cfg->is_valid_publish_id(nan->cfg->cb_ctx, instance_id,
2426 service_id);
2427 }
2428
2429
2430 /*
2431 * nan_set_cluster_id - Set the cluster ID
2432 * @nan: NAN module context from nan_init()
2433 * @cluster_id: The cluster ID (6 bytes)
2434 */
nan_set_cluster_id(struct nan_data * nan,const u8 * cluster_id)2435 void nan_set_cluster_id(struct nan_data *nan, const u8 *cluster_id)
2436 {
2437 os_memcpy(nan->cluster_id, cluster_id, sizeof(nan->cluster_id));
2438 }
2439
2440
2441 /*
2442 * nan_tx_status_get_peer - Get the peer for a transmitted NAF
2443 *
2444 * @nan: NAN module context from nan_init()
2445 * @dst: Destination address of the transmitted frame
2446 * Return: Pointer to the peer or NULL if not found
2447 */
nan_tx_status_get_peer(struct nan_data * nan,const u8 * dst)2448 static struct nan_peer *nan_tx_status_get_peer(struct nan_data *nan,
2449 const u8 *dst)
2450 {
2451 struct nan_peer *peer;
2452
2453 peer = nan_get_peer(nan, dst);
2454 if (peer)
2455 return peer;
2456
2457 /*
2458 * It is possible that the NAF was transmitted over an NDI, e.g.,
2459 * in case that a secure NDP was established with the peer
2460 */
2461 dl_list_for_each(peer, &nan->peer_list, struct nan_peer, list) {
2462 struct nan_ndp *pndp;
2463 const u8 *paddr;
2464
2465 /* When a peer is paired, NAFs are not allowed on NDIs */
2466 if (peer->pairing.flags & NAN_PAIRING_FLAG_PAIRED)
2467 continue;
2468
2469 /*
2470 * When an NDP termination is initiated locally, the NDP is
2471 * removed from the list and is set to the 'ndp_setup' object
2472 * so need to also check that one.
2473 */
2474 if (peer->ndp_setup.ndp) {
2475 pndp = peer->ndp_setup.ndp;
2476
2477 if (pndp->initiator)
2478 paddr = pndp->resp_ndi;
2479 else
2480 paddr = pndp->init_ndi;
2481
2482 if (!os_memcmp(dst, paddr, ETH_ALEN))
2483 return peer;
2484 }
2485
2486 dl_list_for_each(pndp, &peer->ndps, struct nan_ndp, list) {
2487 if (pndp->initiator)
2488 paddr = pndp->resp_ndi;
2489 else
2490 paddr = pndp->init_ndi;
2491
2492 if (os_memcmp(dst, paddr, ETH_ALEN))
2493 continue;
2494
2495 return peer;
2496 }
2497 }
2498
2499 return NULL;
2500 }
2501
2502
2503 /*
2504 * nan_tx_status - Notification of the result of a transmitted NAN Action frame
2505 * @nan: NAN module context from nan_init()
2506 * @dst: Destination address of the transmitted frame
2507 * @data: The transmitted frame
2508 * @data_len: Length of the transmitted frame in octets
2509 * @acked: Whether the frame was acknowledged
2510 * Returns: 0 if the frame is a NAF and -1 if not.
2511 */
nan_tx_status(struct nan_data * nan,const u8 * dst,const u8 * data,size_t data_len,bool acked)2512 int nan_tx_status(struct nan_data *nan, const u8 *dst, const u8 *data,
2513 size_t data_len, bool acked)
2514 {
2515 struct nan_peer *peer;
2516 const struct ieee80211_mgmt *mgmt = (const struct ieee80211_mgmt *)data;
2517 u8 subtype;
2518 int ret;
2519
2520 if (!nan_is_naf(mgmt, data_len) || !dst)
2521 return -1;
2522
2523 wpa_printf(MSG_DEBUG, "NAN: TX status: peer=" MACSTR ", acked=%u",
2524 MAC2STR(dst), acked);
2525
2526 peer = nan_tx_status_get_peer(nan, dst);
2527 if (!peer) {
2528 wpa_printf(MSG_DEBUG, "NAN: TX status: peer not found");
2529 return 0;
2530 }
2531
2532 subtype = mgmt->u.action.u.naf.subtype;
2533
2534 ret = nan_ndp_naf_sent(nan, peer, subtype);
2535 ret |= nan_ndl_naf_sent(nan, peer, subtype);
2536
2537 if (ret || peer->ndp_setup.status == NAN_NDP_STATUS_REJECTED ||
2538 !peer->ndl || peer->ndl->status == NAN_NDL_STATUS_REJECTED) {
2539 wpa_printf(MSG_DEBUG,
2540 "NAN: TX status: Stopping NDP establishment. ret=%d",
2541 ret);
2542
2543 if (peer->ndp_setup.ndp)
2544 nan_ndp_disconnected(nan, peer, peer->ndp_setup.reason,
2545 true);
2546 return 0;
2547 }
2548
2549 /* Both state machines are done */
2550 if (peer->ndp_setup.state == NAN_NDP_STATE_DONE &&
2551 peer->ndl->state == NAN_NDL_STATE_DONE) {
2552 wpa_printf(MSG_DEBUG, "NAN: TX status: NDP setup done");
2553
2554 if (nan_configure_peer_schedule(nan, peer, &nan->sched) ||
2555 nan_ndp_connected(nan, peer))
2556 nan_ndp_disconnected(nan, peer,
2557 NAN_REASON_UNSPECIFIED_REASON,
2558 true);
2559 }
2560
2561 return 0;
2562 }
2563
2564
nan_handle_ndp_setup(struct nan_data * nan,struct nan_ndp_params * params)2565 int nan_handle_ndp_setup(struct nan_data *nan, struct nan_ndp_params *params)
2566 {
2567 struct nan_peer *peer;
2568 enum nan_subtype naf_oui = NAN_SUBTYPE_INVALID;
2569 unsigned int timeout;
2570 int ret;
2571
2572 if (!nan_ndp_supported(nan))
2573 return -1;
2574
2575 peer = nan_get_peer(nan, params->ndp_id.peer_nmi);
2576 if (!peer) {
2577 wpa_printf(MSG_DEBUG, "NAN: NDP peer not found");
2578 return -1;
2579 }
2580
2581 /*
2582 * If the peer is paired, select the CSID based on the pairing
2583 * information (and ignore the CSID in the parameters, if any).
2584 * Otherwise, make sure that PASN CSIDs are not used.
2585 */
2586 if (peer->pairing.flags & NAN_PAIRING_FLAG_PAIRED) {
2587 params->sec.csid = peer->pairing.pairing_csid;
2588 wpa_printf(MSG_DEBUG,
2589 "NAN: Paired peer, selected CSID=%d from pairing",
2590 params->sec.csid);
2591 } else if (NAN_CS_IS_PASN(params->sec.csid)) {
2592 wpa_printf(MSG_DEBUG,
2593 "NAN: PASN CSID %d requires peer to be paired",
2594 params->sec.csid);
2595 return -1;
2596 }
2597
2598 switch (params->type) {
2599 case NAN_NDP_ACTION_REQ:
2600 params->ndp_id.id = nan_get_next_ndp_id(nan);
2601 ret = nan_ndp_setup_req(nan, peer, params);
2602 if (ret)
2603 return ret;
2604
2605 ret = nan_ndl_setup(nan, peer, params,
2606 peer->ndp_setup.dialog_token);
2607 if (ret) {
2608 nan_ndp_setup_stop(nan, peer);
2609 return ret;
2610 }
2611
2612 naf_oui = NAN_SUBTYPE_DATA_PATH_REQUEST;
2613 timeout = NAN_NDP_SETUP_TIMEOUT_LONG;
2614 ret = nan_configure_peer_schedule(nan, peer, &nan->sched);
2615 if (ret) {
2616 nan_ndp_setup_stop(nan, peer);
2617 return ret;
2618 }
2619 break;
2620 case NAN_NDP_ACTION_RESP:
2621 /*
2622 * NDL establishment as part of the NDP establishment. It is
2623 * possible that this would use an already existing NDL or start
2624 * a new NDL setup.
2625 */
2626 ret = nan_ndp_setup_resp(nan, peer, params);
2627 if (ret) {
2628 nan_ndp_setup_stop(nan, peer);
2629 return ret;
2630 }
2631
2632 if (peer->ndp_setup.status != NAN_NDP_STATUS_REJECTED) {
2633 ret = nan_ndl_setup(nan, peer, params,
2634 peer->ndp_setup.dialog_token);
2635 if (!ret) {
2636 ret = nan_configure_peer_schedule(nan, peer,
2637 &nan->sched);
2638 if (ret)
2639 peer->ndl->send_naf_on_error = 1;
2640 }
2641
2642 if (ret) {
2643 if (peer->ndl && peer->ndl->send_naf_on_error) {
2644 nan_ndp_setup_failure(
2645 nan, peer,
2646 NAN_REASON_NDL_UNACCEPTABLE, 0);
2647 } else {
2648 nan_ndp_setup_stop(nan, peer);
2649 return ret;
2650 }
2651 }
2652 } else if (peer->ndl && dl_list_empty(&peer->ndps)) {
2653 peer->ndl->status = NAN_NDL_STATUS_REJECTED;
2654 }
2655
2656 naf_oui = NAN_SUBTYPE_DATA_PATH_RESPONSE;
2657
2658 /*
2659 * In case of counter proposal, allow the peer more time to
2660 * process the counter request.
2661 */
2662 timeout = (peer->ndl &&
2663 peer->ndl->status == NAN_NDL_STATUS_CONTINUED) ?
2664 NAN_NDP_SETUP_TIMEOUT_LONG :
2665 NAN_NDP_SETUP_TIMEOUT_SHORT;
2666 break;
2667 case NAN_NDP_ACTION_CONF:
2668 ret = nan_ndl_setup(nan, peer, params,
2669 peer->ndp_setup.dialog_token);
2670 if (!ret) {
2671 ret = nan_configure_peer_schedule(nan, peer,
2672 &nan->sched);
2673 if (ret)
2674 peer->ndl->send_naf_on_error = 1;
2675 }
2676
2677 if (ret) {
2678 if (peer->ndl && peer->ndl->send_naf_on_error) {
2679 nan_ndp_setup_failure(
2680 nan, peer,
2681 NAN_REASON_NDL_UNACCEPTABLE, 0);
2682 } else {
2683 nan_ndp_setup_stop(nan, peer);
2684 return ret;
2685 }
2686 }
2687
2688 naf_oui = NAN_SUBTYPE_DATA_PATH_CONFIRM;
2689 timeout = NAN_NDP_SETUP_TIMEOUT_SHORT;
2690 break;
2691
2692 case NAN_NDP_ACTION_TERM:
2693 naf_oui = NAN_SUBTYPE_DATA_PATH_TERMINATION;
2694 timeout = NAN_NDP_SETUP_TIMEOUT_SHORT;
2695 ret = nan_ndp_term_req(nan, peer, ¶ms->ndp_id);
2696 if (ret)
2697 return ret;
2698 break;
2699 default:
2700 wpa_printf(MSG_DEBUG, "NAN: Unsupported NDP setup type=%u",
2701 params->type);
2702 return -1;
2703 }
2704
2705 ret = nan_action_send(nan, peer, naf_oui);
2706 if (ret) {
2707 wpa_printf(MSG_DEBUG,
2708 "NAN: Failed sending NAF. Resetting: ret=%d", ret);
2709 nan_ndp_disconnected(nan, peer, peer->ndp_setup.reason, true);
2710 return 0;
2711 }
2712
2713 nan_set_peer_timeout(nan, peer, timeout, 0);
2714 return ret;
2715 }
2716
2717
nan_ndp_terminated(struct nan_data * nan,struct nan_peer * peer,struct nan_ndp_id * ndp_id,const u8 * local_ndi,const u8 * peer_ndi,enum nan_reason reason,u8 gtk_id)2718 void nan_ndp_terminated(struct nan_data *nan, struct nan_peer *peer,
2719 struct nan_ndp_id *ndp_id, const u8 *local_ndi,
2720 const u8 *peer_ndi, enum nan_reason reason, u8 gtk_id)
2721 {
2722 /*
2723 * Remove the NDI station only if no other NDP is using the same
2724 * peer NDI address. The terminated NDP has already been removed
2725 * from peer->ndps before this function is called.
2726 */
2727 bool remove_sta = !nan_peer_ndi_in_use(peer, peer_ndi);
2728
2729 /* Remove sec entry if no other NDP is using this peer NDI */
2730 if (remove_sta)
2731 nan_peer_del_sec_entry(&peer->info, peer_ndi);
2732
2733 if (nan->cfg->ndp_disconnected)
2734 nan->cfg->ndp_disconnected(nan->cfg->cb_ctx, ndp_id, local_ndi,
2735 peer_ndi, reason, false, remove_sta,
2736 false, gtk_id);
2737
2738 /* Need to also remove the NDL if it is not needed */
2739 if (dl_list_empty(&peer->ndps) && !peer->ndp_setup.ndp)
2740 nan_ndl_reset(nan, peer);
2741 }
2742
2743
2744 struct nan_device_capabilities *
nan_peer_get_device_capabilities(struct nan_data * nan,const u8 * addr,u8 map_id)2745 nan_peer_get_device_capabilities(struct nan_data *nan, const u8 *addr,
2746 u8 map_id)
2747 {
2748 struct nan_dev_capa_entry *cur;
2749 struct nan_peer *peer;
2750
2751 peer = nan_get_peer(nan, addr);
2752 if (!peer)
2753 return NULL;
2754
2755 dl_list_for_each(cur, &peer->info.dev_capa, struct nan_dev_capa_entry,
2756 list) {
2757 if (cur->map_id == map_id)
2758 return &cur->capa;
2759 }
2760
2761 return NULL;
2762 }
2763
2764
nan_peer_get_tk(struct nan_data * nan,const u8 * addr,const u8 * peer_ndi,const u8 * local_ndi,u8 * tk,size_t * tk_len,enum nan_cipher_suite_id * csid)2765 int nan_peer_get_tk(struct nan_data *nan, const u8 *addr,
2766 const u8 *peer_ndi, const u8 *local_ndi,
2767 u8 *tk, size_t *tk_len, enum nan_cipher_suite_id *csid)
2768 {
2769 struct nan_peer *peer;
2770
2771 if (!nan || !tk || !tk_len || !csid)
2772 return -1;
2773
2774 peer = nan_get_peer(nan, addr);
2775 if (!peer)
2776 return -1;
2777
2778 return nan_sec_get_tk(nan, peer, peer_ndi, local_ndi, tk, tk_len, csid);
2779 }
2780
2781
nan_peer_get_pairing_cfg(struct nan_data * nan,const u8 * addr,const u8 ** nonce,const u8 ** tag)2782 const struct nan_pairing_cfg * nan_peer_get_pairing_cfg(struct nan_data *nan,
2783 const u8 *addr,
2784 const u8 **nonce,
2785 const u8 **tag)
2786 {
2787 struct nan_peer *peer;
2788
2789 if (!nan || !addr || !nonce || !tag)
2790 return NULL;
2791
2792 peer = nan_get_peer(nan, addr);
2793 if (!peer)
2794 return NULL;
2795
2796 /* Return nonce and tag pointers if valid, NULL otherwise */
2797 if (peer->pairing.nonce_tag_valid) {
2798 *nonce = peer->pairing.nonce;
2799 *tag = peer->pairing.tag;
2800 } else {
2801 *nonce = NULL;
2802 *tag = NULL;
2803 }
2804
2805 return &peer->pairing.pairing_cfg;
2806 }
2807
2808
2809 static bool
nan_peer_channel_in_local_sched(const struct nan_data * nan,int peer_ctrl_freq,const struct nan_schedule * local_sched)2810 nan_peer_channel_in_local_sched(const struct nan_data *nan,
2811 int peer_ctrl_freq,
2812 const struct nan_schedule *local_sched)
2813 {
2814 unsigned int i;
2815
2816 /* It's enough to compare the control freqs to ensure compatibility */
2817 for (i = 0; i < local_sched->n_chans; i++) {
2818 if (peer_ctrl_freq == local_sched->chans[i].chan.freq)
2819 return true;
2820 }
2821
2822 return false;
2823 }
2824
2825
2826 static void
nan_peer_get_committed_avail_add(const struct nan_data * nan,const struct nan_peer * peer,const struct nan_avail_entry * avail,const struct nan_schedule * local_sched,struct nan_peer_schedule * sched)2827 nan_peer_get_committed_avail_add(const struct nan_data *nan,
2828 const struct nan_peer *peer,
2829 const struct nan_avail_entry *avail,
2830 const struct nan_schedule *local_sched,
2831 struct nan_peer_schedule *sched)
2832 {
2833 struct nan_map *map;
2834 struct nan_map_chan *chan;
2835 struct nan_sched_chan schan;
2836 const struct oper_class_map *op;
2837 u8 chan_id;
2838 bool committed;
2839 int freq, bw, center_freq1, center_freq2, idx;
2840 u8 i;
2841 const struct nan_band_chan *band_chan;
2842 const struct nan_chan_entry *bc_chan;
2843
2844 if (avail->type != NAN_AVAIL_ENTRY_CTRL_TYPE_COMMITTED &&
2845 avail->type != NAN_AVAIL_ENTRY_CTRL_TYPE_COND)
2846 return;
2847
2848 /*
2849 * This should not happen in practice as committed and conditional
2850 * entries should have only a single channel entry.
2851 */
2852 if (avail->n_band_chan != 1) {
2853 wpa_printf(MSG_DEBUG,
2854 "NAN: Skip availability entry with n_band_chan=%u",
2855 avail->n_band_chan);
2856 return;
2857 }
2858
2859 band_chan = &avail->band_chan[0];
2860 bc_chan = &band_chan->u.chan;
2861
2862 /* Get all the channel parameters */
2863 op = get_oper_class(NULL, band_chan->u.chan.op_class);
2864 if (!op) {
2865 wpa_printf(MSG_DEBUG, "NAN: Unknown operating class %u",
2866 band_chan->u.chan.op_class);
2867 return;
2868 }
2869
2870 idx = ffs(le_to_host16(bc_chan->chan_bitmap)) - 1;
2871 if (idx < 0) {
2872 wpa_printf(MSG_DEBUG,
2873 "NAN: No channel found in chan_bitmap 0x%04x for oper_class %u",
2874 le_to_host16(bc_chan->chan_bitmap),
2875 bc_chan->op_class);
2876 return;
2877 }
2878
2879 chan_id = op_class_idx_to_chan(op, idx);
2880 if (!chan_id) {
2881 wpa_printf(MSG_DEBUG,
2882 "NAN: No channel found for oper_class %u idx %u",
2883 bc_chan->op_class, idx);
2884 return;
2885 }
2886
2887 freq = ieee80211_chan_to_freq(NULL, bc_chan->op_class, chan_id);
2888 bw = oper_class_bw_to_int(op);
2889
2890 center_freq2 = 0;
2891 if (op->op_class < 128) {
2892 center_freq1 = ieee80211_get_center_freq(freq, op->bw);
2893 } else if (op->op_class > 130) {
2894 wpa_printf(MSG_DEBUG, "NAN: Missing support for op_class %u",
2895 op->op_class);
2896 return;
2897 } else {
2898 idx = ffs(bc_chan->pri_chan_bitmap) - 1;
2899 if (idx < 0) {
2900 wpa_printf(MSG_DEBUG,
2901 "NAN: No primary channel found in pri_chan_bitmap 0x%04x",
2902 le_to_host16(bc_chan->pri_chan_bitmap));
2903 return;
2904 }
2905
2906 center_freq1 = freq;
2907 if (op->bw == BW80 || op->bw == BW80P80)
2908 freq = freq - 30 + idx * 20;
2909 else if (op->bw == BW160)
2910 freq = freq - 70 + idx * 20;
2911
2912 /* TODO: Missing support for 80 + 80 */
2913 }
2914
2915 /* Skip channels that are not in local schedule */
2916 if (local_sched &&
2917 !nan_peer_channel_in_local_sched(nan, freq, local_sched))
2918 return;
2919
2920 /* Assume committed for conditional slots if setup is done */
2921 committed = (avail->type == NAN_AVAIL_ENTRY_CTRL_TYPE_COMMITTED) ||
2922 (avail->type == NAN_AVAIL_ENTRY_CTRL_TYPE_COND &&
2923 peer->ndl->state == NAN_NDL_STATE_DONE &&
2924 peer->ndl->status == NAN_NDL_STATUS_ACCEPTED);
2925
2926 /* Find map ID entry if already exists */
2927 for (i = 0; i < sched->n_maps; i++)
2928 if (sched->maps[i].map_id == avail->map_id)
2929 break;
2930
2931 map = &sched->maps[i];
2932 if (i == sched->n_maps) {
2933 if (sched->n_maps == NAN_MAX_MAPS) {
2934 wpa_printf(MSG_DEBUG,
2935 "NAN: Too many map entries in schedule");
2936 return;
2937 }
2938 sched->n_maps++;
2939 }
2940
2941 map->map_id = avail->map_id;
2942
2943 os_memset(&schan, 0, sizeof(schan));
2944
2945 /* Find channel entry if already exists */
2946 for (i = 0; i < map->n_chans; i++) {
2947 if (map->chans[i].committed != committed)
2948 return;
2949
2950 if (map->chans[i].chan.freq == freq &&
2951 map->chans[i].chan.bandwidth == bw &&
2952 map->chans[i].chan.center_freq1 == center_freq1 &&
2953 map->chans[i].chan.center_freq2 == center_freq2)
2954 break;
2955 }
2956
2957 chan = &map->chans[i];
2958 if (i == map->n_chans) {
2959 if (map->n_chans == NAN_MAX_CHAN_ENTRIES) {
2960 wpa_printf(MSG_DEBUG,
2961 "NAN: Too many channel entries in schedule map_id=%u",
2962 map->map_id);
2963 return;
2964 }
2965 map->n_chans++;
2966 }
2967
2968 chan->committed = committed;
2969 chan->rx_nss = avail->rx_nss;
2970 chan->chan.freq = freq;
2971 chan->chan.bandwidth = bw;
2972 chan->chan.center_freq1 = center_freq1;
2973 chan->chan.center_freq2 = center_freq2;
2974
2975 os_memcpy(&chan->tbm, &avail->tbm, sizeof(avail->tbm));
2976 }
2977
2978
2979 static void
nan_peer_get_committed_avail(const struct nan_data * nan,const struct nan_peer * peer,const struct nan_schedule * local_sched,struct nan_peer_schedule * sched)2980 nan_peer_get_committed_avail(const struct nan_data *nan,
2981 const struct nan_peer *peer,
2982 const struct nan_schedule *local_sched,
2983 struct nan_peer_schedule *sched)
2984 {
2985 const struct nan_avail_entry *avail;
2986
2987 dl_list_for_each(avail, &peer->info.avail_entries,
2988 struct nan_avail_entry, list)
2989 nan_peer_get_committed_avail_add(nan, peer, avail,
2990 local_sched, sched);
2991 }
2992
2993
nan_peer_set_sched(struct nan_data * nan,struct nan_peer * peer,struct nan_peer_schedule * sched,const u8 * sched_buf,size_t sched_buf_len,bool ndc)2994 static void nan_peer_set_sched(struct nan_data *nan, struct nan_peer *peer,
2995 struct nan_peer_schedule *sched,
2996 const u8 *sched_buf, size_t sched_buf_len,
2997 bool ndc)
2998 {
2999 struct dl_list sched_entries;
3000 struct nan_avail_entry *cur;
3001 int ret;
3002
3003 if (!sched->n_maps)
3004 return;
3005
3006 if (!sched_buf || !sched_buf_len)
3007 return;
3008
3009 if (sched_buf_len < sizeof(struct nan_sched_entry)) {
3010 wpa_printf(MSG_DEBUG, "NAN: Schedule buffer too short=%zu",
3011 sched_buf_len);
3012 return;
3013 }
3014
3015 /* Convert the schedule the availability entries */
3016 ret = nan_sched_entries_to_avail_entries(nan, &sched_entries,
3017 sched_buf, sched_buf_len);
3018 if (ret) {
3019 wpa_printf(MSG_DEBUG,
3020 "NAN: Failed to parse peer schedule entries");
3021 return;
3022 }
3023
3024 /*
3025 * For each schedule entry find the corresponding map in the committed
3026 * schedule and store the copy of the time bitmap.
3027 */
3028 dl_list_for_each(cur, &sched_entries, struct nan_avail_entry, list) {
3029 struct nan_map *map;
3030 unsigned int i;
3031
3032 for (i = 0; i < sched->n_maps; i++) {
3033 map = &sched->maps[i];
3034
3035 if (map->map_id == cur->map_id)
3036 break;
3037 }
3038
3039 if (i == sched->n_maps) {
3040 wpa_printf(MSG_DEBUG,
3041 "NAN: No map entry found for map_id=%u in peer schedule",
3042 cur->map_id);
3043 continue;
3044 }
3045
3046 if (ndc)
3047 os_memcpy(&map->ndc, &cur->tbm, sizeof(cur->tbm));
3048 else
3049 os_memcpy(&map->immutable, &cur->tbm, sizeof(cur->tbm));
3050 }
3051
3052 nan_flush_avail_entries(&sched_entries);
3053 }
3054
3055
nan_peer_get_ndc_sched(struct nan_data * nan,struct nan_peer * peer,struct nan_peer_schedule * sched)3056 static void nan_peer_get_ndc_sched(struct nan_data *nan,
3057 struct nan_peer *peer,
3058 struct nan_peer_schedule *sched)
3059 {
3060 if (!peer->ndl)
3061 return;
3062
3063 nan_peer_set_sched(nan, peer, sched,
3064 peer->ndl->ndc_sched,
3065 peer->ndl->ndc_sched_len, true);
3066 }
3067
3068
nan_peer_get_immut_sched(struct nan_data * nan,struct nan_peer * peer,struct nan_peer_schedule * sched)3069 static void nan_peer_get_immut_sched(struct nan_data *nan,
3070 struct nan_peer *peer,
3071 struct nan_peer_schedule *sched)
3072 {
3073 if (!peer->ndl)
3074 return;
3075
3076 nan_peer_set_sched(nan, peer, sched,
3077 peer->ndl->immut_sched,
3078 peer->ndl->immut_sched_len, false);
3079 }
3080
3081
3082
3083 /*
3084 * nan_peer_get_schedule_info - Get peer's schedule information
3085 * @nan: NAN module context from nan_init()
3086 * @addr: NAN MAC address of the peer
3087 * @sched: on return would hold the schedule information.
3088 * Returns: 0 on success; -1 otherwise.
3089 */
nan_peer_get_schedule_info(struct nan_data * nan,const u8 * addr,struct nan_peer_schedule * sched)3090 int nan_peer_get_schedule_info(struct nan_data *nan, const u8 *addr,
3091 struct nan_peer_schedule *sched)
3092 {
3093 struct nan_peer *peer;
3094
3095 if (!nan || !sched)
3096 return -1;
3097
3098 os_memset(sched, 0, sizeof(*sched));
3099
3100 peer = nan_get_peer(nan, addr);
3101 if (!peer)
3102 return -1;
3103
3104 nan_peer_get_committed_avail(nan, peer, NULL, sched);
3105 nan_peer_get_ndc_sched(nan, peer, sched);
3106 nan_peer_get_immut_sched(nan, peer, sched);
3107
3108 if (peer->ndl)
3109 sched->max_idle_period = peer->ndl->max_idle_period;
3110
3111 return 0;
3112 }
3113
3114
3115 /*
3116 * nan_peer_get_pot_avail - Get peer's potential availability entries
3117 * @nan: NAN module context from nan_init()
3118 * @addr: NAN MAC address of the peer
3119 * @pot_avail: On return, holds the potential availability entries.
3120 * Returns 0 on success, -1 on failure
3121 */
nan_peer_get_pot_avail(struct nan_data * nan,const u8 * addr,struct nan_peer_potential_avail * pot_avail)3122 int nan_peer_get_pot_avail(struct nan_data *nan, const u8 *addr,
3123 struct nan_peer_potential_avail *pot_avail)
3124 {
3125 struct nan_avail_entry *avail;
3126 struct nan_peer *peer;
3127 u8 i;
3128
3129 if (!nan || !pot_avail)
3130 return -1;
3131
3132 os_memset(pot_avail, 0, sizeof(*pot_avail));
3133
3134 peer = nan_get_peer(nan, addr);
3135 if (!peer)
3136 return -1;
3137
3138 dl_list_for_each(avail, &peer->info.avail_entries,
3139 struct nan_avail_entry, list) {
3140 struct pot_entry *pot;
3141
3142 if (avail->type != NAN_AVAIL_ENTRY_CTRL_TYPE_POTENTIAL)
3143 continue;
3144
3145 if (pot_avail->n_maps == NAN_MAX_MAPS) {
3146 wpa_printf(MSG_DEBUG,
3147 "NAN: Too many potential maps stored");
3148 break;
3149 }
3150
3151 pot = &pot_avail->maps[pot_avail->n_maps++];
3152 pot->rx_nss = avail->rx_nss;
3153 pot->preference = avail->preference;
3154 pot->utilization = avail->utilization;
3155 pot->is_band = avail->band_chan_type == NAN_TYPE_BAND;
3156
3157 for (i = 0; i < avail->n_band_chan; i++, pot->n_band_chan++) {
3158 const struct nan_band_chan *band_chan;
3159
3160 if (pot->n_band_chan == NAN_MAX_CHAN_ENTRIES) {
3161 wpa_printf(MSG_DEBUG,
3162 "NAN: Too many band_chan entries stored for potential entry");
3163 break;
3164 }
3165
3166 band_chan = &avail->band_chan[i];
3167
3168 if (pot->is_band) {
3169 pot->entries[i].band_id =
3170 band_chan->u.band_id;
3171 } else {
3172 const struct nan_chan_entry *bc_chan;
3173
3174 bc_chan = &band_chan->u.chan;
3175 pot->entries[i].op_class = bc_chan->op_class;
3176 pot->entries[i].chan_bitmap =
3177 le_to_host16(bc_chan->chan_bitmap);
3178 }
3179 }
3180 }
3181
3182 return 0;
3183 }
3184
3185
3186 /**
3187 * nan_convert_sched_to_avail_attrs - Convert NAN schedule to availability attrs
3188 * @nan: NAN module context from nan_init()
3189 * @map_ids_bitmap: Bitmap of map IDs for which NAN availability attributes
3190 * should be added. Not all map IDs are covered by &chans. For map IDs that
3191 * are not covered, NAN availability attributes will be added with
3192 * potential availability entries.
3193 * @sequence_id: Sequence ID for the availability attributes
3194 * @n_chans: Number of channel entries in chans
3195 * @chans: Channel entries
3196 * @buf: Buffer to which the availability attributes will be added
3197 * @include_potential: Whether to include potential availability entries
3198 * Returns: 0 on success; -1 on failure
3199 *
3200 * Convert the given NAN schedule information to availability attributes and add
3201 * them to the given buffer. For each given map ID the get_chans() callback will
3202 * be used to get the channel entries for the potential availability entries.
3203 */
nan_convert_sched_to_avail_attrs(struct nan_data * nan,u8 sequence_id,u32 map_ids_bitmap,size_t n_chans,struct nan_chan_schedule * chans,struct wpabuf * buf,bool include_potential)3204 int nan_convert_sched_to_avail_attrs(struct nan_data *nan, u8 sequence_id,
3205 u32 map_ids_bitmap,
3206 size_t n_chans,
3207 struct nan_chan_schedule *chans,
3208 struct wpabuf *buf,
3209 bool include_potential)
3210 {
3211 return nan_add_avail_attrs(nan, sequence_id, map_ids_bitmap,
3212 NAN_AVAIL_ENTRY_CTRL_TYPE_COND,
3213 n_chans, chans, buf, include_potential);
3214 }
3215
3216
nan_peer_pairing_supported(struct nan_data * nan,const u8 * addr)3217 bool nan_peer_pairing_supported(struct nan_data *nan, const u8 *addr)
3218 {
3219 struct nan_peer *peer;
3220
3221 peer = nan_get_peer(nan, addr);
3222 if (!peer)
3223 return false;
3224
3225 return peer->pairing.pairing_cfg.pairing_setup;
3226 }
3227
3228
nan_peer_npk_nik_caching_supported(struct nan_data * nan,const u8 * addr)3229 bool nan_peer_npk_nik_caching_supported(struct nan_data *nan, const u8 *addr)
3230 {
3231 struct nan_peer *peer;
3232
3233 peer = nan_get_peer(nan, addr);
3234 if (!peer)
3235 return false;
3236
3237 return peer->pairing.pairing_cfg.npk_caching;
3238 }
3239
3240
3241 /**
3242 * nan_peer_del_all_ndps - Delete all NDPs with a given peer
3243 * @nan: NAN module context from nan_init()
3244 * @addr: NAN MAC address of the peer
3245 * Returns: 0 on success, -1 on failure
3246 *
3247 * This function deletes all NDPs with the given peer and stops any ongoing
3248 * NDP setup. It also resets the NDL state machine and flushes any security
3249 * context with the peer. The function doesn't delete the peer itself and
3250 * doesn't send any NAFs to the peer notifying about the deletions.
3251 */
nan_peer_del_all_ndps(struct nan_data * nan,const u8 * addr)3252 int nan_peer_del_all_ndps(struct nan_data *nan, const u8 *addr)
3253 {
3254 struct nan_peer *peer;
3255 struct nan_ndp *ndp, *tndp;
3256
3257 if (!nan)
3258 return -1;
3259
3260 peer = nan_get_peer(nan, addr);
3261 if (!peer)
3262 return -1;
3263
3264 wpa_printf(MSG_DEBUG, "NAN: Deleting all NDPs with peer " MACSTR,
3265 MAC2STR(addr));
3266
3267 if (peer->ndp_setup.ndp)
3268 nan_ndp_setup_stop(nan, peer);
3269
3270 dl_list_for_each_safe(ndp, tndp, &peer->ndps, struct nan_ndp, list) {
3271 dl_list_del(&ndp->list);
3272 peer->ndp_setup.ndp = ndp;
3273 nan_ndp_disconnected(nan, peer, NAN_REASON_UNSPECIFIED_REASON,
3274 true);
3275 }
3276
3277 nan_ndl_reset(nan, peer);
3278 nan_peer_flush_sec(&peer->info);
3279
3280 return 0;
3281 }
3282
3283
3284 /**
3285 * nan_get_peer_elems - Get element container data for a peer
3286 * @nan: NAN module context from nan_init()
3287 * @addr: NAN MAC address of the peer
3288 * @elems: On return, pointer to the element container data
3289 * Returns: Length of the element data on success; -1 on failure
3290 *
3291 * Retrieve the element container data associated with a peer. The function
3292 * first looks for an entry with map_id 0. If not found and the peer has an
3293 * active NDL, it returns the elements corresponding to the NDC channel's
3294 * map_id. If no NDC map_id entry is found, it returns the first entry found.
3295 */
nan_get_peer_elems(struct nan_data * nan,const u8 * addr,u8 ** elems)3296 int nan_get_peer_elems(struct nan_data *nan, const u8 *addr, u8 **elems)
3297 {
3298 struct nan_elem_container_entry *entry;
3299 struct nan_peer *peer;
3300 u8 ndc_map_id = 0;
3301 bool ndc_map_id_found = false;
3302
3303 peer = nan_get_peer(nan, addr);
3304 if (!peer)
3305 return -1;
3306
3307 if (peer->ndl) {
3308 const struct nan_sched_entry *peer_ndc =
3309 (const struct nan_sched_entry *) peer->ndl->ndc_sched;
3310
3311 if (peer_ndc &&
3312 peer->ndl->ndc_sched_len >= sizeof(*peer_ndc))
3313 ndc_map_id = peer_ndc->map_id;
3314 }
3315
3316 /* Prefer map_id == 0, so it applies for all */
3317 dl_list_for_each(entry, &peer->info.element_container,
3318 struct nan_elem_container_entry, list) {
3319 if (entry->map_id == 0) {
3320 *elems = entry->data;
3321 return entry->len;
3322 }
3323
3324 if (ndc_map_id && entry->map_id == ndc_map_id)
3325 ndc_map_id_found = true;
3326 }
3327
3328 /*
3329 * TODO: Properly support different elements per map_id. For now, take
3330 * the elements that correspond to the NDC* channel if available.
3331 * Currently upper layers don't support configuring different
3332 * elements per map_id. Until that is changed, take the map_id
3333 * corresponding to the NDC channel as it at least must intersect with
3334 * the local schedule. If no such entry exists, return the first entry
3335 * found.
3336 */
3337 dl_list_for_each(entry, &peer->info.element_container,
3338 struct nan_elem_container_entry, list) {
3339 if (!ndc_map_id_found || entry->map_id == ndc_map_id) {
3340 *elems = entry->data;
3341 return entry->len;
3342 }
3343 }
3344
3345 return -1;
3346 }
3347
3348
3349 /**
3350 * nan_set_bootstrap_configuration - Set NAN bootstrap configuration
3351 * @nan: NAN module context from nan_init()
3352 * @supported_bootstrap_methods: Bitmap of supported bootstrap methods
3353 * @auto_accept_bootstrap_methods: Bitmap of bootstrap methods to auto-accept
3354 * @bootstrap_comeback_timeout: Timeout in TUs for bootstrap comeback
3355 * Returns: 0 on success, -1 on failure.
3356 */
nan_set_bootstrap_configuration(struct nan_data * nan,u16 supported_bootstrap_methods,u16 auto_accept_bootstrap_methods,u16 bootstrap_comeback_timeout)3357 int nan_set_bootstrap_configuration(struct nan_data *nan,
3358 u16 supported_bootstrap_methods,
3359 u16 auto_accept_bootstrap_methods,
3360 u16 bootstrap_comeback_timeout)
3361 {
3362 if (!nan)
3363 return -1;
3364
3365 nan->cfg->supported_bootstrap_methods = supported_bootstrap_methods;
3366 nan->cfg->auto_accept_bootstrap_methods =
3367 auto_accept_bootstrap_methods;
3368 nan->cfg->bootstrap_comeback_timeout = bootstrap_comeback_timeout;
3369
3370 return 0;
3371 }
3372
3373
3374 /**
3375 * nan_is_ndpe_supported - Check if NDPE attribute is supported with peer
3376 * @nan: NAN module context from nan_init()
3377 * @peer: NAN peer
3378 * Returns: true if the peer supports NDPE attribute; false otherwise.
3379 */
nan_is_ndpe_supported(struct nan_data * nan,const struct nan_peer * peer)3380 bool nan_is_ndpe_supported(struct nan_data *nan, const struct nan_peer *peer)
3381 {
3382 struct nan_dev_capa_entry *cur;
3383
3384 if (!nan || !peer)
3385 return false;
3386
3387 dl_list_for_each(cur, &peer->info.dev_capa,
3388 struct nan_dev_capa_entry, list) {
3389 /*
3390 * Take the first one, as NDPE support should be identical
3391 * across all attributes.
3392 */
3393 return !!(cur->capa.capa & NAN_DEV_CAPA_NDPE_ATTR_SUPP);
3394 }
3395
3396 return false;
3397 }
3398
3399
3400 /**
3401 * nan_set_mgmt_group_cipher - Set NAN management group cipher
3402 * @nan: Pointer to NAN data structure
3403 * @cipher: Cipher suite to be set (WPA_CIPHER_AES_128_CMAC or
3404 * WPA_CIPHER_BIP_GMAC_256)
3405 * Returns: 0 on success, -1 on failure
3406 *
3407 * This function sets the management group cipher for NAN communication.
3408 * The cipher can only be changed when NAN is not started.
3409 */
nan_set_mgmt_group_cipher(struct nan_data * nan,int cipher)3410 int nan_set_mgmt_group_cipher(struct nan_data *nan, int cipher)
3411 {
3412 if (!nan)
3413 return -1;
3414
3415 if (nan->nan_started) {
3416 wpa_printf(MSG_DEBUG,
3417 "NAN: Cannot set NAN management group cipher while NAN is started");
3418 return -1;
3419 }
3420
3421 if (cipher != WPA_CIPHER_AES_128_CMAC &&
3422 cipher != WPA_CIPHER_BIP_GMAC_256) {
3423 wpa_printf(MSG_DEBUG,
3424 "NAN: Unsupported NAN management group cipher %d",
3425 cipher);
3426 return -1;
3427 }
3428
3429 if (cipher == WPA_CIPHER_BIP_GMAC_256)
3430 nan->cfg->security_capab |=
3431 NAN_CS_INFO_CAPA_IGTK_USE_NCS_BIP_GMAC_256;
3432 else
3433 nan->cfg->security_capab &=
3434 ~NAN_CS_INFO_CAPA_IGTK_USE_NCS_BIP_GMAC_256;
3435 return 0;
3436 }
3437
3438
3439 /**
3440 * nan_set_beacon_prot - Enable or disable NAN beacon protection
3441 * @nan: Pointer to NAN data structure
3442 * @enable: true to enable beacon protection, false to disable
3443 * Returns: 0 on success, -1 on failure
3444 *
3445 * This function enables or disables NAN beacon protection. Beacon protection
3446 * can only be changed when NAN is not started. Additionally, the device must
3447 * support management frame protection for beacon protection to be enabled.
3448 */
nan_set_beacon_prot(struct nan_data * nan,bool enable)3449 int nan_set_beacon_prot(struct nan_data *nan, bool enable)
3450 {
3451 u8 gtk_supp;
3452
3453 if (!nan)
3454 return -1;
3455
3456 if (nan->nan_started) {
3457 wpa_printf(MSG_DEBUG,
3458 "NAN: Cannot change beacon protection setting while NAN is started");
3459 return -1;
3460 }
3461
3462 if (((nan->cfg->security_capab & NAN_CS_INFO_CAPA_GTK_SUPP_MASK) >>
3463 NAN_CS_INFO_CAPA_GTK_SUPP_POS) == NAN_CS_INFO_CAPA_GTK_SUPP_NONE) {
3464 if (enable) {
3465 wpa_printf(MSG_DEBUG,
3466 "NAN: Management frame protection is not supported by the device");
3467 return -1;
3468 }
3469 return 0;
3470 }
3471
3472 if (enable)
3473 gtk_supp = NAN_CS_INFO_CAPA_GTK_SUPP_ALL;
3474 else
3475 gtk_supp = NAN_CS_INFO_CAPA_GTK_SUPP_NO_BIGTK;
3476
3477 nan->cfg->security_capab &= ~NAN_CS_INFO_CAPA_GTK_SUPP_MASK;
3478 nan->cfg->security_capab |= gtk_supp << NAN_CS_INFO_CAPA_GTK_SUPP_POS;
3479 return 0;
3480 }
3481
3482
3483 /**
3484 * nan_set_max_ndl_idle_period - Set maximum NDL idle period
3485 * @nan: Pointer to NAN data structure
3486 * @max_idle_period: Maximum idle period in seconds
3487 * Returns: 0 on success, -1 on failure
3488 */
nan_set_max_ndl_idle_period(struct nan_data * nan,u16 max_idle_period)3489 int nan_set_max_ndl_idle_period(struct nan_data *nan, u16 max_idle_period)
3490 {
3491 if (!nan)
3492 return -1;
3493
3494 if (!nan->cfg->get_peer_inactivity) {
3495 wpa_printf(MSG_DEBUG,
3496 "NAN: Cannot set max NDL idle period as get_peer_inactivity callback is not set");
3497 return -1;
3498 }
3499
3500 wpa_printf(MSG_DEBUG,
3501 "NAN: Setting max NDL idle period to %u (prev=%u) seconds",
3502 max_idle_period, nan->cfg->max_ndl_idle_period);
3503
3504 nan->cfg->max_ndl_idle_period = max_idle_period;
3505
3506 if (!nan->nan_started)
3507 return 0;
3508
3509 /*
3510 * Handle the current timeout. If a positive idle period is set
3511 * configure the timeout logic to run in 1 second (as calling it
3512 * immediately could cause NDP termination in the same context, and
3513 * the caller might be able to handle it).
3514 */
3515 eloop_cancel_timeout(nan_idle_period_timeout, nan, NULL);
3516 if (max_idle_period)
3517 eloop_register_timeout(1, 0, nan_idle_period_timeout,
3518 nan, NULL);
3519 return 0;
3520 }
3521
3522
nan_has_active_ndp(struct nan_data * nan)3523 bool nan_has_active_ndp(struct nan_data *nan)
3524 {
3525 struct nan_peer *peer;
3526
3527 if (!nan)
3528 return false;
3529
3530 dl_list_for_each(peer, &nan->peer_list, struct nan_peer, list) {
3531 if (!dl_list_empty(&peer->ndps))
3532 return true;
3533 }
3534
3535 return false;
3536 }
3537
3538
nan_set_sched_update_pending(struct nan_data * nan,bool pending)3539 void nan_set_sched_update_pending(struct nan_data *nan, bool pending)
3540 {
3541 if (!nan)
3542 return;
3543
3544 wpa_printf(MSG_DEBUG, "NAN: Set sched_update_pending to %d", pending);
3545 nan->sched_update_pending = pending;
3546 }
3547
3548
nan_local_sched_update(struct nan_data * nan,struct nan_schedule * sched)3549 void nan_local_sched_update(struct nan_data *nan, struct nan_schedule *sched)
3550 {
3551 struct nan_peer *peer;
3552
3553 if (!nan || !sched)
3554 return;
3555
3556 wpabuf_free(nan->sched.elems);
3557 os_memcpy(&nan->sched, sched, sizeof(nan->sched));
3558
3559 dl_list_for_each(peer, &nan->peer_list, struct nan_peer, list) {
3560 wpa_printf(MSG_DEBUG, "NAN: Updating schedule for peer " MACSTR,
3561 MAC2STR(peer->nmi_addr));
3562
3563 if (peer->ndl && peer->ndl->state == NAN_NDL_STATE_DONE)
3564 nan_peer_update_schedule(nan, peer, sched);
3565 }
3566 }
3567
3568
nan_get_status(struct nan_data * nan,char * buf,size_t buflen)3569 int nan_get_status(struct nan_data *nan, char *buf, size_t buflen)
3570 {
3571 char *pos, *end;
3572 struct nan_peer *peer;
3573 int ret;
3574
3575 if (!nan)
3576 return -1;
3577
3578 pos = buf;
3579 end = buf + buflen;
3580
3581 ret = os_snprintf(pos, end - pos,
3582 "nan_started=%d\n"
3583 "nmi=" MACSTR "\n"
3584 "cluster_id=" MACSTR "\n",
3585 nan->nan_started, MAC2STR(nan->cfg->nmi_addr),
3586 MAC2STR(nan->cluster_id));
3587 if (os_snprintf_error(end - pos, ret))
3588 return pos - buf;
3589 pos += ret;
3590
3591 dl_list_for_each(peer, &nan->peer_list, struct nan_peer, list) {
3592 struct nan_ndp *ndp;
3593 unsigned int ndp_count = 0;
3594
3595 dl_list_for_each(ndp, &peer->ndps, struct nan_ndp, list)
3596 ndp_count++;
3597
3598 ret = os_snprintf(pos, end - pos,
3599 "peer=" MACSTR " paired=%d ndp_count=%u\n",
3600 MAC2STR(peer->nmi_addr),
3601 !!(peer->pairing.flags &
3602 NAN_PAIRING_FLAG_PAIRED),
3603 ndp_count);
3604 if (os_snprintf_error(end - pos, ret))
3605 return pos - buf;
3606 pos += ret;
3607 }
3608
3609 return pos - buf;
3610 }
3611
3612
nan_peer_dump_ndps_to_buf(struct nan_data * nan,const u8 * addr,char * buf,size_t buflen)3613 int nan_peer_dump_ndps_to_buf(struct nan_data *nan, const u8 *addr,
3614 char *buf, size_t buflen)
3615 {
3616 struct nan_peer *peer;
3617 struct nan_ndp *ndp;
3618 char *pos, *end;
3619
3620 if (!nan)
3621 return -1;
3622
3623 peer = nan_get_peer(nan, addr);
3624 if (!peer) {
3625 wpa_printf(MSG_DEBUG, "NAN: Peer " MACSTR " not found",
3626 MAC2STR(addr));
3627 return -1;
3628 }
3629
3630 pos = buf;
3631 end = buf + buflen;
3632
3633 dl_list_for_each(ndp, &peer->ndps, struct nan_ndp, list) {
3634 int ret;
3635
3636 ret = os_snprintf(pos, end - pos,
3637 "ndp_id=%u initiator=%d "
3638 "init_ndi=" MACSTR " resp_ndi=" MACSTR
3639 " qos_min_slots=%u qos_max_latency=%u\n",
3640 ndp->ndp_id, ndp->initiator,
3641 MAC2STR(ndp->init_ndi),
3642 MAC2STR(ndp->resp_ndi),
3643 ndp->qos.min_slots, ndp->qos.max_latency);
3644 if (os_snprintf_error(end - pos, ret))
3645 return pos - buf;
3646 pos += ret;
3647 }
3648
3649 return pos - buf;
3650 }
3651
3652
3653 /**
3654 * nan_terminate_ndi_ndps - Terminate all NDPs with a given NDI address
3655 * @nan: NAN module context from nan_init()
3656 * @ndi_addr: NDI address for which all NDPs should be terminated
3657 *
3658 * This function terminates all NDPs that have the given NDI address as either
3659 * initiator or responder NDI.
3660 */
nan_terminate_ndi_ndps(struct nan_data * nan,const u8 * ndi_addr)3661 void nan_terminate_ndi_ndps(struct nan_data *nan, const u8 *ndi_addr)
3662 {
3663 struct nan_peer *peer;
3664
3665 if (!nan)
3666 return;
3667
3668 dl_list_for_each(peer, &nan->peer_list, struct nan_peer, list) {
3669 /*
3670 * It is possible that an NDP setup in progress is not on the
3671 * NDI that is being removed. However, to simplify things, stop
3672 * the setup, so the other NDPs could be cleanly removed.
3673 */
3674 nan_ndp_setup_stop(nan, peer);
3675 nan_terminate_ndps_for_ndi(nan, peer, ndi_addr);
3676 }
3677 }
3678