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