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 
ieee802_11_parse_vendor_specific(const u8 * pos,size_t elen,struct ieee802_11_elems * elems,int show_errors)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                     case OWE_OUI_TYPE:
134                               /* OWE Transition Mode element */
135                               break;
136                     case DPP_CC_OUI_TYPE:
137                               /* DPP Configurator Connectivity element */
138                               break;
139                     case SAE_PK_OUI_TYPE:
140                               elems->sae_pk = pos + 4;
141                               elems->sae_pk_len = elen - 4;
142                               break;
143                     default:
144                               wpa_printf(MSG_MSGDUMP, "Unknown WFA "
145                                            "information element ignored "
146                                            "(type=%d len=%lu)",
147                                            pos[3], (unsigned long) elen);
148                               return -1;
149                     }
150                     break;
151 
152           case OUI_BROADCOM:
153                     switch (pos[3]) {
154                     case VENDOR_HT_CAPAB_OUI_TYPE:
155                               elems->vendor_ht_cap = pos;
156                               elems->vendor_ht_cap_len = elen;
157                               break;
158                     case VENDOR_VHT_TYPE:
159                               if (elen > 4 &&
160                                   (pos[4] == VENDOR_VHT_SUBTYPE ||
161                                    pos[4] == VENDOR_VHT_SUBTYPE2)) {
162                                         elems->vendor_vht = pos;
163                                         elems->vendor_vht_len = elen;
164                               } else
165                                         return -1;
166                               break;
167                     default:
168                               wpa_printf(MSG_EXCESSIVE, "Unknown Broadcom "
169                                            "information element ignored "
170                                            "(type=%d len=%lu)",
171                                            pos[3], (unsigned long) elen);
172                               return -1;
173                     }
174                     break;
175 
176           case OUI_QCA:
177                     switch (pos[3]) {
178                     case QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST:
179                               elems->pref_freq_list = pos;
180                               elems->pref_freq_list_len = elen;
181                               break;
182                     default:
183                               wpa_printf(MSG_EXCESSIVE,
184                                            "Unknown QCA information element ignored (type=%d len=%lu)",
185                                            pos[3], (unsigned long) elen);
186                               return -1;
187                     }
188                     break;
189 
190           default:
191                     wpa_printf(MSG_EXCESSIVE, "unknown vendor specific "
192                                  "information element ignored (vendor OUI "
193                                  "%02x:%02x:%02x len=%lu)",
194                                  pos[0], pos[1], pos[2], (unsigned long) elen);
195                     return -1;
196           }
197 
198           return 0;
199 }
200 
201 
ieee802_11_parse_mle(const u8 * pos,size_t elen,size_t ** total_len,struct ieee802_11_elems * elems,int show_errors)202 static int ieee802_11_parse_mle(const u8 *pos, size_t elen, size_t **total_len,
203                                         struct ieee802_11_elems *elems,
204                                         int show_errors)
205 {
206           u8 mle_type = pos[0] & MULTI_LINK_CONTROL_TYPE_MASK;
207 
208           switch (mle_type) {
209           case MULTI_LINK_CONTROL_TYPE_BASIC:
210                     elems->basic_mle = pos;
211                     elems->basic_mle_len = elen;
212                     *total_len = &elems->basic_mle_len;
213                     break;
214           case MULTI_LINK_CONTROL_TYPE_PROBE_REQ:
215                     elems->probe_req_mle = pos;
216                     elems->probe_req_mle_len = elen;
217                     *total_len = &elems->probe_req_mle_len;
218                     break;
219           case MULTI_LINK_CONTROL_TYPE_RECONF:
220                     elems->reconf_mle = pos;
221                     elems->reconf_mle_len = elen;
222                     *total_len = &elems->reconf_mle_len;
223                     break;
224           case MULTI_LINK_CONTROL_TYPE_TDLS:
225                     elems->tdls_mle = pos;
226                     elems->tdls_mle_len = elen;
227                     *total_len = &elems->tdls_mle_len;
228                     break;
229           case MULTI_LINK_CONTROL_TYPE_PRIOR_ACCESS:
230                     elems->prior_access_mle = pos;
231                     elems->prior_access_mle_len = elen;
232                     *total_len = &elems->prior_access_mle_len;
233                     break;
234           default:
235                     if (show_errors) {
236                               wpa_printf(MSG_MSGDUMP,
237                                            "Unknown Multi-Link element type %u",
238                                            mle_type);
239                     }
240                     return -1;
241           }
242 
243           return 0;
244 }
245 
246 
ieee802_11_fragments_length(struct ieee802_11_elems * elems,const u8 * start,size_t len)247 static size_t ieee802_11_fragments_length(struct ieee802_11_elems *elems,
248                                                     const u8 *start, size_t len)
249 {
250           const struct element *elem;
251           size_t frags_len = 0;
252 
253           for_each_element(elem, start, len) {
254                     if (elem->id != WLAN_EID_FRAGMENT)
255                               break;
256 
257                     frags_len += elem->datalen + 2;
258                     elems->num_frag_elems++;
259           }
260 
261           return frags_len;
262 }
263 
264 
ieee802_11_parse_extension(const u8 * pos,size_t elen,struct ieee802_11_elems * elems,const u8 * start,size_t len,int show_errors)265 static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
266                                               struct ieee802_11_elems *elems,
267                                               const u8 *start, size_t len,
268                                               int show_errors)
269 {
270           u8 ext_id;
271           size_t *total_len = NULL;
272 
273           if (elen < 1) {
274                     if (show_errors) {
275                               wpa_printf(MSG_MSGDUMP,
276                                            "short information element (Ext)");
277                     }
278                     return -1;
279           }
280 
281           ext_id = *pos++;
282           elen--;
283 
284           switch (ext_id) {
285           case WLAN_EID_EXT_ASSOC_DELAY_INFO:
286                     if (elen != 1)
287                               break;
288                     elems->assoc_delay_info = pos;
289                     break;
290           case WLAN_EID_EXT_FILS_REQ_PARAMS:
291                     if (elen < 3)
292                               break;
293                     elems->fils_req_params = pos;
294                     elems->fils_req_params_len = elen;
295                     break;
296           case WLAN_EID_EXT_FILS_KEY_CONFIRM:
297                     elems->fils_key_confirm = pos;
298                     elems->fils_key_confirm_len = elen;
299                     break;
300           case WLAN_EID_EXT_FILS_SESSION:
301                     if (elen != FILS_SESSION_LEN)
302                               break;
303                     elems->fils_session = pos;
304                     break;
305           case WLAN_EID_EXT_FILS_HLP_CONTAINER:
306                     if (elen < 2 * ETH_ALEN)
307                               break;
308                     elems->fils_hlp = pos;
309                     elems->fils_hlp_len = elen;
310                     total_len = &elems->fils_hlp_len;
311                     break;
312           case WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN:
313                     if (elen < 1)
314                               break;
315                     elems->fils_ip_addr_assign = pos;
316                     elems->fils_ip_addr_assign_len = elen;
317                     break;
318           case WLAN_EID_EXT_KEY_DELIVERY:
319                     if (elen < WPA_KEY_RSC_LEN)
320                               break;
321                     elems->key_delivery = pos;
322                     elems->key_delivery_len = elen;
323                     break;
324           case WLAN_EID_EXT_WRAPPED_DATA:
325                     elems->wrapped_data = pos;
326                     elems->wrapped_data_len = elen;
327                     total_len = &elems->wrapped_data_len;
328                     break;
329           case WLAN_EID_EXT_FILS_PUBLIC_KEY:
330                     if (elen < 1)
331                               break;
332                     elems->fils_pk = pos;
333                     elems->fils_pk_len = elen;
334                     break;
335           case WLAN_EID_EXT_FILS_NONCE:
336                     if (elen != FILS_NONCE_LEN)
337                               break;
338                     elems->fils_nonce = pos;
339                     break;
340           case WLAN_EID_EXT_OWE_DH_PARAM:
341                     if (elen < 2)
342                               break;
343                     elems->owe_dh = pos;
344                     elems->owe_dh_len = elen;
345                     break;
346           case WLAN_EID_EXT_PASSWORD_IDENTIFIER:
347                     elems->password_id = pos;
348                     elems->password_id_len = elen;
349                     break;
350           case WLAN_EID_EXT_HE_CAPABILITIES:
351                     elems->he_capabilities = pos;
352                     elems->he_capabilities_len = elen;
353                     break;
354           case WLAN_EID_EXT_HE_OPERATION:
355                     elems->he_operation = pos;
356                     elems->he_operation_len = elen;
357                     break;
358           case WLAN_EID_EXT_OCV_OCI:
359                     elems->oci = pos;
360                     elems->oci_len = elen;
361                     break;
362           case WLAN_EID_EXT_SHORT_SSID_LIST:
363                     elems->short_ssid_list = pos;
364                     elems->short_ssid_list_len = elen;
365                     break;
366           case WLAN_EID_EXT_HE_6GHZ_BAND_CAP:
367                     if (elen < sizeof(struct ieee80211_he_6ghz_band_cap))
368                               break;
369                     elems->he_6ghz_band_cap = pos;
370                     break;
371           case WLAN_EID_EXT_PASN_PARAMS:
372                     elems->pasn_params = pos;
373                     elems->pasn_params_len = elen;
374                     break;
375           case WLAN_EID_EXT_EHT_CAPABILITIES:
376                     elems->eht_capabilities = pos;
377                     elems->eht_capabilities_len = elen;
378                     break;
379           case WLAN_EID_EXT_EHT_OPERATION:
380                     elems->eht_operation = pos;
381                     elems->eht_operation_len = elen;
382                     break;
383           case WLAN_EID_EXT_MULTI_LINK:
384                     if (elen < 2)
385                               break;
386                     if (ieee802_11_parse_mle(pos, elen, &total_len, elems,
387                                                    show_errors))
388                               return -1;
389                     break;
390           case WLAN_EID_EXT_KNOWN_BSSID:
391                     elems->mbssid_known_bss = pos;
392                     elems->mbssid_known_bss_len = elen;
393                     break;
394           default:
395                     if (show_errors) {
396                               wpa_printf(MSG_MSGDUMP,
397                                            "IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)",
398                                            ext_id, (unsigned int) elen);
399                     }
400                     return -1;
401           }
402 
403           if (elen == 254 && total_len)
404                     *total_len += ieee802_11_fragments_length(
405                               elems, pos + elen, (start + len) - (pos + elen));
406 
407           return 0;
408 }
409 
410 
__ieee802_11_parse_elems(const u8 * start,size_t len,struct ieee802_11_elems * elems,int show_errors)411 static ParseRes __ieee802_11_parse_elems(const u8 *start, size_t len,
412                                                    struct ieee802_11_elems *elems,
413                                                    int show_errors)
414 {
415           const struct element *elem;
416           int unknown = 0;
417 
418           if (!start)
419                     return ParseOK;
420 
421           for_each_element(elem, start, len) {
422                     u8 id = elem->id, elen = elem->datalen;
423                     const u8 *pos = elem->data;
424                     size_t *total_len = NULL;
425 
426                     if (id == WLAN_EID_FRAGMENT && elems->num_frag_elems > 0) {
427                               elems->num_frag_elems--;
428                               continue;
429                     }
430                     elems->num_frag_elems = 0;
431 
432                     switch (id) {
433                     case WLAN_EID_SSID:
434                               if (elen > SSID_MAX_LEN) {
435                                         wpa_printf(MSG_DEBUG,
436                                                      "Ignored too long SSID element (elen=%u)",
437                                                      elen);
438                                         break;
439                               }
440                               if (elems->ssid) {
441                                         wpa_printf(MSG_MSGDUMP,
442                                                      "Ignored duplicated SSID element");
443                                         break;
444                               }
445                               elems->ssid = pos;
446                               elems->ssid_len = elen;
447                               break;
448                     case WLAN_EID_SUPP_RATES:
449                               elems->supp_rates = pos;
450                               elems->supp_rates_len = elen;
451                               break;
452                     case WLAN_EID_DS_PARAMS:
453                               if (elen < 1)
454                                         break;
455                               elems->ds_params = pos;
456                               break;
457                     case WLAN_EID_CF_PARAMS:
458                     case WLAN_EID_TIM:
459                               break;
460                     case WLAN_EID_CHALLENGE:
461                               elems->challenge = pos;
462                               elems->challenge_len = elen;
463                               break;
464                     case WLAN_EID_ERP_INFO:
465                               if (elen < 1)
466                                         break;
467                               elems->erp_info = pos;
468                               break;
469                     case WLAN_EID_EXT_SUPP_RATES:
470                               elems->ext_supp_rates = pos;
471                               elems->ext_supp_rates_len = elen;
472                               break;
473                     case WLAN_EID_VENDOR_SPECIFIC:
474                               if (ieee802_11_parse_vendor_specific(pos, elen,
475                                                                            elems,
476                                                                            show_errors))
477                                         unknown++;
478                               break;
479                     case WLAN_EID_RSN:
480                               elems->rsn_ie = pos;
481                               elems->rsn_ie_len = elen;
482                               break;
483                     case WLAN_EID_RSNX:
484                               elems->rsnxe = pos;
485                               elems->rsnxe_len = elen;
486                               break;
487                     case WLAN_EID_PWR_CAPABILITY:
488                               if (elen < 2)
489                                         break;
490                               elems->power_capab = pos;
491                               elems->power_capab_len = elen;
492                               break;
493                     case WLAN_EID_SUPPORTED_CHANNELS:
494                               elems->supp_channels = pos;
495                               elems->supp_channels_len = elen;
496                               break;
497                     case WLAN_EID_MOBILITY_DOMAIN:
498                               if (elen < sizeof(struct rsn_mdie))
499                                         break;
500                               elems->mdie = pos;
501                               elems->mdie_len = elen;
502                               break;
503                     case WLAN_EID_FAST_BSS_TRANSITION:
504                               if (elen < sizeof(struct rsn_ftie))
505                                         break;
506                               elems->ftie = pos;
507                               elems->ftie_len = elen;
508                               elems->fte_defrag_len = elen;
509                               total_len = &elems->fte_defrag_len;
510                               break;
511                     case WLAN_EID_TIMEOUT_INTERVAL:
512                               if (elen != 5)
513                                         break;
514                               elems->timeout_int = pos;
515                               break;
516                     case WLAN_EID_HT_CAP:
517                               if (elen < sizeof(struct ieee80211_ht_capabilities))
518                                         break;
519                               elems->ht_capabilities = pos;
520                               break;
521                     case WLAN_EID_HT_OPERATION:
522                               if (elen < sizeof(struct ieee80211_ht_operation))
523                                         break;
524                               elems->ht_operation = pos;
525                               break;
526                     case WLAN_EID_MESH_CONFIG:
527                               elems->mesh_config = pos;
528                               elems->mesh_config_len = elen;
529                               break;
530                     case WLAN_EID_MESH_ID:
531                               elems->mesh_id = pos;
532                               elems->mesh_id_len = elen;
533                               break;
534                     case WLAN_EID_PEER_MGMT:
535                               elems->peer_mgmt = pos;
536                               elems->peer_mgmt_len = elen;
537                               break;
538                     case WLAN_EID_VHT_CAP:
539                               if (elen < sizeof(struct ieee80211_vht_capabilities))
540                                         break;
541                               elems->vht_capabilities = pos;
542                               break;
543                     case WLAN_EID_VHT_OPERATION:
544                               if (elen < sizeof(struct ieee80211_vht_operation))
545                                         break;
546                               elems->vht_operation = pos;
547                               break;
548                     case WLAN_EID_OPERATING_MODE_NOTIFICATION:
549                               if (elen != 1)
550                                         break;
551                               elems->opmode_notif = pos;
552                               break;
553                     case WLAN_EID_LINK_ID:
554                               if (elen < 18)
555                                         break;
556                               elems->link_id = pos;
557                               break;
558                     case WLAN_EID_INTERWORKING:
559                               elems->interworking = pos;
560                               elems->interworking_len = elen;
561                               break;
562                     case WLAN_EID_QOS_MAP_SET:
563                               if (elen < 16)
564                                         break;
565                               elems->qos_map_set = pos;
566                               elems->qos_map_set_len = elen;
567                               break;
568                     case WLAN_EID_EXT_CAPAB:
569                               elems->ext_capab = pos;
570                               elems->ext_capab_len = elen;
571                               break;
572                     case WLAN_EID_BSS_MAX_IDLE_PERIOD:
573                               if (elen < 3)
574                                         break;
575                               elems->bss_max_idle_period = pos;
576                               break;
577                     case WLAN_EID_SSID_LIST:
578                               elems->ssid_list = pos;
579                               elems->ssid_list_len = elen;
580                               break;
581                     case WLAN_EID_AMPE:
582                               elems->ampe = pos;
583                               elems->ampe_len = elen;
584                               break;
585                     case WLAN_EID_MIC:
586                               elems->mic = pos;
587                               elems->mic_len = elen;
588                               /* after mic everything is encrypted, so stop. */
589                               goto done;
590                     case WLAN_EID_MULTI_BAND:
591                               if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) {
592                                         wpa_printf(MSG_MSGDUMP,
593                                                      "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)",
594                                                      id, elen);
595                                         break;
596                               }
597 
598                               elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos;
599                               elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen;
600                               elems->mb_ies.nof_ies++;
601                               break;
602                     case WLAN_EID_SUPPORTED_OPERATING_CLASSES:
603                               elems->supp_op_classes = pos;
604                               elems->supp_op_classes_len = elen;
605                               break;
606                     case WLAN_EID_RRM_ENABLED_CAPABILITIES:
607                               elems->rrm_enabled = pos;
608                               elems->rrm_enabled_len = elen;
609                               break;
610                     case WLAN_EID_MULTIPLE_BSSID:
611                               if (elen < 1)
612                                         break;
613                               elems->mbssid = pos;
614                               elems->mbssid_len = elen;
615                               break;
616                     case WLAN_EID_CAG_NUMBER:
617                               elems->cag_number = pos;
618                               elems->cag_number_len = elen;
619                               break;
620                     case WLAN_EID_AP_CSN:
621                               if (elen < 1)
622                                         break;
623                               elems->ap_csn = pos;
624                               break;
625                     case WLAN_EID_FILS_INDICATION:
626                               if (elen < 2)
627                                         break;
628                               elems->fils_indic = pos;
629                               elems->fils_indic_len = elen;
630                               break;
631                     case WLAN_EID_DILS:
632                               if (elen < 2)
633                                         break;
634                               elems->dils = pos;
635                               elems->dils_len = elen;
636                               break;
637                     case WLAN_EID_S1G_CAPABILITIES:
638                               if (elen < 15)
639                                         break;
640                               elems->s1g_capab = pos;
641                               break;
642                     case WLAN_EID_FRAGMENT:
643                               wpa_printf(MSG_MSGDUMP,
644                                            "Fragment without a valid last element - skip");
645 
646                               break;
647                     case WLAN_EID_EXTENSION:
648                               if (ieee802_11_parse_extension(pos, elen, elems, start,
649                                                                    len, show_errors))
650                                         unknown++;
651                               break;
652                     default:
653                               unknown++;
654                               if (!show_errors)
655                                         break;
656                               wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse "
657                                            "ignored unknown element (id=%d elen=%d)",
658                                            id, elen);
659                               break;
660                     }
661 
662                     if (elen == 255 && total_len)
663                               *total_len += ieee802_11_fragments_length(
664                                         elems, pos + elen,
665                                         (start + len) - (pos + elen));
666 
667           }
668 
669           if (!for_each_element_completed(elem, start, len)) {
670                     if (show_errors) {
671                               wpa_printf(MSG_DEBUG,
672                                            "IEEE 802.11 element parse failed @%d",
673                                            (int) (start + len - (const u8 *) elem));
674                               wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
675                     }
676                     return ParseFailed;
677           }
678 
679 done:
680           return unknown ? ParseUnknown : ParseOK;
681 }
682 
683 
684 /**
685  * ieee802_11_parse_elems - Parse information elements in management frames
686  * @start: Pointer to the start of IEs
687  * @len: Length of IE buffer in octets
688  * @elems: Data structure for parsed elements
689  * @show_errors: Whether to show parsing errors in debug log
690  * Returns: Parsing result
691  */
ieee802_11_parse_elems(const u8 * start,size_t len,struct ieee802_11_elems * elems,int show_errors)692 ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
693                                         struct ieee802_11_elems *elems,
694                                         int show_errors)
695 {
696           os_memset(elems, 0, sizeof(*elems));
697 
698           return __ieee802_11_parse_elems(start, len, elems, show_errors);
699 }
700 
701 
702 /**
703  * ieee802_11_elems_clear_ids - Clear the data for the given element IDs
704  * @ids: Array of element IDs for which data should be cleared.
705  * @num: The number of entries in the array
706  */
ieee802_11_elems_clear_ids(struct ieee802_11_elems * elems,const u8 * ids,size_t num)707 void ieee802_11_elems_clear_ids(struct ieee802_11_elems *elems,
708                                         const u8 *ids, size_t num)
709 {
710           size_t i;
711 
712           for (i = 0; i < num; i++) {
713                     switch (ids[i]) {
714                     case WLAN_EID_SSID:
715                               elems->ssid = NULL;
716                               elems->ssid_len = 0;
717                               break;
718                     case WLAN_EID_SUPP_RATES:
719                               elems->supp_rates = NULL;
720                               elems->supp_rates_len = 0;
721                               break;
722                     case WLAN_EID_DS_PARAMS:
723                               elems->ds_params = NULL;
724                               break;
725                     case WLAN_EID_CHALLENGE:
726                               elems->challenge = NULL;
727                               elems->challenge_len = 0;
728                               break;
729                     case WLAN_EID_ERP_INFO:
730                               elems->erp_info = NULL;
731                               break;
732                     case WLAN_EID_EXT_SUPP_RATES:
733                               elems->ext_supp_rates = NULL;
734                               elems->ext_supp_rates_len = 0;
735                               break;
736                     case WLAN_EID_RSN:
737                               elems->rsn_ie = NULL;
738                               elems->rsn_ie_len = 0;
739                               break;
740                     case WLAN_EID_RSNX:
741                               elems->rsnxe = NULL;
742                               elems->rsnxe_len = 0;
743                               break;
744                     case WLAN_EID_PWR_CAPABILITY:
745                               elems->power_capab = NULL;
746                               elems->power_capab_len = 0;
747                               break;
748                     case WLAN_EID_SUPPORTED_CHANNELS:
749                               elems->supp_channels = NULL;
750                               elems->supp_channels_len = 0;
751                               break;
752                     case WLAN_EID_MOBILITY_DOMAIN:
753                               elems->mdie = NULL;
754                               elems->mdie_len = 0;
755                               break;
756                     case WLAN_EID_FAST_BSS_TRANSITION:
757                               elems->ftie = NULL;
758                               elems->ftie_len = 0;
759                               break;
760                     case WLAN_EID_TIMEOUT_INTERVAL:
761                               elems->timeout_int = NULL;
762                               break;
763                     case WLAN_EID_HT_CAP:
764                               elems->ht_capabilities = NULL;
765                               break;
766                     case WLAN_EID_HT_OPERATION:
767                               elems->ht_operation = NULL;
768                               break;
769                     case WLAN_EID_MESH_CONFIG:
770                               elems->mesh_config = NULL;
771                               elems->mesh_config_len = 0;
772                               break;
773                     case WLAN_EID_MESH_ID:
774                               elems->mesh_id = NULL;
775                               elems->mesh_id_len = 0;
776                               break;
777                     case WLAN_EID_PEER_MGMT:
778                               elems->peer_mgmt = NULL;
779                               elems->peer_mgmt_len = 0;
780                               break;
781                     case WLAN_EID_VHT_CAP:
782                               elems->vht_capabilities = NULL;
783                               break;
784                     case WLAN_EID_VHT_OPERATION:
785                               elems->vht_operation = NULL;
786                               break;
787                     case WLAN_EID_OPERATING_MODE_NOTIFICATION:
788                               elems->opmode_notif = NULL;
789                               break;
790                     case WLAN_EID_LINK_ID:
791                               elems->link_id = NULL;
792                               break;
793                     case WLAN_EID_INTERWORKING:
794                               elems->interworking = NULL;
795                               elems->interworking_len = 0;
796                               break;
797                     case WLAN_EID_QOS_MAP_SET:
798                               elems->qos_map_set = NULL;
799                               elems->qos_map_set_len = 0;
800                               break;
801                     case WLAN_EID_EXT_CAPAB:
802                               elems->ext_capab = NULL;
803                               elems->ext_capab_len = 0;
804                               break;
805                     case WLAN_EID_BSS_MAX_IDLE_PERIOD:
806                               elems->bss_max_idle_period = NULL;
807                               break;
808                     case WLAN_EID_SSID_LIST:
809                               elems->ssid_list = NULL;
810                               elems->ssid_list_len = 0;
811                               break;
812                     case WLAN_EID_AMPE:
813                               elems->ampe = NULL;
814                               elems->ampe_len = 0;
815                               break;
816                     case WLAN_EID_MIC:
817                               elems->mic = NULL;
818                               elems->mic_len = 0;
819                               break;
820                     case WLAN_EID_MULTI_BAND:
821                               os_memset(&elems->mb_ies, 0, sizeof(elems->mb_ies));
822                               elems->mb_ies.nof_ies = 0;
823                               break;
824                     case WLAN_EID_SUPPORTED_OPERATING_CLASSES:
825                               elems->supp_op_classes = NULL;
826                               elems->supp_op_classes_len = 0;
827                               break;
828                     case WLAN_EID_RRM_ENABLED_CAPABILITIES:
829                               elems->rrm_enabled = NULL;
830                               elems->rrm_enabled_len = 0;
831                               break;
832                     case WLAN_EID_CAG_NUMBER:
833                               elems->cag_number = NULL;
834                               elems->cag_number_len = 0;
835                               break;
836                     case WLAN_EID_AP_CSN:
837                               elems->ap_csn = NULL;
838                               break;
839                     case WLAN_EID_FILS_INDICATION:
840                               elems->fils_indic = NULL;
841                               elems->fils_indic_len = 0;
842                               break;
843                     case WLAN_EID_DILS:
844                               elems->dils = NULL;
845                               elems->dils_len = 0;
846                               break;
847                     case WLAN_EID_S1G_CAPABILITIES:
848                               elems->s1g_capab = NULL;
849                               break;
850                     }
851           }
852 }
853 
854 
855 /**
856  * ieee802_11_elems_clear_ext_ids - Clear the data for the given element
857  * extension IDs
858  * @ids: Array of element extension IDs for which data should be cleared.
859  * @num: The number of entries in the array
860  */
ieee802_11_elems_clear_ext_ids(struct ieee802_11_elems * elems,const u8 * ids,size_t num)861 void ieee802_11_elems_clear_ext_ids(struct ieee802_11_elems *elems,
862                                             const u8 *ids, size_t num)
863 {
864           size_t i;
865 
866           for (i = 0; i < num; i++) {
867                     switch (ids[i]) {
868                     case WLAN_EID_EXT_ASSOC_DELAY_INFO:
869                               elems->assoc_delay_info = NULL;
870                               break;
871                     case WLAN_EID_EXT_FILS_REQ_PARAMS:
872                               elems->fils_req_params = NULL;
873                               elems->fils_req_params_len = 0;
874                               break;
875                     case WLAN_EID_EXT_FILS_KEY_CONFIRM:
876                               elems->fils_key_confirm = NULL;
877                               elems->fils_key_confirm_len = 0;
878                               break;
879                     case WLAN_EID_EXT_FILS_SESSION:
880                               elems->fils_session = NULL;
881                               break;
882                     case WLAN_EID_EXT_FILS_HLP_CONTAINER:
883                               elems->fils_hlp = NULL;
884                               elems->fils_hlp_len = 0;
885                               break;
886                     case WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN:
887                               elems->fils_ip_addr_assign = NULL;
888                               elems->fils_ip_addr_assign_len = 0;
889                               break;
890                     case WLAN_EID_EXT_KEY_DELIVERY:
891                               elems->key_delivery = NULL;
892                               elems->key_delivery_len = 0;
893                               break;
894                     case WLAN_EID_EXT_WRAPPED_DATA:
895                               elems->wrapped_data = NULL;
896                               elems->wrapped_data_len = 0;
897                               break;
898                     case WLAN_EID_EXT_FILS_PUBLIC_KEY:
899                               elems->fils_pk = NULL;
900                               elems->fils_pk_len = 0;
901                               break;
902                     case WLAN_EID_EXT_FILS_NONCE:
903                               elems->fils_nonce = NULL;
904                               break;
905                     case WLAN_EID_EXT_OWE_DH_PARAM:
906                               elems->owe_dh = NULL;
907                               elems->owe_dh_len = 0;
908                               break;
909                     case WLAN_EID_EXT_PASSWORD_IDENTIFIER:
910                               elems->password_id = NULL;
911                               elems->password_id_len = 0;
912                               break;
913                     case WLAN_EID_EXT_HE_CAPABILITIES:
914                               elems->he_capabilities = NULL;
915                               elems->he_capabilities_len = 0;
916                               break;
917                     case WLAN_EID_EXT_HE_OPERATION:
918                               elems->he_operation = NULL;
919                               elems->he_operation_len = 0;
920                               break;
921                     case WLAN_EID_EXT_OCV_OCI:
922                               elems->oci = NULL;
923                               elems->oci_len = 0;
924                               break;
925                     case WLAN_EID_EXT_SHORT_SSID_LIST:
926                               elems->short_ssid_list = NULL;
927                               elems->short_ssid_list_len = 0;
928                               break;
929                     case WLAN_EID_EXT_HE_6GHZ_BAND_CAP:
930                               elems->he_6ghz_band_cap = NULL;
931                               break;
932                     case WLAN_EID_EXT_PASN_PARAMS:
933                               elems->pasn_params = NULL;
934                               elems->pasn_params_len = 0;
935                               break;
936                     case WLAN_EID_EXT_MULTI_LINK:
937                               elems->basic_mle = NULL;
938                               elems->probe_req_mle = NULL;
939                               elems->reconf_mle = NULL;
940                               elems->tdls_mle = NULL;
941                               elems->prior_access_mle = NULL;
942 
943                               elems->basic_mle_len = 0;
944                               elems->probe_req_mle_len = 0;
945                               elems->reconf_mle_len = 0;
946                               elems->tdls_mle_len = 0;
947                               elems->prior_access_mle_len = 0;
948                               break;
949                     case WLAN_EID_EXT_EHT_CAPABILITIES:
950                               elems->eht_capabilities = NULL;
951                               elems->eht_capabilities_len = 0;
952                               break;
953                     case WLAN_EID_EXT_EHT_OPERATION:
954                               elems->eht_operation = NULL;
955                               elems->eht_operation_len = 0;
956                               break;
957                     }
958           }
959 }
960 
961 
ieee802_11_parse_link_assoc_req(const u8 * start,size_t len,struct ieee802_11_elems * elems,struct wpabuf * mlbuf,u8 link_id,bool show_errors)962 ParseRes ieee802_11_parse_link_assoc_req(const u8 *start, size_t len,
963                                                    struct ieee802_11_elems *elems,
964                                                    struct wpabuf *mlbuf,
965                                                    u8 link_id, bool show_errors)
966 {
967           const struct ieee80211_eht_ml *ml;
968           const u8 *pos;
969           ParseRes res = ParseFailed;
970 
971           pos = wpabuf_head(mlbuf);
972           len = wpabuf_len(mlbuf);
973 
974           /* Must have control and common info length */
975           if (len < sizeof(*ml) + 1 || len < sizeof(*ml) + pos[sizeof(*ml)])
976                     goto out;
977 
978           ml = (const struct ieee80211_eht_ml *) pos;
979 
980           /* As we are interested with the Per-STA profile, ignore other types */
981           if ((le_to_host16(ml->ml_control) & MULTI_LINK_CONTROL_TYPE_MASK) !=
982                MULTI_LINK_CONTROL_TYPE_BASIC)
983                     goto out;
984 
985           /* Skip the common info */
986           len -= sizeof(*ml) + pos[sizeof(*ml)];
987           pos += sizeof(*ml) + pos[sizeof(*ml)];
988 
989           while (len > 2) {
990                     size_t sub_elem_len = *(pos + 1);
991                     size_t sta_info_len;
992                     u16 link_info_control;
993                     const u8 *non_inherit;
994 
995                     wpa_printf(MSG_DEBUG,
996                                  "MLD: sub element: len=%zu, sub_elem_len=%zu",
997                                  len, sub_elem_len);
998 
999                     if (2 + sub_elem_len > len) {
1000                               if (show_errors)
1001                                         wpa_printf(MSG_DEBUG,
1002                                                      "MLD: error: len=%zu, sub_elem_len=%zu",
1003                                                      len, sub_elem_len);
1004                               goto out;
1005                     }
1006 
1007                     if (*pos != 0) {
1008                               pos += 2 + sub_elem_len;
1009                               len -= 2 + sub_elem_len;
1010                               continue;
1011                     }
1012 
1013                     if (sub_elem_len < 5) {
1014                               if (show_errors)
1015                                         wpa_printf(MSG_DEBUG,
1016                                                      "MLD: error: sub_elem_len=%zu < 5",
1017                                                      sub_elem_len);
1018                               goto out;
1019                     }
1020 
1021                     link_info_control = WPA_GET_LE16(pos + 2);
1022                     if ((link_info_control & BASIC_MLE_STA_CTRL_LINK_ID_MASK) !=
1023                         link_id) {
1024                               pos += 2 + sub_elem_len;
1025                               len -= 2 + sub_elem_len;
1026                               continue;
1027                     }
1028 
1029                     sta_info_len = *(pos + 4);
1030                     if (sub_elem_len < sta_info_len + 3 || sta_info_len < 1) {
1031                               if (show_errors)
1032                                         wpa_printf(MSG_DEBUG,
1033                                                      "MLD: error: sub_elem_len=%zu, sta_info_len=%zu",
1034                                                      sub_elem_len, sta_info_len);
1035                               goto out;
1036                     }
1037 
1038                     pos += sta_info_len + 4;
1039                     sub_elem_len -= sta_info_len + 2;
1040 
1041                     if (sub_elem_len < 2) {
1042                               if (show_errors)
1043                                         wpa_printf(MSG_DEBUG,
1044                                                      "MLD: missing capability info");
1045                               goto out;
1046                     }
1047 
1048                     pos += 2;
1049                     sub_elem_len -= 2;
1050 
1051                     /* Handle non-inheritance */
1052                     non_inherit = get_ie_ext(pos, sub_elem_len,
1053                                                    WLAN_EID_EXT_NON_INHERITANCE);
1054                     if (non_inherit && non_inherit[1] > 1) {
1055                               u8 non_inherit_len = non_inherit[1] - 1;
1056 
1057                               /*
1058                                * Do not include the Non-Inheritance element when
1059                                * parsing below. It should be the last element in the
1060                                * subelement.
1061                                */
1062                               if (3U + non_inherit_len > sub_elem_len)
1063                                         goto out;
1064                               sub_elem_len -= 3 + non_inherit_len;
1065 
1066                               /* Skip the ID, length and extension ID */
1067                               non_inherit += 3;
1068 
1069                               if (non_inherit_len < 1UL + non_inherit[0]) {
1070                                         if (show_errors)
1071                                                   wpa_printf(MSG_DEBUG,
1072                                                                "MLD: Invalid inheritance");
1073                                         goto out;
1074                               }
1075 
1076                               ieee802_11_elems_clear_ids(elems, &non_inherit[1],
1077                                                                non_inherit[0]);
1078 
1079                               non_inherit_len -= 1 + non_inherit[0];
1080                               non_inherit += 1 + non_inherit[0];
1081 
1082                               if (non_inherit_len < 1UL ||
1083                                   non_inherit_len < 1UL + non_inherit[0]) {
1084                                         if (show_errors)
1085                                                   wpa_printf(MSG_DEBUG,
1086                                                                "MLD: Invalid inheritance");
1087                                         goto out;
1088                               }
1089 
1090                               ieee802_11_elems_clear_ext_ids(elems, &non_inherit[1],
1091                                                                    non_inherit[0]);
1092                     }
1093 
1094                     wpa_printf(MSG_DEBUG, "MLD: link: sub_elem_len=%zu",
1095                                  sub_elem_len);
1096 
1097                     if (sub_elem_len)
1098                               res = __ieee802_11_parse_elems(pos, sub_elem_len,
1099                                                                    elems, show_errors);
1100                     else
1101                               res = ParseOK;
1102                     break;
1103           }
1104 
1105 out:
1106           return res;
1107 }
1108 
1109 
ieee802_11_ie_count(const u8 * ies,size_t ies_len)1110 int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
1111 {
1112           const struct element *elem;
1113           int count = 0;
1114 
1115           if (ies == NULL)
1116                     return 0;
1117 
1118           for_each_element(elem, ies, ies_len)
1119                     count++;
1120 
1121           return count;
1122 }
1123 
1124 
ieee802_11_vendor_ie_concat(const u8 * ies,size_t ies_len,u32 oui_type)1125 struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
1126                                                       u32 oui_type)
1127 {
1128           struct wpabuf *buf;
1129           const struct element *elem, *found = NULL;
1130 
1131           for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) {
1132                     if (elem->datalen >= 4 &&
1133                         WPA_GET_BE32(elem->data) == oui_type) {
1134                               found = elem;
1135                               break;
1136                     }
1137           }
1138 
1139           if (!found)
1140                     return NULL; /* No specified vendor IE found */
1141 
1142           buf = wpabuf_alloc(ies_len);
1143           if (buf == NULL)
1144                     return NULL;
1145 
1146           /*
1147            * There may be multiple vendor IEs in the message, so need to
1148            * concatenate their data fields.
1149            */
1150           for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) {
1151                     if (elem->datalen >= 4 && WPA_GET_BE32(elem->data) == oui_type)
1152                               wpabuf_put_data(buf, elem->data + 4, elem->datalen - 4);
1153           }
1154 
1155           return buf;
1156 }
1157 
1158 
get_hdr_bssid(const struct ieee80211_hdr * hdr,size_t len)1159 const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
1160 {
1161           u16 fc, type, stype;
1162 
1163           /*
1164            * PS-Poll frames are 16 bytes. All other frames are
1165            * 24 bytes or longer.
1166            */
1167           if (len < 16)
1168                     return NULL;
1169 
1170           fc = le_to_host16(hdr->frame_control);
1171           type = WLAN_FC_GET_TYPE(fc);
1172           stype = WLAN_FC_GET_STYPE(fc);
1173 
1174           switch (type) {
1175           case WLAN_FC_TYPE_DATA:
1176                     if (len < 24)
1177                               return NULL;
1178                     switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
1179                     case WLAN_FC_FROMDS | WLAN_FC_TODS:
1180                     case WLAN_FC_TODS:
1181                               return hdr->addr1;
1182                     case WLAN_FC_FROMDS:
1183                               return hdr->addr2;
1184                     default:
1185                               return NULL;
1186                     }
1187           case WLAN_FC_TYPE_CTRL:
1188                     if (stype != WLAN_FC_STYPE_PSPOLL)
1189                               return NULL;
1190                     return hdr->addr1;
1191           case WLAN_FC_TYPE_MGMT:
1192                     return hdr->addr3;
1193           default:
1194                     return NULL;
1195           }
1196 }
1197 
1198 
hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],const char * name,const char * val)1199 int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
1200                                 const char *name, const char *val)
1201 {
1202           int num, v;
1203           const char *pos;
1204           struct hostapd_wmm_ac_params *ac;
1205 
1206           /* skip 'wme_ac_' or 'wmm_ac_' prefix */
1207           pos = name + 7;
1208           if (os_strncmp(pos, "be_", 3) == 0) {
1209                     num = 0;
1210                     pos += 3;
1211           } else if (os_strncmp(pos, "bk_", 3) == 0) {
1212                     num = 1;
1213                     pos += 3;
1214           } else if (os_strncmp(pos, "vi_", 3) == 0) {
1215                     num = 2;
1216                     pos += 3;
1217           } else if (os_strncmp(pos, "vo_", 3) == 0) {
1218                     num = 3;
1219                     pos += 3;
1220           } else {
1221                     wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos);
1222                     return -1;
1223           }
1224 
1225           ac = &wmm_ac_params[num];
1226 
1227           if (os_strcmp(pos, "aifs") == 0) {
1228                     v = atoi(val);
1229                     if (v < 1 || v > 255) {
1230                               wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v);
1231                               return -1;
1232                     }
1233                     ac->aifs = v;
1234           } else if (os_strcmp(pos, "cwmin") == 0) {
1235                     v = atoi(val);
1236                     if (v < 0 || v > 15) {
1237                               wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v);
1238                               return -1;
1239                     }
1240                     ac->cwmin = v;
1241           } else if (os_strcmp(pos, "cwmax") == 0) {
1242                     v = atoi(val);
1243                     if (v < 0 || v > 15) {
1244                               wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v);
1245                               return -1;
1246                     }
1247                     ac->cwmax = v;
1248           } else if (os_strcmp(pos, "txop_limit") == 0) {
1249                     v = atoi(val);
1250                     if (v < 0 || v > 0xffff) {
1251                               wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
1252                               return -1;
1253                     }
1254                     ac->txop_limit = v;
1255           } else if (os_strcmp(pos, "acm") == 0) {
1256                     v = atoi(val);
1257                     if (v < 0 || v > 1) {
1258                               wpa_printf(MSG_ERROR, "Invalid acm value %d", v);
1259                               return -1;
1260                     }
1261                     ac->admission_control_mandatory = v;
1262           } else {
1263                     wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos);
1264                     return -1;
1265           }
1266 
1267           return 0;
1268 }
1269 
1270 
1271 /* convert floats with one decimal place to value*10 int, i.e.,
1272  * "1.5" will return 15
1273  */
hostapd_config_read_int10(const char * value)1274 static int hostapd_config_read_int10(const char *value)
1275 {
1276           int i, d;
1277           char *pos;
1278 
1279           i = atoi(value);
1280           pos = os_strchr(value, '.');
1281           d = 0;
1282           if (pos) {
1283                     pos++;
1284                     if (*pos >= '0' && *pos <= '9')
1285                               d = *pos - '0';
1286           }
1287 
1288           return i * 10 + d;
1289 }
1290 
1291 
valid_cw(int cw)1292 static int valid_cw(int cw)
1293 {
1294           return (cw == 1 || cw == 3 || cw == 7 || cw == 15 || cw == 31 ||
1295                     cw == 63 || cw == 127 || cw == 255 || cw == 511 || cw == 1023 ||
1296                     cw == 2047 || cw == 4095 || cw == 8191 || cw == 16383 ||
1297                     cw == 32767);
1298 }
1299 
1300 
hostapd_config_tx_queue(struct hostapd_tx_queue_params tx_queue[],const char * name,const char * val)1301 int hostapd_config_tx_queue(struct hostapd_tx_queue_params tx_queue[],
1302                                   const char *name, const char *val)
1303 {
1304           int num;
1305           const char *pos;
1306           struct hostapd_tx_queue_params *queue;
1307 
1308           /* skip 'tx_queue_' prefix */
1309           pos = name + 9;
1310           if (os_strncmp(pos, "data", 4) == 0 &&
1311               pos[4] >= '0' && pos[4] <= '9' && pos[5] == '_') {
1312                     num = pos[4] - '0';
1313                     pos += 6;
1314           } else if (os_strncmp(pos, "after_beacon_", 13) == 0 ||
1315                        os_strncmp(pos, "beacon_", 7) == 0) {
1316                     wpa_printf(MSG_INFO, "DEPRECATED: '%s' not used", name);
1317                     return 0;
1318           } else {
1319                     wpa_printf(MSG_ERROR, "Unknown tx_queue name '%s'", pos);
1320                     return -1;
1321           }
1322 
1323           if (num >= NUM_TX_QUEUES) {
1324                     /* for backwards compatibility, do not trigger failure */
1325                     wpa_printf(MSG_INFO, "DEPRECATED: '%s' not used", name);
1326                     return 0;
1327           }
1328 
1329           queue = &tx_queue[num];
1330 
1331           if (os_strcmp(pos, "aifs") == 0) {
1332                     queue->aifs = atoi(val);
1333                     if (queue->aifs < 0 || queue->aifs > 255) {
1334                               wpa_printf(MSG_ERROR, "Invalid AIFS value %d",
1335                                            queue->aifs);
1336                               return -1;
1337                     }
1338           } else if (os_strcmp(pos, "cwmin") == 0) {
1339                     queue->cwmin = atoi(val);
1340                     if (!valid_cw(queue->cwmin)) {
1341                               wpa_printf(MSG_ERROR, "Invalid cwMin value %d",
1342                                            queue->cwmin);
1343                               return -1;
1344                     }
1345           } else if (os_strcmp(pos, "cwmax") == 0) {
1346                     queue->cwmax = atoi(val);
1347                     if (!valid_cw(queue->cwmax)) {
1348                               wpa_printf(MSG_ERROR, "Invalid cwMax value %d",
1349                                            queue->cwmax);
1350                               return -1;
1351                     }
1352           } else if (os_strcmp(pos, "burst") == 0) {
1353                     queue->burst = hostapd_config_read_int10(val);
1354           } else {
1355                     wpa_printf(MSG_ERROR, "Unknown queue field '%s'", pos);
1356                     return -1;
1357           }
1358 
1359           return 0;
1360 }
1361 
1362 
ieee80211_freq_to_chan(int freq,u8 * channel)1363 enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel)
1364 {
1365           u8 op_class;
1366 
1367           return ieee80211_freq_to_channel_ext(freq, 0, CONF_OPER_CHWIDTH_USE_HT,
1368                                                        &op_class, channel);
1369 }
1370 
1371 
1372 /**
1373  * ieee80211_freq_to_channel_ext - Convert frequency into channel info
1374  * for HT40, VHT, and HE. DFS channels are not covered.
1375  * @freq: Frequency (MHz) to convert
1376  * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
1377  * @chanwidth: VHT/EDMG/etc. channel width
1378  * @op_class: Buffer for returning operating class
1379  * @channel: Buffer for returning channel number
1380  * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
1381  */
1382 enum hostapd_hw_mode
ieee80211_freq_to_channel_ext(unsigned int freq,int sec_channel,enum oper_chan_width chanwidth,u8 * op_class,u8 * channel)1383 ieee80211_freq_to_channel_ext(unsigned int freq, int sec_channel,
1384                                     enum oper_chan_width chanwidth,
1385                                     u8 *op_class, u8 *channel)
1386 {
1387           u8 vht_opclass;
1388 
1389           /* TODO: more operating classes */
1390 
1391           if (sec_channel > 1 || sec_channel < -1)
1392                     return NUM_HOSTAPD_MODES;
1393 
1394           if (freq >= 2412 && freq <= 2472) {
1395                     if ((freq - 2407) % 5)
1396                               return NUM_HOSTAPD_MODES;
1397 
1398                     if (chanwidth)
1399                               return NUM_HOSTAPD_MODES;
1400 
1401                     /* 2.407 GHz, channels 1..13 */
1402                     if (sec_channel == 1)
1403                               *op_class = 83;
1404                     else if (sec_channel == -1)
1405                               *op_class = 84;
1406                     else
1407                               *op_class = 81;
1408 
1409                     *channel = (freq - 2407) / 5;
1410 
1411                     return HOSTAPD_MODE_IEEE80211G;
1412           }
1413 
1414           if (freq == 2484) {
1415                     if (sec_channel || chanwidth)
1416                               return NUM_HOSTAPD_MODES;
1417 
1418                     *op_class = 82; /* channel 14 */
1419                     *channel = 14;
1420 
1421                     return HOSTAPD_MODE_IEEE80211B;
1422           }
1423 
1424           if (freq >= 4900 && freq < 5000) {
1425                     if ((freq - 4000) % 5)
1426                               return NUM_HOSTAPD_MODES;
1427                     *channel = (freq - 4000) / 5;
1428                     *op_class = 0; /* TODO */
1429                     return HOSTAPD_MODE_IEEE80211A;
1430           }
1431 
1432           switch (chanwidth) {
1433           case CONF_OPER_CHWIDTH_80MHZ:
1434                     vht_opclass = 128;
1435                     break;
1436           case CONF_OPER_CHWIDTH_160MHZ:
1437                     vht_opclass = 129;
1438                     break;
1439           case CONF_OPER_CHWIDTH_80P80MHZ:
1440                     vht_opclass = 130;
1441                     break;
1442           default:
1443                     vht_opclass = 0;
1444                     break;
1445           }
1446 
1447           /* 5 GHz, channels 36..48 */
1448           if (freq >= 5180 && freq <= 5240) {
1449                     if ((freq - 5000) % 5)
1450                               return NUM_HOSTAPD_MODES;
1451 
1452                     if (vht_opclass)
1453                               *op_class = vht_opclass;
1454                     else if (sec_channel == 1)
1455                               *op_class = 116;
1456                     else if (sec_channel == -1)
1457                               *op_class = 117;
1458                     else
1459                               *op_class = 115;
1460 
1461                     *channel = (freq - 5000) / 5;
1462 
1463                     return HOSTAPD_MODE_IEEE80211A;
1464           }
1465 
1466           /* 5 GHz, channels 52..64 */
1467           if (freq >= 5260 && freq <= 5320) {
1468                     if ((freq - 5000) % 5)
1469                               return NUM_HOSTAPD_MODES;
1470 
1471                     if (vht_opclass)
1472                               *op_class = vht_opclass;
1473                     else if (sec_channel == 1)
1474                               *op_class = 119;
1475                     else if (sec_channel == -1)
1476                               *op_class = 120;
1477                     else
1478                               *op_class = 118;
1479 
1480                     *channel = (freq - 5000) / 5;
1481 
1482                     return HOSTAPD_MODE_IEEE80211A;
1483           }
1484 
1485           /* 5 GHz, channels 149..177 */
1486           if (freq >= 5745 && freq <= 5885) {
1487                     if ((freq - 5000) % 5)
1488                               return NUM_HOSTAPD_MODES;
1489 
1490                     if (vht_opclass)
1491                               *op_class = vht_opclass;
1492                     else if (sec_channel == 1)
1493                               *op_class = 126;
1494                     else if (sec_channel == -1)
1495                               *op_class = 127;
1496                     else
1497                               *op_class = 125;
1498 
1499                     *channel = (freq - 5000) / 5;
1500 
1501                     return HOSTAPD_MODE_IEEE80211A;
1502           }
1503 
1504           /* 5 GHz, channels 100..144 */
1505           if (freq >= 5500 && freq <= 5720) {
1506                     if ((freq - 5000) % 5)
1507                               return NUM_HOSTAPD_MODES;
1508 
1509                     if (vht_opclass)
1510                               *op_class = vht_opclass;
1511                     else if (sec_channel == 1)
1512                               *op_class = 122;
1513                     else if (sec_channel == -1)
1514                               *op_class = 123;
1515                     else
1516                               *op_class = 121;
1517 
1518                     *channel = (freq - 5000) / 5;
1519 
1520                     return HOSTAPD_MODE_IEEE80211A;
1521           }
1522 
1523           if (freq >= 5000 && freq < 5900) {
1524                     if ((freq - 5000) % 5)
1525                               return NUM_HOSTAPD_MODES;
1526                     *channel = (freq - 5000) / 5;
1527                     *op_class = 0; /* TODO */
1528                     return HOSTAPD_MODE_IEEE80211A;
1529           }
1530 
1531           if (freq > 5950 && freq <= 7115) {
1532                     if ((freq - 5950) % 5)
1533                               return NUM_HOSTAPD_MODES;
1534 
1535                     switch (chanwidth) {
1536                     case CONF_OPER_CHWIDTH_80MHZ:
1537                               *op_class = 133;
1538                               break;
1539                     case CONF_OPER_CHWIDTH_160MHZ:
1540                               *op_class = 134;
1541                               break;
1542                     case CONF_OPER_CHWIDTH_80P80MHZ:
1543                               *op_class = 135;
1544                               break;
1545                     case CONF_OPER_CHWIDTH_320MHZ:
1546                               *op_class = 137;
1547                               break;
1548                     default:
1549                               if (sec_channel)
1550                                         *op_class = 132;
1551                               else
1552                                         *op_class = 131;
1553                               break;
1554                     }
1555 
1556                     *channel = (freq - 5950) / 5;
1557                     return HOSTAPD_MODE_IEEE80211A;
1558           }
1559 
1560           if (freq == 5935) {
1561                     *op_class = 136;
1562                     *channel = (freq - 5925) / 5;
1563                     return HOSTAPD_MODE_IEEE80211A;
1564           }
1565 
1566           /* 56.16 GHz, channel 1..6 */
1567           if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 6) {
1568                     if (sec_channel)
1569                               return NUM_HOSTAPD_MODES;
1570 
1571                     switch (chanwidth) {
1572                     case CONF_OPER_CHWIDTH_USE_HT:
1573                     case CONF_OPER_CHWIDTH_2160MHZ:
1574                               *channel = (freq - 56160) / 2160;
1575                               *op_class = 180;
1576                               break;
1577                     case CONF_OPER_CHWIDTH_4320MHZ:
1578                               /* EDMG channels 9 - 13 */
1579                               if (freq > 56160 + 2160 * 5)
1580                                         return NUM_HOSTAPD_MODES;
1581 
1582                               *channel = (freq - 56160) / 2160 + 8;
1583                               *op_class = 181;
1584                               break;
1585                     case CONF_OPER_CHWIDTH_6480MHZ:
1586                               /* EDMG channels 17 - 20 */
1587                               if (freq > 56160 + 2160 * 4)
1588                                         return NUM_HOSTAPD_MODES;
1589 
1590                               *channel = (freq - 56160) / 2160 + 16;
1591                               *op_class = 182;
1592                               break;
1593                     case CONF_OPER_CHWIDTH_8640MHZ:
1594                               /* EDMG channels 25 - 27 */
1595                               if (freq > 56160 + 2160 * 3)
1596                                         return NUM_HOSTAPD_MODES;
1597 
1598                               *channel = (freq - 56160) / 2160 + 24;
1599                               *op_class = 183;
1600                               break;
1601                     default:
1602                               return NUM_HOSTAPD_MODES;
1603                     }
1604 
1605                     return HOSTAPD_MODE_IEEE80211AD;
1606           }
1607 
1608           return NUM_HOSTAPD_MODES;
1609 }
1610 
1611 
ieee80211_chaninfo_to_channel(unsigned int freq,enum chan_width chanwidth,int sec_channel,u8 * op_class,u8 * channel)1612 int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
1613                                           int sec_channel, u8 *op_class, u8 *channel)
1614 {
1615           int cw = CHAN_WIDTH_UNKNOWN;
1616 
1617           switch (chanwidth) {
1618           case CHAN_WIDTH_UNKNOWN:
1619           case CHAN_WIDTH_20_NOHT:
1620           case CHAN_WIDTH_20:
1621           case CHAN_WIDTH_40:
1622                     cw = CONF_OPER_CHWIDTH_USE_HT;
1623                     break;
1624           case CHAN_WIDTH_80:
1625                     cw = CONF_OPER_CHWIDTH_80MHZ;
1626                     break;
1627           case CHAN_WIDTH_80P80:
1628                     cw = CONF_OPER_CHWIDTH_80P80MHZ;
1629                     break;
1630           case CHAN_WIDTH_160:
1631                     cw = CONF_OPER_CHWIDTH_160MHZ;
1632                     break;
1633           case CHAN_WIDTH_2160:
1634                     cw = CONF_OPER_CHWIDTH_2160MHZ;
1635                     break;
1636           case CHAN_WIDTH_4320:
1637                     cw = CONF_OPER_CHWIDTH_4320MHZ;
1638                     break;
1639           case CHAN_WIDTH_6480:
1640                     cw = CONF_OPER_CHWIDTH_6480MHZ;
1641                     break;
1642           case CHAN_WIDTH_8640:
1643                     cw = CONF_OPER_CHWIDTH_8640MHZ;
1644                     break;
1645           case CHAN_WIDTH_320:
1646                     cw = CONF_OPER_CHWIDTH_320MHZ;
1647                     break;
1648           }
1649 
1650           if (ieee80211_freq_to_channel_ext(freq, sec_channel, cw, op_class,
1651                                                     channel) == NUM_HOSTAPD_MODES) {
1652                     wpa_printf(MSG_WARNING,
1653                                  "Cannot determine operating class and channel (freq=%u chanwidth=%d sec_channel=%d)",
1654                                  freq, chanwidth, sec_channel);
1655                     return -1;
1656           }
1657 
1658           return 0;
1659 }
1660 
1661 
1662 static const char *const us_op_class_cc[] = {
1663           "US", "CA", NULL
1664 };
1665 
1666 static const char *const eu_op_class_cc[] = {
1667           "AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
1668           "DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
1669           "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
1670           "RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL
1671 };
1672 
1673 static const char *const jp_op_class_cc[] = {
1674           "JP", NULL
1675 };
1676 
1677 static const char *const cn_op_class_cc[] = {
1678           "CN", NULL
1679 };
1680 
1681 
country_match(const char * const cc[],const char * const country)1682 static int country_match(const char *const cc[], const char *const country)
1683 {
1684           int i;
1685 
1686           if (country == NULL)
1687                     return 0;
1688           for (i = 0; cc[i]; i++) {
1689                     if (cc[i][0] == country[0] && cc[i][1] == country[1])
1690                               return 1;
1691           }
1692 
1693           return 0;
1694 }
1695 
1696 
ieee80211_chan_to_freq_us(u8 op_class,u8 chan)1697 static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan)
1698 {
1699           switch (op_class) {
1700           case 12: /* channels 1..11 */
1701           case 32: /* channels 1..7; 40 MHz */
1702           case 33: /* channels 5..11; 40 MHz */
1703                     if (chan < 1 || chan > 11)
1704                               return -1;
1705                     return 2407 + 5 * chan;
1706           case 1: /* channels 36,40,44,48 */
1707           case 2: /* channels 52,56,60,64; dfs */
1708           case 22: /* channels 36,44; 40 MHz */
1709           case 23: /* channels 52,60; 40 MHz */
1710           case 27: /* channels 40,48; 40 MHz */
1711           case 28: /* channels 56,64; 40 MHz */
1712                     if (chan < 36 || chan > 64)
1713                               return -1;
1714                     return 5000 + 5 * chan;
1715           case 4: /* channels 100-144 */
1716           case 24: /* channels 100-140; 40 MHz */
1717                     if (chan < 100 || chan > 144)
1718                               return -1;
1719                     return 5000 + 5 * chan;
1720           case 3: /* channels 149,153,157,161 */
1721           case 25: /* channels 149,157; 40 MHz */
1722           case 26: /* channels 149,157; 40 MHz */
1723           case 30: /* channels 153,161; 40 MHz */
1724           case 31: /* channels 153,161; 40 MHz */
1725                     if (chan < 149 || chan > 161)
1726                               return -1;
1727                     return 5000 + 5 * chan;
1728           case 5: /* channels 149,153,157,161,165 */
1729                     if (chan < 149 || chan > 165)
1730                               return -1;
1731                     return 5000 + 5 * chan;
1732           case 34: /* 60 GHz band, channels 1..8 */
1733                     if (chan < 1 || chan > 8)
1734                               return -1;
1735                     return 56160 + 2160 * chan;
1736           case 37: /* 60 GHz band, EDMG CB2, channels 9..15 */
1737                     if (chan < 9 || chan > 15)
1738                               return -1;
1739                     return 56160 + 2160 * (chan - 8);
1740           case 38: /* 60 GHz band, EDMG CB3, channels 17..22 */
1741                     if (chan < 17 || chan > 22)
1742                               return -1;
1743                     return 56160 + 2160 * (chan - 16);
1744           case 39: /* 60 GHz band, EDMG CB4, channels 25..29 */
1745                     if (chan < 25 || chan > 29)
1746                               return -1;
1747                     return 56160 + 2160 * (chan - 24);
1748           default:
1749                     return -1;
1750           }
1751 }
1752 
1753 
ieee80211_chan_to_freq_eu(u8 op_class,u8 chan)1754 static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan)
1755 {
1756           switch (op_class) {
1757           case 4: /* channels 1..13 */
1758           case 11: /* channels 1..9; 40 MHz */
1759           case 12: /* channels 5..13; 40 MHz */
1760                     if (chan < 1 || chan > 13)
1761                               return -1;
1762                     return 2407 + 5 * chan;
1763           case 1: /* channels 36,40,44,48 */
1764           case 2: /* channels 52,56,60,64; dfs */
1765           case 5: /* channels 36,44; 40 MHz */
1766           case 6: /* channels 52,60; 40 MHz */
1767           case 8: /* channels 40,48; 40 MHz */
1768           case 9: /* channels 56,64; 40 MHz */
1769                     if (chan < 36 || chan > 64)
1770                               return -1;
1771                     return 5000 + 5 * chan;
1772           case 3: /* channels 100-140 */
1773           case 7: /* channels 100-132; 40 MHz */
1774           case 10: /* channels 104-136; 40 MHz */
1775           case 16: /* channels 100-140 */
1776                     if (chan < 100 || chan > 140)
1777                               return -1;
1778                     return 5000 + 5 * chan;
1779           case 17: /* channels 149,153,157,161,165,169 */
1780                     if (chan < 149 || chan > 169)
1781                               return -1;
1782                     return 5000 + 5 * chan;
1783           case 18: /* 60 GHz band, channels 1..6 */
1784                     if (chan < 1 || chan > 6)
1785                               return -1;
1786                     return 56160 + 2160 * chan;
1787           case 21: /* 60 GHz band, EDMG CB2, channels 9..11 */
1788                     if (chan < 9 || chan > 11)
1789                               return -1;
1790                     return 56160 + 2160 * (chan - 8);
1791           case 22: /* 60 GHz band, EDMG CB3, channels 17..18 */
1792                     if (chan < 17 || chan > 18)
1793                               return -1;
1794                     return 56160 + 2160 * (chan - 16);
1795           case 23: /* 60 GHz band, EDMG CB4, channels 25 */
1796                     if (chan != 25)
1797                               return -1;
1798                     return 56160 + 2160 * (chan - 24);
1799           default:
1800                     return -1;
1801           }
1802 }
1803 
1804 
ieee80211_chan_to_freq_jp(u8 op_class,u8 chan)1805 static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan)
1806 {
1807           /* Table E-3 in IEEE Std 802.11-2020 - Operating classes in Japan */
1808           switch (op_class) {
1809           case 30: /* channels 1..13 */
1810           case 56: /* channels 1..9; 40 MHz */
1811           case 57: /* channels 5..13; 40 MHz */
1812                     if (chan < 1 || chan > 13)
1813                               return -1;
1814                     return 2407 + 5 * chan;
1815           case 31: /* channel 14 */
1816                     if (chan != 14)
1817                               return -1;
1818                     return 2414 + 5 * chan;
1819           case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */
1820           case 32: /* channels 52,56,60,64 */
1821           case 33: /* channels 52,56,60,64 */
1822           case 36: /* channels 36,44; 40 MHz */
1823           case 37: /* channels 52,60; 40 MHz */
1824           case 38: /* channels 52,60; 40 MHz */
1825           case 41: /* channels 40,48; 40 MHz */
1826           case 42: /* channels 56,64; 40 MHz */
1827           case 43: /* channels 56,64; 40 MHz */
1828                     if (chan < 34 || chan > 64)
1829                               return -1;
1830                     return 5000 + 5 * chan;
1831           case 34: /* channels 100-144 */
1832           case 35: /* reserved */
1833           case 39: /* channels 100-140; 40 MHz */
1834           case 40: /* reserved */
1835           case 44: /* channels 104-144; 40 MHz */
1836           case 45: /* reserved */
1837           case 58: /* channels 100-144 */
1838                     if (chan < 100 || chan > 144)
1839                               return -1;
1840                     return 5000 + 5 * chan;
1841           case 59: /* 60 GHz band, channels 1..6 */
1842                     if (chan < 1 || chan > 6)
1843                               return -1;
1844                     return 56160 + 2160 * chan;
1845           case 62: /* 60 GHz band, EDMG CB2, channels 9..11 */
1846                     if (chan < 9 || chan > 11)
1847                               return -1;
1848                     return 56160 + 2160 * (chan - 8);
1849           case 63: /* 60 GHz band, EDMG CB3, channels 17..18 */
1850                     if (chan < 17 || chan > 18)
1851                               return -1;
1852                     return 56160 + 2160 * (chan - 16);
1853           case 64: /* 60 GHz band, EDMG CB4, channel 25 */
1854                     if (chan != 25)
1855                               return -1;
1856                     return 56160 + 2160 * (chan - 24);
1857           default:
1858                     return -1;
1859           }
1860 }
1861 
1862 
ieee80211_chan_to_freq_cn(u8 op_class,u8 chan)1863 static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan)
1864 {
1865           switch (op_class) {
1866           case 7: /* channels 1..13 */
1867           case 8: /* channels 1..9; 40 MHz */
1868           case 9: /* channels 5..13; 40 MHz */
1869                     if (chan < 1 || chan > 13)
1870                               return -1;
1871                     return 2407 + 5 * chan;
1872           case 1: /* channels 36,40,44,48 */
1873           case 2: /* channels 52,56,60,64; dfs */
1874           case 4: /* channels 36,44; 40 MHz */
1875           case 5: /* channels 52,60; 40 MHz */
1876                     if (chan < 36 || chan > 64)
1877                               return -1;
1878                     return 5000 + 5 * chan;
1879           case 3: /* channels 149,153,157,161,165 */
1880           case 6: /* channels 149,157; 40 MHz */
1881                     if (chan < 149 || chan > 165)
1882                               return -1;
1883                     return 5000 + 5 * chan;
1884           default:
1885                     return -1;
1886           }
1887 }
1888 
1889 
ieee80211_chan_to_freq_global(u8 op_class,u8 chan)1890 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
1891 {
1892           /* Table E-4 in IEEE Std 802.11-2020 - Global operating classes */
1893           switch (op_class) {
1894           case 81:
1895                     /* channels 1..13 */
1896                     if (chan < 1 || chan > 13)
1897                               return -1;
1898                     return 2407 + 5 * chan;
1899           case 82:
1900                     /* channel 14 */
1901                     if (chan != 14)
1902                               return -1;
1903                     return 2414 + 5 * chan;
1904           case 83: /* channels 1..9; 40 MHz */
1905           case 84: /* channels 5..13; 40 MHz */
1906                     if (chan < 1 || chan > 13)
1907                               return -1;
1908                     return 2407 + 5 * chan;
1909           case 115: /* channels 36,40,44,48; indoor only */
1910           case 116: /* channels 36,44; 40 MHz; indoor only */
1911           case 117: /* channels 40,48; 40 MHz; indoor only */
1912           case 118: /* channels 52,56,60,64; dfs */
1913           case 119: /* channels 52,60; 40 MHz; dfs */
1914           case 120: /* channels 56,64; 40 MHz; dfs */
1915                     if (chan < 36 || chan > 64)
1916                               return -1;
1917                     return 5000 + 5 * chan;
1918           case 121: /* channels 100-144 */
1919           case 122: /* channels 100-140; 40 MHz */
1920           case 123: /* channels 104-144; 40 MHz */
1921                     if (chan < 100 || chan > 144)
1922                               return -1;
1923                     return 5000 + 5 * chan;
1924           case 124: /* channels 149,153,157,161 */
1925                     if (chan < 149 || chan > 161)
1926                               return -1;
1927                     return 5000 + 5 * chan;
1928           case 125: /* channels 149,153,157,161,165,169,173,177 */
1929           case 126: /* channels 149,157,165,173; 40 MHz */
1930           case 127: /* channels 153,161,169,177; 40 MHz */
1931                     if (chan < 149 || chan > 177)
1932                               return -1;
1933                     return 5000 + 5 * chan;
1934           case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
1935           case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
1936                     if (chan < 36 || chan > 177)
1937                               return -1;
1938                     return 5000 + 5 * chan;
1939           case 129: /* center freqs 50, 114, 163; 160 MHz */
1940                     if (chan < 36 || chan > 177)
1941                               return -1;
1942                     return 5000 + 5 * chan;
1943           case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
1944           case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
1945           case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
1946           case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
1947           case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
1948           case 137: /* UHB channels, 320 MHz: 31, 63, 95, 127, 159, 191 */
1949                     if (chan < 1 || chan > 233)
1950                               return -1;
1951                     return 5950 + chan * 5;
1952           case 136: /* UHB channels, 20 MHz: 2 */
1953                     if (chan == 2)
1954                               return 5935;
1955                     return -1;
1956           case 180: /* 60 GHz band, channels 1..8 */
1957                     if (chan < 1 || chan > 8)
1958                               return -1;
1959                     return 56160 + 2160 * chan;
1960           case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
1961                     if (chan < 9 || chan > 15)
1962                               return -1;
1963                     return 56160 + 2160 * (chan - 8);
1964           case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
1965                     if (chan < 17 || chan > 22)
1966                               return -1;
1967                     return 56160 + 2160 * (chan - 16);
1968           case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
1969                     if (chan < 25 || chan > 29)
1970                               return -1;
1971                     return 56160 + 2160 * (chan - 24);
1972           default:
1973                     return -1;
1974           }
1975 }
1976 
1977 /**
1978  * ieee80211_chan_to_freq - Convert channel info to frequency
1979  * @country: Country code, if known; otherwise, global operating class is used
1980  * @op_class: Operating class
1981  * @chan: Channel number
1982  * Returns: Frequency in MHz or -1 if the specified channel is unknown
1983  */
ieee80211_chan_to_freq(const char * country,u8 op_class,u8 chan)1984 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan)
1985 {
1986           int freq;
1987 
1988           if (country_match(us_op_class_cc, country)) {
1989                     freq = ieee80211_chan_to_freq_us(op_class, chan);
1990                     if (freq > 0)
1991                               return freq;
1992           }
1993 
1994           if (country_match(eu_op_class_cc, country)) {
1995                     freq = ieee80211_chan_to_freq_eu(op_class, chan);
1996                     if (freq > 0)
1997                               return freq;
1998           }
1999 
2000           if (country_match(jp_op_class_cc, country)) {
2001                     freq = ieee80211_chan_to_freq_jp(op_class, chan);
2002                     if (freq > 0)
2003                               return freq;
2004           }
2005 
2006           if (country_match(cn_op_class_cc, country)) {
2007                     freq = ieee80211_chan_to_freq_cn(op_class, chan);
2008                     if (freq > 0)
2009                               return freq;
2010           }
2011 
2012           return ieee80211_chan_to_freq_global(op_class, chan);
2013 }
2014 
2015 
ieee80211_is_dfs(int freq,const struct hostapd_hw_modes * modes,u16 num_modes)2016 int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
2017                          u16 num_modes)
2018 {
2019           int i, j;
2020 
2021           if (!modes || !num_modes)
2022                     return (freq >= 5260 && freq <= 5320) ||
2023                               (freq >= 5500 && freq <= 5720);
2024 
2025           for (i = 0; i < num_modes; i++) {
2026                     for (j = 0; j < modes[i].num_channels; j++) {
2027                               if (modes[i].channels[j].freq == freq &&
2028                                   (modes[i].channels[j].flag & HOSTAPD_CHAN_RADAR))
2029                                         return 1;
2030                     }
2031           }
2032 
2033           return 0;
2034 }
2035 
2036 
2037 /*
2038  * 802.11-2020: Table E-4 - Global operating classes
2039  * DFS_50_100_Behavior: 118, 119, 120, 121, 122, 123
2040  */
is_dfs_global_op_class(u8 op_class)2041 int is_dfs_global_op_class(u8 op_class)
2042 {
2043     return (op_class >= 118) && (op_class <= 123);
2044 }
2045 
2046 
is_80plus_op_class(u8 op_class)2047 bool is_80plus_op_class(u8 op_class)
2048 {
2049           /* Operating classes with "80+" behavior indication in Table E-4 */
2050           return op_class == 130 || op_class == 135;
2051 }
2052 
2053 
is_11b(u8 rate)2054 static int is_11b(u8 rate)
2055 {
2056           return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
2057 }
2058 
2059 
supp_rates_11b_only(struct ieee802_11_elems * elems)2060 int supp_rates_11b_only(struct ieee802_11_elems *elems)
2061 {
2062           int num_11b = 0, num_others = 0;
2063           int i;
2064 
2065           if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
2066                     return 0;
2067 
2068           for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
2069                     if (is_11b(elems->supp_rates[i]))
2070                               num_11b++;
2071                     else
2072                               num_others++;
2073           }
2074 
2075           for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
2076                i++) {
2077                     if (is_11b(elems->ext_supp_rates[i]))
2078                               num_11b++;
2079                     else
2080                               num_others++;
2081           }
2082 
2083           return num_11b > 0 && num_others == 0;
2084 }
2085 
2086 
fc2str(u16 fc)2087 const char * fc2str(u16 fc)
2088 {
2089           u16 stype = WLAN_FC_GET_STYPE(fc);
2090 #define C2S(x) case x: return #x;
2091 
2092           switch (WLAN_FC_GET_TYPE(fc)) {
2093           case WLAN_FC_TYPE_MGMT:
2094                     switch (stype) {
2095                     C2S(WLAN_FC_STYPE_ASSOC_REQ)
2096                     C2S(WLAN_FC_STYPE_ASSOC_RESP)
2097                     C2S(WLAN_FC_STYPE_REASSOC_REQ)
2098                     C2S(WLAN_FC_STYPE_REASSOC_RESP)
2099                     C2S(WLAN_FC_STYPE_PROBE_REQ)
2100                     C2S(WLAN_FC_STYPE_PROBE_RESP)
2101                     C2S(WLAN_FC_STYPE_BEACON)
2102                     C2S(WLAN_FC_STYPE_ATIM)
2103                     C2S(WLAN_FC_STYPE_DISASSOC)
2104                     C2S(WLAN_FC_STYPE_AUTH)
2105                     C2S(WLAN_FC_STYPE_DEAUTH)
2106                     C2S(WLAN_FC_STYPE_ACTION)
2107                     }
2108                     break;
2109           case WLAN_FC_TYPE_CTRL:
2110                     switch (stype) {
2111                     C2S(WLAN_FC_STYPE_PSPOLL)
2112                     C2S(WLAN_FC_STYPE_RTS)
2113                     C2S(WLAN_FC_STYPE_CTS)
2114                     C2S(WLAN_FC_STYPE_ACK)
2115                     C2S(WLAN_FC_STYPE_CFEND)
2116                     C2S(WLAN_FC_STYPE_CFENDACK)
2117                     }
2118                     break;
2119           case WLAN_FC_TYPE_DATA:
2120                     switch (stype) {
2121                     C2S(WLAN_FC_STYPE_DATA)
2122                     C2S(WLAN_FC_STYPE_DATA_CFACK)
2123                     C2S(WLAN_FC_STYPE_DATA_CFPOLL)
2124                     C2S(WLAN_FC_STYPE_DATA_CFACKPOLL)
2125                     C2S(WLAN_FC_STYPE_NULLFUNC)
2126                     C2S(WLAN_FC_STYPE_CFACK)
2127                     C2S(WLAN_FC_STYPE_CFPOLL)
2128                     C2S(WLAN_FC_STYPE_CFACKPOLL)
2129                     C2S(WLAN_FC_STYPE_QOS_DATA)
2130                     C2S(WLAN_FC_STYPE_QOS_DATA_CFACK)
2131                     C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL)
2132                     C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL)
2133                     C2S(WLAN_FC_STYPE_QOS_NULL)
2134                     C2S(WLAN_FC_STYPE_QOS_CFPOLL)
2135                     C2S(WLAN_FC_STYPE_QOS_CFACKPOLL)
2136                     }
2137                     break;
2138           }
2139           return "WLAN_FC_TYPE_UNKNOWN";
2140 #undef C2S
2141 }
2142 
2143 
reason2str(u16 reason)2144 const char * reason2str(u16 reason)
2145 {
2146 #define R2S(r) case WLAN_REASON_ ## r: return #r;
2147           switch (reason) {
2148           R2S(UNSPECIFIED)
2149           R2S(PREV_AUTH_NOT_VALID)
2150           R2S(DEAUTH_LEAVING)
2151           R2S(DISASSOC_DUE_TO_INACTIVITY)
2152           R2S(DISASSOC_AP_BUSY)
2153           R2S(CLASS2_FRAME_FROM_NONAUTH_STA)
2154           R2S(CLASS3_FRAME_FROM_NONASSOC_STA)
2155           R2S(DISASSOC_STA_HAS_LEFT)
2156           R2S(STA_REQ_ASSOC_WITHOUT_AUTH)
2157           R2S(PWR_CAPABILITY_NOT_VALID)
2158           R2S(SUPPORTED_CHANNEL_NOT_VALID)
2159           R2S(BSS_TRANSITION_DISASSOC)
2160           R2S(INVALID_IE)
2161           R2S(MICHAEL_MIC_FAILURE)
2162           R2S(4WAY_HANDSHAKE_TIMEOUT)
2163           R2S(GROUP_KEY_UPDATE_TIMEOUT)
2164           R2S(IE_IN_4WAY_DIFFERS)
2165           R2S(GROUP_CIPHER_NOT_VALID)
2166           R2S(PAIRWISE_CIPHER_NOT_VALID)
2167           R2S(AKMP_NOT_VALID)
2168           R2S(UNSUPPORTED_RSN_IE_VERSION)
2169           R2S(INVALID_RSN_IE_CAPAB)
2170           R2S(IEEE_802_1X_AUTH_FAILED)
2171           R2S(CIPHER_SUITE_REJECTED)
2172           R2S(TDLS_TEARDOWN_UNREACHABLE)
2173           R2S(TDLS_TEARDOWN_UNSPECIFIED)
2174           R2S(SSP_REQUESTED_DISASSOC)
2175           R2S(NO_SSP_ROAMING_AGREEMENT)
2176           R2S(BAD_CIPHER_OR_AKM)
2177           R2S(NOT_AUTHORIZED_THIS_LOCATION)
2178           R2S(SERVICE_CHANGE_PRECLUDES_TS)
2179           R2S(UNSPECIFIED_QOS_REASON)
2180           R2S(NOT_ENOUGH_BANDWIDTH)
2181           R2S(DISASSOC_LOW_ACK)
2182           R2S(EXCEEDED_TXOP)
2183           R2S(STA_LEAVING)
2184           R2S(END_TS_BA_DLS)
2185           R2S(UNKNOWN_TS_BA)
2186           R2S(TIMEOUT)
2187           R2S(PEERKEY_MISMATCH)
2188           R2S(AUTHORIZED_ACCESS_LIMIT_REACHED)
2189           R2S(EXTERNAL_SERVICE_REQUIREMENTS)
2190           R2S(INVALID_FT_ACTION_FRAME_COUNT)
2191           R2S(INVALID_PMKID)
2192           R2S(INVALID_MDE)
2193           R2S(INVALID_FTE)
2194           R2S(MESH_PEERING_CANCELLED)
2195           R2S(MESH_MAX_PEERS)
2196           R2S(MESH_CONFIG_POLICY_VIOLATION)
2197           R2S(MESH_CLOSE_RCVD)
2198           R2S(MESH_MAX_RETRIES)
2199           R2S(MESH_CONFIRM_TIMEOUT)
2200           R2S(MESH_INVALID_GTK)
2201           R2S(MESH_INCONSISTENT_PARAMS)
2202           R2S(MESH_INVALID_SECURITY_CAP)
2203           R2S(MESH_PATH_ERROR_NO_PROXY_INFO)
2204           R2S(MESH_PATH_ERROR_NO_FORWARDING_INFO)
2205           R2S(MESH_PATH_ERROR_DEST_UNREACHABLE)
2206           R2S(MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS)
2207           R2S(MESH_CHANNEL_SWITCH_REGULATORY_REQ)
2208           R2S(MESH_CHANNEL_SWITCH_UNSPECIFIED)
2209           }
2210           return "UNKNOWN";
2211 #undef R2S
2212 }
2213 
2214 
status2str(u16 status)2215 const char * status2str(u16 status)
2216 {
2217 #define S2S(s) case WLAN_STATUS_ ## s: return #s;
2218           switch (status) {
2219           S2S(SUCCESS)
2220           S2S(UNSPECIFIED_FAILURE)
2221           S2S(TDLS_WAKEUP_ALTERNATE)
2222           S2S(TDLS_WAKEUP_REJECT)
2223           S2S(SECURITY_DISABLED)
2224           S2S(UNACCEPTABLE_LIFETIME)
2225           S2S(NOT_IN_SAME_BSS)
2226           S2S(CAPS_UNSUPPORTED)
2227           S2S(REASSOC_NO_ASSOC)
2228           S2S(ASSOC_DENIED_UNSPEC)
2229           S2S(NOT_SUPPORTED_AUTH_ALG)
2230           S2S(UNKNOWN_AUTH_TRANSACTION)
2231           S2S(CHALLENGE_FAIL)
2232           S2S(AUTH_TIMEOUT)
2233           S2S(AP_UNABLE_TO_HANDLE_NEW_STA)
2234           S2S(ASSOC_DENIED_RATES)
2235           S2S(ASSOC_DENIED_NOSHORT)
2236           S2S(SPEC_MGMT_REQUIRED)
2237           S2S(PWR_CAPABILITY_NOT_VALID)
2238           S2S(SUPPORTED_CHANNEL_NOT_VALID)
2239           S2S(ASSOC_DENIED_NO_SHORT_SLOT_TIME)
2240           S2S(ASSOC_DENIED_NO_HT)
2241           S2S(R0KH_UNREACHABLE)
2242           S2S(ASSOC_DENIED_NO_PCO)
2243           S2S(ASSOC_REJECTED_TEMPORARILY)
2244           S2S(ROBUST_MGMT_FRAME_POLICY_VIOLATION)
2245           S2S(UNSPECIFIED_QOS_FAILURE)
2246           S2S(DENIED_INSUFFICIENT_BANDWIDTH)
2247           S2S(DENIED_POOR_CHANNEL_CONDITIONS)
2248           S2S(DENIED_QOS_NOT_SUPPORTED)
2249           S2S(REQUEST_DECLINED)
2250           S2S(INVALID_PARAMETERS)
2251           S2S(REJECTED_WITH_SUGGESTED_CHANGES)
2252           S2S(INVALID_IE)
2253           S2S(GROUP_CIPHER_NOT_VALID)
2254           S2S(PAIRWISE_CIPHER_NOT_VALID)
2255           S2S(AKMP_NOT_VALID)
2256           S2S(UNSUPPORTED_RSN_IE_VERSION)
2257           S2S(INVALID_RSN_IE_CAPAB)
2258           S2S(CIPHER_REJECTED_PER_POLICY)
2259           S2S(TS_NOT_CREATED)
2260           S2S(DIRECT_LINK_NOT_ALLOWED)
2261           S2S(DEST_STA_NOT_PRESENT)
2262           S2S(DEST_STA_NOT_QOS_STA)
2263           S2S(ASSOC_DENIED_LISTEN_INT_TOO_LARGE)
2264           S2S(INVALID_FT_ACTION_FRAME_COUNT)
2265           S2S(INVALID_PMKID)
2266           S2S(INVALID_MDIE)
2267           S2S(INVALID_FTIE)
2268           S2S(REQUESTED_TCLAS_NOT_SUPPORTED)
2269           S2S(INSUFFICIENT_TCLAS_PROCESSING_RESOURCES)
2270           S2S(TRY_ANOTHER_BSS)
2271           S2S(GAS_ADV_PROTO_NOT_SUPPORTED)
2272           S2S(NO_OUTSTANDING_GAS_REQ)
2273           S2S(GAS_RESP_NOT_RECEIVED)
2274           S2S(STA_TIMED_OUT_WAITING_FOR_GAS_RESP)
2275           S2S(GAS_RESP_LARGER_THAN_LIMIT)
2276           S2S(REQ_REFUSED_HOME)
2277           S2S(ADV_SRV_UNREACHABLE)
2278           S2S(REQ_REFUSED_SSPN)
2279           S2S(REQ_REFUSED_UNAUTH_ACCESS)
2280           S2S(INVALID_RSNIE)
2281           S2S(U_APSD_COEX_NOT_SUPPORTED)
2282           S2S(U_APSD_COEX_MODE_NOT_SUPPORTED)
2283           S2S(BAD_INTERVAL_WITH_U_APSD_COEX)
2284           S2S(ANTI_CLOGGING_TOKEN_REQ)
2285           S2S(FINITE_CYCLIC_GROUP_NOT_SUPPORTED)
2286           S2S(CANNOT_FIND_ALT_TBTT)
2287           S2S(TRANSMISSION_FAILURE)
2288           S2S(REQ_TCLAS_NOT_SUPPORTED)
2289           S2S(TCLAS_RESOURCES_EXCHAUSTED)
2290           S2S(REJECTED_WITH_SUGGESTED_BSS_TRANSITION)
2291           S2S(REJECT_WITH_SCHEDULE)
2292           S2S(REJECT_NO_WAKEUP_SPECIFIED)
2293           S2S(SUCCESS_POWER_SAVE_MODE)
2294           S2S(PENDING_ADMITTING_FST_SESSION)
2295           S2S(PERFORMING_FST_NOW)
2296           S2S(PENDING_GAP_IN_BA_WINDOW)
2297           S2S(REJECT_U_PID_SETTING)
2298           S2S(REFUSED_EXTERNAL_REASON)
2299           S2S(REFUSED_AP_OUT_OF_MEMORY)
2300           S2S(REJECTED_EMERGENCY_SERVICE_NOT_SUPPORTED)
2301           S2S(QUERY_RESP_OUTSTANDING)
2302           S2S(REJECT_DSE_BAND)
2303           S2S(TCLAS_PROCESSING_TERMINATED)
2304           S2S(TS_SCHEDULE_CONFLICT)
2305           S2S(DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL)
2306           S2S(MCCAOP_RESERVATION_CONFLICT)
2307           S2S(MAF_LIMIT_EXCEEDED)
2308           S2S(MCCA_TRACK_LIMIT_EXCEEDED)
2309           S2S(DENIED_DUE_TO_SPECTRUM_MANAGEMENT)
2310           S2S(ASSOC_DENIED_NO_VHT)
2311           S2S(ENABLEMENT_DENIED)
2312           S2S(RESTRICTION_FROM_AUTHORIZED_GDB)
2313           S2S(AUTHORIZATION_DEENABLED)
2314           S2S(FILS_AUTHENTICATION_FAILURE)
2315           S2S(UNKNOWN_AUTHENTICATION_SERVER)
2316           S2S(UNKNOWN_PASSWORD_IDENTIFIER)
2317           S2S(DENIED_HE_NOT_SUPPORTED)
2318           S2S(SAE_HASH_TO_ELEMENT)
2319           S2S(SAE_PK)
2320           S2S(INVALID_PUBLIC_KEY)
2321           S2S(PASN_BASE_AKMP_FAILED)
2322           S2S(OCI_MISMATCH)
2323           }
2324           return "UNKNOWN";
2325 #undef S2S
2326 }
2327 
2328 
mb_ies_info_by_ies(struct mb_ies_info * info,const u8 * ies_buf,size_t ies_len)2329 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
2330                            size_t ies_len)
2331 {
2332           const struct element *elem;
2333 
2334           os_memset(info, 0, sizeof(*info));
2335 
2336           if (!ies_buf)
2337                     return 0;
2338 
2339           for_each_element_id(elem, WLAN_EID_MULTI_BAND, ies_buf, ies_len) {
2340                     if (info->nof_ies >= MAX_NOF_MB_IES_SUPPORTED)
2341                               return 0;
2342 
2343                     wpa_printf(MSG_DEBUG, "MB IE of %u bytes found",
2344                                  elem->datalen + 2);
2345                     info->ies[info->nof_ies].ie = elem->data;
2346                     info->ies[info->nof_ies].ie_len = elem->datalen;
2347                     info->nof_ies++;
2348           }
2349 
2350           if (!for_each_element_completed(elem, ies_buf, ies_len)) {
2351                     wpa_hexdump(MSG_DEBUG, "Truncated IEs", ies_buf, ies_len);
2352                     return -1;
2353           }
2354 
2355           return 0;
2356 }
2357 
2358 
mb_ies_by_info(struct mb_ies_info * info)2359 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info)
2360 {
2361           struct wpabuf *mb_ies = NULL;
2362 
2363           WPA_ASSERT(info != NULL);
2364 
2365           if (info->nof_ies) {
2366                     u8 i;
2367                     size_t mb_ies_size = 0;
2368 
2369                     for (i = 0; i < info->nof_ies; i++)
2370                               mb_ies_size += 2 + info->ies[i].ie_len;
2371 
2372                     mb_ies = wpabuf_alloc(mb_ies_size);
2373                     if (mb_ies) {
2374                               for (i = 0; i < info->nof_ies; i++) {
2375                                         wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND);
2376                                         wpabuf_put_u8(mb_ies, info->ies[i].ie_len);
2377                                         wpabuf_put_data(mb_ies,
2378                                                             info->ies[i].ie,
2379                                                             info->ies[i].ie_len);
2380                               }
2381                     }
2382           }
2383 
2384           return mb_ies;
2385 }
2386 
2387 
2388 const struct oper_class_map global_op_class[] = {
2389           { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP },
2390           { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP },
2391 
2392           /* Do not enable HT40 on 2.4 GHz for P2P use for now */
2393           { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP },
2394           { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP },
2395 
2396           { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP },
2397           { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP },
2398           { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP },
2399           { HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP },
2400           { HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP },
2401           { HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP },
2402           { HOSTAPD_MODE_IEEE80211A, 121, 100, 144, 4, BW20, NO_P2P_SUPP },
2403           { HOSTAPD_MODE_IEEE80211A, 122, 100, 140, 8, BW40PLUS, NO_P2P_SUPP },
2404           { HOSTAPD_MODE_IEEE80211A, 123, 104, 144, 8, BW40MINUS, NO_P2P_SUPP },
2405           { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
2406           { HOSTAPD_MODE_IEEE80211A, 125, 149, 177, 4, BW20, P2P_SUPP },
2407           { HOSTAPD_MODE_IEEE80211A, 126, 149, 173, 8, BW40PLUS, P2P_SUPP },
2408           { HOSTAPD_MODE_IEEE80211A, 127, 153, 177, 8, BW40MINUS, P2P_SUPP },
2409 
2410           /*
2411            * IEEE Std 802.11ax-2021, Table E-4 actually talks about channel center
2412            * frequency index for operation classes 128, 129, 130, 132, 133, 134,
2413            * and 135, but currently use the lowest 20 MHz channel for simplicity
2414            * (these center frequencies are not actual channels, which makes
2415            * wpas_p2p_verify_channel() fail).
2416            * Specially for the operation class 136, it is also defined to use the
2417            * channel center frequency index value, but it happens to be a 20 MHz
2418            * channel and the channel number in the channel set would match the
2419            * value in for the frequency center.
2420            *
2421            * Operating class value pair 128 and 130 is used to describe a 80+80
2422            * MHz channel on the 5 GHz band. 130 is identified with "80+", so this
2423            * is encoded with two octets 130 and 128. Similarly, operating class
2424            * value pair 133 and 135 is used to describe a 80+80 MHz channel on
2425            * the 6 GHz band (135 being the one with "80+" indication). All other
2426            * operating classes listed here are used as 1-octet values.
2427            */
2428           { HOSTAPD_MODE_IEEE80211A, 128, 36, 177, 4, BW80, P2P_SUPP },
2429           { HOSTAPD_MODE_IEEE80211A, 129, 36, 177, 4, BW160, P2P_SUPP },
2430           { HOSTAPD_MODE_IEEE80211A, 130, 36, 177, 4, BW80P80, P2P_SUPP },
2431           { HOSTAPD_MODE_IEEE80211A, 131, 1, 233, 4, BW20, P2P_SUPP },
2432           { HOSTAPD_MODE_IEEE80211A, 132, 1, 233, 8, BW40, P2P_SUPP },
2433           { HOSTAPD_MODE_IEEE80211A, 133, 1, 233, 16, BW80, P2P_SUPP },
2434           { HOSTAPD_MODE_IEEE80211A, 134, 1, 233, 32, BW160, P2P_SUPP },
2435           { HOSTAPD_MODE_IEEE80211A, 135, 1, 233, 16, BW80P80, NO_P2P_SUPP },
2436           { HOSTAPD_MODE_IEEE80211A, 136, 2, 2, 4, BW20, NO_P2P_SUPP },
2437 
2438           /* IEEE P802.11be/D5.0, Table E-4 (Global operating classes) */
2439           { HOSTAPD_MODE_IEEE80211A, 137, 31, 191, 32, BW320, NO_P2P_SUPP },
2440 
2441           /*
2442            * IEEE Std 802.11ad-2012 and P802.ay/D5.0 60 GHz operating classes.
2443            * Class 180 has the legacy channels 1-6. Classes 181-183 include
2444            * channels which implement channel bonding features.
2445            */
2446           { HOSTAPD_MODE_IEEE80211AD, 180, 1, 6, 1, BW2160, P2P_SUPP },
2447           { HOSTAPD_MODE_IEEE80211AD, 181, 9, 13, 1, BW4320, P2P_SUPP },
2448           { HOSTAPD_MODE_IEEE80211AD, 182, 17, 20, 1, BW6480, P2P_SUPP },
2449           { HOSTAPD_MODE_IEEE80211AD, 183, 25, 27, 1, BW8640, P2P_SUPP },
2450 
2451           { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
2452 };
2453 
2454 
ieee80211_phy_type_by_freq(int freq)2455 static enum phy_type ieee80211_phy_type_by_freq(int freq)
2456 {
2457           enum hostapd_hw_mode hw_mode;
2458           u8 channel;
2459 
2460           hw_mode = ieee80211_freq_to_chan(freq, &channel);
2461 
2462           switch (hw_mode) {
2463           case HOSTAPD_MODE_IEEE80211A:
2464                     return PHY_TYPE_OFDM;
2465           case HOSTAPD_MODE_IEEE80211B:
2466                     return PHY_TYPE_HRDSSS;
2467           case HOSTAPD_MODE_IEEE80211G:
2468                     return PHY_TYPE_ERP;
2469           case HOSTAPD_MODE_IEEE80211AD:
2470                     return PHY_TYPE_DMG;
2471           default:
2472                     return PHY_TYPE_UNSPECIFIED;
2473           };
2474 }
2475 
2476 
2477 /* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */
ieee80211_get_phy_type(int freq,int ht,int vht)2478 enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht)
2479 {
2480           if (vht)
2481                     return PHY_TYPE_VHT;
2482           if (ht)
2483                     return PHY_TYPE_HT;
2484 
2485           return ieee80211_phy_type_by_freq(freq);
2486 }
2487 
2488 
2489 size_t global_op_class_size = ARRAY_SIZE(global_op_class);
2490 
2491 
2492 /**
2493  * get_ie - Fetch a specified information element from IEs buffer
2494  * @ies: Information elements buffer
2495  * @len: Information elements buffer length
2496  * @eid: Information element identifier (WLAN_EID_*)
2497  * Returns: Pointer to the information element (id field) or %NULL if not found
2498  *
2499  * This function returns the first matching information element in the IEs
2500  * buffer or %NULL in case the element is not found.
2501  */
get_ie(const u8 * ies,size_t len,u8 eid)2502 const u8 * get_ie(const u8 *ies, size_t len, u8 eid)
2503 {
2504           const struct element *elem;
2505 
2506           if (!ies)
2507                     return NULL;
2508 
2509           for_each_element_id(elem, eid, ies, len)
2510                     return &elem->id;
2511 
2512           return NULL;
2513 }
2514 
2515 
2516 /**
2517  * get_ie_ext - Fetch a specified extended information element from IEs buffer
2518  * @ies: Information elements buffer
2519  * @len: Information elements buffer length
2520  * @ext: Information element extension identifier (WLAN_EID_EXT_*)
2521  * Returns: Pointer to the information element (id field) or %NULL if not found
2522  *
2523  * This function returns the first matching information element in the IEs
2524  * buffer or %NULL in case the element is not found.
2525  */
get_ie_ext(const u8 * ies,size_t len,u8 ext)2526 const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext)
2527 {
2528           const struct element *elem;
2529 
2530           if (!ies)
2531                     return NULL;
2532 
2533           for_each_element_extid(elem, ext, ies, len)
2534                     return &elem->id;
2535 
2536           return NULL;
2537 }
2538 
2539 
get_vendor_ie(const u8 * ies,size_t len,u32 vendor_type)2540 const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type)
2541 {
2542           const struct element *elem;
2543 
2544           for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, len) {
2545                     if (elem->datalen >= 4 &&
2546                         vendor_type == WPA_GET_BE32(elem->data))
2547                               return &elem->id;
2548           }
2549 
2550           return NULL;
2551 }
2552 
2553 
mbo_add_ie(u8 * buf,size_t len,const u8 * attr,size_t attr_len)2554 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
2555 {
2556           /*
2557            * MBO IE requires 6 bytes without the attributes: EID (1), length (1),
2558            * OUI (3), OUI type (1).
2559            */
2560           if (len < 6 + attr_len) {
2561                     wpa_printf(MSG_DEBUG,
2562                                  "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu",
2563                                  len, attr_len);
2564                     return 0;
2565           }
2566 
2567           *buf++ = WLAN_EID_VENDOR_SPECIFIC;
2568           *buf++ = attr_len + 4;
2569           WPA_PUT_BE24(buf, OUI_WFA);
2570           buf += 3;
2571           *buf++ = MBO_OUI_TYPE;
2572           os_memcpy(buf, attr, attr_len);
2573 
2574           return 6 + attr_len;
2575 }
2576 
2577 
check_multi_ap_ie(const u8 * multi_ap_ie,size_t multi_ap_len,struct multi_ap_params * multi_ap)2578 u16 check_multi_ap_ie(const u8 *multi_ap_ie, size_t multi_ap_len,
2579                           struct multi_ap_params *multi_ap)
2580 {
2581           const struct element *elem;
2582           bool ext_present = false;
2583           unsigned int vlan_id;
2584 
2585           os_memset(multi_ap, 0, sizeof(*multi_ap));
2586 
2587           /* Default profile is 1, when Multi-AP profile subelement is not
2588            * present in the element. */
2589           multi_ap->profile = 1;
2590 
2591           for_each_element(elem, multi_ap_ie, multi_ap_len) {
2592                     u8 id = elem->id, elen = elem->datalen;
2593                     const u8 *pos = elem->data;
2594 
2595                     switch (id) {
2596                     case MULTI_AP_SUB_ELEM_TYPE:
2597                               if (elen >= 1) {
2598                                         multi_ap->capability = *pos;
2599                                         ext_present = true;
2600                               } else {
2601                                         wpa_printf(MSG_DEBUG,
2602                                                      "Multi-AP invalid Multi-AP subelement");
2603                                         return WLAN_STATUS_INVALID_IE;
2604                               }
2605                               break;
2606                     case MULTI_AP_PROFILE_SUB_ELEM_TYPE:
2607                               if (elen < 1) {
2608                                         wpa_printf(MSG_DEBUG,
2609                                                      "Multi-AP IE invalid Multi-AP profile subelement");
2610                                         return WLAN_STATUS_INVALID_IE;
2611                               }
2612 
2613                               multi_ap->profile = *pos;
2614                               if (multi_ap->profile > MULTI_AP_PROFILE_MAX) {
2615                                         wpa_printf(MSG_DEBUG,
2616                                                      "Multi-AP IE with invalid profile 0x%02x",
2617                                                      multi_ap->profile);
2618                                         return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
2619                               }
2620                               break;
2621                     case MULTI_AP_VLAN_SUB_ELEM_TYPE:
2622                               if (multi_ap->profile < MULTI_AP_PROFILE_2) {
2623                                         wpa_printf(MSG_DEBUG,
2624                                                      "Multi-AP IE invalid profile to read VLAN IE");
2625                                         return WLAN_STATUS_INVALID_IE;
2626                               }
2627                               if (elen < 2) {
2628                                         wpa_printf(MSG_DEBUG,
2629                                                      "Multi-AP IE invalid Multi-AP VLAN subelement");
2630                                         return WLAN_STATUS_INVALID_IE;
2631                               }
2632 
2633                               vlan_id = WPA_GET_LE16(pos);
2634                               if (vlan_id < 1 || vlan_id > 4094) {
2635                                         wpa_printf(MSG_INFO,
2636                                                      "Multi-AP IE invalid Multi-AP VLAN ID %d",
2637                                                      vlan_id);
2638                                         return WLAN_STATUS_INVALID_IE;
2639                               }
2640                               multi_ap->vlanid = vlan_id;
2641                               break;
2642                     default:
2643                               wpa_printf(MSG_DEBUG,
2644                                            "Ignore unknown subelement %u in Multi-AP IE",
2645                                            id);
2646                               break;
2647                     }
2648           }
2649 
2650           if (!for_each_element_completed(elem, multi_ap_ie, multi_ap_len)) {
2651                     wpa_printf(MSG_DEBUG, "Multi AP IE parse failed @%d",
2652                                  (int) (multi_ap_ie + multi_ap_len -
2653                                           (const u8 *) elem));
2654                     wpa_hexdump(MSG_MSGDUMP, "IEs", multi_ap_ie, multi_ap_len);
2655           }
2656 
2657           if (!ext_present) {
2658                     wpa_printf(MSG_DEBUG,
2659                                  "Multi-AP element without Multi-AP Extension subelement");
2660                     return WLAN_STATUS_INVALID_IE;
2661           }
2662 
2663           return WLAN_STATUS_SUCCESS;
2664 }
2665 
2666 
add_multi_ap_ie(u8 * buf,size_t len,const struct multi_ap_params * multi_ap)2667 size_t add_multi_ap_ie(u8 *buf, size_t len,
2668                            const struct multi_ap_params *multi_ap)
2669 {
2670           u8 *pos = buf;
2671           u8 *len_ptr;
2672 
2673           if (len < 6)
2674                     return 0;
2675 
2676           *pos++ = WLAN_EID_VENDOR_SPECIFIC;
2677           len_ptr = pos; /* Length field to be set at the end */
2678           pos++;
2679           WPA_PUT_BE24(pos, OUI_WFA);
2680           pos += 3;
2681           *pos++ = MULTI_AP_OUI_TYPE;
2682 
2683           /* Multi-AP Extension subelement */
2684           if (buf + len - pos < 3)
2685                     return 0;
2686           *pos++ = MULTI_AP_SUB_ELEM_TYPE;
2687           *pos++ = 1; /* len */
2688           *pos++ = multi_ap->capability;
2689 
2690           /* Add Multi-AP Profile subelement only for R2 or newer configuration */
2691           if (multi_ap->profile >= MULTI_AP_PROFILE_2) {
2692                     if (buf + len - pos < 3)
2693                               return 0;
2694                     *pos++ = MULTI_AP_PROFILE_SUB_ELEM_TYPE;
2695                     *pos++ = 1;
2696                     *pos++ = multi_ap->profile;
2697           }
2698 
2699           /* Add Multi-AP Default 802.1Q Setting subelement only for backhaul BSS
2700            */
2701           if (multi_ap->vlanid &&
2702               multi_ap->profile >= MULTI_AP_PROFILE_2 &&
2703               (multi_ap->capability & MULTI_AP_BACKHAUL_BSS)) {
2704                     if (buf + len - pos < 4)
2705                               return 0;
2706                     *pos++ = MULTI_AP_VLAN_SUB_ELEM_TYPE;
2707                     *pos++ = 2;
2708                     WPA_PUT_LE16(pos, multi_ap->vlanid);
2709                     pos += 2;
2710           }
2711 
2712           *len_ptr = pos - len_ptr - 1;
2713 
2714           return pos - buf;
2715 }
2716 
2717 
2718 static const struct country_op_class us_op_class[] = {
2719           { 1, 115 },
2720           { 2, 118 },
2721           { 3, 124 },
2722           { 4, 121 },
2723           { 5, 125 },
2724           { 12, 81 },
2725           { 22, 116 },
2726           { 23, 119 },
2727           { 24, 122 },
2728           { 25, 126 },
2729           { 26, 126 },
2730           { 27, 117 },
2731           { 28, 120 },
2732           { 29, 123 },
2733           { 30, 127 },
2734           { 31, 127 },
2735           { 32, 83 },
2736           { 33, 84 },
2737           { 34, 180 },
2738 };
2739 
2740 static const struct country_op_class eu_op_class[] = {
2741           { 1, 115 },
2742           { 2, 118 },
2743           { 3, 121 },
2744           { 4, 81 },
2745           { 5, 116 },
2746           { 6, 119 },
2747           { 7, 122 },
2748           { 8, 117 },
2749           { 9, 120 },
2750           { 10, 123 },
2751           { 11, 83 },
2752           { 12, 84 },
2753           { 17, 125 },
2754           { 18, 180 },
2755 };
2756 
2757 static const struct country_op_class jp_op_class[] = {
2758           { 1, 115 },
2759           { 30, 81 },
2760           { 31, 82 },
2761           { 32, 118 },
2762           { 33, 118 },
2763           { 34, 121 },
2764           { 35, 121 },
2765           { 36, 116 },
2766           { 37, 119 },
2767           { 38, 119 },
2768           { 39, 122 },
2769           { 40, 122 },
2770           { 41, 117 },
2771           { 42, 120 },
2772           { 43, 120 },
2773           { 44, 123 },
2774           { 45, 123 },
2775           { 56, 83 },
2776           { 57, 84 },
2777           { 58, 121 },
2778           { 59, 180 },
2779 };
2780 
2781 static const struct country_op_class cn_op_class[] = {
2782           { 1, 115 },
2783           { 2, 118 },
2784           { 3, 125 },
2785           { 4, 116 },
2786           { 5, 119 },
2787           { 6, 126 },
2788           { 7, 81 },
2789           { 8, 83 },
2790           { 9, 84 },
2791 };
2792 
2793 static u8
global_op_class_from_country_array(u8 op_class,size_t array_size,const struct country_op_class * country_array)2794 global_op_class_from_country_array(u8 op_class, size_t array_size,
2795                                            const struct country_op_class *country_array)
2796 {
2797           size_t i;
2798 
2799           for (i = 0; i < array_size; i++) {
2800                     if (country_array[i].country_op_class == op_class)
2801                               return country_array[i].global_op_class;
2802           }
2803 
2804           return 0;
2805 }
2806 
2807 
country_to_global_op_class(const char * country,u8 op_class)2808 u8 country_to_global_op_class(const char *country, u8 op_class)
2809 {
2810           const struct country_op_class *country_array;
2811           size_t size;
2812           u8 g_op_class;
2813 
2814           if (country_match(us_op_class_cc, country)) {
2815                     country_array = us_op_class;
2816                     size = ARRAY_SIZE(us_op_class);
2817           } else if (country_match(eu_op_class_cc, country)) {
2818                     country_array = eu_op_class;
2819                     size = ARRAY_SIZE(eu_op_class);
2820           } else if (country_match(jp_op_class_cc, country)) {
2821                     country_array = jp_op_class;
2822                     size = ARRAY_SIZE(jp_op_class);
2823           } else if (country_match(cn_op_class_cc, country)) {
2824                     country_array = cn_op_class;
2825                     size = ARRAY_SIZE(cn_op_class);
2826           } else {
2827                     /*
2828                      * Countries that do not match any of the above countries use
2829                      * global operating classes
2830                      */
2831                     return op_class;
2832           }
2833 
2834           g_op_class = global_op_class_from_country_array(op_class, size,
2835                                                                       country_array);
2836 
2837           /*
2838            * If the given operating class did not match any of the country's
2839            * operating classes, assume that global operating class is used.
2840            */
2841           return g_op_class ? g_op_class : op_class;
2842 }
2843 
2844 
get_oper_class(const char * country,u8 op_class)2845 const struct oper_class_map * get_oper_class(const char *country, u8 op_class)
2846 {
2847           const struct oper_class_map *op;
2848 
2849           if (country)
2850                     op_class = country_to_global_op_class(country, op_class);
2851 
2852           op = &global_op_class[0];
2853           while (op->op_class && op->op_class != op_class)
2854                     op++;
2855 
2856           if (!op->op_class)
2857                     return NULL;
2858 
2859           return op;
2860 }
2861 
2862 
oper_class_bw_to_int(const struct oper_class_map * map)2863 int oper_class_bw_to_int(const struct oper_class_map *map)
2864 {
2865           switch (map->bw) {
2866           case BW20:
2867                     return 20;
2868           case BW40:
2869           case BW40PLUS:
2870           case BW40MINUS:
2871                     return 40;
2872           case BW80:
2873                     return 80;
2874           case BW80P80:
2875           case BW160:
2876                     return 160;
2877           case BW320:
2878                     return 320;
2879           case BW2160:
2880                     return 2160;
2881           default:
2882                     return 0;
2883           }
2884 }
2885 
2886 
center_idx_to_bw_6ghz(u8 idx)2887 int center_idx_to_bw_6ghz(u8 idx)
2888 {
2889           /* Channel: 2 */
2890           if (idx == 2)
2891                     return 0; /* 20 MHz */
2892           /* channels: 1, 5, 9, 13... */
2893           if ((idx & 0x3) == 0x1)
2894                     return 0; /* 20 MHz */
2895           /* channels 3, 11, 19... */
2896           if ((idx & 0x7) == 0x3)
2897                     return 1; /* 40 MHz */
2898           /* channels 7, 23, 39.. */
2899           if ((idx & 0xf) == 0x7)
2900                     return 2; /* 80 MHz */
2901           /* channels 15, 47, 79...*/
2902           if ((idx & 0x1f) == 0xf)
2903                     return 3; /* 160 MHz */
2904           /* channels 31, 63, 95, 127, 159, 191 */
2905           if ((idx & 0x1f) == 0x1f && idx < 192)
2906                     return 4; /* 320 MHz */
2907 
2908           return -1;
2909 }
2910 
2911 
is_6ghz_freq(int freq)2912 bool is_6ghz_freq(int freq)
2913 {
2914           if (freq < 5935 || freq > 7115)
2915                     return false;
2916 
2917           if (freq == 5935)
2918                     return true;
2919 
2920           if (center_idx_to_bw_6ghz((freq - 5950) / 5) < 0)
2921                     return false;
2922 
2923           return true;
2924 }
2925 
2926 
is_6ghz_op_class(u8 op_class)2927 bool is_6ghz_op_class(u8 op_class)
2928 {
2929           return op_class >= 131 && op_class <= 137;
2930 }
2931 
2932 
is_6ghz_psc_frequency(int freq)2933 bool is_6ghz_psc_frequency(int freq)
2934 {
2935           int i;
2936 
2937           if (!is_6ghz_freq(freq) || freq == 5935)
2938                     return false;
2939           if ((((freq - 5950) / 5) & 0x3) != 0x1)
2940                     return false;
2941 
2942           i = (freq - 5950 + 55) % 80;
2943           if (i == 0)
2944                     i = (freq - 5950 + 55) / 80;
2945 
2946           if (i >= 1 && i <= 15)
2947                     return true;
2948 
2949           return false;
2950 }
2951 
2952 
2953 /**
2954  * get_6ghz_sec_channel - Get the relative position of the secondary channel
2955  * to the primary channel in 6 GHz
2956  * @channel: Primary channel to be checked for (in global op class 131)
2957  * Returns: 1 = secondary channel above, -1 = secondary channel below
2958  */
2959 
get_6ghz_sec_channel(int channel)2960 int get_6ghz_sec_channel(int channel)
2961 {
2962           /*
2963            * In the 6 GHz band, primary channels are numbered as 1, 5, 9, 13.., so
2964            * the 40 MHz channels are formed with the channel pairs as (1,5),
2965            * (9,13), (17,21)..
2966            * The secondary channel for a given primary channel is below the
2967            * primary channel for the channels 5, 13, 21.. and it is above the
2968            * primary channel for the channels 1, 9, 17..
2969            */
2970 
2971           if (((channel - 1) / 4) % 2)
2972                     return -1;
2973           return 1;
2974 }
2975 
2976 
is_same_band(int freq1,int freq2)2977 bool is_same_band(int freq1, int freq2)
2978 {
2979           if (IS_2P4GHZ(freq1) && IS_2P4GHZ(freq2))
2980                     return true;
2981 
2982           if (IS_5GHZ(freq1) && IS_5GHZ(freq2))
2983                     return true;
2984 
2985           if (is_6ghz_freq(freq1) && is_6ghz_freq(freq2))
2986                     return true;
2987 
2988           return false;
2989 }
2990 
2991 
ieee802_11_parse_candidate_list(const char * pos,u8 * nei_rep,size_t nei_rep_len)2992 int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
2993                                             size_t nei_rep_len)
2994 {
2995           u8 *nei_pos = nei_rep;
2996           const char *end;
2997 
2998           /*
2999            * BSS Transition Candidate List Entries - Neighbor Report elements
3000            * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
3001            * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
3002            */
3003           while (pos) {
3004                     u8 *nei_start;
3005                     long int val;
3006                     char *endptr, *tmp;
3007 
3008                     pos = os_strstr(pos, " neighbor=");
3009                     if (!pos)
3010                               break;
3011                     if (nei_pos + 15 > nei_rep + nei_rep_len) {
3012                               wpa_printf(MSG_DEBUG,
3013                                            "Not enough room for additional neighbor");
3014                               return -1;
3015                     }
3016                     pos += 10;
3017 
3018                     nei_start = nei_pos;
3019                     *nei_pos++ = WLAN_EID_NEIGHBOR_REPORT;
3020                     nei_pos++; /* length to be filled in */
3021 
3022                     if (hwaddr_aton(pos, nei_pos)) {
3023                               wpa_printf(MSG_DEBUG, "Invalid BSSID");
3024                               return -1;
3025                     }
3026                     nei_pos += ETH_ALEN;
3027                     pos += 17;
3028                     if (*pos != ',') {
3029                               wpa_printf(MSG_DEBUG, "Missing BSSID Information");
3030                               return -1;
3031                     }
3032                     pos++;
3033 
3034                     val = strtol(pos, &endptr, 0);
3035                     WPA_PUT_LE32(nei_pos, val);
3036                     nei_pos += 4;
3037                     if (*endptr != ',') {
3038                               wpa_printf(MSG_DEBUG, "Missing Operating Class");
3039                               return -1;
3040                     }
3041                     pos = endptr + 1;
3042 
3043                     *nei_pos++ = atoi(pos); /* Operating Class */
3044                     pos = os_strchr(pos, ',');
3045                     if (pos == NULL) {
3046                               wpa_printf(MSG_DEBUG, "Missing Channel Number");
3047                               return -1;
3048                     }
3049                     pos++;
3050 
3051                     *nei_pos++ = atoi(pos); /* Channel Number */
3052                     pos = os_strchr(pos, ',');
3053                     if (pos == NULL) {
3054                               wpa_printf(MSG_DEBUG, "Missing PHY Type");
3055                               return -1;
3056                     }
3057                     pos++;
3058 
3059                     *nei_pos++ = atoi(pos); /* PHY Type */
3060                     end = os_strchr(pos, ' ');
3061                     tmp = os_strchr(pos, ',');
3062                     if (tmp && (!end || tmp < end)) {
3063                               /* Optional Subelements (hexdump) */
3064                               size_t len;
3065 
3066                               pos = tmp + 1;
3067                               end = os_strchr(pos, ' ');
3068                               if (end)
3069                                         len = end - pos;
3070                               else
3071                                         len = os_strlen(pos);
3072                               if (nei_pos + len / 2 > nei_rep + nei_rep_len) {
3073                                         wpa_printf(MSG_DEBUG,
3074                                                      "Not enough room for neighbor subelements");
3075                                         return -1;
3076                               }
3077                               if (len & 0x01 ||
3078                                   hexstr2bin(pos, nei_pos, len / 2) < 0) {
3079                                         wpa_printf(MSG_DEBUG,
3080                                                      "Invalid neighbor subelement info");
3081                                         return -1;
3082                               }
3083                               nei_pos += len / 2;
3084                               pos = end;
3085                     }
3086 
3087                     nei_start[1] = nei_pos - nei_start - 2;
3088           }
3089 
3090           return nei_pos - nei_rep;
3091 }
3092 
3093 
ieee802_11_ext_capab(const u8 * ie,unsigned int capab)3094 int ieee802_11_ext_capab(const u8 *ie, unsigned int capab)
3095 {
3096           if (!ie || ie[1] <= capab / 8)
3097                     return 0;
3098           return !!(ie[2 + capab / 8] & BIT(capab % 8));
3099 }
3100 
3101 
ieee802_11_rsnx_capab_len(const u8 * rsnxe,size_t rsnxe_len,unsigned int capab)3102 bool ieee802_11_rsnx_capab_len(const u8 *rsnxe, size_t rsnxe_len,
3103                                      unsigned int capab)
3104 {
3105           const u8 *end;
3106           size_t flen, i;
3107           u32 capabs = 0;
3108 
3109           if (!rsnxe || rsnxe_len == 0)
3110                     return false;
3111           end = rsnxe + rsnxe_len;
3112           flen = (rsnxe[0] & 0x0f) + 1;
3113           if (rsnxe + flen > end)
3114                     return false;
3115           if (flen > 4)
3116                     flen = 4;
3117           for (i = 0; i < flen; i++)
3118                     capabs |= rsnxe[i] << (8 * i);
3119 
3120           return !!(capabs & BIT(capab));
3121 }
3122 
3123 
ieee802_11_rsnx_capab(const u8 * rsnxe,unsigned int capab)3124 bool ieee802_11_rsnx_capab(const u8 *rsnxe, unsigned int capab)
3125 {
3126           return ieee802_11_rsnx_capab_len(rsnxe ? rsnxe + 2 : NULL,
3127                                                    rsnxe ? rsnxe[1] : 0, capab);
3128 }
3129 
3130 
hostapd_encode_edmg_chan(int edmg_enable,u8 edmg_channel,int primary_channel,struct ieee80211_edmg_config * edmg)3131 void hostapd_encode_edmg_chan(int edmg_enable, u8 edmg_channel,
3132                                     int primary_channel,
3133                                     struct ieee80211_edmg_config *edmg)
3134 {
3135           if (!edmg_enable) {
3136                     edmg->channels = 0;
3137                     edmg->bw_config = 0;
3138                     return;
3139           }
3140 
3141           /* Only EDMG CB1 and EDMG CB2 contiguous channels supported for now */
3142           switch (edmg_channel) {
3143           case EDMG_CHANNEL_9:
3144                     edmg->channels = EDMG_CHANNEL_9_SUBCHANNELS;
3145                     edmg->bw_config = EDMG_BW_CONFIG_5;
3146                     return;
3147           case EDMG_CHANNEL_10:
3148                     edmg->channels = EDMG_CHANNEL_10_SUBCHANNELS;
3149                     edmg->bw_config = EDMG_BW_CONFIG_5;
3150                     return;
3151           case EDMG_CHANNEL_11:
3152                     edmg->channels = EDMG_CHANNEL_11_SUBCHANNELS;
3153                     edmg->bw_config = EDMG_BW_CONFIG_5;
3154                     return;
3155           case EDMG_CHANNEL_12:
3156                     edmg->channels = EDMG_CHANNEL_12_SUBCHANNELS;
3157                     edmg->bw_config = EDMG_BW_CONFIG_5;
3158                     return;
3159           case EDMG_CHANNEL_13:
3160                     edmg->channels = EDMG_CHANNEL_13_SUBCHANNELS;
3161                     edmg->bw_config = EDMG_BW_CONFIG_5;
3162                     return;
3163           default:
3164                     if (primary_channel > 0 && primary_channel < 7) {
3165                               edmg->channels = BIT(primary_channel - 1);
3166                               edmg->bw_config = EDMG_BW_CONFIG_4;
3167                     } else {
3168                               edmg->channels = 0;
3169                               edmg->bw_config = 0;
3170                     }
3171                     break;
3172           }
3173 }
3174 
3175 
3176 /* Check if the requested EDMG configuration is a subset of the allowed
3177  * EDMG configuration. */
ieee802_edmg_is_allowed(struct ieee80211_edmg_config allowed,struct ieee80211_edmg_config requested)3178 int ieee802_edmg_is_allowed(struct ieee80211_edmg_config allowed,
3179                                   struct ieee80211_edmg_config requested)
3180 {
3181           /*
3182            * The validation check if the requested EDMG configuration
3183            * is a subset of the allowed EDMG configuration:
3184            * 1. Check that the requested channels are part (set) of the allowed
3185            * channels.
3186            * 2. P802.11ay defines the values of bw_config between 4 and 15.
3187            * (bw config % 4) will give us 4 groups inside bw_config definition,
3188            * inside each group we can check the subset just by comparing the
3189            * bw_config value.
3190            * Between this 4 groups, there is no subset relation - as a result of
3191            * the P802.11ay definition.
3192            * bw_config defined by IEEE P802.11ay/D4.0, 9.4.2.251, Table 13.
3193            */
3194           if (((requested.channels & allowed.channels) != requested.channels) ||
3195               ((requested.bw_config % 4) > (allowed.bw_config % 4)) ||
3196               requested.bw_config > allowed.bw_config)
3197                     return 0;
3198 
3199           return 1;
3200 }
3201 
3202 
op_class_to_bandwidth(u8 op_class)3203 int op_class_to_bandwidth(u8 op_class)
3204 {
3205           switch (op_class) {
3206           case 81:
3207           case 82:
3208                     return 20;
3209           case 83: /* channels 1..9; 40 MHz */
3210           case 84: /* channels 5..13; 40 MHz */
3211                     return 40;
3212           case 115: /* channels 36,40,44,48; indoor only */
3213                     return 20;
3214           case 116: /* channels 36,44; 40 MHz; indoor only */
3215           case 117: /* channels 40,48; 40 MHz; indoor only */
3216                     return 40;
3217           case 118: /* channels 52,56,60,64; dfs */
3218                     return 20;
3219           case 119: /* channels 52,60; 40 MHz; dfs */
3220           case 120: /* channels 56,64; 40 MHz; dfs */
3221                     return 40;
3222           case 121: /* channels 100-144 */
3223                     return 20;
3224           case 122: /* channels 100-140; 40 MHz */
3225           case 123: /* channels 104-144; 40 MHz */
3226                     return 40;
3227           case 124: /* channels 149,153,157,161 */
3228           case 125: /* channels 149,153,157,161,165,169,173,177 */
3229                     return 20;
3230           case 126: /* channels 149,157,161,165,169,173; 40 MHz */
3231           case 127: /* channels 153..177; 40 MHz */
3232                     return 40;
3233           case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
3234                     return 80;
3235           case 129: /* center freqs 50, 114, 163; 160 MHz */
3236                     return 160;
3237           case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80+80 MHz */
3238                     return 80;
3239           case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
3240                     return 20;
3241           case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
3242                     return 40;
3243           case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
3244                     return 80;
3245           case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
3246           case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
3247                     return 160;
3248           case 136: /* UHB channels, 20 MHz: 2 */
3249                     return 20;
3250           case 137: /* UHB channels, 320 MHz: 31, 63, 95, 127, 159, 191 */
3251                     return 320;
3252           case 180: /* 60 GHz band, channels 1..8 */
3253                     return 2160;
3254           case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
3255                     return 4320;
3256           case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
3257                     return 6480;
3258           case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
3259                     return 8640;
3260           default:
3261                     return 20;
3262           }
3263 }
3264 
3265 
op_class_to_ch_width(u8 op_class)3266 enum oper_chan_width op_class_to_ch_width(u8 op_class)
3267 {
3268           switch (op_class) {
3269           case 81:
3270           case 82:
3271                     return CONF_OPER_CHWIDTH_USE_HT;
3272           case 83: /* channels 1..9; 40 MHz */
3273           case 84: /* channels 5..13; 40 MHz */
3274                     return CONF_OPER_CHWIDTH_USE_HT;
3275           case 115: /* channels 36,40,44,48; indoor only */
3276                     return CONF_OPER_CHWIDTH_USE_HT;
3277           case 116: /* channels 36,44; 40 MHz; indoor only */
3278           case 117: /* channels 40,48; 40 MHz; indoor only */
3279                     return CONF_OPER_CHWIDTH_USE_HT;
3280           case 118: /* channels 52,56,60,64; dfs */
3281                     return CONF_OPER_CHWIDTH_USE_HT;
3282           case 119: /* channels 52,60; 40 MHz; dfs */
3283           case 120: /* channels 56,64; 40 MHz; dfs */
3284                     return CONF_OPER_CHWIDTH_USE_HT;
3285           case 121: /* channels 100-144 */
3286                     return CONF_OPER_CHWIDTH_USE_HT;
3287           case 122: /* channels 100-140; 40 MHz */
3288           case 123: /* channels 104-144; 40 MHz */
3289                     return CONF_OPER_CHWIDTH_USE_HT;
3290           case 124: /* channels 149,153,157,161 */
3291           case 125: /* channels 149,153,157,161,165,169,171 */
3292                     return CONF_OPER_CHWIDTH_USE_HT;
3293           case 126: /* channels 149,157,165, 173; 40 MHz */
3294           case 127: /* channels 153,161,169,177; 40 MHz */
3295                     return CONF_OPER_CHWIDTH_USE_HT;
3296           case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
3297                     return CONF_OPER_CHWIDTH_80MHZ;
3298           case 129: /* center freqs 50, 114, 163; 160 MHz */
3299                     return CONF_OPER_CHWIDTH_160MHZ;
3300           case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80+80 MHz */
3301                     return CONF_OPER_CHWIDTH_80P80MHZ;
3302           case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
3303                     return CONF_OPER_CHWIDTH_USE_HT;
3304           case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
3305                     return CONF_OPER_CHWIDTH_USE_HT;
3306           case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
3307                     return CONF_OPER_CHWIDTH_80MHZ;
3308           case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
3309                     return CONF_OPER_CHWIDTH_160MHZ;
3310           case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
3311                     return CONF_OPER_CHWIDTH_80P80MHZ;
3312           case 136: /* UHB channels, 20 MHz: 2 */
3313                     return CONF_OPER_CHWIDTH_USE_HT;
3314           case 137: /* UHB channels, 320 MHz: 31, 63, 95, 127, 159, 191 */
3315                     return CONF_OPER_CHWIDTH_320MHZ;
3316           case 180: /* 60 GHz band, channels 1..8 */
3317                     return CONF_OPER_CHWIDTH_2160MHZ;
3318           case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
3319                     return CONF_OPER_CHWIDTH_4320MHZ;
3320           case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
3321                     return CONF_OPER_CHWIDTH_6480MHZ;
3322           case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
3323                     return CONF_OPER_CHWIDTH_8640MHZ;
3324           default:
3325                     return CONF_OPER_CHWIDTH_USE_HT;
3326           }
3327 }
3328 
3329 
3330 /**
3331  * chwidth_freq2_to_ch_width - Determine channel width as enum oper_chan_width
3332  * @chwidth: Channel width integer
3333  * @freq2: Value for frequency 2. 0 is not used
3334  * Returns: enum oper_chan_width, -1 on failure
3335  */
chwidth_freq2_to_ch_width(int chwidth,int freq2)3336 int chwidth_freq2_to_ch_width(int chwidth, int freq2)
3337 {
3338           if (freq2 < 0)
3339                     return -1;
3340           if (freq2)
3341                     return CONF_OPER_CHWIDTH_80P80MHZ;
3342 
3343           switch (chwidth) {
3344           case 0:
3345           case 20:
3346           case 40:
3347                     return CONF_OPER_CHWIDTH_USE_HT;
3348           case 80:
3349                     return CONF_OPER_CHWIDTH_80MHZ;
3350           case 160:
3351                     return CONF_OPER_CHWIDTH_160MHZ;
3352           case 320:
3353                     return CONF_OPER_CHWIDTH_320MHZ;
3354           default:
3355                     wpa_printf(MSG_DEBUG, "Unknown max oper bandwidth: %d",
3356                                  chwidth);
3357                     return -1;
3358           }
3359 }
3360 
3361 
ieee802_11_defrag(const u8 * data,size_t len,bool ext_elem)3362 struct wpabuf * ieee802_11_defrag(const u8 *data, size_t len, bool ext_elem)
3363 {
3364           struct wpabuf *buf;
3365           const u8 *pos, *end = data + len;
3366           size_t min_defrag_len = ext_elem ? 255 : 256;
3367 
3368           if (!data || !len)
3369                     return NULL;
3370 
3371           if (len < min_defrag_len)
3372                     return wpabuf_alloc_copy(data, len);
3373 
3374           buf = wpabuf_alloc_copy(data, min_defrag_len - 1);
3375           if (!buf)
3376                     return NULL;
3377 
3378           pos = &data[min_defrag_len - 1];
3379           len -= min_defrag_len - 1;
3380           while (len > 2 && pos[0] == WLAN_EID_FRAGMENT && pos[1]) {
3381                     int ret;
3382                     size_t elen = 2 + pos[1];
3383 
3384                     if (elen > (size_t) (end - pos) || elen > len)
3385                               break;
3386                     ret = wpabuf_resize(&buf, pos[1]);
3387                     if (ret < 0) {
3388                               wpabuf_free(buf);
3389                               return NULL;
3390                     }
3391 
3392                     /* Copy only the fragment data (without the EID and length) */
3393                     wpabuf_put_data(buf, &pos[2], pos[1]);
3394                     pos += elen;
3395                     len -= elen;
3396           }
3397 
3398           return buf;
3399 }
3400 
3401 
get_ml_ie(const u8 * ies,size_t len,u8 type)3402 const u8 * get_ml_ie(const u8 *ies, size_t len, u8 type)
3403 {
3404           const struct element *elem;
3405 
3406           if (!ies)
3407                     return NULL;
3408 
3409           for_each_element_extid(elem, WLAN_EID_EXT_MULTI_LINK, ies, len) {
3410                     if (elem->datalen >= 2 &&
3411                         (elem->data[1] & MULTI_LINK_CONTROL_TYPE_MASK) == type)
3412                               return &elem->id;
3413           }
3414 
3415           return NULL;
3416 }
3417 
3418 
get_basic_mle_mld_addr(const u8 * buf,size_t len)3419 const u8 * get_basic_mle_mld_addr(const u8 *buf, size_t len)
3420 {
3421           const size_t mld_addr_pos =
3422                     2 /* Control field */ +
3423                     1 /* Common Info Length field */;
3424           const size_t fixed_len = mld_addr_pos +
3425                     ETH_ALEN /* MLD MAC Address field */;
3426 
3427           if (len < fixed_len)
3428                     return NULL;
3429 
3430           if ((buf[0] & MULTI_LINK_CONTROL_TYPE_MASK) !=
3431               MULTI_LINK_CONTROL_TYPE_BASIC)
3432                     return NULL;
3433 
3434           return &buf[mld_addr_pos];
3435 }
3436