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 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
ieee802_11_parse_extension(const u8 * pos,size_t elen,struct ieee802_11_elems * elems,int show_errors)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_OCV_OCI:
278 elems->oci = pos;
279 elems->oci_len = elen;
280 break;
281 default:
282 if (show_errors) {
283 wpa_printf(MSG_MSGDUMP,
284 "IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)",
285 ext_id, (unsigned int) elen);
286 }
287 return -1;
288 }
289
290 return 0;
291 }
292
293
294 /**
295 * ieee802_11_parse_elems - Parse information elements in management frames
296 * @start: Pointer to the start of IEs
297 * @len: Length of IE buffer in octets
298 * @elems: Data structure for parsed elements
299 * @show_errors: Whether to show parsing errors in debug log
300 * Returns: Parsing result
301 */
ieee802_11_parse_elems(const u8 * start,size_t len,struct ieee802_11_elems * elems,int show_errors)302 ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
303 struct ieee802_11_elems *elems,
304 int show_errors)
305 {
306 const struct element *elem;
307 int unknown = 0;
308
309 os_memset(elems, 0, sizeof(*elems));
310
311 if (!start)
312 return ParseOK;
313
314 for_each_element(elem, start, len) {
315 u8 id = elem->id, elen = elem->datalen;
316 const u8 *pos = elem->data;
317
318 switch (id) {
319 case WLAN_EID_SSID:
320 if (elen > SSID_MAX_LEN) {
321 wpa_printf(MSG_DEBUG,
322 "Ignored too long SSID element (elen=%u)",
323 elen);
324 break;
325 }
326 elems->ssid = pos;
327 elems->ssid_len = elen;
328 break;
329 case WLAN_EID_SUPP_RATES:
330 elems->supp_rates = pos;
331 elems->supp_rates_len = elen;
332 break;
333 case WLAN_EID_DS_PARAMS:
334 if (elen < 1)
335 break;
336 elems->ds_params = pos;
337 break;
338 case WLAN_EID_CF_PARAMS:
339 case WLAN_EID_TIM:
340 break;
341 case WLAN_EID_CHALLENGE:
342 elems->challenge = pos;
343 elems->challenge_len = elen;
344 break;
345 case WLAN_EID_ERP_INFO:
346 if (elen < 1)
347 break;
348 elems->erp_info = pos;
349 break;
350 case WLAN_EID_EXT_SUPP_RATES:
351 elems->ext_supp_rates = pos;
352 elems->ext_supp_rates_len = elen;
353 break;
354 case WLAN_EID_VENDOR_SPECIFIC:
355 if (ieee802_11_parse_vendor_specific(pos, elen,
356 elems,
357 show_errors))
358 unknown++;
359 break;
360 case WLAN_EID_RSN:
361 elems->rsn_ie = pos;
362 elems->rsn_ie_len = elen;
363 break;
364 case WLAN_EID_PWR_CAPABILITY:
365 if (elen < 2)
366 break;
367 elems->power_capab = pos;
368 elems->power_capab_len = elen;
369 break;
370 case WLAN_EID_SUPPORTED_CHANNELS:
371 elems->supp_channels = pos;
372 elems->supp_channels_len = elen;
373 break;
374 case WLAN_EID_MOBILITY_DOMAIN:
375 if (elen < sizeof(struct rsn_mdie))
376 break;
377 elems->mdie = pos;
378 elems->mdie_len = elen;
379 break;
380 case WLAN_EID_FAST_BSS_TRANSITION:
381 if (elen < sizeof(struct rsn_ftie))
382 break;
383 elems->ftie = pos;
384 elems->ftie_len = elen;
385 break;
386 case WLAN_EID_TIMEOUT_INTERVAL:
387 if (elen != 5)
388 break;
389 elems->timeout_int = pos;
390 break;
391 case WLAN_EID_HT_CAP:
392 if (elen < sizeof(struct ieee80211_ht_capabilities))
393 break;
394 elems->ht_capabilities = pos;
395 break;
396 case WLAN_EID_HT_OPERATION:
397 if (elen < sizeof(struct ieee80211_ht_operation))
398 break;
399 elems->ht_operation = pos;
400 break;
401 case WLAN_EID_MESH_CONFIG:
402 elems->mesh_config = pos;
403 elems->mesh_config_len = elen;
404 break;
405 case WLAN_EID_MESH_ID:
406 elems->mesh_id = pos;
407 elems->mesh_id_len = elen;
408 break;
409 case WLAN_EID_PEER_MGMT:
410 elems->peer_mgmt = pos;
411 elems->peer_mgmt_len = elen;
412 break;
413 case WLAN_EID_VHT_CAP:
414 if (elen < sizeof(struct ieee80211_vht_capabilities))
415 break;
416 elems->vht_capabilities = pos;
417 break;
418 case WLAN_EID_VHT_OPERATION:
419 if (elen < sizeof(struct ieee80211_vht_operation))
420 break;
421 elems->vht_operation = pos;
422 break;
423 case WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION:
424 if (elen != 1)
425 break;
426 elems->vht_opmode_notif = pos;
427 break;
428 case WLAN_EID_LINK_ID:
429 if (elen < 18)
430 break;
431 elems->link_id = pos;
432 break;
433 case WLAN_EID_INTERWORKING:
434 elems->interworking = pos;
435 elems->interworking_len = elen;
436 break;
437 case WLAN_EID_QOS_MAP_SET:
438 if (elen < 16)
439 break;
440 elems->qos_map_set = pos;
441 elems->qos_map_set_len = elen;
442 break;
443 case WLAN_EID_EXT_CAPAB:
444 elems->ext_capab = pos;
445 elems->ext_capab_len = elen;
446 break;
447 case WLAN_EID_BSS_MAX_IDLE_PERIOD:
448 if (elen < 3)
449 break;
450 elems->bss_max_idle_period = pos;
451 break;
452 case WLAN_EID_SSID_LIST:
453 elems->ssid_list = pos;
454 elems->ssid_list_len = elen;
455 break;
456 case WLAN_EID_AMPE:
457 elems->ampe = pos;
458 elems->ampe_len = elen;
459 break;
460 case WLAN_EID_MIC:
461 elems->mic = pos;
462 elems->mic_len = elen;
463 /* after mic everything is encrypted, so stop. */
464 goto done;
465 case WLAN_EID_MULTI_BAND:
466 if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) {
467 wpa_printf(MSG_MSGDUMP,
468 "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)",
469 id, elen);
470 break;
471 }
472
473 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos;
474 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen;
475 elems->mb_ies.nof_ies++;
476 break;
477 case WLAN_EID_SUPPORTED_OPERATING_CLASSES:
478 elems->supp_op_classes = pos;
479 elems->supp_op_classes_len = elen;
480 break;
481 case WLAN_EID_RRM_ENABLED_CAPABILITIES:
482 elems->rrm_enabled = pos;
483 elems->rrm_enabled_len = elen;
484 break;
485 case WLAN_EID_CAG_NUMBER:
486 elems->cag_number = pos;
487 elems->cag_number_len = elen;
488 break;
489 case WLAN_EID_AP_CSN:
490 if (elen < 1)
491 break;
492 elems->ap_csn = pos;
493 break;
494 case WLAN_EID_FILS_INDICATION:
495 if (elen < 2)
496 break;
497 elems->fils_indic = pos;
498 elems->fils_indic_len = elen;
499 break;
500 case WLAN_EID_DILS:
501 if (elen < 2)
502 break;
503 elems->dils = pos;
504 elems->dils_len = elen;
505 break;
506 case WLAN_EID_FRAGMENT:
507 /* TODO */
508 break;
509 case WLAN_EID_EXTENSION:
510 if (ieee802_11_parse_extension(pos, elen, elems,
511 show_errors))
512 unknown++;
513 break;
514 default:
515 unknown++;
516 if (!show_errors)
517 break;
518 wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse "
519 "ignored unknown element (id=%d elen=%d)",
520 id, elen);
521 break;
522 }
523 }
524
525 if (!for_each_element_completed(elem, start, len)) {
526 if (show_errors) {
527 wpa_printf(MSG_DEBUG,
528 "IEEE 802.11 element parse failed @%d",
529 (int) (start + len - (const u8 *) elem));
530 wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
531 }
532 return ParseFailed;
533 }
534
535 done:
536 return unknown ? ParseUnknown : ParseOK;
537 }
538
539
ieee802_11_ie_count(const u8 * ies,size_t ies_len)540 int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
541 {
542 const struct element *elem;
543 int count = 0;
544
545 if (ies == NULL)
546 return 0;
547
548 for_each_element(elem, ies, ies_len)
549 count++;
550
551 return count;
552 }
553
554
ieee802_11_vendor_ie_concat(const u8 * ies,size_t ies_len,u32 oui_type)555 struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
556 u32 oui_type)
557 {
558 struct wpabuf *buf;
559 const struct element *elem, *found = NULL;
560
561 for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) {
562 if (elem->datalen >= 4 &&
563 WPA_GET_BE32(elem->data) == oui_type) {
564 found = elem;
565 break;
566 }
567 }
568
569 if (!found)
570 return NULL; /* No specified vendor IE found */
571
572 buf = wpabuf_alloc(ies_len);
573 if (buf == NULL)
574 return NULL;
575
576 /*
577 * There may be multiple vendor IEs in the message, so need to
578 * concatenate their data fields.
579 */
580 for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) {
581 if (elem->datalen >= 4 && WPA_GET_BE32(elem->data) == oui_type)
582 wpabuf_put_data(buf, elem->data + 4, elem->datalen - 4);
583 }
584
585 return buf;
586 }
587
588
get_hdr_bssid(const struct ieee80211_hdr * hdr,size_t len)589 const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
590 {
591 u16 fc, type, stype;
592
593 /*
594 * PS-Poll frames are 16 bytes. All other frames are
595 * 24 bytes or longer.
596 */
597 if (len < 16)
598 return NULL;
599
600 fc = le_to_host16(hdr->frame_control);
601 type = WLAN_FC_GET_TYPE(fc);
602 stype = WLAN_FC_GET_STYPE(fc);
603
604 switch (type) {
605 case WLAN_FC_TYPE_DATA:
606 if (len < 24)
607 return NULL;
608 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
609 case WLAN_FC_FROMDS | WLAN_FC_TODS:
610 case WLAN_FC_TODS:
611 return hdr->addr1;
612 case WLAN_FC_FROMDS:
613 return hdr->addr2;
614 default:
615 return NULL;
616 }
617 case WLAN_FC_TYPE_CTRL:
618 if (stype != WLAN_FC_STYPE_PSPOLL)
619 return NULL;
620 return hdr->addr1;
621 case WLAN_FC_TYPE_MGMT:
622 if (len < 24)
623 return NULL;
624 return hdr->addr3;
625 default:
626 return NULL;
627 }
628 }
629
630
hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],const char * name,const char * val)631 int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
632 const char *name, const char *val)
633 {
634 int num, v;
635 const char *pos;
636 struct hostapd_wmm_ac_params *ac;
637
638 /* skip 'wme_ac_' or 'wmm_ac_' prefix */
639 pos = name + 7;
640 if (os_strncmp(pos, "be_", 3) == 0) {
641 num = 0;
642 pos += 3;
643 } else if (os_strncmp(pos, "bk_", 3) == 0) {
644 num = 1;
645 pos += 3;
646 } else if (os_strncmp(pos, "vi_", 3) == 0) {
647 num = 2;
648 pos += 3;
649 } else if (os_strncmp(pos, "vo_", 3) == 0) {
650 num = 3;
651 pos += 3;
652 } else {
653 wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos);
654 return -1;
655 }
656
657 ac = &wmm_ac_params[num];
658
659 if (os_strcmp(pos, "aifs") == 0) {
660 v = atoi(val);
661 if (v < 1 || v > 255) {
662 wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v);
663 return -1;
664 }
665 ac->aifs = v;
666 } else if (os_strcmp(pos, "cwmin") == 0) {
667 v = atoi(val);
668 if (v < 0 || v > 15) {
669 wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v);
670 return -1;
671 }
672 ac->cwmin = v;
673 } else if (os_strcmp(pos, "cwmax") == 0) {
674 v = atoi(val);
675 if (v < 0 || v > 15) {
676 wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v);
677 return -1;
678 }
679 ac->cwmax = v;
680 } else if (os_strcmp(pos, "txop_limit") == 0) {
681 v = atoi(val);
682 if (v < 0 || v > 0xffff) {
683 wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
684 return -1;
685 }
686 ac->txop_limit = v;
687 } else if (os_strcmp(pos, "acm") == 0) {
688 v = atoi(val);
689 if (v < 0 || v > 1) {
690 wpa_printf(MSG_ERROR, "Invalid acm value %d", v);
691 return -1;
692 }
693 ac->admission_control_mandatory = v;
694 } else {
695 wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos);
696 return -1;
697 }
698
699 return 0;
700 }
701
702
ieee80211_freq_to_chan(int freq,u8 * channel)703 enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel)
704 {
705 u8 op_class;
706
707 return ieee80211_freq_to_channel_ext(freq, 0, VHT_CHANWIDTH_USE_HT,
708 &op_class, channel);
709 }
710
711
712 /**
713 * ieee80211_freq_to_channel_ext - Convert frequency into channel info
714 * for HT40 and VHT. DFS channels are not covered.
715 * @freq: Frequency (MHz) to convert
716 * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
717 * @vht: VHT channel width (VHT_CHANWIDTH_*)
718 * @op_class: Buffer for returning operating class
719 * @channel: Buffer for returning channel number
720 * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
721 */
ieee80211_freq_to_channel_ext(unsigned int freq,int sec_channel,int vht,u8 * op_class,u8 * channel)722 enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
723 int sec_channel, int vht,
724 u8 *op_class, u8 *channel)
725 {
726 u8 vht_opclass;
727
728 /* TODO: more operating classes */
729
730 if (sec_channel > 1 || sec_channel < -1)
731 return NUM_HOSTAPD_MODES;
732
733 if (freq >= 2412 && freq <= 2472) {
734 if ((freq - 2407) % 5)
735 return NUM_HOSTAPD_MODES;
736
737 if (vht)
738 return NUM_HOSTAPD_MODES;
739
740 /* 2.407 GHz, channels 1..13 */
741 if (sec_channel == 1)
742 *op_class = 83;
743 else if (sec_channel == -1)
744 *op_class = 84;
745 else
746 *op_class = 81;
747
748 *channel = (freq - 2407) / 5;
749
750 return HOSTAPD_MODE_IEEE80211G;
751 }
752
753 if (freq == 2484) {
754 if (sec_channel || vht)
755 return NUM_HOSTAPD_MODES;
756
757 *op_class = 82; /* channel 14 */
758 *channel = 14;
759
760 return HOSTAPD_MODE_IEEE80211B;
761 }
762
763 if (freq >= 4900 && freq < 5000) {
764 if ((freq - 4000) % 5)
765 return NUM_HOSTAPD_MODES;
766 *channel = (freq - 4000) / 5;
767 *op_class = 0; /* TODO */
768 return HOSTAPD_MODE_IEEE80211A;
769 }
770
771 switch (vht) {
772 case VHT_CHANWIDTH_80MHZ:
773 vht_opclass = 128;
774 break;
775 case VHT_CHANWIDTH_160MHZ:
776 vht_opclass = 129;
777 break;
778 case VHT_CHANWIDTH_80P80MHZ:
779 vht_opclass = 130;
780 break;
781 default:
782 vht_opclass = 0;
783 break;
784 }
785
786 /* 5 GHz, channels 36..48 */
787 if (freq >= 5180 && freq <= 5240) {
788 if ((freq - 5000) % 5)
789 return NUM_HOSTAPD_MODES;
790
791 if (vht_opclass)
792 *op_class = vht_opclass;
793 else if (sec_channel == 1)
794 *op_class = 116;
795 else if (sec_channel == -1)
796 *op_class = 117;
797 else
798 *op_class = 115;
799
800 *channel = (freq - 5000) / 5;
801
802 return HOSTAPD_MODE_IEEE80211A;
803 }
804
805 /* 5 GHz, channels 52..64 */
806 if (freq >= 5260 && freq <= 5320) {
807 if ((freq - 5000) % 5)
808 return NUM_HOSTAPD_MODES;
809
810 if (vht_opclass)
811 *op_class = vht_opclass;
812 else if (sec_channel == 1)
813 *op_class = 119;
814 else if (sec_channel == -1)
815 *op_class = 120;
816 else
817 *op_class = 118;
818
819 *channel = (freq - 5000) / 5;
820
821 return HOSTAPD_MODE_IEEE80211A;
822 }
823
824 /* 5 GHz, channels 149..169 */
825 if (freq >= 5745 && freq <= 5845) {
826 if ((freq - 5000) % 5)
827 return NUM_HOSTAPD_MODES;
828
829 if (vht_opclass)
830 *op_class = vht_opclass;
831 else if (sec_channel == 1)
832 *op_class = 126;
833 else if (sec_channel == -1)
834 *op_class = 127;
835 else if (freq <= 5805)
836 *op_class = 124;
837 else
838 *op_class = 125;
839
840 *channel = (freq - 5000) / 5;
841
842 return HOSTAPD_MODE_IEEE80211A;
843 }
844
845 /* 5 GHz, channels 100..140 */
846 if (freq >= 5000 && freq <= 5700) {
847 if ((freq - 5000) % 5)
848 return NUM_HOSTAPD_MODES;
849
850 if (vht_opclass)
851 *op_class = vht_opclass;
852 else if (sec_channel == 1)
853 *op_class = 122;
854 else if (sec_channel == -1)
855 *op_class = 123;
856 else
857 *op_class = 121;
858
859 *channel = (freq - 5000) / 5;
860
861 return HOSTAPD_MODE_IEEE80211A;
862 }
863
864 if (freq >= 5000 && freq < 5900) {
865 if ((freq - 5000) % 5)
866 return NUM_HOSTAPD_MODES;
867 *channel = (freq - 5000) / 5;
868 *op_class = 0; /* TODO */
869 return HOSTAPD_MODE_IEEE80211A;
870 }
871
872 /* 56.16 GHz, channel 1..4 */
873 if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) {
874 if (sec_channel || vht)
875 return NUM_HOSTAPD_MODES;
876
877 *channel = (freq - 56160) / 2160;
878 *op_class = 180;
879
880 return HOSTAPD_MODE_IEEE80211AD;
881 }
882
883 return NUM_HOSTAPD_MODES;
884 }
885
886
ieee80211_chaninfo_to_channel(unsigned int freq,enum chan_width chanwidth,int sec_channel,u8 * op_class,u8 * channel)887 int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
888 int sec_channel, u8 *op_class, u8 *channel)
889 {
890 int vht = CHAN_WIDTH_UNKNOWN;
891
892 switch (chanwidth) {
893 case CHAN_WIDTH_UNKNOWN:
894 case CHAN_WIDTH_20_NOHT:
895 case CHAN_WIDTH_20:
896 case CHAN_WIDTH_40:
897 vht = VHT_CHANWIDTH_USE_HT;
898 break;
899 case CHAN_WIDTH_80:
900 vht = VHT_CHANWIDTH_80MHZ;
901 break;
902 case CHAN_WIDTH_80P80:
903 vht = VHT_CHANWIDTH_80P80MHZ;
904 break;
905 case CHAN_WIDTH_160:
906 vht = VHT_CHANWIDTH_160MHZ;
907 break;
908 }
909
910 if (ieee80211_freq_to_channel_ext(freq, sec_channel, vht, op_class,
911 channel) == NUM_HOSTAPD_MODES) {
912 wpa_printf(MSG_WARNING,
913 "Cannot determine operating class and channel (freq=%u chanwidth=%d sec_channel=%d)",
914 freq, chanwidth, sec_channel);
915 return -1;
916 }
917
918 return 0;
919 }
920
921
922 static const char *const us_op_class_cc[] = {
923 "US", "CA", NULL
924 };
925
926 static const char *const eu_op_class_cc[] = {
927 "AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
928 "DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
929 "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
930 "RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL
931 };
932
933 static const char *const jp_op_class_cc[] = {
934 "JP", NULL
935 };
936
937 static const char *const cn_op_class_cc[] = {
938 "CN", NULL
939 };
940
941
country_match(const char * const cc[],const char * const country)942 static int country_match(const char *const cc[], const char *const country)
943 {
944 int i;
945
946 if (country == NULL)
947 return 0;
948 for (i = 0; cc[i]; i++) {
949 if (cc[i][0] == country[0] && cc[i][1] == country[1])
950 return 1;
951 }
952
953 return 0;
954 }
955
956
ieee80211_chan_to_freq_us(u8 op_class,u8 chan)957 static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan)
958 {
959 switch (op_class) {
960 case 12: /* channels 1..11 */
961 case 32: /* channels 1..7; 40 MHz */
962 case 33: /* channels 5..11; 40 MHz */
963 if (chan < 1 || chan > 11)
964 return -1;
965 return 2407 + 5 * chan;
966 case 1: /* channels 36,40,44,48 */
967 case 2: /* channels 52,56,60,64; dfs */
968 case 22: /* channels 36,44; 40 MHz */
969 case 23: /* channels 52,60; 40 MHz */
970 case 27: /* channels 40,48; 40 MHz */
971 case 28: /* channels 56,64; 40 MHz */
972 if (chan < 36 || chan > 64)
973 return -1;
974 return 5000 + 5 * chan;
975 case 4: /* channels 100-144 */
976 case 24: /* channels 100-140; 40 MHz */
977 if (chan < 100 || chan > 144)
978 return -1;
979 return 5000 + 5 * chan;
980 case 3: /* channels 149,153,157,161 */
981 case 25: /* channels 149,157; 40 MHz */
982 case 26: /* channels 149,157; 40 MHz */
983 case 30: /* channels 153,161; 40 MHz */
984 case 31: /* channels 153,161; 40 MHz */
985 if (chan < 149 || chan > 161)
986 return -1;
987 return 5000 + 5 * chan;
988 case 5: /* channels 149,153,157,161,165 */
989 if (chan < 149 || chan > 165)
990 return -1;
991 return 5000 + 5 * chan;
992 case 34: /* 60 GHz band, channels 1..3 */
993 if (chan < 1 || chan > 3)
994 return -1;
995 return 56160 + 2160 * chan;
996 }
997 return -1;
998 }
999
1000
ieee80211_chan_to_freq_eu(u8 op_class,u8 chan)1001 static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan)
1002 {
1003 switch (op_class) {
1004 case 4: /* channels 1..13 */
1005 case 11: /* channels 1..9; 40 MHz */
1006 case 12: /* channels 5..13; 40 MHz */
1007 if (chan < 1 || chan > 13)
1008 return -1;
1009 return 2407 + 5 * chan;
1010 case 1: /* channels 36,40,44,48 */
1011 case 2: /* channels 52,56,60,64; dfs */
1012 case 5: /* channels 36,44; 40 MHz */
1013 case 6: /* channels 52,60; 40 MHz */
1014 case 8: /* channels 40,48; 40 MHz */
1015 case 9: /* channels 56,64; 40 MHz */
1016 if (chan < 36 || chan > 64)
1017 return -1;
1018 return 5000 + 5 * chan;
1019 case 3: /* channels 100-140 */
1020 case 7: /* channels 100-132; 40 MHz */
1021 case 10: /* channels 104-136; 40 MHz */
1022 case 16: /* channels 100-140 */
1023 if (chan < 100 || chan > 140)
1024 return -1;
1025 return 5000 + 5 * chan;
1026 case 17: /* channels 149,153,157,161,165,169 */
1027 if (chan < 149 || chan > 169)
1028 return -1;
1029 return 5000 + 5 * chan;
1030 case 18: /* 60 GHz band, channels 1..4 */
1031 if (chan < 1 || chan > 4)
1032 return -1;
1033 return 56160 + 2160 * chan;
1034 }
1035 return -1;
1036 }
1037
1038
ieee80211_chan_to_freq_jp(u8 op_class,u8 chan)1039 static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan)
1040 {
1041 switch (op_class) {
1042 case 30: /* channels 1..13 */
1043 case 56: /* channels 1..9; 40 MHz */
1044 case 57: /* channels 5..13; 40 MHz */
1045 if (chan < 1 || chan > 13)
1046 return -1;
1047 return 2407 + 5 * chan;
1048 case 31: /* channel 14 */
1049 if (chan != 14)
1050 return -1;
1051 return 2414 + 5 * chan;
1052 case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */
1053 case 32: /* channels 52,56,60,64 */
1054 case 33: /* channels 52,56,60,64 */
1055 case 36: /* channels 36,44; 40 MHz */
1056 case 37: /* channels 52,60; 40 MHz */
1057 case 38: /* channels 52,60; 40 MHz */
1058 case 41: /* channels 40,48; 40 MHz */
1059 case 42: /* channels 56,64; 40 MHz */
1060 case 43: /* channels 56,64; 40 MHz */
1061 if (chan < 34 || chan > 64)
1062 return -1;
1063 return 5000 + 5 * chan;
1064 case 34: /* channels 100-140 */
1065 case 35: /* channels 100-140 */
1066 case 39: /* channels 100-132; 40 MHz */
1067 case 40: /* channels 100-132; 40 MHz */
1068 case 44: /* channels 104-136; 40 MHz */
1069 case 45: /* channels 104-136; 40 MHz */
1070 case 58: /* channels 100-140 */
1071 if (chan < 100 || chan > 140)
1072 return -1;
1073 return 5000 + 5 * chan;
1074 case 59: /* 60 GHz band, channels 1..4 */
1075 if (chan < 1 || chan > 3)
1076 return -1;
1077 return 56160 + 2160 * chan;
1078 }
1079 return -1;
1080 }
1081
1082
ieee80211_chan_to_freq_cn(u8 op_class,u8 chan)1083 static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan)
1084 {
1085 switch (op_class) {
1086 case 7: /* channels 1..13 */
1087 case 8: /* channels 1..9; 40 MHz */
1088 case 9: /* channels 5..13; 40 MHz */
1089 if (chan < 1 || chan > 13)
1090 return -1;
1091 return 2407 + 5 * chan;
1092 case 1: /* channels 36,40,44,48 */
1093 case 2: /* channels 52,56,60,64; dfs */
1094 case 4: /* channels 36,44; 40 MHz */
1095 case 5: /* channels 52,60; 40 MHz */
1096 if (chan < 36 || chan > 64)
1097 return -1;
1098 return 5000 + 5 * chan;
1099 case 3: /* channels 149,153,157,161,165 */
1100 case 6: /* channels 149,157; 40 MHz */
1101 if (chan < 149 || chan > 165)
1102 return -1;
1103 return 5000 + 5 * chan;
1104 }
1105 return -1;
1106 }
1107
1108
ieee80211_chan_to_freq_global(u8 op_class,u8 chan)1109 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
1110 {
1111 /* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
1112 switch (op_class) {
1113 case 81:
1114 /* channels 1..13 */
1115 if (chan < 1 || chan > 13)
1116 return -1;
1117 return 2407 + 5 * chan;
1118 case 82:
1119 /* channel 14 */
1120 if (chan != 14)
1121 return -1;
1122 return 2414 + 5 * chan;
1123 case 83: /* channels 1..9; 40 MHz */
1124 case 84: /* channels 5..13; 40 MHz */
1125 if (chan < 1 || chan > 13)
1126 return -1;
1127 return 2407 + 5 * chan;
1128 case 115: /* channels 36,40,44,48; indoor only */
1129 case 116: /* channels 36,44; 40 MHz; indoor only */
1130 case 117: /* channels 40,48; 40 MHz; indoor only */
1131 case 118: /* channels 52,56,60,64; dfs */
1132 case 119: /* channels 52,60; 40 MHz; dfs */
1133 case 120: /* channels 56,64; 40 MHz; dfs */
1134 if (chan < 36 || chan > 64)
1135 return -1;
1136 return 5000 + 5 * chan;
1137 case 121: /* channels 100-140 */
1138 case 122: /* channels 100-142; 40 MHz */
1139 case 123: /* channels 104-136; 40 MHz */
1140 if (chan < 100 || chan > 140)
1141 return -1;
1142 return 5000 + 5 * chan;
1143 case 124: /* channels 149,153,157,161 */
1144 case 126: /* channels 149,157; 40 MHz */
1145 case 127: /* channels 153,161; 40 MHz */
1146 if (chan < 149 || chan > 161)
1147 return -1;
1148 return 5000 + 5 * chan;
1149 case 125: /* channels 149,153,157,161,165,169 */
1150 if (chan < 149 || chan > 169)
1151 return -1;
1152 return 5000 + 5 * chan;
1153 case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
1154 case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
1155 if (chan < 36 || chan > 161)
1156 return -1;
1157 return 5000 + 5 * chan;
1158 case 129: /* center freqs 50, 114; 160 MHz */
1159 if (chan < 36 || chan > 128)
1160 return -1;
1161 return 5000 + 5 * chan;
1162 case 180: /* 60 GHz band, channels 1..4 */
1163 if (chan < 1 || chan > 4)
1164 return -1;
1165 return 56160 + 2160 * chan;
1166 }
1167 return -1;
1168 }
1169
1170 /**
1171 * ieee80211_chan_to_freq - Convert channel info to frequency
1172 * @country: Country code, if known; otherwise, global operating class is used
1173 * @op_class: Operating class
1174 * @chan: Channel number
1175 * Returns: Frequency in MHz or -1 if the specified channel is unknown
1176 */
ieee80211_chan_to_freq(const char * country,u8 op_class,u8 chan)1177 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan)
1178 {
1179 int freq;
1180
1181 if (country_match(us_op_class_cc, country)) {
1182 freq = ieee80211_chan_to_freq_us(op_class, chan);
1183 if (freq > 0)
1184 return freq;
1185 }
1186
1187 if (country_match(eu_op_class_cc, country)) {
1188 freq = ieee80211_chan_to_freq_eu(op_class, chan);
1189 if (freq > 0)
1190 return freq;
1191 }
1192
1193 if (country_match(jp_op_class_cc, country)) {
1194 freq = ieee80211_chan_to_freq_jp(op_class, chan);
1195 if (freq > 0)
1196 return freq;
1197 }
1198
1199 if (country_match(cn_op_class_cc, country)) {
1200 freq = ieee80211_chan_to_freq_cn(op_class, chan);
1201 if (freq > 0)
1202 return freq;
1203 }
1204
1205 return ieee80211_chan_to_freq_global(op_class, chan);
1206 }
1207
1208
ieee80211_is_dfs(int freq,const struct hostapd_hw_modes * modes,u16 num_modes)1209 int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
1210 u16 num_modes)
1211 {
1212 int i, j;
1213
1214 if (!modes || !num_modes)
1215 return (freq >= 5260 && freq <= 5320) ||
1216 (freq >= 5500 && freq <= 5700);
1217
1218 for (i = 0; i < num_modes; i++) {
1219 for (j = 0; j < modes[i].num_channels; j++) {
1220 if (modes[i].channels[j].freq == freq &&
1221 (modes[i].channels[j].flag & HOSTAPD_CHAN_RADAR))
1222 return 1;
1223 }
1224 }
1225
1226 return 0;
1227 }
1228
1229
is_11b(u8 rate)1230 static int is_11b(u8 rate)
1231 {
1232 return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
1233 }
1234
1235
supp_rates_11b_only(struct ieee802_11_elems * elems)1236 int supp_rates_11b_only(struct ieee802_11_elems *elems)
1237 {
1238 int num_11b = 0, num_others = 0;
1239 int i;
1240
1241 if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
1242 return 0;
1243
1244 for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
1245 if (is_11b(elems->supp_rates[i]))
1246 num_11b++;
1247 else
1248 num_others++;
1249 }
1250
1251 for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
1252 i++) {
1253 if (is_11b(elems->ext_supp_rates[i]))
1254 num_11b++;
1255 else
1256 num_others++;
1257 }
1258
1259 return num_11b > 0 && num_others == 0;
1260 }
1261
1262
fc2str(u16 fc)1263 const char * fc2str(u16 fc)
1264 {
1265 u16 stype = WLAN_FC_GET_STYPE(fc);
1266 #define C2S(x) case x: return #x;
1267
1268 switch (WLAN_FC_GET_TYPE(fc)) {
1269 case WLAN_FC_TYPE_MGMT:
1270 switch (stype) {
1271 C2S(WLAN_FC_STYPE_ASSOC_REQ)
1272 C2S(WLAN_FC_STYPE_ASSOC_RESP)
1273 C2S(WLAN_FC_STYPE_REASSOC_REQ)
1274 C2S(WLAN_FC_STYPE_REASSOC_RESP)
1275 C2S(WLAN_FC_STYPE_PROBE_REQ)
1276 C2S(WLAN_FC_STYPE_PROBE_RESP)
1277 C2S(WLAN_FC_STYPE_BEACON)
1278 C2S(WLAN_FC_STYPE_ATIM)
1279 C2S(WLAN_FC_STYPE_DISASSOC)
1280 C2S(WLAN_FC_STYPE_AUTH)
1281 C2S(WLAN_FC_STYPE_DEAUTH)
1282 C2S(WLAN_FC_STYPE_ACTION)
1283 }
1284 break;
1285 case WLAN_FC_TYPE_CTRL:
1286 switch (stype) {
1287 C2S(WLAN_FC_STYPE_PSPOLL)
1288 C2S(WLAN_FC_STYPE_RTS)
1289 C2S(WLAN_FC_STYPE_CTS)
1290 C2S(WLAN_FC_STYPE_ACK)
1291 C2S(WLAN_FC_STYPE_CFEND)
1292 C2S(WLAN_FC_STYPE_CFENDACK)
1293 }
1294 break;
1295 case WLAN_FC_TYPE_DATA:
1296 switch (stype) {
1297 C2S(WLAN_FC_STYPE_DATA)
1298 C2S(WLAN_FC_STYPE_DATA_CFACK)
1299 C2S(WLAN_FC_STYPE_DATA_CFPOLL)
1300 C2S(WLAN_FC_STYPE_DATA_CFACKPOLL)
1301 C2S(WLAN_FC_STYPE_NULLFUNC)
1302 C2S(WLAN_FC_STYPE_CFACK)
1303 C2S(WLAN_FC_STYPE_CFPOLL)
1304 C2S(WLAN_FC_STYPE_CFACKPOLL)
1305 C2S(WLAN_FC_STYPE_QOS_DATA)
1306 C2S(WLAN_FC_STYPE_QOS_DATA_CFACK)
1307 C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL)
1308 C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL)
1309 C2S(WLAN_FC_STYPE_QOS_NULL)
1310 C2S(WLAN_FC_STYPE_QOS_CFPOLL)
1311 C2S(WLAN_FC_STYPE_QOS_CFACKPOLL)
1312 }
1313 break;
1314 }
1315 return "WLAN_FC_TYPE_UNKNOWN";
1316 #undef C2S
1317 }
1318
1319
mb_ies_info_by_ies(struct mb_ies_info * info,const u8 * ies_buf,size_t ies_len)1320 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
1321 size_t ies_len)
1322 {
1323 const struct element *elem;
1324
1325 os_memset(info, 0, sizeof(*info));
1326
1327 if (!ies_buf)
1328 return 0;
1329
1330 for_each_element_id(elem, WLAN_EID_MULTI_BAND, ies_buf, ies_len) {
1331 if (info->nof_ies >= MAX_NOF_MB_IES_SUPPORTED)
1332 return 0;
1333
1334 wpa_printf(MSG_DEBUG, "MB IE of %u bytes found",
1335 elem->datalen + 2);
1336 info->ies[info->nof_ies].ie = elem->data;
1337 info->ies[info->nof_ies].ie_len = elem->datalen;
1338 info->nof_ies++;
1339 }
1340
1341 if (!for_each_element_completed(elem, ies_buf, ies_len)) {
1342 wpa_hexdump(MSG_DEBUG, "Truncated IEs", ies_buf, ies_len);
1343 return -1;
1344 }
1345
1346 return 0;
1347 }
1348
1349
mb_ies_by_info(struct mb_ies_info * info)1350 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info)
1351 {
1352 struct wpabuf *mb_ies = NULL;
1353
1354 WPA_ASSERT(info != NULL);
1355
1356 if (info->nof_ies) {
1357 u8 i;
1358 size_t mb_ies_size = 0;
1359
1360 for (i = 0; i < info->nof_ies; i++)
1361 mb_ies_size += 2 + info->ies[i].ie_len;
1362
1363 mb_ies = wpabuf_alloc(mb_ies_size);
1364 if (mb_ies) {
1365 for (i = 0; i < info->nof_ies; i++) {
1366 wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND);
1367 wpabuf_put_u8(mb_ies, info->ies[i].ie_len);
1368 wpabuf_put_data(mb_ies,
1369 info->ies[i].ie,
1370 info->ies[i].ie_len);
1371 }
1372 }
1373 }
1374
1375 return mb_ies;
1376 }
1377
1378
1379 const struct oper_class_map global_op_class[] = {
1380 { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP },
1381 { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP },
1382
1383 /* Do not enable HT40 on 2.4 GHz for P2P use for now */
1384 { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP },
1385 { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP },
1386
1387 { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP },
1388 { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP },
1389 { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP },
1390 { HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP },
1391 { HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP },
1392 { HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP },
1393 { HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP },
1394 { HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP },
1395 { HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP },
1396 { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
1397 { HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20, P2P_SUPP },
1398 { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS, P2P_SUPP },
1399 { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS, P2P_SUPP },
1400
1401 /*
1402 * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center
1403 * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of
1404 * 80 MHz, but currently use the following definition for simplicity
1405 * (these center frequencies are not actual channels, which makes
1406 * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take
1407 * care of removing invalid channels.
1408 */
1409 { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP },
1410 { HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP },
1411 { HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP },
1412 { HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP },
1413 { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
1414 };
1415
1416
ieee80211_phy_type_by_freq(int freq)1417 static enum phy_type ieee80211_phy_type_by_freq(int freq)
1418 {
1419 enum hostapd_hw_mode hw_mode;
1420 u8 channel;
1421
1422 hw_mode = ieee80211_freq_to_chan(freq, &channel);
1423
1424 switch (hw_mode) {
1425 case HOSTAPD_MODE_IEEE80211A:
1426 return PHY_TYPE_OFDM;
1427 case HOSTAPD_MODE_IEEE80211B:
1428 return PHY_TYPE_HRDSSS;
1429 case HOSTAPD_MODE_IEEE80211G:
1430 return PHY_TYPE_ERP;
1431 case HOSTAPD_MODE_IEEE80211AD:
1432 return PHY_TYPE_DMG;
1433 default:
1434 return PHY_TYPE_UNSPECIFIED;
1435 };
1436 }
1437
1438
1439 /* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */
ieee80211_get_phy_type(int freq,int ht,int vht)1440 enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht)
1441 {
1442 if (vht)
1443 return PHY_TYPE_VHT;
1444 if (ht)
1445 return PHY_TYPE_HT;
1446
1447 return ieee80211_phy_type_by_freq(freq);
1448 }
1449
1450
1451 size_t global_op_class_size = ARRAY_SIZE(global_op_class);
1452
1453
1454 /**
1455 * get_ie - Fetch a specified information element from IEs buffer
1456 * @ies: Information elements buffer
1457 * @len: Information elements buffer length
1458 * @eid: Information element identifier (WLAN_EID_*)
1459 * Returns: Pointer to the information element (id field) or %NULL if not found
1460 *
1461 * This function returns the first matching information element in the IEs
1462 * buffer or %NULL in case the element is not found.
1463 */
get_ie(const u8 * ies,size_t len,u8 eid)1464 const u8 * get_ie(const u8 *ies, size_t len, u8 eid)
1465 {
1466 const struct element *elem;
1467
1468 if (!ies)
1469 return NULL;
1470
1471 for_each_element_id(elem, eid, ies, len)
1472 return &elem->id;
1473
1474 return NULL;
1475 }
1476
1477
1478 /**
1479 * get_ie_ext - Fetch a specified extended information element from IEs buffer
1480 * @ies: Information elements buffer
1481 * @len: Information elements buffer length
1482 * @ext: Information element extension identifier (WLAN_EID_EXT_*)
1483 * Returns: Pointer to the information element (id field) or %NULL if not found
1484 *
1485 * This function returns the first matching information element in the IEs
1486 * buffer or %NULL in case the element is not found.
1487 */
get_ie_ext(const u8 * ies,size_t len,u8 ext)1488 const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext)
1489 {
1490 const struct element *elem;
1491
1492 if (!ies)
1493 return NULL;
1494
1495 for_each_element_extid(elem, ext, ies, len)
1496 return &elem->id;
1497
1498 return NULL;
1499 }
1500
1501
get_vendor_ie(const u8 * ies,size_t len,u32 vendor_type)1502 const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type)
1503 {
1504 const struct element *elem;
1505
1506 for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, len) {
1507 if (elem->datalen >= 4 &&
1508 vendor_type == WPA_GET_BE32(elem->data))
1509 return &elem->id;
1510 }
1511
1512 return NULL;
1513 }
1514
1515
mbo_add_ie(u8 * buf,size_t len,const u8 * attr,size_t attr_len)1516 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
1517 {
1518 /*
1519 * MBO IE requires 6 bytes without the attributes: EID (1), length (1),
1520 * OUI (3), OUI type (1).
1521 */
1522 if (len < 6 + attr_len) {
1523 wpa_printf(MSG_DEBUG,
1524 "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu",
1525 len, attr_len);
1526 return 0;
1527 }
1528
1529 *buf++ = WLAN_EID_VENDOR_SPECIFIC;
1530 *buf++ = attr_len + 4;
1531 WPA_PUT_BE24(buf, OUI_WFA);
1532 buf += 3;
1533 *buf++ = MBO_OUI_TYPE;
1534 os_memcpy(buf, attr, attr_len);
1535
1536 return 6 + attr_len;
1537 }
1538
1539
add_multi_ap_ie(u8 * buf,size_t len,u8 value)1540 size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value)
1541 {
1542 u8 *pos = buf;
1543
1544 if (len < 9)
1545 return 0;
1546
1547 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
1548 *pos++ = 7; /* len */
1549 WPA_PUT_BE24(pos, OUI_WFA);
1550 pos += 3;
1551 *pos++ = MULTI_AP_OUI_TYPE;
1552 *pos++ = MULTI_AP_SUB_ELEM_TYPE;
1553 *pos++ = 1; /* len */
1554 *pos++ = value;
1555
1556 return pos - buf;
1557 }
1558
1559
1560 static const struct country_op_class us_op_class[] = {
1561 { 1, 115 },
1562 { 2, 118 },
1563 { 3, 124 },
1564 { 4, 121 },
1565 { 5, 125 },
1566 { 12, 81 },
1567 { 22, 116 },
1568 { 23, 119 },
1569 { 24, 122 },
1570 { 25, 126 },
1571 { 26, 126 },
1572 { 27, 117 },
1573 { 28, 120 },
1574 { 29, 123 },
1575 { 30, 127 },
1576 { 31, 127 },
1577 { 32, 83 },
1578 { 33, 84 },
1579 { 34, 180 },
1580 };
1581
1582 static const struct country_op_class eu_op_class[] = {
1583 { 1, 115 },
1584 { 2, 118 },
1585 { 3, 121 },
1586 { 4, 81 },
1587 { 5, 116 },
1588 { 6, 119 },
1589 { 7, 122 },
1590 { 8, 117 },
1591 { 9, 120 },
1592 { 10, 123 },
1593 { 11, 83 },
1594 { 12, 84 },
1595 { 17, 125 },
1596 { 18, 180 },
1597 };
1598
1599 static const struct country_op_class jp_op_class[] = {
1600 { 1, 115 },
1601 { 30, 81 },
1602 { 31, 82 },
1603 { 32, 118 },
1604 { 33, 118 },
1605 { 34, 121 },
1606 { 35, 121 },
1607 { 36, 116 },
1608 { 37, 119 },
1609 { 38, 119 },
1610 { 39, 122 },
1611 { 40, 122 },
1612 { 41, 117 },
1613 { 42, 120 },
1614 { 43, 120 },
1615 { 44, 123 },
1616 { 45, 123 },
1617 { 56, 83 },
1618 { 57, 84 },
1619 { 58, 121 },
1620 { 59, 180 },
1621 };
1622
1623 static const struct country_op_class cn_op_class[] = {
1624 { 1, 115 },
1625 { 2, 118 },
1626 { 3, 125 },
1627 { 4, 116 },
1628 { 5, 119 },
1629 { 6, 126 },
1630 { 7, 81 },
1631 { 8, 83 },
1632 { 9, 84 },
1633 };
1634
1635 static u8
global_op_class_from_country_array(u8 op_class,size_t array_size,const struct country_op_class * country_array)1636 global_op_class_from_country_array(u8 op_class, size_t array_size,
1637 const struct country_op_class *country_array)
1638 {
1639 size_t i;
1640
1641 for (i = 0; i < array_size; i++) {
1642 if (country_array[i].country_op_class == op_class)
1643 return country_array[i].global_op_class;
1644 }
1645
1646 return 0;
1647 }
1648
1649
country_to_global_op_class(const char * country,u8 op_class)1650 u8 country_to_global_op_class(const char *country, u8 op_class)
1651 {
1652 const struct country_op_class *country_array;
1653 size_t size;
1654 u8 g_op_class;
1655
1656 if (country_match(us_op_class_cc, country)) {
1657 country_array = us_op_class;
1658 size = ARRAY_SIZE(us_op_class);
1659 } else if (country_match(eu_op_class_cc, country)) {
1660 country_array = eu_op_class;
1661 size = ARRAY_SIZE(eu_op_class);
1662 } else if (country_match(jp_op_class_cc, country)) {
1663 country_array = jp_op_class;
1664 size = ARRAY_SIZE(jp_op_class);
1665 } else if (country_match(cn_op_class_cc, country)) {
1666 country_array = cn_op_class;
1667 size = ARRAY_SIZE(cn_op_class);
1668 } else {
1669 /*
1670 * Countries that do not match any of the above countries use
1671 * global operating classes
1672 */
1673 return op_class;
1674 }
1675
1676 g_op_class = global_op_class_from_country_array(op_class, size,
1677 country_array);
1678
1679 /*
1680 * If the given operating class did not match any of the country's
1681 * operating classes, assume that global operating class is used.
1682 */
1683 return g_op_class ? g_op_class : op_class;
1684 }
1685
1686
get_oper_class(const char * country,u8 op_class)1687 const struct oper_class_map * get_oper_class(const char *country, u8 op_class)
1688 {
1689 const struct oper_class_map *op;
1690
1691 if (country)
1692 op_class = country_to_global_op_class(country, op_class);
1693
1694 op = &global_op_class[0];
1695 while (op->op_class && op->op_class != op_class)
1696 op++;
1697
1698 if (!op->op_class)
1699 return NULL;
1700
1701 return op;
1702 }
1703
1704
oper_class_bw_to_int(const struct oper_class_map * map)1705 int oper_class_bw_to_int(const struct oper_class_map *map)
1706 {
1707 switch (map->bw) {
1708 case BW20:
1709 return 20;
1710 case BW40PLUS:
1711 case BW40MINUS:
1712 return 40;
1713 case BW80:
1714 return 80;
1715 case BW80P80:
1716 case BW160:
1717 return 160;
1718 case BW2160:
1719 return 2160;
1720 default:
1721 return 0;
1722 }
1723 }
1724
1725
ieee802_11_parse_candidate_list(const char * pos,u8 * nei_rep,size_t nei_rep_len)1726 int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
1727 size_t nei_rep_len)
1728 {
1729 u8 *nei_pos = nei_rep;
1730 const char *end;
1731
1732 /*
1733 * BSS Transition Candidate List Entries - Neighbor Report elements
1734 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
1735 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
1736 */
1737 while (pos) {
1738 u8 *nei_start;
1739 long int val;
1740 char *endptr, *tmp;
1741
1742 pos = os_strstr(pos, " neighbor=");
1743 if (!pos)
1744 break;
1745 if (nei_pos + 15 > nei_rep + nei_rep_len) {
1746 wpa_printf(MSG_DEBUG,
1747 "Not enough room for additional neighbor");
1748 return -1;
1749 }
1750 pos += 10;
1751
1752 nei_start = nei_pos;
1753 *nei_pos++ = WLAN_EID_NEIGHBOR_REPORT;
1754 nei_pos++; /* length to be filled in */
1755
1756 if (hwaddr_aton(pos, nei_pos)) {
1757 wpa_printf(MSG_DEBUG, "Invalid BSSID");
1758 return -1;
1759 }
1760 nei_pos += ETH_ALEN;
1761 pos += 17;
1762 if (*pos != ',') {
1763 wpa_printf(MSG_DEBUG, "Missing BSSID Information");
1764 return -1;
1765 }
1766 pos++;
1767
1768 val = strtol(pos, &endptr, 0);
1769 WPA_PUT_LE32(nei_pos, val);
1770 nei_pos += 4;
1771 if (*endptr != ',') {
1772 wpa_printf(MSG_DEBUG, "Missing Operating Class");
1773 return -1;
1774 }
1775 pos = endptr + 1;
1776
1777 *nei_pos++ = atoi(pos); /* Operating Class */
1778 pos = os_strchr(pos, ',');
1779 if (pos == NULL) {
1780 wpa_printf(MSG_DEBUG, "Missing Channel Number");
1781 return -1;
1782 }
1783 pos++;
1784
1785 *nei_pos++ = atoi(pos); /* Channel Number */
1786 pos = os_strchr(pos, ',');
1787 if (pos == NULL) {
1788 wpa_printf(MSG_DEBUG, "Missing PHY Type");
1789 return -1;
1790 }
1791 pos++;
1792
1793 *nei_pos++ = atoi(pos); /* PHY Type */
1794 end = os_strchr(pos, ' ');
1795 tmp = os_strchr(pos, ',');
1796 if (tmp && (!end || tmp < end)) {
1797 /* Optional Subelements (hexdump) */
1798 size_t len;
1799
1800 pos = tmp + 1;
1801 end = os_strchr(pos, ' ');
1802 if (end)
1803 len = end - pos;
1804 else
1805 len = os_strlen(pos);
1806 if (nei_pos + len / 2 > nei_rep + nei_rep_len) {
1807 wpa_printf(MSG_DEBUG,
1808 "Not enough room for neighbor subelements");
1809 return -1;
1810 }
1811 if (len & 0x01 ||
1812 hexstr2bin(pos, nei_pos, len / 2) < 0) {
1813 wpa_printf(MSG_DEBUG,
1814 "Invalid neighbor subelement info");
1815 return -1;
1816 }
1817 nei_pos += len / 2;
1818 pos = end;
1819 }
1820
1821 nei_start[1] = nei_pos - nei_start - 2;
1822 }
1823
1824 return nei_pos - nei_rep;
1825 }
1826
1827
ieee802_11_ext_capab(const u8 * ie,unsigned int capab)1828 int ieee802_11_ext_capab(const u8 *ie, unsigned int capab)
1829 {
1830 if (!ie || ie[1] <= capab / 8)
1831 return 0;
1832 return !!(ie[2 + capab / 8] & BIT(capab % 8));
1833 }
1834