xref: /freebsd/contrib/wpa/src/nan/nan_ndp.c (revision 71e72c9e91c4b8007a4292e09669e8b549c29e97)
1 /*
2  * Wi-Fi Aware - NAN Data Path
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 "nan_i.h"
12 
13 
nan_ndp_state_str(enum nan_ndp_state state)14 static const char * nan_ndp_state_str(enum nan_ndp_state state)
15 {
16 #define C2S(x) case x: return #x;
17 	switch (state) {
18 	C2S(NAN_NDP_STATE_NONE)
19 	C2S(NAN_NDP_STATE_START)
20 	C2S(NAN_NDP_STATE_REQ_SENT)
21 	C2S(NAN_NDP_STATE_REQ_RECV)
22 	C2S(NAN_NDP_STATE_RES_SENT)
23 	C2S(NAN_NDP_STATE_RES_RECV)
24 	C2S(NAN_NDP_STATE_CON_SENT)
25 	C2S(NAN_NDP_STATE_CON_RECV)
26 	C2S(NAN_NDP_STATE_DONE)
27 	default:
28 		return "Invalid NAN NDP state";
29 	}
30 }
31 
32 
nan_ndp_set_state(struct nan_data * nan,struct nan_ndp_setup * ndp_setup,enum nan_ndp_state state)33 static void nan_ndp_set_state(struct nan_data *nan,
34 			      struct nan_ndp_setup *ndp_setup,
35 			      enum nan_ndp_state state)
36 {
37 	wpa_printf(MSG_DEBUG,
38 		   "NAN: NDP: state: %s (%u) --> %s (%u)",
39 		   nan_ndp_state_str(ndp_setup->state),
40 		   ndp_setup->state, nan_ndp_state_str(state),
41 		   state);
42 
43 	ndp_setup->state = state;
44 }
45 
46 
47 static struct nan_ndp *
nan_ndp_alloc(struct nan_data * nan,struct nan_peer * peer,u8 initiator,u8 * init_ndi,u8 ndp_id,u8 min_slots,u16 max_latency)48 nan_ndp_alloc(struct nan_data *nan, struct nan_peer *peer,
49 	      u8 initiator, u8 *init_ndi, u8 ndp_id, u8 min_slots,
50 	      u16 max_latency)
51 {
52 	struct nan_ndp *ndp = os_zalloc(sizeof(*ndp));
53 
54 	if (!ndp)
55 		return NULL;
56 
57 	ndp->peer = peer;
58 	ndp->initiator = initiator;
59 	ndp->ndp_id = ndp_id;
60 
61 	os_memcpy(ndp->init_ndi, init_ndi, sizeof(ndp->init_ndi));
62 
63 	ndp->qos.min_slots = min_slots;
64 	ndp->qos.max_latency = max_latency;
65 
66 	return ndp;
67 }
68 
69 
nan_ndp_ssi(struct nan_data * nan,struct nan_ndp_setup * ndp_setup,const u8 * ssi,u16 ssi_len)70 static int nan_ndp_ssi(struct nan_data *nan, struct nan_ndp_setup *ndp_setup,
71 		       const u8 *ssi, u16 ssi_len)
72 {
73 	os_free(ndp_setup->ssi);
74 	ndp_setup->ssi = NULL;
75 	ndp_setup->ssi_len = 0;
76 
77 	if (!ssi || !ssi_len)
78 		return 0;
79 
80 	ndp_setup->ssi = os_memdup(ssi, ssi_len);
81 	if (!ndp_setup->ssi) {
82 		wpa_printf(MSG_INFO, "NAN: NDP: Failed to allocate NDP ssi");
83 		return -1;
84 	}
85 
86 	ndp_setup->ssi_len = ssi_len;
87 	return 0;
88 }
89 
90 
91 /**
92  * nan_ndp_setup_req - Start handling of NDP setup request
93  * @nan: NAN module context from nan_init()
94  * @peer: The peer to initiate the NDP setup with
95  * @params: NDP setup request parameters
96  * Returns: 0 on success, negative on failure
97  *
98  * On successful request, the data structures would be ready to
99  * continue the NDP establishment.
100  */
nan_ndp_setup_req(struct nan_data * nan,struct nan_peer * peer,struct nan_ndp_params * params)101 int nan_ndp_setup_req(struct nan_data *nan, struct nan_peer *peer,
102 		      struct nan_ndp_params *params)
103 {
104 	int ret;
105 
106 	if (peer->ndp_setup.ndp) {
107 		wpa_printf(MSG_DEBUG, "NAN: NDP: already WIP with peer");
108 		return -1;
109 	}
110 
111 	peer->ndp_setup.ndp = nan_ndp_alloc(nan, peer, 1,
112 					    params->ndp_id.init_ndi,
113 					    params->ndp_id.id,
114 					    params->qos.min_slots,
115 					    params->qos.max_latency);
116 	if (!peer->ndp_setup.ndp) {
117 		wpa_printf(MSG_DEBUG, "NAN: NDP: Failed allocation");
118 		return -1;
119 	}
120 
121 	peer->ndp_setup.dialog_token = nan_get_next_dialog_token(nan);
122 	peer->ndp_setup.publish_inst_id = params->u.req.publish_inst_id;
123 	os_memcpy(peer->ndp_setup.service_id, params->u.req.service_id,
124 		  NAN_SERVICE_ID_LEN);
125 
126 	/* Require confirmation for all locally initiated NDPs */
127 	peer->ndp_setup.conf_req = 1;
128 
129 	/* Store service specific information */
130 	ret = nan_ndp_ssi(nan, &peer->ndp_setup, params->ssi, params->ssi_len);
131 	if (ret) {
132 		os_free(peer->ndp_setup.ndp);
133 		peer->ndp_setup.ndp = NULL;
134 		return ret;
135 	}
136 
137 	nan_sec_reset(nan, &peer->ndp_setup.sec);
138 
139 	if (params->sec.csid) {
140 		peer->ndp_setup.sec.i_csid = params->sec.csid;
141 		os_memcpy(peer->ndp_setup.sec.pmk, params->sec.pmk, PMK_LEN);
142 
143 		peer->ndp_setup.sec.present = true;
144 		peer->ndp_setup.sec.valid = true;
145 
146 		peer->ndp_setup.sec.i_instance_id =
147 			peer->ndp_setup.publish_inst_id;
148 
149 		os_memcpy(&peer->ndp_setup.sec.local_gtk, &params->sec.gtk,
150 			  sizeof(peer->ndp_setup.sec.local_gtk));
151 	}
152 
153 	if (params->interface_id) {
154 		wpa_printf(MSG_DEBUG,
155 			   "NAN: NDP setup request with local interface id");
156 
157 		os_memcpy(peer->ndp_setup.local_interface_id,
158 			  params->interface_id,
159 			  NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN);
160 
161 		peer->ndp_setup.local_interface_id_valid = true;
162 	}
163 
164 	nan_ndp_set_state(nan, &peer->ndp_setup, NAN_NDP_STATE_START);
165 	peer->ndp_setup.status = NAN_NDP_STATUS_CONTINUED;
166 	return 0;
167 }
168 
169 
170 /**
171  * nan_ndp_setup_resp - Handle higher layer response for an NDP request
172  * @nan: NAN module context from nan_init()
173  * @peer: Peer that originated the NDP setup request
174  * @params: NDP setup parameters
175  * Returns: 0 on success, negative on failure
176  *
177  * The response status can be either ACCEPTED or REJECTED. The internal logic of
178  * the NDP state machine adjusts its own state according to the response status
179  * and its internal state.
180  */
nan_ndp_setup_resp(struct nan_data * nan,struct nan_peer * peer,struct nan_ndp_params * params)181 int nan_ndp_setup_resp(struct nan_data *nan, struct nan_peer *peer,
182 		       struct nan_ndp_params *params)
183 {
184 	int ret;
185 
186 	if (!peer->ndp_setup.ndp ||
187 	    peer->ndp_setup.ndp->ndp_id != params->ndp_id.id ||
188 	    !ether_addr_equal(peer->ndp_setup.ndp->init_ndi,
189 			      params->ndp_id.init_ndi)) {
190 		wpa_printf(MSG_DEBUG,
191 			   "NAN: NDP: No matching NDP found for NDP response");
192 		return -1;
193 	}
194 
195 	if (peer->ndp_setup.state != NAN_NDP_STATE_REQ_RECV) {
196 		wpa_printf(MSG_DEBUG,
197 			   "NAN: NDP: Unexpected state for response");
198 		return -1;
199 	}
200 
201 	if (params->u.resp.status != NAN_NDP_STATUS_ACCEPTED &&
202 	    params->u.resp.status != NAN_NDP_STATUS_REJECTED) {
203 		wpa_printf(MSG_DEBUG,
204 			   "NAN: NDP: Unexpected response status=%u",
205 			params->u.resp.status);
206 		return -1;
207 	}
208 
209 	peer->ndp_setup.status = params->u.resp.status;
210 	peer->ndp_setup.reason = params->u.resp.reason_code;
211 
212 	if (peer->ndp_setup.status == NAN_NDP_STATUS_ACCEPTED) {
213 		if (peer->ndp_setup.conf_req)
214 			peer->ndp_setup.status = NAN_NDP_STATUS_CONTINUED;
215 
216 		os_memcpy(peer->ndp_setup.ndp->resp_ndi,
217 			  params->u.resp.resp_ndi, ETH_ALEN);
218 
219 		if (!peer->ndp_setup.sec.present && params->sec.csid) {
220 			wpa_printf(MSG_DEBUG,
221 				   "NAN: NDP: Security not requested by peer");
222 			return -1;
223 		}
224 
225 		if (peer->ndp_setup.sec.present) {
226 			if (params->sec.csid != peer->ndp_setup.sec.i_csid) {
227 				wpa_printf(MSG_DEBUG,
228 					   "NAN: NDP: Different cipher suite specified.");
229 				return -1;
230 			}
231 
232 			peer->ndp_setup.sec.r_csid = params->sec.csid;
233 			os_memcpy(peer->ndp_setup.sec.pmk, params->sec.pmk,
234 				  PMK_LEN);
235 			os_memcpy(&peer->ndp_setup.sec.local_gtk,
236 				  &params->sec.gtk,
237 				  sizeof(peer->ndp_setup.sec.local_gtk));
238 
239 			ret = nan_sec_init_resp(nan, peer);
240 			if (ret) {
241 				wpa_printf(MSG_DEBUG,
242 					   "NAN: NDP: Failed to init responder security");
243 
244 				peer->ndp_setup.status =
245 					NAN_NDP_STATUS_REJECTED;
246 				peer->ndp_setup.reason =
247 					NAN_REASON_INVALID_PARAMETERS;
248 				return 0;
249 			}
250 
251 			peer->ndp_setup.status = NAN_NDP_STATUS_CONTINUED;
252 		}
253 	}
254 
255 	/* Store service specific information */
256 	ret = nan_ndp_ssi(nan, &peer->ndp_setup, params->ssi, params->ssi_len);
257 	if (ret)
258 		return ret;
259 
260 	if (params->interface_id) {
261 		wpa_printf(MSG_DEBUG,
262 			   "NAN: NDP setup response with local interface id");
263 
264 		os_memcpy(peer->ndp_setup.local_interface_id,
265 			  params->interface_id,
266 			  NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN);
267 
268 		peer->ndp_setup.local_interface_id_valid = true;
269 	}
270 
271 	return 0;
272 }
273 
274 
nan_ndp_attr_handle_tlvs(struct nan_data * nan,struct nan_peer * peer,const u8 * tlvs,u16 tlvs_len)275 static int nan_ndp_attr_handle_tlvs(struct nan_data *nan,
276 				    struct nan_peer *peer,
277 				    const u8 *tlvs, u16 tlvs_len)
278 {
279 	wpa_printf(MSG_DEBUG, "NAN: NDP: Handle NDPE TLVs len=%u", tlvs_len);
280 
281 	while (tlvs_len > 3) {
282 		u8 tlv_type = tlvs[0];
283 		u16 tlv_len = WPA_GET_LE16(tlvs + 1);
284 		const u8 *tlv_data = tlvs + 3;
285 		int ret;
286 
287 		if (tlv_len + 3 > tlvs_len) {
288 			wpa_printf(MSG_DEBUG,
289 				   "NAN: NDP: Invalid TLV len=%u for type=%u",
290 				   tlv_len, tlv_type);
291 			return -1;
292 		}
293 
294 		switch (tlv_type) {
295 		case NAN_NDPE_TLV_IPV6_LINK_LOCAL:
296 			if (tlv_len != NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN) {
297 				wpa_printf(MSG_DEBUG,
298 					   "NAN: NDP: req: Invalid interface ID tlv len=%u",
299 					   tlv_len);
300 				break;
301 			}
302 
303 			peer->ndp_setup.peer_interface_id_valid = true;
304 			os_memcpy(peer->ndp_setup.peer_interface_id, tlv_data,
305 				  NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN);
306 			break;
307 		case NAN_NDPE_TLV_SRV_INFO:
308 			wpa_printf(MSG_DEBUG,
309 				   "NAN: NDP: Handle NDP service specific information");
310 
311 			if (tlv_len >= 4 && WPA_GET_BE24(tlv_data) == OUI_WFA &&
312 			    tlv_data[3] == NAN_SRV_PROTO_GENERIC)
313 				ret = nan_ndp_ssi(nan, &peer->ndp_setup,
314 						  tlv_data + 4, tlv_len - 4);
315 			else
316 				ret = nan_ndp_ssi(nan, &peer->ndp_setup,
317 						  tlv_data, tlv_len);
318 			if (ret)
319 				wpa_printf(MSG_DEBUG,
320 					   "NAN: NDP: Failed to save ssi - continue");
321 			break;
322 		default:
323 			wpa_printf(MSG_DEBUG, "NAN: NDP: unknown TLV type=%u",
324 				   tlv_type);
325 			break;
326 		}
327 
328 		tlvs += 3 + tlv_len;
329 		tlvs_len -= 3 + tlv_len;
330 	}
331 
332 	if (tlvs_len) {
333 		wpa_printf(MSG_DEBUG,
334 			   "NAN: NDP: TLV parsing ended with %u left octets",
335 			   tlvs_len);
336 		return -1;
337 	}
338 
339 	return 0;
340 }
341 
342 
nan_ndp_attr_handle_req(struct nan_data * nan,struct nan_peer * peer,struct ieee80211_ndp * ndp_attr,u16 ndp_len,u8 status,bool ndpe)343 static int nan_ndp_attr_handle_req(struct nan_data *nan, struct nan_peer *peer,
344 				   struct ieee80211_ndp *ndp_attr, u16 ndp_len,
345 				   u8 status, bool ndpe)
346 {
347 	struct nan_ndp_setup *ndp_setup = &peer->ndp_setup;
348 	u16 exp_len = sizeof(struct ieee80211_ndp);
349 	u8 publish_inst_id;
350 
351 	if (ndp_setup->ndp) {
352 		wpa_printf(MSG_DEBUG,
353 			   "NAN: NDP: req: While already WIP with peer");
354 		return -1;
355 	}
356 
357 	if (!(ndp_attr->ndp_ctrl & NAN_NDP_CTRL_PUBLISH_ID_PRESENT)) {
358 		wpa_printf(MSG_DEBUG,
359 			   "NAN: NDP: req: Without publish ID");
360 		return -1;
361 	}
362 
363 	exp_len++;
364 	if (ndp_len < exp_len) {
365 		wpa_printf(MSG_DEBUG,
366 			   "NAN: NDP: req: Length too short: ndp_len=%u, exp_len=%u",
367 			   ndp_len, exp_len);
368 		return -1;
369 	}
370 
371 	publish_inst_id = *ndp_attr->optional;
372 	if (!nan_publish_instance_id_valid(nan, publish_inst_id,
373 					   ndp_setup->service_id)) {
374 		wpa_printf(MSG_DEBUG,
375 			   "NAN: NDP: req: Invalid publish instance ID=%u",
376 			publish_inst_id);
377 		return -1;
378 	}
379 
380 	/* Note: The QoS setting should be set in the response. */
381 	ndp_setup->ndp = nan_ndp_alloc(nan, peer, 0,
382 				       ndp_attr->initiator_ndi,
383 				       ndp_attr->ndp_id,
384 				       NAN_QOS_MIN_SLOTS_NO_PREF,
385 				       NAN_QOS_MAX_LATENCY_NO_PREF);
386 	if (!ndp_setup->ndp)
387 		return -1;
388 
389 	nan_sec_reset(nan, &peer->ndp_setup.sec);
390 	nan_ndp_set_state(nan, ndp_setup, NAN_NDP_STATE_REQ_RECV);
391 
392 	ndp_setup->status = NAN_NDP_STATUS_CONTINUED;
393 	ndp_setup->conf_req =
394 		!!(ndp_attr->ndp_ctrl & NAN_NDP_CTRL_CONFIRM_REQUIRED);
395 	ndp_setup->dialog_token = ndp_attr->dialog_token;
396 	ndp_setup->publish_inst_id = publish_inst_id;
397 	ndp_setup->sec.present =
398 		!!(ndp_attr->ndp_ctrl & NAN_NDP_CTRL_SECURITY_PRESENT);
399 
400 	/* Handle service specific information */
401 	ndp_len -= exp_len;
402 
403 	if (!ndpe && (ndp_attr->ndp_ctrl & NAN_NDP_CTRL_SPEC_INFO_PRESENT) &&
404 	    ndp_len) {
405 		int ret;
406 
407 		wpa_printf(MSG_DEBUG,
408 			   "NAN: NDP: req: Handle NDP service specific information");
409 
410 		ret = nan_ndp_ssi(nan, &peer->ndp_setup,
411 				  (const u8 *) ndp_attr->optional + 1,
412 				  ndp_len);
413 		if (ret)
414 			wpa_printf(MSG_DEBUG,
415 				   "NAN: NDP: req: Failed to save ssi. continue");
416 		return ret;
417 	}
418 
419 	if (ndpe)
420 		return nan_ndp_attr_handle_tlvs(nan, peer,
421 						ndp_attr->optional + 1,
422 						ndp_len);
423 
424 	return 0;
425 }
426 
427 
nan_ndp_attr_handle_res(struct nan_data * nan,struct nan_peer * peer,struct ieee80211_ndp * ndp_attr,u16 ndp_len,u8 status,bool ndpe)428 static int nan_ndp_attr_handle_res(struct nan_data *nan, struct nan_peer *peer,
429 				   struct ieee80211_ndp *ndp_attr, u16 ndp_len,
430 				   u8 status, bool ndpe)
431 {
432 	struct nan_ndp_setup *ndp_setup = &peer->ndp_setup;
433 	u16 opt_len;
434 	bool sec_present;
435 
436 	if (!ndp_setup->ndp) {
437 		wpa_printf(MSG_DEBUG,
438 			   "NAN: NDP: resp: While no NDP WIP with peer");
439 		return -1;
440 	}
441 
442 	if (ndp_setup->state != NAN_NDP_STATE_REQ_SENT) {
443 		wpa_printf(MSG_DEBUG,
444 			   "NAN: NDP: resp: While not expecting one");
445 
446 		if (ndp_setup->state != NAN_NDP_STATE_START)
447 			return -1;
448 
449 		/*
450 		 * Due to races with the driver, it is possible that the
451 		 * response is received before an ACK is indicated. Allow the
452 		 * processing of the attribute, and if all parameters are OK,
453 		 * fast forward the state machine below.
454 		 */
455 		wpa_printf(MSG_DEBUG,
456 			   "NAN: NDP: resp: Received before Tx status.");
457 	}
458 
459 	if (ndp_attr->ndp_ctrl & NAN_NDP_CTRL_PUBLISH_ID_PRESENT) {
460 		wpa_printf(MSG_DEBUG,
461 			   "NAN: NDP: resp: Unexpected publish ID");
462 		return -1;
463 	}
464 
465 	opt_len = 0;
466 	if (status == NAN_NDP_STATUS_CONTINUED ||
467 	    status == NAN_NDP_STATUS_ACCEPTED) {
468 		if (!(ndp_attr->ndp_ctrl &
469 		      NAN_NDP_CTRL_RESPONDER_NDI_PRESENT)) {
470 			wpa_printf(MSG_DEBUG,
471 				   "NAN: NDP: resp: without responder NDI");
472 			return -1;
473 		}
474 		opt_len += ETH_ALEN;
475 	}
476 
477 	if (ndp_len < (sizeof(struct ieee80211_ndp) + opt_len)) {
478 		wpa_printf(MSG_DEBUG, "NAN: NDP: resp: Length too short");
479 		return -1;
480 	}
481 
482 	if (ndp_setup->ndp->ndp_id != ndp_attr->ndp_id ||
483 	    ndp_setup->dialog_token != ndp_attr->dialog_token ||
484 	    !ether_addr_equal(ndp_setup->ndp->init_ndi,
485 			      ndp_attr->initiator_ndi)) {
486 		wpa_printf(MSG_DEBUG,
487 			   "NAN: NDP: resp: Invalid NDP ID, dialog token or addr");
488 		return -1;
489 	}
490 
491 	if (ndp_setup->state == NAN_NDP_STATE_START) {
492 		wpa_printf(MSG_DEBUG,
493 			   "NAN: NDP: resp: Continue though no TX status yet.");
494 		nan_ndp_set_state(nan, &peer->ndp_setup,
495 				  NAN_NDP_STATE_REQ_SENT);
496 	}
497 
498 	ndp_setup->status = status;
499 
500 	if (status == NAN_NDP_STATUS_REJECTED) {
501 		ndp_setup->reason = ndp_attr->reason_code;
502 		nan_ndp_set_state(nan, &peer->ndp_setup,
503 				  NAN_NDP_STATE_DONE);
504 		goto store_ssi;
505 	}
506 
507 	sec_present = !!(ndp_attr->ndp_ctrl & NAN_NDP_CTRL_SECURITY_PRESENT);
508 	if (ndp_setup->sec.present != sec_present) {
509 		wpa_printf(MSG_DEBUG,
510 			   "NAN: NDP: Security present mismatch");
511 		return -1;
512 	}
513 
514 	if ((sec_present || ndp_setup->conf_req) &&
515 	    status != NAN_NDP_STATUS_CONTINUED) {
516 		wpa_printf(MSG_DEBUG,
517 			   "NAN: NDP: Security present or confirm required and status != continued");
518 		return -1;
519 	}
520 
521 	if (status == NAN_NDP_STATUS_ACCEPTED)
522 		nan_ndp_set_state(nan, &peer->ndp_setup, NAN_NDP_STATE_DONE);
523 	else
524 		nan_ndp_set_state(nan, &peer->ndp_setup,
525 				  NAN_NDP_STATE_RES_RECV);
526 
527 	os_memcpy(ndp_setup->ndp->resp_ndi, &ndp_attr->optional[0],
528 		  sizeof(ndp_setup->ndp->resp_ndi));
529 
530 	/*
531 	 * In case that security is not configured, move the status to accepted.
532 	 * The state machine would transition to the 'done' state after the
533 	 * confirm is acked.
534 	 * TODO: Once security is configured, need to validate the security must
535 	 * be present.
536 	 */
537 	if (!(ndp_attr->ndp_ctrl & NAN_NDP_CTRL_SECURITY_PRESENT))
538 		ndp_setup->status = NAN_NDP_STATUS_ACCEPTED;
539 
540 store_ssi:
541 	/* Handle service specific information */
542 	ndp_len -= sizeof(struct ieee80211_ndp) + opt_len;
543 	if (!ndpe && (ndp_attr->ndp_ctrl & NAN_NDP_CTRL_SPEC_INFO_PRESENT) &&
544 	    ndp_len) {
545 		int ret;
546 
547 		wpa_printf(MSG_DEBUG, "NAN: NDP: resp: Handle NDP ssi");
548 		ret = nan_ndp_ssi(nan, &peer->ndp_setup,
549 				  ndp_attr->optional + opt_len, ndp_len);
550 		if (ret)
551 			wpa_printf(MSG_DEBUG,
552 				   "NAN: NDP: resp: Failed to save ssi. continue");
553 		return ret;
554 	}
555 
556 	if (ndpe)
557 		return nan_ndp_attr_handle_tlvs(nan, peer,
558 						ndp_attr->optional + opt_len,
559 						ndp_len);
560 
561 	return 0;
562 }
563 
564 
nan_ndp_attr_handle_confirm(struct nan_data * nan,struct nan_peer * peer,struct ieee80211_ndp * ndp_attr,u8 status)565 static int nan_ndp_attr_handle_confirm(struct nan_data *nan,
566 				       struct nan_peer *peer,
567 				       struct ieee80211_ndp *ndp_attr,
568 				       u8 status)
569 {
570 	struct nan_ndp_setup *ndp_setup = &peer->ndp_setup;
571 	bool sec_present;
572 
573 	if (!ndp_setup->ndp) {
574 		wpa_printf(MSG_DEBUG,
575 			   "NAN: NDP: Received confirm while no NDP WIP with peer");
576 		return -1;
577 	}
578 
579 	if (ndp_setup->state != NAN_NDP_STATE_RES_SENT) {
580 		wpa_printf(MSG_DEBUG,
581 			   "NAN: NDP: confirm: While not expecting one");
582 
583 		if (ndp_setup->state != NAN_NDP_STATE_REQ_RECV ||
584 		    ndp_setup->status != NAN_NDP_STATUS_CONTINUED)
585 			return -1;
586 
587 		/*
588 		 * Due to races with the driver, it is possible that the
589 		 * confirm is received before an ACK is indicated. Allow the
590 		 * processing of the attribute, and if all parameters are OK,
591 		 * fast forward the state machine below.
592 		 */
593 		wpa_printf(MSG_DEBUG,
594 			   "NAN: NDP: Confirm received before Tx status");
595 	}
596 
597 	if (ndp_setup->ndp->ndp_id != ndp_attr->ndp_id ||
598 	    ndp_setup->dialog_token != ndp_attr->dialog_token ||
599 	    !ether_addr_equal(ndp_setup->ndp->init_ndi,
600 			      ndp_attr->initiator_ndi)) {
601 		wpa_printf(MSG_DEBUG,
602 			   "NAN: NDP: confirm: Invalid NDP ID, dialog token or init ID");
603 		return -1;
604 	}
605 
606 	sec_present = !!(ndp_attr->ndp_ctrl & NAN_NDP_CTRL_SECURITY_PRESENT);
607 	if (ndp_setup->sec.present != sec_present) {
608 		wpa_printf(MSG_DEBUG,
609 			   "NAN: NDP: confirm: Security present mismatch");
610 		return -1;
611 	}
612 
613 	if (sec_present && status != NAN_NDP_STATUS_CONTINUED) {
614 		wpa_printf(MSG_DEBUG,
615 			   "NAN: NDP: confirm: status != continued with security");
616 		return -1;
617 	}
618 
619 	if (ndp_setup->state == NAN_NDP_STATE_REQ_RECV) {
620 		wpa_printf(MSG_DEBUG,
621 			   "NAN: NDP: confirm: Continue though no TX status yet.");
622 		nan_ndp_set_state(nan, &peer->ndp_setup,
623 				  NAN_NDP_STATE_RES_SENT);
624 	}
625 
626 	ndp_setup->status = status;
627 
628 	if (sec_present)
629 		nan_ndp_set_state(nan, &peer->ndp_setup,
630 				  NAN_NDP_STATE_CON_RECV);
631 	else
632 		nan_ndp_set_state(nan, &peer->ndp_setup, NAN_NDP_STATE_DONE);
633 
634 	return 0;
635 }
636 
637 
nan_ndp_find_ndp(struct nan_peer * peer,u8 ndp_id,const u8 * init_ndi)638 static struct nan_ndp * nan_ndp_find_ndp(struct nan_peer *peer,
639 					 u8 ndp_id, const u8 *init_ndi)
640 {
641 	struct nan_ndp *pndp;
642 
643 	dl_list_for_each(pndp, &peer->ndps, struct nan_ndp, list) {
644 		if (pndp->ndp_id == ndp_id &&
645 		    ether_addr_equal(pndp->init_ndi, init_ndi))
646 			return pndp;
647 	}
648 
649 	return NULL;
650 }
651 
652 
nan_ndp_attr_sec_install(struct nan_data * nan,struct nan_peer * peer,const struct ieee80211_ndp * ndp_attr,u8 status)653 static int nan_ndp_attr_sec_install(struct nan_data *nan, struct nan_peer *peer,
654 				    const struct ieee80211_ndp *ndp_attr,
655 				    u8 status)
656 {
657 	struct nan_ndp_setup *ndp_setup = &peer->ndp_setup;
658 	bool sec_present;
659 
660 	if (!ndp_setup->ndp) {
661 		wpa_printf(MSG_DEBUG,
662 			   "NAN: NDP: sec install while no NDP WIP with peer");
663 		return -1;
664 	}
665 
666 	if (ndp_setup->state != NAN_NDP_STATE_CON_SENT) {
667 		wpa_printf(MSG_DEBUG,
668 			   "NAN: NDP: sec install while not expecting one");
669 
670 		if (ndp_setup->state != NAN_NDP_STATE_RES_RECV ||
671 		    ndp_setup->status != NAN_NDP_STATUS_CONTINUED)
672 			return -1;
673 
674 		/* Due to races with the driver, it is possible that the
675 		 * install is received before an ACK is indicated. Allow the
676 		 * processing of the attribute, and if all parameters are OK,
677 		 * fast forward the state machine below.
678 		 */
679 		wpa_printf(MSG_DEBUG,
680 			   "NAN: NDP: sec install received before Tx status.");
681 	}
682 
683 	if (ndp_setup->ndp->ndp_id != ndp_attr->ndp_id ||
684 	    ndp_setup->dialog_token != ndp_attr->dialog_token ||
685 	    !ether_addr_equal(ndp_setup->ndp->init_ndi,
686 			      ndp_attr->initiator_ndi)) {
687 		wpa_printf(MSG_DEBUG,
688 			   "NAN: NDP: sec install: Invalid NDP parameters");
689 		return -1;
690 	}
691 
692 	sec_present = !!(ndp_attr->ndp_ctrl & NAN_NDP_CTRL_SECURITY_PRESENT);
693 	if (ndp_setup->sec.present != sec_present) {
694 		wpa_printf(MSG_DEBUG,
695 			   "NAN: NDP: sec install: Security present mismatch");
696 		return -1;
697 	}
698 
699 	if (status != NAN_NDP_STATUS_ACCEPTED) {
700 		wpa_printf(MSG_DEBUG,
701 			   "NAN: NDP: sec install: status != ACCEPTED");
702 		return -1;
703 	}
704 
705 	nan_ndp_set_state(nan, &peer->ndp_setup, NAN_NDP_STATE_DONE);
706 	return 0;
707 }
708 
709 
nan_ndp_attr_handle_term(struct nan_data * nan,struct nan_peer * peer,struct ieee80211_ndp * ndp_attr,u8 status)710 static int nan_ndp_attr_handle_term(struct nan_data *nan, struct nan_peer *peer,
711 				    struct ieee80211_ndp *ndp_attr, u8 status)
712 {
713 	struct nan_ndp_setup *ndp_setup = &peer->ndp_setup;
714 	struct nan_ndp_id ndp_id;
715 	const u8 *local_ndi, *peer_ndi;
716 	struct nan_ndp *pndp;
717 
718 	wpa_printf(MSG_DEBUG,
719 		   "NAN: NDP: Termination peer=" MACSTR " ndp_id=%u, init_ndi="
720 		   MACSTR,
721 		   MAC2STR(peer->nmi_addr), ndp_attr->ndp_id,
722 		   MAC2STR(ndp_attr->initiator_ndi));
723 
724 	/*
725 	 * This should not really happen, but just in case, terminate the
726 	 * establishment. Since the NDP establishment is not yet done, the NDP
727 	 * is not added to the list of NDPs, so just reject the establishment.
728 	 */
729 	if (ndp_setup->ndp && ndp_setup->ndp->ndp_id == ndp_attr->ndp_id &&
730 	    ether_addr_equal(ndp_setup->ndp->init_ndi,
731 			     ndp_attr->initiator_ndi)) {
732 		wpa_printf(MSG_DEBUG,
733 			   "NAN: NDP: Termination while NDP is in progress");
734 
735 		nan_ndp_set_state(nan, &peer->ndp_setup, NAN_NDP_STATE_DONE);
736 		ndp_setup->status = NAN_NDP_STATUS_REJECTED;
737 		ndp_setup->reason = NAN_REASON_UNSPECIFIED_REASON;
738 		return 0;
739 	}
740 
741 	/* Find the NDP in the list of active NDPs */
742 	pndp = nan_ndp_find_ndp(peer, ndp_attr->ndp_id,
743 				ndp_attr->initiator_ndi);
744 	if (!pndp) {
745 		wpa_printf(MSG_DEBUG,
746 			   "NAN: NDP: Termination but NDP does not exist");
747 		return 1;
748 	}
749 
750 	wpa_printf(MSG_DEBUG, "NAN: NDP: Terminating");
751 
752 	os_memcpy(ndp_id.peer_nmi, peer->nmi_addr, ETH_ALEN);
753 	os_memcpy(ndp_id.init_ndi, pndp->init_ndi, ETH_ALEN);
754 	ndp_id.id = pndp->ndp_id;
755 
756 	if (pndp->initiator) {
757 		local_ndi = pndp->init_ndi;
758 		peer_ndi = pndp->resp_ndi;
759 	} else {
760 		local_ndi = pndp->resp_ndi;
761 		peer_ndi = pndp->init_ndi;
762 	}
763 
764 	/*
765 	 * Remove the NDP from the list of active NDPs before calling
766 	 * nan_ndp_terminated() as the function checks the list of NDPs to
767 	 * determine if the NDL should be reset as well. Free the NDP only after
768 	 * the call as the NDI addresses are still referenced.
769 	 */
770 	dl_list_del(&pndp->list);
771 
772 	nan_ndp_terminated(nan, peer, &ndp_id, local_ndi, peer_ndi,
773 			   ndp_attr->reason_code, pndp->gtk_id);
774 
775 	os_free(pndp);
776 
777 	/* Indicate that no further processing is needed */
778 	return 1;
779 }
780 
781 
782 /**
783  * nan_ndp_handle_ndp_attr - Handle NDP attribute and update local state
784  * @nan: NAN module context from nan_init()
785  * @peer: The peer from which the original message was received
786  * @msg: Parsed NAN Action frame
787  * Returns: 0 on success processing indicating that processing can continue; 1
788  * in case of successful processing but no further processing is needed;
789  * negative on failure.
790  */
nan_ndp_handle_ndp_attr(struct nan_data * nan,struct nan_peer * peer,struct nan_msg * msg)791 int nan_ndp_handle_ndp_attr(struct nan_data *nan, struct nan_peer *peer,
792 			    struct nan_msg *msg)
793 {
794 	struct ieee80211_ndp *ndp_attr = NULL;
795 	size_t ndp_attr_len = 0;
796 	bool ndpe_supported;
797 	u8 type, status;
798 	int ret;
799 
800 	if (!msg || !peer || (!msg->attrs.ndp && !msg->attrs.ndpe))
801 		return -1;
802 
803 	ndpe_supported = nan_is_ndpe_supported(nan, peer);
804 	wpa_printf(MSG_DEBUG,
805 		   "NAN: NDP: Handle NDP attribute. ndpe_supported=%u",
806 		   ndpe_supported);
807 
808 	/*
809 	 * The NDP attribute and the NDPE attribute are very similar in
810 	 * structure so handle them in the same way where possible.
811 	 */
812 	if (ndpe_supported) {
813 		ndp_attr = (struct ieee80211_ndp *) msg->attrs.ndpe;
814 		ndp_attr_len = msg->attrs.ndpe_len;
815 	}
816 
817 	if (!ndp_attr || !ndp_attr_len) {
818 		ndp_attr = (struct ieee80211_ndp *) msg->attrs.ndp;
819 		ndp_attr_len = msg->attrs.ndp_len;
820 		ndpe_supported = false;
821 		if (!ndp_attr || !ndp_attr_len)
822 			return -1;
823 	}
824 
825 	type = BITS(ndp_attr->type_and_status, NAN_NDP_TYPE_MASK,
826 		    NAN_NDP_TYPE_POS);
827 	status = BITS(ndp_attr->type_and_status, NAN_NDP_STATUS_MASK,
828 		      NAN_NDP_STATUS_POS);
829 
830 	if (peer->ndp_setup.ndp) {
831 		wpa_printf(MSG_DEBUG,
832 			   "NAN: NDP: attr: state=%s (%d), status=%d",
833 			   nan_ndp_state_str(peer->ndp_setup.state),
834 			   peer->ndp_setup.state,
835 			   peer->ndp_setup.status);
836 	} else {
837 		wpa_printf(MSG_DEBUG, "NAN: NDP: attr: no active NDP setup");
838 	}
839 
840 	wpa_printf(MSG_DEBUG, "NAN: NDP: attr: type=0x%x, status=0x%x",
841 		   type, status);
842 
843 	switch (type) {
844 	case NAN_NDP_TYPE_REQUEST:
845 		ret = nan_ndp_attr_handle_req(nan, peer, ndp_attr,
846 					      ndp_attr_len, status,
847 					      ndpe_supported);
848 		break;
849 	case NAN_NDP_TYPE_RESPONSE:
850 		ret = nan_ndp_attr_handle_res(nan, peer, ndp_attr,
851 					      ndp_attr_len, status,
852 					      ndpe_supported);
853 		break;
854 	case NAN_NDP_TYPE_CONFIRM:
855 		ret = nan_ndp_attr_handle_confirm(nan, peer, ndp_attr, status);
856 		break;
857 	case NAN_NDP_TYPE_SECURITY_INSTALL:
858 		ret = nan_ndp_attr_sec_install(nan, peer, ndp_attr, status);
859 		break;
860 	case NAN_NDP_TYPE_TERMINATE:
861 		return nan_ndp_attr_handle_term(nan, peer, ndp_attr, status);
862 	default:
863 		return -1;
864 	}
865 
866 	/* Error or no security.. We are done. */
867 	if (ret || !peer->ndp_setup.sec.present ||
868 	    peer->ndp_setup.status == NAN_NDP_STATUS_REJECTED)
869 		return ret;
870 
871 	ret = nan_sec_rx(nan, peer, msg);
872 	if (ret)
873 		return ret;
874 
875 	/* Processing of confirm is successful, so to the overall status is
876 	 * success. */
877 	if (type == NAN_NDP_TYPE_CONFIRM)
878 		peer->ndp_setup.status = NAN_NDP_STATUS_ACCEPTED;
879 
880 	return 0;
881 }
882 
883 
884 /**
885  * nan_ndp_add_ndp_attr - Add NDP attribute to frame
886  * @nan: NAN module context from nan_init()
887  * @peer: The peer to which the NAF should be sent
888  * @buf: wpabuf to which the attribute would be added
889  * Returns: 0 on success, negative on failure
890  */
nan_ndp_add_ndp_attr(struct nan_data * nan,struct nan_peer * peer,struct wpabuf * buf)891 int nan_ndp_add_ndp_attr(struct nan_data *nan, struct nan_peer *peer,
892 			 struct wpabuf *buf)
893 {
894 	struct nan_ndp_setup *ndp_setup;
895 	u8 type, ndp_ctrl = 0;
896 	u8 *len_ptr;
897 	bool ndpe_supported;
898 	bool add_srv_info = false;
899 
900 	if (!peer || !peer->ndp_setup.ndp)
901 		return -1;
902 
903 	ndpe_supported = nan_is_ndpe_supported(nan, peer);
904 	ndp_setup = &peer->ndp_setup;
905 
906 	switch (ndp_setup->state) {
907 	case NAN_NDP_STATE_START:
908 		type = NAN_NDP_TYPE_REQUEST;
909 		ndp_ctrl = NAN_NDP_CTRL_PUBLISH_ID_PRESENT;
910 		if (ndp_setup->conf_req)
911 			ndp_ctrl |= NAN_NDP_CTRL_CONFIRM_REQUIRED;
912 		if (ndp_setup->ssi && ndp_setup->ssi_len) {
913 			add_srv_info = true;
914 			if (!ndpe_supported)
915 				ndp_ctrl |= NAN_NDP_CTRL_SPEC_INFO_PRESENT;
916 		}
917 		break;
918 	case NAN_NDP_STATE_REQ_RECV:
919 		type = NAN_NDP_TYPE_RESPONSE;
920 		if (ndp_setup->status != NAN_NDP_STATUS_REJECTED)
921 			ndp_ctrl |= NAN_NDP_CTRL_RESPONDER_NDI_PRESENT;
922 		if (ndp_setup->ssi && ndp_setup->ssi_len) {
923 			add_srv_info = true;
924 			if (!ndpe_supported)
925 				ndp_ctrl |= NAN_NDP_CTRL_SPEC_INFO_PRESENT;
926 		}
927 		break;
928 	case NAN_NDP_STATE_RES_RECV:
929 		type = NAN_NDP_TYPE_CONFIRM;
930 		break;
931 	case NAN_NDP_STATE_CON_RECV:
932 		/* TODO: Integrate NDP security flows */
933 		type = NAN_NDP_TYPE_SECURITY_INSTALL;
934 		break;
935 	case NAN_NDP_STATE_NONE:
936 	case NAN_NDP_STATE_DONE:
937 		if (ndp_setup->status == NAN_NDP_STATUS_REJECTED)
938 			type = NAN_NDP_TYPE_TERMINATE;
939 		else
940 			return -1;
941 		break;
942 	case NAN_NDP_STATE_REQ_SENT:
943 	case NAN_NDP_STATE_RES_SENT:
944 	case NAN_NDP_STATE_CON_SENT:
945 	default:
946 		return 0;
947 	}
948 
949 	if (ndp_setup->sec.present)
950 		ndp_ctrl |= NAN_NDP_CTRL_SECURITY_PRESENT;
951 
952 	/*
953 	 * The NDP attribute and the NDPE attribute are very similar in
954 	 * structure so handle them in the same way where possible.
955 	 */
956 	if (ndpe_supported)
957 		wpabuf_put_u8(buf, NAN_ATTR_NDP_EXT);
958 	else
959 		wpabuf_put_u8(buf, NAN_ATTR_NDP);
960 
961 	len_ptr = wpabuf_put(buf, 2);
962 
963 	wpabuf_put_u8(buf, ndp_setup->dialog_token);
964 	wpabuf_put_u8(buf, type |
965 		      (ndp_setup->status << NAN_NDP_STATUS_POS));
966 	wpabuf_put_u8(buf, ndp_setup->reason);
967 	wpabuf_put_data(buf, ndp_setup->ndp->init_ndi, ETH_ALEN);
968 	wpabuf_put_u8(buf, ndp_setup->ndp->ndp_id);
969 	wpabuf_put_u8(buf, ndp_ctrl);
970 
971 	if (ndp_ctrl & NAN_NDP_CTRL_PUBLISH_ID_PRESENT)
972 		wpabuf_put_u8(buf, ndp_setup->publish_inst_id);
973 
974 	if (ndp_ctrl & NAN_NDP_CTRL_RESPONDER_NDI_PRESENT)
975 		wpabuf_put_data(buf, ndp_setup->ndp->resp_ndi, ETH_ALEN);
976 
977 	if (add_srv_info) {
978 		if (!ndpe_supported) {
979 			wpabuf_put_data(buf, ndp_setup->ssi,
980 					ndp_setup->ssi_len);
981 		} else {
982 			/*
983 			 * TODO: For the service specific info use the WFA
984 			 * format. If there is a need to support other vendor
985 			 * OUIs, this would need to be extended.
986 			 */
987 			wpabuf_put_u8(buf, NAN_NDPE_TLV_SRV_INFO);
988 			wpabuf_put_le16(buf, 4 + ndp_setup->ssi_len);
989 			wpabuf_put_be24(buf, OUI_WFA);
990 			wpabuf_put_u8(buf, NAN_SRV_PROTO_GENERIC);
991 			wpabuf_put_data(buf, ndp_setup->ssi,
992 					ndp_setup->ssi_len);
993 		}
994 	}
995 
996 	if (ndpe_supported && ndp_setup->local_interface_id_valid) {
997 		wpabuf_put_u8(buf, NAN_NDPE_TLV_IPV6_LINK_LOCAL);
998 		wpabuf_put_le16(buf, NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN);
999 		wpabuf_put_data(buf, ndp_setup->local_interface_id,
1000 				NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN);
1001 	}
1002 
1003 	WPA_PUT_LE16(len_ptr, (u8 *) wpabuf_put(buf, 0) - len_ptr - 2);
1004 	return 0;
1005 }
1006 
1007 
1008 /**
1009  * nan_ndp_setup_reset - Reset the ndp_setup state
1010  * @nan: NAN module context from nan_init()
1011  * @peer: The peer that requires ndp setup reset
1012  */
nan_ndp_setup_reset(struct nan_data * nan,struct nan_peer * peer)1013 void nan_ndp_setup_reset(struct nan_data *nan, struct nan_peer *peer)
1014 {
1015 	if (!peer)
1016 		return;
1017 
1018 	os_free(peer->ndp_setup.ssi);
1019 	os_free(peer->ndp_setup.ndp);
1020 
1021 	os_memset(&peer->ndp_setup, 0, sizeof(peer->ndp_setup));
1022 	nan_ndp_set_state(nan, &peer->ndp_setup, NAN_NDP_STATE_NONE);
1023 }
1024 
1025 
1026 /**
1027  * nan_ndp_setup_failure - Indicate failure during NDP setup
1028  * @nan: NAN module context from nan_init()
1029  * @peer: The peer from which the original message was received
1030  * @reason: The failure reason
1031  * @reset_state: Reset the NDP state iff equals to true.
1032  */
nan_ndp_setup_failure(struct nan_data * nan,struct nan_peer * peer,enum nan_reason reason,bool reset_state)1033 void nan_ndp_setup_failure(struct nan_data *nan, struct nan_peer *peer,
1034 			   enum nan_reason reason, bool reset_state)
1035 {
1036 	struct nan_ndp_setup *ndp_setup = &peer->ndp_setup;
1037 
1038 	wpa_printf(MSG_DEBUG, "NAN: NDP: setup failure: peer " MACSTR
1039 		   ". state=%s (%u). reason=%u",
1040 		   MAC2STR(peer->nmi_addr), nan_ndp_state_str(ndp_setup->state),
1041 		   ndp_setup->state, reason);
1042 
1043 	if (reset_state) {
1044 		nan_ndp_setup_reset(nan, peer);
1045 	} else {
1046 		ndp_setup->status = NAN_NDP_STATUS_REJECTED;
1047 		ndp_setup->reason = reason;
1048 	}
1049 }
1050 
1051 
1052 /**
1053  * nan_ndp_naf_sent - Indicate a NAF has been sent
1054  * @nan: NAN module context from nan_init()
1055  * @peer: The peer with whom the NDP is being setup
1056  * @subtype: The NAN OUI subtype. See &enum nan_subtype
1057  *
1058  * Notification, indicating to the NDP SM to that a NAF was sent, so the
1059  * NDP SM could update its state.
1060  */
nan_ndp_naf_sent(struct nan_data * nan,struct nan_peer * peer,enum nan_subtype subtype)1061 int nan_ndp_naf_sent(struct nan_data *nan, struct nan_peer *peer,
1062 		     enum nan_subtype subtype)
1063 {
1064 	struct nan_ndp_setup *ndp_setup;
1065 
1066 	if (!peer || !peer->ndp_setup.ndp)
1067 		return -1;
1068 
1069 	ndp_setup = &peer->ndp_setup;
1070 
1071 	wpa_printf(MSG_DEBUG, "NAN: NDP: Tx done: state=%s (%d), status=%d",
1072 		   nan_ndp_state_str(ndp_setup->state),
1073 		   ndp_setup->state, ndp_setup->status);
1074 
1075 	/*
1076 	 * Note: Due to races between the Tx status and Rx path, it is possible
1077 	 * that the Tx status is received after the peer response was already
1078 	 * processed (which can result with another frame being sent). In such a
1079 	 * case the logic above fast-forwards the state, and the transitions
1080 	 * here need to take this into consideration.
1081 	 */
1082 	switch (ndp_setup->state) {
1083 	case NAN_NDP_STATE_START:
1084 		if (subtype == NAN_SUBTYPE_DATA_PATH_REQUEST)
1085 			nan_ndp_set_state(nan, &peer->ndp_setup,
1086 					  NAN_NDP_STATE_REQ_SENT);
1087 		break;
1088 	case NAN_NDP_STATE_REQ_RECV:
1089 		if (subtype == NAN_SUBTYPE_DATA_PATH_RESPONSE) {
1090 			if (ndp_setup->status == NAN_NDP_STATUS_ACCEPTED)
1091 				nan_ndp_set_state(nan, &peer->ndp_setup,
1092 						  NAN_NDP_STATE_DONE);
1093 			else
1094 				nan_ndp_set_state(nan, &peer->ndp_setup,
1095 						  NAN_NDP_STATE_RES_SENT);
1096 		}
1097 		break;
1098 	case NAN_NDP_STATE_RES_RECV:
1099 		if (subtype == NAN_SUBTYPE_DATA_PATH_CONFIRM) {
1100 			if (ndp_setup->status == NAN_NDP_STATUS_ACCEPTED)
1101 				nan_ndp_set_state(nan, &peer->ndp_setup,
1102 						  NAN_NDP_STATE_DONE);
1103 			else
1104 				nan_ndp_set_state(nan, &peer->ndp_setup,
1105 						  NAN_NDP_STATE_CON_SENT);
1106 		}
1107 		break;
1108 	case NAN_NDP_STATE_CON_RECV:
1109 		if (subtype == NAN_SUBTYPE_DATA_PATH_KEY_INSTALL &&
1110 		    ndp_setup->status == NAN_NDP_STATUS_ACCEPTED)
1111 			nan_ndp_set_state(nan, &peer->ndp_setup,
1112 					  NAN_NDP_STATE_DONE);
1113 		break;
1114 	case NAN_NDP_STATE_REQ_SENT:
1115 	case NAN_NDP_STATE_RES_SENT:
1116 	case NAN_NDP_STATE_CON_SENT:
1117 	case NAN_NDP_STATE_DONE:
1118 	default:
1119 		break;
1120 	}
1121 
1122 	return 0;
1123 }
1124 
1125 
1126 /*
1127  * nan_ndp_term_req - Handle local NDP termination request
1128  * @nan: NAN module context from nan_init()
1129  * @peer: The peer with whom the NDP is being setup
1130  * @ndp_id: NDP identifier
1131  * Returns: 0 on success, -1 on failure
1132  */
nan_ndp_term_req(struct nan_data * nan,struct nan_peer * peer,struct nan_ndp_id * ndp_id)1133 int nan_ndp_term_req(struct nan_data *nan, struct nan_peer *peer,
1134 		     struct nan_ndp_id *ndp_id)
1135 {
1136 	struct nan_ndp_setup *ndp_setup = &peer->ndp_setup;
1137 	struct nan_ndp *pndp;
1138 
1139 	wpa_printf(MSG_DEBUG,
1140 		   "NAN: NDP: Terminate request with peer=" MACSTR
1141 		   " ndp_id=%u, init_ndi=" MACSTR,
1142 		   MAC2STR(peer->nmi_addr), ndp_id->id,
1143 		   MAC2STR(ndp_id->init_ndi));
1144 
1145 	if (ndp_setup->ndp) {
1146 		if (ndp_setup->ndp->ndp_id == ndp_id->id &&
1147 		    ether_addr_equal(ndp_setup->ndp->init_ndi,
1148 				     ndp_id->init_ndi)) {
1149 			wpa_printf(MSG_DEBUG,
1150 				   "NAN: NDP: WIP with peer. Terminate");
1151 
1152 			nan_ndp_set_state(nan, &peer->ndp_setup,
1153 					  NAN_NDP_STATE_DONE);
1154 			ndp_setup->status = NAN_NDP_STATUS_REJECTED;
1155 			ndp_setup->reason = NAN_REASON_UNSPECIFIED_REASON;
1156 			return 0;
1157 		}
1158 
1159 		wpa_printf(MSG_DEBUG,
1160 			   "NAN: NDP: Cannot terminate NDP while NDP establishment is WIP");
1161 		return -1;
1162 	}
1163 
1164 	/* Find the NDP in the list of active NDPs */
1165 	pndp = nan_ndp_find_ndp(peer, ndp_id->id, ndp_id->init_ndi);
1166 	if (!pndp) {
1167 		wpa_printf(MSG_DEBUG,
1168 			   "NAN: NDP: Termination request for unknown NDP");
1169 		return -1;
1170 	}
1171 
1172 	/* Remove the NDP from the list and setup data for the termination */
1173 	dl_list_del(&pndp->list);
1174 
1175 	peer->ndp_setup.ndp = pndp;
1176 	peer->ndp_setup.status = NAN_NDP_STATUS_REJECTED;
1177 	peer->ndp_setup.reason = NAN_REASON_UNSPECIFIED_REASON;
1178 	return 0;
1179 }
1180 
1181 
1182 /**
1183  * nan_ndp_requested_gtk_csid - Get the GTK CSID requested by peer for NDP setup
1184  * @nan: NAN module context from nan_init()
1185  * @ndp_id: NDP identifier
1186  * Returns: The GTK CSID requested by peer, or NAN_CS_NONE if no matching NDP is
1187  *	found or GTK is not requested by peer.
1188  */
nan_ndp_requested_gtk_csid(struct nan_data * nan,const struct nan_ndp_id * ndp_id)1189 int nan_ndp_requested_gtk_csid(struct nan_data *nan,
1190 			       const struct nan_ndp_id *ndp_id)
1191 {
1192 	struct nan_peer *peer;
1193 
1194 	peer = nan_get_peer(nan, ndp_id->peer_nmi);
1195 	if (!peer) {
1196 		wpa_printf(MSG_DEBUG,
1197 			   "NAN: NDP: No matching peer found for GTK CSID request");
1198 		return NAN_CS_NONE;
1199 	}
1200 
1201 	if (!peer->ndp_setup.ndp ||
1202 	    peer->ndp_setup.ndp->ndp_id != ndp_id->id ||
1203 	    !ether_addr_equal(peer->ndp_setup.ndp->init_ndi,
1204 			      ndp_id->init_ndi)) {
1205 		wpa_printf(MSG_DEBUG,
1206 			   "NAN: NDP: No matching NDP found for GTK CSID request");
1207 		return NAN_CS_NONE;
1208 	}
1209 
1210 	if (peer->ndp_setup.state != NAN_NDP_STATE_REQ_RECV)
1211 		return NAN_CS_NONE;
1212 
1213 	return peer->ndp_setup.sec.peer_gtk.csid;
1214 }
1215