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