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