1 /*
2 * IEEE 802.11 Common routines
3 * Copyright (c) 2002-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 "includes.h"
10
11 #include "common.h"
12 #include "defs.h"
13 #include "wpa_common.h"
14 #include "drivers/driver.h"
15 #include "qca-vendor.h"
16 #include "ieee802_11_defs.h"
17 #include "ieee802_11_common.h"
18 #ifdef LOS_CONFIG_MESH
19 #include "soc_mesh.h"
20 #endif /* LOS_CONFIG_MESH */
21
ieee802_11_parse_vendor_specific(const u8 * pos,size_t elen,struct ieee802_11_elems * elems,int show_errors)22 static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
23 struct ieee802_11_elems *elems,
24 int show_errors)
25 {
26 unsigned int oui;
27
28 /* first 3 bytes in vendor specific information element are the IEEE
29 * OUI of the vendor. The following byte is used a vendor specific
30 * sub-type. */
31 if (elen < 4) {
32 if (show_errors) {
33 wpa_msgdump_log1(MSG_MSGDUMP, "short vendor specific "
34 "information element ignored (len=%lu)",
35 (unsigned long) elen);
36 }
37 return -1;
38 }
39
40 oui = WPA_GET_BE24(pos);
41 switch (oui) {
42 case OUI_MICROSOFT:
43 /* Microsoft/Wi-Fi information elements are further typed and
44 * subtyped */
45 switch (pos[3]) {
46 case 1:
47 /* Microsoft OUI (00:50:F2) with OUI Type 1:
48 * real WPA information element */
49 elems->wpa_ie = pos;
50 elems->wpa_ie_len = elen;
51 break;
52 #ifndef LOS_CONFIG_80211_IES_CROP
53 case WMM_OUI_TYPE:
54 /* WMM information element */
55 if (elen < 5) {
56 wpa_printf(MSG_MSGDUMP, "short WMM "
57 "information element ignored "
58 "(len=%lu)",
59 (unsigned long) elen);
60 return -1;
61 }
62 switch (pos[4]) {
63 case WMM_OUI_SUBTYPE_INFORMATION_ELEMENT:
64 case WMM_OUI_SUBTYPE_PARAMETER_ELEMENT:
65 /*
66 * Share same pointer since only one of these
67 * is used and they start with same data.
68 * Length field can be used to distinguish the
69 * IEs.
70 */
71 elems->wmm = pos;
72 elems->wmm_len = elen;
73 break;
74 case WMM_OUI_SUBTYPE_TSPEC_ELEMENT:
75 elems->wmm_tspec = pos;
76 elems->wmm_tspec_len = elen;
77 break;
78 default:
79 wpa_printf(MSG_EXCESSIVE, "unknown WMM "
80 "information element ignored "
81 "(subtype=%d len=%lu)",
82 pos[4], (unsigned long) elen);
83 return -1;
84 }
85 break;
86 #endif /* LOS_CONFIG_80211_IES_CROP */
87 case 4:
88 /* Wi-Fi Protected Setup (WPS) IE */
89 elems->wps_ie = pos;
90 elems->wps_ie_len = elen;
91 break;
92 default:
93 #ifndef CONFIG_PRINT_NOUSE
94 wpa_printf(MSG_EXCESSIVE, "Unknown Microsoft "
95 "information element ignored "
96 "(type=%d len=%lu)",
97 pos[3], (unsigned long) elen);
98 #endif /* CONFIG_PRINT_NOUSE */
99 return -1;
100 }
101 break;
102
103 case OUI_WFA:
104 switch (pos[3]) {
105 #ifdef CONFIG_P2P
106 case P2P_OUI_TYPE:
107 /* Wi-Fi Alliance - P2P IE */
108 elems->p2p = pos;
109 elems->p2p_len = elen;
110 break;
111 #endif /* CONFIG_P2P */
112 #ifndef LOS_CONFIG_80211_IES_CROP
113 case WFD_OUI_TYPE:
114 /* Wi-Fi Alliance - WFD IE */
115 elems->wfd = pos;
116 elems->wfd_len = elen;
117 break;
118 case HS20_INDICATION_OUI_TYPE:
119 /* Hotspot 2.0 */
120 elems->hs20 = pos;
121 elems->hs20_len = elen;
122 break;
123 case HS20_OSEN_OUI_TYPE:
124 /* Hotspot 2.0 OSEN */
125 elems->osen = pos;
126 elems->osen_len = elen;
127 break;
128 #endif /* LOS_CONFIG_80211_IES_CROP */
129 #ifdef CONFIG_MBO
130 case MBO_OUI_TYPE:
131 /* MBO-OCE */
132 elems->mbo = pos;
133 elems->mbo_len = elen;
134 break;
135 #endif /* CONFIG_MBO */
136 #ifndef LOS_CONFIG_80211_IES_CROP
137 case HS20_ROAMING_CONS_SEL_OUI_TYPE:
138 /* Hotspot 2.0 Roaming Consortium Selection */
139 elems->roaming_cons_sel = pos;
140 elems->roaming_cons_sel_len = elen;
141 break;
142 #endif /* LOS_CONFIG_80211_IES_CROP */
143 #ifdef CONFIG_MULTI_AP
144 case MULTI_AP_OUI_TYPE:
145 elems->multi_ap = pos;
146 elems->multi_ap_len = elen;
147 break;
148 #endif /* CONFIG_MULTI_AP */
149 case OWE_OUI_TYPE:
150 /* OWE Transition Mode element */
151 break;
152 case DPP_CC_OUI_TYPE:
153 /* DPP Configurator Connectivity element */
154 break;
155 case SAE_PK_OUI_TYPE:
156 elems->sae_pk = pos + 4;
157 elems->sae_pk_len = elen - 4;
158 break;
159 default:
160 wpa_msgdump_log2(MSG_MSGDUMP, "Unknown WFA "
161 "information element ignored "
162 "(type=%d len=%lu)",
163 pos[3], (unsigned long) elen);
164 return -1;
165 }
166 break;
167
168 #ifndef LOS_CONFIG_80211_IES_CROP
169 case OUI_BROADCOM:
170 switch (pos[3]) {
171 case VENDOR_HT_CAPAB_OUI_TYPE:
172 elems->vendor_ht_cap = pos;
173 elems->vendor_ht_cap_len = elen;
174 break;
175 case VENDOR_VHT_TYPE:
176 if (elen > 4 &&
177 (pos[4] == VENDOR_VHT_SUBTYPE ||
178 pos[4] == VENDOR_VHT_SUBTYPE2)) {
179 elems->vendor_vht = pos;
180 elems->vendor_vht_len = elen;
181 } else
182 return -1;
183 break;
184 default:
185 wpa_printf(MSG_EXCESSIVE, "Unknown Broadcom "
186 "information element ignored "
187 "(type=%d len=%lu)",
188 pos[3], (unsigned long) elen);
189 return -1;
190 }
191 break;
192
193 case OUI_QCA:
194 switch (pos[3]) {
195 case QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST:
196 elems->pref_freq_list = pos;
197 elems->pref_freq_list_len = elen;
198 break;
199 default:
200 wpa_printf(MSG_EXCESSIVE,
201 "Unknown QCA information element ignored (type=%d len=%lu)",
202 pos[3], (unsigned long) elen);
203 return -1;
204 }
205 break;
206 #endif /* LOS_CONFIG_80211_IES_CROP */
207 #ifdef CONFIG_MESH
208 case WPA_WLAN_OUI_SOC:
209 los_mesh_ie_parse(elems, pos, elen);
210 wpa_error_log2(MSG_ERROR, "get soc mesh bcn_priority : %d, is_mbr : %d",
211 elems->mesh_bcn_priority, elems->mesh_is_mbr);
212 break;
213 #endif
214 default:
215 wpa_msgdump_log4(MSG_EXCESSIVE, "unknown vendor specific "
216 "information element ignored (vendor OUI "
217 "%02x:%02x:%02x len=%lu)",
218 pos[0], pos[1], pos[2], (unsigned long) elen);
219 return -1;
220 }
221
222 return 0;
223 }
224
225 #ifdef CONFIG_OWE
ieee802_11_parse_extension(const u8 * pos,size_t elen,struct ieee802_11_elems * elems,int show_errors)226 static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
227 struct ieee802_11_elems *elems,
228 int show_errors)
229 {
230 u8 ext_id;
231
232 if (elen < 1) {
233 if (show_errors) {
234 wpa_printf(MSG_MSGDUMP,
235 "short information element (Ext)");
236 }
237 return -1;
238 }
239
240 ext_id = *pos++;
241 elen--;
242
243 elems->frag_ies.last_eid_ext = 0;
244
245 switch (ext_id) {
246 #ifndef LOS_CONFIG_80211_IES_CROP
247 case WLAN_EID_EXT_ASSOC_DELAY_INFO:
248 if (elen != 1)
249 break;
250 elems->assoc_delay_info = pos;
251 break;
252 case WLAN_EID_EXT_FILS_REQ_PARAMS:
253 if (elen < 3)
254 break;
255 elems->fils_req_params = pos;
256 elems->fils_req_params_len = elen;
257 break;
258 case WLAN_EID_EXT_FILS_KEY_CONFIRM:
259 elems->fils_key_confirm = pos;
260 elems->fils_key_confirm_len = elen;
261 break;
262 case WLAN_EID_EXT_FILS_SESSION:
263 if (elen != FILS_SESSION_LEN)
264 break;
265 elems->fils_session = pos;
266 break;
267 case WLAN_EID_EXT_FILS_HLP_CONTAINER:
268 if (elen < 2 * ETH_ALEN)
269 break;
270 elems->fils_hlp = pos;
271 elems->fils_hlp_len = elen;
272 break;
273 case WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN:
274 if (elen < 1)
275 break;
276 elems->fils_ip_addr_assign = pos;
277 elems->fils_ip_addr_assign_len = elen;
278 break;
279 case WLAN_EID_EXT_KEY_DELIVERY:
280 if (elen < WPA_KEY_RSC_LEN)
281 break;
282 elems->key_delivery = pos;
283 elems->key_delivery_len = elen;
284 break;
285 case WLAN_EID_EXT_WRAPPED_DATA:
286 elems->wrapped_data = pos;
287 elems->wrapped_data_len = elen;
288 break;
289 case WLAN_EID_EXT_FILS_PUBLIC_KEY:
290 if (elen < 1)
291 break;
292 elems->fils_pk = pos;
293 elems->fils_pk_len = elen;
294 break;
295 case WLAN_EID_EXT_FILS_NONCE:
296 if (elen != FILS_NONCE_LEN)
297 break;
298 elems->fils_nonce = pos;
299 break;
300 #endif /* LOS_CONFIG_80211_IES_CROP */
301 case WLAN_EID_EXT_OWE_DH_PARAM:
302 if (elen < 2)
303 break;
304 elems->owe_dh = pos;
305 elems->owe_dh_len = elen;
306 break;
307 #ifndef LOS_CONFIG_80211_IES_CROP
308 case WLAN_EID_EXT_PASSWORD_IDENTIFIER:
309 elems->password_id = pos;
310 elems->password_id_len = elen;
311 break;
312 case WLAN_EID_EXT_HE_CAPABILITIES:
313 elems->he_capabilities = pos;
314 elems->he_capabilities_len = elen;
315 break;
316 case WLAN_EID_EXT_HE_OPERATION:
317 elems->he_operation = pos;
318 elems->he_operation_len = elen;
319 break;
320 case WLAN_EID_EXT_OCV_OCI:
321 elems->oci = pos;
322 elems->oci_len = elen;
323 break;
324 case WLAN_EID_EXT_SHORT_SSID_LIST:
325 elems->short_ssid_list = pos;
326 elems->short_ssid_list_len = elen;
327 break;
328 case WLAN_EID_EXT_HE_6GHZ_BAND_CAP:
329 if (elen < sizeof(struct ieee80211_he_6ghz_band_cap))
330 break;
331 elems->he_6ghz_band_cap = pos;
332 break;
333 case WLAN_EID_EXT_PASN_PARAMS:
334 elems->pasn_params = pos;
335 elems->pasn_params_len = elen;
336 break;
337 #endif /* LOS_CONFIG_80211_IES_CROP */
338 default:
339 if (show_errors) {
340 wpa_printf(MSG_MSGDUMP,
341 "IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)",
342 ext_id, (unsigned int) elen);
343 }
344 return -1;
345 }
346
347 if (elen == 254)
348 elems->frag_ies.last_eid_ext = ext_id;
349
350 return 0;
351 }
352 #endif
353
ieee802_11_parse_fragment(struct frag_ies_info * frag_ies,const u8 * pos,u8 elen)354 static void ieee802_11_parse_fragment(struct frag_ies_info *frag_ies,
355 const u8 *pos, u8 elen)
356 {
357 if (frag_ies->n_frags >= MAX_NUM_FRAG_IES_SUPPORTED) {
358 wpa_printf(MSG_MSGDUMP, "Too many element fragments - skip");
359 return;
360 }
361
362 /*
363 * Note: while EID == 0 is a valid ID (SSID IE), it should not be
364 * fragmented.
365 */
366 if (!frag_ies->last_eid) {
367 wpa_printf(MSG_MSGDUMP,
368 "Fragment without a valid last element - skip");
369 return;
370 }
371
372 frag_ies->frags[frag_ies->n_frags].ie = pos;
373 frag_ies->frags[frag_ies->n_frags].ie_len = elen;
374 frag_ies->frags[frag_ies->n_frags].eid = frag_ies->last_eid;
375 frag_ies->frags[frag_ies->n_frags].eid_ext = frag_ies->last_eid_ext;
376 frag_ies->n_frags++;
377 }
378
379
380 /**
381 * ieee802_11_parse_elems - Parse information elements in management frames
382 * @start: Pointer to the start of IEs
383 * @len: Length of IE buffer in octets
384 * @elems: Data structure for parsed elements
385 * @show_errors: Whether to show parsing errors in debug log
386 * Returns: Parsing result
387 */
ieee802_11_parse_elems(const u8 * start,size_t len,struct ieee802_11_elems * elems,int show_errors)388 ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
389 struct ieee802_11_elems *elems,
390 int show_errors)
391 {
392 const struct element *elem;
393 int unknown = 0;
394
395 os_memset(elems, 0, sizeof(*elems));
396
397 if (!start)
398 return ParseOK;
399
400 for_each_element(elem, start, len) {
401 u8 id = elem->id, elen = elem->datalen;
402 const u8 *pos = elem->data;
403
404 switch (id) {
405 case WLAN_EID_SSID:
406 if (elen > SSID_MAX_LEN) {
407 wpa_printf(MSG_DEBUG,
408 "Ignored too long SSID element (elen=%u)",
409 elen);
410 break;
411 }
412 if (elems->ssid) {
413 wpa_printf(MSG_MSGDUMP,
414 "Ignored duplicated SSID element");
415 break;
416 }
417 elems->ssid = pos;
418 elems->ssid_len = elen;
419 break;
420 case WLAN_EID_SUPP_RATES:
421 elems->supp_rates = pos;
422 elems->supp_rates_len = elen;
423 break;
424 case WLAN_EID_DS_PARAMS:
425 if (elen < 1)
426 break;
427 elems->ds_params = pos;
428 break;
429 case WLAN_EID_CF_PARAMS:
430 case WLAN_EID_TIM:
431 break;
432 case WLAN_EID_CHALLENGE:
433 elems->challenge = pos;
434 elems->challenge_len = elen;
435 break;
436 #ifndef LOS_CONFIG_80211_IES_CROP
437 case WLAN_EID_ERP_INFO:
438 if (elen < 1)
439 break;
440 elems->erp_info = pos;
441 break;
442 #endif /* LOS_CONFIG_80211_IES_CROP */
443 case WLAN_EID_EXT_SUPP_RATES:
444 elems->ext_supp_rates = pos;
445 elems->ext_supp_rates_len = elen;
446 break;
447 case WLAN_EID_VENDOR_SPECIFIC:
448 if (ieee802_11_parse_vendor_specific(pos, elen,
449 elems,
450 show_errors))
451 unknown++;
452 break;
453 case WLAN_EID_RSN:
454 elems->rsn_ie = pos;
455 elems->rsn_ie_len = elen;
456 break;
457 case WLAN_EID_RSNX:
458 elems->rsnxe = pos;
459 elems->rsnxe_len = elen;
460 break;
461 #ifndef LOS_CONFIG_80211_IES_CROP
462 case WLAN_EID_PWR_CAPABILITY:
463 if (elen < 2)
464 break;
465 elems->power_capab = pos;
466 elems->power_capab_len = elen;
467 break;
468 #endif /* LOS_CONFIG_80211_IES_CROP */
469 case WLAN_EID_SUPPORTED_CHANNELS:
470 elems->supp_channels = pos;
471 elems->supp_channels_len = elen;
472 break;
473 case WLAN_EID_MOBILITY_DOMAIN:
474 if (elen < sizeof(struct rsn_mdie))
475 break;
476 elems->mdie = pos;
477 elems->mdie_len = elen;
478 break;
479 case WLAN_EID_FAST_BSS_TRANSITION:
480 if (elen < sizeof(struct rsn_ftie))
481 break;
482 elems->ftie = pos;
483 elems->ftie_len = elen;
484 break;
485 #ifndef LOS_CONFIG_80211_IES_CROP
486 case WLAN_EID_TIMEOUT_INTERVAL:
487 if (elen != 5)
488 break;
489 elems->timeout_int = pos;
490 break;
491 case WLAN_EID_HT_CAP:
492 if (elen < sizeof(struct ieee80211_ht_capabilities))
493 break;
494 elems->ht_capabilities = pos;
495 break;
496 case WLAN_EID_HT_OPERATION:
497 if (elen < sizeof(struct ieee80211_ht_operation))
498 break;
499 elems->ht_operation = pos;
500 break;
501 #endif /* LOS_CONFIG_80211_IES_CROP */
502 case WLAN_EID_MESH_CONFIG:
503 elems->mesh_config = pos;
504 elems->mesh_config_len = elen;
505 break;
506 case WLAN_EID_MESH_ID:
507 elems->mesh_id = pos;
508 elems->mesh_id_len = elen;
509 break;
510 case WLAN_EID_PEER_MGMT:
511 elems->peer_mgmt = pos;
512 elems->peer_mgmt_len = elen;
513 break;
514 #ifndef EXT_CODE_CROP
515 case WLAN_EID_VHT_CAP:
516 if (elen < sizeof(struct ieee80211_vht_capabilities))
517 break;
518 elems->vht_capabilities = pos;
519 break;
520 case WLAN_EID_VHT_OPERATION:
521 if (elen < sizeof(struct ieee80211_vht_operation))
522 break;
523 elems->vht_operation = pos;
524 break;
525 case WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION:
526 if (elen != 1)
527 break;
528 elems->vht_opmode_notif = pos;
529 break;
530 #endif
531 case WLAN_EID_LINK_ID:
532 if (elen < 18)
533 break;
534 elems->link_id = pos;
535 break;
536 #ifndef EXT_CODE_CROP
537 case WLAN_EID_INTERWORKING:
538 elems->interworking = pos;
539 elems->interworking_len = elen;
540 break;
541 case WLAN_EID_QOS_MAP_SET:
542 if (elen < 16)
543 break;
544 elems->qos_map_set = pos;
545 elems->qos_map_set_len = elen;
546 break;
547 #endif /* LOS_CONFIG_80211_IES_CROP */
548 case WLAN_EID_EXT_CAPAB:
549 elems->ext_capab = pos;
550 elems->ext_capab_len = elen;
551 break;
552 #ifndef LOS_CONFIG_80211_IES_CROP
553 case WLAN_EID_BSS_MAX_IDLE_PERIOD:
554 if (elen < 3)
555 break;
556 elems->bss_max_idle_period = pos;
557 break;
558 case WLAN_EID_SSID_LIST:
559 elems->ssid_list = pos;
560 elems->ssid_list_len = elen;
561 break;
562 #endif /* LOS_CONFIG_80211_IES_CROP */
563 case WLAN_EID_AMPE:
564 elems->ampe = pos;
565 elems->ampe_len = elen;
566 break;
567 case WLAN_EID_MIC:
568 elems->mic = pos;
569 elems->mic_len = elen;
570 /* after mic everything is encrypted, so stop. */
571 goto done;
572 #ifdef CONFIG_MBO
573 case WLAN_EID_MULTI_BAND:
574 if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) {
575 wpa_printf(MSG_MSGDUMP,
576 "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)",
577 id, elen);
578 break;
579 }
580
581 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos;
582 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen;
583 elems->mb_ies.nof_ies++;
584 break;
585 #endif /* CONFIG_MBO */
586 #ifndef LOS_CONFIG_80211_IES_CROP
587 case WLAN_EID_SUPPORTED_OPERATING_CLASSES:
588 elems->supp_op_classes = pos;
589 elems->supp_op_classes_len = elen;
590 break;
591 case WLAN_EID_RRM_ENABLED_CAPABILITIES:
592 elems->rrm_enabled = pos;
593 elems->rrm_enabled_len = elen;
594 break;
595 case WLAN_EID_CAG_NUMBER:
596 elems->cag_number = pos;
597 elems->cag_number_len = elen;
598 break;
599 case WLAN_EID_AP_CSN:
600 if (elen < 1)
601 break;
602 elems->ap_csn = pos;
603 break;
604 case WLAN_EID_FILS_INDICATION:
605 if (elen < 2)
606 break;
607 elems->fils_indic = pos;
608 elems->fils_indic_len = elen;
609 break;
610 case WLAN_EID_DILS:
611 if (elen < 2)
612 break;
613 elems->dils = pos;
614 elems->dils_len = elen;
615 break;
616 case WLAN_EID_S1G_CAPABILITIES:
617 if (elen < 15)
618 break;
619 elems->s1g_capab = pos;
620 break;
621 case WLAN_EID_FRAGMENT:
622 ieee802_11_parse_fragment(&elems->frag_ies, pos, elen);
623 break;
624 #endif /* LOS_CONFIG_80211_IES_CROP */
625 #ifdef CONFIG_OWE
626 case WLAN_EID_EXTENSION:
627 if (ieee802_11_parse_extension(pos, elen, elems,
628 show_errors))
629 unknown++;
630 break;
631 #endif /* CONFIG_OWE */
632 default:
633 unknown++;
634 if (!show_errors)
635 break;
636 #ifndef CONFIG_PRINT_NOUSE
637 wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse "
638 "ignored unknown element (id=%d elen=%d)",
639 id, elen);
640 #endif /* CONFIG_PRINT_NOUSE */
641 break;
642 }
643
644 if (id != WLAN_EID_FRAGMENT && elen == 255)
645 elems->frag_ies.last_eid = id;
646
647 if (id == WLAN_EID_EXTENSION && !elems->frag_ies.last_eid_ext)
648 elems->frag_ies.last_eid = 0;
649 }
650
651 if (!for_each_element_completed(elem, start, len)) {
652 if (show_errors) {
653 wpa_printf(MSG_DEBUG,
654 "IEEE 802.11 element parse failed @%d",
655 (int) (start + len - (const u8 *) elem));
656 wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
657 }
658 return ParseFailed;
659 }
660
661 done:
662 return unknown ? ParseUnknown : ParseOK;
663 }
664
665
ieee802_11_ie_count(const u8 * ies,size_t ies_len)666 int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
667 {
668 const struct element *elem;
669 int count = 0;
670
671 if (ies == NULL)
672 return 0;
673
674 for_each_element(elem, ies, ies_len)
675 count++;
676
677 return count;
678 }
679
680
ieee802_11_vendor_ie_concat(const u8 * ies,size_t ies_len,u32 oui_type)681 struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
682 u32 oui_type)
683 {
684 struct wpabuf *buf;
685 const struct element *elem, *found = NULL;
686
687 for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) {
688 if (elem->datalen >= 4 &&
689 WPA_GET_BE32(elem->data) == oui_type) {
690 found = elem;
691 break;
692 }
693 }
694
695 if (!found)
696 return NULL; /* No specified vendor IE found */
697
698 buf = wpabuf_alloc(ies_len);
699 if (buf == NULL)
700 return NULL;
701
702 /*
703 * There may be multiple vendor IEs in the message, so need to
704 * concatenate their data fields.
705 */
706 for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) {
707 if (elem->datalen >= 4 && WPA_GET_BE32(elem->data) == oui_type)
708 wpabuf_put_data(buf, elem->data + 4, elem->datalen - 4);
709 }
710
711 return buf;
712 }
713
714
get_hdr_bssid(const struct ieee80211_hdr * hdr,size_t len)715 const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
716 {
717 u16 fc, type, stype;
718
719 /*
720 * PS-Poll frames are 16 bytes. All other frames are
721 * 24 bytes or longer.
722 */
723 if (len < 16)
724 return NULL;
725
726 fc = le_to_host16(hdr->frame_control);
727 type = WLAN_FC_GET_TYPE(fc);
728 stype = WLAN_FC_GET_STYPE(fc);
729
730 switch (type) {
731 case WLAN_FC_TYPE_DATA:
732 if (len < 24)
733 return NULL;
734 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
735 case WLAN_FC_FROMDS | WLAN_FC_TODS:
736 case WLAN_FC_TODS:
737 return hdr->addr1;
738 case WLAN_FC_FROMDS:
739 return hdr->addr2;
740 default:
741 return NULL;
742 }
743 case WLAN_FC_TYPE_CTRL:
744 if (stype != WLAN_FC_STYPE_PSPOLL)
745 return NULL;
746 return hdr->addr1;
747 case WLAN_FC_TYPE_MGMT:
748 return hdr->addr3;
749 default:
750 return NULL;
751 }
752 }
753 #ifndef LOS_CONFIG_HOSTAPD_QOS
754
hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],const char * name,const char * val)755 int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
756 const char *name, const char *val)
757 {
758 int num, v;
759 const char *pos;
760 struct hostapd_wmm_ac_params *ac;
761
762 /* skip 'wme_ac_' or 'wmm_ac_' prefix */
763 pos = name + 7;
764 if (os_strncmp(pos, "be_", 3) == 0) {
765 num = 0;
766 pos += 3;
767 } else if (os_strncmp(pos, "bk_", 3) == 0) {
768 num = 1;
769 pos += 3;
770 } else if (os_strncmp(pos, "vi_", 3) == 0) {
771 num = 2;
772 pos += 3;
773 } else if (os_strncmp(pos, "vo_", 3) == 0) {
774 num = 3;
775 pos += 3;
776 } else {
777 wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos);
778 return -1;
779 }
780
781 ac = &wmm_ac_params[num];
782
783 if (os_strcmp(pos, "aifs") == 0) {
784 v = atoi(val);
785 if (v < 1 || v > 255) {
786 wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v);
787 return -1;
788 }
789 ac->aifs = v;
790 } else if (os_strcmp(pos, "cwmin") == 0) {
791 v = atoi(val);
792 if (v < 0 || v > 15) {
793 wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v);
794 return -1;
795 }
796 ac->cwmin = v;
797 } else if (os_strcmp(pos, "cwmax") == 0) {
798 v = atoi(val);
799 if (v < 0 || v > 15) {
800 wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v);
801 return -1;
802 }
803 ac->cwmax = v;
804 } else if (os_strcmp(pos, "txop_limit") == 0) {
805 v = atoi(val);
806 if (v < 0 || v > 0xffff) {
807 wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
808 return -1;
809 }
810 ac->txop_limit = v;
811 } else if (os_strcmp(pos, "acm") == 0) {
812 v = atoi(val);
813 if (v < 0 || v > 1) {
814 wpa_printf(MSG_ERROR, "Invalid acm value %d", v);
815 return -1;
816 }
817 ac->admission_control_mandatory = v;
818 } else {
819 wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos);
820 return -1;
821 }
822
823 return 0;
824 }
825 #endif
826
827 /* convert floats with one decimal place to value*10 int, i.e.,
828 * "1.5" will return 15
829 */
hostapd_config_read_int10(const char * value)830 static int hostapd_config_read_int10(const char *value)
831 {
832 int i, d;
833 char *pos;
834
835 i = atoi(value);
836 pos = os_strchr(value, '.');
837 d = 0;
838 if (pos) {
839 pos++;
840 if (*pos >= '0' && *pos <= '9')
841 d = *pos - '0';
842 }
843
844 return i * 10 + d;
845 }
846
847
valid_cw(int cw)848 static int valid_cw(int cw)
849 {
850 return (cw == 1 || cw == 3 || cw == 7 || cw == 15 || cw == 31 ||
851 cw == 63 || cw == 127 || cw == 255 || cw == 511 || cw == 1023 ||
852 cw == 2047 || cw == 4095 || cw == 8191 || cw == 16383 ||
853 cw == 32767);
854 }
855
856
hostapd_config_tx_queue(struct hostapd_tx_queue_params tx_queue[],const char * name,const char * val)857 int hostapd_config_tx_queue(struct hostapd_tx_queue_params tx_queue[],
858 const char *name, const char *val)
859 {
860 int num;
861 const char *pos;
862 struct hostapd_tx_queue_params *queue;
863
864 /* skip 'tx_queue_' prefix */
865 pos = name + 9;
866 if (os_strncmp(pos, "data", 4) == 0 &&
867 pos[4] >= '0' && pos[4] <= '9' && pos[5] == '_') {
868 num = pos[4] - '0';
869 pos += 6;
870 } else if (os_strncmp(pos, "after_beacon_", 13) == 0 ||
871 os_strncmp(pos, "beacon_", 7) == 0) {
872 wpa_printf(MSG_INFO, "DEPRECATED: '%s' not used", name);
873 return 0;
874 } else {
875 wpa_printf(MSG_ERROR, "Unknown tx_queue name '%s'", pos);
876 return -1;
877 }
878
879 if (num >= NUM_TX_QUEUES) {
880 /* for backwards compatibility, do not trigger failure */
881 wpa_printf(MSG_INFO, "DEPRECATED: '%s' not used", name);
882 return 0;
883 }
884
885 queue = &tx_queue[num];
886
887 if (os_strcmp(pos, "aifs") == 0) {
888 queue->aifs = atoi(val);
889 if (queue->aifs < 0 || queue->aifs > 255) {
890 wpa_printf(MSG_ERROR, "Invalid AIFS value %d",
891 queue->aifs);
892 return -1;
893 }
894 } else if (os_strcmp(pos, "cwmin") == 0) {
895 queue->cwmin = atoi(val);
896 if (!valid_cw(queue->cwmin)) {
897 wpa_printf(MSG_ERROR, "Invalid cwMin value %d",
898 queue->cwmin);
899 return -1;
900 }
901 } else if (os_strcmp(pos, "cwmax") == 0) {
902 queue->cwmax = atoi(val);
903 if (!valid_cw(queue->cwmax)) {
904 wpa_printf(MSG_ERROR, "Invalid cwMax value %d",
905 queue->cwmax);
906 return -1;
907 }
908 } else if (os_strcmp(pos, "burst") == 0) {
909 queue->burst = hostapd_config_read_int10(val);
910 } else {
911 wpa_printf(MSG_ERROR, "Unknown queue field '%s'", pos);
912 return -1;
913 }
914
915 return 0;
916 }
917
918
ieee80211_freq_to_chan(int freq,u8 * channel)919 enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel)
920 {
921 u8 op_class;
922
923 #ifndef EXT_CODE_CROP
924 return ieee80211_freq_to_channel_ext(freq, 0, CHANWIDTH_USE_HT,
925 #else
926 return ieee80211_freq_to_channel_ext(freq, 0,
927 #endif /* EXT_CODE_CROP */
928 &op_class, channel);
929 }
930
931
932 /**
933 * ieee80211_freq_to_channel_ext - Convert frequency into channel info
934 * for HT40, VHT, and HE. DFS channels are not covered.
935 * @freq: Frequency (MHz) to convert
936 * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
937 * @chanwidth: VHT/EDMG channel width (CHANWIDTH_*)
938 * @op_class: Buffer for returning operating class
939 * @channel: Buffer for returning channel number
940 * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
941 */
ieee80211_freq_to_channel_ext(unsigned int freq,int sec_channel,int chanwidth,u8 * op_class,u8 * channel)942 enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
943 int sec_channel,
944 #ifndef EXT_CODE_CROP
945 int chanwidth,
946 #endif /* EXT_CODE_CROP */
947 u8 *op_class, u8 *channel)
948 {
949 #ifndef EXT_CODE_CROP
950 u8 vht_opclass;
951
952 /* TODO: more operating classes */
953
954 if (sec_channel > 1 || sec_channel < -1)
955 return NUM_HOSTAPD_MODES;
956 #else
957 (void)sec_channel;
958 #endif /* EXT_CODE_CROP */
959
960 if (freq >= 2412 && freq <= 2472) {
961 if ((freq - 2407) % 5)
962 return NUM_HOSTAPD_MODES;
963
964 #ifndef EXT_CODE_CROP
965 if (chanwidth)
966 return NUM_HOSTAPD_MODES;
967
968 /* 2.407 GHz, channels 1..13 */
969 if (sec_channel == 1)
970 *op_class = 83;
971 else if (sec_channel == -1)
972 *op_class = 84;
973 else
974 #endif /* EXT_CODE_CROP */
975 *op_class = 81;
976
977 *channel = (freq - 2407) / 5;
978
979 return HOSTAPD_MODE_IEEE80211G;
980 }
981
982 if (freq == 2484) {
983 #ifndef EXT_CODE_CROP
984 if (sec_channel || chanwidth)
985 return NUM_HOSTAPD_MODES;
986 #endif /* EXT_CODE_CROP */
987
988 *op_class = 82; /* channel 14 */
989 *channel = 14;
990
991 return HOSTAPD_MODE_IEEE80211B;
992 }
993 #ifndef EXT_CODE_CROP
994 if (freq >= 4900 && freq < 5000) {
995 if ((freq - 4000) % 5)
996 return NUM_HOSTAPD_MODES;
997 *channel = (freq - 4000) / 5;
998 *op_class = 0; /* TODO */
999 return HOSTAPD_MODE_IEEE80211A;
1000 }
1001
1002 switch (chanwidth) {
1003 case CHANWIDTH_80MHZ:
1004 vht_opclass = 128;
1005 break;
1006 case CHANWIDTH_160MHZ:
1007 vht_opclass = 129;
1008 break;
1009 case CHANWIDTH_80P80MHZ:
1010 vht_opclass = 130;
1011 break;
1012 default:
1013 vht_opclass = 0;
1014 break;
1015 }
1016
1017 /* 5 GHz, channels 36..48 */
1018 if (freq >= 5180 && freq <= 5240) {
1019 if ((freq - 5000) % 5)
1020 return NUM_HOSTAPD_MODES;
1021
1022 if (vht_opclass)
1023 *op_class = vht_opclass;
1024 else if (sec_channel == 1)
1025 *op_class = 116;
1026 else if (sec_channel == -1)
1027 *op_class = 117;
1028 else
1029 *op_class = 115;
1030
1031 *channel = (freq - 5000) / 5;
1032
1033 return HOSTAPD_MODE_IEEE80211A;
1034 }
1035
1036 /* 5 GHz, channels 52..64 */
1037 if (freq >= 5260 && freq <= 5320) {
1038 if ((freq - 5000) % 5)
1039 return NUM_HOSTAPD_MODES;
1040
1041 if (vht_opclass)
1042 *op_class = vht_opclass;
1043 else if (sec_channel == 1)
1044 *op_class = 119;
1045 else if (sec_channel == -1)
1046 *op_class = 120;
1047 else
1048 *op_class = 118;
1049
1050 *channel = (freq - 5000) / 5;
1051
1052 return HOSTAPD_MODE_IEEE80211A;
1053 }
1054
1055 /* 5 GHz, channels 149..177 */
1056 if (freq >= 5745 && freq <= 5885) {
1057 if ((freq - 5000) % 5)
1058 return NUM_HOSTAPD_MODES;
1059
1060 if (vht_opclass)
1061 *op_class = vht_opclass;
1062 else if (sec_channel == 1)
1063 *op_class = 126;
1064 else if (sec_channel == -1)
1065 *op_class = 127;
1066 else if (freq <= 5805)
1067 *op_class = 124;
1068 else
1069 *op_class = 125;
1070
1071 *channel = (freq - 5000) / 5;
1072
1073 return HOSTAPD_MODE_IEEE80211A;
1074 }
1075
1076 /* 5 GHz, channels 100..144 */
1077 if (freq >= 5500 && freq <= 5720) {
1078 if ((freq - 5000) % 5)
1079 return NUM_HOSTAPD_MODES;
1080
1081 if (vht_opclass)
1082 *op_class = vht_opclass;
1083 else if (sec_channel == 1)
1084 *op_class = 122;
1085 else if (sec_channel == -1)
1086 *op_class = 123;
1087 else
1088 *op_class = 121;
1089
1090 *channel = (freq - 5000) / 5;
1091
1092 return HOSTAPD_MODE_IEEE80211A;
1093 }
1094
1095 if (freq >= 5000 && freq < 5900) {
1096 if ((freq - 5000) % 5)
1097 return NUM_HOSTAPD_MODES;
1098 *channel = (freq - 5000) / 5;
1099 *op_class = 0; /* TODO */
1100 return HOSTAPD_MODE_IEEE80211A;
1101 }
1102
1103 if (freq > 5950 && freq <= 7115) {
1104 if ((freq - 5950) % 5)
1105 return NUM_HOSTAPD_MODES;
1106
1107 switch (chanwidth) {
1108 case CHANWIDTH_80MHZ:
1109 *op_class = 133;
1110 break;
1111 case CHANWIDTH_160MHZ:
1112 *op_class = 134;
1113 break;
1114 case CHANWIDTH_80P80MHZ:
1115 *op_class = 135;
1116 break;
1117 default:
1118 if (sec_channel)
1119 *op_class = 132;
1120 else
1121 *op_class = 131;
1122 break;
1123 }
1124
1125 *channel = (freq - 5950) / 5;
1126 return HOSTAPD_MODE_IEEE80211A;
1127 }
1128
1129 if (freq == 5935) {
1130 *op_class = 136;
1131 *channel = (freq - 5925) / 5;
1132 return HOSTAPD_MODE_IEEE80211A;
1133 }
1134
1135 /* 56.16 GHz, channel 1..6 */
1136 if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 6) {
1137 if (sec_channel)
1138 return NUM_HOSTAPD_MODES;
1139
1140 switch (chanwidth) {
1141 case CHANWIDTH_USE_HT:
1142 case CHANWIDTH_2160MHZ:
1143 *channel = (freq - 56160) / 2160;
1144 *op_class = 180;
1145 break;
1146 case CHANWIDTH_4320MHZ:
1147 /* EDMG channels 9 - 13 */
1148 if (freq > 56160 + 2160 * 5)
1149 return NUM_HOSTAPD_MODES;
1150
1151 *channel = (freq - 56160) / 2160 + 8;
1152 *op_class = 181;
1153 break;
1154 case CHANWIDTH_6480MHZ:
1155 /* EDMG channels 17 - 20 */
1156 if (freq > 56160 + 2160 * 4)
1157 return NUM_HOSTAPD_MODES;
1158
1159 *channel = (freq - 56160) / 2160 + 16;
1160 *op_class = 182;
1161 break;
1162 case CHANWIDTH_8640MHZ:
1163 /* EDMG channels 25 - 27 */
1164 if (freq > 56160 + 2160 * 3)
1165 return NUM_HOSTAPD_MODES;
1166
1167 *channel = (freq - 56160) / 2160 + 24;
1168 *op_class = 183;
1169 break;
1170 default:
1171 return NUM_HOSTAPD_MODES;
1172 }
1173
1174 return HOSTAPD_MODE_IEEE80211AD;
1175 }
1176 #endif /* EXT_CODE_CROP */
1177 return NUM_HOSTAPD_MODES;
1178 }
1179
1180
ieee80211_chaninfo_to_channel(unsigned int freq,enum chan_width chanwidth,int sec_channel,u8 * op_class,u8 * channel)1181 int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
1182 int sec_channel, u8 *op_class, u8 *channel)
1183 {
1184 #ifndef EXT_CODE_CROP
1185 int cw = CHAN_WIDTH_UNKNOWN;
1186
1187 switch (chanwidth) {
1188 case CHAN_WIDTH_UNKNOWN:
1189 case CHAN_WIDTH_20_NOHT:
1190 case CHAN_WIDTH_20:
1191 case CHAN_WIDTH_40:
1192 cw = CHANWIDTH_USE_HT;
1193 break;
1194 case CHAN_WIDTH_80:
1195 cw = CHANWIDTH_80MHZ;
1196 break;
1197 case CHAN_WIDTH_80P80:
1198 cw = CHANWIDTH_80P80MHZ;
1199 break;
1200 case CHAN_WIDTH_160:
1201 cw = CHANWIDTH_160MHZ;
1202 break;
1203 case CHAN_WIDTH_2160:
1204 cw = CHANWIDTH_2160MHZ;
1205 break;
1206 case CHAN_WIDTH_4320:
1207 cw = CHANWIDTH_4320MHZ;
1208 break;
1209 case CHAN_WIDTH_6480:
1210 cw = CHANWIDTH_6480MHZ;
1211 break;
1212 case CHAN_WIDTH_8640:
1213 cw = CHANWIDTH_8640MHZ;
1214 break;
1215 }
1216 #endif /* EXT_CODE_CROP */
1217
1218 if (ieee80211_freq_to_channel_ext(freq, sec_channel,
1219 #ifndef EXT_CODE_CROP
1220 cw,
1221 #endif /* EXT_CODE_CROP */
1222 op_class, channel) == NUM_HOSTAPD_MODES) {
1223 wpa_printf(MSG_WARNING,
1224 "Cannot determine operating class and channel (freq=%u chanwidth=%d sec_channel=%d)",
1225 freq, chanwidth, sec_channel);
1226 return -1;
1227 }
1228
1229 return 0;
1230 }
1231
1232
1233 static const char *const us_op_class_cc[] = {
1234 "US", "CA", NULL
1235 };
1236
1237 static const char *const eu_op_class_cc[] = {
1238 "AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
1239 "DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
1240 "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
1241 "RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL
1242 };
1243
1244 static const char *const jp_op_class_cc[] = {
1245 "JP", NULL
1246 };
1247
1248 static const char *const cn_op_class_cc[] = {
1249 "CN", NULL
1250 };
1251
1252
country_match(const char * const cc[],const char * const country)1253 static int country_match(const char *const cc[], const char *const country)
1254 {
1255 int i;
1256
1257 if (country == NULL)
1258 return 0;
1259 for (i = 0; cc[i]; i++) {
1260 if (cc[i][0] == country[0] && cc[i][1] == country[1])
1261 return 1;
1262 }
1263
1264 return 0;
1265 }
1266
1267
ieee80211_chan_to_freq_us(u8 op_class,u8 chan)1268 static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan)
1269 {
1270 switch (op_class) {
1271 case 12: /* channels 1..11 */
1272 case 32: /* channels 1..7; 40 MHz */
1273 case 33: /* channels 5..11; 40 MHz */
1274 if (chan < 1 || chan > 11)
1275 return -1;
1276 return 2407 + 5 * chan;
1277 case 1: /* channels 36,40,44,48 */
1278 case 2: /* channels 52,56,60,64; dfs */
1279 case 22: /* channels 36,44; 40 MHz */
1280 case 23: /* channels 52,60; 40 MHz */
1281 case 27: /* channels 40,48; 40 MHz */
1282 case 28: /* channels 56,64; 40 MHz */
1283 if (chan < 36 || chan > 64)
1284 return -1;
1285 return 5000 + 5 * chan;
1286 case 4: /* channels 100-144 */
1287 case 24: /* channels 100-140; 40 MHz */
1288 if (chan < 100 || chan > 144)
1289 return -1;
1290 return 5000 + 5 * chan;
1291 case 3: /* channels 149,153,157,161 */
1292 case 25: /* channels 149,157; 40 MHz */
1293 case 26: /* channels 149,157; 40 MHz */
1294 case 30: /* channels 153,161; 40 MHz */
1295 case 31: /* channels 153,161; 40 MHz */
1296 if (chan < 149 || chan > 161)
1297 return -1;
1298 return 5000 + 5 * chan;
1299 case 5: /* channels 149,153,157,161,165 */
1300 if (chan < 149 || chan > 165)
1301 return -1;
1302 return 5000 + 5 * chan;
1303 case 34: /* 60 GHz band, channels 1..8 */
1304 if (chan < 1 || chan > 8)
1305 return -1;
1306 return 56160 + 2160 * chan;
1307 case 37: /* 60 GHz band, EDMG CB2, channels 9..15 */
1308 if (chan < 9 || chan > 15)
1309 return -1;
1310 return 56160 + 2160 * (chan - 8);
1311 case 38: /* 60 GHz band, EDMG CB3, channels 17..22 */
1312 if (chan < 17 || chan > 22)
1313 return -1;
1314 return 56160 + 2160 * (chan - 16);
1315 case 39: /* 60 GHz band, EDMG CB4, channels 25..29 */
1316 if (chan < 25 || chan > 29)
1317 return -1;
1318 return 56160 + 2160 * (chan - 24);
1319 }
1320 return -1;
1321 }
1322
1323
ieee80211_chan_to_freq_eu(u8 op_class,u8 chan)1324 static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan)
1325 {
1326 switch (op_class) {
1327 case 4: /* channels 1..13 */
1328 case 11: /* channels 1..9; 40 MHz */
1329 case 12: /* channels 5..13; 40 MHz */
1330 if (chan < 1 || chan > 13)
1331 return -1;
1332 return 2407 + 5 * chan;
1333 case 1: /* channels 36,40,44,48 */
1334 case 2: /* channels 52,56,60,64; dfs */
1335 case 5: /* channels 36,44; 40 MHz */
1336 case 6: /* channels 52,60; 40 MHz */
1337 case 8: /* channels 40,48; 40 MHz */
1338 case 9: /* channels 56,64; 40 MHz */
1339 if (chan < 36 || chan > 64)
1340 return -1;
1341 return 5000 + 5 * chan;
1342 case 3: /* channels 100-140 */
1343 case 7: /* channels 100-132; 40 MHz */
1344 case 10: /* channels 104-136; 40 MHz */
1345 case 16: /* channels 100-140 */
1346 if (chan < 100 || chan > 140)
1347 return -1;
1348 return 5000 + 5 * chan;
1349 case 17: /* channels 149,153,157,161,165,169 */
1350 if (chan < 149 || chan > 169)
1351 return -1;
1352 return 5000 + 5 * chan;
1353 case 18: /* 60 GHz band, channels 1..6 */
1354 if (chan < 1 || chan > 6)
1355 return -1;
1356 return 56160 + 2160 * chan;
1357 case 21: /* 60 GHz band, EDMG CB2, channels 9..11 */
1358 if (chan < 9 || chan > 11)
1359 return -1;
1360 return 56160 + 2160 * (chan - 8);
1361 case 22: /* 60 GHz band, EDMG CB3, channels 17..18 */
1362 if (chan < 17 || chan > 18)
1363 return -1;
1364 return 56160 + 2160 * (chan - 16);
1365 case 23: /* 60 GHz band, EDMG CB4, channels 25 */
1366 if (chan != 25)
1367 return -1;
1368 return 56160 + 2160 * (chan - 24);
1369 }
1370 return -1;
1371 }
1372
1373
ieee80211_chan_to_freq_jp(u8 op_class,u8 chan)1374 static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan)
1375 {
1376 switch (op_class) {
1377 case 30: /* channels 1..13 */
1378 case 56: /* channels 1..9; 40 MHz */
1379 case 57: /* channels 5..13; 40 MHz */
1380 if (chan < 1 || chan > 13)
1381 return -1;
1382 return 2407 + 5 * chan;
1383 case 31: /* channel 14 */
1384 if (chan != 14)
1385 return -1;
1386 return 2414 + 5 * chan;
1387 case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */
1388 case 32: /* channels 52,56,60,64 */
1389 case 33: /* channels 52,56,60,64 */
1390 case 36: /* channels 36,44; 40 MHz */
1391 case 37: /* channels 52,60; 40 MHz */
1392 case 38: /* channels 52,60; 40 MHz */
1393 case 41: /* channels 40,48; 40 MHz */
1394 case 42: /* channels 56,64; 40 MHz */
1395 case 43: /* channels 56,64; 40 MHz */
1396 if (chan < 34 || chan > 64)
1397 return -1;
1398 return 5000 + 5 * chan;
1399 case 34: /* channels 100-140 */
1400 case 35: /* channels 100-140 */
1401 case 39: /* channels 100-132; 40 MHz */
1402 case 40: /* channels 100-132; 40 MHz */
1403 case 44: /* channels 104-136; 40 MHz */
1404 case 45: /* channels 104-136; 40 MHz */
1405 case 58: /* channels 100-140 */
1406 if (chan < 100 || chan > 140)
1407 return -1;
1408 return 5000 + 5 * chan;
1409 case 59: /* 60 GHz band, channels 1..6 */
1410 if (chan < 1 || chan > 6)
1411 return -1;
1412 return 56160 + 2160 * chan;
1413 case 62: /* 60 GHz band, EDMG CB2, channels 9..11 */
1414 if (chan < 9 || chan > 11)
1415 return -1;
1416 return 56160 + 2160 * (chan - 8);
1417 case 63: /* 60 GHz band, EDMG CB3, channels 17..18 */
1418 if (chan < 17 || chan > 18)
1419 return -1;
1420 return 56160 + 2160 * (chan - 16);
1421 case 64: /* 60 GHz band, EDMG CB4, channel 25 */
1422 if (chan != 25)
1423 return -1;
1424 return 56160 + 2160 * (chan - 24);
1425 }
1426 return -1;
1427 }
1428
1429
ieee80211_chan_to_freq_cn(u8 op_class,u8 chan)1430 static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan)
1431 {
1432 switch (op_class) {
1433 case 7: /* channels 1..13 */
1434 case 8: /* channels 1..9; 40 MHz */
1435 case 9: /* channels 5..13; 40 MHz */
1436 if (chan < 1 || chan > 13)
1437 return -1;
1438 return 2407 + 5 * chan;
1439 case 1: /* channels 36,40,44,48 */
1440 case 2: /* channels 52,56,60,64; dfs */
1441 case 4: /* channels 36,44; 40 MHz */
1442 case 5: /* channels 52,60; 40 MHz */
1443 if (chan < 36 || chan > 64)
1444 return -1;
1445 return 5000 + 5 * chan;
1446 case 3: /* channels 149,153,157,161,165 */
1447 case 6: /* channels 149,157; 40 MHz */
1448 if (chan < 149 || chan > 165)
1449 return -1;
1450 return 5000 + 5 * chan;
1451 }
1452 return -1;
1453 }
1454
1455
ieee80211_chan_to_freq_global(u8 op_class,u8 chan)1456 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
1457 {
1458 /* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
1459 switch (op_class) {
1460 case 81:
1461 /* channels 1..13 */
1462 if (chan < 1 || chan > 13)
1463 return -1;
1464 return 2407 + 5 * chan;
1465 case 82:
1466 /* channel 14 */
1467 if (chan != 14)
1468 return -1;
1469 return 2414 + 5 * chan;
1470 case 83: /* channels 1..9; 40 MHz */
1471 case 84: /* channels 5..13; 40 MHz */
1472 if (chan < 1 || chan > 13)
1473 return -1;
1474 return 2407 + 5 * chan;
1475 case 115: /* channels 36,40,44,48; indoor only */
1476 case 116: /* channels 36,44; 40 MHz; indoor only */
1477 case 117: /* channels 40,48; 40 MHz; indoor only */
1478 case 118: /* channels 52,56,60,64; dfs */
1479 case 119: /* channels 52,60; 40 MHz; dfs */
1480 case 120: /* channels 56,64; 40 MHz; dfs */
1481 if (chan < 36 || chan > 64)
1482 return -1;
1483 return 5000 + 5 * chan;
1484 case 121: /* channels 100-140 */
1485 case 122: /* channels 100-142; 40 MHz */
1486 case 123: /* channels 104-136; 40 MHz */
1487 if (chan < 100 || chan > 140)
1488 return -1;
1489 return 5000 + 5 * chan;
1490 case 124: /* channels 149,153,157,161 */
1491 if (chan < 149 || chan > 161)
1492 return -1;
1493 return 5000 + 5 * chan;
1494 case 125: /* channels 149,153,157,161,165,169,173,177 */
1495 case 126: /* channels 149,157,165,173; 40 MHz */
1496 case 127: /* channels 153,161,169,177; 40 MHz */
1497 if (chan < 149 || chan > 177)
1498 return -1;
1499 return 5000 + 5 * chan;
1500 case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
1501 case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
1502 if (chan < 36 || chan > 177)
1503 return -1;
1504 return 5000 + 5 * chan;
1505 case 129: /* center freqs 50, 114, 163; 160 MHz */
1506 if (chan < 36 || chan > 177)
1507 return -1;
1508 return 5000 + 5 * chan;
1509 case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
1510 case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
1511 case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
1512 case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
1513 case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
1514 if (chan < 1 || chan > 233)
1515 return -1;
1516 return 5950 + chan * 5;
1517 case 136: /* UHB channels, 20 MHz: 2 */
1518 if (chan == 2)
1519 return 5935;
1520 return -1;
1521 case 180: /* 60 GHz band, channels 1..8 */
1522 if (chan < 1 || chan > 8)
1523 return -1;
1524 return 56160 + 2160 * chan;
1525 case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
1526 if (chan < 9 || chan > 15)
1527 return -1;
1528 return 56160 + 2160 * (chan - 8);
1529 case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
1530 if (chan < 17 || chan > 22)
1531 return -1;
1532 return 56160 + 2160 * (chan - 16);
1533 case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
1534 if (chan < 25 || chan > 29)
1535 return -1;
1536 return 56160 + 2160 * (chan - 24);
1537 }
1538 return -1;
1539 }
1540
1541 /**
1542 * ieee80211_chan_to_freq - Convert channel info to frequency
1543 * @country: Country code, if known; otherwise, global operating class is used
1544 * @op_class: Operating class
1545 * @chan: Channel number
1546 * Returns: Frequency in MHz or -1 if the specified channel is unknown
1547 */
ieee80211_chan_to_freq(const char * country,u8 op_class,u8 chan)1548 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan)
1549 {
1550 #ifndef EXT_CODE_CROP
1551 int freq;
1552
1553 if (country_match(us_op_class_cc, country)) {
1554 freq = ieee80211_chan_to_freq_us(op_class, chan);
1555 if (freq > 0)
1556 return freq;
1557 }
1558
1559 if (country_match(eu_op_class_cc, country)) {
1560 freq = ieee80211_chan_to_freq_eu(op_class, chan);
1561 if (freq > 0)
1562 return freq;
1563 }
1564
1565 if (country_match(jp_op_class_cc, country)) {
1566 freq = ieee80211_chan_to_freq_jp(op_class, chan);
1567 if (freq > 0)
1568 return freq;
1569 }
1570
1571 if (country_match(cn_op_class_cc, country)) {
1572 freq = ieee80211_chan_to_freq_cn(op_class, chan);
1573 if (freq > 0)
1574 return freq;
1575 }
1576
1577 return ieee80211_chan_to_freq_global(op_class, chan);
1578 #else
1579 if (chan < 1 || chan > 14)
1580 return -1;
1581 if (chan == 14) {
1582 return 2484;
1583 }
1584 return 2407 + 5 * chan;
1585 #endif
1586 }
1587
1588
ieee80211_is_dfs(int freq,const struct hostapd_hw_modes * modes,u16 num_modes)1589 int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
1590 u16 num_modes)
1591 {
1592 int i, j;
1593
1594 if (!modes || !num_modes)
1595 return (freq >= 5260 && freq <= 5320) ||
1596 (freq >= 5500 && freq <= 5700);
1597
1598 for (i = 0; i < num_modes; i++) {
1599 for (j = 0; j < modes[i].num_channels; j++) {
1600 if (modes[i].channels[j].freq == freq &&
1601 (modes[i].channels[j].flag & HOSTAPD_CHAN_RADAR))
1602 return 1;
1603 }
1604 }
1605
1606 return 0;
1607 }
1608
1609
1610 /*
1611 * 802.11-2020: Table E-4 - Global operating classes
1612 * DFS_50_100_Behavior: 118, 119, 120, 121, 122, 123
1613 */
is_dfs_global_op_class(u8 op_class)1614 int is_dfs_global_op_class(u8 op_class)
1615 {
1616 return (op_class >= 118) && (op_class <= 123);
1617 }
1618
1619
is_11b(u8 rate)1620 static int is_11b(u8 rate)
1621 {
1622 return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
1623 }
1624
1625
supp_rates_11b_only(struct ieee802_11_elems * elems)1626 int supp_rates_11b_only(struct ieee802_11_elems *elems)
1627 {
1628 int num_11b = 0, num_others = 0;
1629 int i;
1630
1631 if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
1632 return 0;
1633
1634 for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
1635 if (is_11b(elems->supp_rates[i]))
1636 num_11b++;
1637 else
1638 num_others++;
1639 }
1640
1641 for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
1642 i++) {
1643 if (is_11b(elems->ext_supp_rates[i]))
1644 num_11b++;
1645 else
1646 num_others++;
1647 }
1648
1649 return num_11b > 0 && num_others == 0;
1650 }
1651
1652
fc2str(u16 fc)1653 const char * fc2str(u16 fc)
1654 {
1655 u16 stype = WLAN_FC_GET_STYPE(fc);
1656 #define C2S(x) case x: return #x;
1657
1658 switch (WLAN_FC_GET_TYPE(fc)) {
1659 case WLAN_FC_TYPE_MGMT:
1660 switch (stype) {
1661 C2S(WLAN_FC_STYPE_ASSOC_REQ)
1662 C2S(WLAN_FC_STYPE_ASSOC_RESP)
1663 C2S(WLAN_FC_STYPE_REASSOC_REQ)
1664 C2S(WLAN_FC_STYPE_REASSOC_RESP)
1665 C2S(WLAN_FC_STYPE_PROBE_REQ)
1666 C2S(WLAN_FC_STYPE_PROBE_RESP)
1667 C2S(WLAN_FC_STYPE_BEACON)
1668 C2S(WLAN_FC_STYPE_ATIM)
1669 C2S(WLAN_FC_STYPE_DISASSOC)
1670 C2S(WLAN_FC_STYPE_AUTH)
1671 C2S(WLAN_FC_STYPE_DEAUTH)
1672 C2S(WLAN_FC_STYPE_ACTION)
1673 }
1674 break;
1675 case WLAN_FC_TYPE_CTRL:
1676 switch (stype) {
1677 C2S(WLAN_FC_STYPE_PSPOLL)
1678 C2S(WLAN_FC_STYPE_RTS)
1679 C2S(WLAN_FC_STYPE_CTS)
1680 C2S(WLAN_FC_STYPE_ACK)
1681 C2S(WLAN_FC_STYPE_CFEND)
1682 C2S(WLAN_FC_STYPE_CFENDACK)
1683 }
1684 break;
1685 case WLAN_FC_TYPE_DATA:
1686 switch (stype) {
1687 C2S(WLAN_FC_STYPE_DATA)
1688 C2S(WLAN_FC_STYPE_DATA_CFACK)
1689 C2S(WLAN_FC_STYPE_DATA_CFPOLL)
1690 C2S(WLAN_FC_STYPE_DATA_CFACKPOLL)
1691 C2S(WLAN_FC_STYPE_NULLFUNC)
1692 C2S(WLAN_FC_STYPE_CFACK)
1693 C2S(WLAN_FC_STYPE_CFPOLL)
1694 C2S(WLAN_FC_STYPE_CFACKPOLL)
1695 C2S(WLAN_FC_STYPE_QOS_DATA)
1696 C2S(WLAN_FC_STYPE_QOS_DATA_CFACK)
1697 C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL)
1698 C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL)
1699 C2S(WLAN_FC_STYPE_QOS_NULL)
1700 C2S(WLAN_FC_STYPE_QOS_CFPOLL)
1701 C2S(WLAN_FC_STYPE_QOS_CFACKPOLL)
1702 }
1703 break;
1704 }
1705 return "WLAN_FC_TYPE_UNKNOWN";
1706 #undef C2S
1707 }
1708
1709
reason2str(u16 reason)1710 const char * reason2str(u16 reason)
1711 {
1712 #define R2S(r) case WLAN_REASON_ ## r: return #r;
1713 switch (reason) {
1714 R2S(UNSPECIFIED)
1715 R2S(PREV_AUTH_NOT_VALID)
1716 R2S(DEAUTH_LEAVING)
1717 R2S(DISASSOC_DUE_TO_INACTIVITY)
1718 R2S(DISASSOC_AP_BUSY)
1719 R2S(CLASS2_FRAME_FROM_NONAUTH_STA)
1720 R2S(CLASS3_FRAME_FROM_NONASSOC_STA)
1721 R2S(DISASSOC_STA_HAS_LEFT)
1722 R2S(STA_REQ_ASSOC_WITHOUT_AUTH)
1723 R2S(PWR_CAPABILITY_NOT_VALID)
1724 R2S(SUPPORTED_CHANNEL_NOT_VALID)
1725 R2S(BSS_TRANSITION_DISASSOC)
1726 R2S(INVALID_IE)
1727 R2S(MICHAEL_MIC_FAILURE)
1728 R2S(4WAY_HANDSHAKE_TIMEOUT)
1729 R2S(GROUP_KEY_UPDATE_TIMEOUT)
1730 R2S(IE_IN_4WAY_DIFFERS)
1731 R2S(GROUP_CIPHER_NOT_VALID)
1732 R2S(PAIRWISE_CIPHER_NOT_VALID)
1733 R2S(AKMP_NOT_VALID)
1734 R2S(UNSUPPORTED_RSN_IE_VERSION)
1735 R2S(INVALID_RSN_IE_CAPAB)
1736 R2S(IEEE_802_1X_AUTH_FAILED)
1737 R2S(CIPHER_SUITE_REJECTED)
1738 R2S(TDLS_TEARDOWN_UNREACHABLE)
1739 R2S(TDLS_TEARDOWN_UNSPECIFIED)
1740 R2S(SSP_REQUESTED_DISASSOC)
1741 R2S(NO_SSP_ROAMING_AGREEMENT)
1742 R2S(BAD_CIPHER_OR_AKM)
1743 R2S(NOT_AUTHORIZED_THIS_LOCATION)
1744 R2S(SERVICE_CHANGE_PRECLUDES_TS)
1745 R2S(UNSPECIFIED_QOS_REASON)
1746 R2S(NOT_ENOUGH_BANDWIDTH)
1747 R2S(DISASSOC_LOW_ACK)
1748 R2S(EXCEEDED_TXOP)
1749 R2S(STA_LEAVING)
1750 R2S(END_TS_BA_DLS)
1751 R2S(UNKNOWN_TS_BA)
1752 R2S(TIMEOUT)
1753 R2S(PEERKEY_MISMATCH)
1754 R2S(AUTHORIZED_ACCESS_LIMIT_REACHED)
1755 R2S(EXTERNAL_SERVICE_REQUIREMENTS)
1756 R2S(INVALID_FT_ACTION_FRAME_COUNT)
1757 R2S(INVALID_PMKID)
1758 R2S(INVALID_MDE)
1759 R2S(INVALID_FTE)
1760 R2S(MESH_PEERING_CANCELLED)
1761 R2S(MESH_MAX_PEERS)
1762 R2S(MESH_CONFIG_POLICY_VIOLATION)
1763 R2S(MESH_CLOSE_RCVD)
1764 R2S(MESH_MAX_RETRIES)
1765 R2S(MESH_CONFIRM_TIMEOUT)
1766 R2S(MESH_INVALID_GTK)
1767 R2S(MESH_INCONSISTENT_PARAMS)
1768 R2S(MESH_INVALID_SECURITY_CAP)
1769 R2S(MESH_PATH_ERROR_NO_PROXY_INFO)
1770 R2S(MESH_PATH_ERROR_NO_FORWARDING_INFO)
1771 R2S(MESH_PATH_ERROR_DEST_UNREACHABLE)
1772 R2S(MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS)
1773 R2S(MESH_CHANNEL_SWITCH_REGULATORY_REQ)
1774 R2S(MESH_CHANNEL_SWITCH_UNSPECIFIED)
1775 }
1776 return "UNKNOWN";
1777 #undef R2S
1778 }
1779
1780
status2str(u16 status)1781 const char * status2str(u16 status)
1782 {
1783 #define S2S(s) case WLAN_STATUS_ ## s: return #s;
1784 switch (status) {
1785 S2S(SUCCESS)
1786 S2S(UNSPECIFIED_FAILURE)
1787 S2S(TDLS_WAKEUP_ALTERNATE)
1788 S2S(TDLS_WAKEUP_REJECT)
1789 S2S(SECURITY_DISABLED)
1790 S2S(UNACCEPTABLE_LIFETIME)
1791 S2S(NOT_IN_SAME_BSS)
1792 S2S(CAPS_UNSUPPORTED)
1793 S2S(REASSOC_NO_ASSOC)
1794 S2S(ASSOC_DENIED_UNSPEC)
1795 S2S(NOT_SUPPORTED_AUTH_ALG)
1796 S2S(UNKNOWN_AUTH_TRANSACTION)
1797 S2S(CHALLENGE_FAIL)
1798 S2S(AUTH_TIMEOUT)
1799 S2S(AP_UNABLE_TO_HANDLE_NEW_STA)
1800 S2S(ASSOC_DENIED_RATES)
1801 S2S(ASSOC_DENIED_NOSHORT)
1802 S2S(SPEC_MGMT_REQUIRED)
1803 S2S(PWR_CAPABILITY_NOT_VALID)
1804 S2S(SUPPORTED_CHANNEL_NOT_VALID)
1805 S2S(ASSOC_DENIED_NO_SHORT_SLOT_TIME)
1806 S2S(ASSOC_DENIED_NO_HT)
1807 S2S(R0KH_UNREACHABLE)
1808 S2S(ASSOC_DENIED_NO_PCO)
1809 S2S(ASSOC_REJECTED_TEMPORARILY)
1810 S2S(ROBUST_MGMT_FRAME_POLICY_VIOLATION)
1811 S2S(UNSPECIFIED_QOS_FAILURE)
1812 S2S(DENIED_INSUFFICIENT_BANDWIDTH)
1813 S2S(DENIED_POOR_CHANNEL_CONDITIONS)
1814 S2S(DENIED_QOS_NOT_SUPPORTED)
1815 S2S(REQUEST_DECLINED)
1816 S2S(INVALID_PARAMETERS)
1817 S2S(REJECTED_WITH_SUGGESTED_CHANGES)
1818 S2S(INVALID_IE)
1819 S2S(GROUP_CIPHER_NOT_VALID)
1820 S2S(PAIRWISE_CIPHER_NOT_VALID)
1821 S2S(AKMP_NOT_VALID)
1822 S2S(UNSUPPORTED_RSN_IE_VERSION)
1823 S2S(INVALID_RSN_IE_CAPAB)
1824 S2S(CIPHER_REJECTED_PER_POLICY)
1825 S2S(TS_NOT_CREATED)
1826 S2S(DIRECT_LINK_NOT_ALLOWED)
1827 S2S(DEST_STA_NOT_PRESENT)
1828 S2S(DEST_STA_NOT_QOS_STA)
1829 S2S(ASSOC_DENIED_LISTEN_INT_TOO_LARGE)
1830 S2S(INVALID_FT_ACTION_FRAME_COUNT)
1831 S2S(INVALID_PMKID)
1832 S2S(INVALID_MDIE)
1833 S2S(INVALID_FTIE)
1834 S2S(REQUESTED_TCLAS_NOT_SUPPORTED)
1835 S2S(INSUFFICIENT_TCLAS_PROCESSING_RESOURCES)
1836 S2S(TRY_ANOTHER_BSS)
1837 S2S(GAS_ADV_PROTO_NOT_SUPPORTED)
1838 S2S(NO_OUTSTANDING_GAS_REQ)
1839 S2S(GAS_RESP_NOT_RECEIVED)
1840 S2S(STA_TIMED_OUT_WAITING_FOR_GAS_RESP)
1841 S2S(GAS_RESP_LARGER_THAN_LIMIT)
1842 S2S(REQ_REFUSED_HOME)
1843 S2S(ADV_SRV_UNREACHABLE)
1844 S2S(REQ_REFUSED_SSPN)
1845 S2S(REQ_REFUSED_UNAUTH_ACCESS)
1846 S2S(INVALID_RSNIE)
1847 S2S(U_APSD_COEX_NOT_SUPPORTED)
1848 S2S(U_APSD_COEX_MODE_NOT_SUPPORTED)
1849 S2S(BAD_INTERVAL_WITH_U_APSD_COEX)
1850 S2S(ANTI_CLOGGING_TOKEN_REQ)
1851 S2S(FINITE_CYCLIC_GROUP_NOT_SUPPORTED)
1852 S2S(CANNOT_FIND_ALT_TBTT)
1853 S2S(TRANSMISSION_FAILURE)
1854 S2S(REQ_TCLAS_NOT_SUPPORTED)
1855 S2S(TCLAS_RESOURCES_EXCHAUSTED)
1856 S2S(REJECTED_WITH_SUGGESTED_BSS_TRANSITION)
1857 S2S(REJECT_WITH_SCHEDULE)
1858 S2S(REJECT_NO_WAKEUP_SPECIFIED)
1859 S2S(SUCCESS_POWER_SAVE_MODE)
1860 S2S(PENDING_ADMITTING_FST_SESSION)
1861 S2S(PERFORMING_FST_NOW)
1862 S2S(PENDING_GAP_IN_BA_WINDOW)
1863 S2S(REJECT_U_PID_SETTING)
1864 S2S(REFUSED_EXTERNAL_REASON)
1865 S2S(REFUSED_AP_OUT_OF_MEMORY)
1866 S2S(REJECTED_EMERGENCY_SERVICE_NOT_SUPPORTED)
1867 S2S(QUERY_RESP_OUTSTANDING)
1868 S2S(REJECT_DSE_BAND)
1869 S2S(TCLAS_PROCESSING_TERMINATED)
1870 S2S(TS_SCHEDULE_CONFLICT)
1871 S2S(DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL)
1872 S2S(MCCAOP_RESERVATION_CONFLICT)
1873 S2S(MAF_LIMIT_EXCEEDED)
1874 S2S(MCCA_TRACK_LIMIT_EXCEEDED)
1875 S2S(DENIED_DUE_TO_SPECTRUM_MANAGEMENT)
1876 S2S(ASSOC_DENIED_NO_VHT)
1877 S2S(ENABLEMENT_DENIED)
1878 S2S(RESTRICTION_FROM_AUTHORIZED_GDB)
1879 S2S(AUTHORIZATION_DEENABLED)
1880 S2S(FILS_AUTHENTICATION_FAILURE)
1881 S2S(UNKNOWN_AUTHENTICATION_SERVER)
1882 S2S(UNKNOWN_PASSWORD_IDENTIFIER)
1883 S2S(DENIED_HE_NOT_SUPPORTED)
1884 S2S(SAE_HASH_TO_ELEMENT)
1885 S2S(SAE_PK)
1886 }
1887 return "UNKNOWN";
1888 #undef S2S
1889 }
1890
1891
mb_ies_info_by_ies(struct mb_ies_info * info,const u8 * ies_buf,size_t ies_len)1892 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
1893 size_t ies_len)
1894 {
1895 const struct element *elem;
1896
1897 os_memset(info, 0, sizeof(*info));
1898
1899 if (!ies_buf)
1900 return 0;
1901
1902 for_each_element_id(elem, WLAN_EID_MULTI_BAND, ies_buf, ies_len) {
1903 if (info->nof_ies >= MAX_NOF_MB_IES_SUPPORTED)
1904 return 0;
1905
1906 wpa_printf(MSG_DEBUG, "MB IE of %u bytes found",
1907 elem->datalen + 2);
1908 info->ies[info->nof_ies].ie = elem->data;
1909 info->ies[info->nof_ies].ie_len = elem->datalen;
1910 info->nof_ies++;
1911 }
1912
1913 if (!for_each_element_completed(elem, ies_buf, ies_len)) {
1914 wpa_hexdump(MSG_DEBUG, "Truncated IEs", ies_buf, ies_len);
1915 return -1;
1916 }
1917
1918 return 0;
1919 }
1920
1921
mb_ies_by_info(struct mb_ies_info * info)1922 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info)
1923 {
1924 struct wpabuf *mb_ies = NULL;
1925
1926 WPA_ASSERT(info != NULL);
1927
1928 if (info->nof_ies) {
1929 u8 i;
1930 size_t mb_ies_size = 0;
1931
1932 for (i = 0; i < info->nof_ies; i++)
1933 mb_ies_size += 2 + info->ies[i].ie_len;
1934
1935 mb_ies = wpabuf_alloc(mb_ies_size);
1936 if (mb_ies) {
1937 for (i = 0; i < info->nof_ies; i++) {
1938 wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND);
1939 wpabuf_put_u8(mb_ies, info->ies[i].ie_len);
1940 wpabuf_put_data(mb_ies,
1941 info->ies[i].ie,
1942 info->ies[i].ie_len);
1943 }
1944 }
1945 }
1946
1947 return mb_ies;
1948 }
1949
1950
1951 const struct oper_class_map global_op_class[] = {
1952 { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP },
1953 { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP },
1954
1955 #ifndef EXT_CODE_CROP
1956 /* Do not enable HT40 on 2.4 GHz for P2P use for now */
1957 { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP },
1958 { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP },
1959
1960 { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP },
1961 { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP },
1962 { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP },
1963 { HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP },
1964 { HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP },
1965 { HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP },
1966 { HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP },
1967 { HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP },
1968 { HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP },
1969 { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
1970 { HOSTAPD_MODE_IEEE80211A, 125, 149, 177, 4, BW20, P2P_SUPP },
1971 { HOSTAPD_MODE_IEEE80211A, 126, 149, 173, 8, BW40PLUS, P2P_SUPP },
1972 { HOSTAPD_MODE_IEEE80211A, 127, 153, 177, 8, BW40MINUS, P2P_SUPP },
1973
1974 /*
1975 * IEEE P802.11ax/D8.0 Table E-4 actually talks about channel center
1976 * frequency index 42, 58, 106, 122, 138, 155, 171 with channel spacing
1977 * of 80 MHz, but currently use the following definition for simplicity
1978 * (these center frequencies are not actual channels, which makes
1979 * wpas_p2p_verify_channel() fail). wpas_p2p_verify_80mhz() should take
1980 * care of removing invalid channels.
1981 */
1982 { HOSTAPD_MODE_IEEE80211A, 128, 36, 177, 4, BW80, P2P_SUPP },
1983 { HOSTAPD_MODE_IEEE80211A, 129, 36, 177, 4, BW160, P2P_SUPP },
1984 { HOSTAPD_MODE_IEEE80211A, 131, 1, 233, 4, BW20, P2P_SUPP },
1985 { HOSTAPD_MODE_IEEE80211A, 132, 1, 233, 8, BW40, P2P_SUPP },
1986 { HOSTAPD_MODE_IEEE80211A, 133, 1, 233, 16, BW80, P2P_SUPP },
1987 { HOSTAPD_MODE_IEEE80211A, 134, 1, 233, 32, BW160, P2P_SUPP },
1988 { HOSTAPD_MODE_IEEE80211A, 135, 1, 233, 16, BW80P80, NO_P2P_SUPP },
1989 { HOSTAPD_MODE_IEEE80211A, 136, 2, 2, 4, BW20, NO_P2P_SUPP },
1990
1991 /*
1992 * IEEE Std 802.11ad-2012 and P802.ay/D5.0 60 GHz operating classes.
1993 * Class 180 has the legacy channels 1-6. Classes 181-183 include
1994 * channels which implement channel bonding features.
1995 */
1996 { HOSTAPD_MODE_IEEE80211AD, 180, 1, 6, 1, BW2160, P2P_SUPP },
1997 { HOSTAPD_MODE_IEEE80211AD, 181, 9, 13, 1, BW4320, P2P_SUPP },
1998 { HOSTAPD_MODE_IEEE80211AD, 182, 17, 20, 1, BW6480, P2P_SUPP },
1999 { HOSTAPD_MODE_IEEE80211AD, 183, 25, 27, 1, BW8640, P2P_SUPP },
2000
2001 /* Keep the operating class 130 as the last entry as a workaround for
2002 * the OneHundredAndThirty Delimiter value used in the Supported
2003 * Operating Classes element to indicate the end of the Operating
2004 * Classes field. */
2005 { HOSTAPD_MODE_IEEE80211A, 130, 36, 177, 4, BW80P80, P2P_SUPP },
2006 #endif /* EXT_CODE_CROP */
2007 { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
2008 };
2009
2010
ieee80211_phy_type_by_freq(int freq)2011 static enum phy_type ieee80211_phy_type_by_freq(int freq)
2012 {
2013 enum hostapd_hw_mode hw_mode;
2014 u8 channel;
2015
2016 hw_mode = ieee80211_freq_to_chan(freq, &channel);
2017
2018 switch (hw_mode) {
2019 #ifndef EXT_CODE_CROP
2020 case HOSTAPD_MODE_IEEE80211A:
2021 return PHY_TYPE_OFDM;
2022 #endif /* EXT_CODE_CROP */
2023 case HOSTAPD_MODE_IEEE80211B:
2024 return PHY_TYPE_HRDSSS;
2025 case HOSTAPD_MODE_IEEE80211G:
2026 return PHY_TYPE_ERP;
2027 #ifndef EXT_CODE_CROP
2028 case HOSTAPD_MODE_IEEE80211AD:
2029 return PHY_TYPE_DMG;
2030 #endif /* EXT_CODE_CROP */
2031 default:
2032 return PHY_TYPE_UNSPECIFIED;
2033 };
2034 }
2035
2036
2037 /* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */
2038 #ifndef EXT_CODE_CROP
ieee80211_get_phy_type(int freq,int ht,int vht)2039 enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht)
2040 #else
2041 enum phy_type ieee80211_get_phy_type(int freq, int ht)
2042 #endif /* EXT_CODE_CROP */
2043 {
2044 #ifndef EXT_CODE_CROP
2045 if (vht)
2046 return PHY_TYPE_VHT;
2047 #endif /* EXT_CODE_CROP */
2048 if (ht)
2049 return PHY_TYPE_HT;
2050
2051 return ieee80211_phy_type_by_freq(freq);
2052 }
2053
2054
2055 size_t global_op_class_size = ARRAY_SIZE(global_op_class);
2056
2057
2058 /**
2059 * get_ie - Fetch a specified information element from IEs buffer
2060 * @ies: Information elements buffer
2061 * @len: Information elements buffer length
2062 * @eid: Information element identifier (WLAN_EID_*)
2063 * Returns: Pointer to the information element (id field) or %NULL if not found
2064 *
2065 * This function returns the first matching information element in the IEs
2066 * buffer or %NULL in case the element is not found.
2067 */
get_ie(const u8 * ies,size_t len,u8 eid)2068 const u8 * get_ie(const u8 *ies, size_t len, u8 eid)
2069 {
2070 const struct element *elem;
2071
2072 if (!ies)
2073 return NULL;
2074
2075 for_each_element_id(elem, eid, ies, len)
2076 return &elem->id;
2077
2078 return NULL;
2079 }
2080
2081
2082 /**
2083 * get_ie_ext - Fetch a specified extended information element from IEs buffer
2084 * @ies: Information elements buffer
2085 * @len: Information elements buffer length
2086 * @ext: Information element extension identifier (WLAN_EID_EXT_*)
2087 * Returns: Pointer to the information element (id field) or %NULL if not found
2088 *
2089 * This function returns the first matching information element in the IEs
2090 * buffer or %NULL in case the element is not found.
2091 */
get_ie_ext(const u8 * ies,size_t len,u8 ext)2092 const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext)
2093 {
2094 const struct element *elem;
2095
2096 if (!ies)
2097 return NULL;
2098
2099 for_each_element_extid(elem, ext, ies, len)
2100 return &elem->id;
2101
2102 return NULL;
2103 }
2104
2105
get_vendor_ie(const u8 * ies,size_t len,u32 vendor_type)2106 const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type)
2107 {
2108 const struct element *elem;
2109
2110 for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, len) {
2111 if (elem->datalen >= 4 &&
2112 vendor_type == WPA_GET_BE32(elem->data))
2113 return &elem->id;
2114 }
2115
2116 return NULL;
2117 }
2118
2119 #ifdef CONFIG_MBO
mbo_add_ie(u8 * buf,size_t len,const u8 * attr,size_t attr_len)2120 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
2121 {
2122 /*
2123 * MBO IE requires 6 bytes without the attributes: EID (1), length (1),
2124 * OUI (3), OUI type (1).
2125 */
2126 if (len < 6 + attr_len) {
2127 wpa_printf(MSG_DEBUG,
2128 "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu",
2129 len, attr_len);
2130 return 0;
2131 }
2132
2133 *buf++ = WLAN_EID_VENDOR_SPECIFIC;
2134 *buf++ = attr_len + 4;
2135 WPA_PUT_BE24(buf, OUI_WFA);
2136 buf += 3;
2137 *buf++ = MBO_OUI_TYPE;
2138 os_memcpy(buf, attr, attr_len);
2139
2140 return 6 + attr_len;
2141 }
2142 #endif /* CONFIG_MBO */
2143
2144 #ifdef CONFIG_MULTI_AP
add_multi_ap_ie(u8 * buf,size_t len,u8 value)2145 size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value)
2146 {
2147 u8 *pos = buf;
2148
2149 if (len < 9)
2150 return 0;
2151
2152 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
2153 *pos++ = 7; /* len */
2154 WPA_PUT_BE24(pos, OUI_WFA);
2155 pos += 3;
2156 *pos++ = MULTI_AP_OUI_TYPE;
2157 *pos++ = MULTI_AP_SUB_ELEM_TYPE;
2158 *pos++ = 1; /* len */
2159 *pos++ = value;
2160
2161 return pos - buf;
2162 }
2163 #endif /* CONFIG_MULTI_AP */
2164
2165 static const struct country_op_class us_op_class[] = {
2166 { 1, 115 },
2167 { 2, 118 },
2168 { 3, 124 },
2169 { 4, 121 },
2170 { 5, 125 },
2171 { 12, 81 },
2172 { 22, 116 },
2173 { 23, 119 },
2174 { 24, 122 },
2175 { 25, 126 },
2176 { 26, 126 },
2177 { 27, 117 },
2178 { 28, 120 },
2179 { 29, 123 },
2180 { 30, 127 },
2181 { 31, 127 },
2182 { 32, 83 },
2183 { 33, 84 },
2184 { 34, 180 },
2185 };
2186
2187 static const struct country_op_class eu_op_class[] = {
2188 { 1, 115 },
2189 { 2, 118 },
2190 { 3, 121 },
2191 { 4, 81 },
2192 { 5, 116 },
2193 { 6, 119 },
2194 { 7, 122 },
2195 { 8, 117 },
2196 { 9, 120 },
2197 { 10, 123 },
2198 { 11, 83 },
2199 { 12, 84 },
2200 { 17, 125 },
2201 { 18, 180 },
2202 };
2203
2204 static const struct country_op_class jp_op_class[] = {
2205 { 1, 115 },
2206 { 30, 81 },
2207 { 31, 82 },
2208 { 32, 118 },
2209 { 33, 118 },
2210 { 34, 121 },
2211 { 35, 121 },
2212 { 36, 116 },
2213 { 37, 119 },
2214 { 38, 119 },
2215 { 39, 122 },
2216 { 40, 122 },
2217 { 41, 117 },
2218 { 42, 120 },
2219 { 43, 120 },
2220 { 44, 123 },
2221 { 45, 123 },
2222 { 56, 83 },
2223 { 57, 84 },
2224 { 58, 121 },
2225 { 59, 180 },
2226 };
2227
2228 static const struct country_op_class cn_op_class[] = {
2229 { 1, 115 },
2230 { 2, 118 },
2231 { 3, 125 },
2232 { 4, 116 },
2233 { 5, 119 },
2234 { 6, 126 },
2235 { 7, 81 },
2236 { 8, 83 },
2237 { 9, 84 },
2238 };
2239
2240 static u8
global_op_class_from_country_array(u8 op_class,size_t array_size,const struct country_op_class * country_array)2241 global_op_class_from_country_array(u8 op_class, size_t array_size,
2242 const struct country_op_class *country_array)
2243 {
2244 size_t i;
2245
2246 for (i = 0; i < array_size; i++) {
2247 if (country_array[i].country_op_class == op_class)
2248 return country_array[i].global_op_class;
2249 }
2250
2251 return 0;
2252 }
2253
2254
country_to_global_op_class(const char * country,u8 op_class)2255 u8 country_to_global_op_class(const char *country, u8 op_class)
2256 {
2257 const struct country_op_class *country_array;
2258 size_t size;
2259 u8 g_op_class;
2260
2261 if (country_match(us_op_class_cc, country)) {
2262 country_array = us_op_class;
2263 size = ARRAY_SIZE(us_op_class);
2264 } else if (country_match(eu_op_class_cc, country)) {
2265 country_array = eu_op_class;
2266 size = ARRAY_SIZE(eu_op_class);
2267 } else if (country_match(jp_op_class_cc, country)) {
2268 country_array = jp_op_class;
2269 size = ARRAY_SIZE(jp_op_class);
2270 } else if (country_match(cn_op_class_cc, country)) {
2271 country_array = cn_op_class;
2272 size = ARRAY_SIZE(cn_op_class);
2273 } else {
2274 /*
2275 * Countries that do not match any of the above countries use
2276 * global operating classes
2277 */
2278 return op_class;
2279 }
2280
2281 g_op_class = global_op_class_from_country_array(op_class, size,
2282 country_array);
2283
2284 /*
2285 * If the given operating class did not match any of the country's
2286 * operating classes, assume that global operating class is used.
2287 */
2288 return g_op_class ? g_op_class : op_class;
2289 }
2290
2291
get_oper_class(const char * country,u8 op_class)2292 const struct oper_class_map * get_oper_class(const char *country, u8 op_class)
2293 {
2294 const struct oper_class_map *op;
2295
2296 if (country)
2297 op_class = country_to_global_op_class(country, op_class);
2298
2299 op = &global_op_class[0];
2300 while (op->op_class && op->op_class != op_class)
2301 op++;
2302
2303 if (!op->op_class)
2304 return NULL;
2305
2306 return op;
2307 }
2308
2309
oper_class_bw_to_int(const struct oper_class_map * map)2310 int oper_class_bw_to_int(const struct oper_class_map *map)
2311 {
2312 switch (map->bw) {
2313 case BW20:
2314 return 20;
2315 case BW40:
2316 case BW40PLUS:
2317 case BW40MINUS:
2318 return 40;
2319 case BW80:
2320 return 80;
2321 case BW80P80:
2322 case BW160:
2323 return 160;
2324 case BW2160:
2325 return 2160;
2326 default:
2327 return 0;
2328 }
2329 }
2330
center_idx_to_bw_6ghz(u8 idx)2331 int center_idx_to_bw_6ghz(u8 idx)
2332 {
2333 /* Channel: 2 */
2334 if (idx == 2)
2335 return 0; /* 20 MHz */
2336 /* channels: 1, 5, 9, 13... */
2337 if ((idx & 0x3) == 0x1)
2338 return 0; /* 20 MHz */
2339 /* channels 3, 11, 19... */
2340 if ((idx & 0x7) == 0x3)
2341 return 1; /* 40 MHz */
2342 /* channels 7, 23, 39.. */
2343 if ((idx & 0xf) == 0x7)
2344 return 2; /* 80 MHz */
2345 /* channels 15, 47, 79...*/
2346 if ((idx & 0x1f) == 0xf)
2347 return 3; /* 160 MHz */
2348
2349 return -1;
2350 }
2351
2352
is_6ghz_freq(int freq)2353 bool is_6ghz_freq(int freq)
2354 {
2355 if (freq < 5935 || freq > 7115)
2356 return false;
2357
2358 if (freq == 5935)
2359 return true;
2360
2361 if (center_idx_to_bw_6ghz((freq - 5950) / 5) < 0)
2362 return false;
2363
2364 return true;
2365 }
2366
2367
is_6ghz_op_class(u8 op_class)2368 bool is_6ghz_op_class(u8 op_class)
2369 {
2370 return op_class >= 131 && op_class <= 136;
2371 }
2372
2373
is_6ghz_psc_frequency(int freq)2374 bool is_6ghz_psc_frequency(int freq)
2375 {
2376 int i;
2377
2378 if (!is_6ghz_freq(freq) || freq == 5935)
2379 return false;
2380 if ((((freq - 5950) / 5) & 0x3) != 0x1)
2381 return false;
2382
2383 i = (freq - 5950 + 55) % 80;
2384 if (i == 0)
2385 i = (freq - 5950 + 55) / 80;
2386
2387 if (i >= 1 && i <= 15)
2388 return true;
2389
2390 return false;
2391 }
2392
2393
2394 /**
2395 * get_6ghz_sec_channel - Get the relative position of the secondary channel
2396 * to the primary channel in 6 GHz
2397 * @channel: Primary channel to be checked for (in global op class 131)
2398 * Returns: 1 = secondary channel above, -1 = secondary channel below
2399 */
2400
get_6ghz_sec_channel(int channel)2401 int get_6ghz_sec_channel(int channel)
2402 {
2403 /*
2404 * In the 6 GHz band, primary channels are numbered as 1, 5, 9, 13.., so
2405 * the 40 MHz channels are formed with the channel pairs as (1,5),
2406 * (9,13), (17,21)..
2407 * The secondary channel for a given primary channel is below the
2408 * primary channel for the channels 5, 13, 21.. and it is above the
2409 * primary channel for the channels 1, 9, 17..
2410 */
2411
2412 if (((channel - 1) / 4) % 2)
2413 return -1;
2414 return 1;
2415 }
2416
ieee802_11_parse_candidate_list(const char * pos,u8 * nei_rep,size_t nei_rep_len)2417 int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
2418 size_t nei_rep_len)
2419 {
2420 u8 *nei_pos = nei_rep;
2421 const char *end;
2422
2423 /*
2424 * BSS Transition Candidate List Entries - Neighbor Report elements
2425 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
2426 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
2427 */
2428 while (pos) {
2429 u8 *nei_start;
2430 long int val;
2431 char *endptr, *tmp;
2432
2433 pos = os_strstr(pos, " neighbor=");
2434 if (!pos)
2435 break;
2436 if (nei_pos + 15 > nei_rep + nei_rep_len) {
2437 wpa_printf(MSG_DEBUG,
2438 "Not enough room for additional neighbor");
2439 return -1;
2440 }
2441 pos += 10;
2442
2443 nei_start = nei_pos;
2444 *nei_pos++ = WLAN_EID_NEIGHBOR_REPORT;
2445 nei_pos++; /* length to be filled in */
2446
2447 if (hwaddr_aton(pos, nei_pos)) {
2448 wpa_printf(MSG_DEBUG, "Invalid BSSID");
2449 return -1;
2450 }
2451 nei_pos += ETH_ALEN;
2452 pos += 17;
2453 if (*pos != ',') {
2454 wpa_printf(MSG_DEBUG, "Missing BSSID Information");
2455 return -1;
2456 }
2457 pos++;
2458
2459 val = strtol(pos, &endptr, 0);
2460 WPA_PUT_LE32(nei_pos, val);
2461 nei_pos += 4;
2462 if (*endptr != ',') {
2463 wpa_printf(MSG_DEBUG, "Missing Operating Class");
2464 return -1;
2465 }
2466 pos = endptr + 1;
2467
2468 *nei_pos++ = atoi(pos); /* Operating Class */
2469 pos = os_strchr(pos, ',');
2470 if (pos == NULL) {
2471 wpa_printf(MSG_DEBUG, "Missing Channel Number");
2472 return -1;
2473 }
2474 pos++;
2475
2476 *nei_pos++ = atoi(pos); /* Channel Number */
2477 pos = os_strchr(pos, ',');
2478 if (pos == NULL) {
2479 wpa_printf(MSG_DEBUG, "Missing PHY Type");
2480 return -1;
2481 }
2482 pos++;
2483
2484 *nei_pos++ = atoi(pos); /* PHY Type */
2485 end = os_strchr(pos, ' ');
2486 tmp = os_strchr(pos, ',');
2487 if (tmp && (!end || tmp < end)) {
2488 /* Optional Subelements (hexdump) */
2489 size_t len;
2490
2491 pos = tmp + 1;
2492 end = os_strchr(pos, ' ');
2493 if (end)
2494 len = end - pos;
2495 else
2496 len = os_strlen(pos);
2497 if (nei_pos + len / 2 > nei_rep + nei_rep_len) {
2498 wpa_printf(MSG_DEBUG,
2499 "Not enough room for neighbor subelements");
2500 return -1;
2501 }
2502 if (len & 0x01 ||
2503 hexstr2bin(pos, nei_pos, len / 2) < 0) {
2504 wpa_printf(MSG_DEBUG,
2505 "Invalid neighbor subelement info");
2506 return -1;
2507 }
2508 nei_pos += len / 2;
2509 pos = end;
2510 }
2511
2512 nei_start[1] = nei_pos - nei_start - 2;
2513 }
2514
2515 return nei_pos - nei_rep;
2516 }
2517
2518
ieee802_11_ext_capab(const u8 * ie,unsigned int capab)2519 int ieee802_11_ext_capab(const u8 *ie, unsigned int capab)
2520 {
2521 if (!ie || ie[1] <= capab / 8)
2522 return 0;
2523 return !!(ie[2 + capab / 8] & BIT(capab % 8));
2524 }
2525
2526
ieee802_11_rsnx_capab_len(const u8 * rsnxe,size_t rsnxe_len,unsigned int capab)2527 bool ieee802_11_rsnx_capab_len(const u8 *rsnxe, size_t rsnxe_len,
2528 unsigned int capab)
2529 {
2530 const u8 *end;
2531 size_t flen, i;
2532 u32 capabs = 0;
2533
2534 if (!rsnxe || rsnxe_len == 0)
2535 return false;
2536 end = rsnxe + rsnxe_len;
2537 flen = (rsnxe[0] & 0x0f) + 1;
2538 if (rsnxe + flen > end)
2539 return false;
2540 if (flen > 4)
2541 flen = 4;
2542 for (i = 0; i < flen; i++)
2543 capabs |= rsnxe[i] << (8 * i);
2544
2545 return capabs & BIT(capab);
2546 }
2547
2548
ieee802_11_rsnx_capab(const u8 * rsnxe,unsigned int capab)2549 bool ieee802_11_rsnx_capab(const u8 *rsnxe, unsigned int capab)
2550 {
2551 return ieee802_11_rsnx_capab_len(rsnxe ? rsnxe + 2 : NULL,
2552 rsnxe ? rsnxe[1] : 0, capab);
2553 }
2554
2555
hostapd_encode_edmg_chan(int edmg_enable,u8 edmg_channel,int primary_channel,struct ieee80211_edmg_config * edmg)2556 void hostapd_encode_edmg_chan(int edmg_enable, u8 edmg_channel,
2557 int primary_channel,
2558 struct ieee80211_edmg_config *edmg)
2559 {
2560 if (!edmg_enable) {
2561 edmg->channels = 0;
2562 edmg->bw_config = 0;
2563 return;
2564 }
2565
2566 /* Only EDMG CB1 and EDMG CB2 contiguous channels supported for now */
2567 switch (edmg_channel) {
2568 case EDMG_CHANNEL_9:
2569 edmg->channels = EDMG_CHANNEL_9_SUBCHANNELS;
2570 edmg->bw_config = EDMG_BW_CONFIG_5;
2571 return;
2572 case EDMG_CHANNEL_10:
2573 edmg->channels = EDMG_CHANNEL_10_SUBCHANNELS;
2574 edmg->bw_config = EDMG_BW_CONFIG_5;
2575 return;
2576 case EDMG_CHANNEL_11:
2577 edmg->channels = EDMG_CHANNEL_11_SUBCHANNELS;
2578 edmg->bw_config = EDMG_BW_CONFIG_5;
2579 return;
2580 case EDMG_CHANNEL_12:
2581 edmg->channels = EDMG_CHANNEL_12_SUBCHANNELS;
2582 edmg->bw_config = EDMG_BW_CONFIG_5;
2583 return;
2584 case EDMG_CHANNEL_13:
2585 edmg->channels = EDMG_CHANNEL_13_SUBCHANNELS;
2586 edmg->bw_config = EDMG_BW_CONFIG_5;
2587 return;
2588 default:
2589 if (primary_channel > 0 && primary_channel < 7) {
2590 edmg->channels = BIT(primary_channel - 1);
2591 edmg->bw_config = EDMG_BW_CONFIG_4;
2592 } else {
2593 edmg->channels = 0;
2594 edmg->bw_config = 0;
2595 }
2596 break;
2597 }
2598 }
2599
2600
2601 /* Check if the requested EDMG configuration is a subset of the allowed
2602 * EDMG configuration. */
ieee802_edmg_is_allowed(struct ieee80211_edmg_config allowed,struct ieee80211_edmg_config requested)2603 int ieee802_edmg_is_allowed(struct ieee80211_edmg_config allowed,
2604 struct ieee80211_edmg_config requested)
2605 {
2606 /*
2607 * The validation check if the requested EDMG configuration
2608 * is a subset of the allowed EDMG configuration:
2609 * 1. Check that the requested channels are part (set) of the allowed
2610 * channels.
2611 * 2. P802.11ay defines the values of bw_config between 4 and 15.
2612 * (bw config % 4) will give us 4 groups inside bw_config definition,
2613 * inside each group we can check the subset just by comparing the
2614 * bw_config value.
2615 * Between this 4 groups, there is no subset relation - as a result of
2616 * the P802.11ay definition.
2617 * bw_config defined by IEEE P802.11ay/D4.0, 9.4.2.251, Table 13.
2618 */
2619 if (((requested.channels & allowed.channels) != requested.channels) ||
2620 ((requested.bw_config % 4) > (allowed.bw_config % 4)) ||
2621 requested.bw_config > allowed.bw_config)
2622 return 0;
2623
2624 return 1;
2625 }
2626
2627
op_class_to_bandwidth(u8 op_class)2628 int op_class_to_bandwidth(u8 op_class)
2629 {
2630 switch (op_class) {
2631 case 81:
2632 case 82:
2633 return 20;
2634 case 83: /* channels 1..9; 40 MHz */
2635 case 84: /* channels 5..13; 40 MHz */
2636 return 40;
2637 case 115: /* channels 36,40,44,48; indoor only */
2638 return 20;
2639 case 116: /* channels 36,44; 40 MHz; indoor only */
2640 case 117: /* channels 40,48; 40 MHz; indoor only */
2641 return 40;
2642 case 118: /* channels 52,56,60,64; dfs */
2643 return 20;
2644 case 119: /* channels 52,60; 40 MHz; dfs */
2645 case 120: /* channels 56,64; 40 MHz; dfs */
2646 return 40;
2647 case 121: /* channels 100-140 */
2648 return 20;
2649 case 122: /* channels 100-142; 40 MHz */
2650 case 123: /* channels 104-136; 40 MHz */
2651 return 40;
2652 case 124: /* channels 149,153,157,161 */
2653 case 125: /* channels 149,153,157,161,165,169,173,177 */
2654 return 20;
2655 case 126: /* channels 149,157,161,165,169,173; 40 MHz */
2656 case 127: /* channels 153..177; 40 MHz */
2657 return 40;
2658 case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
2659 return 80;
2660 case 129: /* center freqs 50, 114, 163; 160 MHz */
2661 return 160;
2662 case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80+80 MHz */
2663 return 80;
2664 case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
2665 return 20;
2666 case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
2667 return 40;
2668 case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
2669 return 80;
2670 case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
2671 case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
2672 return 160;
2673 case 136: /* UHB channels, 20 MHz: 2 */
2674 return 20;
2675 case 180: /* 60 GHz band, channels 1..8 */
2676 return 2160;
2677 case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
2678 return 4320;
2679 case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
2680 return 6480;
2681 case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
2682 return 8640;
2683 }
2684
2685 return 20;
2686 }
2687
2688
op_class_to_ch_width(u8 op_class)2689 int op_class_to_ch_width(u8 op_class)
2690 {
2691 switch (op_class) {
2692 case 81:
2693 case 82:
2694 return CHANWIDTH_USE_HT;
2695 case 83: /* channels 1..9; 40 MHz */
2696 case 84: /* channels 5..13; 40 MHz */
2697 return CHANWIDTH_USE_HT;
2698 case 115: /* channels 36,40,44,48; indoor only */
2699 return CHANWIDTH_USE_HT;
2700 case 116: /* channels 36,44; 40 MHz; indoor only */
2701 case 117: /* channels 40,48; 40 MHz; indoor only */
2702 return CHANWIDTH_USE_HT;
2703 case 118: /* channels 52,56,60,64; dfs */
2704 return CHANWIDTH_USE_HT;
2705 case 119: /* channels 52,60; 40 MHz; dfs */
2706 case 120: /* channels 56,64; 40 MHz; dfs */
2707 return CHANWIDTH_USE_HT;
2708 case 121: /* channels 100-140 */
2709 return CHANWIDTH_USE_HT;
2710 case 122: /* channels 100-142; 40 MHz */
2711 case 123: /* channels 104-136; 40 MHz */
2712 return CHANWIDTH_USE_HT;
2713 case 124: /* channels 149,153,157,161 */
2714 case 125: /* channels 149,153,157,161,165,169,171 */
2715 return CHANWIDTH_USE_HT;
2716 case 126: /* channels 149,157,165, 173; 40 MHz */
2717 case 127: /* channels 153,161,169,177; 40 MHz */
2718 return CHANWIDTH_USE_HT;
2719 case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
2720 return CHANWIDTH_80MHZ;
2721 case 129: /* center freqs 50, 114, 163; 160 MHz */
2722 return CHANWIDTH_160MHZ;
2723 case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80+80 MHz */
2724 return CHANWIDTH_80P80MHZ;
2725 case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
2726 return CHANWIDTH_USE_HT;
2727 case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
2728 return CHANWIDTH_USE_HT;
2729 case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
2730 return CHANWIDTH_80MHZ;
2731 case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
2732 return CHANWIDTH_160MHZ;
2733 case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
2734 return CHANWIDTH_80P80MHZ;
2735 case 136: /* UHB channels, 20 MHz: 2 */
2736 return CHANWIDTH_USE_HT;
2737 case 180: /* 60 GHz band, channels 1..8 */
2738 return CHANWIDTH_2160MHZ;
2739 case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
2740 return CHANWIDTH_4320MHZ;
2741 case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
2742 return CHANWIDTH_6480MHZ;
2743 case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
2744 return CHANWIDTH_8640MHZ;
2745 }
2746 return CHANWIDTH_USE_HT;
2747 }
2748
2749
ieee802_11_defrag_data(struct ieee802_11_elems * elems,u8 eid,u8 eid_ext,const u8 * data,u8 len)2750 struct wpabuf * ieee802_11_defrag_data(struct ieee802_11_elems *elems,
2751 u8 eid, u8 eid_ext,
2752 const u8 *data, u8 len)
2753 {
2754 struct frag_ies_info *frag_ies = &elems->frag_ies;
2755 struct wpabuf *buf;
2756 unsigned int i;
2757
2758 if (!elems || !data || !len)
2759 return NULL;
2760
2761 buf = wpabuf_alloc_copy(data, len);
2762 if (!buf)
2763 return NULL;
2764
2765 for (i = 0; i < frag_ies->n_frags; i++) {
2766 int ret;
2767
2768 if (frag_ies->frags[i].eid != eid ||
2769 frag_ies->frags[i].eid_ext != eid_ext)
2770 continue;
2771
2772 ret = wpabuf_resize(&buf, frag_ies->frags[i].ie_len);
2773 if (ret < 0) {
2774 wpabuf_free(buf);
2775 return NULL;
2776 }
2777
2778 /* Copy only the fragment data (without the EID and length) */
2779 wpabuf_put_data(buf, frag_ies->frags[i].ie,
2780 frag_ies->frags[i].ie_len);
2781 }
2782
2783 return buf;
2784 }
2785
2786
ieee802_11_defrag(struct ieee802_11_elems * elems,u8 eid,u8 eid_ext)2787 struct wpabuf * ieee802_11_defrag(struct ieee802_11_elems *elems,
2788 u8 eid, u8 eid_ext)
2789 {
2790 const u8 *data;
2791 u8 len;
2792
2793 /*
2794 * TODO: Defragmentation mechanism can be supported for all IEs. For now
2795 * handle only those that are used (or use ieee802_11_defrag_data()).
2796 */
2797 switch (eid) {
2798 case WLAN_EID_EXTENSION:
2799 switch (eid_ext) {
2800 case WLAN_EID_EXT_FILS_HLP_CONTAINER:
2801 data = elems->fils_hlp;
2802 len = elems->fils_hlp_len;
2803 break;
2804 case WLAN_EID_EXT_WRAPPED_DATA:
2805 data = elems->wrapped_data;
2806 len = elems->wrapped_data_len;
2807 break;
2808 default:
2809 wpa_printf(MSG_DEBUG,
2810 "Defragmentation not supported. eid_ext=%u",
2811 eid_ext);
2812 return NULL;
2813 }
2814 break;
2815 default:
2816 wpa_printf(MSG_DEBUG,
2817 "Defragmentation not supported. eid=%u", eid);
2818 return NULL;
2819 }
2820
2821 return ieee802_11_defrag_data(elems, eid, eid_ext, data, len);
2822 }
2823