xref: /aosp_15_r20/external/wpa_supplicant_8/wpa_supplicant/bss.c (revision 03f9172ca588f91df233974f4258bab95191f931)
1 /*
2  * BSS table
3  * Copyright (c) 2009-2019, Jouni Malinen <[email protected]>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "utils/includes.h"
10 
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "common/ieee802_11_defs.h"
14 #include "drivers/driver.h"
15 #include "eap_peer/eap.h"
16 #include "rsn_supp/wpa.h"
17 #include "wpa_supplicant_i.h"
18 #include "config.h"
19 #include "notify.h"
20 #include "scan.h"
21 #include "bssid_ignore.h"
22 #include "bss.h"
23 
wpa_bss_set_hessid(struct wpa_bss * bss)24 static void wpa_bss_set_hessid(struct wpa_bss *bss)
25 {
26 #ifdef CONFIG_INTERWORKING
27 	const u8 *ie = wpa_bss_get_ie(bss, WLAN_EID_INTERWORKING);
28 	if (ie == NULL || (ie[1] != 7 && ie[1] != 9)) {
29 		os_memset(bss->hessid, 0, ETH_ALEN);
30 		return;
31 	}
32 	if (ie[1] == 7)
33 		os_memcpy(bss->hessid, ie + 3, ETH_ALEN);
34 	else
35 		os_memcpy(bss->hessid, ie + 5, ETH_ALEN);
36 #endif /* CONFIG_INTERWORKING */
37 }
38 
39 
40 /**
41  * wpa_bss_anqp_alloc - Allocate ANQP data structure for a BSS entry
42  * Returns: Allocated ANQP data structure or %NULL on failure
43  *
44  * The allocated ANQP data structure has its users count set to 1. It may be
45  * shared by multiple BSS entries and each shared entry is freed with
46  * wpa_bss_anqp_free().
47  */
wpa_bss_anqp_alloc(void)48 struct wpa_bss_anqp * wpa_bss_anqp_alloc(void)
49 {
50 	struct wpa_bss_anqp *anqp;
51 	anqp = os_zalloc(sizeof(*anqp));
52 	if (anqp == NULL)
53 		return NULL;
54 #ifdef CONFIG_INTERWORKING
55 	dl_list_init(&anqp->anqp_elems);
56 #endif /* CONFIG_INTERWORKING */
57 	anqp->users = 1;
58 	return anqp;
59 }
60 
61 
62 /**
63  * wpa_bss_anqp_clone - Clone an ANQP data structure
64  * @anqp: ANQP data structure from wpa_bss_anqp_alloc()
65  * Returns: Cloned ANQP data structure or %NULL on failure
66  */
wpa_bss_anqp_clone(struct wpa_bss_anqp * anqp)67 static struct wpa_bss_anqp * wpa_bss_anqp_clone(struct wpa_bss_anqp *anqp)
68 {
69 	struct wpa_bss_anqp *n;
70 
71 	n = os_zalloc(sizeof(*n));
72 	if (n == NULL)
73 		return NULL;
74 
75 #define ANQP_DUP(f) if (anqp->f) n->f = wpabuf_dup(anqp->f)
76 #ifdef CONFIG_INTERWORKING
77 	dl_list_init(&n->anqp_elems);
78 	ANQP_DUP(capability_list);
79 	ANQP_DUP(venue_name);
80 	ANQP_DUP(network_auth_type);
81 	ANQP_DUP(roaming_consortium);
82 	ANQP_DUP(ip_addr_type_availability);
83 	ANQP_DUP(nai_realm);
84 	ANQP_DUP(anqp_3gpp);
85 	ANQP_DUP(domain_name);
86 	ANQP_DUP(fils_realm_info);
87 #endif /* CONFIG_INTERWORKING */
88 #ifdef CONFIG_HS20
89 	ANQP_DUP(hs20_capability_list);
90 	ANQP_DUP(hs20_operator_friendly_name);
91 	ANQP_DUP(hs20_wan_metrics);
92 	ANQP_DUP(hs20_connection_capability);
93 	ANQP_DUP(hs20_operating_class);
94 	ANQP_DUP(hs20_osu_providers_list);
95 	ANQP_DUP(hs20_operator_icon_metadata);
96 	ANQP_DUP(hs20_osu_providers_nai_list);
97 #endif /* CONFIG_HS20 */
98 #undef ANQP_DUP
99 
100 	return n;
101 }
102 
103 
104 /**
105  * wpa_bss_anqp_unshare_alloc - Unshare ANQP data (if shared) in a BSS entry
106  * @bss: BSS entry
107  * Returns: 0 on success, -1 on failure
108  *
109  * This function ensures the specific BSS entry has an ANQP data structure that
110  * is not shared with any other BSS entry.
111  */
wpa_bss_anqp_unshare_alloc(struct wpa_bss * bss)112 int wpa_bss_anqp_unshare_alloc(struct wpa_bss *bss)
113 {
114 	struct wpa_bss_anqp *anqp;
115 
116 	if (bss->anqp && bss->anqp->users > 1) {
117 		/* allocated, but shared - clone an unshared copy */
118 		anqp = wpa_bss_anqp_clone(bss->anqp);
119 		if (anqp == NULL)
120 			return -1;
121 		anqp->users = 1;
122 		bss->anqp->users--;
123 		bss->anqp = anqp;
124 		return 0;
125 	}
126 
127 	if (bss->anqp)
128 		return 0; /* already allocated and not shared */
129 
130 	/* not allocated - allocate a new storage area */
131 	bss->anqp = wpa_bss_anqp_alloc();
132 	return bss->anqp ? 0 : -1;
133 }
134 
135 
136 /**
137  * wpa_bss_anqp_free - Free an ANQP data structure
138  * @anqp: ANQP data structure from wpa_bss_anqp_alloc() or wpa_bss_anqp_clone()
139  */
wpa_bss_anqp_free(struct wpa_bss_anqp * anqp)140 static void wpa_bss_anqp_free(struct wpa_bss_anqp *anqp)
141 {
142 #ifdef CONFIG_INTERWORKING
143 	struct wpa_bss_anqp_elem *elem;
144 #endif /* CONFIG_INTERWORKING */
145 
146 	if (anqp == NULL)
147 		return;
148 
149 	anqp->users--;
150 	if (anqp->users > 0) {
151 		/* Another BSS entry holds a pointer to this ANQP info */
152 		return;
153 	}
154 
155 #ifdef CONFIG_INTERWORKING
156 	wpabuf_free(anqp->capability_list);
157 	wpabuf_free(anqp->venue_name);
158 	wpabuf_free(anqp->network_auth_type);
159 	wpabuf_free(anqp->roaming_consortium);
160 	wpabuf_free(anqp->ip_addr_type_availability);
161 	wpabuf_free(anqp->nai_realm);
162 	wpabuf_free(anqp->anqp_3gpp);
163 	wpabuf_free(anqp->domain_name);
164 	wpabuf_free(anqp->fils_realm_info);
165 
166 	while ((elem = dl_list_first(&anqp->anqp_elems,
167 				     struct wpa_bss_anqp_elem, list))) {
168 		dl_list_del(&elem->list);
169 		wpabuf_free(elem->payload);
170 		os_free(elem);
171 	}
172 #endif /* CONFIG_INTERWORKING */
173 #ifdef CONFIG_HS20
174 	wpabuf_free(anqp->hs20_capability_list);
175 	wpabuf_free(anqp->hs20_operator_friendly_name);
176 	wpabuf_free(anqp->hs20_wan_metrics);
177 	wpabuf_free(anqp->hs20_connection_capability);
178 	wpabuf_free(anqp->hs20_operating_class);
179 	wpabuf_free(anqp->hs20_osu_providers_list);
180 	wpabuf_free(anqp->hs20_operator_icon_metadata);
181 	wpabuf_free(anqp->hs20_osu_providers_nai_list);
182 #endif /* CONFIG_HS20 */
183 
184 	os_free(anqp);
185 }
186 
187 
188 static struct wpa_connect_work *
wpa_bss_check_pending_connect(struct wpa_supplicant * wpa_s,struct wpa_bss * bss)189 wpa_bss_check_pending_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
190 {
191 	struct wpa_radio_work *work;
192 	struct wpa_connect_work *cwork;
193 
194 	work = radio_work_pending(wpa_s, "sme-connect");
195 	if (!work)
196 		work = radio_work_pending(wpa_s, "connect");
197 	if (!work)
198 		return NULL;
199 
200 	cwork = work->ctx;
201 	if (cwork->bss != bss)
202 		return NULL;
203 
204 	return cwork;
205 }
206 
207 
wpa_bss_update_pending_connect(struct wpa_connect_work * cwork,struct wpa_bss * new_bss)208 static void wpa_bss_update_pending_connect(struct wpa_connect_work *cwork,
209 					   struct wpa_bss *new_bss)
210 {
211 	wpa_printf(MSG_DEBUG,
212 		   "Update BSS pointer for the pending connect radio work");
213 	cwork->bss = new_bss;
214 	if (!new_bss)
215 		cwork->bss_removed = 1;
216 }
217 
218 
wpa_bss_remove(struct wpa_supplicant * wpa_s,struct wpa_bss * bss,const char * reason)219 void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
220 		    const char *reason)
221 {
222 	struct wpa_connect_work *cwork;
223 
224 	if (wpa_s->last_scan_res) {
225 		unsigned int i;
226 		for (i = 0; i < wpa_s->last_scan_res_used; i++) {
227 			if (wpa_s->last_scan_res[i] == bss) {
228 				os_memmove(&wpa_s->last_scan_res[i],
229 					   &wpa_s->last_scan_res[i + 1],
230 					   (wpa_s->last_scan_res_used - i - 1)
231 					   * sizeof(struct wpa_bss *));
232 				wpa_s->last_scan_res_used--;
233 				break;
234 			}
235 		}
236 	}
237 	cwork = wpa_bss_check_pending_connect(wpa_s, bss);
238 	if (cwork)
239 		wpa_bss_update_pending_connect(cwork, NULL);
240 	dl_list_del(&bss->list);
241 	dl_list_del(&bss->list_id);
242 	wpa_s->num_bss--;
243 	wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Remove id %u BSSID " MACSTR
244 		" SSID '%s' due to %s", bss->id, MAC2STR(bss->bssid),
245 		wpa_ssid_txt(bss->ssid, bss->ssid_len), reason);
246 	wpas_notify_bss_removed(wpa_s, bss->bssid, bss->id);
247 	wpa_bss_anqp_free(bss->anqp);
248 	os_free(bss);
249 }
250 
251 
252 /**
253  * wpa_bss_get - Fetch a BSS table entry based on BSSID and SSID
254  * @wpa_s: Pointer to wpa_supplicant data
255  * @bssid: BSSID, or %NULL to match any BSSID
256  * @ssid: SSID
257  * @ssid_len: Length of @ssid
258  * Returns: Pointer to the BSS entry or %NULL if not found
259  */
wpa_bss_get(struct wpa_supplicant * wpa_s,const u8 * bssid,const u8 * ssid,size_t ssid_len)260 struct wpa_bss * wpa_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid,
261 			     const u8 *ssid, size_t ssid_len)
262 {
263 	struct wpa_bss *bss;
264 
265 	if (bssid && !wpa_supplicant_filter_bssid_match(wpa_s, bssid))
266 		return NULL;
267 	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
268 		if ((!bssid || ether_addr_equal(bss->bssid, bssid)) &&
269 		    bss->ssid_len == ssid_len &&
270 		    os_memcmp(bss->ssid, ssid, ssid_len) == 0)
271 			return bss;
272 	}
273 	return NULL;
274 }
275 
276 /**
277  * wpa_bss_get_connection - Fetch a BSS table entry based on BSSID and SSID.
278  * @wpa_s: Pointer to wpa_supplicant data
279  * @bssid: BSSID, or %NULL to match any BSSID
280  * @ssid: SSID
281  * @ssid_len: Length of @ssid
282  * Returns: Pointer to the BSS entry or %NULL if not found
283  *
284  * This function is similar to wpa_bss_get() but it will also return OWE
285  * transition mode encrypted networks for which transition-element matches
286  * @ssid.
287  */
wpa_bss_get_connection(struct wpa_supplicant * wpa_s,const u8 * bssid,const u8 * ssid,size_t ssid_len)288 struct wpa_bss * wpa_bss_get_connection(struct wpa_supplicant *wpa_s,
289 					const u8 *bssid,
290 					const u8 *ssid, size_t ssid_len)
291 {
292 	struct wpa_bss *bss;
293 #ifdef CONFIG_OWE
294 	const u8 *owe, *owe_bssid, *owe_ssid;
295 	size_t owe_ssid_len;
296 #endif /* CONFIG_OWE */
297 
298 	if (bssid && !wpa_supplicant_filter_bssid_match(wpa_s, bssid))
299 		return NULL;
300 	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
301 		if (bssid && !ether_addr_equal(bss->bssid, bssid))
302 			continue;
303 
304 		if (bss->ssid_len == ssid_len &&
305 		    os_memcmp(bss->ssid, ssid, ssid_len) == 0)
306 			return bss;
307 
308 #ifdef CONFIG_OWE
309 		/* Check if OWE transition mode element is present and matches
310 		 * the SSID */
311 		owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
312 		if (!owe)
313 			continue;
314 
315 		if (wpas_get_owe_trans_network(owe, &owe_bssid, &owe_ssid,
316 					       &owe_ssid_len))
317 			continue;
318 
319 		if (owe_ssid_len == ssid_len &&
320 		    os_memcmp(owe_ssid, ssid, ssid_len) == 0)
321 			return bss;
322 #endif /* CONFIG_OWE */
323 	}
324 	return NULL;
325 }
326 
327 
calculate_update_time(const struct os_reltime * fetch_time,unsigned int age_ms,struct os_reltime * update_time)328 void calculate_update_time(const struct os_reltime *fetch_time,
329 			   unsigned int age_ms,
330 			   struct os_reltime *update_time)
331 {
332 	os_time_t usec;
333 
334 	update_time->sec = fetch_time->sec;
335 	update_time->usec = fetch_time->usec;
336 	update_time->sec -= age_ms / 1000;
337 	usec = (age_ms % 1000) * 1000;
338 	if (update_time->usec < usec) {
339 		update_time->sec--;
340 		update_time->usec += 1000000;
341 	}
342 	update_time->usec -= usec;
343 }
344 
345 
wpa_bss_copy_res(struct wpa_bss * dst,struct wpa_scan_res * src,struct os_reltime * fetch_time)346 static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src,
347 			     struct os_reltime *fetch_time)
348 {
349 	dst->flags = src->flags;
350 	os_memcpy(dst->bssid, src->bssid, ETH_ALEN);
351 	dst->freq = src->freq;
352 	dst->max_cw = src->max_cw;
353 	dst->beacon_int = src->beacon_int;
354 	dst->caps = src->caps;
355 	dst->qual = src->qual;
356 	dst->noise = src->noise;
357 	dst->level = src->level;
358 	dst->tsf = src->tsf;
359 	dst->beacon_newer = src->beacon_newer;
360 	dst->est_throughput = src->est_throughput;
361 	dst->snr = src->snr;
362 
363 	calculate_update_time(fetch_time, src->age, &dst->last_update);
364 }
365 
366 
wpa_bss_is_wps_candidate(struct wpa_supplicant * wpa_s,struct wpa_bss * bss)367 static int wpa_bss_is_wps_candidate(struct wpa_supplicant *wpa_s,
368 				    struct wpa_bss *bss)
369 {
370 #ifdef CONFIG_WPS
371 	struct wpa_ssid *ssid;
372 	struct wpabuf *wps_ie;
373 	int pbc = 0, ret;
374 
375 	wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
376 	if (!wps_ie)
377 		return 0;
378 
379 	if (wps_is_selected_pbc_registrar(wps_ie)) {
380 		pbc = 1;
381 	} else if (!wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1)) {
382 		wpabuf_free(wps_ie);
383 		return 0;
384 	}
385 
386 	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
387 		if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
388 			continue;
389 		if (ssid->ssid_len &&
390 		    (ssid->ssid_len != bss->ssid_len ||
391 		     os_memcmp(ssid->ssid, bss->ssid, ssid->ssid_len) != 0))
392 			continue;
393 
394 		if (pbc)
395 			ret = eap_is_wps_pbc_enrollee(&ssid->eap);
396 		else
397 			ret = eap_is_wps_pin_enrollee(&ssid->eap);
398 		wpabuf_free(wps_ie);
399 		return ret;
400 	}
401 	wpabuf_free(wps_ie);
402 #endif /* CONFIG_WPS */
403 
404 	return 0;
405 }
406 
407 
is_p2p_pending_bss(struct wpa_supplicant * wpa_s,struct wpa_bss * bss)408 static bool is_p2p_pending_bss(struct wpa_supplicant *wpa_s,
409 			       struct wpa_bss *bss)
410 {
411 #ifdef CONFIG_P2P
412 	u8 addr[ETH_ALEN];
413 
414 	if (ether_addr_equal(bss->bssid, wpa_s->pending_join_iface_addr))
415 		return true;
416 	if (!is_zero_ether_addr(wpa_s->pending_join_dev_addr) &&
417 	    p2p_parse_dev_addr(wpa_bss_ie_ptr(bss), bss->ie_len, addr) == 0 &&
418 	    ether_addr_equal(addr, wpa_s->pending_join_dev_addr))
419 		return true;
420 #endif /* CONFIG_P2P */
421 	return false;
422 }
423 
424 
wpa_bss_known(struct wpa_supplicant * wpa_s,struct wpa_bss * bss)425 static int wpa_bss_known(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
426 {
427 	struct wpa_ssid *ssid;
428 
429 	if (is_p2p_pending_bss(wpa_s, bss))
430 		return 1;
431 
432 	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
433 		if (ssid->ssid == NULL || ssid->ssid_len == 0)
434 			continue;
435 		if (ssid->ssid_len == bss->ssid_len &&
436 		    os_memcmp(ssid->ssid, bss->ssid, ssid->ssid_len) == 0)
437 			return 1;
438 	}
439 
440 	return 0;
441 }
442 
443 
wpa_bss_in_use(struct wpa_supplicant * wpa_s,struct wpa_bss * bss)444 static int wpa_bss_in_use(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
445 {
446 	int i;
447 
448 	if (bss == wpa_s->current_bss)
449 		return 1;
450 
451 	if (bss == wpa_s->ml_connect_probe_bss)
452 		return 1;
453 
454 #ifdef CONFIG_WNM
455 	if (bss == wpa_s->wnm_target_bss)
456 		return 1;
457 #endif /* CONFIG_WNM */
458 
459 	if (wpa_s->current_bss &&
460 	    (bss->ssid_len != wpa_s->current_bss->ssid_len ||
461 	     os_memcmp(bss->ssid, wpa_s->current_bss->ssid,
462 		       bss->ssid_len) != 0))
463 		return 0; /* SSID has changed */
464 
465 	if (!is_zero_ether_addr(bss->bssid) &&
466 	    (ether_addr_equal(bss->bssid, wpa_s->bssid) ||
467 	     ether_addr_equal(bss->bssid, wpa_s->pending_bssid)))
468 		return 1;
469 
470 	if (!wpa_s->valid_links)
471 		return 0;
472 
473 	for_each_link(wpa_s->valid_links, i) {
474 		if (ether_addr_equal(bss->bssid, wpa_s->links[i].bssid))
475 			return 1;
476 	}
477 
478 	return 0;
479 }
480 
481 
wpa_bss_remove_oldest_unknown(struct wpa_supplicant * wpa_s)482 static int wpa_bss_remove_oldest_unknown(struct wpa_supplicant *wpa_s)
483 {
484 	struct wpa_bss *bss;
485 
486 	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
487 		if (!wpa_bss_known(wpa_s, bss) &&
488 		    !wpa_bss_is_wps_candidate(wpa_s, bss)) {
489 			wpa_bss_remove(wpa_s, bss, __func__);
490 			return 0;
491 		}
492 	}
493 
494 	return -1;
495 }
496 
497 
wpa_bss_remove_oldest(struct wpa_supplicant * wpa_s)498 static int wpa_bss_remove_oldest(struct wpa_supplicant *wpa_s)
499 {
500 	struct wpa_bss *bss;
501 
502 	/*
503 	 * Remove the oldest entry that does not match with any configured
504 	 * network.
505 	 */
506 	if (wpa_bss_remove_oldest_unknown(wpa_s) == 0)
507 		return 0;
508 
509 	/*
510 	 * Remove the oldest entry that isn't currently in use.
511 	 */
512 	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
513 		if (!wpa_bss_in_use(wpa_s, bss)) {
514 			wpa_bss_remove(wpa_s, bss, __func__);
515 			return 0;
516 		}
517 	}
518 
519 	return -1;
520 }
521 
522 
wpa_bss_add(struct wpa_supplicant * wpa_s,const u8 * ssid,size_t ssid_len,struct wpa_scan_res * res,struct os_reltime * fetch_time)523 static struct wpa_bss * wpa_bss_add(struct wpa_supplicant *wpa_s,
524 				    const u8 *ssid, size_t ssid_len,
525 				    struct wpa_scan_res *res,
526 				    struct os_reltime *fetch_time)
527 {
528 	struct wpa_bss *bss;
529 	char extra[100];
530 	const u8 *ml_ie;
531 	char *pos, *end;
532 	int ret = 0;
533 	const u8 *mld_addr;
534 
535 	bss = os_zalloc(sizeof(*bss) + res->ie_len + res->beacon_ie_len);
536 	if (bss == NULL)
537 		return NULL;
538 	bss->id = wpa_s->bss_next_id++;
539 	bss->last_update_idx = wpa_s->bss_update_idx;
540 	wpa_bss_copy_res(bss, res, fetch_time);
541 	os_memcpy(bss->ssid, ssid, ssid_len);
542 	bss->ssid_len = ssid_len;
543 	bss->ie_len = res->ie_len;
544 	bss->beacon_ie_len = res->beacon_ie_len;
545 	os_memcpy(bss->ies, res + 1, res->ie_len + res->beacon_ie_len);
546 	wpa_bss_set_hessid(bss);
547 
548 	os_memset(bss->mld_addr, 0, ETH_ALEN);
549 	ml_ie = wpa_scan_get_ml_ie(res, MULTI_LINK_CONTROL_TYPE_BASIC);
550 	if (ml_ie) {
551 		mld_addr = get_basic_mle_mld_addr(&ml_ie[3], ml_ie[1] - 1);
552 		if (mld_addr)
553 			os_memcpy(bss->mld_addr, mld_addr, ETH_ALEN);
554 	}
555 
556 	if (wpa_s->num_bss + 1 > wpa_s->conf->bss_max_count &&
557 	    wpa_bss_remove_oldest(wpa_s) != 0) {
558 		wpa_printf(MSG_ERROR, "Increasing the MAX BSS count to %d "
559 			   "because all BSSes are in use. We should normally "
560 			   "not get here!", (int) wpa_s->num_bss + 1);
561 		wpa_s->conf->bss_max_count = wpa_s->num_bss + 1;
562 	}
563 
564 	dl_list_add_tail(&wpa_s->bss, &bss->list);
565 	dl_list_add_tail(&wpa_s->bss_id, &bss->list_id);
566 	wpa_s->num_bss++;
567 
568 	extra[0] = '\0';
569 	pos = extra;
570 	end = pos + sizeof(extra);
571 	if (!is_zero_ether_addr(bss->hessid))
572 		ret = os_snprintf(pos, end - pos, " HESSID " MACSTR,
573 				  MAC2STR(bss->hessid));
574 
575 	if (!is_zero_ether_addr(bss->mld_addr) &&
576 	    !os_snprintf_error(end - pos, ret)) {
577 		pos += ret;
578 		ret = os_snprintf(pos, end - pos, " MLD ADDR " MACSTR,
579 				  MAC2STR(bss->mld_addr));
580 	}
581 
582 	wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Add new id %u BSSID " MACSTR
583 		" SSID '%s' freq %d%s",
584 		bss->id, MAC2STR(bss->bssid), wpa_ssid_txt(ssid, ssid_len),
585 		bss->freq, extra);
586 	wpas_notify_bss_added(wpa_s, bss->bssid, bss->id);
587 	return bss;
588 }
589 
590 
are_ies_equal(const struct wpa_bss * old,const struct wpa_scan_res * new_res,u32 ie)591 static int are_ies_equal(const struct wpa_bss *old,
592 			 const struct wpa_scan_res *new_res, u32 ie)
593 {
594 	const u8 *old_ie, *new_ie;
595 	struct wpabuf *old_ie_buff = NULL;
596 	struct wpabuf *new_ie_buff = NULL;
597 	int new_ie_len, old_ie_len, ret, is_multi;
598 
599 	switch (ie) {
600 	case WPA_IE_VENDOR_TYPE:
601 		old_ie = wpa_bss_get_vendor_ie(old, ie);
602 		new_ie = wpa_scan_get_vendor_ie(new_res, ie);
603 		is_multi = 0;
604 		break;
605 	case WPS_IE_VENDOR_TYPE:
606 		old_ie_buff = wpa_bss_get_vendor_ie_multi(old, ie);
607 		new_ie_buff = wpa_scan_get_vendor_ie_multi(new_res, ie);
608 		is_multi = 1;
609 		break;
610 	case WLAN_EID_RSN:
611 	case WLAN_EID_SUPP_RATES:
612 	case WLAN_EID_EXT_SUPP_RATES:
613 		old_ie = wpa_bss_get_ie(old, ie);
614 		new_ie = wpa_scan_get_ie(new_res, ie);
615 		is_multi = 0;
616 		break;
617 	default:
618 		wpa_printf(MSG_DEBUG, "bss: %s: cannot compare IEs", __func__);
619 		return 0;
620 	}
621 
622 	if (is_multi) {
623 		/* in case of multiple IEs stored in buffer */
624 		old_ie = old_ie_buff ? wpabuf_head_u8(old_ie_buff) : NULL;
625 		new_ie = new_ie_buff ? wpabuf_head_u8(new_ie_buff) : NULL;
626 		old_ie_len = old_ie_buff ? wpabuf_len(old_ie_buff) : 0;
627 		new_ie_len = new_ie_buff ? wpabuf_len(new_ie_buff) : 0;
628 	} else {
629 		/* in case of single IE */
630 		old_ie_len = old_ie ? old_ie[1] + 2 : 0;
631 		new_ie_len = new_ie ? new_ie[1] + 2 : 0;
632 	}
633 
634 	if (!old_ie || !new_ie)
635 		ret = !old_ie && !new_ie;
636 	else
637 		ret = (old_ie_len == new_ie_len &&
638 		       os_memcmp(old_ie, new_ie, old_ie_len) == 0);
639 
640 	wpabuf_free(old_ie_buff);
641 	wpabuf_free(new_ie_buff);
642 
643 	return ret;
644 }
645 
646 
wpa_bss_compare_res(const struct wpa_bss * old,const struct wpa_scan_res * new_res)647 static u32 wpa_bss_compare_res(const struct wpa_bss *old,
648 			       const struct wpa_scan_res *new_res)
649 {
650 	u32 changes = 0;
651 	int caps_diff = old->caps ^ new_res->caps;
652 
653 	if (old->freq != new_res->freq)
654 		changes |= WPA_BSS_FREQ_CHANGED_FLAG;
655 
656 	if (old->level != new_res->level)
657 		changes |= WPA_BSS_SIGNAL_CHANGED_FLAG;
658 
659 	if (caps_diff & IEEE80211_CAP_PRIVACY)
660 		changes |= WPA_BSS_PRIVACY_CHANGED_FLAG;
661 
662 	if (caps_diff & IEEE80211_CAP_IBSS)
663 		changes |= WPA_BSS_MODE_CHANGED_FLAG;
664 
665 	if (old->ie_len == new_res->ie_len &&
666 	    os_memcmp(wpa_bss_ie_ptr(old), new_res + 1, old->ie_len) == 0)
667 		return changes;
668 	changes |= WPA_BSS_IES_CHANGED_FLAG;
669 
670 	if (!are_ies_equal(old, new_res, WPA_IE_VENDOR_TYPE))
671 		changes |= WPA_BSS_WPAIE_CHANGED_FLAG;
672 
673 	if (!are_ies_equal(old, new_res, WLAN_EID_RSN))
674 		changes |= WPA_BSS_RSNIE_CHANGED_FLAG;
675 
676 	if (!are_ies_equal(old, new_res, WPS_IE_VENDOR_TYPE))
677 		changes |= WPA_BSS_WPS_CHANGED_FLAG;
678 
679 	if (!are_ies_equal(old, new_res, WLAN_EID_SUPP_RATES) ||
680 	    !are_ies_equal(old, new_res, WLAN_EID_EXT_SUPP_RATES))
681 		changes |= WPA_BSS_RATES_CHANGED_FLAG;
682 
683 	return changes;
684 }
685 
686 
notify_bss_changes(struct wpa_supplicant * wpa_s,u32 changes,const struct wpa_bss * bss)687 void notify_bss_changes(struct wpa_supplicant *wpa_s, u32 changes,
688 			const struct wpa_bss *bss)
689 {
690 	if (changes & WPA_BSS_FREQ_CHANGED_FLAG)
691 		wpas_notify_bss_freq_changed(wpa_s, bss->id);
692 
693 	if (changes & WPA_BSS_SIGNAL_CHANGED_FLAG)
694 		wpas_notify_bss_signal_changed(wpa_s, bss->id);
695 
696 	if (changes & WPA_BSS_PRIVACY_CHANGED_FLAG)
697 		wpas_notify_bss_privacy_changed(wpa_s, bss->id);
698 
699 	if (changes & WPA_BSS_MODE_CHANGED_FLAG)
700 		wpas_notify_bss_mode_changed(wpa_s, bss->id);
701 
702 	if (changes & WPA_BSS_WPAIE_CHANGED_FLAG)
703 		wpas_notify_bss_wpaie_changed(wpa_s, bss->id);
704 
705 	if (changes & WPA_BSS_RSNIE_CHANGED_FLAG)
706 		wpas_notify_bss_rsnie_changed(wpa_s, bss->id);
707 
708 	if (changes & WPA_BSS_WPS_CHANGED_FLAG)
709 		wpas_notify_bss_wps_changed(wpa_s, bss->id);
710 
711 	if (changes & WPA_BSS_IES_CHANGED_FLAG)
712 		wpas_notify_bss_ies_changed(wpa_s, bss->id);
713 
714 	if (changes & WPA_BSS_RATES_CHANGED_FLAG)
715 		wpas_notify_bss_rates_changed(wpa_s, bss->id);
716 
717 	wpas_notify_bss_seen(wpa_s, bss->id);
718 }
719 
720 
721 static struct wpa_bss *
wpa_bss_update(struct wpa_supplicant * wpa_s,struct wpa_bss * bss,struct wpa_scan_res * res,struct os_reltime * fetch_time)722 wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
723 	       struct wpa_scan_res *res, struct os_reltime *fetch_time)
724 {
725 	u32 changes;
726 
727 	if (bss->last_update_idx == wpa_s->bss_update_idx) {
728 		struct os_reltime update_time;
729 
730 		/*
731 		 * Some drivers (e.g., cfg80211) include multiple BSS entries
732 		 * for the same BSS if that BSS's channel changes. The BSS list
733 		 * implementation in wpa_supplicant does not do that and we need
734 		 * to filter out the obsolete results here to make sure only the
735 		 * most current BSS information remains in the table.
736 		 */
737 		wpa_printf(MSG_DEBUG, "BSS: " MACSTR
738 			   " has multiple entries in the scan results - select the most current one",
739 			   MAC2STR(bss->bssid));
740 		calculate_update_time(fetch_time, res->age, &update_time);
741 		wpa_printf(MSG_DEBUG,
742 			   "Previous last_update: %u.%06u (freq %d%s)",
743 			   (unsigned int) bss->last_update.sec,
744 			   (unsigned int) bss->last_update.usec,
745 			   bss->freq,
746 			   (bss->flags & WPA_BSS_ASSOCIATED) ? " assoc" : "");
747 		wpa_printf(MSG_DEBUG, "New last_update: %u.%06u (freq %d%s)",
748 			   (unsigned int) update_time.sec,
749 			   (unsigned int) update_time.usec,
750 			   res->freq,
751 			   (res->flags & WPA_SCAN_ASSOCIATED) ? " assoc" : "");
752 		if ((bss->flags & WPA_BSS_ASSOCIATED) ||
753 		    (!(res->flags & WPA_SCAN_ASSOCIATED) &&
754 		     !os_reltime_before(&bss->last_update, &update_time))) {
755 			wpa_printf(MSG_DEBUG,
756 				   "Ignore this BSS entry since the previous update looks more current");
757 			return bss;
758 		}
759 		wpa_printf(MSG_DEBUG,
760 			   "Accept this BSS entry since it looks more current than the previous update");
761 	}
762 
763 	changes = wpa_bss_compare_res(bss, res);
764 	if (changes & WPA_BSS_FREQ_CHANGED_FLAG)
765 		wpa_printf(MSG_DEBUG, "BSS: " MACSTR " changed freq %d --> %d",
766 			   MAC2STR(bss->bssid), bss->freq, res->freq);
767 	bss->scan_miss_count = 0;
768 	bss->last_update_idx = wpa_s->bss_update_idx;
769 	wpa_bss_copy_res(bss, res, fetch_time);
770 	/* Move the entry to the end of the list */
771 	dl_list_del(&bss->list);
772 #ifdef CONFIG_P2P
773 	if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) &&
774 	    !wpa_scan_get_vendor_ie(res, P2P_IE_VENDOR_TYPE) &&
775 	    !(changes & WPA_BSS_FREQ_CHANGED_FLAG)) {
776 		/*
777 		 * This can happen when non-P2P station interface runs a scan
778 		 * without P2P IE in the Probe Request frame. P2P GO would reply
779 		 * to that with a Probe Response that does not include P2P IE.
780 		 * Do not update the IEs in this BSS entry to avoid such loss of
781 		 * information that may be needed for P2P operations to
782 		 * determine group information.
783 		 */
784 		wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Do not update scan IEs for "
785 			MACSTR " since that would remove P2P IE information",
786 			MAC2STR(bss->bssid));
787 	} else
788 #endif /* CONFIG_P2P */
789 	if (bss->ie_len + bss->beacon_ie_len >=
790 	    res->ie_len + res->beacon_ie_len) {
791 		os_memcpy(bss->ies, res + 1, res->ie_len + res->beacon_ie_len);
792 		bss->ie_len = res->ie_len;
793 		bss->beacon_ie_len = res->beacon_ie_len;
794 	} else {
795 		struct wpa_bss *nbss;
796 		struct dl_list *prev = bss->list_id.prev;
797 		struct wpa_connect_work *cwork;
798 		unsigned int i;
799 		bool update_current_bss = wpa_s->current_bss == bss;
800 		bool update_ml_probe_bss = wpa_s->ml_connect_probe_bss == bss;
801 
802 		cwork = wpa_bss_check_pending_connect(wpa_s, bss);
803 
804 		for (i = 0; i < wpa_s->last_scan_res_used; i++) {
805 			if (wpa_s->last_scan_res[i] == bss)
806 				break;
807 		}
808 
809 		dl_list_del(&bss->list_id);
810 		nbss = os_realloc(bss, sizeof(*bss) + res->ie_len +
811 				  res->beacon_ie_len);
812 		if (nbss) {
813 			if (i != wpa_s->last_scan_res_used)
814 				wpa_s->last_scan_res[i] = nbss;
815 
816 			if (update_current_bss)
817 				wpa_s->current_bss = nbss;
818 
819 			if (update_ml_probe_bss)
820 				wpa_s->ml_connect_probe_bss = nbss;
821 
822 			if (cwork)
823 				wpa_bss_update_pending_connect(cwork, nbss);
824 
825 			bss = nbss;
826 			os_memcpy(bss->ies, res + 1,
827 				  res->ie_len + res->beacon_ie_len);
828 			bss->ie_len = res->ie_len;
829 			bss->beacon_ie_len = res->beacon_ie_len;
830 		}
831 		dl_list_add(prev, &bss->list_id);
832 	}
833 	if (changes & WPA_BSS_IES_CHANGED_FLAG) {
834 		const u8 *ml_ie, *mld_addr;
835 
836 		wpa_bss_set_hessid(bss);
837 		os_memset(bss->mld_addr, 0, ETH_ALEN);
838 		ml_ie = wpa_scan_get_ml_ie(res, MULTI_LINK_CONTROL_TYPE_BASIC);
839 		if (ml_ie) {
840 			mld_addr = get_basic_mle_mld_addr(&ml_ie[3],
841 							  ml_ie[1] - 1);
842 			if (mld_addr)
843 				os_memcpy(bss->mld_addr, mld_addr, ETH_ALEN);
844 		}
845 	}
846 	dl_list_add_tail(&wpa_s->bss, &bss->list);
847 
848 	notify_bss_changes(wpa_s, changes, bss);
849 
850 	return bss;
851 }
852 
853 
854 /**
855  * wpa_bss_update_start - Start a BSS table update from scan results
856  * @wpa_s: Pointer to wpa_supplicant data
857  *
858  * This function is called at the start of each BSS table update round for new
859  * scan results. The actual scan result entries are indicated with calls to
860  * wpa_bss_update_scan_res() and the update round is finished with a call to
861  * wpa_bss_update_end().
862  */
wpa_bss_update_start(struct wpa_supplicant * wpa_s)863 void wpa_bss_update_start(struct wpa_supplicant *wpa_s)
864 {
865 	wpa_s->bss_update_idx++;
866 	wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Start scan result update %u",
867 		wpa_s->bss_update_idx);
868 	wpa_s->last_scan_res_used = 0;
869 }
870 
871 
872 /**
873  * wpa_bss_update_scan_res - Update a BSS table entry based on a scan result
874  * @wpa_s: Pointer to wpa_supplicant data
875  * @res: Scan result
876  * @fetch_time: Time when the result was fetched from the driver
877  *
878  * This function updates a BSS table entry (or adds one) based on a scan result.
879  * This is called separately for each scan result between the calls to
880  * wpa_bss_update_start() and wpa_bss_update_end().
881  */
wpa_bss_update_scan_res(struct wpa_supplicant * wpa_s,struct wpa_scan_res * res,struct os_reltime * fetch_time)882 void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s,
883 			     struct wpa_scan_res *res,
884 			     struct os_reltime *fetch_time)
885 {
886 	const u8 *ssid, *p2p, *mesh;
887 	struct wpa_bss *bss;
888 
889 	if (wpa_s->conf->ignore_old_scan_res) {
890 		struct os_reltime update;
891 		calculate_update_time(fetch_time, res->age, &update);
892 		if (os_reltime_before(&update, &wpa_s->scan_trigger_time)) {
893 			struct os_reltime age;
894 			os_reltime_sub(&wpa_s->scan_trigger_time, &update,
895 				       &age);
896 			wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Ignore driver BSS "
897 				"table entry that is %u.%06u seconds older "
898 				"than our scan trigger",
899 				(unsigned int) age.sec,
900 				(unsigned int) age.usec);
901 			return;
902 		}
903 	}
904 
905 	ssid = wpa_scan_get_ie(res, WLAN_EID_SSID);
906 	if (ssid == NULL) {
907 		wpa_dbg(wpa_s, MSG_DEBUG, "BSS: No SSID IE included for "
908 			MACSTR, MAC2STR(res->bssid));
909 		return;
910 	}
911 	if (ssid[1] > SSID_MAX_LEN) {
912 		wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Too long SSID IE included for "
913 			MACSTR, MAC2STR(res->bssid));
914 		return;
915 	}
916 
917 	p2p = wpa_scan_get_vendor_ie(res, P2P_IE_VENDOR_TYPE);
918 #ifdef CONFIG_P2P
919 	if (p2p == NULL &&
920 	    wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) {
921 		/*
922 		 * If it's a P2P specific interface, then don't update
923 		 * the scan result without a P2P IE.
924 		 */
925 		wpa_printf(MSG_DEBUG, "BSS: No P2P IE - skipping BSS " MACSTR
926 			   " update for P2P interface", MAC2STR(res->bssid));
927 		return;
928 	}
929 #endif /* CONFIG_P2P */
930 	if (p2p && ssid[1] == P2P_WILDCARD_SSID_LEN &&
931 	    os_memcmp(ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) == 0)
932 		return; /* Skip P2P listen discovery results here */
933 
934 	/* TODO: add option for ignoring BSSes we are not interested in
935 	 * (to save memory) */
936 
937 	mesh = wpa_scan_get_ie(res, WLAN_EID_MESH_ID);
938 	if (mesh && mesh[1] <= SSID_MAX_LEN)
939 		ssid = mesh;
940 
941 	bss = wpa_bss_get(wpa_s, res->bssid, ssid + 2, ssid[1]);
942 	if (bss == NULL)
943 		bss = wpa_bss_add(wpa_s, ssid + 2, ssid[1], res, fetch_time);
944 	else {
945 		bss = wpa_bss_update(wpa_s, bss, res, fetch_time);
946 		if (wpa_s->last_scan_res) {
947 			unsigned int i;
948 			for (i = 0; i < wpa_s->last_scan_res_used; i++) {
949 				if (bss == wpa_s->last_scan_res[i]) {
950 					/* Already in the list */
951 					return;
952 				}
953 			}
954 		}
955 	}
956 
957 	if (bss == NULL)
958 		return;
959 	if (wpa_s->last_scan_res_used >= wpa_s->last_scan_res_size) {
960 		struct wpa_bss **n;
961 		unsigned int siz;
962 		if (wpa_s->last_scan_res_size == 0)
963 			siz = 32;
964 		else
965 			siz = wpa_s->last_scan_res_size * 2;
966 		n = os_realloc_array(wpa_s->last_scan_res, siz,
967 				     sizeof(struct wpa_bss *));
968 		if (n == NULL)
969 			return;
970 		wpa_s->last_scan_res = n;
971 		wpa_s->last_scan_res_size = siz;
972 	}
973 
974 	if (wpa_s->last_scan_res)
975 		wpa_s->last_scan_res[wpa_s->last_scan_res_used++] = bss;
976 }
977 
978 
wpa_bss_included_in_scan(const struct wpa_bss * bss,const struct scan_info * info)979 static int wpa_bss_included_in_scan(const struct wpa_bss *bss,
980 				    const struct scan_info *info)
981 {
982 	int found;
983 	size_t i;
984 
985 	if (info == NULL)
986 		return 1;
987 
988 	if (info->num_freqs) {
989 		found = 0;
990 		for (i = 0; i < info->num_freqs; i++) {
991 			if (bss->freq == info->freqs[i]) {
992 				found = 1;
993 				break;
994 			}
995 		}
996 		if (!found)
997 			return 0;
998 	}
999 
1000 	if (info->num_ssids) {
1001 		found = 0;
1002 		for (i = 0; i < info->num_ssids; i++) {
1003 			const struct wpa_driver_scan_ssid *s = &info->ssids[i];
1004 			if ((s->ssid == NULL || s->ssid_len == 0) ||
1005 			    (s->ssid_len == bss->ssid_len &&
1006 			     os_memcmp(s->ssid, bss->ssid, bss->ssid_len) ==
1007 			     0)) {
1008 				found = 1;
1009 				break;
1010 			}
1011 		}
1012 		if (!found)
1013 			return 0;
1014 	}
1015 
1016 	return 1;
1017 }
1018 
1019 
1020 /**
1021  * wpa_bss_update_end - End a BSS table update from scan results
1022  * @wpa_s: Pointer to wpa_supplicant data
1023  * @info: Information about scan parameters
1024  * @new_scan: Whether this update round was based on a new scan
1025  *
1026  * This function is called at the end of each BSS table update round for new
1027  * scan results. The start of the update was indicated with a call to
1028  * wpa_bss_update_start().
1029  */
wpa_bss_update_end(struct wpa_supplicant * wpa_s,struct scan_info * info,int new_scan)1030 void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info,
1031 			int new_scan)
1032 {
1033 	struct wpa_bss *bss, *n;
1034 
1035 	os_get_reltime(&wpa_s->last_scan);
1036 	if ((info && info->aborted) || !new_scan)
1037 		return; /* do not expire entries without new scan */
1038 
1039 	dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) {
1040 		if (wpa_bss_in_use(wpa_s, bss))
1041 			continue;
1042 		if (!wpa_bss_included_in_scan(bss, info))
1043 			continue; /* expire only BSSes that were scanned */
1044 		if (bss->last_update_idx < wpa_s->bss_update_idx)
1045 			bss->scan_miss_count++;
1046 		if (bss->scan_miss_count >=
1047 		    wpa_s->conf->bss_expiration_scan_count) {
1048 			wpa_bss_remove(wpa_s, bss, "no match in scan");
1049 		}
1050 	}
1051 
1052 	wpa_printf(MSG_DEBUG, "BSS: last_scan_res_used=%zu/%zu",
1053 		   wpa_s->last_scan_res_used, wpa_s->last_scan_res_size);
1054 }
1055 
1056 
1057 /**
1058  * wpa_bss_flush_by_age - Flush old BSS entries
1059  * @wpa_s: Pointer to wpa_supplicant data
1060  * @age: Maximum entry age in seconds
1061  *
1062  * Remove BSS entries that have not been updated during the last @age seconds.
1063  */
wpa_bss_flush_by_age(struct wpa_supplicant * wpa_s,int age)1064 void wpa_bss_flush_by_age(struct wpa_supplicant *wpa_s, int age)
1065 {
1066 	struct wpa_bss *bss, *n;
1067 	struct os_reltime t;
1068 
1069 	if (dl_list_empty(&wpa_s->bss))
1070 		return;
1071 
1072 	os_get_reltime(&t);
1073 
1074 	if (t.sec < age)
1075 		return; /* avoid underflow; there can be no older entries */
1076 
1077 	t.sec -= age;
1078 
1079 	dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) {
1080 		if (wpa_bss_in_use(wpa_s, bss))
1081 			continue;
1082 
1083 		if (wpa_s->reassoc_same_ess &&
1084 		    wpa_s->wpa_state != WPA_COMPLETED &&
1085 		    wpa_s->last_ssid &&
1086 		    bss->ssid_len == wpa_s->last_ssid->ssid_len &&
1087 		    os_memcmp(bss->ssid, wpa_s->last_ssid->ssid,
1088 			      bss->ssid_len) == 0)
1089 			continue;
1090 
1091 		if (os_reltime_before(&bss->last_update, &t)) {
1092 			wpa_bss_remove(wpa_s, bss, __func__);
1093 		} else
1094 			break;
1095 	}
1096 }
1097 
1098 
1099 /**
1100  * wpa_bss_init - Initialize BSS table
1101  * @wpa_s: Pointer to wpa_supplicant data
1102  * Returns: 0 on success, -1 on failure
1103  *
1104  * This prepares BSS table lists and timer for periodic updates. The BSS table
1105  * is deinitialized with wpa_bss_deinit() once not needed anymore.
1106  */
wpa_bss_init(struct wpa_supplicant * wpa_s)1107 int wpa_bss_init(struct wpa_supplicant *wpa_s)
1108 {
1109 	dl_list_init(&wpa_s->bss);
1110 	dl_list_init(&wpa_s->bss_id);
1111 	return 0;
1112 }
1113 
1114 
1115 /**
1116  * wpa_bss_flush - Flush all unused BSS entries
1117  * @wpa_s: Pointer to wpa_supplicant data
1118  */
wpa_bss_flush(struct wpa_supplicant * wpa_s)1119 void wpa_bss_flush(struct wpa_supplicant *wpa_s)
1120 {
1121 	struct wpa_bss *bss, *n;
1122 
1123 	wpa_s->clear_driver_scan_cache = 1;
1124 
1125 	if (wpa_s->bss.next == NULL)
1126 		return; /* BSS table not yet initialized */
1127 
1128 	dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) {
1129 		if (wpa_bss_in_use(wpa_s, bss))
1130 			continue;
1131 		wpa_bss_remove(wpa_s, bss, __func__);
1132 	}
1133 }
1134 
1135 
1136 /**
1137  * wpa_bss_deinit - Deinitialize BSS table
1138  * @wpa_s: Pointer to wpa_supplicant data
1139  */
wpa_bss_deinit(struct wpa_supplicant * wpa_s)1140 void wpa_bss_deinit(struct wpa_supplicant *wpa_s)
1141 {
1142 	wpa_bss_flush(wpa_s);
1143 }
1144 
1145 
1146 /**
1147  * wpa_bss_get_bssid - Fetch a BSS table entry based on BSSID
1148  * @wpa_s: Pointer to wpa_supplicant data
1149  * @bssid: BSSID
1150  * Returns: Pointer to the BSS entry or %NULL if not found
1151  */
wpa_bss_get_bssid(struct wpa_supplicant * wpa_s,const u8 * bssid)1152 struct wpa_bss * wpa_bss_get_bssid(struct wpa_supplicant *wpa_s,
1153 				   const u8 *bssid)
1154 {
1155 	struct wpa_bss *bss;
1156 	if (!wpa_supplicant_filter_bssid_match(wpa_s, bssid))
1157 		return NULL;
1158 	dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss, list) {
1159 		if (ether_addr_equal(bss->bssid, bssid))
1160 			return bss;
1161 	}
1162 	return NULL;
1163 }
1164 
1165 
1166 /**
1167  * wpa_bss_get_bssid_latest - Fetch the latest BSS table entry based on BSSID
1168  * @wpa_s: Pointer to wpa_supplicant data
1169  * @bssid: BSSID
1170  * Returns: Pointer to the BSS entry or %NULL if not found
1171  *
1172  * This function is like wpa_bss_get_bssid(), but full BSS table is iterated to
1173  * find the entry that has the most recent update. This can help in finding the
1174  * correct entry in cases where the SSID of the AP may have changed recently
1175  * (e.g., in WPS reconfiguration cases).
1176  */
wpa_bss_get_bssid_latest(struct wpa_supplicant * wpa_s,const u8 * bssid)1177 struct wpa_bss * wpa_bss_get_bssid_latest(struct wpa_supplicant *wpa_s,
1178 					  const u8 *bssid)
1179 {
1180 	struct wpa_bss *bss, *found = NULL;
1181 	if (!wpa_supplicant_filter_bssid_match(wpa_s, bssid))
1182 		return NULL;
1183 	dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss, list) {
1184 		if (!ether_addr_equal(bss->bssid, bssid))
1185 			continue;
1186 		if (found == NULL ||
1187 		    os_reltime_before(&found->last_update, &bss->last_update))
1188 			found = bss;
1189 	}
1190 	return found;
1191 }
1192 
1193 
1194 #ifdef CONFIG_P2P
1195 /**
1196  * wpa_bss_get_p2p_dev_addr - Fetch the latest BSS table entry based on P2P Device Addr
1197  * @wpa_s: Pointer to wpa_supplicant data
1198  * @dev_addr: P2P Device Address of the GO
1199  * Returns: Pointer to the BSS entry or %NULL if not found
1200  *
1201  * This function tries to find the entry that has the most recent update. This
1202  * can help in finding the correct entry in cases where the SSID of the P2P
1203  * Device may have changed recently.
1204  */
wpa_bss_get_p2p_dev_addr(struct wpa_supplicant * wpa_s,const u8 * dev_addr)1205 struct wpa_bss * wpa_bss_get_p2p_dev_addr(struct wpa_supplicant *wpa_s,
1206 					  const u8 *dev_addr)
1207 {
1208 	struct wpa_bss *bss, *found = NULL;
1209 	dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss, list) {
1210 		u8 addr[ETH_ALEN];
1211 		if (p2p_parse_dev_addr(wpa_bss_ie_ptr(bss), bss->ie_len,
1212 				       addr) != 0 ||
1213 		    !ether_addr_equal(addr, dev_addr))
1214 			continue;
1215 		if (!found ||
1216 		    os_reltime_before(&found->last_update, &bss->last_update))
1217 			found = bss;
1218 	}
1219 	return found;
1220 }
1221 #endif /* CONFIG_P2P */
1222 
1223 
1224 /**
1225  * wpa_bss_get_id - Fetch a BSS table entry based on identifier
1226  * @wpa_s: Pointer to wpa_supplicant data
1227  * @id: Unique identifier (struct wpa_bss::id) assigned for the entry
1228  * Returns: Pointer to the BSS entry or %NULL if not found
1229  */
wpa_bss_get_id(struct wpa_supplicant * wpa_s,unsigned int id)1230 struct wpa_bss * wpa_bss_get_id(struct wpa_supplicant *wpa_s, unsigned int id)
1231 {
1232 	struct wpa_bss *bss;
1233 	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
1234 		if (bss->id == id)
1235 			return bss;
1236 	}
1237 	return NULL;
1238 }
1239 
1240 
1241 /**
1242  * wpa_bss_get_id_range - Fetch a BSS table entry based on identifier range
1243  * @wpa_s: Pointer to wpa_supplicant data
1244  * @idf: Smallest allowed identifier assigned for the entry
1245  * @idf: Largest allowed identifier assigned for the entry
1246  * Returns: Pointer to the BSS entry or %NULL if not found
1247  *
1248  * This function is similar to wpa_bss_get_id() but allows a BSS entry with the
1249  * smallest id value to be fetched within the specified range without the
1250  * caller having to know the exact id.
1251  */
wpa_bss_get_id_range(struct wpa_supplicant * wpa_s,unsigned int idf,unsigned int idl)1252 struct wpa_bss * wpa_bss_get_id_range(struct wpa_supplicant *wpa_s,
1253 				      unsigned int idf, unsigned int idl)
1254 {
1255 	struct wpa_bss *bss;
1256 	dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
1257 		if (bss->id >= idf && bss->id <= idl)
1258 			return bss;
1259 	}
1260 	return NULL;
1261 }
1262 
1263 
1264 /**
1265  * wpa_bss_get_ie - Fetch a specified information element from a BSS entry
1266  * @bss: BSS table entry
1267  * @ie: Information element identitifier (WLAN_EID_*)
1268  * Returns: Pointer to the information element (id field) or %NULL if not found
1269  *
1270  * This function returns the first matching information element in the BSS
1271  * entry.
1272  */
wpa_bss_get_ie(const struct wpa_bss * bss,u8 ie)1273 const u8 * wpa_bss_get_ie(const struct wpa_bss *bss, u8 ie)
1274 {
1275 	return get_ie(wpa_bss_ie_ptr(bss), bss->ie_len, ie);
1276 }
1277 
1278 
1279 /**
1280  * wpa_bss_get_ie_beacon - Fetch a specified information element from a BSS entry
1281  * @bss: BSS table entry
1282  * @ie: Information element identitifier (WLAN_EID_*)
1283  * Returns: Pointer to the information element (id field) or %NULL if not found
1284  *
1285  * This function returns the first matching information element in the BSS
1286  * entry.
1287  *
1288  * This function is like wpa_bss_get_ie(), but uses IE buffer only from Beacon
1289  * frames instead of either Beacon or Probe Response frames.
1290  */
wpa_bss_get_ie_beacon(const struct wpa_bss * bss,u8 ie)1291 const u8 * wpa_bss_get_ie_beacon(const struct wpa_bss *bss, u8 ie)
1292 {
1293 	const u8 *ies;
1294 
1295 	if (bss->beacon_ie_len == 0)
1296 		return NULL;
1297 
1298 	ies = wpa_bss_ie_ptr(bss);
1299 	ies += bss->ie_len;
1300 	return get_ie(ies, bss->beacon_ie_len, ie);
1301 }
1302 
1303 
1304 /**
1305  * wpa_bss_get_ie_ext - Fetch a specified extended IE from a BSS entry
1306  * @bss: BSS table entry
1307  * @ext: Information element extension identifier (WLAN_EID_EXT_*)
1308  * Returns: Pointer to the information element (id field) or %NULL if not found
1309  *
1310  * This function returns the first matching information element in the BSS
1311  * entry.
1312  */
wpa_bss_get_ie_ext(const struct wpa_bss * bss,u8 ext)1313 const u8 * wpa_bss_get_ie_ext(const struct wpa_bss *bss, u8 ext)
1314 {
1315 	return get_ie_ext(wpa_bss_ie_ptr(bss), bss->ie_len, ext);
1316 }
1317 
1318 
1319 /**
1320  * wpa_bss_get_vendor_ie - Fetch a vendor information element from a BSS entry
1321  * @bss: BSS table entry
1322  * @vendor_type: Vendor type (four octets starting the IE payload)
1323  * Returns: Pointer to the information element (id field) or %NULL if not found
1324  *
1325  * This function returns the first matching information element in the BSS
1326  * entry.
1327  */
wpa_bss_get_vendor_ie(const struct wpa_bss * bss,u32 vendor_type)1328 const u8 * wpa_bss_get_vendor_ie(const struct wpa_bss *bss, u32 vendor_type)
1329 {
1330 	const u8 *ies;
1331 	const struct element *elem;
1332 
1333 	ies = wpa_bss_ie_ptr(bss);
1334 
1335 	for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, bss->ie_len) {
1336 		if (elem->datalen >= 4 &&
1337 		    vendor_type == WPA_GET_BE32(elem->data))
1338 			return &elem->id;
1339 	}
1340 
1341 	return NULL;
1342 }
1343 
1344 
1345 /**
1346  * wpa_bss_get_vendor_ie_beacon - Fetch a vendor information from a BSS entry
1347  * @bss: BSS table entry
1348  * @vendor_type: Vendor type (four octets starting the IE payload)
1349  * Returns: Pointer to the information element (id field) or %NULL if not found
1350  *
1351  * This function returns the first matching information element in the BSS
1352  * entry.
1353  *
1354  * This function is like wpa_bss_get_vendor_ie(), but uses IE buffer only
1355  * from Beacon frames instead of either Beacon or Probe Response frames.
1356  */
wpa_bss_get_vendor_ie_beacon(const struct wpa_bss * bss,u32 vendor_type)1357 const u8 * wpa_bss_get_vendor_ie_beacon(const struct wpa_bss *bss,
1358 					u32 vendor_type)
1359 {
1360 	const u8 *ies;
1361 	const struct element *elem;
1362 
1363 	if (bss->beacon_ie_len == 0)
1364 		return NULL;
1365 
1366 	ies = wpa_bss_ie_ptr(bss);
1367 	ies += bss->ie_len;
1368 
1369 	for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies,
1370 			    bss->beacon_ie_len) {
1371 		if (elem->datalen >= 4 &&
1372 		    vendor_type == WPA_GET_BE32(elem->data))
1373 			return &elem->id;
1374 	}
1375 
1376 	return NULL;
1377 }
1378 
1379 
1380 /**
1381  * wpa_bss_get_vendor_ie_multi - Fetch vendor IE data from a BSS entry
1382  * @bss: BSS table entry
1383  * @vendor_type: Vendor type (four octets starting the IE payload)
1384  * Returns: Pointer to the information element payload or %NULL if not found
1385  *
1386  * This function returns concatenated payload of possibly fragmented vendor
1387  * specific information elements in the BSS entry. The caller is responsible for
1388  * freeing the returned buffer.
1389  */
wpa_bss_get_vendor_ie_multi(const struct wpa_bss * bss,u32 vendor_type)1390 struct wpabuf * wpa_bss_get_vendor_ie_multi(const struct wpa_bss *bss,
1391 					    u32 vendor_type)
1392 {
1393 	struct wpabuf *buf;
1394 	const u8 *end, *pos;
1395 
1396 	buf = wpabuf_alloc(bss->ie_len);
1397 	if (buf == NULL)
1398 		return NULL;
1399 
1400 	pos = wpa_bss_ie_ptr(bss);
1401 	end = pos + bss->ie_len;
1402 
1403 	while (end - pos > 1) {
1404 		u8 ie, len;
1405 
1406 		ie = pos[0];
1407 		len = pos[1];
1408 		if (len > end - pos - 2)
1409 			break;
1410 		pos += 2;
1411 		if (ie == WLAN_EID_VENDOR_SPECIFIC && len >= 4 &&
1412 		    vendor_type == WPA_GET_BE32(pos))
1413 			wpabuf_put_data(buf, pos + 4, len - 4);
1414 		pos += len;
1415 	}
1416 
1417 	if (wpabuf_len(buf) == 0) {
1418 		wpabuf_free(buf);
1419 		buf = NULL;
1420 	}
1421 
1422 	return buf;
1423 }
1424 
1425 
1426 /**
1427  * wpa_bss_get_vendor_ie_multi_beacon - Fetch vendor IE data from a BSS entry
1428  * @bss: BSS table entry
1429  * @vendor_type: Vendor type (four octets starting the IE payload)
1430  * Returns: Pointer to the information element payload or %NULL if not found
1431  *
1432  * This function returns concatenated payload of possibly fragmented vendor
1433  * specific information elements in the BSS entry. The caller is responsible for
1434  * freeing the returned buffer.
1435  *
1436  * This function is like wpa_bss_get_vendor_ie_multi(), but uses IE buffer only
1437  * from Beacon frames instead of either Beacon or Probe Response frames.
1438  */
wpa_bss_get_vendor_ie_multi_beacon(const struct wpa_bss * bss,u32 vendor_type)1439 struct wpabuf * wpa_bss_get_vendor_ie_multi_beacon(const struct wpa_bss *bss,
1440 						   u32 vendor_type)
1441 {
1442 	struct wpabuf *buf;
1443 	const u8 *end, *pos;
1444 
1445 	buf = wpabuf_alloc(bss->beacon_ie_len);
1446 	if (buf == NULL)
1447 		return NULL;
1448 
1449 	pos = wpa_bss_ie_ptr(bss);
1450 	pos += bss->ie_len;
1451 	end = pos + bss->beacon_ie_len;
1452 
1453 	while (end - pos > 1) {
1454 		u8 id, len;
1455 
1456 		id = *pos++;
1457 		len = *pos++;
1458 		if (len > end - pos)
1459 			break;
1460 		if (id == WLAN_EID_VENDOR_SPECIFIC && len >= 4 &&
1461 		    vendor_type == WPA_GET_BE32(pos))
1462 			wpabuf_put_data(buf, pos + 4, len - 4);
1463 		pos += len;
1464 	}
1465 
1466 	if (wpabuf_len(buf) == 0) {
1467 		wpabuf_free(buf);
1468 		buf = NULL;
1469 	}
1470 
1471 	return buf;
1472 }
1473 
1474 
1475 /**
1476  * wpa_bss_get_max_rate - Get maximum legacy TX rate supported in a BSS
1477  * @bss: BSS table entry
1478  * Returns: Maximum legacy rate in units of 500 kbps
1479  */
wpa_bss_get_max_rate(const struct wpa_bss * bss)1480 int wpa_bss_get_max_rate(const struct wpa_bss *bss)
1481 {
1482 	int rate = 0;
1483 	const u8 *ie;
1484 	int i;
1485 
1486 	ie = wpa_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
1487 	for (i = 0; ie && i < ie[1]; i++) {
1488 		if ((ie[i + 2] & 0x7f) > rate)
1489 			rate = ie[i + 2] & 0x7f;
1490 	}
1491 
1492 	ie = wpa_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);
1493 	for (i = 0; ie && i < ie[1]; i++) {
1494 		if ((ie[i + 2] & 0x7f) > rate)
1495 			rate = ie[i + 2] & 0x7f;
1496 	}
1497 
1498 	return rate;
1499 }
1500 
1501 
1502 /**
1503  * wpa_bss_get_bit_rates - Get legacy TX rates supported in a BSS
1504  * @bss: BSS table entry
1505  * @rates: Buffer for returning a pointer to the rates list (units of 500 kbps)
1506  * Returns: number of legacy TX rates or -1 on failure
1507  *
1508  * The caller is responsible for freeing the returned buffer with os_free() in
1509  * case of success.
1510  */
wpa_bss_get_bit_rates(const struct wpa_bss * bss,u8 ** rates)1511 int wpa_bss_get_bit_rates(const struct wpa_bss *bss, u8 **rates)
1512 {
1513 	const u8 *ie, *ie2;
1514 	int i, j;
1515 	unsigned int len;
1516 	u8 *r;
1517 
1518 	ie = wpa_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
1519 	ie2 = wpa_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);
1520 
1521 	len = (ie ? ie[1] : 0) + (ie2 ? ie2[1] : 0);
1522 
1523 	r = os_malloc(len);
1524 	if (!r)
1525 		return -1;
1526 
1527 	for (i = 0; ie && i < ie[1]; i++)
1528 		r[i] = ie[i + 2] & 0x7f;
1529 
1530 	for (j = 0; ie2 && j < ie2[1]; j++)
1531 		r[i + j] = ie2[j + 2] & 0x7f;
1532 
1533 	*rates = r;
1534 	return len;
1535 }
1536 
1537 
1538 #ifdef CONFIG_FILS
wpa_bss_get_fils_cache_id(const struct wpa_bss * bss)1539 const u8 * wpa_bss_get_fils_cache_id(const struct wpa_bss *bss)
1540 {
1541 	const u8 *ie;
1542 
1543 	if (bss) {
1544 		ie = wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION);
1545 		if (ie && ie[1] >= 4 && WPA_GET_LE16(ie + 2) & BIT(7))
1546 			return ie + 4;
1547 	}
1548 
1549 	return NULL;
1550 }
1551 #endif /* CONFIG_FILS */
1552 
1553 
wpa_bss_ext_capab(const struct wpa_bss * bss,unsigned int capab)1554 int wpa_bss_ext_capab(const struct wpa_bss *bss, unsigned int capab)
1555 {
1556 	if (!bss)
1557 		return 0;
1558 	return ieee802_11_ext_capab(wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB),
1559 				    capab);
1560 }
1561 
1562 
1563 static void
wpa_bss_parse_ml_rnr_ap_info(struct wpa_supplicant * wpa_s,struct wpa_bss * bss,u8 mbssid_idx,const struct ieee80211_neighbor_ap_info * ap_info,size_t len,u16 * seen,u16 * missing,struct wpa_ssid * ssid)1564 wpa_bss_parse_ml_rnr_ap_info(struct wpa_supplicant *wpa_s,
1565 			     struct wpa_bss *bss, u8 mbssid_idx,
1566 			     const struct ieee80211_neighbor_ap_info *ap_info,
1567 			     size_t len, u16 *seen, u16 *missing,
1568 			     struct wpa_ssid *ssid)
1569 {
1570 	const u8 *pos, *end;
1571 	const u8 *mld_params;
1572 	u8 count, mld_params_offset;
1573 	u8 i, type, link_id;
1574 
1575 	count = RNR_TBTT_INFO_COUNT_VAL(ap_info->tbtt_info_hdr) + 1;
1576 	type = ap_info->tbtt_info_hdr & RNR_TBTT_INFO_HDR_TYPE_MSK;
1577 
1578 	/* MLD information is at offset 13 or at start */
1579 	if (type == 0 && ap_info->tbtt_info_len >= RNR_TBTT_INFO_MLD_LEN) {
1580 		/* MLD info is appended */
1581 		mld_params_offset = RNR_TBTT_INFO_LEN;
1582 	} else {
1583 		/* TODO: Support NSTR AP */
1584 		return;
1585 	}
1586 
1587 	pos = (const u8 *) ap_info;
1588 	end = pos + len;
1589 	pos += sizeof(*ap_info);
1590 
1591 	for (i = 0; i < count; i++) {
1592 		u8 bss_params;
1593 
1594 		if (end - pos < ap_info->tbtt_info_len)
1595 			break;
1596 
1597 		bss_params = pos[1 + ETH_ALEN + 4];
1598 		mld_params = pos + mld_params_offset;
1599 
1600 		link_id = *(mld_params + 1) & EHT_ML_LINK_ID_MSK;
1601 		if (link_id >= MAX_NUM_MLD_LINKS)
1602 			return;
1603 
1604 		if (*mld_params != mbssid_idx) {
1605 			wpa_printf(MSG_DEBUG,
1606 				   "MLD: Reported link not part of MLD");
1607 		} else if (!(BIT(link_id) & *seen)) {
1608 			struct wpa_bss *neigh_bss;
1609 
1610 			if (ssid && ssid->ssid_len)
1611 				neigh_bss = wpa_bss_get(wpa_s, pos + 1,
1612 							ssid->ssid,
1613 							ssid->ssid_len);
1614 			else
1615 				neigh_bss = wpa_bss_get_bssid(wpa_s, pos + 1);
1616 
1617 			*seen |= BIT(link_id);
1618 			wpa_printf(MSG_DEBUG, "MLD: mld ID=%u, link ID=%u",
1619 				   *mld_params, link_id);
1620 
1621 			if (!neigh_bss) {
1622 				*missing |= BIT(link_id);
1623 			} else if ((!ssid ||
1624 				    (bss_params & (RNR_BSS_PARAM_SAME_SSID |
1625 						   RNR_BSS_PARAM_CO_LOCATED)) ||
1626 				    wpa_scan_res_match(wpa_s, 0, neigh_bss,
1627 						       ssid, 1, 0)) &&
1628 				   !wpa_bssid_ignore_is_listed(
1629 					   wpa_s, neigh_bss->bssid)) {
1630 				struct mld_link *l;
1631 
1632 				bss->valid_links |= BIT(link_id);
1633 				l = &bss->mld_links[link_id];
1634 				os_memcpy(l->bssid, pos + 1, ETH_ALEN);
1635 				l->freq = neigh_bss->freq;
1636 				l->disabled = mld_params[2] &
1637 					RNR_TBTT_INFO_MLD_PARAM2_LINK_DISABLED;
1638 			}
1639 		}
1640 
1641 		pos += ap_info->tbtt_info_len;
1642 	}
1643 }
1644 
1645 
1646 /**
1647  * wpa_bss_parse_basic_ml_element - Parse the Basic Multi-Link element
1648  * @wpa_s: Pointer to wpa_supplicant data
1649  * @bss: BSS table entry
1650  * @mld_addr: AP MLD address (or %NULL)
1651  * @link_info: Array to store link information (or %NULL),
1652  *   should be initialized and #MAX_NUM_MLD_LINKS elements long
1653  * @missing_links: Result bitmask of links that were not discovered (or %NULL)
1654  * @ssid: Target SSID (or %NULL)
1655  * @ap_mld_id: On return would hold the corresponding AP MLD ID (or %NULL)
1656  * Returns: 0 on success or -1 for non-MLD or parsing failures
1657  *
1658  * Parses the Basic Multi-Link element of the BSS into @link_info using the scan
1659  * information stored in the wpa_supplicant data to fill in information for
1660  * links where possible. The @missing_links out parameter will contain any links
1661  * for which no corresponding BSS was found.
1662  */
wpa_bss_parse_basic_ml_element(struct wpa_supplicant * wpa_s,struct wpa_bss * bss,u8 * ap_mld_addr,u16 * missing_links,struct wpa_ssid * ssid,u8 * ap_mld_id)1663 int wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s,
1664 				   struct wpa_bss *bss,
1665 				   u8 *ap_mld_addr,
1666 				   u16 *missing_links,
1667 				   struct wpa_ssid *ssid,
1668 				   u8 *ap_mld_id)
1669 {
1670 	struct ieee802_11_elems elems;
1671 	struct wpabuf *mlbuf;
1672 	const struct element *elem;
1673 	u8 mbssid_idx = 0;
1674 	size_t ml_ie_len;
1675 	const struct ieee80211_eht_ml *eht_ml;
1676 	const struct eht_ml_basic_common_info *ml_basic_common_info;
1677 	u8 i, link_id;
1678 	const u16 control_mask =
1679 		MULTI_LINK_CONTROL_TYPE_MASK |
1680 		BASIC_MULTI_LINK_CTRL_PRES_LINK_ID |
1681 		BASIC_MULTI_LINK_CTRL_PRES_BSS_PARAM_CH_COUNT |
1682 		BASIC_MULTI_LINK_CTRL_PRES_MLD_CAPA;
1683 	const u16 control =
1684 		MULTI_LINK_CONTROL_TYPE_BASIC |
1685 		BASIC_MULTI_LINK_CTRL_PRES_LINK_ID |
1686 		BASIC_MULTI_LINK_CTRL_PRES_BSS_PARAM_CH_COUNT |
1687 		BASIC_MULTI_LINK_CTRL_PRES_MLD_CAPA;
1688 	u16 missing = 0;
1689 	u16 seen;
1690 	const u8 *ies_pos = wpa_bss_ie_ptr(bss);
1691 	size_t ies_len = bss->ie_len ? bss->ie_len : bss->beacon_ie_len;
1692 	int ret = -1;
1693 	struct mld_link *l;
1694 
1695 	if (ieee802_11_parse_elems(ies_pos, ies_len, &elems, 1) ==
1696 	    ParseFailed) {
1697 		wpa_dbg(wpa_s, MSG_DEBUG, "MLD: Failed to parse elements");
1698 		return ret;
1699 	}
1700 
1701 	mlbuf = ieee802_11_defrag(elems.basic_mle, elems.basic_mle_len, true);
1702 	if (!mlbuf) {
1703 		wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No Multi-Link element");
1704 		return ret;
1705 	}
1706 
1707 	ml_ie_len = wpabuf_len(mlbuf);
1708 
1709 	if (ssid) {
1710 		struct wpa_ie_data ie;
1711 		const u8 *rsne;
1712 		size_t rsne_len;
1713 
1714 		if (elems.rsne_override_2 && wpas_rsn_overriding(wpa_s)) {
1715 			rsne = elems.rsne_override_2;
1716 			rsne_len = elems.rsne_override_2_len;
1717 		} else if (elems.rsne_override &&
1718 			   wpas_rsn_overriding(wpa_s)) {
1719 			rsne = elems.rsne_override;
1720 			rsne_len = elems.rsne_override_len;
1721 		} else {
1722 			rsne = elems.rsn_ie;
1723 			rsne_len = elems.rsn_ie_len;
1724 		}
1725 		if (!rsne ||
1726 		    wpa_parse_wpa_ie(rsne - 2, 2 + rsne_len, &ie)) {
1727 			wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No RSN element");
1728 			goto out;
1729 		}
1730 
1731 		if (!(ie.capabilities & WPA_CAPABILITY_MFPC) ||
1732 		    wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION) {
1733 			wpa_dbg(wpa_s, MSG_DEBUG,
1734 				"MLD: No management frame protection");
1735 			goto out;
1736 		}
1737 
1738 		ie.key_mgmt &= ~(WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK |
1739 				 WPA_KEY_MGMT_PSK_SHA256);
1740 		if (!(ie.key_mgmt & ssid->key_mgmt)) {
1741 			wpa_dbg(wpa_s, MSG_DEBUG,
1742 				"MLD: No valid key management");
1743 			goto out;
1744 		}
1745 	}
1746 
1747 	/*
1748 	 * for ext ID + 2 control + common info len + MLD address +
1749 	 * link info
1750 	 */
1751 	if (ml_ie_len < 2UL + 1UL + ETH_ALEN + 1UL)
1752 		goto out;
1753 
1754 	eht_ml = (const struct ieee80211_eht_ml *) wpabuf_head(mlbuf);
1755 	if ((le_to_host16(eht_ml->ml_control) & control_mask) != control) {
1756 		wpa_printf(MSG_DEBUG,
1757 			   "MLD: Unexpected Multi-Link element control=0x%x (mask 0x%x expected 0x%x)",
1758 			   le_to_host16(eht_ml->ml_control), control_mask,
1759 			   control);
1760 		goto out;
1761 	}
1762 
1763 	ml_basic_common_info =
1764 		(const struct eht_ml_basic_common_info *) eht_ml->variable;
1765 
1766 	/* Common info length should be valid */
1767 	if (ml_basic_common_info->len < ETH_ALEN + 1UL)
1768 		goto out;
1769 
1770 	/* Get the MLD address and MLD link ID */
1771 	if (ap_mld_addr)
1772 		os_memcpy(ap_mld_addr, ml_basic_common_info->mld_addr,
1773 			  ETH_ALEN);
1774 
1775 	link_id = ml_basic_common_info->variable[0] & EHT_ML_LINK_ID_MSK;
1776 
1777 	bss->mld_link_id = link_id;
1778 	seen = bss->valid_links = BIT(link_id);
1779 
1780 	l = &bss->mld_links[link_id];
1781 	os_memcpy(l->bssid, bss->bssid, ETH_ALEN);
1782 	l->freq = bss->freq;
1783 
1784 
1785 	/*
1786 	 * The AP MLD ID in the RNR corresponds to the MBSSID index, see
1787 	 * IEEE P802.11be/D4.0, 9.4.2.169.2 (Neighbor AP Information field).
1788 	 *
1789 	 * For the transmitting BSSID it is clear that both the MBSSID index
1790 	 * and the AP MLD ID in the RNR are zero.
1791 	 *
1792 	 * For nontransmitted BSSIDs we will have a BSS generated from the
1793 	 * MBSSID element(s) using inheritance rules. Included in the elements
1794 	 * is the MBSSID Index Element. The RNR is copied from the Beacon/Probe
1795 	 * Response frame that was send by the transmitting BSSID. As such, the
1796 	 * reported AP MLD ID in the RNR will match the value in the MBSSID
1797 	 * Index Element.
1798 	 */
1799 	elem = (const struct element *)
1800 		wpa_bss_get_ie(bss, WLAN_EID_MULTIPLE_BSSID_INDEX);
1801 	if (elem && elem->datalen >= 1)
1802 		mbssid_idx = elem->data[0];
1803 
1804 	for_each_element_id(elem, WLAN_EID_REDUCED_NEIGHBOR_REPORT,
1805 			    wpa_bss_ie_ptr(bss),
1806 			    bss->ie_len ? bss->ie_len : bss->beacon_ie_len) {
1807 		const struct ieee80211_neighbor_ap_info *ap_info;
1808 		const u8 *pos = elem->data;
1809 		size_t len = elem->datalen;
1810 
1811 		/* RNR IE may contain more than one Neighbor AP Info */
1812 		while (sizeof(*ap_info) <= len) {
1813 			size_t ap_info_len = sizeof(*ap_info);
1814 			u8 count;
1815 
1816 			ap_info = (const struct ieee80211_neighbor_ap_info *)
1817 				pos;
1818 			count = RNR_TBTT_INFO_COUNT_VAL(ap_info->tbtt_info_hdr) + 1;
1819 			ap_info_len += count * ap_info->tbtt_info_len;
1820 
1821 			if (ap_info_len > len)
1822 				goto out;
1823 
1824 			wpa_bss_parse_ml_rnr_ap_info(wpa_s, bss, mbssid_idx,
1825 						     ap_info, len, &seen,
1826 						     &missing, ssid);
1827 
1828 			pos += ap_info_len;
1829 			len -= ap_info_len;
1830 		}
1831 	}
1832 
1833 	wpa_printf(MSG_DEBUG, "MLD: valid_links=%04hx (unresolved: 0x%04hx)",
1834 		   bss->valid_links, missing);
1835 
1836 	for_each_link(bss->valid_links, i) {
1837 		wpa_printf(MSG_DEBUG, "MLD: link=%u, bssid=" MACSTR,
1838 			   i, MAC2STR(bss->mld_links[i].bssid));
1839 	}
1840 
1841 	if (missing_links)
1842 		*missing_links = missing;
1843 
1844 	if (ap_mld_id)
1845 		*ap_mld_id = mbssid_idx;
1846 
1847 	ret = 0;
1848 out:
1849 	wpabuf_free(mlbuf);
1850 	return ret;
1851 }
1852 
1853 
1854 /*
1855  * wpa_bss_parse_reconf_ml_element - Parse the Reconfiguration ML element
1856  * @wpa_s: Pointer to wpa_supplicant data
1857  * @bss: BSS table entry
1858  * Returns: The bitmap of links that are going to be removed
1859  */
wpa_bss_parse_reconf_ml_element(struct wpa_supplicant * wpa_s,struct wpa_bss * bss)1860 u16 wpa_bss_parse_reconf_ml_element(struct wpa_supplicant *wpa_s,
1861 				    struct wpa_bss *bss)
1862 {
1863 	struct ieee802_11_elems elems;
1864 	struct wpabuf *mlbuf;
1865 	const u8 *pos = wpa_bss_ie_ptr(bss);
1866 	size_t len = bss->ie_len ? bss->ie_len : bss->beacon_ie_len;
1867 	const struct ieee80211_eht_ml *ml;
1868 	u16 removed_links = 0;
1869 	u8 ml_common_len;
1870 
1871 	if (ieee802_11_parse_elems(pos, len, &elems, 1) == ParseFailed)
1872 		return 0;
1873 
1874 	if (!elems.reconf_mle || !elems.reconf_mle_len)
1875 		return 0;
1876 
1877 	mlbuf = ieee802_11_defrag(elems.reconf_mle, elems.reconf_mle_len, true);
1878 	if (!mlbuf)
1879 		return 0;
1880 
1881 	ml = (const struct ieee80211_eht_ml *) wpabuf_head(mlbuf);
1882 	len = wpabuf_len(mlbuf);
1883 
1884 	if (len < sizeof(*ml))
1885 		goto out;
1886 
1887 	ml_common_len = 1;
1888 	if (ml->ml_control & RECONF_MULTI_LINK_CTRL_PRES_MLD_MAC_ADDR)
1889 		ml_common_len += ETH_ALEN;
1890 
1891 	if (len < sizeof(*ml) + ml_common_len) {
1892 		wpa_printf(MSG_DEBUG,
1893 			   "MLD: Unexpected Reconfiguration ML element length: (%zu < %zu)",
1894 			   len, sizeof(*ml) + ml_common_len);
1895 		goto out;
1896 	}
1897 
1898 	pos = ml->variable + ml_common_len;
1899 	len -= sizeof(*ml) + ml_common_len;
1900 
1901 	while (len >= 2 + sizeof(struct ieee80211_eht_per_sta_profile)) {
1902 		size_t sub_elem_len = *(pos + 1);
1903 
1904 		if (2 + sub_elem_len > len) {
1905 			wpa_printf(MSG_DEBUG,
1906 				   "MLD: Invalid link info len: %zu %zu",
1907 				   2 + sub_elem_len, len);
1908 			goto out;
1909 		}
1910 
1911 		if  (*pos == EHT_ML_SUB_ELEM_PER_STA_PROFILE) {
1912 			const struct ieee80211_eht_per_sta_profile *sta_prof =
1913 				(const struct ieee80211_eht_per_sta_profile *)
1914 				(pos + 2);
1915 			u16 control = le_to_host16(sta_prof->sta_control);
1916 			u8 link_id;
1917 
1918 			link_id = control & EHT_PER_STA_RECONF_CTRL_LINK_ID_MSK;
1919 			removed_links |= BIT(link_id);
1920 		}
1921 
1922 		pos += 2 + sub_elem_len;
1923 		len -= 2 + sub_elem_len;
1924 	}
1925 
1926 	wpa_printf(MSG_DEBUG, "MLD: Reconfiguration: removed_links=0x%x",
1927 		   removed_links);
1928 out:
1929 	wpabuf_free(mlbuf);
1930 	return removed_links;
1931 }
1932 
1933 
wpa_bss_supported_cipher(struct wpa_supplicant * wpa_s,int pairwise_cipher)1934 static bool wpa_bss_supported_cipher(struct wpa_supplicant *wpa_s,
1935 				     int pairwise_cipher)
1936 {
1937 	if (!wpa_s->drv_enc)
1938 		return true;
1939 
1940 	if ((pairwise_cipher & WPA_CIPHER_CCMP) &&
1941 	    (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_CCMP))
1942 		return true;
1943 
1944 	if ((pairwise_cipher & WPA_CIPHER_GCMP) &&
1945 	    (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_GCMP))
1946 		return true;
1947 
1948 	if ((pairwise_cipher & WPA_CIPHER_CCMP_256) &&
1949 	    (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_CCMP_256))
1950 		return true;
1951 
1952 	if ((pairwise_cipher & WPA_CIPHER_GCMP_256) &&
1953 	    (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_GCMP_256))
1954 		return true;
1955 
1956 	return false;
1957 }
1958 
1959 
wpa_bss_supported_key_mgmt(struct wpa_supplicant * wpa_s,int key_mgmt)1960 static bool wpa_bss_supported_key_mgmt(struct wpa_supplicant *wpa_s,
1961 				       int key_mgmt)
1962 {
1963 	if (!wpa_s->drv_key_mgmt)
1964 		return true;
1965 
1966 	if ((key_mgmt & WPA_KEY_MGMT_IEEE8021X) &&
1967 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA2))
1968 		return true;
1969 	if ((key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) &&
1970 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_802_1X_SHA256))
1971 		return true;
1972 	if ((key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) &&
1973 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT))
1974 		return true;
1975 	if ((key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) &&
1976 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_802_1X_SHA384))
1977 		return true;
1978 	if ((key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) &&
1979 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B))
1980 		return true;
1981 	if ((key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) &&
1982 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192))
1983 		return true;
1984 	if ((key_mgmt & WPA_KEY_MGMT_PSK) &&
1985 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK))
1986 		return true;
1987 	if ((key_mgmt & WPA_KEY_MGMT_FT_PSK) &&
1988 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK))
1989 		return true;
1990 	if ((key_mgmt & WPA_KEY_MGMT_PSK_SHA256) &&
1991 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_PSK_SHA256))
1992 		return true;
1993 	if ((key_mgmt & WPA_KEY_MGMT_SAE) &&
1994 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE))
1995 		return true;
1996 	if ((key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY) &&
1997 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE_EXT_KEY))
1998 		return true;
1999 	if ((key_mgmt & WPA_KEY_MGMT_FT_SAE) &&
2000 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE))
2001 		return true;
2002 	if ((key_mgmt & WPA_KEY_MGMT_FT_SAE_EXT_KEY) &&
2003 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE_EXT_KEY))
2004 		return true;
2005 	if ((key_mgmt & WPA_KEY_MGMT_OWE) &&
2006 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE))
2007 		return true;
2008 	if ((key_mgmt & WPA_KEY_MGMT_DPP) &&
2009 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP))
2010 		return true;
2011 	if ((key_mgmt & WPA_KEY_MGMT_FILS_SHA256) &&
2012 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256))
2013 		return true;
2014 	if ((key_mgmt & WPA_KEY_MGMT_FILS_SHA384) &&
2015 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384))
2016 		return true;
2017 	if ((key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) &&
2018 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256))
2019 		return true;
2020 	if ((key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) &&
2021 	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384))
2022 		return true;
2023 
2024 	return false;
2025 }
2026 
2027 
wpa_bss_supported_rsne(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid,const u8 * ie)2028 static bool wpa_bss_supported_rsne(struct wpa_supplicant *wpa_s,
2029 				   struct wpa_ssid *ssid, const u8 *ie)
2030 {
2031 	struct wpa_ie_data data;
2032 
2033 	if (wpa_parse_wpa_ie_rsn(ie, 2 + ie[1], &data) < 0)
2034 		return false;
2035 
2036 	/* Check that there is a supported AKM and pairwise cipher based on
2037 	 * overall capabilities */
2038 	if (!data.pairwise_cipher || !data.key_mgmt)
2039 		return false;
2040 
2041 	if (wpa_s->drv_capa_known) {
2042 		if (!wpa_bss_supported_cipher(wpa_s, data.pairwise_cipher) ||
2043 		    !wpa_bss_supported_key_mgmt(wpa_s, data.key_mgmt))
2044 			return false;
2045 	}
2046 
2047 	if (ssid) {
2048 		/* Check that there is a supported AKM and pairwise cipher
2049 		 * based on the specific network profile. */
2050 		if ((ssid->pairwise_cipher & data.pairwise_cipher) == 0)
2051 			return false;
2052 		if ((ssid->key_mgmt & data.key_mgmt) == 0)
2053 			return false;
2054 	}
2055 
2056 	return true;
2057 }
2058 
2059 
wpa_bss_get_rsne(struct wpa_supplicant * wpa_s,const struct wpa_bss * bss,struct wpa_ssid * ssid,bool mlo)2060 const u8 * wpa_bss_get_rsne(struct wpa_supplicant *wpa_s,
2061 			    const struct wpa_bss *bss, struct wpa_ssid *ssid,
2062 			    bool mlo)
2063 {
2064 	const u8 *ie;
2065 
2066 	if (wpas_rsn_overriding(wpa_s)) {
2067 		if (!ssid)
2068 			ssid = wpa_s->current_ssid;
2069 
2070 		/* MLO cases for RSN overriding are required to use RSNE
2071 		 * Override 2 element and RSNXE Override element together. */
2072 		ie = wpa_bss_get_vendor_ie(bss, RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
2073 		if (mlo && ie &&
2074 		    !wpa_bss_get_vendor_ie(bss,
2075 					   RSNXE_OVERRIDE_IE_VENDOR_TYPE)) {
2076 			wpa_printf(MSG_DEBUG, "BSS " MACSTR
2077 				   " advertises RSNE Override 2 element without RSNXE Override element - ignore RSNE Override 2 element for MLO",
2078 				   MAC2STR(bss->bssid));
2079 		} else if (ie && wpa_bss_supported_rsne(wpa_s, ssid, ie)) {
2080 			return ie;
2081 		}
2082 
2083 		if (!mlo) {
2084 			ie = wpa_bss_get_vendor_ie(
2085 				bss, RSNE_OVERRIDE_IE_VENDOR_TYPE);
2086 			if (ie && wpa_bss_supported_rsne(wpa_s, ssid, ie))
2087 				return ie;
2088 		}
2089 	}
2090 
2091 	return wpa_bss_get_ie(bss, WLAN_EID_RSN);
2092 }
2093 
2094 
wpa_bss_get_rsnxe(struct wpa_supplicant * wpa_s,const struct wpa_bss * bss,struct wpa_ssid * ssid,bool mlo)2095 const u8 * wpa_bss_get_rsnxe(struct wpa_supplicant *wpa_s,
2096 			     const struct wpa_bss *bss, struct wpa_ssid *ssid,
2097 			     bool mlo)
2098 {
2099 	const u8 *ie;
2100 
2101 	if (wpas_rsn_overriding(wpa_s)) {
2102 		ie = wpa_bss_get_vendor_ie(bss, RSNXE_OVERRIDE_IE_VENDOR_TYPE);
2103 		if (ie) {
2104 			const u8 *tmp;
2105 
2106 			tmp = wpa_bss_get_rsne(wpa_s, bss, ssid, mlo);
2107 			if (!tmp || tmp[0] == WLAN_EID_RSN) {
2108 				/* An acceptable RSNE override element was not
2109 				 * found, so need to ignore RSNXE overriding. */
2110 				goto out;
2111 			}
2112 
2113 			return ie;
2114 		}
2115 
2116 		/* MLO cases for RSN overriding are required to use RSNE
2117 		 * Override 2 element and RSNXE Override element together. */
2118 		if (mlo && wpa_bss_get_vendor_ie(
2119 			    bss, RSNE_OVERRIDE_2_IE_VENDOR_TYPE)) {
2120 			wpa_printf(MSG_DEBUG, "BSS " MACSTR
2121 				   " advertises RSNXE Override element without RSNE Override 2 element - ignore RSNXE Override element for MLO",
2122 				   MAC2STR(bss->bssid));
2123 			goto out;
2124 		}
2125 	}
2126 
2127 out:
2128 	return wpa_bss_get_ie(bss, WLAN_EID_RSNX);
2129 }
2130