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