MBO: Add global operating class definitions
[mech_eap.git] / src / common / ieee802_11_common.c
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
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  */
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
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 (end - pos >= 2) {
402                 if (2 + pos[1] > end - pos)
403                         break;
404                 count++;
405                 pos += 2 + pos[1];
406         }
407
408         return count;
409 }
410
411
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 (end - pos > 1) {
423                 if (2 + pos[1] > end - pos)
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 (end - pos > 1) {
445                 if (2 + pos[1] > end - pos)
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
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
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
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, VHT_CHANWIDTH_USE_HT,
574                                              &op_class, channel);
575 }
576
577
578 /**
579  * ieee80211_freq_to_channel_ext - Convert frequency into channel info
580  * for HT40 and VHT. DFS channels are not covered.
581  * @freq: Frequency (MHz) to convert
582  * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
583  * @vht: VHT channel width (VHT_CHANWIDTH_*)
584  * @op_class: Buffer for returning operating class
585  * @channel: Buffer for returning channel number
586  * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
587  */
588 enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
589                                                    int sec_channel, int vht,
590                                                    u8 *op_class, u8 *channel)
591 {
592         u8 vht_opclass;
593
594         /* TODO: more operating classes */
595
596         if (sec_channel > 1 || sec_channel < -1)
597                 return NUM_HOSTAPD_MODES;
598
599         if (freq >= 2412 && freq <= 2472) {
600                 if ((freq - 2407) % 5)
601                         return NUM_HOSTAPD_MODES;
602
603                 if (vht)
604                         return NUM_HOSTAPD_MODES;
605
606                 /* 2.407 GHz, channels 1..13 */
607                 if (sec_channel == 1)
608                         *op_class = 83;
609                 else if (sec_channel == -1)
610                         *op_class = 84;
611                 else
612                         *op_class = 81;
613
614                 *channel = (freq - 2407) / 5;
615
616                 return HOSTAPD_MODE_IEEE80211G;
617         }
618
619         if (freq == 2484) {
620                 if (sec_channel || vht)
621                         return NUM_HOSTAPD_MODES;
622
623                 *op_class = 82; /* channel 14 */
624                 *channel = 14;
625
626                 return HOSTAPD_MODE_IEEE80211B;
627         }
628
629         if (freq >= 4900 && freq < 5000) {
630                 if ((freq - 4000) % 5)
631                         return NUM_HOSTAPD_MODES;
632                 *channel = (freq - 4000) / 5;
633                 *op_class = 0; /* TODO */
634                 return HOSTAPD_MODE_IEEE80211A;
635         }
636
637         switch (vht) {
638         case VHT_CHANWIDTH_80MHZ:
639                 vht_opclass = 128;
640                 break;
641         case VHT_CHANWIDTH_160MHZ:
642                 vht_opclass = 129;
643                 break;
644         case VHT_CHANWIDTH_80P80MHZ:
645                 vht_opclass = 130;
646                 break;
647         default:
648                 vht_opclass = 0;
649                 break;
650         }
651
652         /* 5 GHz, channels 36..48 */
653         if (freq >= 5180 && freq <= 5240) {
654                 if ((freq - 5000) % 5)
655                         return NUM_HOSTAPD_MODES;
656
657                 if (vht_opclass)
658                         *op_class = vht_opclass;
659                 else if (sec_channel == 1)
660                         *op_class = 116;
661                 else if (sec_channel == -1)
662                         *op_class = 117;
663                 else
664                         *op_class = 115;
665
666                 *channel = (freq - 5000) / 5;
667
668                 return HOSTAPD_MODE_IEEE80211A;
669         }
670
671         /* 5 GHz, channels 149..169 */
672         if (freq >= 5745 && freq <= 5845) {
673                 if ((freq - 5000) % 5)
674                         return NUM_HOSTAPD_MODES;
675
676                 if (vht_opclass)
677                         *op_class = vht_opclass;
678                 else if (sec_channel == 1)
679                         *op_class = 126;
680                 else if (sec_channel == -1)
681                         *op_class = 127;
682                 else if (freq <= 5805)
683                         *op_class = 124;
684                 else
685                         *op_class = 125;
686
687                 *channel = (freq - 5000) / 5;
688
689                 return HOSTAPD_MODE_IEEE80211A;
690         }
691
692         /* 5 GHz, channels 100..140 */
693         if (freq >= 5000 && freq <= 5700) {
694                 if ((freq - 5000) % 5)
695                         return NUM_HOSTAPD_MODES;
696
697                 if (vht_opclass)
698                         *op_class = vht_opclass;
699                 else if (sec_channel == 1)
700                         *op_class = 122;
701                 else if (sec_channel == -1)
702                         *op_class = 123;
703                 else
704                         *op_class = 121;
705
706                 *channel = (freq - 5000) / 5;
707
708                 return HOSTAPD_MODE_IEEE80211A;
709         }
710
711         if (freq >= 5000 && freq < 5900) {
712                 if ((freq - 5000) % 5)
713                         return NUM_HOSTAPD_MODES;
714                 *channel = (freq - 5000) / 5;
715                 *op_class = 0; /* TODO */
716                 return HOSTAPD_MODE_IEEE80211A;
717         }
718
719         /* 56.16 GHz, channel 1..4 */
720         if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) {
721                 if (sec_channel || vht)
722                         return NUM_HOSTAPD_MODES;
723
724                 *channel = (freq - 56160) / 2160;
725                 *op_class = 180;
726
727                 return HOSTAPD_MODE_IEEE80211AD;
728         }
729
730         return NUM_HOSTAPD_MODES;
731 }
732
733
734 static const char *const us_op_class_cc[] = {
735         "US", "CA", NULL
736 };
737
738 static const char *const eu_op_class_cc[] = {
739         "AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
740         "DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
741         "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
742         "RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL
743 };
744
745 static const char *const jp_op_class_cc[] = {
746         "JP", NULL
747 };
748
749 static const char *const cn_op_class_cc[] = {
750         "CN", NULL
751 };
752
753
754 static int country_match(const char *const cc[], const char *const country)
755 {
756         int i;
757
758         if (country == NULL)
759                 return 0;
760         for (i = 0; cc[i]; i++) {
761                 if (cc[i][0] == country[0] && cc[i][1] == country[1])
762                         return 1;
763         }
764
765         return 0;
766 }
767
768
769 static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan)
770 {
771         switch (op_class) {
772         case 12: /* channels 1..11 */
773         case 32: /* channels 1..7; 40 MHz */
774         case 33: /* channels 5..11; 40 MHz */
775                 if (chan < 1 || chan > 11)
776                         return -1;
777                 return 2407 + 5 * chan;
778         case 1: /* channels 36,40,44,48 */
779         case 2: /* channels 52,56,60,64; dfs */
780         case 22: /* channels 36,44; 40 MHz */
781         case 23: /* channels 52,60; 40 MHz */
782         case 27: /* channels 40,48; 40 MHz */
783         case 28: /* channels 56,64; 40 MHz */
784                 if (chan < 36 || chan > 64)
785                         return -1;
786                 return 5000 + 5 * chan;
787         case 4: /* channels 100-144 */
788         case 24: /* channels 100-140; 40 MHz */
789                 if (chan < 100 || chan > 144)
790                         return -1;
791                 return 5000 + 5 * chan;
792         case 3: /* channels 149,153,157,161 */
793         case 25: /* channels 149,157; 40 MHz */
794         case 26: /* channels 149,157; 40 MHz */
795         case 30: /* channels 153,161; 40 MHz */
796         case 31: /* channels 153,161; 40 MHz */
797                 if (chan < 149 || chan > 161)
798                         return -1;
799                 return 5000 + 5 * chan;
800         case 5: /* channels 149,153,157,161,165 */
801                 if (chan < 149 || chan > 165)
802                         return -1;
803                 return 5000 + 5 * chan;
804         case 34: /* 60 GHz band, channels 1..3 */
805                 if (chan < 1 || chan > 3)
806                         return -1;
807                 return 56160 + 2160 * chan;
808         }
809         return -1;
810 }
811
812
813 static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan)
814 {
815         switch (op_class) {
816         case 4: /* channels 1..13 */
817         case 11: /* channels 1..9; 40 MHz */
818         case 12: /* channels 5..13; 40 MHz */
819                 if (chan < 1 || chan > 13)
820                         return -1;
821                 return 2407 + 5 * chan;
822         case 1: /* channels 36,40,44,48 */
823         case 2: /* channels 52,56,60,64; dfs */
824         case 5: /* channels 36,44; 40 MHz */
825         case 6: /* channels 52,60; 40 MHz */
826         case 8: /* channels 40,48; 40 MHz */
827         case 9: /* channels 56,64; 40 MHz */
828                 if (chan < 36 || chan > 64)
829                         return -1;
830                 return 5000 + 5 * chan;
831         case 3: /* channels 100-140 */
832         case 7: /* channels 100-132; 40 MHz */
833         case 10: /* channels 104-136; 40 MHz */
834         case 16: /* channels 100-140 */
835                 if (chan < 100 || chan > 140)
836                         return -1;
837                 return 5000 + 5 * chan;
838         case 17: /* channels 149,153,157,161,165,169 */
839                 if (chan < 149 || chan > 169)
840                         return -1;
841                 return 5000 + 5 * chan;
842         case 18: /* 60 GHz band, channels 1..4 */
843                 if (chan < 1 || chan > 4)
844                         return -1;
845                 return 56160 + 2160 * chan;
846         }
847         return -1;
848 }
849
850
851 static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan)
852 {
853         switch (op_class) {
854         case 30: /* channels 1..13 */
855         case 56: /* channels 1..9; 40 MHz */
856         case 57: /* channels 5..13; 40 MHz */
857                 if (chan < 1 || chan > 13)
858                         return -1;
859                 return 2407 + 5 * chan;
860         case 31: /* channel 14 */
861                 if (chan != 14)
862                         return -1;
863                 return 2414 + 5 * chan;
864         case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */
865         case 32: /* channels 52,56,60,64 */
866         case 33: /* channels 52,56,60,64 */
867         case 36: /* channels 36,44; 40 MHz */
868         case 37: /* channels 52,60; 40 MHz */
869         case 38: /* channels 52,60; 40 MHz */
870         case 41: /* channels 40,48; 40 MHz */
871         case 42: /* channels 56,64; 40 MHz */
872         case 43: /* channels 56,64; 40 MHz */
873                 if (chan < 34 || chan > 64)
874                         return -1;
875                 return 5000 + 5 * chan;
876         case 34: /* channels 100-140 */
877         case 35: /* channels 100-140 */
878         case 39: /* channels 100-132; 40 MHz */
879         case 40: /* channels 100-132; 40 MHz */
880         case 44: /* channels 104-136; 40 MHz */
881         case 45: /* channels 104-136; 40 MHz */
882         case 58: /* channels 100-140 */
883                 if (chan < 100 || chan > 140)
884                         return -1;
885                 return 5000 + 5 * chan;
886         case 59: /* 60 GHz band, channels 1..4 */
887                 if (chan < 1 || chan > 3)
888                         return -1;
889                 return 56160 + 2160 * chan;
890         }
891         return -1;
892 }
893
894
895 static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan)
896 {
897         switch (op_class) {
898         case 7: /* channels 1..13 */
899         case 8: /* channels 1..9; 40 MHz */
900         case 9: /* channels 5..13; 40 MHz */
901                 if (chan < 1 || chan > 13)
902                         return -1;
903                 return 2407 + 5 * chan;
904         case 1: /* channels 36,40,44,48 */
905         case 2: /* channels 52,56,60,64; dfs */
906         case 4: /* channels 36,44; 40 MHz */
907         case 5: /* channels 52,60; 40 MHz */
908                 if (chan < 36 || chan > 64)
909                         return -1;
910                 return 5000 + 5 * chan;
911         case 3: /* channels 149,153,157,161,165 */
912         case 6: /* channels 149,157; 40 MHz */
913                 if (chan < 149 || chan > 165)
914                         return -1;
915                 return 5000 + 5 * chan;
916         }
917         return -1;
918 }
919
920
921 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
922 {
923         /* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
924         switch (op_class) {
925         case 81:
926                 /* channels 1..13 */
927                 if (chan < 1 || chan > 13)
928                         return -1;
929                 return 2407 + 5 * chan;
930         case 82:
931                 /* channel 14 */
932                 if (chan != 14)
933                         return -1;
934                 return 2414 + 5 * chan;
935         case 83: /* channels 1..9; 40 MHz */
936         case 84: /* channels 5..13; 40 MHz */
937                 if (chan < 1 || chan > 13)
938                         return -1;
939                 return 2407 + 5 * chan;
940         case 115: /* channels 36,40,44,48; indoor only */
941         case 116: /* channels 36,44; 40 MHz; indoor only */
942         case 117: /* channels 40,48; 40 MHz; indoor only */
943         case 118: /* channels 52,56,60,64; dfs */
944         case 119: /* channels 52,60; 40 MHz; dfs */
945         case 120: /* channels 56,64; 40 MHz; dfs */
946                 if (chan < 36 || chan > 64)
947                         return -1;
948                 return 5000 + 5 * chan;
949         case 121: /* channels 100-140 */
950         case 122: /* channels 100-142; 40 MHz */
951         case 123: /* channels 104-136; 40 MHz */
952                 if (chan < 100 || chan > 140)
953                         return -1;
954                 return 5000 + 5 * chan;
955         case 124: /* channels 149,153,157,161 */
956         case 126: /* channels 149,157; 40 MHz */
957         case 127: /* channels 153,161; 40 MHz */
958                 if (chan < 149 || chan > 161)
959                         return -1;
960                 return 5000 + 5 * chan;
961         case 125: /* channels 149,153,157,161,165,169 */
962                 if (chan < 149 || chan > 169)
963                         return -1;
964                 return 5000 + 5 * chan;
965         case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
966         case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
967                 if (chan < 36 || chan > 161)
968                         return -1;
969                 return 5000 + 5 * chan;
970         case 129: /* center freqs 50, 114; 160 MHz */
971                 if (chan < 50 || chan > 114)
972                         return -1;
973                 return 5000 + 5 * chan;
974         case 180: /* 60 GHz band, channels 1..4 */
975                 if (chan < 1 || chan > 4)
976                         return -1;
977                 return 56160 + 2160 * chan;
978         }
979         return -1;
980 }
981
982 /**
983  * ieee80211_chan_to_freq - Convert channel info to frequency
984  * @country: Country code, if known; otherwise, global operating class is used
985  * @op_class: Operating class
986  * @chan: Channel number
987  * Returns: Frequency in MHz or -1 if the specified channel is unknown
988  */
989 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan)
990 {
991         int freq;
992
993         if (country_match(us_op_class_cc, country)) {
994                 freq = ieee80211_chan_to_freq_us(op_class, chan);
995                 if (freq > 0)
996                         return freq;
997         }
998
999         if (country_match(eu_op_class_cc, country)) {
1000                 freq = ieee80211_chan_to_freq_eu(op_class, chan);
1001                 if (freq > 0)
1002                         return freq;
1003         }
1004
1005         if (country_match(jp_op_class_cc, country)) {
1006                 freq = ieee80211_chan_to_freq_jp(op_class, chan);
1007                 if (freq > 0)
1008                         return freq;
1009         }
1010
1011         if (country_match(cn_op_class_cc, country)) {
1012                 freq = ieee80211_chan_to_freq_cn(op_class, chan);
1013                 if (freq > 0)
1014                         return freq;
1015         }
1016
1017         return ieee80211_chan_to_freq_global(op_class, chan);
1018 }
1019
1020
1021 int ieee80211_is_dfs(int freq)
1022 {
1023         /* TODO: this could be more accurate to better cover all domains */
1024         return (freq >= 5260 && freq <= 5320) || (freq >= 5500 && freq <= 5700);
1025 }
1026
1027
1028 static int is_11b(u8 rate)
1029 {
1030         return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
1031 }
1032
1033
1034 int supp_rates_11b_only(struct ieee802_11_elems *elems)
1035 {
1036         int num_11b = 0, num_others = 0;
1037         int i;
1038
1039         if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
1040                 return 0;
1041
1042         for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
1043                 if (is_11b(elems->supp_rates[i]))
1044                         num_11b++;
1045                 else
1046                         num_others++;
1047         }
1048
1049         for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
1050              i++) {
1051                 if (is_11b(elems->ext_supp_rates[i]))
1052                         num_11b++;
1053                 else
1054                         num_others++;
1055         }
1056
1057         return num_11b > 0 && num_others == 0;
1058 }
1059
1060
1061 const char * fc2str(u16 fc)
1062 {
1063         u16 stype = WLAN_FC_GET_STYPE(fc);
1064 #define C2S(x) case x: return #x;
1065
1066         switch (WLAN_FC_GET_TYPE(fc)) {
1067         case WLAN_FC_TYPE_MGMT:
1068                 switch (stype) {
1069                 C2S(WLAN_FC_STYPE_ASSOC_REQ)
1070                 C2S(WLAN_FC_STYPE_ASSOC_RESP)
1071                 C2S(WLAN_FC_STYPE_REASSOC_REQ)
1072                 C2S(WLAN_FC_STYPE_REASSOC_RESP)
1073                 C2S(WLAN_FC_STYPE_PROBE_REQ)
1074                 C2S(WLAN_FC_STYPE_PROBE_RESP)
1075                 C2S(WLAN_FC_STYPE_BEACON)
1076                 C2S(WLAN_FC_STYPE_ATIM)
1077                 C2S(WLAN_FC_STYPE_DISASSOC)
1078                 C2S(WLAN_FC_STYPE_AUTH)
1079                 C2S(WLAN_FC_STYPE_DEAUTH)
1080                 C2S(WLAN_FC_STYPE_ACTION)
1081                 }
1082                 break;
1083         case WLAN_FC_TYPE_CTRL:
1084                 switch (stype) {
1085                 C2S(WLAN_FC_STYPE_PSPOLL)
1086                 C2S(WLAN_FC_STYPE_RTS)
1087                 C2S(WLAN_FC_STYPE_CTS)
1088                 C2S(WLAN_FC_STYPE_ACK)
1089                 C2S(WLAN_FC_STYPE_CFEND)
1090                 C2S(WLAN_FC_STYPE_CFENDACK)
1091                 }
1092                 break;
1093         case WLAN_FC_TYPE_DATA:
1094                 switch (stype) {
1095                 C2S(WLAN_FC_STYPE_DATA)
1096                 C2S(WLAN_FC_STYPE_DATA_CFACK)
1097                 C2S(WLAN_FC_STYPE_DATA_CFPOLL)
1098                 C2S(WLAN_FC_STYPE_DATA_CFACKPOLL)
1099                 C2S(WLAN_FC_STYPE_NULLFUNC)
1100                 C2S(WLAN_FC_STYPE_CFACK)
1101                 C2S(WLAN_FC_STYPE_CFPOLL)
1102                 C2S(WLAN_FC_STYPE_CFACKPOLL)
1103                 C2S(WLAN_FC_STYPE_QOS_DATA)
1104                 C2S(WLAN_FC_STYPE_QOS_DATA_CFACK)
1105                 C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL)
1106                 C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL)
1107                 C2S(WLAN_FC_STYPE_QOS_NULL)
1108                 C2S(WLAN_FC_STYPE_QOS_CFPOLL)
1109                 C2S(WLAN_FC_STYPE_QOS_CFACKPOLL)
1110                 }
1111                 break;
1112         }
1113         return "WLAN_FC_TYPE_UNKNOWN";
1114 #undef C2S
1115 }
1116
1117
1118 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
1119                        size_t ies_len)
1120 {
1121         os_memset(info, 0, sizeof(*info));
1122
1123         while (ies_buf && ies_len >= 2 &&
1124                info->nof_ies < MAX_NOF_MB_IES_SUPPORTED) {
1125                 size_t len = 2 + ies_buf[1];
1126
1127                 if (len > ies_len) {
1128                         wpa_hexdump(MSG_DEBUG, "Truncated IEs",
1129                                     ies_buf, ies_len);
1130                         return -1;
1131                 }
1132
1133                 if (ies_buf[0] == WLAN_EID_MULTI_BAND) {
1134                         wpa_printf(MSG_DEBUG, "MB IE of %zu bytes found", len);
1135                         info->ies[info->nof_ies].ie = ies_buf + 2;
1136                         info->ies[info->nof_ies].ie_len = ies_buf[1];
1137                         info->nof_ies++;
1138                 }
1139
1140                 ies_len -= len;
1141                 ies_buf += len;
1142         }
1143
1144         return 0;
1145 }
1146
1147
1148 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info)
1149 {
1150         struct wpabuf *mb_ies = NULL;
1151
1152         WPA_ASSERT(info != NULL);
1153
1154         if (info->nof_ies) {
1155                 u8 i;
1156                 size_t mb_ies_size = 0;
1157
1158                 for (i = 0; i < info->nof_ies; i++)
1159                         mb_ies_size += 2 + info->ies[i].ie_len;
1160
1161                 mb_ies = wpabuf_alloc(mb_ies_size);
1162                 if (mb_ies) {
1163                         for (i = 0; i < info->nof_ies; i++) {
1164                                 wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND);
1165                                 wpabuf_put_u8(mb_ies, info->ies[i].ie_len);
1166                                 wpabuf_put_data(mb_ies,
1167                                                 info->ies[i].ie,
1168                                                 info->ies[i].ie_len);
1169                         }
1170                 }
1171         }
1172
1173         return mb_ies;
1174 }
1175
1176
1177 const struct oper_class_map global_op_class[] = {
1178         { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP },
1179         { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP },
1180
1181         /* Do not enable HT40 on 2.4 GHz for P2P use for now */
1182         { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP },
1183         { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP },
1184
1185         { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP },
1186         { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP },
1187         { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP },
1188         { HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP },
1189         { HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP },
1190         { HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP },
1191         { HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP },
1192         { HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP },
1193         { HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP },
1194         { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
1195         { HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20, P2P_SUPP },
1196         { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS, P2P_SUPP },
1197         { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS, P2P_SUPP },
1198
1199         /*
1200          * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center
1201          * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of
1202          * 80 MHz, but currently use the following definition for simplicity
1203          * (these center frequencies are not actual channels, which makes
1204          * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take
1205          * care of removing invalid channels.
1206          */
1207         { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP },
1208         { HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP },
1209         { HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP },
1210         { HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP },
1211         { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
1212 };
1213
1214 size_t global_op_class_size = ARRAY_SIZE(global_op_class);
1215
1216
1217 /**
1218  * get_ie - Fetch a specified information element from IEs buffer
1219  * @ies: Information elements buffer
1220  * @len: Information elements buffer length
1221  * @eid: Information element identifier (WLAN_EID_*)
1222  * Returns: Pointer to the information element (id field) or %NULL if not found
1223  *
1224  * This function returns the first matching information element in the IEs
1225  * buffer or %NULL in case the element is not found.
1226  */
1227 const u8 * get_ie(const u8 *ies, size_t len, u8 eid)
1228 {
1229         const u8 *end;
1230
1231         if (!ies)
1232                 return NULL;
1233
1234         end = ies + len;
1235
1236         while (end - ies > 1) {
1237                 if (2 + ies[1] > end - ies)
1238                         break;
1239
1240                 if (ies[0] == eid)
1241                         return ies;
1242
1243                 ies += 2 + ies[1];
1244         }
1245
1246         return NULL;
1247 }
1248
1249
1250 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
1251 {
1252         /*
1253          * MBO IE requires 6 bytes without the attributes: EID (1), length (1),
1254          * OUI (3), OUI type (1).
1255          */
1256         if (len < 6 + attr_len) {
1257                 wpa_printf(MSG_DEBUG,
1258                            "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu",
1259                            len, attr_len);
1260                 return 0;
1261         }
1262
1263         *buf++ = WLAN_EID_VENDOR_SPECIFIC;
1264         *buf++ = attr_len + 4;
1265         WPA_PUT_BE24(buf, OUI_WFA);
1266         buf += 3;
1267         *buf++ = MBO_OUI_TYPE;
1268         os_memcpy(buf, attr, attr_len);
1269
1270         return 6 + attr_len;
1271 }