1 /*
2 * IEEE 802.11 Common routines
3 * Copyright (c) 2002-2015, 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 "qca-vendor.h"
15 #include "ieee802_11_defs.h"
16 #include "ieee802_11_common.h"
17
18
ieee802_11_parse_vendor_specific(const u8 * pos,size_t elen,struct ieee802_11_elems * elems,int show_errors)19 static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
20 struct ieee802_11_elems *elems,
21 int show_errors)
22 {
23 unsigned int oui;
24
25 /* first 3 bytes in vendor specific information element are the IEEE
26 * OUI of the vendor. The following byte is used a vendor specific
27 * sub-type. */
28 if (elen < 4) {
29 if (show_errors) {
30 wpa_printf(MSG_MSGDUMP, "short vendor specific "
31 "information element ignored (len=%lu)",
32 (unsigned long) elen);
33 }
34 return -1;
35 }
36
37 oui = WPA_GET_BE24(pos);
38 switch (oui) {
39 case OUI_MICROSOFT:
40 /* Microsoft/Wi-Fi information elements are further typed and
41 * subtyped */
42 switch (pos[3]) {
43 case 1:
44 /* Microsoft OUI (00:50:F2) with OUI Type 1:
45 * real WPA information element */
46 elems->wpa_ie = pos;
47 elems->wpa_ie_len = elen;
48 break;
49 case WMM_OUI_TYPE:
50 /* WMM information element */
51 if (elen < 5) {
52 wpa_printf(MSG_MSGDUMP, "short WMM "
53 "information element ignored "
54 "(len=%lu)",
55 (unsigned long) elen);
56 return -1;
57 }
58 switch (pos[4]) {
59 case WMM_OUI_SUBTYPE_INFORMATION_ELEMENT:
60 case WMM_OUI_SUBTYPE_PARAMETER_ELEMENT:
61 /*
62 * Share same pointer since only one of these
63 * is used and they start with same data.
64 * Length field can be used to distinguish the
65 * IEs.
66 */
67 elems->wmm = pos;
68 elems->wmm_len = elen;
69 break;
70 case WMM_OUI_SUBTYPE_TSPEC_ELEMENT:
71 elems->wmm_tspec = pos;
72 elems->wmm_tspec_len = elen;
73 break;
74 default:
75 wpa_printf(MSG_EXCESSIVE, "unknown WMM "
76 "information element ignored "
77 "(subtype=%d len=%lu)",
78 pos[4], (unsigned long) elen);
79 return -1;
80 }
81 break;
82 case 4:
83 /* Wi-Fi Protected Setup (WPS) IE */
84 elems->wps_ie = pos;
85 elems->wps_ie_len = elen;
86 break;
87 default:
88 wpa_printf(MSG_EXCESSIVE, "Unknown Microsoft "
89 "information element ignored "
90 "(type=%d len=%lu)",
91 pos[3], (unsigned long) elen);
92 return -1;
93 }
94 break;
95
96 case OUI_WFA:
97 switch (pos[3]) {
98 case P2P_OUI_TYPE:
99 /* Wi-Fi Alliance - P2P IE */
100 elems->p2p = pos;
101 elems->p2p_len = elen;
102 break;
103 case WFD_OUI_TYPE:
104 /* Wi-Fi Alliance - WFD IE */
105 elems->wfd = pos;
106 elems->wfd_len = elen;
107 break;
108 case HS20_INDICATION_OUI_TYPE:
109 /* Hotspot 2.0 */
110 elems->hs20 = pos;
111 elems->hs20_len = elen;
112 break;
113 case HS20_OSEN_OUI_TYPE:
114 /* Hotspot 2.0 OSEN */
115 elems->osen = pos;
116 elems->osen_len = elen;
117 break;
118 case MBO_OUI_TYPE:
119 /* MBO-OCE */
120 elems->mbo = pos;
121 elems->mbo_len = elen;
122 break;
123 default:
124 wpa_printf(MSG_MSGDUMP, "Unknown WFA "
125 "information element ignored "
126 "(type=%d len=%lu)",
127 pos[3], (unsigned long) elen);
128 return -1;
129 }
130 break;
131
132 case OUI_BROADCOM:
133 switch (pos[3]) {
134 case VENDOR_HT_CAPAB_OUI_TYPE:
135 elems->vendor_ht_cap = pos;
136 elems->vendor_ht_cap_len = elen;
137 break;
138 case VENDOR_VHT_TYPE:
139 if (elen > 4 &&
140 (pos[4] == VENDOR_VHT_SUBTYPE ||
141 pos[4] == VENDOR_VHT_SUBTYPE2)) {
142 elems->vendor_vht = pos;
143 elems->vendor_vht_len = elen;
144 } else
145 return -1;
146 break;
147 default:
148 wpa_printf(MSG_EXCESSIVE, "Unknown Broadcom "
149 "information element ignored "
150 "(type=%d len=%lu)",
151 pos[3], (unsigned long) elen);
152 return -1;
153 }
154 break;
155
156 case OUI_QCA:
157 switch (pos[3]) {
158 case QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST:
159 elems->pref_freq_list = pos;
160 elems->pref_freq_list_len = elen;
161 break;
162 default:
163 wpa_printf(MSG_EXCESSIVE,
164 "Unknown QCA information element ignored (type=%d len=%lu)",
165 pos[3], (unsigned long) elen);
166 return -1;
167 }
168 break;
169
170 default:
171 wpa_printf(MSG_EXCESSIVE, "unknown vendor specific "
172 "information element ignored (vendor OUI "
173 "%02x:%02x:%02x len=%lu)",
174 pos[0], pos[1], pos[2], (unsigned long) elen);
175 return -1;
176 }
177
178 return 0;
179 }
180
181
ieee802_11_parse_extension(const u8 * pos,size_t elen,struct ieee802_11_elems * elems,int show_errors)182 static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
183 struct ieee802_11_elems *elems,
184 int show_errors)
185 {
186 u8 ext_id;
187
188 if (elen < 1) {
189 if (show_errors) {
190 wpa_printf(MSG_MSGDUMP,
191 "short information element (Ext)");
192 }
193 return -1;
194 }
195
196 ext_id = *pos++;
197 elen--;
198
199 switch (ext_id) {
200 case WLAN_EID_EXT_ASSOC_DELAY_INFO:
201 if (elen != 1)
202 break;
203 elems->assoc_delay_info = pos;
204 break;
205 case WLAN_EID_EXT_FILS_REQ_PARAMS:
206 if (elen < 3)
207 break;
208 elems->fils_req_params = pos;
209 elems->fils_req_params_len = elen;
210 break;
211 case WLAN_EID_EXT_FILS_KEY_CONFIRM:
212 elems->fils_key_confirm = pos;
213 elems->fils_key_confirm_len = elen;
214 break;
215 case WLAN_EID_EXT_FILS_SESSION:
216 if (elen != FILS_SESSION_LEN)
217 break;
218 elems->fils_session = pos;
219 break;
220 case WLAN_EID_EXT_FILS_HLP_CONTAINER:
221 if (elen < 2 * ETH_ALEN)
222 break;
223 elems->fils_hlp = pos;
224 elems->fils_hlp_len = elen;
225 break;
226 case WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN:
227 if (elen < 1)
228 break;
229 elems->fils_ip_addr_assign = pos;
230 elems->fils_ip_addr_assign_len = elen;
231 break;
232 case WLAN_EID_EXT_KEY_DELIVERY:
233 if (elen < WPA_KEY_RSC_LEN)
234 break;
235 elems->key_delivery = pos;
236 elems->key_delivery_len = elen;
237 break;
238 case WLAN_EID_EXT_FILS_WRAPPED_DATA:
239 elems->fils_wrapped_data = pos;
240 elems->fils_wrapped_data_len = elen;
241 break;
242 case WLAN_EID_EXT_FILS_PUBLIC_KEY:
243 if (elen < 1)
244 break;
245 elems->fils_pk = pos;
246 elems->fils_pk_len = elen;
247 break;
248 case WLAN_EID_EXT_FILS_NONCE:
249 if (elen != FILS_NONCE_LEN)
250 break;
251 elems->fils_nonce = pos;
252 break;
253 default:
254 if (show_errors) {
255 wpa_printf(MSG_MSGDUMP,
256 "IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)",
257 ext_id, (unsigned int) elen);
258 }
259 return -1;
260 }
261
262 return 0;
263 }
264
265
266 /**
267 * ieee802_11_parse_elems - Parse information elements in management frames
268 * @start: Pointer to the start of IEs
269 * @len: Length of IE buffer in octets
270 * @elems: Data structure for parsed elements
271 * @show_errors: Whether to show parsing errors in debug log
272 * Returns: Parsing result
273 */
ieee802_11_parse_elems(const u8 * start,size_t len,struct ieee802_11_elems * elems,int show_errors)274 ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
275 struct ieee802_11_elems *elems,
276 int show_errors)
277 {
278 size_t left = len;
279 const u8 *pos = start;
280 int unknown = 0;
281
282 os_memset(elems, 0, sizeof(*elems));
283
284 while (left >= 2) {
285 u8 id, elen;
286
287 id = *pos++;
288 elen = *pos++;
289 left -= 2;
290
291 if (elen > left) {
292 if (show_errors) {
293 wpa_printf(MSG_DEBUG, "IEEE 802.11 element "
294 "parse failed (id=%d elen=%d "
295 "left=%lu)",
296 id, elen, (unsigned long) left);
297 wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
298 }
299 return ParseFailed;
300 }
301
302 switch (id) {
303 case WLAN_EID_SSID:
304 if (elen > SSID_MAX_LEN) {
305 wpa_printf(MSG_DEBUG,
306 "Ignored too long SSID element (elen=%u)",
307 elen);
308 break;
309 }
310 elems->ssid = pos;
311 elems->ssid_len = elen;
312 break;
313 case WLAN_EID_SUPP_RATES:
314 elems->supp_rates = pos;
315 elems->supp_rates_len = elen;
316 break;
317 case WLAN_EID_DS_PARAMS:
318 if (elen < 1)
319 break;
320 elems->ds_params = pos;
321 break;
322 case WLAN_EID_CF_PARAMS:
323 case WLAN_EID_TIM:
324 break;
325 case WLAN_EID_CHALLENGE:
326 elems->challenge = pos;
327 elems->challenge_len = elen;
328 break;
329 case WLAN_EID_ERP_INFO:
330 if (elen < 1)
331 break;
332 elems->erp_info = pos;
333 break;
334 case WLAN_EID_EXT_SUPP_RATES:
335 elems->ext_supp_rates = pos;
336 elems->ext_supp_rates_len = elen;
337 break;
338 case WLAN_EID_VENDOR_SPECIFIC:
339 if (ieee802_11_parse_vendor_specific(pos, elen,
340 elems,
341 show_errors))
342 unknown++;
343 break;
344 case WLAN_EID_RSN:
345 elems->rsn_ie = pos;
346 elems->rsn_ie_len = elen;
347 break;
348 case WLAN_EID_PWR_CAPABILITY:
349 break;
350 case WLAN_EID_SUPPORTED_CHANNELS:
351 elems->supp_channels = pos;
352 elems->supp_channels_len = elen;
353 break;
354 case WLAN_EID_MOBILITY_DOMAIN:
355 if (elen < sizeof(struct rsn_mdie))
356 break;
357 elems->mdie = pos;
358 elems->mdie_len = elen;
359 break;
360 case WLAN_EID_FAST_BSS_TRANSITION:
361 if (elen < sizeof(struct rsn_ftie))
362 break;
363 elems->ftie = pos;
364 elems->ftie_len = elen;
365 break;
366 case WLAN_EID_TIMEOUT_INTERVAL:
367 if (elen != 5)
368 break;
369 elems->timeout_int = pos;
370 break;
371 case WLAN_EID_HT_CAP:
372 if (elen < sizeof(struct ieee80211_ht_capabilities))
373 break;
374 elems->ht_capabilities = pos;
375 break;
376 case WLAN_EID_HT_OPERATION:
377 if (elen < sizeof(struct ieee80211_ht_operation))
378 break;
379 elems->ht_operation = pos;
380 break;
381 case WLAN_EID_MESH_CONFIG:
382 elems->mesh_config = pos;
383 elems->mesh_config_len = elen;
384 break;
385 case WLAN_EID_MESH_ID:
386 elems->mesh_id = pos;
387 elems->mesh_id_len = elen;
388 break;
389 case WLAN_EID_PEER_MGMT:
390 elems->peer_mgmt = pos;
391 elems->peer_mgmt_len = elen;
392 break;
393 case WLAN_EID_VHT_CAP:
394 if (elen < sizeof(struct ieee80211_vht_capabilities))
395 break;
396 elems->vht_capabilities = pos;
397 break;
398 case WLAN_EID_VHT_OPERATION:
399 if (elen < sizeof(struct ieee80211_vht_operation))
400 break;
401 elems->vht_operation = pos;
402 break;
403 case WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION:
404 if (elen != 1)
405 break;
406 elems->vht_opmode_notif = pos;
407 break;
408 case WLAN_EID_LINK_ID:
409 if (elen < 18)
410 break;
411 elems->link_id = pos;
412 break;
413 case WLAN_EID_INTERWORKING:
414 elems->interworking = pos;
415 elems->interworking_len = elen;
416 break;
417 case WLAN_EID_QOS_MAP_SET:
418 if (elen < 16)
419 break;
420 elems->qos_map_set = pos;
421 elems->qos_map_set_len = elen;
422 break;
423 case WLAN_EID_EXT_CAPAB:
424 elems->ext_capab = pos;
425 elems->ext_capab_len = elen;
426 break;
427 case WLAN_EID_BSS_MAX_IDLE_PERIOD:
428 if (elen < 3)
429 break;
430 elems->bss_max_idle_period = pos;
431 break;
432 case WLAN_EID_SSID_LIST:
433 elems->ssid_list = pos;
434 elems->ssid_list_len = elen;
435 break;
436 case WLAN_EID_AMPE:
437 elems->ampe = pos;
438 elems->ampe_len = elen;
439 break;
440 case WLAN_EID_MIC:
441 elems->mic = pos;
442 elems->mic_len = elen;
443 /* after mic everything is encrypted, so stop. */
444 left = elen;
445 break;
446 case WLAN_EID_MULTI_BAND:
447 if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) {
448 wpa_printf(MSG_MSGDUMP,
449 "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)",
450 id, elen);
451 break;
452 }
453
454 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos;
455 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen;
456 elems->mb_ies.nof_ies++;
457 break;
458 case WLAN_EID_SUPPORTED_OPERATING_CLASSES:
459 elems->supp_op_classes = pos;
460 elems->supp_op_classes_len = elen;
461 break;
462 case WLAN_EID_RRM_ENABLED_CAPABILITIES:
463 elems->rrm_enabled = pos;
464 elems->rrm_enabled_len = elen;
465 break;
466 case WLAN_EID_CAG_NUMBER:
467 elems->cag_number = pos;
468 elems->cag_number_len = elen;
469 break;
470 case WLAN_EID_AP_CSN:
471 if (elen < 1)
472 break;
473 elems->ap_csn = pos;
474 break;
475 case WLAN_EID_FILS_INDICATION:
476 if (elen < 2)
477 break;
478 elems->fils_indic = pos;
479 elems->fils_indic_len = elen;
480 break;
481 case WLAN_EID_DILS:
482 if (elen < 2)
483 break;
484 elems->dils = pos;
485 elems->dils_len = elen;
486 break;
487 case WLAN_EID_FRAGMENT:
488 /* TODO */
489 break;
490 case WLAN_EID_EXTENSION:
491 if (ieee802_11_parse_extension(pos, elen, elems,
492 show_errors))
493 unknown++;
494 break;
495 default:
496 unknown++;
497 if (!show_errors)
498 break;
499 wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse "
500 "ignored unknown element (id=%d elen=%d)",
501 id, elen);
502 break;
503 }
504
505 left -= elen;
506 pos += elen;
507 }
508
509 if (left)
510 return ParseFailed;
511
512 return unknown ? ParseUnknown : ParseOK;
513 }
514
515
ieee802_11_ie_count(const u8 * ies,size_t ies_len)516 int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
517 {
518 int count = 0;
519 const u8 *pos, *end;
520
521 if (ies == NULL)
522 return 0;
523
524 pos = ies;
525 end = ies + ies_len;
526
527 while (end - pos >= 2) {
528 if (2 + pos[1] > end - pos)
529 break;
530 count++;
531 pos += 2 + pos[1];
532 }
533
534 return count;
535 }
536
537
ieee802_11_vendor_ie_concat(const u8 * ies,size_t ies_len,u32 oui_type)538 struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
539 u32 oui_type)
540 {
541 struct wpabuf *buf;
542 const u8 *end, *pos, *ie;
543
544 pos = ies;
545 end = ies + ies_len;
546 ie = NULL;
547
548 while (end - pos > 1) {
549 if (2 + pos[1] > end - pos)
550 return NULL;
551 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
552 WPA_GET_BE32(&pos[2]) == oui_type) {
553 ie = pos;
554 break;
555 }
556 pos += 2 + pos[1];
557 }
558
559 if (ie == NULL)
560 return NULL; /* No specified vendor IE found */
561
562 buf = wpabuf_alloc(ies_len);
563 if (buf == NULL)
564 return NULL;
565
566 /*
567 * There may be multiple vendor IEs in the message, so need to
568 * concatenate their data fields.
569 */
570 while (end - pos > 1) {
571 if (2 + pos[1] > end - pos)
572 break;
573 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
574 WPA_GET_BE32(&pos[2]) == oui_type)
575 wpabuf_put_data(buf, pos + 6, pos[1] - 4);
576 pos += 2 + pos[1];
577 }
578
579 return buf;
580 }
581
582
get_hdr_bssid(const struct ieee80211_hdr * hdr,size_t len)583 const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
584 {
585 u16 fc, type, stype;
586
587 /*
588 * PS-Poll frames are 16 bytes. All other frames are
589 * 24 bytes or longer.
590 */
591 if (len < 16)
592 return NULL;
593
594 fc = le_to_host16(hdr->frame_control);
595 type = WLAN_FC_GET_TYPE(fc);
596 stype = WLAN_FC_GET_STYPE(fc);
597
598 switch (type) {
599 case WLAN_FC_TYPE_DATA:
600 if (len < 24)
601 return NULL;
602 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
603 case WLAN_FC_FROMDS | WLAN_FC_TODS:
604 case WLAN_FC_TODS:
605 return hdr->addr1;
606 case WLAN_FC_FROMDS:
607 return hdr->addr2;
608 default:
609 return NULL;
610 }
611 case WLAN_FC_TYPE_CTRL:
612 if (stype != WLAN_FC_STYPE_PSPOLL)
613 return NULL;
614 return hdr->addr1;
615 case WLAN_FC_TYPE_MGMT:
616 return hdr->addr3;
617 default:
618 return NULL;
619 }
620 }
621
622
hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],const char * name,const char * val)623 int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
624 const char *name, const char *val)
625 {
626 int num, v;
627 const char *pos;
628 struct hostapd_wmm_ac_params *ac;
629
630 /* skip 'wme_ac_' or 'wmm_ac_' prefix */
631 pos = name + 7;
632 if (os_strncmp(pos, "be_", 3) == 0) {
633 num = 0;
634 pos += 3;
635 } else if (os_strncmp(pos, "bk_", 3) == 0) {
636 num = 1;
637 pos += 3;
638 } else if (os_strncmp(pos, "vi_", 3) == 0) {
639 num = 2;
640 pos += 3;
641 } else if (os_strncmp(pos, "vo_", 3) == 0) {
642 num = 3;
643 pos += 3;
644 } else {
645 wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos);
646 return -1;
647 }
648
649 ac = &wmm_ac_params[num];
650
651 if (os_strcmp(pos, "aifs") == 0) {
652 v = atoi(val);
653 if (v < 1 || v > 255) {
654 wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v);
655 return -1;
656 }
657 ac->aifs = v;
658 } else if (os_strcmp(pos, "cwmin") == 0) {
659 v = atoi(val);
660 if (v < 0 || v > 15) {
661 wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v);
662 return -1;
663 }
664 ac->cwmin = v;
665 } else if (os_strcmp(pos, "cwmax") == 0) {
666 v = atoi(val);
667 if (v < 0 || v > 15) {
668 wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v);
669 return -1;
670 }
671 ac->cwmax = v;
672 } else if (os_strcmp(pos, "txop_limit") == 0) {
673 v = atoi(val);
674 if (v < 0 || v > 0xffff) {
675 wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
676 return -1;
677 }
678 ac->txop_limit = v;
679 } else if (os_strcmp(pos, "acm") == 0) {
680 v = atoi(val);
681 if (v < 0 || v > 1) {
682 wpa_printf(MSG_ERROR, "Invalid acm value %d", v);
683 return -1;
684 }
685 ac->admission_control_mandatory = v;
686 } else {
687 wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos);
688 return -1;
689 }
690
691 return 0;
692 }
693
694
ieee80211_freq_to_chan(int freq,u8 * channel)695 enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel)
696 {
697 u8 op_class;
698
699 return ieee80211_freq_to_channel_ext(freq, 0, VHT_CHANWIDTH_USE_HT,
700 &op_class, channel);
701 }
702
703
704 /**
705 * ieee80211_freq_to_channel_ext - Convert frequency into channel info
706 * for HT40 and VHT. DFS channels are not covered.
707 * @freq: Frequency (MHz) to convert
708 * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
709 * @vht: VHT channel width (VHT_CHANWIDTH_*)
710 * @op_class: Buffer for returning operating class
711 * @channel: Buffer for returning channel number
712 * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
713 */
ieee80211_freq_to_channel_ext(unsigned int freq,int sec_channel,int vht,u8 * op_class,u8 * channel)714 enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
715 int sec_channel, int vht,
716 u8 *op_class, u8 *channel)
717 {
718 u8 vht_opclass;
719
720 /* TODO: more operating classes */
721
722 if (sec_channel > 1 || sec_channel < -1)
723 return NUM_HOSTAPD_MODES;
724
725 if (freq >= 2412 && freq <= 2472) {
726 if ((freq - 2407) % 5)
727 return NUM_HOSTAPD_MODES;
728
729 if (vht)
730 return NUM_HOSTAPD_MODES;
731
732 /* 2.407 GHz, channels 1..13 */
733 if (sec_channel == 1)
734 *op_class = 83;
735 else if (sec_channel == -1)
736 *op_class = 84;
737 else
738 *op_class = 81;
739
740 *channel = (freq - 2407) / 5;
741
742 return HOSTAPD_MODE_IEEE80211G;
743 }
744
745 if (freq == 2484) {
746 if (sec_channel || vht)
747 return NUM_HOSTAPD_MODES;
748
749 *op_class = 82; /* channel 14 */
750 *channel = 14;
751
752 return HOSTAPD_MODE_IEEE80211B;
753 }
754
755 if (freq >= 4900 && freq < 5000) {
756 if ((freq - 4000) % 5)
757 return NUM_HOSTAPD_MODES;
758 *channel = (freq - 4000) / 5;
759 *op_class = 0; /* TODO */
760 return HOSTAPD_MODE_IEEE80211A;
761 }
762
763 switch (vht) {
764 case VHT_CHANWIDTH_80MHZ:
765 vht_opclass = 128;
766 break;
767 case VHT_CHANWIDTH_160MHZ:
768 vht_opclass = 129;
769 break;
770 case VHT_CHANWIDTH_80P80MHZ:
771 vht_opclass = 130;
772 break;
773 default:
774 vht_opclass = 0;
775 break;
776 }
777
778 /* 5 GHz, channels 36..48 */
779 if (freq >= 5180 && freq <= 5240) {
780 if ((freq - 5000) % 5)
781 return NUM_HOSTAPD_MODES;
782
783 if (vht_opclass)
784 *op_class = vht_opclass;
785 else if (sec_channel == 1)
786 *op_class = 116;
787 else if (sec_channel == -1)
788 *op_class = 117;
789 else
790 *op_class = 115;
791
792 *channel = (freq - 5000) / 5;
793
794 return HOSTAPD_MODE_IEEE80211A;
795 }
796
797 /* 5 GHz, channels 52..64 */
798 if (freq >= 5260 && freq <= 5320) {
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 = 119;
806 else if (sec_channel == -1)
807 *op_class = 120;
808 else
809 *op_class = 118;
810
811 *channel = (freq - 5000) / 5;
812
813 return HOSTAPD_MODE_IEEE80211A;
814 }
815
816 /* 5 GHz, channels 149..169 */
817 if (freq >= 5745 && freq <= 5845) {
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 = 126;
825 else if (sec_channel == -1)
826 *op_class = 127;
827 else if (freq <= 5805)
828 *op_class = 124;
829 else
830 *op_class = 125;
831
832 *channel = (freq - 5000) / 5;
833
834 return HOSTAPD_MODE_IEEE80211A;
835 }
836
837 /* 5 GHz, channels 100..140 */
838 if (freq >= 5000 && freq <= 5700) {
839 if ((freq - 5000) % 5)
840 return NUM_HOSTAPD_MODES;
841
842 if (vht_opclass)
843 *op_class = vht_opclass;
844 else if (sec_channel == 1)
845 *op_class = 122;
846 else if (sec_channel == -1)
847 *op_class = 123;
848 else
849 *op_class = 121;
850
851 *channel = (freq - 5000) / 5;
852
853 return HOSTAPD_MODE_IEEE80211A;
854 }
855
856 if (freq >= 5000 && freq < 5900) {
857 if ((freq - 5000) % 5)
858 return NUM_HOSTAPD_MODES;
859 *channel = (freq - 5000) / 5;
860 *op_class = 0; /* TODO */
861 return HOSTAPD_MODE_IEEE80211A;
862 }
863
864 /* 56.16 GHz, channel 1..4 */
865 if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) {
866 if (sec_channel || vht)
867 return NUM_HOSTAPD_MODES;
868
869 *channel = (freq - 56160) / 2160;
870 *op_class = 180;
871
872 return HOSTAPD_MODE_IEEE80211AD;
873 }
874
875 return NUM_HOSTAPD_MODES;
876 }
877
878
879 static const char *const us_op_class_cc[] = {
880 "US", "CA", NULL
881 };
882
883 static const char *const eu_op_class_cc[] = {
884 "AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
885 "DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
886 "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
887 "RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL
888 };
889
890 static const char *const jp_op_class_cc[] = {
891 "JP", NULL
892 };
893
894 static const char *const cn_op_class_cc[] = {
895 "CN", NULL
896 };
897
898
country_match(const char * const cc[],const char * const country)899 static int country_match(const char *const cc[], const char *const country)
900 {
901 int i;
902
903 if (country == NULL)
904 return 0;
905 for (i = 0; cc[i]; i++) {
906 if (cc[i][0] == country[0] && cc[i][1] == country[1])
907 return 1;
908 }
909
910 return 0;
911 }
912
913
ieee80211_chan_to_freq_us(u8 op_class,u8 chan)914 static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan)
915 {
916 switch (op_class) {
917 case 12: /* channels 1..11 */
918 case 32: /* channels 1..7; 40 MHz */
919 case 33: /* channels 5..11; 40 MHz */
920 if (chan < 1 || chan > 11)
921 return -1;
922 return 2407 + 5 * chan;
923 case 1: /* channels 36,40,44,48 */
924 case 2: /* channels 52,56,60,64; dfs */
925 case 22: /* channels 36,44; 40 MHz */
926 case 23: /* channels 52,60; 40 MHz */
927 case 27: /* channels 40,48; 40 MHz */
928 case 28: /* channels 56,64; 40 MHz */
929 if (chan < 36 || chan > 64)
930 return -1;
931 return 5000 + 5 * chan;
932 case 4: /* channels 100-144 */
933 case 24: /* channels 100-140; 40 MHz */
934 if (chan < 100 || chan > 144)
935 return -1;
936 return 5000 + 5 * chan;
937 case 3: /* channels 149,153,157,161 */
938 case 25: /* channels 149,157; 40 MHz */
939 case 26: /* channels 149,157; 40 MHz */
940 case 30: /* channels 153,161; 40 MHz */
941 case 31: /* channels 153,161; 40 MHz */
942 if (chan < 149 || chan > 161)
943 return -1;
944 return 5000 + 5 * chan;
945 case 5: /* channels 149,153,157,161,165 */
946 if (chan < 149 || chan > 165)
947 return -1;
948 return 5000 + 5 * chan;
949 case 34: /* 60 GHz band, channels 1..3 */
950 if (chan < 1 || chan > 3)
951 return -1;
952 return 56160 + 2160 * chan;
953 }
954 return -1;
955 }
956
957
ieee80211_chan_to_freq_eu(u8 op_class,u8 chan)958 static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan)
959 {
960 switch (op_class) {
961 case 4: /* channels 1..13 */
962 case 11: /* channels 1..9; 40 MHz */
963 case 12: /* channels 5..13; 40 MHz */
964 if (chan < 1 || chan > 13)
965 return -1;
966 return 2407 + 5 * chan;
967 case 1: /* channels 36,40,44,48 */
968 case 2: /* channels 52,56,60,64; dfs */
969 case 5: /* channels 36,44; 40 MHz */
970 case 6: /* channels 52,60; 40 MHz */
971 case 8: /* channels 40,48; 40 MHz */
972 case 9: /* channels 56,64; 40 MHz */
973 if (chan < 36 || chan > 64)
974 return -1;
975 return 5000 + 5 * chan;
976 case 3: /* channels 100-140 */
977 case 7: /* channels 100-132; 40 MHz */
978 case 10: /* channels 104-136; 40 MHz */
979 case 16: /* channels 100-140 */
980 if (chan < 100 || chan > 140)
981 return -1;
982 return 5000 + 5 * chan;
983 case 17: /* channels 149,153,157,161,165,169 */
984 if (chan < 149 || chan > 169)
985 return -1;
986 return 5000 + 5 * chan;
987 case 18: /* 60 GHz band, channels 1..4 */
988 if (chan < 1 || chan > 4)
989 return -1;
990 return 56160 + 2160 * chan;
991 }
992 return -1;
993 }
994
995
ieee80211_chan_to_freq_jp(u8 op_class,u8 chan)996 static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan)
997 {
998 switch (op_class) {
999 case 30: /* channels 1..13 */
1000 case 56: /* channels 1..9; 40 MHz */
1001 case 57: /* channels 5..13; 40 MHz */
1002 if (chan < 1 || chan > 13)
1003 return -1;
1004 return 2407 + 5 * chan;
1005 case 31: /* channel 14 */
1006 if (chan != 14)
1007 return -1;
1008 return 2414 + 5 * chan;
1009 case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */
1010 case 32: /* channels 52,56,60,64 */
1011 case 33: /* channels 52,56,60,64 */
1012 case 36: /* channels 36,44; 40 MHz */
1013 case 37: /* channels 52,60; 40 MHz */
1014 case 38: /* channels 52,60; 40 MHz */
1015 case 41: /* channels 40,48; 40 MHz */
1016 case 42: /* channels 56,64; 40 MHz */
1017 case 43: /* channels 56,64; 40 MHz */
1018 if (chan < 34 || chan > 64)
1019 return -1;
1020 return 5000 + 5 * chan;
1021 case 34: /* channels 100-140 */
1022 case 35: /* channels 100-140 */
1023 case 39: /* channels 100-132; 40 MHz */
1024 case 40: /* channels 100-132; 40 MHz */
1025 case 44: /* channels 104-136; 40 MHz */
1026 case 45: /* channels 104-136; 40 MHz */
1027 case 58: /* channels 100-140 */
1028 if (chan < 100 || chan > 140)
1029 return -1;
1030 return 5000 + 5 * chan;
1031 case 59: /* 60 GHz band, channels 1..4 */
1032 if (chan < 1 || chan > 3)
1033 return -1;
1034 return 56160 + 2160 * chan;
1035 }
1036 return -1;
1037 }
1038
1039
ieee80211_chan_to_freq_cn(u8 op_class,u8 chan)1040 static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan)
1041 {
1042 switch (op_class) {
1043 case 7: /* channels 1..13 */
1044 case 8: /* channels 1..9; 40 MHz */
1045 case 9: /* channels 5..13; 40 MHz */
1046 if (chan < 1 || chan > 13)
1047 return -1;
1048 return 2407 + 5 * chan;
1049 case 1: /* channels 36,40,44,48 */
1050 case 2: /* channels 52,56,60,64; dfs */
1051 case 4: /* channels 36,44; 40 MHz */
1052 case 5: /* channels 52,60; 40 MHz */
1053 if (chan < 36 || chan > 64)
1054 return -1;
1055 return 5000 + 5 * chan;
1056 case 3: /* channels 149,153,157,161,165 */
1057 case 6: /* channels 149,157; 40 MHz */
1058 if (chan < 149 || chan > 165)
1059 return -1;
1060 return 5000 + 5 * chan;
1061 }
1062 return -1;
1063 }
1064
1065
ieee80211_chan_to_freq_global(u8 op_class,u8 chan)1066 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
1067 {
1068 /* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
1069 switch (op_class) {
1070 case 81:
1071 /* channels 1..13 */
1072 if (chan < 1 || chan > 13)
1073 return -1;
1074 return 2407 + 5 * chan;
1075 case 82:
1076 /* channel 14 */
1077 if (chan != 14)
1078 return -1;
1079 return 2414 + 5 * chan;
1080 case 83: /* channels 1..9; 40 MHz */
1081 case 84: /* channels 5..13; 40 MHz */
1082 if (chan < 1 || chan > 13)
1083 return -1;
1084 return 2407 + 5 * chan;
1085 case 115: /* channels 36,40,44,48; indoor only */
1086 case 116: /* channels 36,44; 40 MHz; indoor only */
1087 case 117: /* channels 40,48; 40 MHz; indoor only */
1088 case 118: /* channels 52,56,60,64; dfs */
1089 case 119: /* channels 52,60; 40 MHz; dfs */
1090 case 120: /* channels 56,64; 40 MHz; dfs */
1091 if (chan < 36 || chan > 64)
1092 return -1;
1093 return 5000 + 5 * chan;
1094 case 121: /* channels 100-140 */
1095 case 122: /* channels 100-142; 40 MHz */
1096 case 123: /* channels 104-136; 40 MHz */
1097 if (chan < 100 || chan > 140)
1098 return -1;
1099 return 5000 + 5 * chan;
1100 case 124: /* channels 149,153,157,161 */
1101 case 126: /* channels 149,157; 40 MHz */
1102 case 127: /* channels 153,161; 40 MHz */
1103 if (chan < 149 || chan > 161)
1104 return -1;
1105 return 5000 + 5 * chan;
1106 case 125: /* channels 149,153,157,161,165,169 */
1107 if (chan < 149 || chan > 169)
1108 return -1;
1109 return 5000 + 5 * chan;
1110 case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
1111 case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
1112 if (chan < 36 || chan > 161)
1113 return -1;
1114 return 5000 + 5 * chan;
1115 case 129: /* center freqs 50, 114; 160 MHz */
1116 if (chan < 50 || chan > 114)
1117 return -1;
1118 return 5000 + 5 * chan;
1119 case 180: /* 60 GHz band, channels 1..4 */
1120 if (chan < 1 || chan > 4)
1121 return -1;
1122 return 56160 + 2160 * chan;
1123 }
1124 return -1;
1125 }
1126
1127 /**
1128 * ieee80211_chan_to_freq - Convert channel info to frequency
1129 * @country: Country code, if known; otherwise, global operating class is used
1130 * @op_class: Operating class
1131 * @chan: Channel number
1132 * Returns: Frequency in MHz or -1 if the specified channel is unknown
1133 */
ieee80211_chan_to_freq(const char * country,u8 op_class,u8 chan)1134 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan)
1135 {
1136 int freq;
1137
1138 if (country_match(us_op_class_cc, country)) {
1139 freq = ieee80211_chan_to_freq_us(op_class, chan);
1140 if (freq > 0)
1141 return freq;
1142 }
1143
1144 if (country_match(eu_op_class_cc, country)) {
1145 freq = ieee80211_chan_to_freq_eu(op_class, chan);
1146 if (freq > 0)
1147 return freq;
1148 }
1149
1150 if (country_match(jp_op_class_cc, country)) {
1151 freq = ieee80211_chan_to_freq_jp(op_class, chan);
1152 if (freq > 0)
1153 return freq;
1154 }
1155
1156 if (country_match(cn_op_class_cc, country)) {
1157 freq = ieee80211_chan_to_freq_cn(op_class, chan);
1158 if (freq > 0)
1159 return freq;
1160 }
1161
1162 return ieee80211_chan_to_freq_global(op_class, chan);
1163 }
1164
1165
ieee80211_is_dfs(int freq)1166 int ieee80211_is_dfs(int freq)
1167 {
1168 /* TODO: this could be more accurate to better cover all domains */
1169 return (freq >= 5260 && freq <= 5320) || (freq >= 5500 && freq <= 5700);
1170 }
1171
1172
is_11b(u8 rate)1173 static int is_11b(u8 rate)
1174 {
1175 return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
1176 }
1177
1178
supp_rates_11b_only(struct ieee802_11_elems * elems)1179 int supp_rates_11b_only(struct ieee802_11_elems *elems)
1180 {
1181 int num_11b = 0, num_others = 0;
1182 int i;
1183
1184 if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
1185 return 0;
1186
1187 for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
1188 if (is_11b(elems->supp_rates[i]))
1189 num_11b++;
1190 else
1191 num_others++;
1192 }
1193
1194 for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
1195 i++) {
1196 if (is_11b(elems->ext_supp_rates[i]))
1197 num_11b++;
1198 else
1199 num_others++;
1200 }
1201
1202 return num_11b > 0 && num_others == 0;
1203 }
1204
1205
fc2str(u16 fc)1206 const char * fc2str(u16 fc)
1207 {
1208 u16 stype = WLAN_FC_GET_STYPE(fc);
1209 #define C2S(x) case x: return #x;
1210
1211 switch (WLAN_FC_GET_TYPE(fc)) {
1212 case WLAN_FC_TYPE_MGMT:
1213 switch (stype) {
1214 C2S(WLAN_FC_STYPE_ASSOC_REQ)
1215 C2S(WLAN_FC_STYPE_ASSOC_RESP)
1216 C2S(WLAN_FC_STYPE_REASSOC_REQ)
1217 C2S(WLAN_FC_STYPE_REASSOC_RESP)
1218 C2S(WLAN_FC_STYPE_PROBE_REQ)
1219 C2S(WLAN_FC_STYPE_PROBE_RESP)
1220 C2S(WLAN_FC_STYPE_BEACON)
1221 C2S(WLAN_FC_STYPE_ATIM)
1222 C2S(WLAN_FC_STYPE_DISASSOC)
1223 C2S(WLAN_FC_STYPE_AUTH)
1224 C2S(WLAN_FC_STYPE_DEAUTH)
1225 C2S(WLAN_FC_STYPE_ACTION)
1226 }
1227 break;
1228 case WLAN_FC_TYPE_CTRL:
1229 switch (stype) {
1230 C2S(WLAN_FC_STYPE_PSPOLL)
1231 C2S(WLAN_FC_STYPE_RTS)
1232 C2S(WLAN_FC_STYPE_CTS)
1233 C2S(WLAN_FC_STYPE_ACK)
1234 C2S(WLAN_FC_STYPE_CFEND)
1235 C2S(WLAN_FC_STYPE_CFENDACK)
1236 }
1237 break;
1238 case WLAN_FC_TYPE_DATA:
1239 switch (stype) {
1240 C2S(WLAN_FC_STYPE_DATA)
1241 C2S(WLAN_FC_STYPE_DATA_CFACK)
1242 C2S(WLAN_FC_STYPE_DATA_CFPOLL)
1243 C2S(WLAN_FC_STYPE_DATA_CFACKPOLL)
1244 C2S(WLAN_FC_STYPE_NULLFUNC)
1245 C2S(WLAN_FC_STYPE_CFACK)
1246 C2S(WLAN_FC_STYPE_CFPOLL)
1247 C2S(WLAN_FC_STYPE_CFACKPOLL)
1248 C2S(WLAN_FC_STYPE_QOS_DATA)
1249 C2S(WLAN_FC_STYPE_QOS_DATA_CFACK)
1250 C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL)
1251 C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL)
1252 C2S(WLAN_FC_STYPE_QOS_NULL)
1253 C2S(WLAN_FC_STYPE_QOS_CFPOLL)
1254 C2S(WLAN_FC_STYPE_QOS_CFACKPOLL)
1255 }
1256 break;
1257 }
1258 return "WLAN_FC_TYPE_UNKNOWN";
1259 #undef C2S
1260 }
1261
1262
mb_ies_info_by_ies(struct mb_ies_info * info,const u8 * ies_buf,size_t ies_len)1263 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
1264 size_t ies_len)
1265 {
1266 os_memset(info, 0, sizeof(*info));
1267
1268 while (ies_buf && ies_len >= 2 &&
1269 info->nof_ies < MAX_NOF_MB_IES_SUPPORTED) {
1270 size_t len = 2 + ies_buf[1];
1271
1272 if (len > ies_len) {
1273 wpa_hexdump(MSG_DEBUG, "Truncated IEs",
1274 ies_buf, ies_len);
1275 return -1;
1276 }
1277
1278 if (ies_buf[0] == WLAN_EID_MULTI_BAND) {
1279 wpa_printf(MSG_DEBUG, "MB IE of %zu bytes found", len);
1280 info->ies[info->nof_ies].ie = ies_buf + 2;
1281 info->ies[info->nof_ies].ie_len = ies_buf[1];
1282 info->nof_ies++;
1283 }
1284
1285 ies_len -= len;
1286 ies_buf += len;
1287 }
1288
1289 return 0;
1290 }
1291
1292
mb_ies_by_info(struct mb_ies_info * info)1293 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info)
1294 {
1295 struct wpabuf *mb_ies = NULL;
1296
1297 WPA_ASSERT(info != NULL);
1298
1299 if (info->nof_ies) {
1300 u8 i;
1301 size_t mb_ies_size = 0;
1302
1303 for (i = 0; i < info->nof_ies; i++)
1304 mb_ies_size += 2 + info->ies[i].ie_len;
1305
1306 mb_ies = wpabuf_alloc(mb_ies_size);
1307 if (mb_ies) {
1308 for (i = 0; i < info->nof_ies; i++) {
1309 wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND);
1310 wpabuf_put_u8(mb_ies, info->ies[i].ie_len);
1311 wpabuf_put_data(mb_ies,
1312 info->ies[i].ie,
1313 info->ies[i].ie_len);
1314 }
1315 }
1316 }
1317
1318 return mb_ies;
1319 }
1320
1321
1322 const struct oper_class_map global_op_class[] = {
1323 { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP },
1324 { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP },
1325
1326 /* Do not enable HT40 on 2.4 GHz for P2P use for now */
1327 { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP },
1328 { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP },
1329
1330 { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP },
1331 { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP },
1332 { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP },
1333 { HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP },
1334 { HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP },
1335 { HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP },
1336 { HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP },
1337 { HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP },
1338 { HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP },
1339 { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
1340 { HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20, P2P_SUPP },
1341 { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS, P2P_SUPP },
1342 { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS, P2P_SUPP },
1343
1344 /*
1345 * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center
1346 * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of
1347 * 80 MHz, but currently use the following definition for simplicity
1348 * (these center frequencies are not actual channels, which makes
1349 * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take
1350 * care of removing invalid channels.
1351 */
1352 { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP },
1353 { HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP },
1354 { HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP },
1355 { HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP },
1356 { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
1357 };
1358
1359
ieee80211_phy_type_by_freq(int freq)1360 static enum phy_type ieee80211_phy_type_by_freq(int freq)
1361 {
1362 enum hostapd_hw_mode hw_mode;
1363 u8 channel;
1364
1365 hw_mode = ieee80211_freq_to_chan(freq, &channel);
1366
1367 switch (hw_mode) {
1368 case HOSTAPD_MODE_IEEE80211A:
1369 return PHY_TYPE_OFDM;
1370 case HOSTAPD_MODE_IEEE80211B:
1371 return PHY_TYPE_HRDSSS;
1372 case HOSTAPD_MODE_IEEE80211G:
1373 return PHY_TYPE_ERP;
1374 case HOSTAPD_MODE_IEEE80211AD:
1375 return PHY_TYPE_DMG;
1376 default:
1377 return PHY_TYPE_UNSPECIFIED;
1378 };
1379 }
1380
1381
1382 /* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */
ieee80211_get_phy_type(int freq,int ht,int vht)1383 enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht)
1384 {
1385 if (vht)
1386 return PHY_TYPE_VHT;
1387 if (ht)
1388 return PHY_TYPE_HT;
1389
1390 return ieee80211_phy_type_by_freq(freq);
1391 }
1392
1393
1394 size_t global_op_class_size = ARRAY_SIZE(global_op_class);
1395
1396
1397 /**
1398 * get_ie - Fetch a specified information element from IEs buffer
1399 * @ies: Information elements buffer
1400 * @len: Information elements buffer length
1401 * @eid: Information element identifier (WLAN_EID_*)
1402 * Returns: Pointer to the information element (id field) or %NULL if not found
1403 *
1404 * This function returns the first matching information element in the IEs
1405 * buffer or %NULL in case the element is not found.
1406 */
get_ie(const u8 * ies,size_t len,u8 eid)1407 const u8 * get_ie(const u8 *ies, size_t len, u8 eid)
1408 {
1409 const u8 *end;
1410
1411 if (!ies)
1412 return NULL;
1413
1414 end = ies + len;
1415
1416 while (end - ies > 1) {
1417 if (2 + ies[1] > end - ies)
1418 break;
1419
1420 if (ies[0] == eid)
1421 return ies;
1422
1423 ies += 2 + ies[1];
1424 }
1425
1426 return NULL;
1427 }
1428
1429
mbo_add_ie(u8 * buf,size_t len,const u8 * attr,size_t attr_len)1430 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
1431 {
1432 /*
1433 * MBO IE requires 6 bytes without the attributes: EID (1), length (1),
1434 * OUI (3), OUI type (1).
1435 */
1436 if (len < 6 + attr_len) {
1437 wpa_printf(MSG_DEBUG,
1438 "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu",
1439 len, attr_len);
1440 return 0;
1441 }
1442
1443 *buf++ = WLAN_EID_VENDOR_SPECIFIC;
1444 *buf++ = attr_len + 4;
1445 WPA_PUT_BE24(buf, OUI_WFA);
1446 buf += 3;
1447 *buf++ = MBO_OUI_TYPE;
1448 os_memcpy(buf, attr, attr_len);
1449
1450 return 6 + attr_len;
1451 }
1452
1453
1454 static const struct country_op_class us_op_class[] = {
1455 { 1, 115 },
1456 { 2, 118 },
1457 { 3, 124 },
1458 { 4, 121 },
1459 { 5, 125 },
1460 { 12, 81 },
1461 { 22, 116 },
1462 { 23, 119 },
1463 { 24, 122 },
1464 { 25, 126 },
1465 { 26, 126 },
1466 { 27, 117 },
1467 { 28, 120 },
1468 { 29, 123 },
1469 { 30, 127 },
1470 { 31, 127 },
1471 { 32, 83 },
1472 { 33, 84 },
1473 { 34, 180 },
1474 };
1475
1476 static const struct country_op_class eu_op_class[] = {
1477 { 1, 115 },
1478 { 2, 118 },
1479 { 3, 121 },
1480 { 4, 81 },
1481 { 5, 116 },
1482 { 6, 119 },
1483 { 7, 122 },
1484 { 8, 117 },
1485 { 9, 120 },
1486 { 10, 123 },
1487 { 11, 83 },
1488 { 12, 84 },
1489 { 17, 125 },
1490 { 18, 180 },
1491 };
1492
1493 static const struct country_op_class jp_op_class[] = {
1494 { 1, 115 },
1495 { 30, 81 },
1496 { 31, 82 },
1497 { 32, 118 },
1498 { 33, 118 },
1499 { 34, 121 },
1500 { 35, 121 },
1501 { 36, 116 },
1502 { 37, 119 },
1503 { 38, 119 },
1504 { 39, 122 },
1505 { 40, 122 },
1506 { 41, 117 },
1507 { 42, 120 },
1508 { 43, 120 },
1509 { 44, 123 },
1510 { 45, 123 },
1511 { 56, 83 },
1512 { 57, 84 },
1513 { 58, 121 },
1514 { 59, 180 },
1515 };
1516
1517 static const struct country_op_class cn_op_class[] = {
1518 { 1, 115 },
1519 { 2, 118 },
1520 { 3, 125 },
1521 { 4, 116 },
1522 { 5, 119 },
1523 { 6, 126 },
1524 { 7, 81 },
1525 { 8, 83 },
1526 { 9, 84 },
1527 };
1528
1529 static u8
global_op_class_from_country_array(u8 op_class,size_t array_size,const struct country_op_class * country_array)1530 global_op_class_from_country_array(u8 op_class, size_t array_size,
1531 const struct country_op_class *country_array)
1532 {
1533 size_t i;
1534
1535 for (i = 0; i < array_size; i++) {
1536 if (country_array[i].country_op_class == op_class)
1537 return country_array[i].global_op_class;
1538 }
1539
1540 return 0;
1541 }
1542
1543
country_to_global_op_class(const char * country,u8 op_class)1544 u8 country_to_global_op_class(const char *country, u8 op_class)
1545 {
1546 const struct country_op_class *country_array;
1547 size_t size;
1548 u8 g_op_class;
1549
1550 if (country_match(us_op_class_cc, country)) {
1551 country_array = us_op_class;
1552 size = ARRAY_SIZE(us_op_class);
1553 } else if (country_match(eu_op_class_cc, country)) {
1554 country_array = eu_op_class;
1555 size = ARRAY_SIZE(eu_op_class);
1556 } else if (country_match(jp_op_class_cc, country)) {
1557 country_array = jp_op_class;
1558 size = ARRAY_SIZE(jp_op_class);
1559 } else if (country_match(cn_op_class_cc, country)) {
1560 country_array = cn_op_class;
1561 size = ARRAY_SIZE(cn_op_class);
1562 } else {
1563 /*
1564 * Countries that do not match any of the above countries use
1565 * global operating classes
1566 */
1567 return op_class;
1568 }
1569
1570 g_op_class = global_op_class_from_country_array(op_class, size,
1571 country_array);
1572
1573 /*
1574 * If the given operating class did not match any of the country's
1575 * operating classes, assume that global operating class is used.
1576 */
1577 return g_op_class ? g_op_class : op_class;
1578 }
1579
1580
get_oper_class(const char * country,u8 op_class)1581 const struct oper_class_map * get_oper_class(const char *country, u8 op_class)
1582 {
1583 const struct oper_class_map *op;
1584
1585 if (country)
1586 op_class = country_to_global_op_class(country, op_class);
1587
1588 op = &global_op_class[0];
1589 while (op->op_class && op->op_class != op_class)
1590 op++;
1591
1592 if (!op->op_class)
1593 return NULL;
1594
1595 return op;
1596 }
1597