xref: /freebsd/contrib/wpa/src/nan/nan.c (revision 71e72c9e91c4b8007a4292e09669e8b549c29e97)
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(&notify, 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, &notify);
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(&params, 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, &params);
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, &params->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