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