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