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] & 0x7f))
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] & 0x7f))
1568 num_11b++;
1569 else
1570 num_others++;
1571 }
1572
1573 return num_11b > 0 && num_others == 0;
1574 }
1575
1576 #ifndef CONFIG_NO_STDOUT_DEBUG
1577
fc2str(u16 fc)1578 const char * fc2str(u16 fc)
1579 {
1580 u16 stype = WLAN_FC_GET_STYPE(fc);
1581 #define C2S(x) case x: return #x;
1582
1583 switch (WLAN_FC_GET_TYPE(fc)) {
1584 case WLAN_FC_TYPE_MGMT:
1585 switch (stype) {
1586 C2S(WLAN_FC_STYPE_ASSOC_REQ)
1587 C2S(WLAN_FC_STYPE_ASSOC_RESP)
1588 C2S(WLAN_FC_STYPE_REASSOC_REQ)
1589 C2S(WLAN_FC_STYPE_REASSOC_RESP)
1590 C2S(WLAN_FC_STYPE_PROBE_REQ)
1591 C2S(WLAN_FC_STYPE_PROBE_RESP)
1592 C2S(WLAN_FC_STYPE_BEACON)
1593 C2S(WLAN_FC_STYPE_ATIM)
1594 C2S(WLAN_FC_STYPE_DISASSOC)
1595 C2S(WLAN_FC_STYPE_AUTH)
1596 C2S(WLAN_FC_STYPE_DEAUTH)
1597 C2S(WLAN_FC_STYPE_ACTION)
1598 }
1599 break;
1600 case WLAN_FC_TYPE_CTRL:
1601 switch (stype) {
1602 C2S(WLAN_FC_STYPE_PSPOLL)
1603 C2S(WLAN_FC_STYPE_RTS)
1604 C2S(WLAN_FC_STYPE_CTS)
1605 C2S(WLAN_FC_STYPE_ACK)
1606 C2S(WLAN_FC_STYPE_CFEND)
1607 C2S(WLAN_FC_STYPE_CFENDACK)
1608 }
1609 break;
1610 case WLAN_FC_TYPE_DATA:
1611 switch (stype) {
1612 C2S(WLAN_FC_STYPE_DATA)
1613 C2S(WLAN_FC_STYPE_DATA_CFACK)
1614 C2S(WLAN_FC_STYPE_DATA_CFPOLL)
1615 C2S(WLAN_FC_STYPE_DATA_CFACKPOLL)
1616 C2S(WLAN_FC_STYPE_NULLFUNC)
1617 C2S(WLAN_FC_STYPE_CFACK)
1618 C2S(WLAN_FC_STYPE_CFPOLL)
1619 C2S(WLAN_FC_STYPE_CFACKPOLL)
1620 C2S(WLAN_FC_STYPE_QOS_DATA)
1621 C2S(WLAN_FC_STYPE_QOS_DATA_CFACK)
1622 C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL)
1623 C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL)
1624 C2S(WLAN_FC_STYPE_QOS_NULL)
1625 C2S(WLAN_FC_STYPE_QOS_CFPOLL)
1626 C2S(WLAN_FC_STYPE_QOS_CFACKPOLL)
1627 }
1628 break;
1629 }
1630 return "WLAN_FC_TYPE_UNKNOWN";
1631 #undef C2S
1632 }
1633
1634
reason2str(u16 reason)1635 const char * reason2str(u16 reason)
1636 {
1637 #define R2S(r) case WLAN_REASON_ ## r: return #r;
1638 switch (reason) {
1639 R2S(UNSPECIFIED)
1640 R2S(PREV_AUTH_NOT_VALID)
1641 R2S(DEAUTH_LEAVING)
1642 R2S(DISASSOC_DUE_TO_INACTIVITY)
1643 R2S(DISASSOC_AP_BUSY)
1644 R2S(CLASS2_FRAME_FROM_NONAUTH_STA)
1645 R2S(CLASS3_FRAME_FROM_NONASSOC_STA)
1646 R2S(DISASSOC_STA_HAS_LEFT)
1647 R2S(STA_REQ_ASSOC_WITHOUT_AUTH)
1648 R2S(PWR_CAPABILITY_NOT_VALID)
1649 R2S(SUPPORTED_CHANNEL_NOT_VALID)
1650 R2S(BSS_TRANSITION_DISASSOC)
1651 R2S(INVALID_IE)
1652 R2S(MICHAEL_MIC_FAILURE)
1653 R2S(4WAY_HANDSHAKE_TIMEOUT)
1654 R2S(GROUP_KEY_UPDATE_TIMEOUT)
1655 R2S(IE_IN_4WAY_DIFFERS)
1656 R2S(GROUP_CIPHER_NOT_VALID)
1657 R2S(PAIRWISE_CIPHER_NOT_VALID)
1658 R2S(AKMP_NOT_VALID)
1659 R2S(UNSUPPORTED_RSN_IE_VERSION)
1660 R2S(INVALID_RSN_IE_CAPAB)
1661 R2S(IEEE_802_1X_AUTH_FAILED)
1662 R2S(CIPHER_SUITE_REJECTED)
1663 R2S(TDLS_TEARDOWN_UNREACHABLE)
1664 R2S(TDLS_TEARDOWN_UNSPECIFIED)
1665 R2S(SSP_REQUESTED_DISASSOC)
1666 R2S(NO_SSP_ROAMING_AGREEMENT)
1667 R2S(BAD_CIPHER_OR_AKM)
1668 R2S(NOT_AUTHORIZED_THIS_LOCATION)
1669 R2S(SERVICE_CHANGE_PRECLUDES_TS)
1670 R2S(UNSPECIFIED_QOS_REASON)
1671 R2S(NOT_ENOUGH_BANDWIDTH)
1672 R2S(DISASSOC_LOW_ACK)
1673 R2S(EXCEEDED_TXOP)
1674 R2S(STA_LEAVING)
1675 R2S(END_TS_BA_DLS)
1676 R2S(UNKNOWN_TS_BA)
1677 R2S(TIMEOUT)
1678 R2S(PEERKEY_MISMATCH)
1679 R2S(AUTHORIZED_ACCESS_LIMIT_REACHED)
1680 R2S(EXTERNAL_SERVICE_REQUIREMENTS)
1681 R2S(INVALID_FT_ACTION_FRAME_COUNT)
1682 R2S(INVALID_PMKID)
1683 R2S(INVALID_MDE)
1684 R2S(INVALID_FTE)
1685 R2S(MESH_PEERING_CANCELLED)
1686 R2S(MESH_MAX_PEERS)
1687 R2S(MESH_CONFIG_POLICY_VIOLATION)
1688 R2S(MESH_CLOSE_RCVD)
1689 R2S(MESH_MAX_RETRIES)
1690 R2S(MESH_CONFIRM_TIMEOUT)
1691 R2S(MESH_INVALID_GTK)
1692 R2S(MESH_INCONSISTENT_PARAMS)
1693 R2S(MESH_INVALID_SECURITY_CAP)
1694 R2S(MESH_PATH_ERROR_NO_PROXY_INFO)
1695 R2S(MESH_PATH_ERROR_NO_FORWARDING_INFO)
1696 R2S(MESH_PATH_ERROR_DEST_UNREACHABLE)
1697 R2S(MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS)
1698 R2S(MESH_CHANNEL_SWITCH_REGULATORY_REQ)
1699 R2S(MESH_CHANNEL_SWITCH_UNSPECIFIED)
1700 }
1701 return "UNKNOWN";
1702 #undef R2S
1703 }
1704
1705
status2str(u16 status)1706 const char * status2str(u16 status)
1707 {
1708 #define S2S(s) case WLAN_STATUS_ ## s: return #s;
1709 switch (status) {
1710 S2S(SUCCESS)
1711 S2S(UNSPECIFIED_FAILURE)
1712 S2S(TDLS_WAKEUP_ALTERNATE)
1713 S2S(TDLS_WAKEUP_REJECT)
1714 S2S(SECURITY_DISABLED)
1715 S2S(UNACCEPTABLE_LIFETIME)
1716 S2S(NOT_IN_SAME_BSS)
1717 S2S(CAPS_UNSUPPORTED)
1718 S2S(REASSOC_NO_ASSOC)
1719 S2S(ASSOC_DENIED_UNSPEC)
1720 S2S(NOT_SUPPORTED_AUTH_ALG)
1721 S2S(UNKNOWN_AUTH_TRANSACTION)
1722 S2S(CHALLENGE_FAIL)
1723 S2S(AUTH_TIMEOUT)
1724 S2S(AP_UNABLE_TO_HANDLE_NEW_STA)
1725 S2S(ASSOC_DENIED_RATES)
1726 S2S(ASSOC_DENIED_NOSHORT)
1727 S2S(SPEC_MGMT_REQUIRED)
1728 S2S(PWR_CAPABILITY_NOT_VALID)
1729 S2S(SUPPORTED_CHANNEL_NOT_VALID)
1730 S2S(ASSOC_DENIED_NO_SHORT_SLOT_TIME)
1731 S2S(ASSOC_DENIED_NO_HT)
1732 S2S(R0KH_UNREACHABLE)
1733 S2S(ASSOC_DENIED_NO_PCO)
1734 S2S(ASSOC_REJECTED_TEMPORARILY)
1735 S2S(ROBUST_MGMT_FRAME_POLICY_VIOLATION)
1736 S2S(UNSPECIFIED_QOS_FAILURE)
1737 S2S(DENIED_INSUFFICIENT_BANDWIDTH)
1738 S2S(DENIED_POOR_CHANNEL_CONDITIONS)
1739 S2S(DENIED_QOS_NOT_SUPPORTED)
1740 S2S(REQUEST_DECLINED)
1741 S2S(INVALID_PARAMETERS)
1742 S2S(REJECTED_WITH_SUGGESTED_CHANGES)
1743 S2S(INVALID_IE)
1744 S2S(GROUP_CIPHER_NOT_VALID)
1745 S2S(PAIRWISE_CIPHER_NOT_VALID)
1746 S2S(AKMP_NOT_VALID)
1747 S2S(UNSUPPORTED_RSN_IE_VERSION)
1748 S2S(INVALID_RSN_IE_CAPAB)
1749 S2S(CIPHER_REJECTED_PER_POLICY)
1750 S2S(TS_NOT_CREATED)
1751 S2S(DIRECT_LINK_NOT_ALLOWED)
1752 S2S(DEST_STA_NOT_PRESENT)
1753 S2S(DEST_STA_NOT_QOS_STA)
1754 S2S(ASSOC_DENIED_LISTEN_INT_TOO_LARGE)
1755 S2S(INVALID_FT_ACTION_FRAME_COUNT)
1756 S2S(INVALID_PMKID)
1757 S2S(INVALID_MDIE)
1758 S2S(INVALID_FTIE)
1759 S2S(REQUESTED_TCLAS_NOT_SUPPORTED)
1760 S2S(INSUFFICIENT_TCLAS_PROCESSING_RESOURCES)
1761 S2S(TRY_ANOTHER_BSS)
1762 S2S(GAS_ADV_PROTO_NOT_SUPPORTED)
1763 S2S(NO_OUTSTANDING_GAS_REQ)
1764 S2S(GAS_RESP_NOT_RECEIVED)
1765 S2S(STA_TIMED_OUT_WAITING_FOR_GAS_RESP)
1766 S2S(GAS_RESP_LARGER_THAN_LIMIT)
1767 S2S(REQ_REFUSED_HOME)
1768 S2S(ADV_SRV_UNREACHABLE)
1769 S2S(REQ_REFUSED_SSPN)
1770 S2S(REQ_REFUSED_UNAUTH_ACCESS)
1771 S2S(INVALID_RSNIE)
1772 S2S(U_APSD_COEX_NOT_SUPPORTED)
1773 S2S(U_APSD_COEX_MODE_NOT_SUPPORTED)
1774 S2S(BAD_INTERVAL_WITH_U_APSD_COEX)
1775 S2S(ANTI_CLOGGING_TOKEN_REQ)
1776 S2S(FINITE_CYCLIC_GROUP_NOT_SUPPORTED)
1777 S2S(CANNOT_FIND_ALT_TBTT)
1778 S2S(TRANSMISSION_FAILURE)
1779 S2S(REQ_TCLAS_NOT_SUPPORTED)
1780 S2S(TCLAS_RESOURCES_EXCHAUSTED)
1781 S2S(REJECTED_WITH_SUGGESTED_BSS_TRANSITION)
1782 S2S(REJECT_WITH_SCHEDULE)
1783 S2S(REJECT_NO_WAKEUP_SPECIFIED)
1784 S2S(SUCCESS_POWER_SAVE_MODE)
1785 S2S(PENDING_ADMITTING_FST_SESSION)
1786 S2S(PERFORMING_FST_NOW)
1787 S2S(PENDING_GAP_IN_BA_WINDOW)
1788 S2S(REJECT_U_PID_SETTING)
1789 S2S(REFUSED_EXTERNAL_REASON)
1790 S2S(REFUSED_AP_OUT_OF_MEMORY)
1791 S2S(REJECTED_EMERGENCY_SERVICE_NOT_SUPPORTED)
1792 S2S(QUERY_RESP_OUTSTANDING)
1793 S2S(REJECT_DSE_BAND)
1794 S2S(TCLAS_PROCESSING_TERMINATED)
1795 S2S(TS_SCHEDULE_CONFLICT)
1796 S2S(DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL)
1797 S2S(MCCAOP_RESERVATION_CONFLICT)
1798 S2S(MAF_LIMIT_EXCEEDED)
1799 S2S(MCCA_TRACK_LIMIT_EXCEEDED)
1800 S2S(DENIED_DUE_TO_SPECTRUM_MANAGEMENT)
1801 S2S(ASSOC_DENIED_NO_VHT)
1802 S2S(ENABLEMENT_DENIED)
1803 S2S(RESTRICTION_FROM_AUTHORIZED_GDB)
1804 S2S(AUTHORIZATION_DEENABLED)
1805 S2S(FILS_AUTHENTICATION_FAILURE)
1806 S2S(UNKNOWN_AUTHENTICATION_SERVER)
1807 S2S(UNKNOWN_PASSWORD_IDENTIFIER)
1808 S2S(DENIED_HE_NOT_SUPPORTED)
1809 S2S(SAE_HASH_TO_ELEMENT)
1810 S2S(SAE_PK)
1811 }
1812 return "UNKNOWN";
1813 #undef S2S
1814 }
1815
1816 #endif
1817
mb_ies_info_by_ies(struct mb_ies_info * info,const u8 * ies_buf,size_t ies_len)1818 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
1819 size_t ies_len)
1820 {
1821 const struct element *elem;
1822
1823 os_memset(info, 0, sizeof(*info));
1824
1825 if (!ies_buf)
1826 return 0;
1827
1828 for_each_element_id(elem, WLAN_EID_MULTI_BAND, ies_buf, ies_len) {
1829 if (info->nof_ies >= MAX_NOF_MB_IES_SUPPORTED)
1830 return 0;
1831
1832 wpa_printf(MSG_DEBUG, "MB IE of %u bytes found",
1833 elem->datalen + 2);
1834 info->ies[info->nof_ies].ie = elem->data;
1835 info->ies[info->nof_ies].ie_len = elem->datalen;
1836 info->nof_ies++;
1837 }
1838
1839 if (!for_each_element_completed(elem, ies_buf, ies_len)) {
1840 wpa_hexdump(MSG_DEBUG, "Truncated IEs", ies_buf, ies_len);
1841 return -1;
1842 }
1843
1844 return 0;
1845 }
1846
1847
mb_ies_by_info(struct mb_ies_info * info)1848 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info)
1849 {
1850 struct wpabuf *mb_ies = NULL;
1851
1852 WPA_ASSERT(info != NULL);
1853
1854 if (info->nof_ies) {
1855 u8 i;
1856 size_t mb_ies_size = 0;
1857
1858 for (i = 0; i < info->nof_ies; i++)
1859 mb_ies_size += 2 + info->ies[i].ie_len;
1860
1861 mb_ies = wpabuf_alloc(mb_ies_size);
1862 if (mb_ies) {
1863 for (i = 0; i < info->nof_ies; i++) {
1864 wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND);
1865 wpabuf_put_u8(mb_ies, info->ies[i].ie_len);
1866 wpabuf_put_data(mb_ies,
1867 info->ies[i].ie,
1868 info->ies[i].ie_len);
1869 }
1870 }
1871 }
1872
1873 return mb_ies;
1874 }
1875
1876
1877 const struct oper_class_map global_op_class[] = {
1878 { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP },
1879 { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP },
1880
1881 /* Do not enable HT40 on 2.4 GHz for P2P use for now */
1882 { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP },
1883 { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP },
1884
1885 { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP },
1886 { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP },
1887 { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP },
1888 { HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP },
1889 { HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP },
1890 { HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP },
1891 { HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP },
1892 { HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP },
1893 { HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP },
1894 { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
1895 { HOSTAPD_MODE_IEEE80211A, 125, 149, 177, 4, BW20, P2P_SUPP },
1896 { HOSTAPD_MODE_IEEE80211A, 126, 149, 173, 8, BW40PLUS, P2P_SUPP },
1897 { HOSTAPD_MODE_IEEE80211A, 127, 153, 177, 8, BW40MINUS, P2P_SUPP },
1898
1899 /*
1900 * IEEE P802.11ax/D8.0 Table E-4 actually talks about channel center
1901 * frequency index 42, 58, 106, 122, 138, 155, 171 with channel spacing
1902 * of 80 MHz, but currently use the following definition for simplicity
1903 * (these center frequencies are not actual channels, which makes
1904 * wpas_p2p_verify_channel() fail). wpas_p2p_verify_80mhz() should take
1905 * care of removing invalid channels.
1906 */
1907 { HOSTAPD_MODE_IEEE80211A, 128, 36, 177, 4, BW80, P2P_SUPP },
1908 { HOSTAPD_MODE_IEEE80211A, 129, 36, 177, 4, BW160, P2P_SUPP },
1909 { HOSTAPD_MODE_IEEE80211A, 131, 1, 233, 4, BW20, P2P_SUPP },
1910 { HOSTAPD_MODE_IEEE80211A, 132, 1, 233, 8, BW40, P2P_SUPP },
1911 { HOSTAPD_MODE_IEEE80211A, 133, 1, 233, 16, BW80, P2P_SUPP },
1912 { HOSTAPD_MODE_IEEE80211A, 134, 1, 233, 32, BW160, P2P_SUPP },
1913 { HOSTAPD_MODE_IEEE80211A, 135, 1, 233, 16, BW80P80, NO_P2P_SUPP },
1914 { HOSTAPD_MODE_IEEE80211A, 136, 2, 2, 4, BW20, NO_P2P_SUPP },
1915
1916 /*
1917 * IEEE Std 802.11ad-2012 and P802.ay/D5.0 60 GHz operating classes.
1918 * Class 180 has the legacy channels 1-6. Classes 181-183 include
1919 * channels which implement channel bonding features.
1920 */
1921 { HOSTAPD_MODE_IEEE80211AD, 180, 1, 6, 1, BW2160, P2P_SUPP },
1922 { HOSTAPD_MODE_IEEE80211AD, 181, 9, 13, 1, BW4320, P2P_SUPP },
1923 { HOSTAPD_MODE_IEEE80211AD, 182, 17, 20, 1, BW6480, P2P_SUPP },
1924 { HOSTAPD_MODE_IEEE80211AD, 183, 25, 27, 1, BW8640, P2P_SUPP },
1925
1926 /* Keep the operating class 130 as the last entry as a workaround for
1927 * the OneHundredAndThirty Delimiter value used in the Supported
1928 * Operating Classes element to indicate the end of the Operating
1929 * Classes field. */
1930 { HOSTAPD_MODE_IEEE80211A, 130, 36, 177, 4, BW80P80, P2P_SUPP },
1931 { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
1932 };
1933
1934
ieee80211_phy_type_by_freq(int freq)1935 static enum phy_type ieee80211_phy_type_by_freq(int freq)
1936 {
1937 enum hostapd_hw_mode hw_mode;
1938 u8 channel;
1939
1940 hw_mode = ieee80211_freq_to_chan(freq, &channel);
1941
1942 switch (hw_mode) {
1943 case HOSTAPD_MODE_IEEE80211A:
1944 return PHY_TYPE_OFDM;
1945 case HOSTAPD_MODE_IEEE80211B:
1946 return PHY_TYPE_HRDSSS;
1947 case HOSTAPD_MODE_IEEE80211G:
1948 return PHY_TYPE_ERP;
1949 case HOSTAPD_MODE_IEEE80211AD:
1950 return PHY_TYPE_DMG;
1951 default:
1952 return PHY_TYPE_UNSPECIFIED;
1953 };
1954 }
1955
1956
1957 /* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */
ieee80211_get_phy_type(int freq,int ht,int vht)1958 enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht)
1959 {
1960 if (vht)
1961 return PHY_TYPE_VHT;
1962 if (ht)
1963 return PHY_TYPE_HT;
1964
1965 return ieee80211_phy_type_by_freq(freq);
1966 }
1967
1968
1969 size_t global_op_class_size = ARRAY_SIZE(global_op_class);
1970
1971
1972 /**
1973 * get_ie - Fetch a specified information element from IEs buffer
1974 * @ies: Information elements buffer
1975 * @len: Information elements buffer length
1976 * @eid: Information element identifier (WLAN_EID_*)
1977 * Returns: Pointer to the information element (id field) or %NULL if not found
1978 *
1979 * This function returns the first matching information element in the IEs
1980 * buffer or %NULL in case the element is not found.
1981 */
get_ie(const u8 * ies,size_t len,u8 eid)1982 const u8 * get_ie(const u8 *ies, size_t len, u8 eid)
1983 {
1984 const struct element *elem;
1985
1986 if (!ies)
1987 return NULL;
1988
1989 for_each_element_id(elem, eid, ies, len)
1990 return &elem->id;
1991
1992 return NULL;
1993 }
1994
1995
1996 /**
1997 * get_ie_ext - Fetch a specified extended information element from IEs buffer
1998 * @ies: Information elements buffer
1999 * @len: Information elements buffer length
2000 * @ext: Information element extension identifier (WLAN_EID_EXT_*)
2001 * Returns: Pointer to the information element (id field) or %NULL if not found
2002 *
2003 * This function returns the first matching information element in the IEs
2004 * buffer or %NULL in case the element is not found.
2005 */
get_ie_ext(const u8 * ies,size_t len,u8 ext)2006 const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext)
2007 {
2008 const struct element *elem;
2009
2010 if (!ies)
2011 return NULL;
2012
2013 for_each_element_extid(elem, ext, ies, len)
2014 return &elem->id;
2015
2016 return NULL;
2017 }
2018
2019
get_vendor_ie(const u8 * ies,size_t len,u32 vendor_type)2020 const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type)
2021 {
2022 const struct element *elem;
2023
2024 for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, len) {
2025 if (elem->datalen >= 4 &&
2026 vendor_type == WPA_GET_BE32(elem->data))
2027 return &elem->id;
2028 }
2029
2030 return NULL;
2031 }
2032
2033
mbo_add_ie(u8 * buf,size_t len,const u8 * attr,size_t attr_len)2034 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
2035 {
2036 /*
2037 * MBO IE requires 6 bytes without the attributes: EID (1), length (1),
2038 * OUI (3), OUI type (1).
2039 */
2040 if (len < 6 + attr_len) {
2041 wpa_printf(MSG_DEBUG,
2042 "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu",
2043 len, attr_len);
2044 return 0;
2045 }
2046
2047 *buf++ = WLAN_EID_VENDOR_SPECIFIC;
2048 *buf++ = attr_len + 4;
2049 WPA_PUT_BE24(buf, OUI_WFA);
2050 buf += 3;
2051 *buf++ = MBO_OUI_TYPE;
2052 os_memcpy(buf, attr, attr_len);
2053
2054 return 6 + attr_len;
2055 }
2056
2057
add_multi_ap_ie(u8 * buf,size_t len,u8 value)2058 size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value)
2059 {
2060 u8 *pos = buf;
2061
2062 if (len < 9)
2063 return 0;
2064
2065 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
2066 *pos++ = 7; /* len */
2067 WPA_PUT_BE24(pos, OUI_WFA);
2068 pos += 3;
2069 *pos++ = MULTI_AP_OUI_TYPE;
2070 *pos++ = MULTI_AP_SUB_ELEM_TYPE;
2071 *pos++ = 1; /* len */
2072 *pos++ = value;
2073
2074 return pos - buf;
2075 }
2076
2077
2078 static const struct country_op_class us_op_class[] = {
2079 { 1, 115 },
2080 { 2, 118 },
2081 { 3, 124 },
2082 { 4, 121 },
2083 { 5, 125 },
2084 { 12, 81 },
2085 { 22, 116 },
2086 { 23, 119 },
2087 { 24, 122 },
2088 { 25, 126 },
2089 { 26, 126 },
2090 { 27, 117 },
2091 { 28, 120 },
2092 { 29, 123 },
2093 { 30, 127 },
2094 { 31, 127 },
2095 { 32, 83 },
2096 { 33, 84 },
2097 { 34, 180 },
2098 };
2099
2100 static const struct country_op_class eu_op_class[] = {
2101 { 1, 115 },
2102 { 2, 118 },
2103 { 3, 121 },
2104 { 4, 81 },
2105 { 5, 116 },
2106 { 6, 119 },
2107 { 7, 122 },
2108 { 8, 117 },
2109 { 9, 120 },
2110 { 10, 123 },
2111 { 11, 83 },
2112 { 12, 84 },
2113 { 17, 125 },
2114 { 18, 180 },
2115 };
2116
2117 static const struct country_op_class jp_op_class[] = {
2118 { 1, 115 },
2119 { 30, 81 },
2120 { 31, 82 },
2121 { 32, 118 },
2122 { 33, 118 },
2123 { 34, 121 },
2124 { 35, 121 },
2125 { 36, 116 },
2126 { 37, 119 },
2127 { 38, 119 },
2128 { 39, 122 },
2129 { 40, 122 },
2130 { 41, 117 },
2131 { 42, 120 },
2132 { 43, 120 },
2133 { 44, 123 },
2134 { 45, 123 },
2135 { 56, 83 },
2136 { 57, 84 },
2137 { 58, 121 },
2138 { 59, 180 },
2139 };
2140
2141 static const struct country_op_class cn_op_class[] = {
2142 { 1, 115 },
2143 { 2, 118 },
2144 { 3, 125 },
2145 { 4, 116 },
2146 { 5, 119 },
2147 { 6, 126 },
2148 { 7, 81 },
2149 { 8, 83 },
2150 { 9, 84 },
2151 };
2152
2153 static u8
global_op_class_from_country_array(u8 op_class,size_t array_size,const struct country_op_class * country_array)2154 global_op_class_from_country_array(u8 op_class, size_t array_size,
2155 const struct country_op_class *country_array)
2156 {
2157 size_t i;
2158
2159 for (i = 0; i < array_size; i++) {
2160 if (country_array[i].country_op_class == op_class)
2161 return country_array[i].global_op_class;
2162 }
2163
2164 return 0;
2165 }
2166
2167
country_to_global_op_class(const char * country,u8 op_class)2168 u8 country_to_global_op_class(const char *country, u8 op_class)
2169 {
2170 const struct country_op_class *country_array;
2171 size_t size;
2172 u8 g_op_class;
2173
2174 if (country_match(us_op_class_cc, country)) {
2175 country_array = us_op_class;
2176 size = ARRAY_SIZE(us_op_class);
2177 } else if (country_match(eu_op_class_cc, country)) {
2178 country_array = eu_op_class;
2179 size = ARRAY_SIZE(eu_op_class);
2180 } else if (country_match(jp_op_class_cc, country)) {
2181 country_array = jp_op_class;
2182 size = ARRAY_SIZE(jp_op_class);
2183 } else if (country_match(cn_op_class_cc, country)) {
2184 country_array = cn_op_class;
2185 size = ARRAY_SIZE(cn_op_class);
2186 } else {
2187 /*
2188 * Countries that do not match any of the above countries use
2189 * global operating classes
2190 */
2191 return op_class;
2192 }
2193
2194 g_op_class = global_op_class_from_country_array(op_class, size,
2195 country_array);
2196
2197 /*
2198 * If the given operating class did not match any of the country's
2199 * operating classes, assume that global operating class is used.
2200 */
2201 return g_op_class ? g_op_class : op_class;
2202 }
2203
2204
get_oper_class(const char * country,u8 op_class)2205 const struct oper_class_map * get_oper_class(const char *country, u8 op_class)
2206 {
2207 const struct oper_class_map *op;
2208
2209 if (country)
2210 op_class = country_to_global_op_class(country, op_class);
2211
2212 op = &global_op_class[0];
2213 while (op->op_class && op->op_class != op_class)
2214 op++;
2215
2216 if (!op->op_class)
2217 return NULL;
2218
2219 return op;
2220 }
2221
2222
oper_class_bw_to_int(const struct oper_class_map * map)2223 int oper_class_bw_to_int(const struct oper_class_map *map)
2224 {
2225 switch (map->bw) {
2226 case BW20:
2227 return 20;
2228 case BW40:
2229 case BW40PLUS:
2230 case BW40MINUS:
2231 return 40;
2232 case BW80:
2233 return 80;
2234 case BW80P80:
2235 case BW160:
2236 return 160;
2237 case BW2160:
2238 return 2160;
2239 default:
2240 return 0;
2241 }
2242 }
2243
2244
center_idx_to_bw_6ghz(u8 idx)2245 int center_idx_to_bw_6ghz(u8 idx)
2246 {
2247 /* Channel: 2 */
2248 if (idx == 2)
2249 return 0; /* 20 MHz */
2250 /* channels: 1, 5, 9, 13... */
2251 if ((idx & 0x3) == 0x1)
2252 return 0; /* 20 MHz */
2253 /* channels 3, 11, 19... */
2254 if ((idx & 0x7) == 0x3)
2255 return 1; /* 40 MHz */
2256 /* channels 7, 23, 39.. */
2257 if ((idx & 0xf) == 0x7)
2258 return 2; /* 80 MHz */
2259 /* channels 15, 47, 79...*/
2260 if ((idx & 0x1f) == 0xf)
2261 return 3; /* 160 MHz */
2262
2263 return -1;
2264 }
2265
2266
is_6ghz_freq(int freq)2267 bool is_6ghz_freq(int freq)
2268 {
2269 if (freq < 5935 || freq > 7115)
2270 return false;
2271
2272 if (freq == 5935)
2273 return true;
2274
2275 if (center_idx_to_bw_6ghz((freq - 5950) / 5) < 0)
2276 return false;
2277
2278 return true;
2279 }
2280
2281
is_6ghz_op_class(u8 op_class)2282 bool is_6ghz_op_class(u8 op_class)
2283 {
2284 return op_class >= 131 && op_class <= 136;
2285 }
2286
2287
is_6ghz_psc_frequency(int freq)2288 bool is_6ghz_psc_frequency(int freq)
2289 {
2290 int i;
2291
2292 if (!is_6ghz_freq(freq) || freq == 5935)
2293 return false;
2294 if ((((freq - 5950) / 5) & 0x3) != 0x1)
2295 return false;
2296
2297 i = (freq - 5950 + 55) % 80;
2298 if (i == 0)
2299 i = (freq - 5950 + 55) / 80;
2300
2301 if (i >= 1 && i <= 15)
2302 return true;
2303
2304 return false;
2305 }
2306
2307
2308 /**
2309 * get_6ghz_sec_channel - Get the relative position of the secondary channel
2310 * to the primary channel in 6 GHz
2311 * @channel: Primary channel to be checked for (in global op class 131)
2312 * Returns: 1 = secondary channel above, -1 = secondary channel below
2313 */
2314
get_6ghz_sec_channel(int channel)2315 int get_6ghz_sec_channel(int channel)
2316 {
2317 /*
2318 * In the 6 GHz band, primary channels are numbered as 1, 5, 9, 13.., so
2319 * the 40 MHz channels are formed with the channel pairs as (1,5),
2320 * (9,13), (17,21)..
2321 * The secondary channel for a given primary channel is below the
2322 * primary channel for the channels 5, 13, 21.. and it is above the
2323 * primary channel for the channels 1, 9, 17..
2324 */
2325
2326 if (((channel - 1) / 4) % 2)
2327 return -1;
2328 return 1;
2329 }
2330
2331
ieee802_11_parse_candidate_list(const char * pos,u8 * nei_rep,size_t nei_rep_len)2332 int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
2333 size_t nei_rep_len)
2334 {
2335 u8 *nei_pos = nei_rep;
2336 const char *end;
2337
2338 /*
2339 * BSS Transition Candidate List Entries - Neighbor Report elements
2340 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
2341 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
2342 */
2343 while (pos) {
2344 u8 *nei_start;
2345 long int val;
2346 char *endptr, *tmp;
2347
2348 pos = os_strstr(pos, " neighbor=");
2349 if (!pos)
2350 break;
2351 if (nei_pos + 15 > nei_rep + nei_rep_len) {
2352 wpa_printf(MSG_DEBUG,
2353 "Not enough room for additional neighbor");
2354 return -1;
2355 }
2356 pos += 10;
2357
2358 nei_start = nei_pos;
2359 *nei_pos++ = WLAN_EID_NEIGHBOR_REPORT;
2360 nei_pos++; /* length to be filled in */
2361
2362 if (hwaddr_aton(pos, nei_pos)) {
2363 wpa_printf(MSG_DEBUG, "Invalid BSSID");
2364 return -1;
2365 }
2366 nei_pos += ETH_ALEN;
2367 pos += 17;
2368 if (*pos != ',') {
2369 wpa_printf(MSG_DEBUG, "Missing BSSID Information");
2370 return -1;
2371 }
2372 pos++;
2373
2374 val = strtol(pos, &endptr, 0);
2375 WPA_PUT_LE32(nei_pos, val);
2376 nei_pos += 4;
2377 if (*endptr != ',') {
2378 wpa_printf(MSG_DEBUG, "Missing Operating Class");
2379 return -1;
2380 }
2381 pos = endptr + 1;
2382
2383 *nei_pos++ = atoi(pos); /* Operating Class */
2384 pos = os_strchr(pos, ',');
2385 if (pos == NULL) {
2386 wpa_printf(MSG_DEBUG, "Missing Channel Number");
2387 return -1;
2388 }
2389 pos++;
2390
2391 *nei_pos++ = atoi(pos); /* Channel Number */
2392 pos = os_strchr(pos, ',');
2393 if (pos == NULL) {
2394 wpa_printf(MSG_DEBUG, "Missing PHY Type");
2395 return -1;
2396 }
2397 pos++;
2398
2399 *nei_pos++ = atoi(pos); /* PHY Type */
2400 end = os_strchr(pos, ' ');
2401 tmp = os_strchr(pos, ',');
2402 if (tmp && (!end || tmp < end)) {
2403 /* Optional Subelements (hexdump) */
2404 size_t len;
2405
2406 pos = tmp + 1;
2407 end = os_strchr(pos, ' ');
2408 if (end)
2409 len = end - pos;
2410 else
2411 len = os_strlen(pos);
2412 if (nei_pos + len / 2 > nei_rep + nei_rep_len) {
2413 wpa_printf(MSG_DEBUG,
2414 "Not enough room for neighbor subelements");
2415 return -1;
2416 }
2417 if (len & 0x01 ||
2418 hexstr2bin(pos, nei_pos, len / 2) < 0) {
2419 wpa_printf(MSG_DEBUG,
2420 "Invalid neighbor subelement info");
2421 return -1;
2422 }
2423 nei_pos += len / 2;
2424 pos = end;
2425 }
2426
2427 nei_start[1] = nei_pos - nei_start - 2;
2428 }
2429
2430 return nei_pos - nei_rep;
2431 }
2432
2433
ieee802_11_ext_capab(const u8 * ie,unsigned int capab)2434 int ieee802_11_ext_capab(const u8 *ie, unsigned int capab)
2435 {
2436 if (!ie || ie[1] <= capab / 8)
2437 return 0;
2438 return !!(ie[2 + capab / 8] & BIT(capab % 8));
2439 }
2440
2441
ieee802_11_rsnx_capab_len(const u8 * rsnxe,size_t rsnxe_len,unsigned int capab)2442 bool ieee802_11_rsnx_capab_len(const u8 *rsnxe, size_t rsnxe_len,
2443 unsigned int capab)
2444 {
2445 const u8 *end;
2446 size_t flen, i;
2447 u32 capabs = 0;
2448
2449 if (!rsnxe || rsnxe_len == 0)
2450 return false;
2451 end = rsnxe + rsnxe_len;
2452 flen = (rsnxe[0] & 0x0f) + 1;
2453 if (rsnxe + flen > end)
2454 return false;
2455 if (flen > 4)
2456 flen = 4;
2457 for (i = 0; i < flen; i++)
2458 capabs |= rsnxe[i] << (8 * i);
2459
2460 return capabs & BIT(capab);
2461 }
2462
2463
ieee802_11_rsnx_capab(const u8 * rsnxe,unsigned int capab)2464 bool ieee802_11_rsnx_capab(const u8 *rsnxe, unsigned int capab)
2465 {
2466 return ieee802_11_rsnx_capab_len(rsnxe ? rsnxe + 2 : NULL,
2467 rsnxe ? rsnxe[1] : 0, capab);
2468 }
2469
2470
hostapd_encode_edmg_chan(int edmg_enable,u8 edmg_channel,int primary_channel,struct ieee80211_edmg_config * edmg)2471 void hostapd_encode_edmg_chan(int edmg_enable, u8 edmg_channel,
2472 int primary_channel,
2473 struct ieee80211_edmg_config *edmg)
2474 {
2475 if (!edmg_enable) {
2476 edmg->channels = 0;
2477 edmg->bw_config = 0;
2478 return;
2479 }
2480
2481 /* Only EDMG CB1 and EDMG CB2 contiguous channels supported for now */
2482 switch (edmg_channel) {
2483 case EDMG_CHANNEL_9:
2484 edmg->channels = EDMG_CHANNEL_9_SUBCHANNELS;
2485 edmg->bw_config = EDMG_BW_CONFIG_5;
2486 return;
2487 case EDMG_CHANNEL_10:
2488 edmg->channels = EDMG_CHANNEL_10_SUBCHANNELS;
2489 edmg->bw_config = EDMG_BW_CONFIG_5;
2490 return;
2491 case EDMG_CHANNEL_11:
2492 edmg->channels = EDMG_CHANNEL_11_SUBCHANNELS;
2493 edmg->bw_config = EDMG_BW_CONFIG_5;
2494 return;
2495 case EDMG_CHANNEL_12:
2496 edmg->channels = EDMG_CHANNEL_12_SUBCHANNELS;
2497 edmg->bw_config = EDMG_BW_CONFIG_5;
2498 return;
2499 case EDMG_CHANNEL_13:
2500 edmg->channels = EDMG_CHANNEL_13_SUBCHANNELS;
2501 edmg->bw_config = EDMG_BW_CONFIG_5;
2502 return;
2503 default:
2504 if (primary_channel > 0 && primary_channel < 7) {
2505 edmg->channels = BIT(primary_channel - 1);
2506 edmg->bw_config = EDMG_BW_CONFIG_4;
2507 } else {
2508 edmg->channels = 0;
2509 edmg->bw_config = 0;
2510 }
2511 break;
2512 }
2513 }
2514
2515
2516 /* Check if the requested EDMG configuration is a subset of the allowed
2517 * EDMG configuration. */
ieee802_edmg_is_allowed(struct ieee80211_edmg_config allowed,struct ieee80211_edmg_config requested)2518 int ieee802_edmg_is_allowed(struct ieee80211_edmg_config allowed,
2519 struct ieee80211_edmg_config requested)
2520 {
2521 /*
2522 * The validation check if the requested EDMG configuration
2523 * is a subset of the allowed EDMG configuration:
2524 * 1. Check that the requested channels are part (set) of the allowed
2525 * channels.
2526 * 2. P802.11ay defines the values of bw_config between 4 and 15.
2527 * (bw config % 4) will give us 4 groups inside bw_config definition,
2528 * inside each group we can check the subset just by comparing the
2529 * bw_config value.
2530 * Between this 4 groups, there is no subset relation - as a result of
2531 * the P802.11ay definition.
2532 * bw_config defined by IEEE P802.11ay/D4.0, 9.4.2.251, Table 13.
2533 */
2534 if (((requested.channels & allowed.channels) != requested.channels) ||
2535 ((requested.bw_config % 4) > (allowed.bw_config % 4)) ||
2536 requested.bw_config > allowed.bw_config)
2537 return 0;
2538
2539 return 1;
2540 }
2541
2542
op_class_to_bandwidth(u8 op_class)2543 int op_class_to_bandwidth(u8 op_class)
2544 {
2545 switch (op_class) {
2546 case 81:
2547 case 82:
2548 return 20;
2549 case 83: /* channels 1..9; 40 MHz */
2550 case 84: /* channels 5..13; 40 MHz */
2551 return 40;
2552 case 115: /* channels 36,40,44,48; indoor only */
2553 return 20;
2554 case 116: /* channels 36,44; 40 MHz; indoor only */
2555 case 117: /* channels 40,48; 40 MHz; indoor only */
2556 return 40;
2557 case 118: /* channels 52,56,60,64; dfs */
2558 return 20;
2559 case 119: /* channels 52,60; 40 MHz; dfs */
2560 case 120: /* channels 56,64; 40 MHz; dfs */
2561 return 40;
2562 case 121: /* channels 100-140 */
2563 return 20;
2564 case 122: /* channels 100-142; 40 MHz */
2565 case 123: /* channels 104-136; 40 MHz */
2566 return 40;
2567 case 124: /* channels 149,153,157,161 */
2568 case 125: /* channels 149,153,157,161,165,169,173,177 */
2569 return 20;
2570 case 126: /* channels 149,157,161,165,169,173; 40 MHz */
2571 case 127: /* channels 153..177; 40 MHz */
2572 return 40;
2573 case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
2574 return 80;
2575 case 129: /* center freqs 50, 114, 163; 160 MHz */
2576 return 160;
2577 case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80+80 MHz */
2578 return 80;
2579 case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
2580 return 20;
2581 case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
2582 return 40;
2583 case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
2584 return 80;
2585 case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
2586 case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
2587 return 160;
2588 case 136: /* UHB channels, 20 MHz: 2 */
2589 return 20;
2590 case 180: /* 60 GHz band, channels 1..8 */
2591 return 2160;
2592 case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
2593 return 4320;
2594 case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
2595 return 6480;
2596 case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
2597 return 8640;
2598 }
2599
2600 return 20;
2601 }
2602
2603
op_class_to_ch_width(u8 op_class)2604 int op_class_to_ch_width(u8 op_class)
2605 {
2606 switch (op_class) {
2607 case 81:
2608 case 82:
2609 return CHANWIDTH_USE_HT;
2610 case 83: /* channels 1..9; 40 MHz */
2611 case 84: /* channels 5..13; 40 MHz */
2612 return CHANWIDTH_USE_HT;
2613 case 115: /* channels 36,40,44,48; indoor only */
2614 return CHANWIDTH_USE_HT;
2615 case 116: /* channels 36,44; 40 MHz; indoor only */
2616 case 117: /* channels 40,48; 40 MHz; indoor only */
2617 return CHANWIDTH_USE_HT;
2618 case 118: /* channels 52,56,60,64; dfs */
2619 return CHANWIDTH_USE_HT;
2620 case 119: /* channels 52,60; 40 MHz; dfs */
2621 case 120: /* channels 56,64; 40 MHz; dfs */
2622 return CHANWIDTH_USE_HT;
2623 case 121: /* channels 100-140 */
2624 return CHANWIDTH_USE_HT;
2625 case 122: /* channels 100-142; 40 MHz */
2626 case 123: /* channels 104-136; 40 MHz */
2627 return CHANWIDTH_USE_HT;
2628 case 124: /* channels 149,153,157,161 */
2629 case 125: /* channels 149,153,157,161,165,169,171 */
2630 return CHANWIDTH_USE_HT;
2631 case 126: /* channels 149,157,165, 173; 40 MHz */
2632 case 127: /* channels 153,161,169,177; 40 MHz */
2633 return CHANWIDTH_USE_HT;
2634 case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
2635 return CHANWIDTH_80MHZ;
2636 case 129: /* center freqs 50, 114, 163; 160 MHz */
2637 return CHANWIDTH_160MHZ;
2638 case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80+80 MHz */
2639 return CHANWIDTH_80P80MHZ;
2640 case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
2641 return CHANWIDTH_USE_HT;
2642 case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
2643 return CHANWIDTH_USE_HT;
2644 case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
2645 return CHANWIDTH_80MHZ;
2646 case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
2647 return CHANWIDTH_160MHZ;
2648 case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
2649 return CHANWIDTH_80P80MHZ;
2650 case 136: /* UHB channels, 20 MHz: 2 */
2651 return CHANWIDTH_USE_HT;
2652 case 180: /* 60 GHz band, channels 1..8 */
2653 return CHANWIDTH_2160MHZ;
2654 case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
2655 return CHANWIDTH_4320MHZ;
2656 case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
2657 return CHANWIDTH_6480MHZ;
2658 case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
2659 return CHANWIDTH_8640MHZ;
2660 }
2661 return CHANWIDTH_USE_HT;
2662 }
2663
2664
ieee802_11_defrag_data(struct ieee802_11_elems * elems,u8 eid,u8 eid_ext,const u8 * data,u8 len)2665 struct wpabuf * ieee802_11_defrag_data(struct ieee802_11_elems *elems,
2666 u8 eid, u8 eid_ext,
2667 const u8 *data, u8 len)
2668 {
2669 struct frag_ies_info *frag_ies = &elems->frag_ies;
2670 struct wpabuf *buf;
2671 unsigned int i;
2672
2673 if (!elems || !data || !len)
2674 return NULL;
2675
2676 buf = wpabuf_alloc_copy(data, len);
2677 if (!buf)
2678 return NULL;
2679
2680 for (i = 0; i < frag_ies->n_frags; i++) {
2681 int ret;
2682
2683 if (frag_ies->frags[i].eid != eid ||
2684 frag_ies->frags[i].eid_ext != eid_ext)
2685 continue;
2686
2687 ret = wpabuf_resize(&buf, frag_ies->frags[i].ie_len);
2688 if (ret < 0) {
2689 wpabuf_free(buf);
2690 return NULL;
2691 }
2692
2693 /* Copy only the fragment data (without the EID and length) */
2694 wpabuf_put_data(buf, frag_ies->frags[i].ie,
2695 frag_ies->frags[i].ie_len);
2696 }
2697
2698 return buf;
2699 }
2700
2701
ieee802_11_defrag(struct ieee802_11_elems * elems,u8 eid,u8 eid_ext)2702 struct wpabuf * ieee802_11_defrag(struct ieee802_11_elems *elems,
2703 u8 eid, u8 eid_ext)
2704 {
2705 const u8 *data;
2706 u8 len;
2707
2708 /*
2709 * TODO: Defragmentation mechanism can be supported for all IEs. For now
2710 * handle only those that are used (or use ieee802_11_defrag_data()).
2711 */
2712 switch (eid) {
2713 case WLAN_EID_EXTENSION:
2714 switch (eid_ext) {
2715 case WLAN_EID_EXT_FILS_HLP_CONTAINER:
2716 data = elems->fils_hlp;
2717 len = elems->fils_hlp_len;
2718 break;
2719 case WLAN_EID_EXT_WRAPPED_DATA:
2720 data = elems->wrapped_data;
2721 len = elems->wrapped_data_len;
2722 break;
2723 default:
2724 wpa_printf(MSG_DEBUG,
2725 "Defragmentation not supported. eid_ext=%u",
2726 eid_ext);
2727 return NULL;
2728 }
2729 break;
2730 default:
2731 wpa_printf(MSG_DEBUG,
2732 "Defragmentation not supported. eid=%u", eid);
2733 return NULL;
2734 }
2735
2736 return ieee802_11_defrag_data(elems, eid, eid_ext, data, len);
2737 }
2738