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
182 /**
183 * ieee802_11_parse_elems - Parse information elements in management frames
184 * @start: Pointer to the start of IEs
185 * @len: Length of IE buffer in octets
186 * @elems: Data structure for parsed elements
187 * @show_errors: Whether to show parsing errors in debug log
188 * Returns: Parsing result
189 */
ieee802_11_parse_elems(const u8 * start,size_t len,struct ieee802_11_elems * elems,int show_errors)190 ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
191 struct ieee802_11_elems *elems,
192 int show_errors)
193 {
194 size_t left = len;
195 const u8 *pos = start;
196 int unknown = 0;
197
198 os_memset(elems, 0, sizeof(*elems));
199
200 while (left >= 2) {
201 u8 id, elen;
202
203 id = *pos++;
204 elen = *pos++;
205 left -= 2;
206
207 if (elen > left) {
208 if (show_errors) {
209 wpa_printf(MSG_DEBUG, "IEEE 802.11 element "
210 "parse failed (id=%d elen=%d "
211 "left=%lu)",
212 id, elen, (unsigned long) left);
213 wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
214 }
215 return ParseFailed;
216 }
217
218 switch (id) {
219 case WLAN_EID_SSID:
220 if (elen > SSID_MAX_LEN) {
221 wpa_printf(MSG_DEBUG,
222 "Ignored too long SSID element (elen=%u)",
223 elen);
224 break;
225 }
226 elems->ssid = pos;
227 elems->ssid_len = elen;
228 break;
229 case WLAN_EID_SUPP_RATES:
230 elems->supp_rates = pos;
231 elems->supp_rates_len = elen;
232 break;
233 case WLAN_EID_DS_PARAMS:
234 if (elen < 1)
235 break;
236 elems->ds_params = pos;
237 break;
238 case WLAN_EID_CF_PARAMS:
239 case WLAN_EID_TIM:
240 break;
241 case WLAN_EID_CHALLENGE:
242 elems->challenge = pos;
243 elems->challenge_len = elen;
244 break;
245 case WLAN_EID_ERP_INFO:
246 if (elen < 1)
247 break;
248 elems->erp_info = pos;
249 break;
250 case WLAN_EID_EXT_SUPP_RATES:
251 elems->ext_supp_rates = pos;
252 elems->ext_supp_rates_len = elen;
253 break;
254 case WLAN_EID_VENDOR_SPECIFIC:
255 if (ieee802_11_parse_vendor_specific(pos, elen,
256 elems,
257 show_errors))
258 unknown++;
259 break;
260 case WLAN_EID_RSN:
261 elems->rsn_ie = pos;
262 elems->rsn_ie_len = elen;
263 break;
264 case WLAN_EID_PWR_CAPABILITY:
265 break;
266 case WLAN_EID_SUPPORTED_CHANNELS:
267 elems->supp_channels = pos;
268 elems->supp_channels_len = elen;
269 break;
270 case WLAN_EID_MOBILITY_DOMAIN:
271 if (elen < sizeof(struct rsn_mdie))
272 break;
273 elems->mdie = pos;
274 elems->mdie_len = elen;
275 break;
276 case WLAN_EID_FAST_BSS_TRANSITION:
277 if (elen < sizeof(struct rsn_ftie))
278 break;
279 elems->ftie = pos;
280 elems->ftie_len = elen;
281 break;
282 case WLAN_EID_TIMEOUT_INTERVAL:
283 if (elen != 5)
284 break;
285 elems->timeout_int = pos;
286 break;
287 case WLAN_EID_HT_CAP:
288 if (elen < sizeof(struct ieee80211_ht_capabilities))
289 break;
290 elems->ht_capabilities = pos;
291 break;
292 case WLAN_EID_HT_OPERATION:
293 if (elen < sizeof(struct ieee80211_ht_operation))
294 break;
295 elems->ht_operation = pos;
296 break;
297 case WLAN_EID_MESH_CONFIG:
298 elems->mesh_config = pos;
299 elems->mesh_config_len = elen;
300 break;
301 case WLAN_EID_MESH_ID:
302 elems->mesh_id = pos;
303 elems->mesh_id_len = elen;
304 break;
305 case WLAN_EID_PEER_MGMT:
306 elems->peer_mgmt = pos;
307 elems->peer_mgmt_len = elen;
308 break;
309 case WLAN_EID_VHT_CAP:
310 if (elen < sizeof(struct ieee80211_vht_capabilities))
311 break;
312 elems->vht_capabilities = pos;
313 break;
314 case WLAN_EID_VHT_OPERATION:
315 if (elen < sizeof(struct ieee80211_vht_operation))
316 break;
317 elems->vht_operation = pos;
318 break;
319 case WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION:
320 if (elen != 1)
321 break;
322 elems->vht_opmode_notif = pos;
323 break;
324 case WLAN_EID_LINK_ID:
325 if (elen < 18)
326 break;
327 elems->link_id = pos;
328 break;
329 case WLAN_EID_INTERWORKING:
330 elems->interworking = pos;
331 elems->interworking_len = elen;
332 break;
333 case WLAN_EID_QOS_MAP_SET:
334 if (elen < 16)
335 break;
336 elems->qos_map_set = pos;
337 elems->qos_map_set_len = elen;
338 break;
339 case WLAN_EID_EXT_CAPAB:
340 elems->ext_capab = pos;
341 elems->ext_capab_len = elen;
342 break;
343 case WLAN_EID_BSS_MAX_IDLE_PERIOD:
344 if (elen < 3)
345 break;
346 elems->bss_max_idle_period = pos;
347 break;
348 case WLAN_EID_SSID_LIST:
349 elems->ssid_list = pos;
350 elems->ssid_list_len = elen;
351 break;
352 case WLAN_EID_AMPE:
353 elems->ampe = pos;
354 elems->ampe_len = elen;
355 break;
356 case WLAN_EID_MIC:
357 elems->mic = pos;
358 elems->mic_len = elen;
359 /* after mic everything is encrypted, so stop. */
360 left = elen;
361 break;
362 case WLAN_EID_MULTI_BAND:
363 if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) {
364 wpa_printf(MSG_MSGDUMP,
365 "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)",
366 id, elen);
367 break;
368 }
369
370 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos;
371 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen;
372 elems->mb_ies.nof_ies++;
373 break;
374 case WLAN_EID_SUPPORTED_OPERATING_CLASSES:
375 elems->supp_op_classes = pos;
376 elems->supp_op_classes_len = elen;
377 break;
378 default:
379 unknown++;
380 if (!show_errors)
381 break;
382 wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse "
383 "ignored unknown element (id=%d elen=%d)",
384 id, elen);
385 break;
386 }
387
388 left -= elen;
389 pos += elen;
390 }
391
392 if (left)
393 return ParseFailed;
394
395 return unknown ? ParseUnknown : ParseOK;
396 }
397
398
ieee802_11_ie_count(const u8 * ies,size_t ies_len)399 int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
400 {
401 int count = 0;
402 const u8 *pos, *end;
403
404 if (ies == NULL)
405 return 0;
406
407 pos = ies;
408 end = ies + ies_len;
409
410 while (end - pos >= 2) {
411 if (2 + pos[1] > end - pos)
412 break;
413 count++;
414 pos += 2 + pos[1];
415 }
416
417 return count;
418 }
419
420
ieee802_11_vendor_ie_concat(const u8 * ies,size_t ies_len,u32 oui_type)421 struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
422 u32 oui_type)
423 {
424 struct wpabuf *buf;
425 const u8 *end, *pos, *ie;
426
427 pos = ies;
428 end = ies + ies_len;
429 ie = NULL;
430
431 while (end - pos > 1) {
432 if (2 + pos[1] > end - pos)
433 return NULL;
434 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
435 WPA_GET_BE32(&pos[2]) == oui_type) {
436 ie = pos;
437 break;
438 }
439 pos += 2 + pos[1];
440 }
441
442 if (ie == NULL)
443 return NULL; /* No specified vendor IE found */
444
445 buf = wpabuf_alloc(ies_len);
446 if (buf == NULL)
447 return NULL;
448
449 /*
450 * There may be multiple vendor IEs in the message, so need to
451 * concatenate their data fields.
452 */
453 while (end - pos > 1) {
454 if (2 + pos[1] > end - pos)
455 break;
456 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
457 WPA_GET_BE32(&pos[2]) == oui_type)
458 wpabuf_put_data(buf, pos + 6, pos[1] - 4);
459 pos += 2 + pos[1];
460 }
461
462 return buf;
463 }
464
465
get_hdr_bssid(const struct ieee80211_hdr * hdr,size_t len)466 const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
467 {
468 u16 fc, type, stype;
469
470 /*
471 * PS-Poll frames are 16 bytes. All other frames are
472 * 24 bytes or longer.
473 */
474 if (len < 16)
475 return NULL;
476
477 fc = le_to_host16(hdr->frame_control);
478 type = WLAN_FC_GET_TYPE(fc);
479 stype = WLAN_FC_GET_STYPE(fc);
480
481 switch (type) {
482 case WLAN_FC_TYPE_DATA:
483 if (len < 24)
484 return NULL;
485 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
486 case WLAN_FC_FROMDS | WLAN_FC_TODS:
487 case WLAN_FC_TODS:
488 return hdr->addr1;
489 case WLAN_FC_FROMDS:
490 return hdr->addr2;
491 default:
492 return NULL;
493 }
494 case WLAN_FC_TYPE_CTRL:
495 if (stype != WLAN_FC_STYPE_PSPOLL)
496 return NULL;
497 return hdr->addr1;
498 case WLAN_FC_TYPE_MGMT:
499 return hdr->addr3;
500 default:
501 return NULL;
502 }
503 }
504
505
hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],const char * name,const char * val)506 int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
507 const char *name, const char *val)
508 {
509 int num, v;
510 const char *pos;
511 struct hostapd_wmm_ac_params *ac;
512
513 /* skip 'wme_ac_' or 'wmm_ac_' prefix */
514 pos = name + 7;
515 if (os_strncmp(pos, "be_", 3) == 0) {
516 num = 0;
517 pos += 3;
518 } else if (os_strncmp(pos, "bk_", 3) == 0) {
519 num = 1;
520 pos += 3;
521 } else if (os_strncmp(pos, "vi_", 3) == 0) {
522 num = 2;
523 pos += 3;
524 } else if (os_strncmp(pos, "vo_", 3) == 0) {
525 num = 3;
526 pos += 3;
527 } else {
528 wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos);
529 return -1;
530 }
531
532 ac = &wmm_ac_params[num];
533
534 if (os_strcmp(pos, "aifs") == 0) {
535 v = atoi(val);
536 if (v < 1 || v > 255) {
537 wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v);
538 return -1;
539 }
540 ac->aifs = v;
541 } else if (os_strcmp(pos, "cwmin") == 0) {
542 v = atoi(val);
543 if (v < 0 || v > 15) {
544 wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v);
545 return -1;
546 }
547 ac->cwmin = v;
548 } else if (os_strcmp(pos, "cwmax") == 0) {
549 v = atoi(val);
550 if (v < 0 || v > 15) {
551 wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v);
552 return -1;
553 }
554 ac->cwmax = v;
555 } else if (os_strcmp(pos, "txop_limit") == 0) {
556 v = atoi(val);
557 if (v < 0 || v > 0xffff) {
558 wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
559 return -1;
560 }
561 ac->txop_limit = v;
562 } else if (os_strcmp(pos, "acm") == 0) {
563 v = atoi(val);
564 if (v < 0 || v > 1) {
565 wpa_printf(MSG_ERROR, "Invalid acm value %d", v);
566 return -1;
567 }
568 ac->admission_control_mandatory = v;
569 } else {
570 wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos);
571 return -1;
572 }
573
574 return 0;
575 }
576
577
ieee80211_freq_to_chan(int freq,u8 * channel)578 enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel)
579 {
580 u8 op_class;
581
582 return ieee80211_freq_to_channel_ext(freq, 0, VHT_CHANWIDTH_USE_HT,
583 &op_class, channel);
584 }
585
586
587 /**
588 * ieee80211_freq_to_channel_ext - Convert frequency into channel info
589 * for HT40 and VHT. DFS channels are not covered.
590 * @freq: Frequency (MHz) to convert
591 * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
592 * @vht: VHT channel width (VHT_CHANWIDTH_*)
593 * @op_class: Buffer for returning operating class
594 * @channel: Buffer for returning channel number
595 * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
596 */
ieee80211_freq_to_channel_ext(unsigned int freq,int sec_channel,int vht,u8 * op_class,u8 * channel)597 enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
598 int sec_channel, int vht,
599 u8 *op_class, u8 *channel)
600 {
601 u8 vht_opclass;
602
603 /* TODO: more operating classes */
604
605 if (sec_channel > 1 || sec_channel < -1)
606 return NUM_HOSTAPD_MODES;
607
608 if (freq >= 2412 && freq <= 2472) {
609 if ((freq - 2407) % 5)
610 return NUM_HOSTAPD_MODES;
611
612 if (vht)
613 return NUM_HOSTAPD_MODES;
614
615 /* 2.407 GHz, channels 1..13 */
616 if (sec_channel == 1)
617 *op_class = 83;
618 else if (sec_channel == -1)
619 *op_class = 84;
620 else
621 *op_class = 81;
622
623 *channel = (freq - 2407) / 5;
624
625 return HOSTAPD_MODE_IEEE80211G;
626 }
627
628 if (freq == 2484) {
629 if (sec_channel || vht)
630 return NUM_HOSTAPD_MODES;
631
632 *op_class = 82; /* channel 14 */
633 *channel = 14;
634
635 return HOSTAPD_MODE_IEEE80211B;
636 }
637
638 if (freq >= 4900 && freq < 5000) {
639 if ((freq - 4000) % 5)
640 return NUM_HOSTAPD_MODES;
641 *channel = (freq - 4000) / 5;
642 *op_class = 0; /* TODO */
643 return HOSTAPD_MODE_IEEE80211A;
644 }
645
646 switch (vht) {
647 case VHT_CHANWIDTH_80MHZ:
648 vht_opclass = 128;
649 break;
650 case VHT_CHANWIDTH_160MHZ:
651 vht_opclass = 129;
652 break;
653 case VHT_CHANWIDTH_80P80MHZ:
654 vht_opclass = 130;
655 break;
656 default:
657 vht_opclass = 0;
658 break;
659 }
660
661 /* 5 GHz, channels 36..48 */
662 if (freq >= 5180 && freq <= 5240) {
663 if ((freq - 5000) % 5)
664 return NUM_HOSTAPD_MODES;
665
666 if (vht_opclass)
667 *op_class = vht_opclass;
668 else if (sec_channel == 1)
669 *op_class = 116;
670 else if (sec_channel == -1)
671 *op_class = 117;
672 else
673 *op_class = 115;
674
675 *channel = (freq - 5000) / 5;
676
677 return HOSTAPD_MODE_IEEE80211A;
678 }
679
680 /* 5 GHz, channels 149..169 */
681 if (freq >= 5745 && freq <= 5845) {
682 if ((freq - 5000) % 5)
683 return NUM_HOSTAPD_MODES;
684
685 if (vht_opclass)
686 *op_class = vht_opclass;
687 else if (sec_channel == 1)
688 *op_class = 126;
689 else if (sec_channel == -1)
690 *op_class = 127;
691 else if (freq <= 5805)
692 *op_class = 124;
693 else
694 *op_class = 125;
695
696 *channel = (freq - 5000) / 5;
697
698 return HOSTAPD_MODE_IEEE80211A;
699 }
700
701 /* 5 GHz, channels 100..140 */
702 if (freq >= 5000 && freq <= 5700) {
703 if ((freq - 5000) % 5)
704 return NUM_HOSTAPD_MODES;
705
706 if (vht_opclass)
707 *op_class = vht_opclass;
708 else if (sec_channel == 1)
709 *op_class = 122;
710 else if (sec_channel == -1)
711 *op_class = 123;
712 else
713 *op_class = 121;
714
715 *channel = (freq - 5000) / 5;
716
717 return HOSTAPD_MODE_IEEE80211A;
718 }
719
720 if (freq >= 5000 && freq < 5900) {
721 if ((freq - 5000) % 5)
722 return NUM_HOSTAPD_MODES;
723 *channel = (freq - 5000) / 5;
724 *op_class = 0; /* TODO */
725 return HOSTAPD_MODE_IEEE80211A;
726 }
727
728 /* 56.16 GHz, channel 1..4 */
729 if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) {
730 if (sec_channel || vht)
731 return NUM_HOSTAPD_MODES;
732
733 *channel = (freq - 56160) / 2160;
734 *op_class = 180;
735
736 return HOSTAPD_MODE_IEEE80211AD;
737 }
738
739 return NUM_HOSTAPD_MODES;
740 }
741
742
743 static const char *const us_op_class_cc[] = {
744 "US", "CA", NULL
745 };
746
747 static const char *const eu_op_class_cc[] = {
748 "AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
749 "DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
750 "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
751 "RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL
752 };
753
754 static const char *const jp_op_class_cc[] = {
755 "JP", NULL
756 };
757
758 static const char *const cn_op_class_cc[] = {
759 "CN", NULL
760 };
761
762
country_match(const char * const cc[],const char * const country)763 static int country_match(const char *const cc[], const char *const country)
764 {
765 int i;
766
767 if (country == NULL)
768 return 0;
769 for (i = 0; cc[i]; i++) {
770 if (cc[i][0] == country[0] && cc[i][1] == country[1])
771 return 1;
772 }
773
774 return 0;
775 }
776
777
ieee80211_chan_to_freq_us(u8 op_class,u8 chan)778 static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan)
779 {
780 switch (op_class) {
781 case 12: /* channels 1..11 */
782 case 32: /* channels 1..7; 40 MHz */
783 case 33: /* channels 5..11; 40 MHz */
784 if (chan < 1 || chan > 11)
785 return -1;
786 return 2407 + 5 * chan;
787 case 1: /* channels 36,40,44,48 */
788 case 2: /* channels 52,56,60,64; dfs */
789 case 22: /* channels 36,44; 40 MHz */
790 case 23: /* channels 52,60; 40 MHz */
791 case 27: /* channels 40,48; 40 MHz */
792 case 28: /* channels 56,64; 40 MHz */
793 if (chan < 36 || chan > 64)
794 return -1;
795 return 5000 + 5 * chan;
796 case 4: /* channels 100-144 */
797 case 24: /* channels 100-140; 40 MHz */
798 if (chan < 100 || chan > 144)
799 return -1;
800 return 5000 + 5 * chan;
801 case 3: /* channels 149,153,157,161 */
802 case 25: /* channels 149,157; 40 MHz */
803 case 26: /* channels 149,157; 40 MHz */
804 case 30: /* channels 153,161; 40 MHz */
805 case 31: /* channels 153,161; 40 MHz */
806 if (chan < 149 || chan > 161)
807 return -1;
808 return 5000 + 5 * chan;
809 case 5: /* channels 149,153,157,161,165 */
810 if (chan < 149 || chan > 165)
811 return -1;
812 return 5000 + 5 * chan;
813 case 34: /* 60 GHz band, channels 1..3 */
814 if (chan < 1 || chan > 3)
815 return -1;
816 return 56160 + 2160 * chan;
817 }
818 return -1;
819 }
820
821
ieee80211_chan_to_freq_eu(u8 op_class,u8 chan)822 static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan)
823 {
824 switch (op_class) {
825 case 4: /* channels 1..13 */
826 case 11: /* channels 1..9; 40 MHz */
827 case 12: /* channels 5..13; 40 MHz */
828 if (chan < 1 || chan > 13)
829 return -1;
830 return 2407 + 5 * chan;
831 case 1: /* channels 36,40,44,48 */
832 case 2: /* channels 52,56,60,64; dfs */
833 case 5: /* channels 36,44; 40 MHz */
834 case 6: /* channels 52,60; 40 MHz */
835 case 8: /* channels 40,48; 40 MHz */
836 case 9: /* channels 56,64; 40 MHz */
837 if (chan < 36 || chan > 64)
838 return -1;
839 return 5000 + 5 * chan;
840 case 3: /* channels 100-140 */
841 case 7: /* channels 100-132; 40 MHz */
842 case 10: /* channels 104-136; 40 MHz */
843 case 16: /* channels 100-140 */
844 if (chan < 100 || chan > 140)
845 return -1;
846 return 5000 + 5 * chan;
847 case 17: /* channels 149,153,157,161,165,169 */
848 if (chan < 149 || chan > 169)
849 return -1;
850 return 5000 + 5 * chan;
851 case 18: /* 60 GHz band, channels 1..4 */
852 if (chan < 1 || chan > 4)
853 return -1;
854 return 56160 + 2160 * chan;
855 }
856 return -1;
857 }
858
859
ieee80211_chan_to_freq_jp(u8 op_class,u8 chan)860 static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan)
861 {
862 switch (op_class) {
863 case 30: /* channels 1..13 */
864 case 56: /* channels 1..9; 40 MHz */
865 case 57: /* channels 5..13; 40 MHz */
866 if (chan < 1 || chan > 13)
867 return -1;
868 return 2407 + 5 * chan;
869 case 31: /* channel 14 */
870 if (chan != 14)
871 return -1;
872 return 2414 + 5 * chan;
873 case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */
874 case 32: /* channels 52,56,60,64 */
875 case 33: /* channels 52,56,60,64 */
876 case 36: /* channels 36,44; 40 MHz */
877 case 37: /* channels 52,60; 40 MHz */
878 case 38: /* channels 52,60; 40 MHz */
879 case 41: /* channels 40,48; 40 MHz */
880 case 42: /* channels 56,64; 40 MHz */
881 case 43: /* channels 56,64; 40 MHz */
882 if (chan < 34 || chan > 64)
883 return -1;
884 return 5000 + 5 * chan;
885 case 34: /* channels 100-140 */
886 case 35: /* channels 100-140 */
887 case 39: /* channels 100-132; 40 MHz */
888 case 40: /* channels 100-132; 40 MHz */
889 case 44: /* channels 104-136; 40 MHz */
890 case 45: /* channels 104-136; 40 MHz */
891 case 58: /* channels 100-140 */
892 if (chan < 100 || chan > 140)
893 return -1;
894 return 5000 + 5 * chan;
895 case 59: /* 60 GHz band, channels 1..4 */
896 if (chan < 1 || chan > 3)
897 return -1;
898 return 56160 + 2160 * chan;
899 }
900 return -1;
901 }
902
903
ieee80211_chan_to_freq_cn(u8 op_class,u8 chan)904 static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan)
905 {
906 switch (op_class) {
907 case 7: /* channels 1..13 */
908 case 8: /* channels 1..9; 40 MHz */
909 case 9: /* channels 5..13; 40 MHz */
910 if (chan < 1 || chan > 13)
911 return -1;
912 return 2407 + 5 * chan;
913 case 1: /* channels 36,40,44,48 */
914 case 2: /* channels 52,56,60,64; dfs */
915 case 4: /* channels 36,44; 40 MHz */
916 case 5: /* channels 52,60; 40 MHz */
917 if (chan < 36 || chan > 64)
918 return -1;
919 return 5000 + 5 * chan;
920 case 3: /* channels 149,153,157,161,165 */
921 case 6: /* channels 149,157; 40 MHz */
922 if (chan < 149 || chan > 165)
923 return -1;
924 return 5000 + 5 * chan;
925 }
926 return -1;
927 }
928
929
ieee80211_chan_to_freq_global(u8 op_class,u8 chan)930 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
931 {
932 /* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
933 switch (op_class) {
934 case 81:
935 /* channels 1..13 */
936 if (chan < 1 || chan > 13)
937 return -1;
938 return 2407 + 5 * chan;
939 case 82:
940 /* channel 14 */
941 if (chan != 14)
942 return -1;
943 return 2414 + 5 * chan;
944 case 83: /* channels 1..9; 40 MHz */
945 case 84: /* channels 5..13; 40 MHz */
946 if (chan < 1 || chan > 13)
947 return -1;
948 return 2407 + 5 * chan;
949 case 115: /* channels 36,40,44,48; indoor only */
950 case 116: /* channels 36,44; 40 MHz; indoor only */
951 case 117: /* channels 40,48; 40 MHz; indoor only */
952 case 118: /* channels 52,56,60,64; dfs */
953 case 119: /* channels 52,60; 40 MHz; dfs */
954 case 120: /* channels 56,64; 40 MHz; dfs */
955 if (chan < 36 || chan > 64)
956 return -1;
957 return 5000 + 5 * chan;
958 case 121: /* channels 100-140 */
959 case 122: /* channels 100-142; 40 MHz */
960 case 123: /* channels 104-136; 40 MHz */
961 if (chan < 100 || chan > 140)
962 return -1;
963 return 5000 + 5 * chan;
964 case 124: /* channels 149,153,157,161 */
965 case 126: /* channels 149,157; 40 MHz */
966 case 127: /* channels 153,161; 40 MHz */
967 if (chan < 149 || chan > 161)
968 return -1;
969 return 5000 + 5 * chan;
970 case 125: /* channels 149,153,157,161,165,169 */
971 if (chan < 149 || chan > 169)
972 return -1;
973 return 5000 + 5 * chan;
974 case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
975 case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
976 if (chan < 36 || chan > 161)
977 return -1;
978 return 5000 + 5 * chan;
979 case 129: /* center freqs 50, 114; 160 MHz */
980 if (chan < 50 || chan > 114)
981 return -1;
982 return 5000 + 5 * chan;
983 case 180: /* 60 GHz band, channels 1..4 */
984 if (chan < 1 || chan > 4)
985 return -1;
986 return 56160 + 2160 * chan;
987 }
988 return -1;
989 }
990
991 /**
992 * ieee80211_chan_to_freq - Convert channel info to frequency
993 * @country: Country code, if known; otherwise, global operating class is used
994 * @op_class: Operating class
995 * @chan: Channel number
996 * Returns: Frequency in MHz or -1 if the specified channel is unknown
997 */
ieee80211_chan_to_freq(const char * country,u8 op_class,u8 chan)998 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan)
999 {
1000 int freq;
1001
1002 if (country_match(us_op_class_cc, country)) {
1003 freq = ieee80211_chan_to_freq_us(op_class, chan);
1004 if (freq > 0)
1005 return freq;
1006 }
1007
1008 if (country_match(eu_op_class_cc, country)) {
1009 freq = ieee80211_chan_to_freq_eu(op_class, chan);
1010 if (freq > 0)
1011 return freq;
1012 }
1013
1014 if (country_match(jp_op_class_cc, country)) {
1015 freq = ieee80211_chan_to_freq_jp(op_class, chan);
1016 if (freq > 0)
1017 return freq;
1018 }
1019
1020 if (country_match(cn_op_class_cc, country)) {
1021 freq = ieee80211_chan_to_freq_cn(op_class, chan);
1022 if (freq > 0)
1023 return freq;
1024 }
1025
1026 return ieee80211_chan_to_freq_global(op_class, chan);
1027 }
1028
1029
ieee80211_is_dfs(int freq)1030 int ieee80211_is_dfs(int freq)
1031 {
1032 /* TODO: this could be more accurate to better cover all domains */
1033 return (freq >= 5260 && freq <= 5320) || (freq >= 5500 && freq <= 5700);
1034 }
1035
1036
is_11b(u8 rate)1037 static int is_11b(u8 rate)
1038 {
1039 return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
1040 }
1041
1042
supp_rates_11b_only(struct ieee802_11_elems * elems)1043 int supp_rates_11b_only(struct ieee802_11_elems *elems)
1044 {
1045 int num_11b = 0, num_others = 0;
1046 int i;
1047
1048 if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
1049 return 0;
1050
1051 for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
1052 if (is_11b(elems->supp_rates[i]))
1053 num_11b++;
1054 else
1055 num_others++;
1056 }
1057
1058 for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
1059 i++) {
1060 if (is_11b(elems->ext_supp_rates[i]))
1061 num_11b++;
1062 else
1063 num_others++;
1064 }
1065
1066 return num_11b > 0 && num_others == 0;
1067 }
1068
1069
fc2str(u16 fc)1070 const char * fc2str(u16 fc)
1071 {
1072 u16 stype = WLAN_FC_GET_STYPE(fc);
1073 #define C2S(x) case x: return #x;
1074
1075 switch (WLAN_FC_GET_TYPE(fc)) {
1076 case WLAN_FC_TYPE_MGMT:
1077 switch (stype) {
1078 C2S(WLAN_FC_STYPE_ASSOC_REQ)
1079 C2S(WLAN_FC_STYPE_ASSOC_RESP)
1080 C2S(WLAN_FC_STYPE_REASSOC_REQ)
1081 C2S(WLAN_FC_STYPE_REASSOC_RESP)
1082 C2S(WLAN_FC_STYPE_PROBE_REQ)
1083 C2S(WLAN_FC_STYPE_PROBE_RESP)
1084 C2S(WLAN_FC_STYPE_BEACON)
1085 C2S(WLAN_FC_STYPE_ATIM)
1086 C2S(WLAN_FC_STYPE_DISASSOC)
1087 C2S(WLAN_FC_STYPE_AUTH)
1088 C2S(WLAN_FC_STYPE_DEAUTH)
1089 C2S(WLAN_FC_STYPE_ACTION)
1090 }
1091 break;
1092 case WLAN_FC_TYPE_CTRL:
1093 switch (stype) {
1094 C2S(WLAN_FC_STYPE_PSPOLL)
1095 C2S(WLAN_FC_STYPE_RTS)
1096 C2S(WLAN_FC_STYPE_CTS)
1097 C2S(WLAN_FC_STYPE_ACK)
1098 C2S(WLAN_FC_STYPE_CFEND)
1099 C2S(WLAN_FC_STYPE_CFENDACK)
1100 }
1101 break;
1102 case WLAN_FC_TYPE_DATA:
1103 switch (stype) {
1104 C2S(WLAN_FC_STYPE_DATA)
1105 C2S(WLAN_FC_STYPE_DATA_CFACK)
1106 C2S(WLAN_FC_STYPE_DATA_CFPOLL)
1107 C2S(WLAN_FC_STYPE_DATA_CFACKPOLL)
1108 C2S(WLAN_FC_STYPE_NULLFUNC)
1109 C2S(WLAN_FC_STYPE_CFACK)
1110 C2S(WLAN_FC_STYPE_CFPOLL)
1111 C2S(WLAN_FC_STYPE_CFACKPOLL)
1112 C2S(WLAN_FC_STYPE_QOS_DATA)
1113 C2S(WLAN_FC_STYPE_QOS_DATA_CFACK)
1114 C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL)
1115 C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL)
1116 C2S(WLAN_FC_STYPE_QOS_NULL)
1117 C2S(WLAN_FC_STYPE_QOS_CFPOLL)
1118 C2S(WLAN_FC_STYPE_QOS_CFACKPOLL)
1119 }
1120 break;
1121 }
1122 return "WLAN_FC_TYPE_UNKNOWN";
1123 #undef C2S
1124 }
1125
1126
mb_ies_info_by_ies(struct mb_ies_info * info,const u8 * ies_buf,size_t ies_len)1127 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
1128 size_t ies_len)
1129 {
1130 os_memset(info, 0, sizeof(*info));
1131
1132 while (ies_buf && ies_len >= 2 &&
1133 info->nof_ies < MAX_NOF_MB_IES_SUPPORTED) {
1134 size_t len = 2 + ies_buf[1];
1135
1136 if (len > ies_len) {
1137 wpa_hexdump(MSG_DEBUG, "Truncated IEs",
1138 ies_buf, ies_len);
1139 return -1;
1140 }
1141
1142 if (ies_buf[0] == WLAN_EID_MULTI_BAND) {
1143 wpa_printf(MSG_DEBUG, "MB IE of %zu bytes found", len);
1144 info->ies[info->nof_ies].ie = ies_buf + 2;
1145 info->ies[info->nof_ies].ie_len = ies_buf[1];
1146 info->nof_ies++;
1147 }
1148
1149 ies_len -= len;
1150 ies_buf += len;
1151 }
1152
1153 return 0;
1154 }
1155
1156
mb_ies_by_info(struct mb_ies_info * info)1157 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info)
1158 {
1159 struct wpabuf *mb_ies = NULL;
1160
1161 WPA_ASSERT(info != NULL);
1162
1163 if (info->nof_ies) {
1164 u8 i;
1165 size_t mb_ies_size = 0;
1166
1167 for (i = 0; i < info->nof_ies; i++)
1168 mb_ies_size += 2 + info->ies[i].ie_len;
1169
1170 mb_ies = wpabuf_alloc(mb_ies_size);
1171 if (mb_ies) {
1172 for (i = 0; i < info->nof_ies; i++) {
1173 wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND);
1174 wpabuf_put_u8(mb_ies, info->ies[i].ie_len);
1175 wpabuf_put_data(mb_ies,
1176 info->ies[i].ie,
1177 info->ies[i].ie_len);
1178 }
1179 }
1180 }
1181
1182 return mb_ies;
1183 }
1184
1185
1186 const struct oper_class_map global_op_class[] = {
1187 { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP },
1188 { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP },
1189
1190 /* Do not enable HT40 on 2.4 GHz for P2P use for now */
1191 { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP },
1192 { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP },
1193
1194 { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP },
1195 { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP },
1196 { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP },
1197 { HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP },
1198 { HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP },
1199 { HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP },
1200 { HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP },
1201 { HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP },
1202 { HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP },
1203 { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
1204 { HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20, P2P_SUPP },
1205 { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS, P2P_SUPP },
1206 { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS, P2P_SUPP },
1207
1208 /*
1209 * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center
1210 * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of
1211 * 80 MHz, but currently use the following definition for simplicity
1212 * (these center frequencies are not actual channels, which makes
1213 * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take
1214 * care of removing invalid channels.
1215 */
1216 { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP },
1217 { HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP },
1218 { HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP },
1219 { HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP },
1220 { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
1221 };
1222
1223
ieee80211_phy_type_by_freq(int freq)1224 static enum phy_type ieee80211_phy_type_by_freq(int freq)
1225 {
1226 enum hostapd_hw_mode hw_mode;
1227 u8 channel;
1228
1229 hw_mode = ieee80211_freq_to_chan(freq, &channel);
1230
1231 switch (hw_mode) {
1232 case HOSTAPD_MODE_IEEE80211A:
1233 return PHY_TYPE_OFDM;
1234 case HOSTAPD_MODE_IEEE80211B:
1235 return PHY_TYPE_HRDSSS;
1236 case HOSTAPD_MODE_IEEE80211G:
1237 return PHY_TYPE_ERP;
1238 case HOSTAPD_MODE_IEEE80211AD:
1239 return PHY_TYPE_DMG;
1240 default:
1241 return PHY_TYPE_UNSPECIFIED;
1242 };
1243 }
1244
1245
1246 /* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */
ieee80211_get_phy_type(int freq,int ht,int vht)1247 enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht)
1248 {
1249 if (vht)
1250 return PHY_TYPE_VHT;
1251 if (ht)
1252 return PHY_TYPE_HT;
1253
1254 return ieee80211_phy_type_by_freq(freq);
1255 }
1256
1257
1258 size_t global_op_class_size = ARRAY_SIZE(global_op_class);
1259
1260
1261 /**
1262 * get_ie - Fetch a specified information element from IEs buffer
1263 * @ies: Information elements buffer
1264 * @len: Information elements buffer length
1265 * @eid: Information element identifier (WLAN_EID_*)
1266 * Returns: Pointer to the information element (id field) or %NULL if not found
1267 *
1268 * This function returns the first matching information element in the IEs
1269 * buffer or %NULL in case the element is not found.
1270 */
get_ie(const u8 * ies,size_t len,u8 eid)1271 const u8 * get_ie(const u8 *ies, size_t len, u8 eid)
1272 {
1273 const u8 *end;
1274
1275 if (!ies)
1276 return NULL;
1277
1278 end = ies + len;
1279
1280 while (end - ies > 1) {
1281 if (2 + ies[1] > end - ies)
1282 break;
1283
1284 if (ies[0] == eid)
1285 return ies;
1286
1287 ies += 2 + ies[1];
1288 }
1289
1290 return NULL;
1291 }
1292
1293
mbo_add_ie(u8 * buf,size_t len,const u8 * attr,size_t attr_len)1294 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
1295 {
1296 /*
1297 * MBO IE requires 6 bytes without the attributes: EID (1), length (1),
1298 * OUI (3), OUI type (1).
1299 */
1300 if (len < 6 + attr_len) {
1301 wpa_printf(MSG_DEBUG,
1302 "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu",
1303 len, attr_len);
1304 return 0;
1305 }
1306
1307 *buf++ = WLAN_EID_VENDOR_SPECIFIC;
1308 *buf++ = attr_len + 4;
1309 WPA_PUT_BE24(buf, OUI_WFA);
1310 buf += 3;
1311 *buf++ = MBO_OUI_TYPE;
1312 os_memcpy(buf, attr, attr_len);
1313
1314 return 6 + attr_len;
1315 }
1316