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