LCOV - code coverage report
Current view: top level - wpa_supplicant - ctrl_iface.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1393793999 Lines: 2150 3876 55.5 %
Date: 2014-03-02 Functions: 103 151 68.2 %
Branches: 1311 2886 45.4 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * WPA Supplicant / Control interface (shared code for all backends)
       3                 :            :  * Copyright (c) 2004-2014, 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 "utils/includes.h"
      10                 :            : 
      11                 :            : #include "utils/common.h"
      12                 :            : #include "utils/eloop.h"
      13                 :            : #include "utils/uuid.h"
      14                 :            : #include "common/version.h"
      15                 :            : #include "common/ieee802_11_defs.h"
      16                 :            : #include "common/ieee802_11_common.h"
      17                 :            : #include "common/wpa_ctrl.h"
      18                 :            : #include "eap_peer/eap.h"
      19                 :            : #include "eapol_supp/eapol_supp_sm.h"
      20                 :            : #include "rsn_supp/wpa.h"
      21                 :            : #include "rsn_supp/preauth.h"
      22                 :            : #include "rsn_supp/pmksa_cache.h"
      23                 :            : #include "l2_packet/l2_packet.h"
      24                 :            : #include "wps/wps.h"
      25                 :            : #include "config.h"
      26                 :            : #include "wpa_supplicant_i.h"
      27                 :            : #include "driver_i.h"
      28                 :            : #include "wps_supplicant.h"
      29                 :            : #include "ibss_rsn.h"
      30                 :            : #include "ap.h"
      31                 :            : #include "p2p_supplicant.h"
      32                 :            : #include "p2p/p2p.h"
      33                 :            : #include "hs20_supplicant.h"
      34                 :            : #include "wifi_display.h"
      35                 :            : #include "notify.h"
      36                 :            : #include "bss.h"
      37                 :            : #include "scan.h"
      38                 :            : #include "ctrl_iface.h"
      39                 :            : #include "interworking.h"
      40                 :            : #include "blacklist.h"
      41                 :            : #include "autoscan.h"
      42                 :            : #include "wnm_sta.h"
      43                 :            : 
      44                 :            : static int wpa_supplicant_global_iface_list(struct wpa_global *global,
      45                 :            :                                             char *buf, int len);
      46                 :            : static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
      47                 :            :                                                   char *buf, int len);
      48                 :            : 
      49                 :            : 
      50                 :          2 : static int pno_start(struct wpa_supplicant *wpa_s)
      51                 :            : {
      52                 :            :         int ret, interval;
      53                 :            :         size_t i, num_ssid;
      54                 :            :         struct wpa_ssid *ssid;
      55                 :            :         struct wpa_driver_scan_params params;
      56                 :            : 
      57 [ +  - ][ -  + ]:          2 :         if (wpa_s->pno || wpa_s->pno_sched_pending)
      58                 :          0 :                 return 0;
      59                 :            : 
      60 [ -  + ][ #  # ]:          2 :         if ((wpa_s->wpa_state > WPA_SCANNING) &&
      61                 :          0 :             (wpa_s->wpa_state <= WPA_COMPLETED)) {
      62                 :          0 :                 wpa_printf(MSG_ERROR, "PNO: In assoc process");
      63                 :          0 :                 return -EAGAIN;
      64                 :            :         }
      65                 :            : 
      66         [ -  + ]:          2 :         if (wpa_s->wpa_state == WPA_SCANNING) {
      67                 :          0 :                 wpa_supplicant_cancel_scan(wpa_s);
      68         [ #  # ]:          0 :                 if (wpa_s->sched_scanning) {
      69                 :          0 :                         wpa_printf(MSG_DEBUG, "Schedule PNO on completion of "
      70                 :            :                                    "ongoing sched scan");
      71                 :          0 :                         wpa_supplicant_cancel_sched_scan(wpa_s);
      72                 :          0 :                         wpa_s->pno_sched_pending = 1;
      73                 :          0 :                         return 0;
      74                 :            :                 }
      75                 :            :         }
      76                 :            : 
      77                 :          2 :         os_memset(&params, 0, sizeof(params));
      78                 :            : 
      79                 :          2 :         num_ssid = 0;
      80                 :          2 :         ssid = wpa_s->conf->ssid;
      81         [ +  + ]:          3 :         while (ssid) {
      82         [ +  - ]:          1 :                 if (!wpas_network_disabled(wpa_s, ssid))
      83                 :          1 :                         num_ssid++;
      84                 :          1 :                 ssid = ssid->next;
      85                 :            :         }
      86         [ -  + ]:          2 :         if (num_ssid > WPAS_MAX_SCAN_SSIDS) {
      87                 :          0 :                 wpa_printf(MSG_DEBUG, "PNO: Use only the first %u SSIDs from "
      88                 :            :                            "%u", WPAS_MAX_SCAN_SSIDS, (unsigned int) num_ssid);
      89                 :          0 :                 num_ssid = WPAS_MAX_SCAN_SSIDS;
      90                 :            :         }
      91                 :            : 
      92         [ +  + ]:          2 :         if (num_ssid == 0) {
      93                 :          1 :                 wpa_printf(MSG_DEBUG, "PNO: No configured SSIDs");
      94                 :          1 :                 return -1;
      95                 :            :         }
      96                 :            : 
      97                 :          1 :         params.filter_ssids = os_malloc(sizeof(struct wpa_driver_scan_filter) *
      98                 :            :                                         num_ssid);
      99         [ -  + ]:          1 :         if (params.filter_ssids == NULL)
     100                 :          0 :                 return -1;
     101                 :          1 :         i = 0;
     102                 :          1 :         ssid = wpa_s->conf->ssid;
     103         [ +  - ]:          1 :         while (ssid) {
     104         [ +  - ]:          1 :                 if (!wpas_network_disabled(wpa_s, ssid)) {
     105                 :          1 :                         params.ssids[i].ssid = ssid->ssid;
     106                 :          1 :                         params.ssids[i].ssid_len = ssid->ssid_len;
     107                 :          1 :                         params.num_ssids++;
     108                 :          1 :                         os_memcpy(params.filter_ssids[i].ssid, ssid->ssid,
     109                 :            :                                   ssid->ssid_len);
     110                 :          1 :                         params.filter_ssids[i].ssid_len = ssid->ssid_len;
     111                 :          1 :                         params.num_filter_ssids++;
     112                 :          1 :                         i++;
     113         [ +  - ]:          1 :                         if (i == num_ssid)
     114                 :          1 :                                 break;
     115                 :            :                 }
     116                 :          0 :                 ssid = ssid->next;
     117                 :            :         }
     118                 :            : 
     119         [ -  + ]:          1 :         if (wpa_s->conf->filter_rssi)
     120                 :          0 :                 params.filter_rssi = wpa_s->conf->filter_rssi;
     121                 :            : 
     122         [ -  + ]:          1 :         interval = wpa_s->conf->sched_scan_interval ?
     123                 :          0 :                 wpa_s->conf->sched_scan_interval : 10;
     124                 :            : 
     125                 :          1 :         ret = wpa_supplicant_start_sched_scan(wpa_s, &params, interval);
     126                 :          1 :         os_free(params.filter_ssids);
     127         [ -  + ]:          1 :         if (ret == 0)
     128                 :          0 :                 wpa_s->pno = 1;
     129                 :          2 :         return ret;
     130                 :            : }
     131                 :            : 
     132                 :            : 
     133                 :          1 : static int pno_stop(struct wpa_supplicant *wpa_s)
     134                 :            : {
     135                 :          1 :         int ret = 0;
     136                 :            : 
     137 [ +  - ][ -  + ]:          1 :         if (wpa_s->pno || wpa_s->sched_scanning) {
     138                 :          0 :                 wpa_s->pno = 0;
     139                 :          0 :                 ret = wpa_supplicant_stop_sched_scan(wpa_s);
     140                 :            :         }
     141                 :            : 
     142                 :          1 :         wpa_s->pno_sched_pending = 0;
     143                 :            : 
     144         [ -  + ]:          1 :         if (wpa_s->wpa_state == WPA_SCANNING)
     145                 :          0 :                 wpa_supplicant_req_scan(wpa_s, 0, 0);
     146                 :            : 
     147                 :          1 :         return ret;
     148                 :            : }
     149                 :            : 
     150                 :            : 
     151                 :          0 : static int set_bssid_filter(struct wpa_supplicant *wpa_s, char *val)
     152                 :            : {
     153                 :            :         char *pos;
     154                 :          0 :         u8 addr[ETH_ALEN], *filter = NULL, *n;
     155                 :          0 :         size_t count = 0;
     156                 :            : 
     157                 :          0 :         pos = val;
     158         [ #  # ]:          0 :         while (pos) {
     159         [ #  # ]:          0 :                 if (*pos == '\0')
     160                 :          0 :                         break;
     161         [ #  # ]:          0 :                 if (hwaddr_aton(pos, addr)) {
     162                 :          0 :                         os_free(filter);
     163                 :          0 :                         return -1;
     164                 :            :                 }
     165                 :          0 :                 n = os_realloc_array(filter, count + 1, ETH_ALEN);
     166         [ #  # ]:          0 :                 if (n == NULL) {
     167                 :          0 :                         os_free(filter);
     168                 :          0 :                         return -1;
     169                 :            :                 }
     170                 :          0 :                 filter = n;
     171                 :          0 :                 os_memcpy(filter + count * ETH_ALEN, addr, ETH_ALEN);
     172                 :          0 :                 count++;
     173                 :            : 
     174                 :          0 :                 pos = os_strchr(pos, ' ');
     175         [ #  # ]:          0 :                 if (pos)
     176                 :          0 :                         pos++;
     177                 :            :         }
     178                 :            : 
     179                 :          0 :         wpa_hexdump(MSG_DEBUG, "bssid_filter", filter, count * ETH_ALEN);
     180                 :          0 :         os_free(wpa_s->bssid_filter);
     181                 :          0 :         wpa_s->bssid_filter = filter;
     182                 :          0 :         wpa_s->bssid_filter_count = count;
     183                 :            : 
     184                 :          0 :         return 0;
     185                 :            : }
     186                 :            : 
     187                 :            : 
     188                 :          4 : static int set_disallow_aps(struct wpa_supplicant *wpa_s, char *val)
     189                 :            : {
     190                 :            :         char *pos;
     191                 :          4 :         u8 addr[ETH_ALEN], *bssid = NULL, *n;
     192                 :          4 :         struct wpa_ssid_value *ssid = NULL, *ns;
     193                 :          4 :         size_t count = 0, ssid_count = 0;
     194                 :            :         struct wpa_ssid *c;
     195                 :            : 
     196                 :            :         /*
     197                 :            :          * disallow_list ::= <ssid_spec> | <bssid_spec> | <disallow_list> | ""
     198                 :            :          * SSID_SPEC ::= ssid <SSID_HEX>
     199                 :            :          * BSSID_SPEC ::= bssid <BSSID_HEX>
     200                 :            :          */
     201                 :            : 
     202                 :          4 :         pos = val;
     203         [ +  + ]:          7 :         while (pos) {
     204         [ +  + ]:          4 :                 if (*pos == '\0')
     205                 :          1 :                         break;
     206         [ +  + ]:          3 :                 if (os_strncmp(pos, "bssid ", 6) == 0) {
     207                 :            :                         int res;
     208                 :          2 :                         pos += 6;
     209                 :          2 :                         res = hwaddr_aton2(pos, addr);
     210         [ -  + ]:          2 :                         if (res < 0) {
     211                 :          0 :                                 os_free(ssid);
     212                 :          0 :                                 os_free(bssid);
     213                 :          0 :                                 wpa_printf(MSG_DEBUG, "Invalid disallow_aps "
     214                 :            :                                            "BSSID value '%s'", pos);
     215                 :          0 :                                 return -1;
     216                 :            :                         }
     217                 :          2 :                         pos += res;
     218                 :          2 :                         n = os_realloc_array(bssid, count + 1, ETH_ALEN);
     219         [ -  + ]:          2 :                         if (n == NULL) {
     220                 :          0 :                                 os_free(ssid);
     221                 :          0 :                                 os_free(bssid);
     222                 :          0 :                                 return -1;
     223                 :            :                         }
     224                 :          2 :                         bssid = n;
     225                 :          2 :                         os_memcpy(bssid + count * ETH_ALEN, addr, ETH_ALEN);
     226                 :          2 :                         count++;
     227         [ +  - ]:          1 :                 } else if (os_strncmp(pos, "ssid ", 5) == 0) {
     228                 :            :                         char *end;
     229                 :          1 :                         pos += 5;
     230                 :            : 
     231                 :          1 :                         end = pos;
     232         [ +  + ]:         19 :                         while (*end) {
     233 [ +  - ][ +  - ]:         18 :                                 if (*end == '\0' || *end == ' ')
     234                 :            :                                         break;
     235                 :         18 :                                 end++;
     236                 :            :                         }
     237                 :            : 
     238                 :          1 :                         ns = os_realloc_array(ssid, ssid_count + 1,
     239                 :            :                                               sizeof(struct wpa_ssid_value));
     240         [ -  + ]:          1 :                         if (ns == NULL) {
     241                 :          0 :                                 os_free(ssid);
     242                 :          0 :                                 os_free(bssid);
     243                 :          0 :                                 return -1;
     244                 :            :                         }
     245                 :          1 :                         ssid = ns;
     246                 :            : 
     247         [ +  - ]:          2 :                         if ((end - pos) & 0x01 || end - pos > 2 * 32 ||
           [ +  -  -  + ]
     248                 :          1 :                             hexstr2bin(pos, ssid[ssid_count].ssid,
     249                 :          1 :                                        (end - pos) / 2) < 0) {
     250                 :          0 :                                 os_free(ssid);
     251                 :          0 :                                 os_free(bssid);
     252                 :          0 :                                 wpa_printf(MSG_DEBUG, "Invalid disallow_aps "
     253                 :            :                                            "SSID value '%s'", pos);
     254                 :          0 :                                 return -1;
     255                 :            :                         }
     256                 :          1 :                         ssid[ssid_count].ssid_len = (end - pos) / 2;
     257                 :          1 :                         wpa_hexdump_ascii(MSG_DEBUG, "disallow_aps SSID",
     258                 :          1 :                                           ssid[ssid_count].ssid,
     259                 :          1 :                                           ssid[ssid_count].ssid_len);
     260                 :          1 :                         ssid_count++;
     261                 :          1 :                         pos = end;
     262                 :            :                 } else {
     263                 :          0 :                         wpa_printf(MSG_DEBUG, "Unexpected disallow_aps value "
     264                 :            :                                    "'%s'", pos);
     265                 :          0 :                         os_free(ssid);
     266                 :          0 :                         os_free(bssid);
     267                 :          0 :                         return -1;
     268                 :            :                 }
     269                 :            : 
     270                 :          3 :                 pos = os_strchr(pos, ' ');
     271         [ -  + ]:          3 :                 if (pos)
     272                 :          0 :                         pos++;
     273                 :            :         }
     274                 :            : 
     275                 :          4 :         wpa_hexdump(MSG_DEBUG, "disallow_aps_bssid", bssid, count * ETH_ALEN);
     276                 :          4 :         os_free(wpa_s->disallow_aps_bssid);
     277                 :          4 :         wpa_s->disallow_aps_bssid = bssid;
     278                 :          4 :         wpa_s->disallow_aps_bssid_count = count;
     279                 :            : 
     280                 :          4 :         wpa_printf(MSG_DEBUG, "disallow_aps_ssid_count %d", (int) ssid_count);
     281                 :          4 :         os_free(wpa_s->disallow_aps_ssid);
     282                 :          4 :         wpa_s->disallow_aps_ssid = ssid;
     283                 :          4 :         wpa_s->disallow_aps_ssid_count = ssid_count;
     284                 :            : 
     285 [ -  + ][ #  # ]:          4 :         if (!wpa_s->current_ssid || wpa_s->wpa_state < WPA_AUTHENTICATING)
     286                 :          4 :                 return 0;
     287                 :            : 
     288                 :          0 :         c = wpa_s->current_ssid;
     289 [ #  # ][ #  # ]:          0 :         if (c->mode != WPAS_MODE_INFRA && c->mode != WPAS_MODE_IBSS)
     290                 :          0 :                 return 0;
     291                 :            : 
     292   [ #  #  #  # ]:          0 :         if (!disallowed_bssid(wpa_s, wpa_s->bssid) &&
     293                 :          0 :             !disallowed_ssid(wpa_s, c->ssid, c->ssid_len))
     294                 :          0 :                 return 0;
     295                 :            : 
     296                 :          0 :         wpa_printf(MSG_DEBUG, "Disconnect and try to find another network "
     297                 :            :                    "because current AP was marked disallowed");
     298                 :            : 
     299                 :            : #ifdef CONFIG_SME
     300                 :          0 :         wpa_s->sme.prev_bssid_set = 0;
     301                 :            : #endif /* CONFIG_SME */
     302                 :          0 :         wpa_s->reassociate = 1;
     303                 :          0 :         wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
     304                 :          0 :         wpa_supplicant_req_scan(wpa_s, 0, 0);
     305                 :            : 
     306                 :          4 :         return 0;
     307                 :            : }
     308                 :            : 
     309                 :            : 
     310                 :      10842 : static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
     311                 :            :                                          char *cmd)
     312                 :            : {
     313                 :            :         char *value;
     314                 :      10842 :         int ret = 0;
     315                 :            : 
     316                 :      10842 :         value = os_strchr(cmd, ' ');
     317         [ -  + ]:      10842 :         if (value == NULL)
     318                 :          0 :                 return -1;
     319                 :      10842 :         *value++ = '\0';
     320                 :            : 
     321                 :      10842 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value);
     322         [ -  + ]:      10842 :         if (os_strcasecmp(cmd, "EAPOL::heldPeriod") == 0) {
     323                 :          0 :                 eapol_sm_configure(wpa_s->eapol,
     324                 :            :                                    atoi(value), -1, -1, -1);
     325         [ -  + ]:      10842 :         } else if (os_strcasecmp(cmd, "EAPOL::authPeriod") == 0) {
     326                 :          0 :                 eapol_sm_configure(wpa_s->eapol,
     327                 :            :                                    -1, atoi(value), -1, -1);
     328         [ -  + ]:      10842 :         } else if (os_strcasecmp(cmd, "EAPOL::startPeriod") == 0) {
     329                 :          0 :                 eapol_sm_configure(wpa_s->eapol,
     330                 :            :                                    -1, -1, atoi(value), -1);
     331         [ -  + ]:      10842 :         } else if (os_strcasecmp(cmd, "EAPOL::maxStart") == 0) {
     332                 :          0 :                 eapol_sm_configure(wpa_s->eapol,
     333                 :            :                                    -1, -1, -1, atoi(value));
     334         [ +  + ]:      10842 :         } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) {
     335         [ -  + ]:          1 :                 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
     336                 :          1 :                                      atoi(value)))
     337                 :          0 :                         ret = -1;
     338         [ -  + ]:      10841 :         } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") ==
     339                 :            :                    0) {
     340         [ #  # ]:          0 :                 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
     341                 :          0 :                                      atoi(value)))
     342                 :          0 :                         ret = -1;
     343         [ -  + ]:      10841 :         } else if (os_strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) {
     344         [ #  # ]:          0 :                 if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value)))
     345                 :          0 :                         ret = -1;
     346         [ +  + ]:      10841 :         } else if (os_strcasecmp(cmd, "wps_fragment_size") == 0) {
     347                 :          1 :                 wpa_s->wps_fragment_size = atoi(value);
     348                 :            : #ifdef CONFIG_WPS_TESTING
     349         [ +  + ]:      10840 :         } else if (os_strcasecmp(cmd, "wps_version_number") == 0) {
     350                 :            :                 long int val;
     351                 :          3 :                 val = strtol(value, NULL, 0);
     352 [ +  - ][ -  + ]:          3 :                 if (val < 0 || val > 0xff) {
     353                 :          0 :                         ret = -1;
     354                 :          0 :                         wpa_printf(MSG_DEBUG, "WPS: Invalid "
     355                 :            :                                    "wps_version_number %ld", val);
     356                 :            :                 } else {
     357                 :          3 :                         wps_version_number = val;
     358                 :          3 :                         wpa_printf(MSG_DEBUG, "WPS: Testing - force WPS "
     359                 :            :                                    "version %u.%u",
     360                 :          3 :                                    (wps_version_number & 0xf0) >> 4,
     361                 :            :                                    wps_version_number & 0x0f);
     362                 :            :                 }
     363         [ -  + ]:      10837 :         } else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) {
     364                 :          0 :                 wps_testing_dummy_cred = atoi(value);
     365                 :          0 :                 wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d",
     366                 :            :                            wps_testing_dummy_cred);
     367         [ +  + ]:      10837 :         } else if (os_strcasecmp(cmd, "wps_corrupt_pkhash") == 0) {
     368                 :          3 :                 wps_corrupt_pkhash = atoi(value);
     369                 :          3 :                 wpa_printf(MSG_DEBUG, "WPS: Testing - wps_corrupt_pkhash=%d",
     370                 :            :                            wps_corrupt_pkhash);
     371                 :            : #endif /* CONFIG_WPS_TESTING */
     372         [ -  + ]:      10834 :         } else if (os_strcasecmp(cmd, "ampdu") == 0) {
     373         [ #  # ]:          0 :                 if (wpa_drv_ampdu(wpa_s, atoi(value)) < 0)
     374                 :          0 :                         ret = -1;
     375                 :            : #ifdef CONFIG_TDLS
     376                 :            : #ifdef CONFIG_TDLS_TESTING
     377         [ +  + ]:      10834 :         } else if (os_strcasecmp(cmd, "tdls_testing") == 0) {
     378                 :            :                 extern unsigned int tdls_testing;
     379                 :          8 :                 tdls_testing = strtol(value, NULL, 0);
     380                 :          8 :                 wpa_printf(MSG_DEBUG, "TDLS: tdls_testing=0x%x", tdls_testing);
     381                 :            : #endif /* CONFIG_TDLS_TESTING */
     382         [ -  + ]:      10826 :         } else if (os_strcasecmp(cmd, "tdls_disabled") == 0) {
     383                 :          0 :                 int disabled = atoi(value);
     384                 :          0 :                 wpa_printf(MSG_DEBUG, "TDLS: tdls_disabled=%d", disabled);
     385         [ #  # ]:          0 :                 if (disabled) {
     386         [ #  # ]:          0 :                         if (wpa_drv_tdls_oper(wpa_s, TDLS_DISABLE, NULL) < 0)
     387                 :          0 :                                 ret = -1;
     388         [ #  # ]:          0 :                 } else if (wpa_drv_tdls_oper(wpa_s, TDLS_ENABLE, NULL) < 0)
     389                 :          0 :                         ret = -1;
     390                 :          0 :                 wpa_tdls_enable(wpa_s->wpa, !disabled);
     391                 :            : #endif /* CONFIG_TDLS */
     392         [ +  + ]:      10826 :         } else if (os_strcasecmp(cmd, "pno") == 0) {
     393         [ +  + ]:          3 :                 if (atoi(value))
     394                 :          2 :                         ret = pno_start(wpa_s);
     395                 :            :                 else
     396                 :          1 :                         ret = pno_stop(wpa_s);
     397         [ -  + ]:      10823 :         } else if (os_strcasecmp(cmd, "radio_disabled") == 0) {
     398                 :          0 :                 int disabled = atoi(value);
     399         [ #  # ]:          0 :                 if (wpa_drv_radio_disable(wpa_s, disabled) < 0)
     400                 :          0 :                         ret = -1;
     401         [ #  # ]:          0 :                 else if (disabled)
     402                 :          0 :                         wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
     403         [ -  + ]:      10823 :         } else if (os_strcasecmp(cmd, "uapsd") == 0) {
     404         [ #  # ]:          0 :                 if (os_strcmp(value, "disable") == 0)
     405                 :          0 :                         wpa_s->set_sta_uapsd = 0;
     406                 :            :                 else {
     407                 :            :                         int be, bk, vi, vo;
     408                 :            :                         char *pos;
     409                 :            :                         /* format: BE,BK,VI,VO;max SP Length */
     410                 :          0 :                         be = atoi(value);
     411                 :          0 :                         pos = os_strchr(value, ',');
     412         [ #  # ]:          0 :                         if (pos == NULL)
     413                 :          0 :                                 return -1;
     414                 :          0 :                         pos++;
     415                 :          0 :                         bk = atoi(pos);
     416                 :          0 :                         pos = os_strchr(pos, ',');
     417         [ #  # ]:          0 :                         if (pos == NULL)
     418                 :          0 :                                 return -1;
     419                 :          0 :                         pos++;
     420                 :          0 :                         vi = atoi(pos);
     421                 :          0 :                         pos = os_strchr(pos, ',');
     422         [ #  # ]:          0 :                         if (pos == NULL)
     423                 :          0 :                                 return -1;
     424                 :          0 :                         pos++;
     425                 :          0 :                         vo = atoi(pos);
     426                 :            :                         /* ignore max SP Length for now */
     427                 :            : 
     428                 :          0 :                         wpa_s->set_sta_uapsd = 1;
     429                 :          0 :                         wpa_s->sta_uapsd = 0;
     430         [ #  # ]:          0 :                         if (be)
     431                 :          0 :                                 wpa_s->sta_uapsd |= BIT(0);
     432         [ #  # ]:          0 :                         if (bk)
     433                 :          0 :                                 wpa_s->sta_uapsd |= BIT(1);
     434         [ #  # ]:          0 :                         if (vi)
     435                 :          0 :                                 wpa_s->sta_uapsd |= BIT(2);
     436         [ #  # ]:          0 :                         if (vo)
     437                 :          0 :                                 wpa_s->sta_uapsd |= BIT(3);
     438                 :            :                 }
     439         [ -  + ]:      10823 :         } else if (os_strcasecmp(cmd, "ps") == 0) {
     440                 :          0 :                 ret = wpa_drv_set_p2p_powersave(wpa_s, atoi(value), -1, -1);
     441                 :            : #ifdef CONFIG_WIFI_DISPLAY
     442         [ +  + ]:      10823 :         } else if (os_strcasecmp(cmd, "wifi_display") == 0) {
     443                 :          3 :                 int enabled = !!atoi(value);
     444 [ +  - ][ -  + ]:          3 :                 if (enabled && !wpa_s->global->p2p)
     445                 :          0 :                         ret = -1;
     446                 :            :                 else
     447                 :          3 :                         wifi_display_enable(wpa_s->global, enabled);
     448                 :            : #endif /* CONFIG_WIFI_DISPLAY */
     449         [ -  + ]:      10820 :         } else if (os_strcasecmp(cmd, "bssid_filter") == 0) {
     450                 :          0 :                 ret = set_bssid_filter(wpa_s, value);
     451         [ +  + ]:      10820 :         } else if (os_strcasecmp(cmd, "disallow_aps") == 0) {
     452                 :          4 :                 ret = set_disallow_aps(wpa_s, value);
     453         [ -  + ]:      10816 :         } else if (os_strcasecmp(cmd, "no_keep_alive") == 0) {
     454                 :          0 :                 wpa_s->no_keep_alive = !!atoi(value);
     455                 :            :         } else {
     456                 :      10816 :                 value[-1] = '=';
     457                 :      10816 :                 ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
     458         [ +  + ]:      10816 :                 if (ret == 0)
     459                 :      10812 :                         wpa_supplicant_update_config(wpa_s);
     460                 :            :         }
     461                 :            : 
     462                 :      10842 :         return ret;
     463                 :            : }
     464                 :            : 
     465                 :            : 
     466                 :          3 : static int wpa_supplicant_ctrl_iface_get(struct wpa_supplicant *wpa_s,
     467                 :            :                                          char *cmd, char *buf, size_t buflen)
     468                 :            : {
     469                 :          3 :         int res = -1;
     470                 :            : 
     471                 :          3 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE GET '%s'", cmd);
     472                 :            : 
     473         [ +  + ]:          3 :         if (os_strcmp(cmd, "version") == 0) {
     474                 :          1 :                 res = os_snprintf(buf, buflen, "%s", VERSION_STR);
     475         [ -  + ]:          2 :         } else if (os_strcasecmp(cmd, "country") == 0) {
     476 [ #  # ][ #  # ]:          0 :                 if (wpa_s->conf->country[0] && wpa_s->conf->country[1])
     477                 :          0 :                         res = os_snprintf(buf, buflen, "%c%c",
     478                 :          0 :                                           wpa_s->conf->country[0],
     479                 :          0 :                                           wpa_s->conf->country[1]);
     480                 :            : #ifdef CONFIG_WIFI_DISPLAY
     481         [ +  + ]:          2 :         } else if (os_strcasecmp(cmd, "wifi_display") == 0) {
     482                 :            :                 int enabled;
     483 [ +  - ][ -  + ]:          1 :                 if (wpa_s->global->p2p == NULL ||
     484                 :          1 :                     wpa_s->global->p2p_disabled)
     485                 :          0 :                         enabled = 0;
     486                 :            :                 else
     487                 :          1 :                         enabled = wpa_s->global->wifi_display;
     488                 :          1 :                 res = os_snprintf(buf, buflen, "%d", enabled);
     489 [ +  - ][ -  + ]:          1 :                 if (res < 0 || (unsigned int) res >= buflen)
     490                 :          0 :                         return -1;
     491                 :          1 :                 return res;
     492                 :            : #endif /* CONFIG_WIFI_DISPLAY */
     493                 :            : #ifdef CONFIG_TESTING_GET_GTK
     494                 :            :         } else if (os_strcmp(cmd, "gtk") == 0) {
     495                 :            :                 if (wpa_s->last_gtk_len == 0)
     496                 :            :                         return -1;
     497                 :            :                 res = wpa_snprintf_hex(buf, buflen, wpa_s->last_gtk,
     498                 :            :                                        wpa_s->last_gtk_len);
     499                 :            :                 return res;
     500                 :            : #endif /* CONFIG_TESTING_GET_GTK */
     501                 :            :         }
     502                 :            : 
     503 [ +  + ][ -  + ]:          2 :         if (res < 0 || (unsigned int) res >= buflen)
     504                 :          1 :                 return -1;
     505                 :          3 :         return res;
     506                 :            : }
     507                 :            : 
     508                 :            : 
     509                 :            : #ifdef IEEE8021X_EAPOL
     510                 :          2 : static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,
     511                 :            :                                              char *addr)
     512                 :            : {
     513                 :            :         u8 bssid[ETH_ALEN];
     514                 :          2 :         struct wpa_ssid *ssid = wpa_s->current_ssid;
     515                 :            : 
     516         [ +  + ]:          2 :         if (hwaddr_aton(addr, bssid)) {
     517                 :          1 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address "
     518                 :            :                            "'%s'", addr);
     519                 :          1 :                 return -1;
     520                 :            :         }
     521                 :            : 
     522                 :          1 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid));
     523                 :          1 :         rsn_preauth_deinit(wpa_s->wpa);
     524 [ -  + ][ -  + ]:          1 :         if (rsn_preauth_init(wpa_s->wpa, bssid, ssid ? &ssid->eap : NULL))
     525                 :          0 :                 return -1;
     526                 :            : 
     527                 :          2 :         return 0;
     528                 :            : }
     529                 :            : #endif /* IEEE8021X_EAPOL */
     530                 :            : 
     531                 :            : 
     532                 :            : #ifdef CONFIG_PEERKEY
     533                 :            : /* MLME-STKSTART.request(peer) */
     534                 :          3 : static int wpa_supplicant_ctrl_iface_stkstart(
     535                 :            :         struct wpa_supplicant *wpa_s, char *addr)
     536                 :            : {
     537                 :            :         u8 peer[ETH_ALEN];
     538                 :            : 
     539         [ +  + ]:          3 :         if (hwaddr_aton(addr, peer)) {
     540                 :          1 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid "
     541                 :            :                            "address '%s'", addr);
     542                 :          1 :                 return -1;
     543                 :            :         }
     544                 :            : 
     545                 :          2 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR,
     546                 :         12 :                    MAC2STR(peer));
     547                 :            : 
     548                 :          3 :         return wpa_sm_stkstart(wpa_s->wpa, peer);
     549                 :            : }
     550                 :            : #endif /* CONFIG_PEERKEY */
     551                 :            : 
     552                 :            : 
     553                 :            : #ifdef CONFIG_TDLS
     554                 :            : 
     555                 :          2 : static int wpa_supplicant_ctrl_iface_tdls_discover(
     556                 :            :         struct wpa_supplicant *wpa_s, char *addr)
     557                 :            : {
     558                 :            :         u8 peer[ETH_ALEN];
     559                 :            :         int ret;
     560                 :            : 
     561         [ +  + ]:          2 :         if (hwaddr_aton(addr, peer)) {
     562                 :          1 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER: invalid "
     563                 :            :                            "address '%s'", addr);
     564                 :          1 :                 return -1;
     565                 :            :         }
     566                 :            : 
     567                 :          1 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER " MACSTR,
     568                 :          6 :                    MAC2STR(peer));
     569                 :            : 
     570         [ +  - ]:          1 :         if (wpa_tdls_is_external_setup(wpa_s->wpa))
     571                 :          1 :                 ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
     572                 :            :         else
     573                 :          0 :                 ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
     574                 :            : 
     575                 :          2 :         return ret;
     576                 :            : }
     577                 :            : 
     578                 :            : 
     579                 :         21 : static int wpa_supplicant_ctrl_iface_tdls_setup(
     580                 :            :         struct wpa_supplicant *wpa_s, char *addr)
     581                 :            : {
     582                 :            :         u8 peer[ETH_ALEN];
     583                 :            :         int ret;
     584                 :            : 
     585         [ -  + ]:         21 :         if (hwaddr_aton(addr, peer)) {
     586                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP: invalid "
     587                 :            :                            "address '%s'", addr);
     588                 :          0 :                 return -1;
     589                 :            :         }
     590                 :            : 
     591                 :         21 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP " MACSTR,
     592                 :        126 :                    MAC2STR(peer));
     593                 :            : 
     594   [ -  +  #  # ]:         21 :         if ((wpa_s->conf->tdls_external_control) &&
     595                 :          0 :             wpa_tdls_is_external_setup(wpa_s->wpa))
     596                 :          0 :                 return wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
     597                 :            : 
     598                 :         21 :         wpa_tdls_remove(wpa_s->wpa, peer);
     599                 :            : 
     600         [ +  - ]:         21 :         if (wpa_tdls_is_external_setup(wpa_s->wpa))
     601                 :         21 :                 ret = wpa_tdls_start(wpa_s->wpa, peer);
     602                 :            :         else
     603                 :          0 :                 ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
     604                 :            : 
     605                 :         21 :         return ret;
     606                 :            : }
     607                 :            : 
     608                 :            : 
     609                 :          8 : static int wpa_supplicant_ctrl_iface_tdls_teardown(
     610                 :            :         struct wpa_supplicant *wpa_s, char *addr)
     611                 :            : {
     612                 :            :         u8 peer[ETH_ALEN];
     613                 :            :         int ret;
     614                 :            : 
     615         [ -  + ]:          8 :         if (hwaddr_aton(addr, peer)) {
     616                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN: invalid "
     617                 :            :                            "address '%s'", addr);
     618                 :          0 :                 return -1;
     619                 :            :         }
     620                 :            : 
     621                 :          8 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN " MACSTR,
     622                 :         48 :                    MAC2STR(peer));
     623                 :            : 
     624   [ -  +  #  # ]:          8 :         if ((wpa_s->conf->tdls_external_control) &&
     625                 :          0 :             wpa_tdls_is_external_setup(wpa_s->wpa))
     626                 :          0 :                 return wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
     627                 :            : 
     628         [ +  - ]:          8 :         if (wpa_tdls_is_external_setup(wpa_s->wpa))
     629                 :          8 :                 ret = wpa_tdls_teardown_link(
     630                 :            :                         wpa_s->wpa, peer,
     631                 :            :                         WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
     632                 :            :         else
     633                 :          0 :                 ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
     634                 :            : 
     635                 :          8 :         return ret;
     636                 :            : }
     637                 :            : 
     638                 :            : #endif /* CONFIG_TDLS */
     639                 :            : 
     640                 :            : 
     641                 :            : #ifdef CONFIG_IEEE80211R
     642                 :          6 : static int wpa_supplicant_ctrl_iface_ft_ds(
     643                 :            :         struct wpa_supplicant *wpa_s, char *addr)
     644                 :            : {
     645                 :            :         u8 target_ap[ETH_ALEN];
     646                 :            :         struct wpa_bss *bss;
     647                 :            :         const u8 *mdie;
     648                 :            : 
     649         [ -  + ]:          6 :         if (hwaddr_aton(addr, target_ap)) {
     650                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid "
     651                 :            :                            "address '%s'", addr);
     652                 :          0 :                 return -1;
     653                 :            :         }
     654                 :            : 
     655                 :          6 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap));
     656                 :            : 
     657                 :          6 :         bss = wpa_bss_get_bssid(wpa_s, target_ap);
     658         [ +  - ]:          6 :         if (bss)
     659                 :          6 :                 mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
     660                 :            :         else
     661                 :          0 :                 mdie = NULL;
     662                 :            : 
     663                 :          6 :         return wpa_ft_start_over_ds(wpa_s->wpa, target_ap, mdie);
     664                 :            : }
     665                 :            : #endif /* CONFIG_IEEE80211R */
     666                 :            : 
     667                 :            : 
     668                 :            : #ifdef CONFIG_WPS
     669                 :         18 : static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
     670                 :            :                                              char *cmd)
     671                 :            : {
     672                 :         18 :         u8 bssid[ETH_ALEN], *_bssid = bssid;
     673                 :            : #ifdef CONFIG_P2P
     674                 :            :         u8 p2p_dev_addr[ETH_ALEN];
     675                 :            : #endif /* CONFIG_P2P */
     676                 :            : #ifdef CONFIG_AP
     677                 :         18 :         u8 *_p2p_dev_addr = NULL;
     678                 :            : #endif /* CONFIG_AP */
     679                 :            : 
     680 [ -  + ][ #  # ]:         18 :         if (cmd == NULL || os_strcmp(cmd, "any") == 0) {
     681                 :         18 :                 _bssid = NULL;
     682                 :            : #ifdef CONFIG_P2P
     683         [ #  # ]:          0 :         } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
     684         [ #  # ]:          0 :                 if (hwaddr_aton(cmd + 13, p2p_dev_addr)) {
     685                 :          0 :                         wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid "
     686                 :            :                                    "P2P Device Address '%s'",
     687                 :            :                                    cmd + 13);
     688                 :          0 :                         return -1;
     689                 :            :                 }
     690                 :          0 :                 _p2p_dev_addr = p2p_dev_addr;
     691                 :            : #endif /* CONFIG_P2P */
     692         [ #  # ]:          0 :         } else if (hwaddr_aton(cmd, bssid)) {
     693                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
     694                 :            :                            cmd);
     695                 :          0 :                 return -1;
     696                 :            :         }
     697                 :            : 
     698                 :            : #ifdef CONFIG_AP
     699         [ +  + ]:         18 :         if (wpa_s->ap_iface)
     700                 :          3 :                 return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr);
     701                 :            : #endif /* CONFIG_AP */
     702                 :            : 
     703                 :         18 :         return wpas_wps_start_pbc(wpa_s, _bssid, 0);
     704                 :            : }
     705                 :            : 
     706                 :            : 
     707                 :         41 : static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
     708                 :            :                                              char *cmd, char *buf,
     709                 :            :                                              size_t buflen)
     710                 :            : {
     711                 :         41 :         u8 bssid[ETH_ALEN], *_bssid = bssid;
     712                 :            :         char *pin;
     713                 :            :         int ret;
     714                 :            : 
     715                 :         41 :         pin = os_strchr(cmd, ' ');
     716         [ +  - ]:         41 :         if (pin)
     717                 :         41 :                 *pin++ = '\0';
     718                 :            : 
     719         [ +  - ]:         41 :         if (os_strcmp(cmd, "any") == 0)
     720                 :         41 :                 _bssid = NULL;
     721         [ #  # ]:          0 :         else if (os_strcmp(cmd, "get") == 0) {
     722                 :          0 :                 ret = wps_generate_pin();
     723                 :          0 :                 goto done;
     724         [ #  # ]:          0 :         } else if (hwaddr_aton(cmd, bssid)) {
     725                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
     726                 :            :                            cmd);
     727                 :          0 :                 return -1;
     728                 :            :         }
     729                 :            : 
     730                 :            : #ifdef CONFIG_AP
     731         [ +  + ]:         41 :         if (wpa_s->ap_iface) {
     732                 :         28 :                 int timeout = 0;
     733                 :            :                 char *pos;
     734                 :            : 
     735         [ +  - ]:         28 :                 if (pin) {
     736                 :         28 :                         pos = os_strchr(pin, ' ');
     737         [ -  + ]:         28 :                         if (pos) {
     738                 :          0 :                                 *pos++ = '\0';
     739                 :          0 :                                 timeout = atoi(pos);
     740                 :            :                         }
     741                 :            :                 }
     742                 :            : 
     743                 :         28 :                 return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin,
     744                 :            :                                                  buf, buflen, timeout);
     745                 :            :         }
     746                 :            : #endif /* CONFIG_AP */
     747                 :            : 
     748         [ +  - ]:         13 :         if (pin) {
     749                 :         13 :                 ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0,
     750                 :            :                                          DEV_PW_DEFAULT);
     751         [ -  + ]:         13 :                 if (ret < 0)
     752                 :          0 :                         return -1;
     753                 :         13 :                 ret = os_snprintf(buf, buflen, "%s", pin);
     754 [ +  - ][ -  + ]:         13 :                 if (ret < 0 || (size_t) ret >= buflen)
     755                 :          0 :                         return -1;
     756                 :         13 :                 return ret;
     757                 :            :         }
     758                 :            : 
     759                 :          0 :         ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0, DEV_PW_DEFAULT);
     760         [ #  # ]:          0 :         if (ret < 0)
     761                 :          0 :                 return -1;
     762                 :            : 
     763                 :            : done:
     764                 :            :         /* Return the generated PIN */
     765                 :          0 :         ret = os_snprintf(buf, buflen, "%08d", ret);
     766 [ #  # ][ #  # ]:          0 :         if (ret < 0 || (size_t) ret >= buflen)
     767                 :          0 :                 return -1;
     768                 :         41 :         return ret;
     769                 :            : }
     770                 :            : 
     771                 :            : 
     772                 :          5 : static int wpa_supplicant_ctrl_iface_wps_check_pin(
     773                 :            :         struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
     774                 :            : {
     775                 :            :         char pin[9];
     776                 :            :         size_t len;
     777                 :            :         char *pos;
     778                 :            :         int ret;
     779                 :            : 
     780                 :          5 :         wpa_hexdump_ascii_key(MSG_DEBUG, "WPS_CHECK_PIN",
     781                 :            :                               (u8 *) cmd, os_strlen(cmd));
     782         [ +  + ]:         51 :         for (pos = cmd, len = 0; *pos != '\0'; pos++) {
     783 [ +  + ][ +  + ]:         46 :                 if (*pos < '0' || *pos > '9')
     784                 :          6 :                         continue;
     785                 :         40 :                 pin[len++] = *pos;
     786         [ -  + ]:         40 :                 if (len == 9) {
     787                 :          0 :                         wpa_printf(MSG_DEBUG, "WPS: Too long PIN");
     788                 :          0 :                         return -1;
     789                 :            :                 }
     790                 :            :         }
     791 [ +  - ][ -  + ]:          5 :         if (len != 4 && len != 8) {
     792                 :          0 :                 wpa_printf(MSG_DEBUG, "WPS: Invalid PIN length %d", (int) len);
     793                 :          0 :                 return -1;
     794                 :            :         }
     795                 :          5 :         pin[len] = '\0';
     796                 :            : 
     797         [ +  - ]:          5 :         if (len == 8) {
     798                 :            :                 unsigned int pin_val;
     799                 :          5 :                 pin_val = atoi(pin);
     800         [ +  + ]:          5 :                 if (!wps_pin_valid(pin_val)) {
     801                 :          1 :                         wpa_printf(MSG_DEBUG, "WPS: Invalid checksum digit");
     802                 :          1 :                         ret = os_snprintf(buf, buflen, "FAIL-CHECKSUM\n");
     803 [ +  - ][ -  + ]:          1 :                         if (ret < 0 || (size_t) ret >= buflen)
     804                 :          0 :                                 return -1;
     805                 :          1 :                         return ret;
     806                 :            :                 }
     807                 :            :         }
     808                 :            : 
     809                 :          4 :         ret = os_snprintf(buf, buflen, "%s", pin);
     810 [ +  - ][ -  + ]:          4 :         if (ret < 0 || (size_t) ret >= buflen)
     811                 :          0 :                 return -1;
     812                 :            : 
     813                 :          5 :         return ret;
     814                 :            : }
     815                 :            : 
     816                 :            : 
     817                 :            : #ifdef CONFIG_WPS_NFC
     818                 :            : 
     819                 :          3 : static int wpa_supplicant_ctrl_iface_wps_nfc(struct wpa_supplicant *wpa_s,
     820                 :            :                                              char *cmd)
     821                 :            : {
     822                 :          3 :         u8 bssid[ETH_ALEN], *_bssid = bssid;
     823                 :            : 
     824 [ -  + ][ #  # ]:          3 :         if (cmd == NULL || cmd[0] == '\0')
     825                 :          3 :                 _bssid = NULL;
     826         [ #  # ]:          0 :         else if (hwaddr_aton(cmd, bssid))
     827                 :          0 :                 return -1;
     828                 :            : 
     829                 :          3 :         return wpas_wps_start_nfc(wpa_s, NULL, _bssid, NULL, 0, 0, NULL, NULL,
     830                 :            :                                   0, 0);
     831                 :            : }
     832                 :            : 
     833                 :            : 
     834                 :          1 : static int wpa_supplicant_ctrl_iface_wps_nfc_config_token(
     835                 :            :         struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len)
     836                 :            : {
     837                 :            :         int ndef;
     838                 :            :         struct wpabuf *buf;
     839                 :            :         int res;
     840                 :            :         char *pos;
     841                 :            : 
     842                 :          1 :         pos = os_strchr(cmd, ' ');
     843         [ -  + ]:          1 :         if (pos)
     844                 :          0 :                 *pos++ = '\0';
     845         [ -  + ]:          1 :         if (os_strcmp(cmd, "WPS") == 0)
     846                 :          0 :                 ndef = 0;
     847         [ +  - ]:          1 :         else if (os_strcmp(cmd, "NDEF") == 0)
     848                 :          1 :                 ndef = 1;
     849                 :            :         else
     850                 :          0 :                 return -1;
     851                 :            : 
     852                 :          1 :         buf = wpas_wps_nfc_config_token(wpa_s, ndef, pos);
     853         [ -  + ]:          1 :         if (buf == NULL)
     854                 :          0 :                 return -1;
     855                 :            : 
     856                 :          1 :         res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
     857                 :            :                                          wpabuf_len(buf));
     858                 :          1 :         reply[res++] = '\n';
     859                 :          1 :         reply[res] = '\0';
     860                 :            : 
     861                 :          1 :         wpabuf_free(buf);
     862                 :            : 
     863                 :          1 :         return res;
     864                 :            : }
     865                 :            : 
     866                 :            : 
     867                 :          8 : static int wpa_supplicant_ctrl_iface_wps_nfc_token(
     868                 :            :         struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len)
     869                 :            : {
     870                 :            :         int ndef;
     871                 :            :         struct wpabuf *buf;
     872                 :            :         int res;
     873                 :            : 
     874         [ -  + ]:          8 :         if (os_strcmp(cmd, "WPS") == 0)
     875                 :          0 :                 ndef = 0;
     876         [ +  - ]:          8 :         else if (os_strcmp(cmd, "NDEF") == 0)
     877                 :          8 :                 ndef = 1;
     878                 :            :         else
     879                 :          0 :                 return -1;
     880                 :            : 
     881                 :          8 :         buf = wpas_wps_nfc_token(wpa_s, ndef);
     882         [ -  + ]:          8 :         if (buf == NULL)
     883                 :          0 :                 return -1;
     884                 :            : 
     885                 :          8 :         res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
     886                 :            :                                          wpabuf_len(buf));
     887                 :          8 :         reply[res++] = '\n';
     888                 :          8 :         reply[res] = '\0';
     889                 :            : 
     890                 :          8 :         wpabuf_free(buf);
     891                 :            : 
     892                 :          8 :         return res;
     893                 :            : }
     894                 :            : 
     895                 :            : 
     896                 :         12 : static int wpa_supplicant_ctrl_iface_wps_nfc_tag_read(
     897                 :            :         struct wpa_supplicant *wpa_s, char *pos)
     898                 :            : {
     899                 :            :         size_t len;
     900                 :            :         struct wpabuf *buf;
     901                 :            :         int ret;
     902                 :            :         char *freq;
     903                 :         12 :         int forced_freq = 0;
     904                 :            : 
     905                 :         12 :         freq = strstr(pos, " freq=");
     906         [ -  + ]:         12 :         if (freq) {
     907                 :          0 :                 *freq = '\0';
     908                 :          0 :                 freq += 6;
     909                 :          0 :                 forced_freq = atoi(freq);
     910                 :            :         }
     911                 :            : 
     912                 :         12 :         len = os_strlen(pos);
     913         [ -  + ]:         12 :         if (len & 0x01)
     914                 :          0 :                 return -1;
     915                 :         12 :         len /= 2;
     916                 :            : 
     917                 :         12 :         buf = wpabuf_alloc(len);
     918         [ -  + ]:         12 :         if (buf == NULL)
     919                 :          0 :                 return -1;
     920         [ -  + ]:         12 :         if (hexstr2bin(pos, wpabuf_put(buf, len), len) < 0) {
     921                 :          0 :                 wpabuf_free(buf);
     922                 :          0 :                 return -1;
     923                 :            :         }
     924                 :            : 
     925                 :         12 :         ret = wpas_wps_nfc_tag_read(wpa_s, buf, forced_freq);
     926                 :         12 :         wpabuf_free(buf);
     927                 :            : 
     928                 :         12 :         return ret;
     929                 :            : }
     930                 :            : 
     931                 :            : 
     932                 :          9 : static int wpas_ctrl_nfc_get_handover_req_wps(struct wpa_supplicant *wpa_s,
     933                 :            :                                               char *reply, size_t max_len,
     934                 :            :                                               int ndef)
     935                 :            : {
     936                 :            :         struct wpabuf *buf;
     937                 :            :         int res;
     938                 :            : 
     939                 :          9 :         buf = wpas_wps_nfc_handover_req(wpa_s, ndef);
     940         [ -  + ]:          9 :         if (buf == NULL)
     941                 :          0 :                 return -1;
     942                 :            : 
     943                 :          9 :         res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
     944                 :            :                                          wpabuf_len(buf));
     945                 :          9 :         reply[res++] = '\n';
     946                 :          9 :         reply[res] = '\0';
     947                 :            : 
     948                 :          9 :         wpabuf_free(buf);
     949                 :            : 
     950                 :          9 :         return res;
     951                 :            : }
     952                 :            : 
     953                 :            : 
     954                 :            : #ifdef CONFIG_P2P
     955                 :          8 : static int wpas_ctrl_nfc_get_handover_req_p2p(struct wpa_supplicant *wpa_s,
     956                 :            :                                               char *reply, size_t max_len,
     957                 :            :                                               int ndef)
     958                 :            : {
     959                 :            :         struct wpabuf *buf;
     960                 :            :         int res;
     961                 :            : 
     962                 :          8 :         buf = wpas_p2p_nfc_handover_req(wpa_s, ndef);
     963         [ -  + ]:          8 :         if (buf == NULL) {
     964                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Could not generate NFC handover request");
     965                 :          0 :                 return -1;
     966                 :            :         }
     967                 :            : 
     968                 :          8 :         res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
     969                 :            :                                          wpabuf_len(buf));
     970                 :          8 :         reply[res++] = '\n';
     971                 :          8 :         reply[res] = '\0';
     972                 :            : 
     973                 :          8 :         wpabuf_free(buf);
     974                 :            : 
     975                 :          8 :         return res;
     976                 :            : }
     977                 :            : #endif /* CONFIG_P2P */
     978                 :            : 
     979                 :            : 
     980                 :         17 : static int wpas_ctrl_nfc_get_handover_req(struct wpa_supplicant *wpa_s,
     981                 :            :                                           char *cmd, char *reply,
     982                 :            :                                           size_t max_len)
     983                 :            : {
     984                 :            :         char *pos;
     985                 :            :         int ndef;
     986                 :            : 
     987                 :         17 :         pos = os_strchr(cmd, ' ');
     988         [ -  + ]:         17 :         if (pos == NULL)
     989                 :          0 :                 return -1;
     990                 :         17 :         *pos++ = '\0';
     991                 :            : 
     992         [ -  + ]:         17 :         if (os_strcmp(cmd, "WPS") == 0)
     993                 :          0 :                 ndef = 0;
     994         [ +  - ]:         17 :         else if (os_strcmp(cmd, "NDEF") == 0)
     995                 :         17 :                 ndef = 1;
     996                 :            :         else
     997                 :          0 :                 return -1;
     998                 :            : 
     999 [ +  - ][ +  + ]:         17 :         if (os_strcmp(pos, "WPS") == 0 || os_strcmp(pos, "WPS-CR") == 0) {
    1000         [ -  + ]:          9 :                 if (!ndef)
    1001                 :          0 :                         return -1;
    1002                 :          9 :                 return wpas_ctrl_nfc_get_handover_req_wps(
    1003                 :            :                         wpa_s, reply, max_len, ndef);
    1004                 :            :         }
    1005                 :            : 
    1006                 :            : #ifdef CONFIG_P2P
    1007         [ +  - ]:          8 :         if (os_strcmp(pos, "P2P-CR") == 0) {
    1008                 :          8 :                 return wpas_ctrl_nfc_get_handover_req_p2p(
    1009                 :            :                         wpa_s, reply, max_len, ndef);
    1010                 :            :         }
    1011                 :            : #endif /* CONFIG_P2P */
    1012                 :            : 
    1013                 :         17 :         return -1;
    1014                 :            : }
    1015                 :            : 
    1016                 :            : 
    1017                 :          4 : static int wpas_ctrl_nfc_get_handover_sel_wps(struct wpa_supplicant *wpa_s,
    1018                 :            :                                               char *reply, size_t max_len,
    1019                 :            :                                               int ndef, int cr, char *uuid)
    1020                 :            : {
    1021                 :            :         struct wpabuf *buf;
    1022                 :            :         int res;
    1023                 :            : 
    1024                 :          4 :         buf = wpas_wps_nfc_handover_sel(wpa_s, ndef, cr, uuid);
    1025         [ -  + ]:          4 :         if (buf == NULL)
    1026                 :          0 :                 return -1;
    1027                 :            : 
    1028                 :          4 :         res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
    1029                 :            :                                          wpabuf_len(buf));
    1030                 :          4 :         reply[res++] = '\n';
    1031                 :          4 :         reply[res] = '\0';
    1032                 :            : 
    1033                 :          4 :         wpabuf_free(buf);
    1034                 :            : 
    1035                 :          4 :         return res;
    1036                 :            : }
    1037                 :            : 
    1038                 :            : 
    1039                 :            : #ifdef CONFIG_P2P
    1040                 :         13 : static int wpas_ctrl_nfc_get_handover_sel_p2p(struct wpa_supplicant *wpa_s,
    1041                 :            :                                               char *reply, size_t max_len,
    1042                 :            :                                               int ndef, int tag)
    1043                 :            : {
    1044                 :            :         struct wpabuf *buf;
    1045                 :            :         int res;
    1046                 :            : 
    1047                 :         13 :         buf = wpas_p2p_nfc_handover_sel(wpa_s, ndef, tag);
    1048         [ -  + ]:         13 :         if (buf == NULL)
    1049                 :          0 :                 return -1;
    1050                 :            : 
    1051                 :         13 :         res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
    1052                 :            :                                          wpabuf_len(buf));
    1053                 :         13 :         reply[res++] = '\n';
    1054                 :         13 :         reply[res] = '\0';
    1055                 :            : 
    1056                 :         13 :         wpabuf_free(buf);
    1057                 :            : 
    1058                 :         13 :         return res;
    1059                 :            : }
    1060                 :            : #endif /* CONFIG_P2P */
    1061                 :            : 
    1062                 :            : 
    1063                 :         17 : static int wpas_ctrl_nfc_get_handover_sel(struct wpa_supplicant *wpa_s,
    1064                 :            :                                           char *cmd, char *reply,
    1065                 :            :                                           size_t max_len)
    1066                 :            : {
    1067                 :            :         char *pos, *pos2;
    1068                 :            :         int ndef;
    1069                 :            : 
    1070                 :         17 :         pos = os_strchr(cmd, ' ');
    1071         [ -  + ]:         17 :         if (pos == NULL)
    1072                 :          0 :                 return -1;
    1073                 :         17 :         *pos++ = '\0';
    1074                 :            : 
    1075         [ -  + ]:         17 :         if (os_strcmp(cmd, "WPS") == 0)
    1076                 :          0 :                 ndef = 0;
    1077         [ +  - ]:         17 :         else if (os_strcmp(cmd, "NDEF") == 0)
    1078                 :         17 :                 ndef = 1;
    1079                 :            :         else
    1080                 :          0 :                 return -1;
    1081                 :            : 
    1082                 :         17 :         pos2 = os_strchr(pos, ' ');
    1083         [ +  + ]:         17 :         if (pos2)
    1084                 :          3 :                 *pos2++ = '\0';
    1085 [ +  - ][ +  + ]:         17 :         if (os_strcmp(pos, "WPS") == 0 || os_strcmp(pos, "WPS-CR") == 0) {
    1086         [ -  + ]:          4 :                 if (!ndef)
    1087                 :          0 :                         return -1;
    1088                 :          4 :                 return wpas_ctrl_nfc_get_handover_sel_wps(
    1089                 :            :                         wpa_s, reply, max_len, ndef,
    1090                 :          4 :                         os_strcmp(pos, "WPS-CR") == 0, pos2);
    1091                 :            :         }
    1092                 :            : 
    1093                 :            : #ifdef CONFIG_P2P
    1094         [ +  + ]:         13 :         if (os_strcmp(pos, "P2P-CR") == 0) {
    1095                 :          8 :                 return wpas_ctrl_nfc_get_handover_sel_p2p(
    1096                 :            :                         wpa_s, reply, max_len, ndef, 0);
    1097                 :            :         }
    1098                 :            : 
    1099         [ +  - ]:          5 :         if (os_strcmp(pos, "P2P-CR-TAG") == 0) {
    1100                 :          5 :                 return wpas_ctrl_nfc_get_handover_sel_p2p(
    1101                 :            :                         wpa_s, reply, max_len, ndef, 1);
    1102                 :            :         }
    1103                 :            : #endif /* CONFIG_P2P */
    1104                 :            : 
    1105                 :         17 :         return -1;
    1106                 :            : }
    1107                 :            : 
    1108                 :            : 
    1109                 :          0 : static int wpas_ctrl_nfc_rx_handover_sel(struct wpa_supplicant *wpa_s,
    1110                 :            :                                          char *cmd)
    1111                 :            : {
    1112                 :            :         size_t len;
    1113                 :            :         struct wpabuf *buf;
    1114                 :            :         int ret;
    1115                 :            : 
    1116                 :          0 :         len = os_strlen(cmd);
    1117         [ #  # ]:          0 :         if (len & 0x01)
    1118                 :          0 :                 return -1;
    1119                 :          0 :         len /= 2;
    1120                 :            : 
    1121                 :          0 :         buf = wpabuf_alloc(len);
    1122         [ #  # ]:          0 :         if (buf == NULL)
    1123                 :          0 :                 return -1;
    1124         [ #  # ]:          0 :         if (hexstr2bin(cmd, wpabuf_put(buf, len), len) < 0) {
    1125                 :          0 :                 wpabuf_free(buf);
    1126                 :          0 :                 return -1;
    1127                 :            :         }
    1128                 :            : 
    1129                 :          0 :         ret = wpas_wps_nfc_rx_handover_sel(wpa_s, buf);
    1130                 :          0 :         wpabuf_free(buf);
    1131                 :            : 
    1132                 :          0 :         return ret;
    1133                 :            : }
    1134                 :            : 
    1135                 :            : 
    1136                 :         29 : static int wpas_ctrl_nfc_report_handover(struct wpa_supplicant *wpa_s,
    1137                 :            :                                          char *cmd)
    1138                 :            : {
    1139                 :            :         size_t len;
    1140                 :            :         struct wpabuf *req, *sel;
    1141                 :            :         int ret;
    1142                 :            :         char *pos, *role, *type, *pos2;
    1143                 :            : #ifdef CONFIG_P2P
    1144                 :            :         char *freq;
    1145                 :         29 :         int forced_freq = 0;
    1146                 :            : 
    1147                 :         29 :         freq = strstr(cmd, " freq=");
    1148         [ -  + ]:         29 :         if (freq) {
    1149                 :          0 :                 *freq = '\0';
    1150                 :          0 :                 freq += 6;
    1151                 :          0 :                 forced_freq = atoi(freq);
    1152                 :            :         }
    1153                 :            : #endif /* CONFIG_P2P */
    1154                 :            : 
    1155                 :         29 :         role = cmd;
    1156                 :         29 :         pos = os_strchr(role, ' ');
    1157         [ -  + ]:         29 :         if (pos == NULL) {
    1158                 :          0 :                 wpa_printf(MSG_DEBUG, "NFC: Missing type in handover report");
    1159                 :          0 :                 return -1;
    1160                 :            :         }
    1161                 :         29 :         *pos++ = '\0';
    1162                 :            : 
    1163                 :         29 :         type = pos;
    1164                 :         29 :         pos = os_strchr(type, ' ');
    1165         [ -  + ]:         29 :         if (pos == NULL) {
    1166                 :          0 :                 wpa_printf(MSG_DEBUG, "NFC: Missing request message in handover report");
    1167                 :          0 :                 return -1;
    1168                 :            :         }
    1169                 :         29 :         *pos++ = '\0';
    1170                 :            : 
    1171                 :         29 :         pos2 = os_strchr(pos, ' ');
    1172         [ -  + ]:         29 :         if (pos2 == NULL) {
    1173                 :          0 :                 wpa_printf(MSG_DEBUG, "NFC: Missing select message in handover report");
    1174                 :          0 :                 return -1;
    1175                 :            :         }
    1176                 :         29 :         *pos2++ = '\0';
    1177                 :            : 
    1178                 :         29 :         len = os_strlen(pos);
    1179         [ -  + ]:         29 :         if (len & 0x01) {
    1180                 :          0 :                 wpa_printf(MSG_DEBUG, "NFC: Invalid request message length in handover report");
    1181                 :          0 :                 return -1;
    1182                 :            :         }
    1183                 :         29 :         len /= 2;
    1184                 :            : 
    1185                 :         29 :         req = wpabuf_alloc(len);
    1186         [ -  + ]:         29 :         if (req == NULL) {
    1187                 :          0 :                 wpa_printf(MSG_DEBUG, "NFC: Failed to allocate memory for request message");
    1188                 :          0 :                 return -1;
    1189                 :            :         }
    1190         [ -  + ]:         29 :         if (hexstr2bin(pos, wpabuf_put(req, len), len) < 0) {
    1191                 :          0 :                 wpa_printf(MSG_DEBUG, "NFC: Invalid request message hexdump in handover report");
    1192                 :          0 :                 wpabuf_free(req);
    1193                 :          0 :                 return -1;
    1194                 :            :         }
    1195                 :            : 
    1196                 :         29 :         len = os_strlen(pos2);
    1197         [ -  + ]:         29 :         if (len & 0x01) {
    1198                 :          0 :                 wpa_printf(MSG_DEBUG, "NFC: Invalid select message length in handover report");
    1199                 :          0 :                 wpabuf_free(req);
    1200                 :          0 :                 return -1;
    1201                 :            :         }
    1202                 :         29 :         len /= 2;
    1203                 :            : 
    1204                 :         29 :         sel = wpabuf_alloc(len);
    1205         [ -  + ]:         29 :         if (sel == NULL) {
    1206                 :          0 :                 wpa_printf(MSG_DEBUG, "NFC: Failed to allocate memory for select message");
    1207                 :          0 :                 wpabuf_free(req);
    1208                 :          0 :                 return -1;
    1209                 :            :         }
    1210         [ -  + ]:         29 :         if (hexstr2bin(pos2, wpabuf_put(sel, len), len) < 0) {
    1211                 :          0 :                 wpa_printf(MSG_DEBUG, "NFC: Invalid select message hexdump in handover report");
    1212                 :          0 :                 wpabuf_free(req);
    1213                 :          0 :                 wpabuf_free(sel);
    1214                 :          0 :                 return -1;
    1215                 :            :         }
    1216                 :            : 
    1217                 :         29 :         wpa_printf(MSG_DEBUG, "NFC: Connection handover reported - role=%s type=%s req_len=%d sel_len=%d",
    1218                 :         29 :                    role, type, (int) wpabuf_len(req), (int) wpabuf_len(sel));
    1219                 :            : 
    1220 [ +  + ][ +  + ]:         29 :         if (os_strcmp(role, "INIT") == 0 && os_strcmp(type, "WPS") == 0) {
    1221                 :          9 :                 ret = wpas_wps_nfc_report_handover(wpa_s, req, sel);
    1222                 :            : #ifdef CONFIG_AP
    1223 [ +  + ][ +  + ]:         20 :         } else if (os_strcmp(role, "RESP") == 0 && os_strcmp(type, "WPS") == 0)
    1224                 :            :         {
    1225                 :          4 :                 ret = wpas_ap_wps_nfc_report_handover(wpa_s, req, sel);
    1226         [ +  + ]:          7 :                 if (ret < 0)
    1227                 :          3 :                         ret = wpas_er_wps_nfc_report_handover(wpa_s, req, sel);
    1228                 :            : #endif /* CONFIG_AP */
    1229                 :            : #ifdef CONFIG_P2P
    1230 [ +  + ][ +  - ]:         16 :         } else if (os_strcmp(role, "INIT") == 0 && os_strcmp(type, "P2P") == 0)
    1231                 :            :         {
    1232                 :          8 :                 ret = wpas_p2p_nfc_report_handover(wpa_s, 1, req, sel, 0);
    1233 [ +  - ][ +  - ]:          8 :         } else if (os_strcmp(role, "RESP") == 0 && os_strcmp(type, "P2P") == 0)
    1234                 :            :         {
    1235                 :          8 :                 ret = wpas_p2p_nfc_report_handover(wpa_s, 0, req, sel,
    1236                 :            :                                                    forced_freq);
    1237                 :            : #endif /* CONFIG_P2P */
    1238                 :            :         } else {
    1239                 :          0 :                 wpa_printf(MSG_DEBUG, "NFC: Unsupported connection handover "
    1240                 :            :                            "reported: role=%s type=%s", role, type);
    1241                 :          0 :                 ret = -1;
    1242                 :            :         }
    1243                 :         29 :         wpabuf_free(req);
    1244                 :         29 :         wpabuf_free(sel);
    1245                 :            : 
    1246         [ -  + ]:         29 :         if (ret)
    1247                 :          0 :                 wpa_printf(MSG_DEBUG, "NFC: Failed to process reported handover messages");
    1248                 :            : 
    1249                 :         29 :         return ret;
    1250                 :            : }
    1251                 :            : 
    1252                 :            : #endif /* CONFIG_WPS_NFC */
    1253                 :            : 
    1254                 :            : 
    1255                 :         28 : static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s,
    1256                 :            :                                              char *cmd)
    1257                 :            : {
    1258                 :            :         u8 bssid[ETH_ALEN];
    1259                 :            :         char *pin;
    1260                 :            :         char *new_ssid;
    1261                 :            :         char *new_auth;
    1262                 :            :         char *new_encr;
    1263                 :            :         char *new_key;
    1264                 :            :         struct wps_new_ap_settings ap;
    1265                 :            : 
    1266                 :         28 :         pin = os_strchr(cmd, ' ');
    1267         [ -  + ]:         28 :         if (pin == NULL)
    1268                 :          0 :                 return -1;
    1269                 :         28 :         *pin++ = '\0';
    1270                 :            : 
    1271         [ -  + ]:         28 :         if (hwaddr_aton(cmd, bssid)) {
    1272                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
    1273                 :            :                            cmd);
    1274                 :          0 :                 return -1;
    1275                 :            :         }
    1276                 :            : 
    1277                 :         28 :         new_ssid = os_strchr(pin, ' ');
    1278         [ +  + ]:         28 :         if (new_ssid == NULL)
    1279                 :         18 :                 return wpas_wps_start_reg(wpa_s, bssid, pin, NULL);
    1280                 :         10 :         *new_ssid++ = '\0';
    1281                 :            : 
    1282                 :         10 :         new_auth = os_strchr(new_ssid, ' ');
    1283         [ -  + ]:         10 :         if (new_auth == NULL)
    1284                 :          0 :                 return -1;
    1285                 :         10 :         *new_auth++ = '\0';
    1286                 :            : 
    1287                 :         10 :         new_encr = os_strchr(new_auth, ' ');
    1288         [ -  + ]:         10 :         if (new_encr == NULL)
    1289                 :          0 :                 return -1;
    1290                 :         10 :         *new_encr++ = '\0';
    1291                 :            : 
    1292                 :         10 :         new_key = os_strchr(new_encr, ' ');
    1293         [ -  + ]:         10 :         if (new_key == NULL)
    1294                 :          0 :                 return -1;
    1295                 :         10 :         *new_key++ = '\0';
    1296                 :            : 
    1297                 :         10 :         os_memset(&ap, 0, sizeof(ap));
    1298                 :         10 :         ap.ssid_hex = new_ssid;
    1299                 :         10 :         ap.auth = new_auth;
    1300                 :         10 :         ap.encr = new_encr;
    1301                 :         10 :         ap.key_hex = new_key;
    1302                 :         28 :         return wpas_wps_start_reg(wpa_s, bssid, pin, &ap);
    1303                 :            : }
    1304                 :            : 
    1305                 :            : 
    1306                 :            : #ifdef CONFIG_AP
    1307                 :          6 : static int wpa_supplicant_ctrl_iface_wps_ap_pin(struct wpa_supplicant *wpa_s,
    1308                 :            :                                                 char *cmd, char *buf,
    1309                 :            :                                                 size_t buflen)
    1310                 :            : {
    1311                 :          6 :         int timeout = 300;
    1312                 :            :         char *pos;
    1313                 :            :         const char *pin_txt;
    1314                 :            : 
    1315         [ -  + ]:          6 :         if (!wpa_s->ap_iface)
    1316                 :          0 :                 return -1;
    1317                 :            : 
    1318                 :          6 :         pos = os_strchr(cmd, ' ');
    1319         [ +  + ]:          6 :         if (pos)
    1320                 :          2 :                 *pos++ = '\0';
    1321                 :            : 
    1322         [ +  + ]:          6 :         if (os_strcmp(cmd, "disable") == 0) {
    1323                 :          1 :                 wpas_wps_ap_pin_disable(wpa_s);
    1324                 :          1 :                 return os_snprintf(buf, buflen, "OK\n");
    1325                 :            :         }
    1326                 :            : 
    1327         [ +  + ]:          5 :         if (os_strcmp(cmd, "random") == 0) {
    1328         [ -  + ]:          1 :                 if (pos)
    1329                 :          0 :                         timeout = atoi(pos);
    1330                 :          1 :                 pin_txt = wpas_wps_ap_pin_random(wpa_s, timeout);
    1331         [ -  + ]:          1 :                 if (pin_txt == NULL)
    1332                 :          0 :                         return -1;
    1333                 :          1 :                 return os_snprintf(buf, buflen, "%s", pin_txt);
    1334                 :            :         }
    1335                 :            : 
    1336         [ +  + ]:          4 :         if (os_strcmp(cmd, "get") == 0) {
    1337                 :          2 :                 pin_txt = wpas_wps_ap_pin_get(wpa_s);
    1338         [ +  + ]:          2 :                 if (pin_txt == NULL)
    1339                 :          1 :                         return -1;
    1340                 :          1 :                 return os_snprintf(buf, buflen, "%s", pin_txt);
    1341                 :            :         }
    1342                 :            : 
    1343         [ +  - ]:          2 :         if (os_strcmp(cmd, "set") == 0) {
    1344                 :            :                 char *pin;
    1345         [ -  + ]:          2 :                 if (pos == NULL)
    1346                 :          0 :                         return -1;
    1347                 :          2 :                 pin = pos;
    1348                 :          2 :                 pos = os_strchr(pos, ' ');
    1349         [ +  + ]:          2 :                 if (pos) {
    1350                 :          1 :                         *pos++ = '\0';
    1351                 :          1 :                         timeout = atoi(pos);
    1352                 :            :                 }
    1353         [ -  + ]:          2 :                 if (os_strlen(pin) > buflen)
    1354                 :          0 :                         return -1;
    1355         [ -  + ]:          2 :                 if (wpas_wps_ap_pin_set(wpa_s, pin, timeout) < 0)
    1356                 :          0 :                         return -1;
    1357                 :          2 :                 return os_snprintf(buf, buflen, "%s", pin);
    1358                 :            :         }
    1359                 :            : 
    1360                 :          6 :         return -1;
    1361                 :            : }
    1362                 :            : #endif /* CONFIG_AP */
    1363                 :            : 
    1364                 :            : 
    1365                 :            : #ifdef CONFIG_WPS_ER
    1366                 :          4 : static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant *wpa_s,
    1367                 :            :                                                 char *cmd)
    1368                 :            : {
    1369                 :          4 :         char *uuid = cmd, *pin, *pos;
    1370                 :          4 :         u8 addr_buf[ETH_ALEN], *addr = NULL;
    1371                 :          4 :         pin = os_strchr(uuid, ' ');
    1372         [ -  + ]:          4 :         if (pin == NULL)
    1373                 :          0 :                 return -1;
    1374                 :          4 :         *pin++ = '\0';
    1375                 :          4 :         pos = os_strchr(pin, ' ');
    1376         [ +  - ]:          4 :         if (pos) {
    1377                 :          4 :                 *pos++ = '\0';
    1378         [ +  - ]:          4 :                 if (hwaddr_aton(pos, addr_buf) == 0)
    1379                 :          4 :                         addr = addr_buf;
    1380                 :            :         }
    1381                 :          4 :         return wpas_wps_er_add_pin(wpa_s, addr, uuid, pin);
    1382                 :            : }
    1383                 :            : 
    1384                 :            : 
    1385                 :          1 : static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s,
    1386                 :            :                                                   char *cmd)
    1387                 :            : {
    1388                 :          1 :         char *uuid = cmd, *pin;
    1389                 :          1 :         pin = os_strchr(uuid, ' ');
    1390         [ -  + ]:          1 :         if (pin == NULL)
    1391                 :          0 :                 return -1;
    1392                 :          1 :         *pin++ = '\0';
    1393                 :          1 :         return wpas_wps_er_learn(wpa_s, uuid, pin);
    1394                 :            : }
    1395                 :            : 
    1396                 :            : 
    1397                 :          8 : static int wpa_supplicant_ctrl_iface_wps_er_set_config(
    1398                 :            :         struct wpa_supplicant *wpa_s, char *cmd)
    1399                 :            : {
    1400                 :          8 :         char *uuid = cmd, *id;
    1401                 :          8 :         id = os_strchr(uuid, ' ');
    1402         [ -  + ]:          8 :         if (id == NULL)
    1403                 :          0 :                 return -1;
    1404                 :          8 :         *id++ = '\0';
    1405                 :          8 :         return wpas_wps_er_set_config(wpa_s, uuid, atoi(id));
    1406                 :            : }
    1407                 :            : 
    1408                 :            : 
    1409                 :          1 : static int wpa_supplicant_ctrl_iface_wps_er_config(
    1410                 :            :         struct wpa_supplicant *wpa_s, char *cmd)
    1411                 :            : {
    1412                 :            :         char *pin;
    1413                 :            :         char *new_ssid;
    1414                 :            :         char *new_auth;
    1415                 :            :         char *new_encr;
    1416                 :            :         char *new_key;
    1417                 :            :         struct wps_new_ap_settings ap;
    1418                 :            : 
    1419                 :          1 :         pin = os_strchr(cmd, ' ');
    1420         [ -  + ]:          1 :         if (pin == NULL)
    1421                 :          0 :                 return -1;
    1422                 :          1 :         *pin++ = '\0';
    1423                 :            : 
    1424                 :          1 :         new_ssid = os_strchr(pin, ' ');
    1425         [ -  + ]:          1 :         if (new_ssid == NULL)
    1426                 :          0 :                 return -1;
    1427                 :          1 :         *new_ssid++ = '\0';
    1428                 :            : 
    1429                 :          1 :         new_auth = os_strchr(new_ssid, ' ');
    1430         [ -  + ]:          1 :         if (new_auth == NULL)
    1431                 :          0 :                 return -1;
    1432                 :          1 :         *new_auth++ = '\0';
    1433                 :            : 
    1434                 :          1 :         new_encr = os_strchr(new_auth, ' ');
    1435         [ -  + ]:          1 :         if (new_encr == NULL)
    1436                 :          0 :                 return -1;
    1437                 :          1 :         *new_encr++ = '\0';
    1438                 :            : 
    1439                 :          1 :         new_key = os_strchr(new_encr, ' ');
    1440         [ -  + ]:          1 :         if (new_key == NULL)
    1441                 :          0 :                 return -1;
    1442                 :          1 :         *new_key++ = '\0';
    1443                 :            : 
    1444                 :          1 :         os_memset(&ap, 0, sizeof(ap));
    1445                 :          1 :         ap.ssid_hex = new_ssid;
    1446                 :          1 :         ap.auth = new_auth;
    1447                 :          1 :         ap.encr = new_encr;
    1448                 :          1 :         ap.key_hex = new_key;
    1449                 :          1 :         return wpas_wps_er_config(wpa_s, cmd, pin, &ap);
    1450                 :            : }
    1451                 :            : 
    1452                 :            : 
    1453                 :            : #ifdef CONFIG_WPS_NFC
    1454                 :          1 : static int wpa_supplicant_ctrl_iface_wps_er_nfc_config_token(
    1455                 :            :         struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len)
    1456                 :            : {
    1457                 :            :         int ndef;
    1458                 :            :         struct wpabuf *buf;
    1459                 :            :         int res;
    1460                 :            :         char *uuid;
    1461                 :            : 
    1462                 :          1 :         uuid = os_strchr(cmd, ' ');
    1463         [ -  + ]:          1 :         if (uuid == NULL)
    1464                 :          0 :                 return -1;
    1465                 :          1 :         *uuid++ = '\0';
    1466                 :            : 
    1467         [ -  + ]:          1 :         if (os_strcmp(cmd, "WPS") == 0)
    1468                 :          0 :                 ndef = 0;
    1469         [ +  - ]:          1 :         else if (os_strcmp(cmd, "NDEF") == 0)
    1470                 :          1 :                 ndef = 1;
    1471                 :            :         else
    1472                 :          0 :                 return -1;
    1473                 :            : 
    1474                 :          1 :         buf = wpas_wps_er_nfc_config_token(wpa_s, ndef, uuid);
    1475         [ -  + ]:          1 :         if (buf == NULL)
    1476                 :          0 :                 return -1;
    1477                 :            : 
    1478                 :          1 :         res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
    1479                 :            :                                          wpabuf_len(buf));
    1480                 :          1 :         reply[res++] = '\n';
    1481                 :          1 :         reply[res] = '\0';
    1482                 :            : 
    1483                 :          1 :         wpabuf_free(buf);
    1484                 :            : 
    1485                 :          1 :         return res;
    1486                 :            : }
    1487                 :            : #endif /* CONFIG_WPS_NFC */
    1488                 :            : #endif /* CONFIG_WPS_ER */
    1489                 :            : 
    1490                 :            : #endif /* CONFIG_WPS */
    1491                 :            : 
    1492                 :            : 
    1493                 :            : #ifdef CONFIG_IBSS_RSN
    1494                 :          0 : static int wpa_supplicant_ctrl_iface_ibss_rsn(
    1495                 :            :         struct wpa_supplicant *wpa_s, char *addr)
    1496                 :            : {
    1497                 :            :         u8 peer[ETH_ALEN];
    1498                 :            : 
    1499         [ #  # ]:          0 :         if (hwaddr_aton(addr, peer)) {
    1500                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN: invalid "
    1501                 :            :                            "address '%s'", addr);
    1502                 :          0 :                 return -1;
    1503                 :            :         }
    1504                 :            : 
    1505                 :          0 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN " MACSTR,
    1506                 :          0 :                    MAC2STR(peer));
    1507                 :            : 
    1508                 :          0 :         return ibss_rsn_start(wpa_s->ibss_rsn, peer);
    1509                 :            : }
    1510                 :            : #endif /* CONFIG_IBSS_RSN */
    1511                 :            : 
    1512                 :            : 
    1513                 :         12 : static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
    1514                 :            :                                               char *rsp)
    1515                 :            : {
    1516                 :            : #ifdef IEEE8021X_EAPOL
    1517                 :            :         char *pos, *id_pos;
    1518                 :            :         int id;
    1519                 :            :         struct wpa_ssid *ssid;
    1520                 :            : 
    1521                 :         12 :         pos = os_strchr(rsp, '-');
    1522         [ -  + ]:         12 :         if (pos == NULL)
    1523                 :          0 :                 return -1;
    1524                 :         12 :         *pos++ = '\0';
    1525                 :         12 :         id_pos = pos;
    1526                 :         12 :         pos = os_strchr(pos, ':');
    1527         [ -  + ]:         12 :         if (pos == NULL)
    1528                 :          0 :                 return -1;
    1529                 :         12 :         *pos++ = '\0';
    1530                 :         12 :         id = atoi(id_pos);
    1531                 :         12 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);
    1532                 :         12 :         wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
    1533                 :            :                               (u8 *) pos, os_strlen(pos));
    1534                 :            : 
    1535                 :         12 :         ssid = wpa_config_get_network(wpa_s->conf, id);
    1536         [ -  + ]:         12 :         if (ssid == NULL) {
    1537                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
    1538                 :            :                            "to update", id);
    1539                 :          0 :                 return -1;
    1540                 :            :         }
    1541                 :            : 
    1542                 :         12 :         return wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s, ssid, rsp,
    1543                 :            :                                                          pos);
    1544                 :            : #else /* IEEE8021X_EAPOL */
    1545                 :            :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
    1546                 :            :         return -1;
    1547                 :            : #endif /* IEEE8021X_EAPOL */
    1548                 :            : }
    1549                 :            : 
    1550                 :            : 
    1551                 :       1710 : static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
    1552                 :            :                                             const char *params,
    1553                 :            :                                             char *buf, size_t buflen)
    1554                 :            : {
    1555                 :            :         char *pos, *end, tmp[30];
    1556                 :            :         int res, verbose, wps, ret;
    1557                 :            : #ifdef CONFIG_HS20
    1558                 :            :         const u8 *hs20;
    1559                 :            : #endif /* CONFIG_HS20 */
    1560                 :            : 
    1561         [ +  + ]:       1710 :         if (os_strcmp(params, "-DRIVER") == 0)
    1562                 :       1186 :                 return wpa_drv_status(wpa_s, buf, buflen);
    1563                 :        524 :         verbose = os_strcmp(params, "-VERBOSE") == 0;
    1564                 :        524 :         wps = os_strcmp(params, "-WPS") == 0;
    1565                 :        524 :         pos = buf;
    1566                 :        524 :         end = buf + buflen;
    1567         [ +  + ]:        524 :         if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
    1568                 :        355 :                 struct wpa_ssid *ssid = wpa_s->current_ssid;
    1569                 :       2130 :                 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
    1570                 :       2130 :                                   MAC2STR(wpa_s->bssid));
    1571 [ +  - ][ -  + ]:        355 :                 if (ret < 0 || ret >= end - pos)
    1572                 :          0 :                         return pos - buf;
    1573                 :        355 :                 pos += ret;
    1574         [ +  - ]:        355 :                 if (ssid) {
    1575                 :        355 :                         u8 *_ssid = ssid->ssid;
    1576                 :        355 :                         size_t ssid_len = ssid->ssid_len;
    1577                 :            :                         u8 ssid_buf[MAX_SSID_LEN];
    1578         [ +  + ]:        355 :                         if (ssid_len == 0) {
    1579                 :          1 :                                 int _res = wpa_drv_get_ssid(wpa_s, ssid_buf);
    1580         [ -  + ]:          1 :                                 if (_res < 0)
    1581                 :          0 :                                         ssid_len = 0;
    1582                 :            :                                 else
    1583                 :          1 :                                         ssid_len = _res;
    1584                 :          1 :                                 _ssid = ssid_buf;
    1585                 :            :                         }
    1586                 :        355 :                         ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n",
    1587                 :            :                                           wpa_ssid_txt(_ssid, ssid_len),
    1588                 :            :                                           ssid->id);
    1589 [ +  - ][ -  + ]:        355 :                         if (ret < 0 || ret >= end - pos)
    1590                 :          0 :                                 return pos - buf;
    1591                 :        355 :                         pos += ret;
    1592                 :            : 
    1593         [ -  + ]:        355 :                         if (wps && ssid->passphrase &&
           [ #  #  #  # ]
    1594         [ #  # ]:          0 :                             wpa_key_mgmt_wpa_psk(ssid->key_mgmt) &&
    1595         [ #  # ]:          0 :                             (ssid->mode == WPAS_MODE_AP ||
    1596                 :          0 :                              ssid->mode == WPAS_MODE_P2P_GO)) {
    1597                 :          0 :                                 ret = os_snprintf(pos, end - pos,
    1598                 :            :                                                   "passphrase=%s\n",
    1599                 :            :                                                   ssid->passphrase);
    1600 [ #  # ][ #  # ]:          0 :                                 if (ret < 0 || ret >= end - pos)
    1601                 :          0 :                                         return pos - buf;
    1602                 :          0 :                                 pos += ret;
    1603                 :            :                         }
    1604         [ -  + ]:        355 :                         if (ssid->id_str) {
    1605                 :          0 :                                 ret = os_snprintf(pos, end - pos,
    1606                 :            :                                                   "id_str=%s\n",
    1607                 :            :                                                   ssid->id_str);
    1608 [ #  # ][ #  # ]:          0 :                                 if (ret < 0 || ret >= end - pos)
    1609                 :          0 :                                         return pos - buf;
    1610                 :          0 :                                 pos += ret;
    1611                 :            :                         }
    1612                 :            : 
    1613   [ +  +  +  +  :        355 :                         switch (ssid->mode) {
                   -  - ]
    1614                 :            :                         case WPAS_MODE_INFRA:
    1615                 :        320 :                                 ret = os_snprintf(pos, end - pos,
    1616                 :            :                                                   "mode=station\n");
    1617                 :        320 :                                 break;
    1618                 :            :                         case WPAS_MODE_IBSS:
    1619                 :          3 :                                 ret = os_snprintf(pos, end - pos,
    1620                 :            :                                                   "mode=IBSS\n");
    1621                 :          3 :                                 break;
    1622                 :            :                         case WPAS_MODE_AP:
    1623                 :          2 :                                 ret = os_snprintf(pos, end - pos,
    1624                 :            :                                                   "mode=AP\n");
    1625                 :          2 :                                 break;
    1626                 :            :                         case WPAS_MODE_P2P_GO:
    1627                 :         30 :                                 ret = os_snprintf(pos, end - pos,
    1628                 :            :                                                   "mode=P2P GO\n");
    1629                 :         30 :                                 break;
    1630                 :            :                         case WPAS_MODE_P2P_GROUP_FORMATION:
    1631                 :          0 :                                 ret = os_snprintf(pos, end - pos,
    1632                 :            :                                                   "mode=P2P GO - group "
    1633                 :            :                                                   "formation\n");
    1634                 :          0 :                                 break;
    1635                 :            :                         default:
    1636                 :          0 :                                 ret = 0;
    1637                 :          0 :                                 break;
    1638                 :            :                         }
    1639 [ +  - ][ -  + ]:        355 :                         if (ret < 0 || ret >= end - pos)
    1640                 :          0 :                                 return pos - buf;
    1641                 :        355 :                         pos += ret;
    1642                 :            :                 }
    1643                 :            : 
    1644                 :            : #ifdef CONFIG_AP
    1645         [ +  + ]:        355 :                 if (wpa_s->ap_iface) {
    1646                 :         32 :                         pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
    1647                 :         32 :                                                             end - pos,
    1648                 :            :                                                             verbose);
    1649                 :            :                 } else
    1650                 :            : #endif /* CONFIG_AP */
    1651                 :        323 :                 pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);
    1652                 :            :         }
    1653                 :            : #ifdef CONFIG_SAE
    1654 [ +  + ][ +  + ]:        524 :         if (wpa_s->wpa_state >= WPA_ASSOCIATED &&
    1655                 :            : #ifdef CONFIG_AP
    1656         [ +  + ]:        323 :             !wpa_s->ap_iface &&
    1657                 :            : #endif /* CONFIG_AP */
    1658                 :        323 :             wpa_s->sme.sae.state == SAE_ACCEPTED) {
    1659                 :         16 :                 ret = os_snprintf(pos, end - pos, "sae_group=%d\n",
    1660                 :            :                                   wpa_s->sme.sae.group);
    1661 [ +  - ][ -  + ]:         16 :                 if (ret < 0 || ret >= end - pos)
    1662                 :          0 :                         return pos - buf;
    1663                 :         16 :                 pos += ret;
    1664                 :            :         }
    1665                 :            : #endif /* CONFIG_SAE */
    1666                 :        524 :         ret = os_snprintf(pos, end - pos, "wpa_state=%s\n",
    1667                 :            :                           wpa_supplicant_state_txt(wpa_s->wpa_state));
    1668 [ +  - ][ -  + ]:        524 :         if (ret < 0 || ret >= end - pos)
    1669                 :          0 :                 return pos - buf;
    1670                 :        524 :         pos += ret;
    1671                 :            : 
    1672   [ +  -  -  + ]:       1048 :         if (wpa_s->l2 &&
    1673                 :        524 :             l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) {
    1674                 :          0 :                 ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp);
    1675 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    1676                 :          0 :                         return pos - buf;
    1677                 :          0 :                 pos += ret;
    1678                 :            :         }
    1679                 :            : 
    1680                 :            : #ifdef CONFIG_P2P
    1681         [ +  - ]:        524 :         if (wpa_s->global->p2p) {
    1682                 :       3144 :                 ret = os_snprintf(pos, end - pos, "p2p_device_address=" MACSTR
    1683                 :       3144 :                                   "\n", MAC2STR(wpa_s->global->p2p_dev_addr));
    1684 [ +  - ][ -  + ]:        524 :                 if (ret < 0 || ret >= end - pos)
    1685                 :          0 :                         return pos - buf;
    1686                 :        524 :                 pos += ret;
    1687                 :            :         }
    1688                 :            : #endif /* CONFIG_P2P */
    1689                 :            : 
    1690                 :       3144 :         ret = os_snprintf(pos, end - pos, "address=" MACSTR "\n",
    1691                 :       3144 :                           MAC2STR(wpa_s->own_addr));
    1692 [ +  - ][ -  + ]:        524 :         if (ret < 0 || ret >= end - pos)
    1693                 :          0 :                 return pos - buf;
    1694                 :        524 :         pos += ret;
    1695                 :            : 
    1696                 :            : #ifdef CONFIG_HS20
    1697 [ +  + ][ +  + ]:        524 :         if (wpa_s->current_bss &&
    1698                 :        301 :             (hs20 = wpa_bss_get_vendor_ie(wpa_s->current_bss,
    1699         [ +  - ]:         38 :                                           HS20_IE_VENDOR_TYPE)) &&
    1700         [ +  - ]:         38 :             wpa_s->wpa_proto == WPA_PROTO_RSN &&
    1701                 :         38 :             wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
    1702                 :         38 :                 int release = 1;
    1703         [ +  - ]:         38 :                 if (hs20[1] >= 5) {
    1704                 :         38 :                         u8 rel_num = (hs20[6] & 0xf0) >> 4;
    1705                 :         38 :                         release = rel_num + 1;
    1706                 :            :                 }
    1707                 :         38 :                 ret = os_snprintf(pos, end - pos, "hs20=%d\n", release);
    1708 [ +  - ][ -  + ]:         38 :                 if (ret < 0 || ret >= end - pos)
    1709                 :          0 :                         return pos - buf;
    1710                 :         38 :                 pos += ret;
    1711                 :            :         }
    1712                 :            : 
    1713         [ +  + ]:        524 :         if (wpa_s->current_ssid) {
    1714                 :            :                 struct wpa_cred *cred;
    1715                 :            :                 char *type;
    1716                 :            : 
    1717         [ +  + ]:        360 :                 for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
    1718                 :            :                         size_t i;
    1719                 :            : 
    1720         [ +  + ]:         41 :                         if (wpa_s->current_ssid->parent_cred != cred)
    1721                 :          3 :                                 continue;
    1722                 :            : 
    1723         [ +  + ]:         38 :                         if (cred->provisioning_sp) {
    1724                 :          6 :                                 ret = os_snprintf(pos, end - pos,
    1725                 :            :                                                   "provisioning_sp=%s\n",
    1726                 :            :                                                   cred->provisioning_sp);
    1727 [ +  - ][ -  + ]:          6 :                                 if (ret < 0 || ret >= end - pos)
    1728                 :          0 :                                         return pos - buf;
    1729                 :          6 :                                 pos += ret;
    1730                 :            :                         }
    1731                 :            : 
    1732         [ +  + ]:         38 :                         if (!cred->domain)
    1733                 :         21 :                                 goto no_domain;
    1734                 :            : 
    1735                 :         17 :                         i = 0;
    1736 [ +  - ][ +  - ]:         17 :                         if (wpa_s->current_bss && wpa_s->current_bss->anqp) {
    1737                 :         17 :                                 struct wpabuf *names =
    1738                 :         17 :                                         wpa_s->current_bss->anqp->domain_name;
    1739 [ +  + ][ +  + ]:         18 :                                 for (i = 0; names && i < cred->num_domain; i++)
    1740                 :            :                                 {
    1741         [ +  + ]:         13 :                                         if (domain_name_list_contains(
    1742                 :         13 :                                                     names, cred->domain[i], 1))
    1743                 :         12 :                                                 break;
    1744                 :            :                                 }
    1745         [ +  + ]:         17 :                                 if (i == cred->num_domain)
    1746                 :          1 :                                         i = 0; /* show first entry by default */
    1747                 :            :                         }
    1748                 :         17 :                         ret = os_snprintf(pos, end - pos, "home_sp=%s\n",
    1749                 :         17 :                                           cred->domain[i]);
    1750 [ +  - ][ -  + ]:         17 :                         if (ret < 0 || ret >= end - pos)
    1751                 :          0 :                                 return pos - buf;
    1752                 :         17 :                         pos += ret;
    1753                 :            : 
    1754                 :            :                 no_domain:
    1755 [ +  - ][ -  + ]:         38 :                         if (wpa_s->current_bss == NULL ||
    1756                 :         38 :                             wpa_s->current_bss->anqp == NULL)
    1757                 :          0 :                                 res = -1;
    1758                 :            :                         else
    1759                 :         38 :                                 res = interworking_home_sp_cred(
    1760                 :            :                                         wpa_s, cred,
    1761                 :         38 :                                         wpa_s->current_bss->anqp->domain_name);
    1762         [ +  + ]:         38 :                         if (res > 0)
    1763                 :         16 :                                 type = "home";
    1764         [ +  + ]:         22 :                         else if (res == 0)
    1765                 :          3 :                                 type = "roaming";
    1766                 :            :                         else
    1767                 :         19 :                                 type = "unknown";
    1768                 :            : 
    1769                 :         38 :                         ret = os_snprintf(pos, end - pos, "sp_type=%s\n", type);
    1770 [ +  - ][ -  + ]:         38 :                         if (ret < 0 || ret >= end - pos)
    1771                 :          0 :                                 return pos - buf;
    1772                 :         38 :                         pos += ret;
    1773                 :            : 
    1774                 :         38 :                         break;
    1775                 :            :                 }
    1776                 :            :         }
    1777                 :            : #endif /* CONFIG_HS20 */
    1778                 :            : 
    1779 [ +  + ][ -  + ]:        524 :         if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
    1780                 :        410 :             wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
    1781                 :        114 :                 res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos,
    1782                 :            :                                           verbose);
    1783         [ +  - ]:        114 :                 if (res >= 0)
    1784                 :        114 :                         pos += res;
    1785                 :            :         }
    1786                 :            : 
    1787                 :        524 :         res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose);
    1788         [ +  - ]:        524 :         if (res >= 0)
    1789                 :        524 :                 pos += res;
    1790                 :            : 
    1791                 :            : #ifdef CONFIG_WPS
    1792                 :            :         {
    1793                 :            :                 char uuid_str[100];
    1794                 :        524 :                 uuid_bin2str(wpa_s->wps->uuid, uuid_str, sizeof(uuid_str));
    1795                 :        524 :                 ret = os_snprintf(pos, end - pos, "uuid=%s\n", uuid_str);
    1796 [ +  - ][ -  + ]:        524 :                 if (ret < 0 || ret >= end - pos)
    1797                 :          0 :                         return pos - buf;
    1798                 :        524 :                 pos += ret;
    1799                 :            :         }
    1800                 :            : #endif /* CONFIG_WPS */
    1801                 :            : 
    1802                 :            : #ifdef ANDROID
    1803                 :            :         wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_STATE_CHANGE
    1804                 :            :                      "id=%d state=%d BSSID=" MACSTR " SSID=%s",
    1805                 :            :                      wpa_s->current_ssid ? wpa_s->current_ssid->id : -1,
    1806                 :            :                      wpa_s->wpa_state,
    1807                 :            :                      MAC2STR(wpa_s->bssid),
    1808                 :            :                      wpa_s->current_ssid && wpa_s->current_ssid->ssid ?
    1809                 :            :                      wpa_ssid_txt(wpa_s->current_ssid->ssid,
    1810                 :            :                                   wpa_s->current_ssid->ssid_len) : "");
    1811                 :            :         if (wpa_s->wpa_state == WPA_COMPLETED) {
    1812                 :            :                 struct wpa_ssid *ssid = wpa_s->current_ssid;
    1813                 :            :                 wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED
    1814                 :            :                              "- connection to " MACSTR
    1815                 :            :                              " completed %s [id=%d id_str=%s]",
    1816                 :            :                              MAC2STR(wpa_s->bssid), "(auth)",
    1817                 :            :                              ssid ? ssid->id : -1,
    1818                 :            :                              ssid && ssid->id_str ? ssid->id_str : "");
    1819                 :            :         }
    1820                 :            : #endif /* ANDROID */
    1821                 :            : 
    1822                 :       1710 :         return pos - buf;
    1823                 :            : }
    1824                 :            : 
    1825                 :            : 
    1826                 :          0 : static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s,
    1827                 :            :                                            char *cmd)
    1828                 :            : {
    1829                 :            :         char *pos;
    1830                 :            :         int id;
    1831                 :            :         struct wpa_ssid *ssid;
    1832                 :            :         u8 bssid[ETH_ALEN];
    1833                 :            : 
    1834                 :            :         /* cmd: "<network id> <BSSID>" */
    1835                 :          0 :         pos = os_strchr(cmd, ' ');
    1836         [ #  # ]:          0 :         if (pos == NULL)
    1837                 :          0 :                 return -1;
    1838                 :          0 :         *pos++ = '\0';
    1839                 :          0 :         id = atoi(cmd);
    1840                 :          0 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos);
    1841         [ #  # ]:          0 :         if (hwaddr_aton(pos, bssid)) {
    1842                 :          0 :                 wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos);
    1843                 :          0 :                 return -1;
    1844                 :            :         }
    1845                 :            : 
    1846                 :          0 :         ssid = wpa_config_get_network(wpa_s->conf, id);
    1847         [ #  # ]:          0 :         if (ssid == NULL) {
    1848                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
    1849                 :            :                            "to update", id);
    1850                 :          0 :                 return -1;
    1851                 :            :         }
    1852                 :            : 
    1853                 :          0 :         os_memcpy(ssid->bssid, bssid, ETH_ALEN);
    1854                 :          0 :         ssid->bssid_set = !is_zero_ether_addr(bssid);
    1855                 :            : 
    1856                 :          0 :         return 0;
    1857                 :            : }
    1858                 :            : 
    1859                 :            : 
    1860                 :          0 : static int wpa_supplicant_ctrl_iface_blacklist(struct wpa_supplicant *wpa_s,
    1861                 :            :                                                char *cmd, char *buf,
    1862                 :            :                                                size_t buflen)
    1863                 :            : {
    1864                 :            :         u8 bssid[ETH_ALEN];
    1865                 :            :         struct wpa_blacklist *e;
    1866                 :            :         char *pos, *end;
    1867                 :            :         int ret;
    1868                 :            : 
    1869                 :            :         /* cmd: "BLACKLIST [<BSSID>]" */
    1870         [ #  # ]:          0 :         if (*cmd == '\0') {
    1871                 :          0 :                 pos = buf;
    1872                 :          0 :                 end = buf + buflen;
    1873                 :          0 :                 e = wpa_s->blacklist;
    1874         [ #  # ]:          0 :                 while (e) {
    1875                 :          0 :                         ret = os_snprintf(pos, end - pos, MACSTR "\n",
    1876                 :          0 :                                           MAC2STR(e->bssid));
    1877 [ #  # ][ #  # ]:          0 :                         if (ret < 0 || ret >= end - pos)
    1878                 :          0 :                                 return pos - buf;
    1879                 :          0 :                         pos += ret;
    1880                 :          0 :                         e = e->next;
    1881                 :            :                 }
    1882                 :          0 :                 return pos - buf;
    1883                 :            :         }
    1884                 :            : 
    1885                 :          0 :         cmd++;
    1886         [ #  # ]:          0 :         if (os_strncmp(cmd, "clear", 5) == 0) {
    1887                 :          0 :                 wpa_blacklist_clear(wpa_s);
    1888                 :          0 :                 os_memcpy(buf, "OK\n", 3);
    1889                 :          0 :                 return 3;
    1890                 :            :         }
    1891                 :            : 
    1892                 :          0 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: BLACKLIST bssid='%s'", cmd);
    1893         [ #  # ]:          0 :         if (hwaddr_aton(cmd, bssid)) {
    1894                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: invalid BSSID '%s'", cmd);
    1895                 :          0 :                 return -1;
    1896                 :            :         }
    1897                 :            : 
    1898                 :            :         /*
    1899                 :            :          * Add the BSSID twice, so its count will be 2, causing it to be
    1900                 :            :          * skipped when processing scan results.
    1901                 :            :          */
    1902                 :          0 :         ret = wpa_blacklist_add(wpa_s, bssid);
    1903         [ #  # ]:          0 :         if (ret != 0)
    1904                 :          0 :                 return -1;
    1905                 :          0 :         ret = wpa_blacklist_add(wpa_s, bssid);
    1906         [ #  # ]:          0 :         if (ret != 0)
    1907                 :          0 :                 return -1;
    1908                 :          0 :         os_memcpy(buf, "OK\n", 3);
    1909                 :          0 :         return 3;
    1910                 :            : }
    1911                 :            : 
    1912                 :            : 
    1913                 :          0 : static const char * debug_level_str(int level)
    1914                 :            : {
    1915   [ #  #  #  #  :          0 :         switch (level) {
                #  #  # ]
    1916                 :            :         case MSG_EXCESSIVE:
    1917                 :          0 :                 return "EXCESSIVE";
    1918                 :            :         case MSG_MSGDUMP:
    1919                 :          0 :                 return "MSGDUMP";
    1920                 :            :         case MSG_DEBUG:
    1921                 :          0 :                 return "DEBUG";
    1922                 :            :         case MSG_INFO:
    1923                 :          0 :                 return "INFO";
    1924                 :            :         case MSG_WARNING:
    1925                 :          0 :                 return "WARNING";
    1926                 :            :         case MSG_ERROR:
    1927                 :          0 :                 return "ERROR";
    1928                 :            :         default:
    1929                 :          0 :                 return "?";
    1930                 :            :         }
    1931                 :            : }
    1932                 :            : 
    1933                 :            : 
    1934                 :          0 : static int str_to_debug_level(const char *s)
    1935                 :            : {
    1936         [ #  # ]:          0 :         if (os_strcasecmp(s, "EXCESSIVE") == 0)
    1937                 :          0 :                 return MSG_EXCESSIVE;
    1938         [ #  # ]:          0 :         if (os_strcasecmp(s, "MSGDUMP") == 0)
    1939                 :          0 :                 return MSG_MSGDUMP;
    1940         [ #  # ]:          0 :         if (os_strcasecmp(s, "DEBUG") == 0)
    1941                 :          0 :                 return MSG_DEBUG;
    1942         [ #  # ]:          0 :         if (os_strcasecmp(s, "INFO") == 0)
    1943                 :          0 :                 return MSG_INFO;
    1944         [ #  # ]:          0 :         if (os_strcasecmp(s, "WARNING") == 0)
    1945                 :          0 :                 return MSG_WARNING;
    1946         [ #  # ]:          0 :         if (os_strcasecmp(s, "ERROR") == 0)
    1947                 :          0 :                 return MSG_ERROR;
    1948                 :          0 :         return -1;
    1949                 :            : }
    1950                 :            : 
    1951                 :            : 
    1952                 :          0 : static int wpa_supplicant_ctrl_iface_log_level(struct wpa_supplicant *wpa_s,
    1953                 :            :                                                char *cmd, char *buf,
    1954                 :            :                                                size_t buflen)
    1955                 :            : {
    1956                 :            :         char *pos, *end, *stamp;
    1957                 :            :         int ret;
    1958                 :            : 
    1959         [ #  # ]:          0 :         if (cmd == NULL) {
    1960                 :          0 :                 return -1;
    1961                 :            :         }
    1962                 :            : 
    1963                 :            :         /* cmd: "LOG_LEVEL [<level>]" */
    1964         [ #  # ]:          0 :         if (*cmd == '\0') {
    1965                 :          0 :                 pos = buf;
    1966                 :          0 :                 end = buf + buflen;
    1967                 :          0 :                 ret = os_snprintf(pos, end - pos, "Current level: %s\n"
    1968                 :            :                                   "Timestamp: %d\n",
    1969                 :            :                                   debug_level_str(wpa_debug_level),
    1970                 :            :                                   wpa_debug_timestamp);
    1971 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    1972                 :          0 :                         ret = 0;
    1973                 :            : 
    1974                 :          0 :                 return ret;
    1975                 :            :         }
    1976                 :            : 
    1977         [ #  # ]:          0 :         while (*cmd == ' ')
    1978                 :          0 :                 cmd++;
    1979                 :            : 
    1980                 :          0 :         stamp = os_strchr(cmd, ' ');
    1981         [ #  # ]:          0 :         if (stamp) {
    1982                 :          0 :                 *stamp++ = '\0';
    1983         [ #  # ]:          0 :                 while (*stamp == ' ') {
    1984                 :          0 :                         stamp++;
    1985                 :            :                 }
    1986                 :            :         }
    1987                 :            : 
    1988 [ #  # ][ #  # ]:          0 :         if (cmd && os_strlen(cmd)) {
    1989                 :          0 :                 int level = str_to_debug_level(cmd);
    1990         [ #  # ]:          0 :                 if (level < 0)
    1991                 :          0 :                         return -1;
    1992                 :          0 :                 wpa_debug_level = level;
    1993                 :            :         }
    1994                 :            : 
    1995 [ #  # ][ #  # ]:          0 :         if (stamp && os_strlen(stamp))
    1996                 :          0 :                 wpa_debug_timestamp = atoi(stamp);
    1997                 :            : 
    1998                 :          0 :         os_memcpy(buf, "OK\n", 3);
    1999                 :          0 :         return 3;
    2000                 :            : }
    2001                 :            : 
    2002                 :            : 
    2003                 :          7 : static int wpa_supplicant_ctrl_iface_list_networks(
    2004                 :            :         struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
    2005                 :            : {
    2006                 :            :         char *pos, *end;
    2007                 :            :         struct wpa_ssid *ssid;
    2008                 :            :         int ret;
    2009                 :            : 
    2010                 :          7 :         pos = buf;
    2011                 :          7 :         end = buf + buflen;
    2012                 :          7 :         ret = os_snprintf(pos, end - pos,
    2013                 :            :                           "network id / ssid / bssid / flags\n");
    2014 [ +  - ][ -  + ]:          7 :         if (ret < 0 || ret >= end - pos)
    2015                 :          0 :                 return pos - buf;
    2016                 :          7 :         pos += ret;
    2017                 :            : 
    2018                 :          7 :         ssid = wpa_s->conf->ssid;
    2019         [ +  + ]:         15 :         while (ssid) {
    2020                 :          8 :                 ret = os_snprintf(pos, end - pos, "%d\t%s",
    2021                 :            :                                   ssid->id,
    2022                 :          8 :                                   wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
    2023 [ +  - ][ -  + ]:          8 :                 if (ret < 0 || ret >= end - pos)
    2024                 :          0 :                         return pos - buf;
    2025                 :          8 :                 pos += ret;
    2026         [ +  + ]:          8 :                 if (ssid->bssid_set) {
    2027                 :          3 :                         ret = os_snprintf(pos, end - pos, "\t" MACSTR,
    2028                 :         18 :                                           MAC2STR(ssid->bssid));
    2029                 :            :                 } else {
    2030                 :          5 :                         ret = os_snprintf(pos, end - pos, "\tany");
    2031                 :            :                 }
    2032 [ +  - ][ -  + ]:          8 :                 if (ret < 0 || ret >= end - pos)
    2033                 :          0 :                         return pos - buf;
    2034                 :          8 :                 pos += ret;
    2035 [ +  + ][ +  + ]:          8 :                 ret = os_snprintf(pos, end - pos, "\t%s%s%s%s",
         [ +  + ][ +  + ]
    2036                 :          8 :                                   ssid == wpa_s->current_ssid ?
    2037                 :            :                                   "[CURRENT]" : "",
    2038                 :          8 :                                   ssid->disabled ? "[DISABLED]" : "",
    2039                 :          8 :                                   ssid->disabled_until.sec ?
    2040                 :            :                                   "[TEMP-DISABLED]" : "",
    2041                 :          8 :                                   ssid->disabled == 2 ? "[P2P-PERSISTENT]" :
    2042                 :            :                                   "");
    2043 [ +  - ][ -  + ]:          8 :                 if (ret < 0 || ret >= end - pos)
    2044                 :          0 :                         return pos - buf;
    2045                 :          8 :                 pos += ret;
    2046                 :          8 :                 ret = os_snprintf(pos, end - pos, "\n");
    2047 [ +  - ][ -  + ]:          8 :                 if (ret < 0 || ret >= end - pos)
    2048                 :          0 :                         return pos - buf;
    2049                 :          8 :                 pos += ret;
    2050                 :            : 
    2051                 :          8 :                 ssid = ssid->next;
    2052                 :            :         }
    2053                 :            : 
    2054                 :          7 :         return pos - buf;
    2055                 :            : }
    2056                 :            : 
    2057                 :            : 
    2058                 :         28 : static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher)
    2059                 :            : {
    2060                 :            :         int ret;
    2061                 :         28 :         ret = os_snprintf(pos, end - pos, "-");
    2062 [ +  - ][ -  + ]:         28 :         if (ret < 0 || ret >= end - pos)
    2063                 :          0 :                 return pos;
    2064                 :         28 :         pos += ret;
    2065                 :         28 :         ret = wpa_write_ciphers(pos, end, cipher, "+");
    2066         [ -  + ]:         28 :         if (ret < 0)
    2067                 :          0 :                 return pos;
    2068                 :         28 :         pos += ret;
    2069                 :         28 :         return pos;
    2070                 :            : }
    2071                 :            : 
    2072                 :            : 
    2073                 :         28 : static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
    2074                 :            :                                     const u8 *ie, size_t ie_len)
    2075                 :            : {
    2076                 :            :         struct wpa_ie_data data;
    2077                 :            :         char *start;
    2078                 :            :         int ret;
    2079                 :            : 
    2080                 :         28 :         ret = os_snprintf(pos, end - pos, "[%s-", proto);
    2081 [ +  - ][ -  + ]:         28 :         if (ret < 0 || ret >= end - pos)
    2082                 :          0 :                 return pos;
    2083                 :         28 :         pos += ret;
    2084                 :            : 
    2085         [ -  + ]:         28 :         if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) {
    2086                 :          0 :                 ret = os_snprintf(pos, end - pos, "?]");
    2087 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2088                 :          0 :                         return pos;
    2089                 :          0 :                 pos += ret;
    2090                 :          0 :                 return pos;
    2091                 :            :         }
    2092                 :            : 
    2093                 :         28 :         start = pos;
    2094         [ +  + ]:         28 :         if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
    2095         [ +  - ]:          6 :                 ret = os_snprintf(pos, end - pos, "%sEAP",
    2096                 :            :                                   pos == start ? "" : "+");
    2097 [ +  - ][ -  + ]:          6 :                 if (ret < 0 || ret >= end - pos)
    2098                 :          0 :                         return pos;
    2099                 :          6 :                 pos += ret;
    2100                 :            :         }
    2101         [ +  + ]:         28 :         if (data.key_mgmt & WPA_KEY_MGMT_PSK) {
    2102         [ +  - ]:         22 :                 ret = os_snprintf(pos, end - pos, "%sPSK",
    2103                 :            :                                   pos == start ? "" : "+");
    2104 [ +  - ][ -  + ]:         22 :                 if (ret < 0 || ret >= end - pos)
    2105                 :          0 :                         return pos;
    2106                 :         22 :                 pos += ret;
    2107                 :            :         }
    2108         [ -  + ]:         28 :         if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
    2109         [ #  # ]:          0 :                 ret = os_snprintf(pos, end - pos, "%sNone",
    2110                 :            :                                   pos == start ? "" : "+");
    2111 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2112                 :          0 :                         return pos;
    2113                 :          0 :                 pos += ret;
    2114                 :            :         }
    2115                 :            : #ifdef CONFIG_IEEE80211R
    2116         [ -  + ]:         28 :         if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
    2117         [ #  # ]:          0 :                 ret = os_snprintf(pos, end - pos, "%sFT/EAP",
    2118                 :            :                                   pos == start ? "" : "+");
    2119 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2120                 :          0 :                         return pos;
    2121                 :          0 :                 pos += ret;
    2122                 :            :         }
    2123         [ -  + ]:         28 :         if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) {
    2124         [ #  # ]:          0 :                 ret = os_snprintf(pos, end - pos, "%sFT/PSK",
    2125                 :            :                                   pos == start ? "" : "+");
    2126 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2127                 :          0 :                         return pos;
    2128                 :          0 :                 pos += ret;
    2129                 :            :         }
    2130                 :            : #endif /* CONFIG_IEEE80211R */
    2131                 :            : #ifdef CONFIG_IEEE80211W
    2132         [ -  + ]:         28 :         if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
    2133         [ #  # ]:          0 :                 ret = os_snprintf(pos, end - pos, "%sEAP-SHA256",
    2134                 :            :                                   pos == start ? "" : "+");
    2135 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2136                 :          0 :                         return pos;
    2137                 :          0 :                 pos += ret;
    2138                 :            :         }
    2139         [ -  + ]:         28 :         if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
    2140         [ #  # ]:          0 :                 ret = os_snprintf(pos, end - pos, "%sPSK-SHA256",
    2141                 :            :                                   pos == start ? "" : "+");
    2142 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2143                 :          0 :                         return pos;
    2144                 :          0 :                 pos += ret;
    2145                 :            :         }
    2146                 :            : #endif /* CONFIG_IEEE80211W */
    2147                 :            : 
    2148                 :         28 :         pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);
    2149                 :            : 
    2150         [ -  + ]:         28 :         if (data.capabilities & WPA_CAPABILITY_PREAUTH) {
    2151                 :          0 :                 ret = os_snprintf(pos, end - pos, "-preauth");
    2152 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2153                 :          0 :                         return pos;
    2154                 :          0 :                 pos += ret;
    2155                 :            :         }
    2156                 :            : 
    2157                 :         28 :         ret = os_snprintf(pos, end - pos, "]");
    2158 [ +  - ][ -  + ]:         28 :         if (ret < 0 || ret >= end - pos)
    2159                 :          0 :                 return pos;
    2160                 :         28 :         pos += ret;
    2161                 :            : 
    2162                 :         28 :         return pos;
    2163                 :            : }
    2164                 :            : 
    2165                 :            : 
    2166                 :            : #ifdef CONFIG_WPS
    2167                 :         34 : static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant *wpa_s,
    2168                 :            :                                             char *pos, char *end,
    2169                 :            :                                             struct wpabuf *wps_ie)
    2170                 :            : {
    2171                 :            :         int ret;
    2172                 :            :         const char *txt;
    2173                 :            : 
    2174         [ +  + ]:         34 :         if (wps_ie == NULL)
    2175                 :         14 :                 return pos;
    2176         [ +  + ]:         20 :         if (wps_is_selected_pbc_registrar(wps_ie))
    2177                 :          4 :                 txt = "[WPS-PBC]";
    2178                 :            : #ifdef CONFIG_WPS2
    2179         [ +  + ]:         16 :         else if (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 0))
    2180                 :          7 :                 txt = "[WPS-AUTH]";
    2181                 :            : #endif /* CONFIG_WPS2 */
    2182         [ -  + ]:          9 :         else if (wps_is_selected_pin_registrar(wps_ie))
    2183                 :          0 :                 txt = "[WPS-PIN]";
    2184                 :            :         else
    2185                 :          9 :                 txt = "[WPS]";
    2186                 :            : 
    2187                 :         20 :         ret = os_snprintf(pos, end - pos, "%s", txt);
    2188 [ +  - ][ +  - ]:         20 :         if (ret >= 0 && ret < end - pos)
    2189                 :         20 :                 pos += ret;
    2190                 :         20 :         wpabuf_free(wps_ie);
    2191                 :         34 :         return pos;
    2192                 :            : }
    2193                 :            : #endif /* CONFIG_WPS */
    2194                 :            : 
    2195                 :            : 
    2196                 :         34 : static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant *wpa_s,
    2197                 :            :                                         char *pos, char *end,
    2198                 :            :                                         const struct wpa_bss *bss)
    2199                 :            : {
    2200                 :            : #ifdef CONFIG_WPS
    2201                 :            :         struct wpabuf *wps_ie;
    2202                 :         34 :         wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
    2203                 :         34 :         return wpa_supplicant_wps_ie_txt_buf(wpa_s, pos, end, wps_ie);
    2204                 :            : #else /* CONFIG_WPS */
    2205                 :            :         return pos;
    2206                 :            : #endif /* CONFIG_WPS */
    2207                 :            : }
    2208                 :            : 
    2209                 :            : 
    2210                 :            : /* Format one result on one text line into a buffer. */
    2211                 :          0 : static int wpa_supplicant_ctrl_iface_scan_result(
    2212                 :            :         struct wpa_supplicant *wpa_s,
    2213                 :            :         const struct wpa_bss *bss, char *buf, size_t buflen)
    2214                 :            : {
    2215                 :            :         char *pos, *end;
    2216                 :            :         int ret;
    2217                 :            :         const u8 *ie, *ie2, *p2p;
    2218                 :            : 
    2219                 :          0 :         p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
    2220         [ #  # ]:          0 :         if (!p2p)
    2221                 :          0 :                 p2p = wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE);
    2222 [ #  # ][ #  # ]:          0 :         if (p2p && bss->ssid_len == P2P_WILDCARD_SSID_LEN &&
                 [ #  # ]
    2223                 :          0 :             os_memcmp(bss->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) ==
    2224                 :            :             0)
    2225                 :          0 :                 return 0; /* Do not show P2P listen discovery results here */
    2226                 :            : 
    2227                 :          0 :         pos = buf;
    2228                 :          0 :         end = buf + buflen;
    2229                 :            : 
    2230                 :          0 :         ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t",
    2231                 :          0 :                           MAC2STR(bss->bssid), bss->freq, bss->level);
    2232 [ #  # ][ #  # ]:          0 :         if (ret < 0 || ret >= end - pos)
    2233                 :          0 :                 return -1;
    2234                 :          0 :         pos += ret;
    2235                 :          0 :         ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
    2236         [ #  # ]:          0 :         if (ie)
    2237                 :          0 :                 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
    2238                 :          0 :         ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
    2239         [ #  # ]:          0 :         if (ie2)
    2240                 :          0 :                 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
    2241                 :          0 :         pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
    2242 [ #  # ][ #  # ]:          0 :         if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
                 [ #  # ]
    2243                 :          0 :                 ret = os_snprintf(pos, end - pos, "[WEP]");
    2244 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2245                 :          0 :                         return -1;
    2246                 :          0 :                 pos += ret;
    2247                 :            :         }
    2248         [ #  # ]:          0 :         if (bss->caps & IEEE80211_CAP_IBSS) {
    2249                 :          0 :                 ret = os_snprintf(pos, end - pos, "[IBSS]");
    2250 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2251                 :          0 :                         return -1;
    2252                 :          0 :                 pos += ret;
    2253                 :            :         }
    2254         [ #  # ]:          0 :         if (bss->caps & IEEE80211_CAP_ESS) {
    2255                 :          0 :                 ret = os_snprintf(pos, end - pos, "[ESS]");
    2256 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2257                 :          0 :                         return -1;
    2258                 :          0 :                 pos += ret;
    2259                 :            :         }
    2260         [ #  # ]:          0 :         if (p2p) {
    2261                 :          0 :                 ret = os_snprintf(pos, end - pos, "[P2P]");
    2262 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2263                 :          0 :                         return -1;
    2264                 :          0 :                 pos += ret;
    2265                 :            :         }
    2266                 :            : #ifdef CONFIG_HS20
    2267 [ #  # ][ #  # ]:          0 :         if (wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE) && ie2) {
    2268                 :          0 :                 ret = os_snprintf(pos, end - pos, "[HS20]");
    2269 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2270                 :          0 :                         return -1;
    2271                 :          0 :                 pos += ret;
    2272                 :            :         }
    2273                 :            : #endif /* CONFIG_HS20 */
    2274                 :            : 
    2275                 :          0 :         ret = os_snprintf(pos, end - pos, "\t%s",
    2276                 :          0 :                           wpa_ssid_txt(bss->ssid, bss->ssid_len));
    2277 [ #  # ][ #  # ]:          0 :         if (ret < 0 || ret >= end - pos)
    2278                 :          0 :                 return -1;
    2279                 :          0 :         pos += ret;
    2280                 :            : 
    2281                 :          0 :         ret = os_snprintf(pos, end - pos, "\n");
    2282 [ #  # ][ #  # ]:          0 :         if (ret < 0 || ret >= end - pos)
    2283                 :          0 :                 return -1;
    2284                 :          0 :         pos += ret;
    2285                 :            : 
    2286                 :          0 :         return pos - buf;
    2287                 :            : }
    2288                 :            : 
    2289                 :            : 
    2290                 :          0 : static int wpa_supplicant_ctrl_iface_scan_results(
    2291                 :            :         struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
    2292                 :            : {
    2293                 :            :         char *pos, *end;
    2294                 :            :         struct wpa_bss *bss;
    2295                 :            :         int ret;
    2296                 :            : 
    2297                 :          0 :         pos = buf;
    2298                 :          0 :         end = buf + buflen;
    2299                 :          0 :         ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / "
    2300                 :            :                           "flags / ssid\n");
    2301 [ #  # ][ #  # ]:          0 :         if (ret < 0 || ret >= end - pos)
    2302                 :          0 :                 return pos - buf;
    2303                 :          0 :         pos += ret;
    2304                 :            : 
    2305         [ #  # ]:          0 :         dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
    2306                 :          0 :                 ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos,
    2307                 :          0 :                                                             end - pos);
    2308 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2309                 :          0 :                         return pos - buf;
    2310                 :          0 :                 pos += ret;
    2311                 :            :         }
    2312                 :            : 
    2313                 :          0 :         return pos - buf;
    2314                 :            : }
    2315                 :            : 
    2316                 :            : 
    2317                 :        325 : static int wpa_supplicant_ctrl_iface_select_network(
    2318                 :            :         struct wpa_supplicant *wpa_s, char *cmd)
    2319                 :            : {
    2320                 :            :         int id;
    2321                 :            :         struct wpa_ssid *ssid;
    2322                 :            : 
    2323                 :            :         /* cmd: "<network id>" or "any" */
    2324         [ -  + ]:        325 :         if (os_strcmp(cmd, "any") == 0) {
    2325                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any");
    2326                 :          0 :                 ssid = NULL;
    2327                 :            :         } else {
    2328                 :        325 :                 id = atoi(cmd);
    2329                 :        325 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id);
    2330                 :            : 
    2331                 :        325 :                 ssid = wpa_config_get_network(wpa_s->conf, id);
    2332         [ -  + ]:        325 :                 if (ssid == NULL) {
    2333                 :          0 :                         wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
    2334                 :            :                                    "network id=%d", id);
    2335                 :          0 :                         return -1;
    2336                 :            :                 }
    2337         [ -  + ]:        325 :                 if (ssid->disabled == 2) {
    2338                 :          0 :                         wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
    2339                 :            :                                    "SELECT_NETWORK with persistent P2P group");
    2340                 :          0 :                         return -1;
    2341                 :            :                 }
    2342                 :            :         }
    2343                 :            : 
    2344                 :        325 :         wpa_supplicant_select_network(wpa_s, ssid);
    2345                 :            : 
    2346                 :        325 :         return 0;
    2347                 :            : }
    2348                 :            : 
    2349                 :            : 
    2350                 :          3 : static int wpa_supplicant_ctrl_iface_enable_network(
    2351                 :            :         struct wpa_supplicant *wpa_s, char *cmd)
    2352                 :            : {
    2353                 :            :         int id;
    2354                 :            :         struct wpa_ssid *ssid;
    2355                 :            : 
    2356                 :            :         /* cmd: "<network id>" or "all" */
    2357         [ -  + ]:          3 :         if (os_strcmp(cmd, "all") == 0) {
    2358                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all");
    2359                 :          0 :                 ssid = NULL;
    2360                 :            :         } else {
    2361                 :          3 :                 id = atoi(cmd);
    2362                 :          3 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id);
    2363                 :            : 
    2364                 :          3 :                 ssid = wpa_config_get_network(wpa_s->conf, id);
    2365         [ -  + ]:          3 :                 if (ssid == NULL) {
    2366                 :          0 :                         wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
    2367                 :            :                                    "network id=%d", id);
    2368                 :          0 :                         return -1;
    2369                 :            :                 }
    2370         [ -  + ]:          3 :                 if (ssid->disabled == 2) {
    2371                 :          0 :                         wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
    2372                 :            :                                    "ENABLE_NETWORK with persistent P2P group");
    2373                 :          0 :                         return -1;
    2374                 :            :                 }
    2375                 :            : 
    2376         [ +  - ]:          3 :                 if (os_strstr(cmd, " no-connect")) {
    2377                 :          3 :                         ssid->disabled = 0;
    2378                 :          3 :                         return 0;
    2379                 :            :                 }
    2380                 :            :         }
    2381                 :          0 :         wpa_supplicant_enable_network(wpa_s, ssid);
    2382                 :            : 
    2383                 :          3 :         return 0;
    2384                 :            : }
    2385                 :            : 
    2386                 :            : 
    2387                 :          0 : static int wpa_supplicant_ctrl_iface_disable_network(
    2388                 :            :         struct wpa_supplicant *wpa_s, char *cmd)
    2389                 :            : {
    2390                 :            :         int id;
    2391                 :            :         struct wpa_ssid *ssid;
    2392                 :            : 
    2393                 :            :         /* cmd: "<network id>" or "all" */
    2394         [ #  # ]:          0 :         if (os_strcmp(cmd, "all") == 0) {
    2395                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all");
    2396                 :          0 :                 ssid = NULL;
    2397                 :            :         } else {
    2398                 :          0 :                 id = atoi(cmd);
    2399                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id);
    2400                 :            : 
    2401                 :          0 :                 ssid = wpa_config_get_network(wpa_s->conf, id);
    2402         [ #  # ]:          0 :                 if (ssid == NULL) {
    2403                 :          0 :                         wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
    2404                 :            :                                    "network id=%d", id);
    2405                 :          0 :                         return -1;
    2406                 :            :                 }
    2407         [ #  # ]:          0 :                 if (ssid->disabled == 2) {
    2408                 :          0 :                         wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
    2409                 :            :                                    "DISABLE_NETWORK with persistent P2P "
    2410                 :            :                                    "group");
    2411                 :          0 :                         return -1;
    2412                 :            :                 }
    2413                 :            :         }
    2414                 :          0 :         wpa_supplicant_disable_network(wpa_s, ssid);
    2415                 :            : 
    2416                 :          0 :         return 0;
    2417                 :            : }
    2418                 :            : 
    2419                 :            : 
    2420                 :        327 : static int wpa_supplicant_ctrl_iface_add_network(
    2421                 :            :         struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
    2422                 :            : {
    2423                 :            :         struct wpa_ssid *ssid;
    2424                 :            :         int ret;
    2425                 :            : 
    2426                 :        327 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK");
    2427                 :            : 
    2428                 :        327 :         ssid = wpa_config_add_network(wpa_s->conf);
    2429         [ -  + ]:        327 :         if (ssid == NULL)
    2430                 :          0 :                 return -1;
    2431                 :            : 
    2432                 :        327 :         wpas_notify_network_added(wpa_s, ssid);
    2433                 :            : 
    2434                 :        327 :         ssid->disabled = 1;
    2435                 :        327 :         wpa_config_set_network_defaults(ssid);
    2436                 :            : 
    2437                 :        327 :         ret = os_snprintf(buf, buflen, "%d\n", ssid->id);
    2438 [ +  - ][ -  + ]:        327 :         if (ret < 0 || (size_t) ret >= buflen)
    2439                 :          0 :                 return -1;
    2440                 :        327 :         return ret;
    2441                 :            : }
    2442                 :            : 
    2443                 :            : 
    2444                 :       1353 : static int wpa_supplicant_ctrl_iface_remove_network(
    2445                 :            :         struct wpa_supplicant *wpa_s, char *cmd)
    2446                 :            : {
    2447                 :            :         int id;
    2448                 :            :         struct wpa_ssid *ssid;
    2449                 :            :         int was_disabled;
    2450                 :            : 
    2451                 :            :         /* cmd: "<network id>" or "all" */
    2452         [ +  + ]:       1353 :         if (os_strcmp(cmd, "all") == 0) {
    2453                 :       1242 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all");
    2454         [ -  + ]:       1242 :                 if (wpa_s->sched_scanning)
    2455                 :          0 :                         wpa_supplicant_cancel_sched_scan(wpa_s);
    2456                 :            : 
    2457                 :       1242 :                 eapol_sm_invalidate_cached_session(wpa_s->eapol);
    2458         [ +  + ]:       1242 :                 if (wpa_s->current_ssid) {
    2459                 :            : #ifdef CONFIG_SME
    2460                 :         58 :                         wpa_s->sme.prev_bssid_set = 0;
    2461                 :            : #endif /* CONFIG_SME */
    2462                 :         58 :                         wpa_sm_set_config(wpa_s->wpa, NULL);
    2463                 :         58 :                         eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
    2464                 :         58 :                         wpa_supplicant_deauthenticate(
    2465                 :            :                                 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
    2466                 :            :                 }
    2467                 :       1242 :                 ssid = wpa_s->conf->ssid;
    2468         [ +  + ]:       1589 :                 while (ssid) {
    2469                 :        347 :                         struct wpa_ssid *remove_ssid = ssid;
    2470                 :        347 :                         id = ssid->id;
    2471                 :        347 :                         ssid = ssid->next;
    2472                 :        347 :                         wpas_notify_network_removed(wpa_s, remove_ssid);
    2473                 :        347 :                         wpa_config_remove_network(wpa_s->conf, id);
    2474                 :            :                 }
    2475                 :       1242 :                 return 0;
    2476                 :            :         }
    2477                 :            : 
    2478                 :        111 :         id = atoi(cmd);
    2479                 :        111 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id);
    2480                 :            : 
    2481                 :        111 :         ssid = wpa_config_get_network(wpa_s->conf, id);
    2482         [ +  - ]:        111 :         if (ssid)
    2483                 :        111 :                 wpas_notify_network_removed(wpa_s, ssid);
    2484         [ -  + ]:        111 :         if (ssid == NULL) {
    2485                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
    2486                 :            :                            "id=%d", id);
    2487                 :          0 :                 return -1;
    2488                 :            :         }
    2489                 :            : 
    2490 [ +  + ][ +  - ]:        111 :         if (ssid == wpa_s->current_ssid || wpa_s->current_ssid == NULL) {
    2491                 :            : #ifdef CONFIG_SME
    2492                 :        111 :                 wpa_s->sme.prev_bssid_set = 0;
    2493                 :            : #endif /* CONFIG_SME */
    2494                 :            :                 /*
    2495                 :            :                  * Invalidate the EAP session cache if the current or
    2496                 :            :                  * previously used network is removed.
    2497                 :            :                  */
    2498                 :        111 :                 eapol_sm_invalidate_cached_session(wpa_s->eapol);
    2499                 :            :         }
    2500                 :            : 
    2501         [ +  + ]:        111 :         if (ssid == wpa_s->current_ssid) {
    2502                 :         91 :                 wpa_sm_set_config(wpa_s->wpa, NULL);
    2503                 :         91 :                 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
    2504                 :            : 
    2505                 :         91 :                 wpa_supplicant_deauthenticate(wpa_s,
    2506                 :            :                                               WLAN_REASON_DEAUTH_LEAVING);
    2507                 :            :         }
    2508                 :            : 
    2509                 :        111 :         was_disabled = ssid->disabled;
    2510                 :            : 
    2511         [ -  + ]:        111 :         if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
    2512                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Not able to remove the "
    2513                 :            :                            "network id=%d", id);
    2514                 :          0 :                 return -1;
    2515                 :            :         }
    2516                 :            : 
    2517 [ +  + ][ -  + ]:        111 :         if (!was_disabled && wpa_s->sched_scanning) {
    2518                 :          0 :                 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to remove "
    2519                 :            :                            "network from filters");
    2520                 :          0 :                 wpa_supplicant_cancel_sched_scan(wpa_s);
    2521                 :          0 :                 wpa_supplicant_req_scan(wpa_s, 0, 0);
    2522                 :            :         }
    2523                 :            : 
    2524                 :       1353 :         return 0;
    2525                 :            : }
    2526                 :            : 
    2527                 :            : 
    2528                 :       1669 : static int wpa_supplicant_ctrl_iface_set_network(
    2529                 :            :         struct wpa_supplicant *wpa_s, char *cmd)
    2530                 :            : {
    2531                 :            :         int id;
    2532                 :            :         struct wpa_ssid *ssid;
    2533                 :            :         char *name, *value;
    2534                 :            : 
    2535                 :            :         /* cmd: "<network id> <variable name> <value>" */
    2536                 :       1669 :         name = os_strchr(cmd, ' ');
    2537         [ -  + ]:       1669 :         if (name == NULL)
    2538                 :          0 :                 return -1;
    2539                 :       1669 :         *name++ = '\0';
    2540                 :            : 
    2541                 :       1669 :         value = os_strchr(name, ' ');
    2542         [ -  + ]:       1669 :         if (value == NULL)
    2543                 :          0 :                 return -1;
    2544                 :       1669 :         *value++ = '\0';
    2545                 :            : 
    2546                 :       1669 :         id = atoi(cmd);
    2547                 :       1669 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
    2548                 :            :                    id, name);
    2549                 :       1669 :         wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
    2550                 :            :                               (u8 *) value, os_strlen(value));
    2551                 :            : 
    2552                 :       1669 :         ssid = wpa_config_get_network(wpa_s->conf, id);
    2553         [ -  + ]:       1669 :         if (ssid == NULL) {
    2554                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
    2555                 :            :                            "id=%d", id);
    2556                 :          0 :                 return -1;
    2557                 :            :         }
    2558                 :            : 
    2559         [ +  + ]:       1669 :         if (wpa_config_set(ssid, name, value, 0) < 0) {
    2560                 :         28 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
    2561                 :            :                            "variable '%s'", name);
    2562                 :         28 :                 return -1;
    2563                 :            :         }
    2564                 :            : 
    2565 [ +  + ][ +  + ]:       1641 :         if (os_strcmp(name, "bssid") != 0 &&
    2566                 :       1640 :             os_strcmp(name, "priority") != 0)
    2567                 :       1639 :                 wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
    2568                 :            : 
    2569 [ +  - ][ +  + ]:       1641 :         if (wpa_s->current_ssid == ssid || wpa_s->current_ssid == NULL) {
    2570                 :            :                 /*
    2571                 :            :                  * Invalidate the EAP session cache if anything in the current
    2572                 :            :                  * or previously used configuration changes.
    2573                 :            :                  */
    2574                 :       1638 :                 eapol_sm_invalidate_cached_session(wpa_s->eapol);
    2575                 :            :         }
    2576                 :            : 
    2577 [ +  + ][ +  + ]:       1641 :         if ((os_strcmp(name, "psk") == 0 &&
    2578 [ +  + ][ +  + ]:       1641 :              value[0] == '"' && ssid->ssid_len) ||
    2579         [ +  + ]:        328 :             (os_strcmp(name, "ssid") == 0 && ssid->passphrase))
    2580                 :         92 :                 wpa_config_update_psk(ssid);
    2581         [ +  + ]:       1549 :         else if (os_strcmp(name, "priority") == 0)
    2582                 :          1 :                 wpa_config_update_prio_list(wpa_s->conf);
    2583                 :            : 
    2584                 :       1669 :         return 0;
    2585                 :            : }
    2586                 :            : 
    2587                 :            : 
    2588                 :         34 : static int wpa_supplicant_ctrl_iface_get_network(
    2589                 :            :         struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
    2590                 :            : {
    2591                 :            :         int id;
    2592                 :            :         size_t res;
    2593                 :            :         struct wpa_ssid *ssid;
    2594                 :            :         char *name, *value;
    2595                 :            : 
    2596                 :            :         /* cmd: "<network id> <variable name>" */
    2597                 :         34 :         name = os_strchr(cmd, ' ');
    2598 [ +  - ][ -  + ]:         34 :         if (name == NULL || buflen == 0)
    2599                 :          0 :                 return -1;
    2600                 :         34 :         *name++ = '\0';
    2601                 :            : 
    2602                 :         34 :         id = atoi(cmd);
    2603                 :         34 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
    2604                 :            :                    id, name);
    2605                 :            : 
    2606                 :         34 :         ssid = wpa_config_get_network(wpa_s->conf, id);
    2607         [ -  + ]:         34 :         if (ssid == NULL) {
    2608                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
    2609                 :            :                            "id=%d", id);
    2610                 :          0 :                 return -1;
    2611                 :            :         }
    2612                 :            : 
    2613                 :         34 :         value = wpa_config_get_no_key(ssid, name);
    2614         [ +  + ]:         34 :         if (value == NULL) {
    2615                 :          5 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network "
    2616                 :            :                            "variable '%s'", name);
    2617                 :          5 :                 return -1;
    2618                 :            :         }
    2619                 :            : 
    2620                 :         29 :         res = os_strlcpy(buf, value, buflen);
    2621         [ -  + ]:         29 :         if (res >= buflen) {
    2622                 :          0 :                 os_free(value);
    2623                 :          0 :                 return -1;
    2624                 :            :         }
    2625                 :            : 
    2626                 :         29 :         os_free(value);
    2627                 :            : 
    2628                 :         34 :         return res;
    2629                 :            : }
    2630                 :            : 
    2631                 :            : 
    2632                 :          0 : static int wpa_supplicant_ctrl_iface_list_creds(struct wpa_supplicant *wpa_s,
    2633                 :            :                                                 char *buf, size_t buflen)
    2634                 :            : {
    2635                 :            :         char *pos, *end;
    2636                 :            :         struct wpa_cred *cred;
    2637                 :            :         int ret;
    2638                 :            : 
    2639                 :          0 :         pos = buf;
    2640                 :          0 :         end = buf + buflen;
    2641                 :          0 :         ret = os_snprintf(pos, end - pos,
    2642                 :            :                           "cred id / realm / username / domain / imsi\n");
    2643 [ #  # ][ #  # ]:          0 :         if (ret < 0 || ret >= end - pos)
    2644                 :          0 :                 return pos - buf;
    2645                 :          0 :         pos += ret;
    2646                 :            : 
    2647                 :          0 :         cred = wpa_s->conf->cred;
    2648         [ #  # ]:          0 :         while (cred) {
    2649 [ #  # ][ #  # ]:          0 :                 ret = os_snprintf(pos, end - pos, "%d\t%s\t%s\t%s\t%s\n",
         [ #  # ][ #  # ]
    2650                 :          0 :                                   cred->id, cred->realm ? cred->realm : "",
    2651                 :          0 :                                   cred->username ? cred->username : "",
    2652                 :          0 :                                   cred->domain ? cred->domain[0] : "",
    2653                 :          0 :                                   cred->imsi ? cred->imsi : "");
    2654 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2655                 :          0 :                         return pos - buf;
    2656                 :          0 :                 pos += ret;
    2657                 :            : 
    2658                 :          0 :                 cred = cred->next;
    2659                 :            :         }
    2660                 :            : 
    2661                 :          0 :         return pos - buf;
    2662                 :            : }
    2663                 :            : 
    2664                 :            : 
    2665                 :         93 : static int wpa_supplicant_ctrl_iface_add_cred(struct wpa_supplicant *wpa_s,
    2666                 :            :                                               char *buf, size_t buflen)
    2667                 :            : {
    2668                 :            :         struct wpa_cred *cred;
    2669                 :            :         int ret;
    2670                 :            : 
    2671                 :         93 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_CRED");
    2672                 :            : 
    2673                 :         93 :         cred = wpa_config_add_cred(wpa_s->conf);
    2674         [ -  + ]:         93 :         if (cred == NULL)
    2675                 :          0 :                 return -1;
    2676                 :            : 
    2677                 :         93 :         ret = os_snprintf(buf, buflen, "%d\n", cred->id);
    2678 [ +  - ][ -  + ]:         93 :         if (ret < 0 || (size_t) ret >= buflen)
    2679                 :          0 :                 return -1;
    2680                 :         93 :         return ret;
    2681                 :            : }
    2682                 :            : 
    2683                 :            : 
    2684                 :         94 : static int wpas_ctrl_remove_cred(struct wpa_supplicant *wpa_s,
    2685                 :            :                                  struct wpa_cred *cred)
    2686                 :            : {
    2687                 :            :         struct wpa_ssid *ssid;
    2688                 :            :         char str[20];
    2689                 :            : 
    2690 [ +  + ][ -  + ]:         94 :         if (cred == NULL || wpa_config_remove_cred(wpa_s->conf, cred->id) < 0) {
    2691                 :          1 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find cred");
    2692                 :          1 :                 return -1;
    2693                 :            :         }
    2694                 :            : 
    2695                 :            :         /* Remove any network entry created based on the removed credential */
    2696                 :         93 :         ssid = wpa_s->conf->ssid;
    2697         [ +  + ]:        112 :         while (ssid) {
    2698         [ +  - ]:         19 :                 if (ssid->parent_cred == cred) {
    2699                 :         19 :                         wpa_printf(MSG_DEBUG, "Remove network id %d since it "
    2700                 :            :                                    "used the removed credential", ssid->id);
    2701                 :         19 :                         os_snprintf(str, sizeof(str), "%d", ssid->id);
    2702                 :         19 :                         ssid = ssid->next;
    2703                 :         19 :                         wpa_supplicant_ctrl_iface_remove_network(wpa_s, str);
    2704                 :            :                 } else
    2705                 :          0 :                         ssid = ssid->next;
    2706                 :            :         }
    2707                 :            : 
    2708                 :         94 :         return 0;
    2709                 :            : }
    2710                 :            : 
    2711                 :            : 
    2712                 :       1221 : static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant *wpa_s,
    2713                 :            :                                                  char *cmd)
    2714                 :            : {
    2715                 :            :         int id;
    2716                 :            :         struct wpa_cred *cred, *prev;
    2717                 :            : 
    2718                 :            :         /* cmd: "<cred id>", "all", "sp_fqdn=<FQDN>", or
    2719                 :            :          * "provisioning_sp=<FQDN> */
    2720         [ +  + ]:       1221 :         if (os_strcmp(cmd, "all") == 0) {
    2721                 :       1183 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED all");
    2722                 :       1183 :                 cred = wpa_s->conf->cred;
    2723         [ +  + ]:       1239 :                 while (cred) {
    2724                 :         56 :                         prev = cred;
    2725                 :         56 :                         cred = cred->next;
    2726                 :         56 :                         wpas_ctrl_remove_cred(wpa_s, prev);
    2727                 :            :                 }
    2728                 :       1183 :                 return 0;
    2729                 :            :         }
    2730                 :            : 
    2731         [ -  + ]:         38 :         if (os_strncmp(cmd, "sp_fqdn=", 8) == 0) {
    2732                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED SP FQDN '%s'",
    2733                 :            :                            cmd + 8);
    2734                 :          0 :                 cred = wpa_s->conf->cred;
    2735         [ #  # ]:          0 :                 while (cred) {
    2736                 :          0 :                         prev = cred;
    2737                 :          0 :                         cred = cred->next;
    2738         [ #  # ]:          0 :                         if (prev->domain) {
    2739                 :            :                                 size_t i;
    2740         [ #  # ]:          0 :                                 for (i = 0; i < prev->num_domain; i++) {
    2741         [ #  # ]:          0 :                                         if (os_strcmp(prev->domain[i], cmd + 8)
    2742                 :            :                                             != 0)
    2743                 :          0 :                                                 continue;
    2744                 :          0 :                                         wpas_ctrl_remove_cred(wpa_s, prev);
    2745                 :          0 :                                         break;
    2746                 :            :                                 }
    2747                 :            :                         }
    2748                 :            :                 }
    2749                 :          0 :                 return 0;
    2750                 :            :         }
    2751                 :            : 
    2752         [ -  + ]:         38 :         if (os_strncmp(cmd, "provisioning_sp=", 16) == 0) {
    2753                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED provisioning SP FQDN '%s'",
    2754                 :            :                            cmd + 16);
    2755                 :          0 :                 cred = wpa_s->conf->cred;
    2756         [ #  # ]:          0 :                 while (cred) {
    2757                 :          0 :                         prev = cred;
    2758                 :          0 :                         cred = cred->next;
    2759 [ #  # ][ #  # ]:          0 :                         if (prev->provisioning_sp &&
    2760                 :          0 :                             os_strcmp(prev->provisioning_sp, cmd + 16) == 0)
    2761                 :          0 :                                 wpas_ctrl_remove_cred(wpa_s, prev);
    2762                 :            :                 }
    2763                 :          0 :                 return 0;
    2764                 :            :         }
    2765                 :            : 
    2766                 :         38 :         id = atoi(cmd);
    2767                 :         38 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED id=%d", id);
    2768                 :            : 
    2769                 :         38 :         cred = wpa_config_get_cred(wpa_s->conf, id);
    2770                 :       1221 :         return wpas_ctrl_remove_cred(wpa_s, cred);
    2771                 :            : }
    2772                 :            : 
    2773                 :            : 
    2774                 :        403 : static int wpa_supplicant_ctrl_iface_set_cred(struct wpa_supplicant *wpa_s,
    2775                 :            :                                               char *cmd)
    2776                 :            : {
    2777                 :            :         int id;
    2778                 :            :         struct wpa_cred *cred;
    2779                 :            :         char *name, *value;
    2780                 :            : 
    2781                 :            :         /* cmd: "<cred id> <variable name> <value>" */
    2782                 :        403 :         name = os_strchr(cmd, ' ');
    2783         [ -  + ]:        403 :         if (name == NULL)
    2784                 :          0 :                 return -1;
    2785                 :        403 :         *name++ = '\0';
    2786                 :            : 
    2787                 :        403 :         value = os_strchr(name, ' ');
    2788         [ -  + ]:        403 :         if (value == NULL)
    2789                 :          0 :                 return -1;
    2790                 :        403 :         *value++ = '\0';
    2791                 :            : 
    2792                 :        403 :         id = atoi(cmd);
    2793                 :        403 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_CRED id=%d name='%s'",
    2794                 :            :                    id, name);
    2795                 :        403 :         wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
    2796                 :            :                               (u8 *) value, os_strlen(value));
    2797                 :            : 
    2798                 :        403 :         cred = wpa_config_get_cred(wpa_s->conf, id);
    2799         [ -  + ]:        403 :         if (cred == NULL) {
    2800                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find cred id=%d",
    2801                 :            :                            id);
    2802                 :          0 :                 return -1;
    2803                 :            :         }
    2804                 :            : 
    2805         [ +  + ]:        403 :         if (wpa_config_set_cred(cred, name, value, 0) < 0) {
    2806                 :         13 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set cred "
    2807                 :            :                            "variable '%s'", name);
    2808                 :         13 :                 return -1;
    2809                 :            :         }
    2810                 :            : 
    2811                 :        403 :         return 0;
    2812                 :            : }
    2813                 :            : 
    2814                 :            : 
    2815                 :            : #ifndef CONFIG_NO_CONFIG_WRITE
    2816                 :          0 : static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s)
    2817                 :            : {
    2818                 :            :         int ret;
    2819                 :            : 
    2820         [ #  # ]:          0 :         if (!wpa_s->conf->update_config) {
    2821                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
    2822                 :            :                            "to update configuration (update_config=0)");
    2823                 :          0 :                 return -1;
    2824                 :            :         }
    2825                 :            : 
    2826                 :          0 :         ret = wpa_config_write(wpa_s->confname, wpa_s->conf);
    2827         [ #  # ]:          0 :         if (ret) {
    2828                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to "
    2829                 :            :                            "update configuration");
    2830                 :            :         } else {
    2831                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration"
    2832                 :            :                            " updated");
    2833                 :            :         }
    2834                 :            : 
    2835                 :          0 :         return ret;
    2836                 :            : }
    2837                 :            : #endif /* CONFIG_NO_CONFIG_WRITE */
    2838                 :            : 
    2839                 :            : 
    2840                 :            : struct cipher_info {
    2841                 :            :         unsigned int capa;
    2842                 :            :         const char *name;
    2843                 :            :         int group_only;
    2844                 :            : };
    2845                 :            : 
    2846                 :            : static const struct cipher_info ciphers[] = {
    2847                 :            :         { WPA_DRIVER_CAPA_ENC_CCMP_256, "CCMP-256", 0 },
    2848                 :            :         { WPA_DRIVER_CAPA_ENC_GCMP_256, "GCMP-256", 0 },
    2849                 :            :         { WPA_DRIVER_CAPA_ENC_CCMP, "CCMP", 0 },
    2850                 :            :         { WPA_DRIVER_CAPA_ENC_GCMP, "GCMP", 0 },
    2851                 :            :         { WPA_DRIVER_CAPA_ENC_TKIP, "TKIP", 0 },
    2852                 :            :         { WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE, "NONE", 0 },
    2853                 :            :         { WPA_DRIVER_CAPA_ENC_WEP104, "WEP104", 1 },
    2854                 :            :         { WPA_DRIVER_CAPA_ENC_WEP40, "WEP40", 1 }
    2855                 :            : };
    2856                 :            : 
    2857                 :            : 
    2858                 :          5 : static int ctrl_iface_get_capability_pairwise(int res, char *strict,
    2859                 :            :                                               struct wpa_driver_capa *capa,
    2860                 :            :                                               char *buf, size_t buflen)
    2861                 :            : {
    2862                 :            :         int ret;
    2863                 :            :         char *pos, *end;
    2864                 :            :         size_t len;
    2865                 :            :         unsigned int i;
    2866                 :            : 
    2867                 :          5 :         pos = buf;
    2868                 :          5 :         end = pos + buflen;
    2869                 :            : 
    2870         [ -  + ]:          5 :         if (res < 0) {
    2871         [ #  # ]:          0 :                 if (strict)
    2872                 :          0 :                         return 0;
    2873                 :          0 :                 len = os_strlcpy(buf, "CCMP TKIP NONE", buflen);
    2874         [ #  # ]:          0 :                 if (len >= buflen)
    2875                 :          0 :                         return -1;
    2876                 :          0 :                 return len;
    2877                 :            :         }
    2878                 :            : 
    2879         [ +  + ]:         45 :         for (i = 0; i < ARRAY_SIZE(ciphers); i++) {
    2880 [ +  + ][ +  + ]:         40 :                 if (!ciphers[i].group_only && capa->enc & ciphers[i].capa) {
    2881         [ +  + ]:         10 :                         ret = os_snprintf(pos, end - pos, "%s%s",
    2882                 :            :                                           pos == buf ? "" : " ",
    2883                 :            :                                           ciphers[i].name);
    2884 [ +  - ][ -  + ]:         10 :                         if (ret < 0 || ret >= end - pos)
    2885                 :          0 :                                 return pos - buf;
    2886                 :         10 :                         pos += ret;
    2887                 :            :                 }
    2888                 :            :         }
    2889                 :            : 
    2890                 :          5 :         return pos - buf;
    2891                 :            : }
    2892                 :            : 
    2893                 :            : 
    2894                 :          0 : static int ctrl_iface_get_capability_group(int res, char *strict,
    2895                 :            :                                            struct wpa_driver_capa *capa,
    2896                 :            :                                            char *buf, size_t buflen)
    2897                 :            : {
    2898                 :            :         int ret;
    2899                 :            :         char *pos, *end;
    2900                 :            :         size_t len;
    2901                 :            :         unsigned int i;
    2902                 :            : 
    2903                 :          0 :         pos = buf;
    2904                 :          0 :         end = pos + buflen;
    2905                 :            : 
    2906         [ #  # ]:          0 :         if (res < 0) {
    2907         [ #  # ]:          0 :                 if (strict)
    2908                 :          0 :                         return 0;
    2909                 :          0 :                 len = os_strlcpy(buf, "CCMP TKIP WEP104 WEP40", buflen);
    2910         [ #  # ]:          0 :                 if (len >= buflen)
    2911                 :          0 :                         return -1;
    2912                 :          0 :                 return len;
    2913                 :            :         }
    2914                 :            : 
    2915         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(ciphers); i++) {
    2916         [ #  # ]:          0 :                 if (capa->enc & ciphers[i].capa) {
    2917         [ #  # ]:          0 :                         ret = os_snprintf(pos, end - pos, "%s%s",
    2918                 :            :                                           pos == buf ? "" : " ",
    2919                 :            :                                           ciphers[i].name);
    2920 [ #  # ][ #  # ]:          0 :                         if (ret < 0 || ret >= end - pos)
    2921                 :          0 :                                 return pos - buf;
    2922                 :          0 :                         pos += ret;
    2923                 :            :                 }
    2924                 :            :         }
    2925                 :            : 
    2926                 :          0 :         return pos - buf;
    2927                 :            : }
    2928                 :            : 
    2929                 :            : 
    2930                 :          0 : static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
    2931                 :            :                                               struct wpa_driver_capa *capa,
    2932                 :            :                                               char *buf, size_t buflen)
    2933                 :            : {
    2934                 :            :         int ret;
    2935                 :            :         char *pos, *end;
    2936                 :            :         size_t len;
    2937                 :            : 
    2938                 :          0 :         pos = buf;
    2939                 :          0 :         end = pos + buflen;
    2940                 :            : 
    2941         [ #  # ]:          0 :         if (res < 0) {
    2942         [ #  # ]:          0 :                 if (strict)
    2943                 :          0 :                         return 0;
    2944                 :          0 :                 len = os_strlcpy(buf, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE "
    2945                 :            :                                  "NONE", buflen);
    2946         [ #  # ]:          0 :                 if (len >= buflen)
    2947                 :          0 :                         return -1;
    2948                 :          0 :                 return len;
    2949                 :            :         }
    2950                 :            : 
    2951                 :          0 :         ret = os_snprintf(pos, end - pos, "NONE IEEE8021X");
    2952 [ #  # ][ #  # ]:          0 :         if (ret < 0 || ret >= end - pos)
    2953                 :          0 :                 return pos - buf;
    2954                 :          0 :         pos += ret;
    2955                 :            : 
    2956         [ #  # ]:          0 :         if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
    2957                 :            :                               WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
    2958                 :          0 :                 ret = os_snprintf(pos, end - pos, " WPA-EAP");
    2959 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2960                 :          0 :                         return pos - buf;
    2961                 :          0 :                 pos += ret;
    2962                 :            :         }
    2963                 :            : 
    2964         [ #  # ]:          0 :         if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
    2965                 :            :                               WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
    2966                 :          0 :                 ret = os_snprintf(pos, end - pos, " WPA-PSK");
    2967 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2968                 :          0 :                         return pos - buf;
    2969                 :          0 :                 pos += ret;
    2970                 :            :         }
    2971                 :            : 
    2972         [ #  # ]:          0 :         if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
    2973                 :          0 :                 ret = os_snprintf(pos, end - pos, " WPA-NONE");
    2974 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    2975                 :          0 :                         return pos - buf;
    2976                 :          0 :                 pos += ret;
    2977                 :            :         }
    2978                 :            : 
    2979                 :          0 :         return pos - buf;
    2980                 :            : }
    2981                 :            : 
    2982                 :            : 
    2983                 :          0 : static int ctrl_iface_get_capability_proto(int res, char *strict,
    2984                 :            :                                            struct wpa_driver_capa *capa,
    2985                 :            :                                            char *buf, size_t buflen)
    2986                 :            : {
    2987                 :            :         int ret;
    2988                 :            :         char *pos, *end;
    2989                 :            :         size_t len;
    2990                 :            : 
    2991                 :          0 :         pos = buf;
    2992                 :          0 :         end = pos + buflen;
    2993                 :            : 
    2994         [ #  # ]:          0 :         if (res < 0) {
    2995         [ #  # ]:          0 :                 if (strict)
    2996                 :          0 :                         return 0;
    2997                 :          0 :                 len = os_strlcpy(buf, "RSN WPA", buflen);
    2998         [ #  # ]:          0 :                 if (len >= buflen)
    2999                 :          0 :                         return -1;
    3000                 :          0 :                 return len;
    3001                 :            :         }
    3002                 :            : 
    3003         [ #  # ]:          0 :         if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
    3004                 :            :                               WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
    3005         [ #  # ]:          0 :                 ret = os_snprintf(pos, end - pos, "%sRSN",
    3006                 :            :                                   pos == buf ? "" : " ");
    3007 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    3008                 :          0 :                         return pos - buf;
    3009                 :          0 :                 pos += ret;
    3010                 :            :         }
    3011                 :            : 
    3012         [ #  # ]:          0 :         if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
    3013                 :            :                               WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
    3014         [ #  # ]:          0 :                 ret = os_snprintf(pos, end - pos, "%sWPA",
    3015                 :            :                                   pos == buf ? "" : " ");
    3016 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    3017                 :          0 :                         return pos - buf;
    3018                 :          0 :                 pos += ret;
    3019                 :            :         }
    3020                 :            : 
    3021                 :          0 :         return pos - buf;
    3022                 :            : }
    3023                 :            : 
    3024                 :            : 
    3025                 :          0 : static int ctrl_iface_get_capability_auth_alg(int res, char *strict,
    3026                 :            :                                               struct wpa_driver_capa *capa,
    3027                 :            :                                               char *buf, size_t buflen)
    3028                 :            : {
    3029                 :            :         int ret;
    3030                 :            :         char *pos, *end;
    3031                 :            :         size_t len;
    3032                 :            : 
    3033                 :          0 :         pos = buf;
    3034                 :          0 :         end = pos + buflen;
    3035                 :            : 
    3036         [ #  # ]:          0 :         if (res < 0) {
    3037         [ #  # ]:          0 :                 if (strict)
    3038                 :          0 :                         return 0;
    3039                 :          0 :                 len = os_strlcpy(buf, "OPEN SHARED LEAP", buflen);
    3040         [ #  # ]:          0 :                 if (len >= buflen)
    3041                 :          0 :                         return -1;
    3042                 :          0 :                 return len;
    3043                 :            :         }
    3044                 :            : 
    3045         [ #  # ]:          0 :         if (capa->auth & (WPA_DRIVER_AUTH_OPEN)) {
    3046         [ #  # ]:          0 :                 ret = os_snprintf(pos, end - pos, "%sOPEN",
    3047                 :            :                                   pos == buf ? "" : " ");
    3048 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    3049                 :          0 :                         return pos - buf;
    3050                 :          0 :                 pos += ret;
    3051                 :            :         }
    3052                 :            : 
    3053         [ #  # ]:          0 :         if (capa->auth & (WPA_DRIVER_AUTH_SHARED)) {
    3054         [ #  # ]:          0 :                 ret = os_snprintf(pos, end - pos, "%sSHARED",
    3055                 :            :                                   pos == buf ? "" : " ");
    3056 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    3057                 :          0 :                         return pos - buf;
    3058                 :          0 :                 pos += ret;
    3059                 :            :         }
    3060                 :            : 
    3061         [ #  # ]:          0 :         if (capa->auth & (WPA_DRIVER_AUTH_LEAP)) {
    3062         [ #  # ]:          0 :                 ret = os_snprintf(pos, end - pos, "%sLEAP",
    3063                 :            :                                   pos == buf ? "" : " ");
    3064 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    3065                 :          0 :                         return pos - buf;
    3066                 :          0 :                 pos += ret;
    3067                 :            :         }
    3068                 :            : 
    3069                 :          0 :         return pos - buf;
    3070                 :            : }
    3071                 :            : 
    3072                 :            : 
    3073                 :          0 : static int ctrl_iface_get_capability_modes(int res, char *strict,
    3074                 :            :                                            struct wpa_driver_capa *capa,
    3075                 :            :                                            char *buf, size_t buflen)
    3076                 :            : {
    3077                 :            :         int ret;
    3078                 :            :         char *pos, *end;
    3079                 :            :         size_t len;
    3080                 :            : 
    3081                 :          0 :         pos = buf;
    3082                 :          0 :         end = pos + buflen;
    3083                 :            : 
    3084         [ #  # ]:          0 :         if (res < 0) {
    3085         [ #  # ]:          0 :                 if (strict)
    3086                 :          0 :                         return 0;
    3087                 :          0 :                 len = os_strlcpy(buf, "IBSS AP", buflen);
    3088         [ #  # ]:          0 :                 if (len >= buflen)
    3089                 :          0 :                         return -1;
    3090                 :          0 :                 return len;
    3091                 :            :         }
    3092                 :            : 
    3093         [ #  # ]:          0 :         if (capa->flags & WPA_DRIVER_FLAGS_IBSS) {
    3094         [ #  # ]:          0 :                 ret = os_snprintf(pos, end - pos, "%sIBSS",
    3095                 :            :                                   pos == buf ? "" : " ");
    3096 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    3097                 :          0 :                         return pos - buf;
    3098                 :          0 :                 pos += ret;
    3099                 :            :         }
    3100                 :            : 
    3101         [ #  # ]:          0 :         if (capa->flags & WPA_DRIVER_FLAGS_AP) {
    3102         [ #  # ]:          0 :                 ret = os_snprintf(pos, end - pos, "%sAP",
    3103                 :            :                                   pos == buf ? "" : " ");
    3104 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    3105                 :          0 :                         return pos - buf;
    3106                 :          0 :                 pos += ret;
    3107                 :            :         }
    3108                 :            : 
    3109                 :          0 :         return pos - buf;
    3110                 :            : }
    3111                 :            : 
    3112                 :            : 
    3113                 :          0 : static int ctrl_iface_get_capability_channels(struct wpa_supplicant *wpa_s,
    3114                 :            :                                               char *buf, size_t buflen)
    3115                 :            : {
    3116                 :            :         struct hostapd_channel_data *chnl;
    3117                 :            :         int ret, i, j;
    3118                 :            :         char *pos, *end, *hmode;
    3119                 :            : 
    3120                 :          0 :         pos = buf;
    3121                 :          0 :         end = pos + buflen;
    3122                 :            : 
    3123         [ #  # ]:          0 :         for (j = 0; j < wpa_s->hw.num_modes; j++) {
    3124   [ #  #  #  #  :          0 :                 switch (wpa_s->hw.modes[j].mode) {
                      # ]
    3125                 :            :                 case HOSTAPD_MODE_IEEE80211B:
    3126                 :          0 :                         hmode = "B";
    3127                 :          0 :                         break;
    3128                 :            :                 case HOSTAPD_MODE_IEEE80211G:
    3129                 :          0 :                         hmode = "G";
    3130                 :          0 :                         break;
    3131                 :            :                 case HOSTAPD_MODE_IEEE80211A:
    3132                 :          0 :                         hmode = "A";
    3133                 :          0 :                         break;
    3134                 :            :                 case HOSTAPD_MODE_IEEE80211AD:
    3135                 :          0 :                         hmode = "AD";
    3136                 :          0 :                         break;
    3137                 :            :                 default:
    3138                 :          0 :                         continue;
    3139                 :            :                 }
    3140                 :          0 :                 ret = os_snprintf(pos, end - pos, "Mode[%s] Channels:", hmode);
    3141 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    3142                 :          0 :                         return pos - buf;
    3143                 :          0 :                 pos += ret;
    3144                 :          0 :                 chnl = wpa_s->hw.modes[j].channels;
    3145         [ #  # ]:          0 :                 for (i = 0; i < wpa_s->hw.modes[j].num_channels; i++) {
    3146         [ #  # ]:          0 :                         if (chnl[i].flag & HOSTAPD_CHAN_DISABLED)
    3147                 :          0 :                                 continue;
    3148                 :          0 :                         ret = os_snprintf(pos, end - pos, " %d", chnl[i].chan);
    3149 [ #  # ][ #  # ]:          0 :                         if (ret < 0 || ret >= end - pos)
    3150                 :          0 :                                 return pos - buf;
    3151                 :          0 :                         pos += ret;
    3152                 :            :                 }
    3153                 :          0 :                 ret = os_snprintf(pos, end - pos, "\n");
    3154 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    3155                 :          0 :                         return pos - buf;
    3156                 :          0 :                 pos += ret;
    3157                 :            :         }
    3158                 :            : 
    3159                 :          0 :         return pos - buf;
    3160                 :            : }
    3161                 :            : 
    3162                 :            : 
    3163                 :          0 : static int ctrl_iface_get_capability_freq(struct wpa_supplicant *wpa_s,
    3164                 :            :                                           char *buf, size_t buflen)
    3165                 :            : {
    3166                 :            :         struct hostapd_channel_data *chnl;
    3167                 :            :         int ret, i, j;
    3168                 :            :         char *pos, *end, *hmode;
    3169                 :            : 
    3170                 :          0 :         pos = buf;
    3171                 :          0 :         end = pos + buflen;
    3172                 :            : 
    3173         [ #  # ]:          0 :         for (j = 0; j < wpa_s->hw.num_modes; j++) {
    3174   [ #  #  #  #  :          0 :                 switch (wpa_s->hw.modes[j].mode) {
                      # ]
    3175                 :            :                 case HOSTAPD_MODE_IEEE80211B:
    3176                 :          0 :                         hmode = "B";
    3177                 :          0 :                         break;
    3178                 :            :                 case HOSTAPD_MODE_IEEE80211G:
    3179                 :          0 :                         hmode = "G";
    3180                 :          0 :                         break;
    3181                 :            :                 case HOSTAPD_MODE_IEEE80211A:
    3182                 :          0 :                         hmode = "A";
    3183                 :          0 :                         break;
    3184                 :            :                 case HOSTAPD_MODE_IEEE80211AD:
    3185                 :          0 :                         hmode = "AD";
    3186                 :          0 :                         break;
    3187                 :            :                 default:
    3188                 :          0 :                         continue;
    3189                 :            :                 }
    3190                 :          0 :                 ret = os_snprintf(pos, end - pos, "Mode[%s] Channels:\n",
    3191                 :            :                                   hmode);
    3192 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    3193                 :          0 :                         return pos - buf;
    3194                 :          0 :                 pos += ret;
    3195                 :          0 :                 chnl = wpa_s->hw.modes[j].channels;
    3196         [ #  # ]:          0 :                 for (i = 0; i < wpa_s->hw.modes[j].num_channels; i++) {
    3197         [ #  # ]:          0 :                         if (chnl[i].flag & HOSTAPD_CHAN_DISABLED)
    3198                 :          0 :                                 continue;
    3199 [ #  # ][ #  # ]:          0 :                         ret = os_snprintf(pos, end - pos, " %d = %d MHz%s%s\n",
    3200                 :          0 :                                           chnl[i].chan, chnl[i].freq,
    3201                 :          0 :                                           chnl[i].flag & HOSTAPD_CHAN_NO_IBSS ?
    3202                 :            :                                           " (NO_IBSS)" : "",
    3203                 :          0 :                                           chnl[i].flag & HOSTAPD_CHAN_RADAR ?
    3204                 :            :                                           " (DFS)" : "");
    3205                 :            : 
    3206 [ #  # ][ #  # ]:          0 :                         if (ret < 0 || ret >= end - pos)
    3207                 :          0 :                                 return pos - buf;
    3208                 :          0 :                         pos += ret;
    3209                 :            :                 }
    3210                 :          0 :                 ret = os_snprintf(pos, end - pos, "\n");
    3211 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    3212                 :          0 :                         return pos - buf;
    3213                 :          0 :                 pos += ret;
    3214                 :            :         }
    3215                 :            : 
    3216                 :          0 :         return pos - buf;
    3217                 :            : }
    3218                 :            : 
    3219                 :            : 
    3220                 :          5 : static int wpa_supplicant_ctrl_iface_get_capability(
    3221                 :            :         struct wpa_supplicant *wpa_s, const char *_field, char *buf,
    3222                 :            :         size_t buflen)
    3223                 :            : {
    3224                 :            :         struct wpa_driver_capa capa;
    3225                 :            :         int res;
    3226                 :            :         char *strict;
    3227                 :            :         char field[30];
    3228                 :            :         size_t len;
    3229                 :            : 
    3230                 :            :         /* Determine whether or not strict checking was requested */
    3231                 :          5 :         len = os_strlcpy(field, _field, sizeof(field));
    3232         [ -  + ]:          5 :         if (len >= sizeof(field))
    3233                 :          0 :                 return -1;
    3234                 :          5 :         strict = os_strchr(field, ' ');
    3235         [ -  + ]:          5 :         if (strict != NULL) {
    3236                 :          0 :                 *strict++ = '\0';
    3237         [ #  # ]:          0 :                 if (os_strcmp(strict, "strict") != 0)
    3238                 :          0 :                         return -1;
    3239                 :            :         }
    3240                 :            : 
    3241         [ -  + ]:          5 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
    3242                 :            :                 field, strict ? strict : "");
    3243                 :            : 
    3244         [ -  + ]:          5 :         if (os_strcmp(field, "eap") == 0) {
    3245                 :          0 :                 return eap_get_names(buf, buflen);
    3246                 :            :         }
    3247                 :            : 
    3248                 :          5 :         res = wpa_drv_get_capa(wpa_s, &capa);
    3249                 :            : 
    3250         [ +  - ]:          5 :         if (os_strcmp(field, "pairwise") == 0)
    3251                 :          5 :                 return ctrl_iface_get_capability_pairwise(res, strict, &capa,
    3252                 :            :                                                           buf, buflen);
    3253                 :            : 
    3254         [ #  # ]:          0 :         if (os_strcmp(field, "group") == 0)
    3255                 :          0 :                 return ctrl_iface_get_capability_group(res, strict, &capa,
    3256                 :            :                                                        buf, buflen);
    3257                 :            : 
    3258         [ #  # ]:          0 :         if (os_strcmp(field, "key_mgmt") == 0)
    3259                 :          0 :                 return ctrl_iface_get_capability_key_mgmt(res, strict, &capa,
    3260                 :            :                                                           buf, buflen);
    3261                 :            : 
    3262         [ #  # ]:          0 :         if (os_strcmp(field, "proto") == 0)
    3263                 :          0 :                 return ctrl_iface_get_capability_proto(res, strict, &capa,
    3264                 :            :                                                        buf, buflen);
    3265                 :            : 
    3266         [ #  # ]:          0 :         if (os_strcmp(field, "auth_alg") == 0)
    3267                 :          0 :                 return ctrl_iface_get_capability_auth_alg(res, strict, &capa,
    3268                 :            :                                                           buf, buflen);
    3269                 :            : 
    3270         [ #  # ]:          0 :         if (os_strcmp(field, "modes") == 0)
    3271                 :          0 :                 return ctrl_iface_get_capability_modes(res, strict, &capa,
    3272                 :            :                                                        buf, buflen);
    3273                 :            : 
    3274         [ #  # ]:          0 :         if (os_strcmp(field, "channels") == 0)
    3275                 :          0 :                 return ctrl_iface_get_capability_channels(wpa_s, buf, buflen);
    3276                 :            : 
    3277         [ #  # ]:          0 :         if (os_strcmp(field, "freq") == 0)
    3278                 :          0 :                 return ctrl_iface_get_capability_freq(wpa_s, buf, buflen);
    3279                 :            : 
    3280                 :          0 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
    3281                 :            :                    field);
    3282                 :            : 
    3283                 :          5 :         return -1;
    3284                 :            : }
    3285                 :            : 
    3286                 :            : 
    3287                 :            : #ifdef CONFIG_INTERWORKING
    3288                 :         72 : static char * anqp_add_hex(char *pos, char *end, const char *title,
    3289                 :            :                            struct wpabuf *data)
    3290                 :            : {
    3291                 :         72 :         char *start = pos;
    3292                 :            :         size_t i;
    3293                 :            :         int ret;
    3294                 :            :         const u8 *d;
    3295                 :            : 
    3296         [ +  + ]:         72 :         if (data == NULL)
    3297                 :         62 :                 return start;
    3298                 :            : 
    3299                 :         10 :         ret = os_snprintf(pos, end - pos, "%s=", title);
    3300 [ +  - ][ -  + ]:         10 :         if (ret < 0 || ret >= end - pos)
    3301                 :          0 :                 return start;
    3302                 :         10 :         pos += ret;
    3303                 :            : 
    3304                 :         10 :         d = wpabuf_head_u8(data);
    3305         [ +  + ]:        432 :         for (i = 0; i < wpabuf_len(data); i++) {
    3306                 :        422 :                 ret = os_snprintf(pos, end - pos, "%02x", *d++);
    3307 [ +  - ][ -  + ]:        422 :                 if (ret < 0 || ret >= end - pos)
    3308                 :          0 :                         return start;
    3309                 :        422 :                 pos += ret;
    3310                 :            :         }
    3311                 :            : 
    3312                 :         10 :         ret = os_snprintf(pos, end - pos, "\n");
    3313 [ +  - ][ -  + ]:         10 :         if (ret < 0 || ret >= end - pos)
    3314                 :          0 :                 return start;
    3315                 :         10 :         pos += ret;
    3316                 :            : 
    3317                 :         72 :         return pos;
    3318                 :            : }
    3319                 :            : #endif /* CONFIG_INTERWORKING */
    3320                 :            : 
    3321                 :            : 
    3322                 :        176 : static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
    3323                 :            :                           unsigned long mask, char *buf, size_t buflen)
    3324                 :            : {
    3325                 :            :         size_t i;
    3326                 :            :         int ret;
    3327                 :            :         char *pos, *end;
    3328                 :            :         const u8 *ie, *ie2;
    3329                 :            : 
    3330                 :        176 :         pos = buf;
    3331                 :        176 :         end = buf + buflen;
    3332                 :            : 
    3333         [ +  + ]:        176 :         if (mask & WPA_BSS_MASK_ID) {
    3334                 :         35 :                 ret = os_snprintf(pos, end - pos, "id=%u\n", bss->id);
    3335 [ +  - ][ -  + ]:         35 :                 if (ret < 0 || ret >= end - pos)
    3336                 :          0 :                         return 0;
    3337                 :         35 :                 pos += ret;
    3338                 :            :         }
    3339                 :            : 
    3340         [ +  + ]:        176 :         if (mask & WPA_BSS_MASK_BSSID) {
    3341                 :       1050 :                 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
    3342                 :       1050 :                                   MAC2STR(bss->bssid));
    3343 [ +  - ][ -  + ]:        175 :                 if (ret < 0 || ret >= end - pos)
    3344                 :          0 :                         return 0;
    3345                 :        175 :                 pos += ret;
    3346                 :            :         }
    3347                 :            : 
    3348         [ +  + ]:        176 :         if (mask & WPA_BSS_MASK_FREQ) {
    3349                 :         34 :                 ret = os_snprintf(pos, end - pos, "freq=%d\n", bss->freq);
    3350 [ +  - ][ -  + ]:         34 :                 if (ret < 0 || ret >= end - pos)
    3351                 :          0 :                         return 0;
    3352                 :         34 :                 pos += ret;
    3353                 :            :         }
    3354                 :            : 
    3355         [ +  + ]:        176 :         if (mask & WPA_BSS_MASK_BEACON_INT) {
    3356                 :         34 :                 ret = os_snprintf(pos, end - pos, "beacon_int=%d\n",
    3357                 :         34 :                                   bss->beacon_int);
    3358 [ +  - ][ -  + ]:         34 :                 if (ret < 0 || ret >= end - pos)
    3359                 :          0 :                         return 0;
    3360                 :         34 :                 pos += ret;
    3361                 :            :         }
    3362                 :            : 
    3363         [ +  + ]:        176 :         if (mask & WPA_BSS_MASK_CAPABILITIES) {
    3364                 :         34 :                 ret = os_snprintf(pos, end - pos, "capabilities=0x%04x\n",
    3365                 :         34 :                                   bss->caps);
    3366 [ +  - ][ -  + ]:         34 :                 if (ret < 0 || ret >= end - pos)
    3367                 :          0 :                         return 0;
    3368                 :         34 :                 pos += ret;
    3369                 :            :         }
    3370                 :            : 
    3371         [ +  + ]:        176 :         if (mask & WPA_BSS_MASK_QUAL) {
    3372                 :         34 :                 ret = os_snprintf(pos, end - pos, "qual=%d\n", bss->qual);
    3373 [ +  - ][ -  + ]:         34 :                 if (ret < 0 || ret >= end - pos)
    3374                 :          0 :                         return 0;
    3375                 :         34 :                 pos += ret;
    3376                 :            :         }
    3377                 :            : 
    3378         [ +  + ]:        176 :         if (mask & WPA_BSS_MASK_NOISE) {
    3379                 :         34 :                 ret = os_snprintf(pos, end - pos, "noise=%d\n", bss->noise);
    3380 [ +  - ][ -  + ]:         34 :                 if (ret < 0 || ret >= end - pos)
    3381                 :          0 :                         return 0;
    3382                 :         34 :                 pos += ret;
    3383                 :            :         }
    3384                 :            : 
    3385         [ +  + ]:        176 :         if (mask & WPA_BSS_MASK_LEVEL) {
    3386                 :         34 :                 ret = os_snprintf(pos, end - pos, "level=%d\n", bss->level);
    3387 [ +  - ][ -  + ]:         34 :                 if (ret < 0 || ret >= end - pos)
    3388                 :          0 :                         return 0;
    3389                 :         34 :                 pos += ret;
    3390                 :            :         }
    3391                 :            : 
    3392         [ +  + ]:        176 :         if (mask & WPA_BSS_MASK_TSF) {
    3393                 :         34 :                 ret = os_snprintf(pos, end - pos, "tsf=%016llu\n",
    3394                 :         34 :                                   (unsigned long long) bss->tsf);
    3395 [ +  - ][ -  + ]:         34 :                 if (ret < 0 || ret >= end - pos)
    3396                 :          0 :                         return 0;
    3397                 :         34 :                 pos += ret;
    3398                 :            :         }
    3399                 :            : 
    3400         [ +  + ]:        176 :         if (mask & WPA_BSS_MASK_AGE) {
    3401                 :            :                 struct os_reltime now;
    3402                 :            : 
    3403                 :         34 :                 os_get_reltime(&now);
    3404                 :         68 :                 ret = os_snprintf(pos, end - pos, "age=%d\n",
    3405                 :         68 :                                   (int) (now.sec - bss->last_update.sec));
    3406 [ +  - ][ -  + ]:         34 :                 if (ret < 0 || ret >= end - pos)
    3407                 :          0 :                         return 0;
    3408                 :         34 :                 pos += ret;
    3409                 :            :         }
    3410                 :            : 
    3411         [ +  + ]:        176 :         if (mask & WPA_BSS_MASK_IE) {
    3412                 :         34 :                 ret = os_snprintf(pos, end - pos, "ie=");
    3413 [ +  - ][ -  + ]:         34 :                 if (ret < 0 || ret >= end - pos)
    3414                 :          0 :                         return 0;
    3415                 :         34 :                 pos += ret;
    3416                 :            : 
    3417                 :         34 :                 ie = (const u8 *) (bss + 1);
    3418         [ +  + ]:       7884 :                 for (i = 0; i < bss->ie_len; i++) {
    3419                 :       7850 :                         ret = os_snprintf(pos, end - pos, "%02x", *ie++);
    3420 [ +  - ][ -  + ]:       7850 :                         if (ret < 0 || ret >= end - pos)
    3421                 :          0 :                                 return 0;
    3422                 :       7850 :                         pos += ret;
    3423                 :            :                 }
    3424                 :            : 
    3425                 :         34 :                 ret = os_snprintf(pos, end - pos, "\n");
    3426 [ +  - ][ -  + ]:         34 :                 if (ret < 0 || ret >= end - pos)
    3427                 :          0 :                         return 0;
    3428                 :         34 :                 pos += ret;
    3429                 :            :         }
    3430                 :            : 
    3431         [ +  + ]:        176 :         if (mask & WPA_BSS_MASK_FLAGS) {
    3432                 :         34 :                 ret = os_snprintf(pos, end - pos, "flags=");
    3433 [ +  - ][ -  + ]:         34 :                 if (ret < 0 || ret >= end - pos)
    3434                 :          0 :                         return 0;
    3435                 :         34 :                 pos += ret;
    3436                 :            : 
    3437                 :         34 :                 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
    3438         [ +  + ]:         34 :                 if (ie)
    3439                 :          5 :                         pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie,
    3440                 :          5 :                                                     2 + ie[1]);
    3441                 :         34 :                 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
    3442         [ +  + ]:         34 :                 if (ie2)
    3443                 :         23 :                         pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2,
    3444                 :         23 :                                                     2 + ie2[1]);
    3445                 :         34 :                 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
    3446 [ +  + ][ +  + ]:         34 :                 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
                 [ -  + ]
    3447                 :          0 :                         ret = os_snprintf(pos, end - pos, "[WEP]");
    3448 [ #  # ][ #  # ]:          0 :                         if (ret < 0 || ret >= end - pos)
    3449                 :          0 :                                 return 0;
    3450                 :          0 :                         pos += ret;
    3451                 :            :                 }
    3452         [ -  + ]:         34 :                 if (bss->caps & IEEE80211_CAP_IBSS) {
    3453                 :          0 :                         ret = os_snprintf(pos, end - pos, "[IBSS]");
    3454 [ #  # ][ #  # ]:          0 :                         if (ret < 0 || ret >= end - pos)
    3455                 :          0 :                                 return 0;
    3456                 :          0 :                         pos += ret;
    3457                 :            :                 }
    3458         [ +  - ]:         34 :                 if (bss->caps & IEEE80211_CAP_ESS) {
    3459                 :         34 :                         ret = os_snprintf(pos, end - pos, "[ESS]");
    3460 [ +  - ][ -  + ]:         34 :                         if (ret < 0 || ret >= end - pos)
    3461                 :          0 :                                 return 0;
    3462                 :         34 :                         pos += ret;
    3463                 :            :                 }
    3464   [ +  +  -  + ]:         64 :                 if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) ||
    3465                 :         30 :                     wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) {
    3466                 :          4 :                         ret = os_snprintf(pos, end - pos, "[P2P]");
    3467 [ +  - ][ -  + ]:          4 :                         if (ret < 0 || ret >= end - pos)
    3468                 :          0 :                                 return 0;
    3469                 :          4 :                         pos += ret;
    3470                 :            :                 }
    3471                 :            : #ifdef CONFIG_HS20
    3472         [ +  + ]:         34 :                 if (wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE)) {
    3473                 :          6 :                         ret = os_snprintf(pos, end - pos, "[HS20]");
    3474 [ +  - ][ -  + ]:          6 :                         if (ret < 0 || ret >= end - pos)
    3475                 :          0 :                                 return 0;
    3476                 :          6 :                         pos += ret;
    3477                 :            :                 }
    3478                 :            : #endif /* CONFIG_HS20 */
    3479                 :            : 
    3480                 :         34 :                 ret = os_snprintf(pos, end - pos, "\n");
    3481 [ +  - ][ -  + ]:         34 :                 if (ret < 0 || ret >= end - pos)
    3482                 :          0 :                         return 0;
    3483                 :         34 :                 pos += ret;
    3484                 :            :         }
    3485                 :            : 
    3486         [ +  + ]:        176 :         if (mask & WPA_BSS_MASK_SSID) {
    3487                 :         34 :                 ret = os_snprintf(pos, end - pos, "ssid=%s\n",
    3488                 :         34 :                                   wpa_ssid_txt(bss->ssid, bss->ssid_len));
    3489 [ +  - ][ -  + ]:         34 :                 if (ret < 0 || ret >= end - pos)
    3490                 :          0 :                         return 0;
    3491                 :         34 :                 pos += ret;
    3492                 :            :         }
    3493                 :            : 
    3494                 :            : #ifdef CONFIG_WPS
    3495         [ +  + ]:        176 :         if (mask & WPA_BSS_MASK_WPS_SCAN) {
    3496                 :         34 :                 ie = (const u8 *) (bss + 1);
    3497                 :         34 :                 ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end);
    3498 [ +  - ][ -  + ]:         34 :                 if (ret < 0 || ret >= end - pos)
    3499                 :          0 :                         return 0;
    3500                 :         34 :                 pos += ret;
    3501                 :            :         }
    3502                 :            : #endif /* CONFIG_WPS */
    3503                 :            : 
    3504                 :            : #ifdef CONFIG_P2P
    3505         [ +  + ]:        176 :         if (mask & WPA_BSS_MASK_P2P_SCAN) {
    3506                 :         34 :                 ie = (const u8 *) (bss + 1);
    3507                 :         34 :                 ret = wpas_p2p_scan_result_text(ie, bss->ie_len, pos, end);
    3508 [ +  - ][ -  + ]:         34 :                 if (ret < 0 || ret >= end - pos)
    3509                 :          0 :                         return 0;
    3510                 :         34 :                 pos += ret;
    3511                 :            :         }
    3512                 :            : #endif /* CONFIG_P2P */
    3513                 :            : 
    3514                 :            : #ifdef CONFIG_WIFI_DISPLAY
    3515         [ +  + ]:        176 :         if (mask & WPA_BSS_MASK_WIFI_DISPLAY) {
    3516                 :            :                 struct wpabuf *wfd;
    3517                 :         34 :                 ie = (const u8 *) (bss + 1);
    3518                 :         34 :                 wfd = ieee802_11_vendor_ie_concat(ie, bss->ie_len,
    3519                 :            :                                                   WFD_IE_VENDOR_TYPE);
    3520         [ +  + ]:         34 :                 if (wfd) {
    3521                 :          4 :                         ret = os_snprintf(pos, end - pos, "wfd_subelems=");
    3522 [ +  - ][ -  + ]:          4 :                         if (ret < 0 || ret >= end - pos) {
    3523                 :          0 :                                 wpabuf_free(wfd);
    3524                 :          0 :                                 return 0;
    3525                 :            :                         }
    3526                 :          4 :                         pos += ret;
    3527                 :            : 
    3528                 :          8 :                         pos += wpa_snprintf_hex(pos, end - pos,
    3529                 :          4 :                                                 wpabuf_head(wfd),
    3530                 :            :                                                 wpabuf_len(wfd));
    3531                 :          4 :                         wpabuf_free(wfd);
    3532                 :            : 
    3533                 :          4 :                         ret = os_snprintf(pos, end - pos, "\n");
    3534 [ +  - ][ -  + ]:          4 :                         if (ret < 0 || ret >= end - pos)
    3535                 :          0 :                                 return 0;
    3536                 :          4 :                         pos += ret;
    3537                 :            :                 }
    3538                 :            :         }
    3539                 :            : #endif /* CONFIG_WIFI_DISPLAY */
    3540                 :            : 
    3541                 :            : #ifdef CONFIG_INTERWORKING
    3542 [ +  + ][ +  + ]:        176 :         if ((mask & WPA_BSS_MASK_INTERNETW) && bss->anqp) {
    3543                 :          6 :                 struct wpa_bss_anqp *anqp = bss->anqp;
    3544                 :          6 :                 pos = anqp_add_hex(pos, end, "anqp_venue_name",
    3545                 :            :                                    anqp->venue_name);
    3546                 :          6 :                 pos = anqp_add_hex(pos, end, "anqp_network_auth_type",
    3547                 :            :                                    anqp->network_auth_type);
    3548                 :          6 :                 pos = anqp_add_hex(pos, end, "anqp_roaming_consortium",
    3549                 :            :                                    anqp->roaming_consortium);
    3550                 :          6 :                 pos = anqp_add_hex(pos, end, "anqp_ip_addr_type_availability",
    3551                 :            :                                    anqp->ip_addr_type_availability);
    3552                 :          6 :                 pos = anqp_add_hex(pos, end, "anqp_nai_realm",
    3553                 :            :                                    anqp->nai_realm);
    3554                 :          6 :                 pos = anqp_add_hex(pos, end, "anqp_3gpp", anqp->anqp_3gpp);
    3555                 :          6 :                 pos = anqp_add_hex(pos, end, "anqp_domain_name",
    3556                 :            :                                    anqp->domain_name);
    3557                 :            : #ifdef CONFIG_HS20
    3558                 :          6 :                 pos = anqp_add_hex(pos, end, "hs20_operator_friendly_name",
    3559                 :            :                                    anqp->hs20_operator_friendly_name);
    3560                 :          6 :                 pos = anqp_add_hex(pos, end, "hs20_wan_metrics",
    3561                 :            :                                    anqp->hs20_wan_metrics);
    3562                 :          6 :                 pos = anqp_add_hex(pos, end, "hs20_connection_capability",
    3563                 :            :                                    anqp->hs20_connection_capability);
    3564                 :          6 :                 pos = anqp_add_hex(pos, end, "hs20_operating_class",
    3565                 :            :                                    anqp->hs20_operating_class);
    3566                 :          6 :                 pos = anqp_add_hex(pos, end, "hs20_osu_providers_list",
    3567                 :            :                                    anqp->hs20_osu_providers_list);
    3568                 :            : #endif /* CONFIG_HS20 */
    3569                 :            :         }
    3570                 :            : #endif /* CONFIG_INTERWORKING */
    3571                 :            : 
    3572         [ -  + ]:        176 :         if (mask & WPA_BSS_MASK_DELIM) {
    3573                 :          0 :                 ret = os_snprintf(pos, end - pos, "====\n");
    3574 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    3575                 :          0 :                         return 0;
    3576                 :          0 :                 pos += ret;
    3577                 :            :         }
    3578                 :            : 
    3579                 :        176 :         return pos - buf;
    3580                 :            : }
    3581                 :            : 
    3582                 :            : 
    3583                 :        116 : static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
    3584                 :            :                                          const char *cmd, char *buf,
    3585                 :            :                                          size_t buflen)
    3586                 :            : {
    3587                 :            :         u8 bssid[ETH_ALEN];
    3588                 :            :         size_t i;
    3589                 :            :         struct wpa_bss *bss;
    3590                 :        116 :         struct wpa_bss *bsslast = NULL;
    3591                 :            :         struct dl_list *next;
    3592                 :        116 :         int ret = 0;
    3593                 :            :         int len;
    3594                 :            :         char *ctmp;
    3595                 :        116 :         unsigned long mask = WPA_BSS_MASK_ALL;
    3596                 :            : 
    3597         [ +  + ]:        116 :         if (os_strncmp(cmd, "RANGE=", 6) == 0) {
    3598         [ +  + ]:         82 :                 if (os_strncmp(cmd + 6, "ALL", 3) == 0) {
    3599         [ +  + ]:         81 :                         bss = dl_list_first(&wpa_s->bss_id, struct wpa_bss,
    3600                 :            :                                             list_id);
    3601         [ +  + ]:         81 :                         bsslast = dl_list_last(&wpa_s->bss_id, struct wpa_bss,
    3602                 :            :                                                list_id);
    3603                 :            :                 } else { /* N1-N2 */
    3604                 :            :                         unsigned int id1, id2;
    3605                 :            : 
    3606         [ -  + ]:          1 :                         if ((ctmp = os_strchr(cmd + 6, '-')) == NULL) {
    3607                 :          0 :                                 wpa_printf(MSG_INFO, "Wrong BSS range "
    3608                 :            :                                            "format");
    3609                 :          0 :                                 return 0;
    3610                 :            :                         }
    3611                 :            : 
    3612         [ -  + ]:          1 :                         if (*(cmd + 6) == '-')
    3613                 :          0 :                                 id1 = 0;
    3614                 :            :                         else
    3615                 :          1 :                                 id1 = atoi(cmd + 6);
    3616                 :          1 :                         ctmp++;
    3617 [ -  + ][ #  # ]:          1 :                         if (*ctmp >= '0' && *ctmp <= '9')
    3618                 :          0 :                                 id2 = atoi(ctmp);
    3619                 :            :                         else
    3620                 :          1 :                                 id2 = (unsigned int) -1;
    3621                 :          1 :                         bss = wpa_bss_get_id_range(wpa_s, id1, id2);
    3622         [ +  - ]:          1 :                         if (id2 == (unsigned int) -1)
    3623         [ +  - ]:          1 :                                 bsslast = dl_list_last(&wpa_s->bss_id,
    3624                 :            :                                                        struct wpa_bss,
    3625                 :            :                                                        list_id);
    3626                 :            :                         else {
    3627                 :          0 :                                 bsslast = wpa_bss_get_id(wpa_s, id2);
    3628 [ #  # ][ #  # ]:          0 :                                 if (bsslast == NULL && bss && id2 > id1) {
                 [ #  # ]
    3629                 :          0 :                                         struct wpa_bss *tmp = bss;
    3630                 :            :                                         for (;;) {
    3631                 :          0 :                                                 next = tmp->list_id.next;
    3632         [ #  # ]:          0 :                                                 if (next == &wpa_s->bss_id)
    3633                 :          0 :                                                         break;
    3634                 :          0 :                                                 tmp = dl_list_entry(
    3635                 :            :                                                         next, struct wpa_bss,
    3636                 :            :                                                         list_id);
    3637         [ #  # ]:          0 :                                                 if (tmp->id > id2)
    3638                 :          0 :                                                         break;
    3639                 :          0 :                                                 bsslast = tmp;
    3640                 :         82 :                                         }
    3641                 :            :                                 }
    3642                 :            :                         }
    3643                 :            :                 }
    3644         [ -  + ]:         34 :         } else if (os_strncmp(cmd, "FIRST", 5) == 0)
    3645         [ #  # ]:          0 :                 bss = dl_list_first(&wpa_s->bss_id, struct wpa_bss, list_id);
    3646         [ -  + ]:         34 :         else if (os_strncmp(cmd, "LAST", 4) == 0)
    3647         [ #  # ]:          0 :                 bss = dl_list_last(&wpa_s->bss_id, struct wpa_bss, list_id);
    3648         [ +  + ]:         34 :         else if (os_strncmp(cmd, "ID-", 3) == 0) {
    3649                 :          1 :                 i = atoi(cmd + 3);
    3650                 :          1 :                 bss = wpa_bss_get_id(wpa_s, i);
    3651         [ -  + ]:         33 :         } else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
    3652                 :          0 :                 i = atoi(cmd + 5);
    3653                 :          0 :                 bss = wpa_bss_get_id(wpa_s, i);
    3654         [ #  # ]:          0 :                 if (bss) {
    3655                 :          0 :                         next = bss->list_id.next;
    3656         [ #  # ]:          0 :                         if (next == &wpa_s->bss_id)
    3657                 :          0 :                                 bss = NULL;
    3658                 :            :                         else
    3659                 :          0 :                                 bss = dl_list_entry(next, struct wpa_bss,
    3660                 :            :                                                     list_id);
    3661                 :            :                 }
    3662                 :            : #ifdef CONFIG_P2P
    3663         [ +  + ]:         33 :         } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
    3664         [ +  - ]:          3 :                 if (hwaddr_aton(cmd + 13, bssid) == 0)
    3665                 :          3 :                         bss = wpa_bss_get_p2p_dev_addr(wpa_s, bssid);
    3666                 :            :                 else
    3667                 :          0 :                         bss = NULL;
    3668                 :            : #endif /* CONFIG_P2P */
    3669         [ +  - ]:         30 :         } else if (hwaddr_aton(cmd, bssid) == 0)
    3670                 :         30 :                 bss = wpa_bss_get_bssid(wpa_s, bssid);
    3671                 :            :         else {
    3672                 :            :                 struct wpa_bss *tmp;
    3673                 :          0 :                 i = atoi(cmd);
    3674                 :          0 :                 bss = NULL;
    3675         [ #  # ]:          0 :                 dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id)
    3676                 :            :                 {
    3677         [ #  # ]:          0 :                         if (i-- == 0) {
    3678                 :          0 :                                 bss = tmp;
    3679                 :          0 :                                 break;
    3680                 :            :                         }
    3681                 :            :                 }
    3682                 :            :         }
    3683                 :            : 
    3684         [ +  + ]:        116 :         if ((ctmp = os_strstr(cmd, "MASK=")) != NULL) {
    3685                 :         82 :                 mask = strtoul(ctmp + 5, NULL, 0x10);
    3686         [ -  + ]:         82 :                 if (mask == 0)
    3687                 :          0 :                         mask = WPA_BSS_MASK_ALL;
    3688                 :            :         }
    3689                 :            : 
    3690         [ +  + ]:        116 :         if (bss == NULL)
    3691                 :         14 :                 return 0;
    3692                 :            : 
    3693         [ +  + ]:        102 :         if (bsslast == NULL)
    3694                 :         34 :                 bsslast = bss;
    3695                 :            :         do {
    3696                 :        176 :                 len = print_bss_info(wpa_s, bss, mask, buf, buflen);
    3697                 :        176 :                 ret += len;
    3698                 :        176 :                 buf += len;
    3699                 :        176 :                 buflen -= len;
    3700         [ +  + ]:        176 :                 if (bss == bsslast) {
    3701 [ -  + ][ #  # ]:        102 :                         if ((mask & WPA_BSS_MASK_DELIM) && len &&
                 [ #  # ]
    3702         [ #  # ]:          0 :                             (bss == dl_list_last(&wpa_s->bss_id,
    3703                 :            :                                                  struct wpa_bss, list_id)))
    3704                 :          0 :                                 os_snprintf(buf - 5, 5, "####\n");
    3705                 :        102 :                         break;
    3706                 :            :                 }
    3707                 :         74 :                 next = bss->list_id.next;
    3708         [ -  + ]:         74 :                 if (next == &wpa_s->bss_id)
    3709                 :          0 :                         break;
    3710                 :         74 :                 bss = dl_list_entry(next, struct wpa_bss, list_id);
    3711 [ +  - ][ +  - ]:         74 :         } while (bss && len);
    3712                 :            : 
    3713                 :        116 :         return ret;
    3714                 :            : }
    3715                 :            : 
    3716                 :            : 
    3717                 :          0 : static int wpa_supplicant_ctrl_iface_ap_scan(
    3718                 :            :         struct wpa_supplicant *wpa_s, char *cmd)
    3719                 :            : {
    3720                 :          0 :         int ap_scan = atoi(cmd);
    3721                 :          0 :         return wpa_supplicant_set_ap_scan(wpa_s, ap_scan);
    3722                 :            : }
    3723                 :            : 
    3724                 :            : 
    3725                 :          0 : static int wpa_supplicant_ctrl_iface_scan_interval(
    3726                 :            :         struct wpa_supplicant *wpa_s, char *cmd)
    3727                 :            : {
    3728                 :          0 :         int scan_int = atoi(cmd);
    3729                 :          0 :         return wpa_supplicant_set_scan_interval(wpa_s, scan_int);
    3730                 :            : }
    3731                 :            : 
    3732                 :            : 
    3733                 :          0 : static int wpa_supplicant_ctrl_iface_bss_expire_age(
    3734                 :            :         struct wpa_supplicant *wpa_s, char *cmd)
    3735                 :            : {
    3736                 :          0 :         int expire_age = atoi(cmd);
    3737                 :          0 :         return wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age);
    3738                 :            : }
    3739                 :            : 
    3740                 :            : 
    3741                 :          0 : static int wpa_supplicant_ctrl_iface_bss_expire_count(
    3742                 :            :         struct wpa_supplicant *wpa_s, char *cmd)
    3743                 :            : {
    3744                 :          0 :         int expire_count = atoi(cmd);
    3745                 :          0 :         return wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count);
    3746                 :            : }
    3747                 :            : 
    3748                 :            : 
    3749                 :         81 : static int wpa_supplicant_ctrl_iface_bss_flush(
    3750                 :            :         struct wpa_supplicant *wpa_s, char *cmd)
    3751                 :            : {
    3752                 :         81 :         int flush_age = atoi(cmd);
    3753                 :            : 
    3754         [ +  - ]:         81 :         if (flush_age == 0)
    3755                 :         81 :                 wpa_bss_flush(wpa_s);
    3756                 :            :         else
    3757                 :          0 :                 wpa_bss_flush_by_age(wpa_s, flush_age);
    3758                 :         81 :         return 0;
    3759                 :            : }
    3760                 :            : 
    3761                 :            : 
    3762                 :          0 : static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s)
    3763                 :            : {
    3764                 :          0 :         wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication");
    3765                 :            :         /* MLME-DELETEKEYS.request */
    3766                 :          0 :         wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0);
    3767                 :          0 :         wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0);
    3768                 :          0 :         wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0);
    3769                 :          0 :         wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0);
    3770                 :            : #ifdef CONFIG_IEEE80211W
    3771                 :          0 :         wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0);
    3772                 :          0 :         wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0);
    3773                 :            : #endif /* CONFIG_IEEE80211W */
    3774                 :            : 
    3775                 :          0 :         wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL,
    3776                 :            :                         0);
    3777                 :            :         /* MLME-SETPROTECTION.request(None) */
    3778                 :          0 :         wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid,
    3779                 :            :                                    MLME_SETPROTECTION_PROTECT_TYPE_NONE,
    3780                 :            :                                    MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
    3781                 :          0 :         wpa_sm_drop_sa(wpa_s->wpa);
    3782                 :          0 : }
    3783                 :            : 
    3784                 :            : 
    3785                 :         20 : static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s,
    3786                 :            :                                           char *addr)
    3787                 :            : {
    3788                 :            : #ifdef CONFIG_NO_SCAN_PROCESSING
    3789                 :            :         return -1;
    3790                 :            : #else /* CONFIG_NO_SCAN_PROCESSING */
    3791                 :            :         u8 bssid[ETH_ALEN];
    3792                 :            :         struct wpa_bss *bss;
    3793                 :         20 :         struct wpa_ssid *ssid = wpa_s->current_ssid;
    3794                 :            : 
    3795         [ -  + ]:         20 :         if (hwaddr_aton(addr, bssid)) {
    3796                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid "
    3797                 :            :                            "address '%s'", addr);
    3798                 :          0 :                 return -1;
    3799                 :            :         }
    3800                 :            : 
    3801                 :         20 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM " MACSTR, MAC2STR(bssid));
    3802                 :            : 
    3803         [ -  + ]:         20 :         if (!ssid) {
    3804                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: No network "
    3805                 :            :                            "configuration known for the target AP");
    3806                 :          0 :                 return -1;
    3807                 :            :         }
    3808                 :            : 
    3809                 :         20 :         bss = wpa_bss_get(wpa_s, bssid, ssid->ssid, ssid->ssid_len);
    3810         [ -  + ]:         20 :         if (!bss) {
    3811                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: Target AP not found "
    3812                 :            :                            "from BSS table");
    3813                 :          0 :                 return -1;
    3814                 :            :         }
    3815                 :            : 
    3816                 :            :         /*
    3817                 :            :          * TODO: Find best network configuration block from configuration to
    3818                 :            :          * allow roaming to other networks
    3819                 :            :          */
    3820                 :            : 
    3821                 :         20 :         wpa_s->reassociate = 1;
    3822                 :         20 :         wpa_supplicant_connect(wpa_s, bss, ssid);
    3823                 :            : 
    3824                 :         20 :         return 0;
    3825                 :            : #endif /* CONFIG_NO_SCAN_PROCESSING */
    3826                 :            : }
    3827                 :            : 
    3828                 :            : 
    3829                 :            : #ifdef CONFIG_P2P
    3830                 :        151 : static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
    3831                 :            : {
    3832                 :        151 :         unsigned int timeout = atoi(cmd);
    3833                 :        151 :         enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL;
    3834                 :        151 :         u8 dev_id[ETH_ALEN], *_dev_id = NULL;
    3835                 :        151 :         u8 dev_type[WPS_DEV_TYPE_LEN], *_dev_type = NULL;
    3836                 :            :         char *pos;
    3837                 :            :         unsigned int search_delay;
    3838                 :            : 
    3839         [ +  + ]:        151 :         if (os_strstr(cmd, "type=social"))
    3840                 :        129 :                 type = P2P_FIND_ONLY_SOCIAL;
    3841         [ -  + ]:         22 :         else if (os_strstr(cmd, "type=progressive"))
    3842                 :          0 :                 type = P2P_FIND_PROGRESSIVE;
    3843                 :            : 
    3844                 :        151 :         pos = os_strstr(cmd, "dev_id=");
    3845         [ +  + ]:        151 :         if (pos) {
    3846                 :          4 :                 pos += 7;
    3847         [ -  + ]:          4 :                 if (hwaddr_aton(pos, dev_id))
    3848                 :          0 :                         return -1;
    3849                 :          4 :                 _dev_id = dev_id;
    3850                 :            :         }
    3851                 :            : 
    3852                 :        151 :         pos = os_strstr(cmd, "dev_type=");
    3853         [ +  + ]:        151 :         if (pos) {
    3854                 :          4 :                 pos += 9;
    3855         [ -  + ]:          4 :                 if (wps_dev_type_str2bin(pos, dev_type) < 0)
    3856                 :          0 :                         return -1;
    3857                 :          4 :                 _dev_type = dev_type;
    3858                 :            :         }
    3859                 :            : 
    3860                 :        151 :         pos = os_strstr(cmd, "delay=");
    3861         [ -  + ]:        151 :         if (pos) {
    3862                 :          0 :                 pos += 6;
    3863                 :          0 :                 search_delay = atoi(pos);
    3864                 :            :         } else
    3865                 :        151 :                 search_delay = wpas_p2p_search_delay(wpa_s);
    3866                 :            : 
    3867                 :        151 :         return wpas_p2p_find(wpa_s, timeout, type, _dev_type != NULL, _dev_type,
    3868                 :            :                              _dev_id, search_delay);
    3869                 :            : }
    3870                 :            : 
    3871                 :            : 
    3872                 :        118 : static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
    3873                 :            :                             char *buf, size_t buflen)
    3874                 :            : {
    3875                 :            :         u8 addr[ETH_ALEN];
    3876                 :            :         char *pos, *pos2;
    3877                 :        118 :         char *pin = NULL;
    3878                 :            :         enum p2p_wps_method wps_method;
    3879                 :            :         int new_pin;
    3880                 :            :         int ret;
    3881                 :        118 :         int persistent_group, persistent_id = -1;
    3882                 :            :         int join;
    3883                 :            :         int auth;
    3884                 :            :         int automatic;
    3885                 :        118 :         int go_intent = -1;
    3886                 :        118 :         int freq = 0;
    3887                 :            :         int pd;
    3888                 :            :         int ht40, vht;
    3889                 :            : 
    3890                 :            :         /* <addr> <"pbc" | "pin" | PIN> [label|display|keypad]
    3891                 :            :          * [persistent|persistent=<network id>]
    3892                 :            :          * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] [provdisc]
    3893                 :            :          * [ht40] [vht] */
    3894                 :            : 
    3895         [ -  + ]:        118 :         if (hwaddr_aton(cmd, addr))
    3896                 :          0 :                 return -1;
    3897                 :            : 
    3898                 :        118 :         pos = cmd + 17;
    3899         [ -  + ]:        118 :         if (*pos != ' ')
    3900                 :          0 :                 return -1;
    3901                 :        118 :         pos++;
    3902                 :            : 
    3903                 :        118 :         persistent_group = os_strstr(pos, " persistent") != NULL;
    3904                 :        118 :         pos2 = os_strstr(pos, " persistent=");
    3905         [ -  + ]:        118 :         if (pos2) {
    3906                 :            :                 struct wpa_ssid *ssid;
    3907                 :          0 :                 persistent_id = atoi(pos2 + 12);
    3908                 :          0 :                 ssid = wpa_config_get_network(wpa_s->conf, persistent_id);
    3909 [ #  # ][ #  # ]:          0 :                 if (ssid == NULL || ssid->disabled != 2 ||
                 [ #  # ]
    3910                 :          0 :                     ssid->mode != WPAS_MODE_P2P_GO) {
    3911                 :          0 :                         wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
    3912                 :            :                                    "SSID id=%d for persistent P2P group (GO)",
    3913                 :            :                                    persistent_id);
    3914                 :          0 :                         return -1;
    3915                 :            :                 }
    3916                 :            :         }
    3917                 :        118 :         join = os_strstr(pos, " join") != NULL;
    3918                 :        118 :         auth = os_strstr(pos, " auth") != NULL;
    3919                 :        118 :         automatic = os_strstr(pos, " auto") != NULL;
    3920                 :        118 :         pd = os_strstr(pos, " provdisc") != NULL;
    3921 [ +  - ][ -  + ]:        118 :         vht = (os_strstr(cmd, " vht") != NULL) || wpa_s->conf->p2p_go_vht;
    3922 [ +  - ][ +  - ]:        118 :         ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40 ||
                 [ -  + ]
    3923                 :            :                 vht;
    3924                 :            : 
    3925                 :        118 :         pos2 = os_strstr(pos, " go_intent=");
    3926         [ +  + ]:        118 :         if (pos2) {
    3927                 :         38 :                 pos2 += 11;
    3928                 :         38 :                 go_intent = atoi(pos2);
    3929 [ +  - ][ -  + ]:         38 :                 if (go_intent < 0 || go_intent > 15)
    3930                 :          0 :                         return -1;
    3931                 :            :         }
    3932                 :            : 
    3933                 :        118 :         pos2 = os_strstr(pos, " freq=");
    3934         [ +  + ]:        118 :         if (pos2) {
    3935                 :         18 :                 pos2 += 6;
    3936                 :         18 :                 freq = atoi(pos2);
    3937         [ -  + ]:         18 :                 if (freq <= 0)
    3938                 :          0 :                         return -1;
    3939                 :            :         }
    3940                 :            : 
    3941         [ -  + ]:        118 :         if (os_strncmp(pos, "pin", 3) == 0) {
    3942                 :            :                 /* Request random PIN (to be displayed) and enable the PIN */
    3943                 :          0 :                 wps_method = WPS_PIN_DISPLAY;
    3944         [ +  + ]:        118 :         } else if (os_strncmp(pos, "pbc", 3) == 0) {
    3945                 :          8 :                 wps_method = WPS_PBC;
    3946                 :            :         } else {
    3947                 :        110 :                 pin = pos;
    3948                 :        110 :                 pos = os_strchr(pin, ' ');
    3949                 :        110 :                 wps_method = WPS_PIN_KEYPAD;
    3950         [ +  - ]:        110 :                 if (pos) {
    3951                 :        110 :                         *pos++ = '\0';
    3952         [ +  + ]:        110 :                         if (os_strncmp(pos, "display", 7) == 0)
    3953                 :         43 :                                 wps_method = WPS_PIN_DISPLAY;
    3954                 :            :                 }
    3955         [ -  + ]:        110 :                 if (!wps_pin_str_valid(pin)) {
    3956                 :          0 :                         os_memcpy(buf, "FAIL-INVALID-PIN\n", 17);
    3957                 :          0 :                         return 17;
    3958                 :            :                 }
    3959                 :            :         }
    3960                 :            : 
    3961                 :        118 :         new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
    3962                 :            :                                    persistent_group, automatic, join,
    3963                 :            :                                    auth, go_intent, freq, persistent_id, pd,
    3964                 :            :                                    ht40, vht);
    3965         [ -  + ]:        118 :         if (new_pin == -2) {
    3966                 :          0 :                 os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
    3967                 :          0 :                 return 25;
    3968                 :            :         }
    3969         [ -  + ]:        118 :         if (new_pin == -3) {
    3970                 :          0 :                 os_memcpy(buf, "FAIL-CHANNEL-UNSUPPORTED\n", 25);
    3971                 :          0 :                 return 25;
    3972                 :            :         }
    3973         [ -  + ]:        118 :         if (new_pin < 0)
    3974                 :          0 :                 return -1;
    3975 [ +  + ][ -  + ]:        118 :         if (wps_method == WPS_PIN_DISPLAY && pin == NULL) {
    3976                 :          0 :                 ret = os_snprintf(buf, buflen, "%08d", new_pin);
    3977 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || (size_t) ret >= buflen)
    3978                 :          0 :                         return -1;
    3979                 :          0 :                 return ret;
    3980                 :            :         }
    3981                 :            : 
    3982                 :        118 :         os_memcpy(buf, "OK\n", 3);
    3983                 :        118 :         return 3;
    3984                 :            : }
    3985                 :            : 
    3986                 :            : 
    3987                 :        127 : static int p2p_ctrl_listen(struct wpa_supplicant *wpa_s, char *cmd)
    3988                 :            : {
    3989                 :        127 :         unsigned int timeout = atoi(cmd);
    3990                 :        127 :         return wpas_p2p_listen(wpa_s, timeout);
    3991                 :            : }
    3992                 :            : 
    3993                 :            : 
    3994                 :          8 : static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd)
    3995                 :            : {
    3996                 :            :         u8 addr[ETH_ALEN];
    3997                 :            :         char *pos;
    3998                 :          8 :         enum wpas_p2p_prov_disc_use use = WPAS_P2P_PD_FOR_GO_NEG;
    3999                 :            : 
    4000                 :            :         /* <addr> <config method> [join|auto] */
    4001                 :            : 
    4002         [ -  + ]:          8 :         if (hwaddr_aton(cmd, addr))
    4003                 :          0 :                 return -1;
    4004                 :            : 
    4005                 :          8 :         pos = cmd + 17;
    4006         [ -  + ]:          8 :         if (*pos != ' ')
    4007                 :          0 :                 return -1;
    4008                 :          8 :         pos++;
    4009                 :            : 
    4010         [ -  + ]:          8 :         if (os_strstr(pos, " join") != NULL)
    4011                 :          0 :                 use = WPAS_P2P_PD_FOR_JOIN;
    4012         [ -  + ]:          8 :         else if (os_strstr(pos, " auto") != NULL)
    4013                 :          0 :                 use = WPAS_P2P_PD_AUTO;
    4014                 :            : 
    4015                 :          8 :         return wpas_p2p_prov_disc(wpa_s, addr, pos, use);
    4016                 :            : }
    4017                 :            : 
    4018                 :            : 
    4019                 :          0 : static int p2p_get_passphrase(struct wpa_supplicant *wpa_s, char *buf,
    4020                 :            :                               size_t buflen)
    4021                 :            : {
    4022                 :          0 :         struct wpa_ssid *ssid = wpa_s->current_ssid;
    4023                 :            : 
    4024 [ #  # ][ #  # ]:          0 :         if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
                 [ #  # ]
    4025                 :          0 :             ssid->passphrase == NULL)
    4026                 :          0 :                 return -1;
    4027                 :            : 
    4028                 :          0 :         os_strlcpy(buf, ssid->passphrase, buflen);
    4029                 :          0 :         return os_strlen(buf);
    4030                 :            : }
    4031                 :            : 
    4032                 :            : 
    4033                 :         23 : static int p2p_ctrl_serv_disc_req(struct wpa_supplicant *wpa_s, char *cmd,
    4034                 :            :                                   char *buf, size_t buflen)
    4035                 :            : {
    4036                 :            :         u64 ref;
    4037                 :            :         int res;
    4038                 :            :         u8 dst_buf[ETH_ALEN], *dst;
    4039                 :            :         struct wpabuf *tlvs;
    4040                 :            :         char *pos;
    4041                 :            :         size_t len;
    4042                 :            : 
    4043         [ -  + ]:         23 :         if (hwaddr_aton(cmd, dst_buf))
    4044                 :          0 :                 return -1;
    4045                 :         23 :         dst = dst_buf;
    4046 [ +  + ][ +  - ]:         23 :         if (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 &&
         [ +  - ][ +  - ]
    4047 [ +  - ][ +  - ]:         12 :             dst[3] == 0 && dst[4] == 0 && dst[5] == 0)
    4048                 :         12 :                 dst = NULL;
    4049                 :         23 :         pos = cmd + 17;
    4050         [ -  + ]:         23 :         if (*pos != ' ')
    4051                 :          0 :                 return -1;
    4052                 :         23 :         pos++;
    4053                 :            : 
    4054         [ +  + ]:         23 :         if (os_strncmp(pos, "upnp ", 5) == 0) {
    4055                 :            :                 u8 version;
    4056                 :          1 :                 pos += 5;
    4057         [ -  + ]:          1 :                 if (hexstr2bin(pos, &version, 1) < 0)
    4058                 :          0 :                         return -1;
    4059                 :          1 :                 pos += 2;
    4060         [ -  + ]:          1 :                 if (*pos != ' ')
    4061                 :          0 :                         return -1;
    4062                 :          1 :                 pos++;
    4063                 :          1 :                 ref = wpas_p2p_sd_request_upnp(wpa_s, dst, version, pos);
    4064                 :            : #ifdef CONFIG_WIFI_DISPLAY
    4065         [ -  + ]:         22 :         } else if (os_strncmp(pos, "wifi-display ", 13) == 0) {
    4066                 :          0 :                 ref = wpas_p2p_sd_request_wifi_display(wpa_s, dst, pos + 13);
    4067                 :            : #endif /* CONFIG_WIFI_DISPLAY */
    4068                 :            :         } else {
    4069                 :         22 :                 len = os_strlen(pos);
    4070         [ -  + ]:         22 :                 if (len & 1)
    4071                 :          0 :                         return -1;
    4072                 :         22 :                 len /= 2;
    4073                 :         22 :                 tlvs = wpabuf_alloc(len);
    4074         [ -  + ]:         22 :                 if (tlvs == NULL)
    4075                 :          0 :                         return -1;
    4076         [ -  + ]:         22 :                 if (hexstr2bin(pos, wpabuf_put(tlvs, len), len) < 0) {
    4077                 :          0 :                         wpabuf_free(tlvs);
    4078                 :          0 :                         return -1;
    4079                 :            :                 }
    4080                 :            : 
    4081                 :         22 :                 ref = wpas_p2p_sd_request(wpa_s, dst, tlvs);
    4082                 :         22 :                 wpabuf_free(tlvs);
    4083                 :            :         }
    4084         [ -  + ]:         23 :         if (ref == 0)
    4085                 :          0 :                 return -1;
    4086                 :         23 :         res = os_snprintf(buf, buflen, "%llx", (long long unsigned) ref);
    4087 [ +  - ][ -  + ]:         23 :         if (res < 0 || (unsigned) res >= buflen)
    4088                 :          0 :                 return -1;
    4089                 :         23 :         return res;
    4090                 :            : }
    4091                 :            : 
    4092                 :            : 
    4093                 :          5 : static int p2p_ctrl_serv_disc_cancel_req(struct wpa_supplicant *wpa_s,
    4094                 :            :                                          char *cmd)
    4095                 :            : {
    4096                 :            :         long long unsigned val;
    4097                 :            :         u64 req;
    4098         [ -  + ]:          5 :         if (sscanf(cmd, "%llx", &val) != 1)
    4099                 :          0 :                 return -1;
    4100                 :          5 :         req = val;
    4101                 :          5 :         return wpas_p2p_sd_cancel_request(wpa_s, req);
    4102                 :            : }
    4103                 :            : 
    4104                 :            : 
    4105                 :          0 : static int p2p_ctrl_serv_disc_resp(struct wpa_supplicant *wpa_s, char *cmd)
    4106                 :            : {
    4107                 :            :         int freq;
    4108                 :            :         u8 dst[ETH_ALEN];
    4109                 :            :         u8 dialog_token;
    4110                 :            :         struct wpabuf *resp_tlvs;
    4111                 :            :         char *pos, *pos2;
    4112                 :            :         size_t len;
    4113                 :            : 
    4114                 :          0 :         pos = os_strchr(cmd, ' ');
    4115         [ #  # ]:          0 :         if (pos == NULL)
    4116                 :          0 :                 return -1;
    4117                 :          0 :         *pos++ = '\0';
    4118                 :          0 :         freq = atoi(cmd);
    4119         [ #  # ]:          0 :         if (freq == 0)
    4120                 :          0 :                 return -1;
    4121                 :            : 
    4122         [ #  # ]:          0 :         if (hwaddr_aton(pos, dst))
    4123                 :          0 :                 return -1;
    4124                 :          0 :         pos += 17;
    4125         [ #  # ]:          0 :         if (*pos != ' ')
    4126                 :          0 :                 return -1;
    4127                 :          0 :         pos++;
    4128                 :            : 
    4129                 :          0 :         pos2 = os_strchr(pos, ' ');
    4130         [ #  # ]:          0 :         if (pos2 == NULL)
    4131                 :          0 :                 return -1;
    4132                 :          0 :         *pos2++ = '\0';
    4133                 :          0 :         dialog_token = atoi(pos);
    4134                 :            : 
    4135                 :          0 :         len = os_strlen(pos2);
    4136         [ #  # ]:          0 :         if (len & 1)
    4137                 :          0 :                 return -1;
    4138                 :          0 :         len /= 2;
    4139                 :          0 :         resp_tlvs = wpabuf_alloc(len);
    4140         [ #  # ]:          0 :         if (resp_tlvs == NULL)
    4141                 :          0 :                 return -1;
    4142         [ #  # ]:          0 :         if (hexstr2bin(pos2, wpabuf_put(resp_tlvs, len), len) < 0) {
    4143                 :          0 :                 wpabuf_free(resp_tlvs);
    4144                 :          0 :                 return -1;
    4145                 :            :         }
    4146                 :            : 
    4147                 :          0 :         wpas_p2p_sd_response(wpa_s, freq, dst, dialog_token, resp_tlvs);
    4148                 :          0 :         wpabuf_free(resp_tlvs);
    4149                 :          0 :         return 0;
    4150                 :            : }
    4151                 :            : 
    4152                 :            : 
    4153                 :          0 : static int p2p_ctrl_serv_disc_external(struct wpa_supplicant *wpa_s,
    4154                 :            :                                        char *cmd)
    4155                 :            : {
    4156 [ #  # ][ #  # ]:          0 :         if (os_strcmp(cmd, "0") && os_strcmp(cmd, "1"))
    4157                 :          0 :                 return -1;
    4158                 :          0 :         wpa_s->p2p_sd_over_ctrl_iface = atoi(cmd);
    4159                 :          0 :         return 0;
    4160                 :            : }
    4161                 :            : 
    4162                 :            : 
    4163                 :         60 : static int p2p_ctrl_service_add_bonjour(struct wpa_supplicant *wpa_s,
    4164                 :            :                                         char *cmd)
    4165                 :            : {
    4166                 :            :         char *pos;
    4167                 :            :         size_t len;
    4168                 :            :         struct wpabuf *query, *resp;
    4169                 :            : 
    4170                 :         60 :         pos = os_strchr(cmd, ' ');
    4171         [ -  + ]:         60 :         if (pos == NULL)
    4172                 :          0 :                 return -1;
    4173                 :         60 :         *pos++ = '\0';
    4174                 :            : 
    4175                 :         60 :         len = os_strlen(cmd);
    4176         [ -  + ]:         60 :         if (len & 1)
    4177                 :          0 :                 return -1;
    4178                 :         60 :         len /= 2;
    4179                 :         60 :         query = wpabuf_alloc(len);
    4180         [ -  + ]:         60 :         if (query == NULL)
    4181                 :          0 :                 return -1;
    4182         [ -  + ]:         60 :         if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) {
    4183                 :          0 :                 wpabuf_free(query);
    4184                 :          0 :                 return -1;
    4185                 :            :         }
    4186                 :            : 
    4187                 :         60 :         len = os_strlen(pos);
    4188         [ -  + ]:         60 :         if (len & 1) {
    4189                 :          0 :                 wpabuf_free(query);
    4190                 :          0 :                 return -1;
    4191                 :            :         }
    4192                 :         60 :         len /= 2;
    4193                 :         60 :         resp = wpabuf_alloc(len);
    4194         [ -  + ]:         60 :         if (resp == NULL) {
    4195                 :          0 :                 wpabuf_free(query);
    4196                 :          0 :                 return -1;
    4197                 :            :         }
    4198         [ -  + ]:         60 :         if (hexstr2bin(pos, wpabuf_put(resp, len), len) < 0) {
    4199                 :          0 :                 wpabuf_free(query);
    4200                 :          0 :                 wpabuf_free(resp);
    4201                 :          0 :                 return -1;
    4202                 :            :         }
    4203                 :            : 
    4204         [ -  + ]:         60 :         if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0) {
    4205                 :          0 :                 wpabuf_free(query);
    4206                 :          0 :                 wpabuf_free(resp);
    4207                 :          0 :                 return -1;
    4208                 :            :         }
    4209                 :         60 :         return 0;
    4210                 :            : }
    4211                 :            : 
    4212                 :            : 
    4213                 :        275 : static int p2p_ctrl_service_add_upnp(struct wpa_supplicant *wpa_s, char *cmd)
    4214                 :            : {
    4215                 :            :         char *pos;
    4216                 :            :         u8 version;
    4217                 :            : 
    4218                 :        275 :         pos = os_strchr(cmd, ' ');
    4219         [ -  + ]:        275 :         if (pos == NULL)
    4220                 :          0 :                 return -1;
    4221                 :        275 :         *pos++ = '\0';
    4222                 :            : 
    4223         [ -  + ]:        275 :         if (hexstr2bin(cmd, &version, 1) < 0)
    4224                 :          0 :                 return -1;
    4225                 :            : 
    4226                 :        275 :         return wpas_p2p_service_add_upnp(wpa_s, version, pos);
    4227                 :            : }
    4228                 :            : 
    4229                 :            : 
    4230                 :        335 : static int p2p_ctrl_service_add(struct wpa_supplicant *wpa_s, char *cmd)
    4231                 :            : {
    4232                 :            :         char *pos;
    4233                 :            : 
    4234                 :        335 :         pos = os_strchr(cmd, ' ');
    4235         [ -  + ]:        335 :         if (pos == NULL)
    4236                 :          0 :                 return -1;
    4237                 :        335 :         *pos++ = '\0';
    4238                 :            : 
    4239         [ +  + ]:        335 :         if (os_strcmp(cmd, "bonjour") == 0)
    4240                 :         60 :                 return p2p_ctrl_service_add_bonjour(wpa_s, pos);
    4241         [ +  - ]:        275 :         if (os_strcmp(cmd, "upnp") == 0)
    4242                 :        275 :                 return p2p_ctrl_service_add_upnp(wpa_s, pos);
    4243                 :          0 :         wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd);
    4244                 :        335 :         return -1;
    4245                 :            : }
    4246                 :            : 
    4247                 :            : 
    4248                 :          0 : static int p2p_ctrl_service_del_bonjour(struct wpa_supplicant *wpa_s,
    4249                 :            :                                         char *cmd)
    4250                 :            : {
    4251                 :            :         size_t len;
    4252                 :            :         struct wpabuf *query;
    4253                 :            :         int ret;
    4254                 :            : 
    4255                 :          0 :         len = os_strlen(cmd);
    4256         [ #  # ]:          0 :         if (len & 1)
    4257                 :          0 :                 return -1;
    4258                 :          0 :         len /= 2;
    4259                 :          0 :         query = wpabuf_alloc(len);
    4260         [ #  # ]:          0 :         if (query == NULL)
    4261                 :          0 :                 return -1;
    4262         [ #  # ]:          0 :         if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) {
    4263                 :          0 :                 wpabuf_free(query);
    4264                 :          0 :                 return -1;
    4265                 :            :         }
    4266                 :            : 
    4267                 :          0 :         ret = wpas_p2p_service_del_bonjour(wpa_s, query);
    4268                 :          0 :         wpabuf_free(query);
    4269                 :          0 :         return ret;
    4270                 :            : }
    4271                 :            : 
    4272                 :            : 
    4273                 :          0 : static int p2p_ctrl_service_del_upnp(struct wpa_supplicant *wpa_s, char *cmd)
    4274                 :            : {
    4275                 :            :         char *pos;
    4276                 :            :         u8 version;
    4277                 :            : 
    4278                 :          0 :         pos = os_strchr(cmd, ' ');
    4279         [ #  # ]:          0 :         if (pos == NULL)
    4280                 :          0 :                 return -1;
    4281                 :          0 :         *pos++ = '\0';
    4282                 :            : 
    4283         [ #  # ]:          0 :         if (hexstr2bin(cmd, &version, 1) < 0)
    4284                 :          0 :                 return -1;
    4285                 :            : 
    4286                 :          0 :         return wpas_p2p_service_del_upnp(wpa_s, version, pos);
    4287                 :            : }
    4288                 :            : 
    4289                 :            : 
    4290                 :          0 : static int p2p_ctrl_service_del(struct wpa_supplicant *wpa_s, char *cmd)
    4291                 :            : {
    4292                 :            :         char *pos;
    4293                 :            : 
    4294                 :          0 :         pos = os_strchr(cmd, ' ');
    4295         [ #  # ]:          0 :         if (pos == NULL)
    4296                 :          0 :                 return -1;
    4297                 :          0 :         *pos++ = '\0';
    4298                 :            : 
    4299         [ #  # ]:          0 :         if (os_strcmp(cmd, "bonjour") == 0)
    4300                 :          0 :                 return p2p_ctrl_service_del_bonjour(wpa_s, pos);
    4301         [ #  # ]:          0 :         if (os_strcmp(cmd, "upnp") == 0)
    4302                 :          0 :                 return p2p_ctrl_service_del_upnp(wpa_s, pos);
    4303                 :          0 :         wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd);
    4304                 :          0 :         return -1;
    4305                 :            : }
    4306                 :            : 
    4307                 :            : 
    4308                 :          1 : static int p2p_ctrl_reject(struct wpa_supplicant *wpa_s, char *cmd)
    4309                 :            : {
    4310                 :            :         u8 addr[ETH_ALEN];
    4311                 :            : 
    4312                 :            :         /* <addr> */
    4313                 :            : 
    4314         [ -  + ]:          1 :         if (hwaddr_aton(cmd, addr))
    4315                 :          0 :                 return -1;
    4316                 :            : 
    4317                 :          1 :         return wpas_p2p_reject(wpa_s, addr);
    4318                 :            : }
    4319                 :            : 
    4320                 :            : 
    4321                 :          7 : static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
    4322                 :            : {
    4323                 :            :         char *pos;
    4324                 :            :         int id;
    4325                 :            :         struct wpa_ssid *ssid;
    4326                 :          7 :         u8 *_peer = NULL, peer[ETH_ALEN];
    4327                 :          7 :         int freq = 0, pref_freq = 0;
    4328                 :            :         int ht40, vht;
    4329                 :            : 
    4330                 :          7 :         id = atoi(cmd);
    4331                 :          7 :         pos = os_strstr(cmd, " peer=");
    4332         [ +  - ]:          7 :         if (pos) {
    4333                 :          7 :                 pos += 6;
    4334         [ -  + ]:          7 :                 if (hwaddr_aton(pos, peer))
    4335                 :          0 :                         return -1;
    4336                 :          7 :                 _peer = peer;
    4337                 :            :         }
    4338                 :          7 :         ssid = wpa_config_get_network(wpa_s->conf, id);
    4339 [ +  - ][ -  + ]:          7 :         if (ssid == NULL || ssid->disabled != 2) {
    4340                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
    4341                 :            :                            "for persistent P2P group",
    4342                 :            :                            id);
    4343                 :          0 :                 return -1;
    4344                 :            :         }
    4345                 :            : 
    4346                 :          7 :         pos = os_strstr(cmd, " freq=");
    4347         [ +  + ]:          7 :         if (pos) {
    4348                 :          2 :                 pos += 6;
    4349                 :          2 :                 freq = atoi(pos);
    4350         [ -  + ]:          2 :                 if (freq <= 0)
    4351                 :          0 :                         return -1;
    4352                 :            :         }
    4353                 :            : 
    4354                 :          7 :         pos = os_strstr(cmd, " pref=");
    4355         [ +  + ]:          7 :         if (pos) {
    4356                 :          1 :                 pos += 6;
    4357                 :          1 :                 pref_freq = atoi(pos);
    4358         [ -  + ]:          1 :                 if (pref_freq <= 0)
    4359                 :          0 :                         return -1;
    4360                 :            :         }
    4361                 :            : 
    4362 [ +  - ][ -  + ]:          7 :         vht = (os_strstr(cmd, " vht") != NULL) || wpa_s->conf->p2p_go_vht;
    4363 [ +  - ][ +  - ]:          7 :         ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40 ||
                 [ -  + ]
    4364                 :            :                 vht;
    4365                 :            : 
    4366                 :          7 :         return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, ht40, vht,
    4367                 :            :                                pref_freq);
    4368                 :            : }
    4369                 :            : 
    4370                 :            : 
    4371                 :          4 : static int p2p_ctrl_invite_group(struct wpa_supplicant *wpa_s, char *cmd)
    4372                 :            : {
    4373                 :            :         char *pos;
    4374                 :          4 :         u8 peer[ETH_ALEN], go_dev_addr[ETH_ALEN], *go_dev = NULL;
    4375                 :            : 
    4376                 :          4 :         pos = os_strstr(cmd, " peer=");
    4377         [ -  + ]:          4 :         if (!pos)
    4378                 :          0 :                 return -1;
    4379                 :            : 
    4380                 :          4 :         *pos = '\0';
    4381                 :          4 :         pos += 6;
    4382         [ -  + ]:          4 :         if (hwaddr_aton(pos, peer)) {
    4383                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", pos);
    4384                 :          0 :                 return -1;
    4385                 :            :         }
    4386                 :            : 
    4387                 :          4 :         pos = os_strstr(pos, " go_dev_addr=");
    4388         [ -  + ]:          4 :         if (pos) {
    4389                 :          0 :                 pos += 13;
    4390         [ #  # ]:          0 :                 if (hwaddr_aton(pos, go_dev_addr)) {
    4391                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'",
    4392                 :            :                                    pos);
    4393                 :          0 :                         return -1;
    4394                 :            :                 }
    4395                 :          0 :                 go_dev = go_dev_addr;
    4396                 :            :         }
    4397                 :            : 
    4398                 :          4 :         return wpas_p2p_invite_group(wpa_s, cmd, peer, go_dev);
    4399                 :            : }
    4400                 :            : 
    4401                 :            : 
    4402                 :         11 : static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd)
    4403                 :            : {
    4404         [ +  + ]:         11 :         if (os_strncmp(cmd, "persistent=", 11) == 0)
    4405                 :          7 :                 return p2p_ctrl_invite_persistent(wpa_s, cmd + 11);
    4406         [ +  - ]:          4 :         if (os_strncmp(cmd, "group=", 6) == 0)
    4407                 :          4 :                 return p2p_ctrl_invite_group(wpa_s, cmd + 6);
    4408                 :            : 
    4409                 :         11 :         return -1;
    4410                 :            : }
    4411                 :            : 
    4412                 :            : 
    4413                 :          5 : static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
    4414                 :            :                                          char *cmd, int freq, int ht40,
    4415                 :            :                                          int vht)
    4416                 :            : {
    4417                 :            :         int id;
    4418                 :            :         struct wpa_ssid *ssid;
    4419                 :            : 
    4420                 :          5 :         id = atoi(cmd);
    4421                 :          5 :         ssid = wpa_config_get_network(wpa_s->conf, id);
    4422 [ +  - ][ -  + ]:          5 :         if (ssid == NULL || ssid->disabled != 2) {
    4423                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
    4424                 :            :                            "for persistent P2P group",
    4425                 :            :                            id);
    4426                 :          0 :                 return -1;
    4427                 :            :         }
    4428                 :            : 
    4429                 :          5 :         return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, ht40, vht,
    4430                 :            :                                              NULL, 0);
    4431                 :            : }
    4432                 :            : 
    4433                 :            : 
    4434                 :         15 : static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
    4435                 :            : {
    4436                 :         15 :         int freq = 0, ht40, vht;
    4437                 :            :         char *pos;
    4438                 :            : 
    4439                 :         15 :         pos = os_strstr(cmd, "freq=");
    4440         [ +  + ]:         15 :         if (pos)
    4441                 :          9 :                 freq = atoi(pos + 5);
    4442                 :            : 
    4443 [ +  - ][ -  + ]:         15 :         vht = (os_strstr(cmd, "vht") != NULL) || wpa_s->conf->p2p_go_vht;
    4444 [ +  - ][ +  - ]:         15 :         ht40 = (os_strstr(cmd, "ht40") != NULL) || wpa_s->conf->p2p_go_ht40 ||
                 [ -  + ]
    4445                 :            :                 vht;
    4446                 :            : 
    4447         [ +  + ]:         15 :         if (os_strncmp(cmd, "persistent=", 11) == 0)
    4448                 :          5 :                 return p2p_ctrl_group_add_persistent(wpa_s, cmd + 11, freq,
    4449                 :            :                                                      ht40, vht);
    4450 [ +  + ][ -  + ]:         10 :         if (os_strcmp(cmd, "persistent") == 0 ||
    4451                 :          9 :             os_strncmp(cmd, "persistent ", 11) == 0)
    4452                 :          1 :                 return wpas_p2p_group_add(wpa_s, 1, freq, ht40, vht);
    4453         [ +  - ]:          9 :         if (os_strncmp(cmd, "freq=", 5) == 0)
    4454                 :          9 :                 return wpas_p2p_group_add(wpa_s, 0, freq, ht40, vht);
    4455         [ #  # ]:          0 :         if (ht40)
    4456                 :          0 :                 return wpas_p2p_group_add(wpa_s, 0, freq, ht40, vht);
    4457                 :            : 
    4458                 :          0 :         wpa_printf(MSG_DEBUG, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'",
    4459                 :            :                    cmd);
    4460                 :         15 :         return -1;
    4461                 :            : }
    4462                 :            : 
    4463                 :            : 
    4464                 :        346 : static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
    4465                 :            :                          char *buf, size_t buflen)
    4466                 :            : {
    4467                 :            :         u8 addr[ETH_ALEN], *addr_ptr;
    4468                 :            :         int next, res;
    4469                 :            :         const struct p2p_peer_info *info;
    4470                 :            :         char *pos, *end;
    4471                 :            :         char devtype[WPS_DEV_TYPE_BUFSIZE];
    4472                 :            :         struct wpa_ssid *ssid;
    4473                 :            :         size_t i;
    4474                 :            : 
    4475         [ -  + ]:        346 :         if (!wpa_s->global->p2p)
    4476                 :          0 :                 return -1;
    4477                 :            : 
    4478         [ -  + ]:        346 :         if (os_strcmp(cmd, "FIRST") == 0) {
    4479                 :          0 :                 addr_ptr = NULL;
    4480                 :          0 :                 next = 0;
    4481         [ -  + ]:        346 :         } else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
    4482         [ #  # ]:          0 :                 if (hwaddr_aton(cmd + 5, addr) < 0)
    4483                 :          0 :                         return -1;
    4484                 :          0 :                 addr_ptr = addr;
    4485                 :          0 :                 next = 1;
    4486                 :            :         } else {
    4487         [ -  + ]:        346 :                 if (hwaddr_aton(cmd, addr) < 0)
    4488                 :          0 :                         return -1;
    4489                 :        346 :                 addr_ptr = addr;
    4490                 :        346 :                 next = 0;
    4491                 :            :         }
    4492                 :            : 
    4493                 :        346 :         info = p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next);
    4494         [ +  + ]:        346 :         if (info == NULL)
    4495                 :        108 :                 return -1;
    4496                 :            : 
    4497                 :        238 :         pos = buf;
    4498                 :        238 :         end = buf + buflen;
    4499                 :            : 
    4500                 :        238 :         res = os_snprintf(pos, end - pos, MACSTR "\n"
    4501                 :            :                           "pri_dev_type=%s\n"
    4502                 :            :                           "device_name=%s\n"
    4503                 :            :                           "manufacturer=%s\n"
    4504                 :            :                           "model_name=%s\n"
    4505                 :            :                           "model_number=%s\n"
    4506                 :            :                           "serial_number=%s\n"
    4507                 :            :                           "config_methods=0x%x\n"
    4508                 :            :                           "dev_capab=0x%x\n"
    4509                 :            :                           "group_capab=0x%x\n"
    4510                 :            :                           "level=%d\n",
    4511                 :       1428 :                           MAC2STR(info->p2p_device_addr),
    4512                 :        238 :                           wps_dev_type_bin2str(info->pri_dev_type,
    4513                 :            :                                                devtype, sizeof(devtype)),
    4514                 :        238 :                           info->device_name,
    4515                 :        238 :                           info->manufacturer,
    4516                 :        238 :                           info->model_name,
    4517                 :        238 :                           info->model_number,
    4518                 :        238 :                           info->serial_number,
    4519                 :        238 :                           info->config_methods,
    4520                 :        238 :                           info->dev_capab,
    4521                 :        238 :                           info->group_capab,
    4522                 :            :                           info->level);
    4523 [ +  - ][ -  + ]:        238 :         if (res < 0 || res >= end - pos)
    4524                 :          0 :                 return pos - buf;
    4525                 :        238 :         pos += res;
    4526                 :            : 
    4527         [ +  + ]:        242 :         for (i = 0; i < info->wps_sec_dev_type_list_len / WPS_DEV_TYPE_LEN; i++)
    4528                 :            :         {
    4529                 :            :                 const u8 *t;
    4530                 :          4 :                 t = &info->wps_sec_dev_type_list[i * WPS_DEV_TYPE_LEN];
    4531                 :          4 :                 res = os_snprintf(pos, end - pos, "sec_dev_type=%s\n",
    4532                 :            :                                   wps_dev_type_bin2str(t, devtype,
    4533                 :            :                                                        sizeof(devtype)));
    4534 [ +  - ][ -  + ]:          4 :                 if (res < 0 || res >= end - pos)
    4535                 :          0 :                         return pos - buf;
    4536                 :          4 :                 pos += res;
    4537                 :            :         }
    4538                 :            : 
    4539                 :        238 :         ssid = wpas_p2p_get_persistent(wpa_s, info->p2p_device_addr, NULL, 0);
    4540         [ +  + ]:        238 :         if (ssid) {
    4541                 :         23 :                 res = os_snprintf(pos, end - pos, "persistent=%d\n", ssid->id);
    4542 [ +  - ][ -  + ]:         23 :                 if (res < 0 || res >= end - pos)
    4543                 :          0 :                         return pos - buf;
    4544                 :         23 :                 pos += res;
    4545                 :            :         }
    4546                 :            : 
    4547                 :        238 :         res = p2p_get_peer_info_txt(info, pos, end - pos);
    4548         [ -  + ]:        238 :         if (res < 0)
    4549                 :          0 :                 return pos - buf;
    4550                 :        238 :         pos += res;
    4551                 :            : 
    4552                 :        346 :         return pos - buf;
    4553                 :            : }
    4554                 :            : 
    4555                 :            : 
    4556                 :          0 : static int p2p_ctrl_disallow_freq(struct wpa_supplicant *wpa_s,
    4557                 :            :                                   const char *param)
    4558                 :            : {
    4559                 :            :         unsigned int i;
    4560                 :            : 
    4561         [ #  # ]:          0 :         if (wpa_s->global->p2p == NULL)
    4562                 :          0 :                 return -1;
    4563                 :            : 
    4564         [ #  # ]:          0 :         if (freq_range_list_parse(&wpa_s->global->p2p_disallow_freq, param) < 0)
    4565                 :          0 :                 return -1;
    4566                 :            : 
    4567         [ #  # ]:          0 :         for (i = 0; i < wpa_s->global->p2p_disallow_freq.num; i++) {
    4568                 :            :                 struct wpa_freq_range *freq;
    4569                 :          0 :                 freq = &wpa_s->global->p2p_disallow_freq.range[i];
    4570                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Disallowed frequency range %u-%u",
    4571                 :            :                            freq->min, freq->max);
    4572                 :            :         }
    4573                 :            : 
    4574                 :          0 :         wpas_p2p_update_channel_list(wpa_s);
    4575                 :          0 :         return 0;
    4576                 :            : }
    4577                 :            : 
    4578                 :            : 
    4579                 :         12 : static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
    4580                 :            : {
    4581                 :            :         char *param;
    4582                 :            : 
    4583         [ -  + ]:         12 :         if (wpa_s->global->p2p == NULL)
    4584                 :          0 :                 return -1;
    4585                 :            : 
    4586                 :         12 :         param = os_strchr(cmd, ' ');
    4587         [ -  + ]:         12 :         if (param == NULL)
    4588                 :          0 :                 return -1;
    4589                 :         12 :         *param++ = '\0';
    4590                 :            : 
    4591         [ -  + ]:         12 :         if (os_strcmp(cmd, "discoverability") == 0) {
    4592                 :          0 :                 p2p_set_client_discoverability(wpa_s->global->p2p,
    4593                 :            :                                                atoi(param));
    4594                 :          0 :                 return 0;
    4595                 :            :         }
    4596                 :            : 
    4597         [ -  + ]:         12 :         if (os_strcmp(cmd, "managed") == 0) {
    4598                 :          0 :                 p2p_set_managed_oper(wpa_s->global->p2p, atoi(param));
    4599                 :          0 :                 return 0;
    4600                 :            :         }
    4601                 :            : 
    4602         [ -  + ]:         12 :         if (os_strcmp(cmd, "listen_channel") == 0) {
    4603                 :          0 :                 return p2p_set_listen_channel(wpa_s->global->p2p, 81,
    4604                 :          0 :                                               atoi(param));
    4605                 :            :         }
    4606                 :            : 
    4607         [ -  + ]:         12 :         if (os_strcmp(cmd, "ssid_postfix") == 0) {
    4608                 :          0 :                 return p2p_set_ssid_postfix(wpa_s->global->p2p, (u8 *) param,
    4609                 :            :                                             os_strlen(param));
    4610                 :            :         }
    4611                 :            : 
    4612         [ -  + ]:         12 :         if (os_strcmp(cmd, "noa") == 0) {
    4613                 :            :                 char *pos;
    4614                 :            :                 int count, start, duration;
    4615                 :            :                 /* GO NoA parameters: count,start_offset(ms),duration(ms) */
    4616                 :          0 :                 count = atoi(param);
    4617                 :          0 :                 pos = os_strchr(param, ',');
    4618         [ #  # ]:          0 :                 if (pos == NULL)
    4619                 :          0 :                         return -1;
    4620                 :          0 :                 pos++;
    4621                 :          0 :                 start = atoi(pos);
    4622                 :          0 :                 pos = os_strchr(pos, ',');
    4623         [ #  # ]:          0 :                 if (pos == NULL)
    4624                 :          0 :                         return -1;
    4625                 :          0 :                 pos++;
    4626                 :          0 :                 duration = atoi(pos);
    4627 [ #  # ][ #  # ]:          0 :                 if (count < 0 || count > 255 || start < 0 || duration < 0)
         [ #  # ][ #  # ]
    4628                 :          0 :                         return -1;
    4629 [ #  # ][ #  # ]:          0 :                 if (count == 0 && duration > 0)
    4630                 :          0 :                         return -1;
    4631                 :          0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: P2P_SET GO NoA: count=%d "
    4632                 :            :                            "start=%d duration=%d", count, start, duration);
    4633                 :          0 :                 return wpas_p2p_set_noa(wpa_s, count, start, duration);
    4634                 :            :         }
    4635                 :            : 
    4636         [ -  + ]:         12 :         if (os_strcmp(cmd, "ps") == 0)
    4637                 :          0 :                 return wpa_drv_set_p2p_powersave(wpa_s, atoi(param), -1, -1);
    4638                 :            : 
    4639         [ -  + ]:         12 :         if (os_strcmp(cmd, "oppps") == 0)
    4640                 :          0 :                 return wpa_drv_set_p2p_powersave(wpa_s, -1, atoi(param), -1);
    4641                 :            : 
    4642         [ -  + ]:         12 :         if (os_strcmp(cmd, "ctwindow") == 0)
    4643                 :          0 :                 return wpa_drv_set_p2p_powersave(wpa_s, -1, -1, atoi(param));
    4644                 :            : 
    4645         [ +  + ]:         12 :         if (os_strcmp(cmd, "disabled") == 0) {
    4646                 :          2 :                 wpa_s->global->p2p_disabled = atoi(param);
    4647         [ +  - ]:          2 :                 wpa_printf(MSG_DEBUG, "P2P functionality %s",
    4648                 :          2 :                            wpa_s->global->p2p_disabled ?
    4649                 :            :                            "disabled" : "enabled");
    4650         [ +  - ]:          2 :                 if (wpa_s->global->p2p_disabled) {
    4651                 :          2 :                         wpas_p2p_stop_find(wpa_s);
    4652                 :          2 :                         os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
    4653                 :          2 :                         p2p_flush(wpa_s->global->p2p);
    4654                 :            :                 }
    4655                 :          2 :                 return 0;
    4656                 :            :         }
    4657                 :            : 
    4658         [ -  + ]:         10 :         if (os_strcmp(cmd, "conc_pref") == 0) {
    4659         [ #  # ]:          0 :                 if (os_strcmp(param, "sta") == 0)
    4660                 :          0 :                         wpa_s->global->conc_pref = WPA_CONC_PREF_STA;
    4661         [ #  # ]:          0 :                 else if (os_strcmp(param, "p2p") == 0)
    4662                 :          0 :                         wpa_s->global->conc_pref = WPA_CONC_PREF_P2P;
    4663                 :            :                 else {
    4664                 :          0 :                         wpa_printf(MSG_INFO, "Invalid conc_pref value");
    4665                 :          0 :                         return -1;
    4666                 :            :                 }
    4667                 :          0 :                 wpa_printf(MSG_DEBUG, "Single channel concurrency preference: "
    4668                 :            :                            "%s", param);
    4669                 :          0 :                 return 0;
    4670                 :            :         }
    4671                 :            : 
    4672         [ -  + ]:         10 :         if (os_strcmp(cmd, "force_long_sd") == 0) {
    4673                 :          0 :                 wpa_s->force_long_sd = atoi(param);
    4674                 :          0 :                 return 0;
    4675                 :            :         }
    4676                 :            : 
    4677         [ -  + ]:         10 :         if (os_strcmp(cmd, "peer_filter") == 0) {
    4678                 :            :                 u8 addr[ETH_ALEN];
    4679         [ #  # ]:          0 :                 if (hwaddr_aton(param, addr))
    4680                 :          0 :                         return -1;
    4681                 :          0 :                 p2p_set_peer_filter(wpa_s->global->p2p, addr);
    4682                 :          0 :                 return 0;
    4683                 :            :         }
    4684                 :            : 
    4685         [ -  + ]:         10 :         if (os_strcmp(cmd, "cross_connect") == 0)
    4686                 :          0 :                 return wpas_p2p_set_cross_connect(wpa_s, atoi(param));
    4687                 :            : 
    4688         [ -  + ]:         10 :         if (os_strcmp(cmd, "go_apsd") == 0) {
    4689         [ #  # ]:          0 :                 if (os_strcmp(param, "disable") == 0)
    4690                 :          0 :                         wpa_s->set_ap_uapsd = 0;
    4691                 :            :                 else {
    4692                 :          0 :                         wpa_s->set_ap_uapsd = 1;
    4693                 :          0 :                         wpa_s->ap_uapsd = atoi(param);
    4694                 :            :                 }
    4695                 :          0 :                 return 0;
    4696                 :            :         }
    4697                 :            : 
    4698         [ -  + ]:         10 :         if (os_strcmp(cmd, "client_apsd") == 0) {
    4699         [ #  # ]:          0 :                 if (os_strcmp(param, "disable") == 0)
    4700                 :          0 :                         wpa_s->set_sta_uapsd = 0;
    4701                 :            :                 else {
    4702                 :            :                         int be, bk, vi, vo;
    4703                 :            :                         char *pos;
    4704                 :            :                         /* format: BE,BK,VI,VO;max SP Length */
    4705                 :          0 :                         be = atoi(param);
    4706                 :          0 :                         pos = os_strchr(param, ',');
    4707         [ #  # ]:          0 :                         if (pos == NULL)
    4708                 :          0 :                                 return -1;
    4709                 :          0 :                         pos++;
    4710                 :          0 :                         bk = atoi(pos);
    4711                 :          0 :                         pos = os_strchr(pos, ',');
    4712         [ #  # ]:          0 :                         if (pos == NULL)
    4713                 :          0 :                                 return -1;
    4714                 :          0 :                         pos++;
    4715                 :          0 :                         vi = atoi(pos);
    4716                 :          0 :                         pos = os_strchr(pos, ',');
    4717         [ #  # ]:          0 :                         if (pos == NULL)
    4718                 :          0 :                                 return -1;
    4719                 :          0 :                         pos++;
    4720                 :          0 :                         vo = atoi(pos);
    4721                 :            :                         /* ignore max SP Length for now */
    4722                 :            : 
    4723                 :          0 :                         wpa_s->set_sta_uapsd = 1;
    4724                 :          0 :                         wpa_s->sta_uapsd = 0;
    4725         [ #  # ]:          0 :                         if (be)
    4726                 :          0 :                                 wpa_s->sta_uapsd |= BIT(0);
    4727         [ #  # ]:          0 :                         if (bk)
    4728                 :          0 :                                 wpa_s->sta_uapsd |= BIT(1);
    4729         [ #  # ]:          0 :                         if (vi)
    4730                 :          0 :                                 wpa_s->sta_uapsd |= BIT(2);
    4731         [ #  # ]:          0 :                         if (vo)
    4732                 :          0 :                                 wpa_s->sta_uapsd |= BIT(3);
    4733                 :            :                 }
    4734                 :          0 :                 return 0;
    4735                 :            :         }
    4736                 :            : 
    4737         [ -  + ]:         10 :         if (os_strcmp(cmd, "disallow_freq") == 0)
    4738                 :          0 :                 return p2p_ctrl_disallow_freq(wpa_s, param);
    4739                 :            : 
    4740         [ -  + ]:         10 :         if (os_strcmp(cmd, "disc_int") == 0) {
    4741                 :            :                 int min_disc_int, max_disc_int, max_disc_tu;
    4742                 :            :                 char *pos;
    4743                 :            : 
    4744                 :          0 :                 pos = param;
    4745                 :            : 
    4746                 :          0 :                 min_disc_int = atoi(pos);
    4747                 :          0 :                 pos = os_strchr(pos, ' ');
    4748         [ #  # ]:          0 :                 if (pos == NULL)
    4749                 :          0 :                         return -1;
    4750                 :          0 :                 *pos++ = '\0';
    4751                 :            : 
    4752                 :          0 :                 max_disc_int = atoi(pos);
    4753                 :          0 :                 pos = os_strchr(pos, ' ');
    4754         [ #  # ]:          0 :                 if (pos == NULL)
    4755                 :          0 :                         return -1;
    4756                 :          0 :                 *pos++ = '\0';
    4757                 :            : 
    4758                 :          0 :                 max_disc_tu = atoi(pos);
    4759                 :            : 
    4760                 :          0 :                 return p2p_set_disc_int(wpa_s->global->p2p, min_disc_int,
    4761                 :            :                                         max_disc_int, max_disc_tu);
    4762                 :            :         }
    4763                 :            : 
    4764         [ +  + ]:         10 :         if (os_strcmp(cmd, "per_sta_psk") == 0) {
    4765                 :          4 :                 wpa_s->global->p2p_per_sta_psk = !!atoi(param);
    4766                 :          4 :                 return 0;
    4767                 :            :         }
    4768                 :            : 
    4769                 :            : #ifdef CONFIG_WPS_NFC
    4770         [ +  + ]:          6 :         if (os_strcmp(cmd, "nfc_tag") == 0)
    4771                 :          5 :                 return wpas_p2p_nfc_tag_enabled(wpa_s, !!atoi(param));
    4772                 :            : #endif /* CONFIG_WPS_NFC */
    4773                 :            : 
    4774         [ +  - ]:          1 :         if (os_strcmp(cmd, "disable_ip_addr_req") == 0) {
    4775                 :          1 :                 wpa_s->p2p_disable_ip_addr_req = !!atoi(param);
    4776                 :          1 :                 return 0;
    4777                 :            :         }
    4778                 :            : 
    4779                 :          0 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
    4780                 :            :                    cmd);
    4781                 :            : 
    4782                 :         12 :         return -1;
    4783                 :            : }
    4784                 :            : 
    4785                 :            : 
    4786                 :       1200 : static void p2p_ctrl_flush(struct wpa_supplicant *wpa_s)
    4787                 :            : {
    4788                 :       1200 :         os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
    4789                 :       1200 :         wpa_s->force_long_sd = 0;
    4790         [ +  - ]:       1200 :         if (wpa_s->global->p2p)
    4791                 :       1200 :                 p2p_flush(wpa_s->global->p2p);
    4792                 :       1200 : }
    4793                 :            : 
    4794                 :            : 
    4795                 :          1 : static int p2p_ctrl_presence_req(struct wpa_supplicant *wpa_s, char *cmd)
    4796                 :            : {
    4797                 :            :         char *pos, *pos2;
    4798                 :          1 :         unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0;
    4799                 :            : 
    4800         [ +  - ]:          1 :         if (cmd[0]) {
    4801                 :          1 :                 pos = os_strchr(cmd, ' ');
    4802         [ -  + ]:          1 :                 if (pos == NULL)
    4803                 :          0 :                         return -1;
    4804                 :          1 :                 *pos++ = '\0';
    4805                 :          1 :                 dur1 = atoi(cmd);
    4806                 :            : 
    4807                 :          1 :                 pos2 = os_strchr(pos, ' ');
    4808         [ -  + ]:          1 :                 if (pos2)
    4809                 :          0 :                         *pos2++ = '\0';
    4810                 :          1 :                 int1 = atoi(pos);
    4811                 :            :         } else
    4812                 :          0 :                 pos2 = NULL;
    4813                 :            : 
    4814         [ -  + ]:          1 :         if (pos2) {
    4815                 :          0 :                 pos = os_strchr(pos2, ' ');
    4816         [ #  # ]:          0 :                 if (pos == NULL)
    4817                 :          0 :                         return -1;
    4818                 :          0 :                 *pos++ = '\0';
    4819                 :          0 :                 dur2 = atoi(pos2);
    4820                 :          0 :                 int2 = atoi(pos);
    4821                 :            :         }
    4822                 :            : 
    4823                 :          1 :         return wpas_p2p_presence_req(wpa_s, dur1, int1, dur2, int2);
    4824                 :            : }
    4825                 :            : 
    4826                 :            : 
    4827                 :          0 : static int p2p_ctrl_ext_listen(struct wpa_supplicant *wpa_s, char *cmd)
    4828                 :            : {
    4829                 :            :         char *pos;
    4830                 :          0 :         unsigned int period = 0, interval = 0;
    4831                 :            : 
    4832         [ #  # ]:          0 :         if (cmd[0]) {
    4833                 :          0 :                 pos = os_strchr(cmd, ' ');
    4834         [ #  # ]:          0 :                 if (pos == NULL)
    4835                 :          0 :                         return -1;
    4836                 :          0 :                 *pos++ = '\0';
    4837                 :          0 :                 period = atoi(cmd);
    4838                 :          0 :                 interval = atoi(pos);
    4839                 :            :         }
    4840                 :            : 
    4841                 :          0 :         return wpas_p2p_ext_listen(wpa_s, period, interval);
    4842                 :            : }
    4843                 :            : 
    4844                 :            : 
    4845                 :          4 : static int p2p_ctrl_remove_client(struct wpa_supplicant *wpa_s, const char *cmd)
    4846                 :            : {
    4847                 :            :         const char *pos;
    4848                 :            :         u8 peer[ETH_ALEN];
    4849                 :          4 :         int iface_addr = 0;
    4850                 :            : 
    4851                 :          4 :         pos = cmd;
    4852         [ -  + ]:          4 :         if (os_strncmp(pos, "iface=", 6) == 0) {
    4853                 :          0 :                 iface_addr = 1;
    4854                 :          0 :                 pos += 6;
    4855                 :            :         }
    4856         [ -  + ]:          4 :         if (hwaddr_aton(pos, peer))
    4857                 :          0 :                 return -1;
    4858                 :            : 
    4859                 :          4 :         wpas_p2p_remove_client(wpa_s, peer, iface_addr);
    4860                 :          4 :         return 0;
    4861                 :            : }
    4862                 :            : 
    4863                 :            : #endif /* CONFIG_P2P */
    4864                 :            : 
    4865                 :            : 
    4866                 :        153 : static int * freq_range_to_channel_list(struct wpa_supplicant *wpa_s, char *val)
    4867                 :            : {
    4868                 :            :         struct wpa_freq_range_list ranges;
    4869                 :        153 :         int *freqs = NULL;
    4870                 :            :         struct hostapd_hw_modes *mode;
    4871                 :            :         u16 i;
    4872                 :            : 
    4873         [ -  + ]:        153 :         if (wpa_s->hw.modes == NULL)
    4874                 :          0 :                 return NULL;
    4875                 :            : 
    4876                 :        153 :         os_memset(&ranges, 0, sizeof(ranges));
    4877         [ -  + ]:        153 :         if (freq_range_list_parse(&ranges, val) < 0)
    4878                 :          0 :                 return NULL;
    4879                 :            : 
    4880         [ +  + ]:        612 :         for (i = 0; i < wpa_s->hw.num_modes; i++) {
    4881                 :            :                 int j;
    4882                 :            : 
    4883                 :        459 :                 mode = &wpa_s->hw.modes[i];
    4884         [ +  + ]:       8415 :                 for (j = 0; j < mode->num_channels; j++) {
    4885                 :            :                         unsigned int freq;
    4886                 :            : 
    4887         [ +  + ]:       7956 :                         if (mode->channels[j].flag & HOSTAPD_CHAN_DISABLED)
    4888                 :       2295 :                                 continue;
    4889                 :            : 
    4890                 :       5661 :                         freq = mode->channels[j].freq;
    4891         [ +  + ]:       5661 :                         if (!freq_range_list_includes(&ranges, freq))
    4892                 :       5313 :                                 continue;
    4893                 :            : 
    4894                 :        348 :                         int_array_add_unique(&freqs, freq);
    4895                 :            :                 }
    4896                 :            :         }
    4897                 :            : 
    4898                 :        153 :         os_free(ranges.range);
    4899                 :        153 :         return freqs;
    4900                 :            : }
    4901                 :            : 
    4902                 :            : 
    4903                 :            : #ifdef CONFIG_INTERWORKING
    4904                 :            : 
    4905                 :        109 : static int ctrl_interworking_select(struct wpa_supplicant *wpa_s, char *param)
    4906                 :            : {
    4907                 :        109 :         int auto_sel = 0;
    4908                 :        109 :         int *freqs = NULL;
    4909                 :            : 
    4910         [ +  + ]:        109 :         if (param) {
    4911                 :            :                 char *pos;
    4912                 :            : 
    4913                 :        108 :                 auto_sel = os_strstr(param, "auto") != NULL;
    4914                 :            : 
    4915                 :        108 :                 pos = os_strstr(param, "freq=");
    4916         [ +  + ]:        108 :                 if (pos) {
    4917                 :        107 :                         freqs = freq_range_to_channel_list(wpa_s, pos + 5);
    4918         [ -  + ]:        107 :                         if (freqs == NULL)
    4919                 :          0 :                                 return -1;
    4920                 :            :                 }
    4921                 :            : 
    4922                 :            :         }
    4923                 :            : 
    4924                 :        109 :         return interworking_select(wpa_s, auto_sel, freqs);
    4925                 :            : }
    4926                 :            : 
    4927                 :            : 
    4928                 :         33 : static int ctrl_interworking_connect(struct wpa_supplicant *wpa_s, char *dst)
    4929                 :            : {
    4930                 :            :         u8 bssid[ETH_ALEN];
    4931                 :            :         struct wpa_bss *bss;
    4932                 :            : 
    4933         [ -  + ]:         33 :         if (hwaddr_aton(dst, bssid)) {
    4934                 :          0 :                 wpa_printf(MSG_DEBUG, "Invalid BSSID '%s'", dst);
    4935                 :          0 :                 return -1;
    4936                 :            :         }
    4937                 :            : 
    4938                 :         33 :         bss = wpa_bss_get_bssid(wpa_s, bssid);
    4939         [ -  + ]:         33 :         if (bss == NULL) {
    4940                 :          0 :                 wpa_printf(MSG_DEBUG, "Could not find BSS " MACSTR,
    4941                 :          0 :                            MAC2STR(bssid));
    4942                 :          0 :                 return -1;
    4943                 :            :         }
    4944                 :            : 
    4945                 :         33 :         return interworking_connect(wpa_s, bss);
    4946                 :            : }
    4947                 :            : 
    4948                 :            : 
    4949                 :         18 : static int get_anqp(struct wpa_supplicant *wpa_s, char *dst)
    4950                 :            : {
    4951                 :            :         u8 dst_addr[ETH_ALEN];
    4952                 :            :         int used;
    4953                 :            :         char *pos;
    4954                 :            : #define MAX_ANQP_INFO_ID 100
    4955                 :            :         u16 id[MAX_ANQP_INFO_ID];
    4956                 :         18 :         size_t num_id = 0;
    4957                 :            : 
    4958                 :         18 :         used = hwaddr_aton2(dst, dst_addr);
    4959         [ -  + ]:         18 :         if (used < 0)
    4960                 :          0 :                 return -1;
    4961                 :         18 :         pos = dst + used;
    4962         [ +  - ]:         18 :         while (num_id < MAX_ANQP_INFO_ID) {
    4963                 :         18 :                 id[num_id] = atoi(pos);
    4964         [ +  - ]:         18 :                 if (id[num_id])
    4965                 :         18 :                         num_id++;
    4966                 :         18 :                 pos = os_strchr(pos + 1, ',');
    4967         [ +  - ]:         18 :                 if (pos == NULL)
    4968                 :         18 :                         break;
    4969                 :          0 :                 pos++;
    4970                 :            :         }
    4971                 :            : 
    4972         [ -  + ]:         18 :         if (num_id == 0)
    4973                 :          0 :                 return -1;
    4974                 :            : 
    4975                 :         18 :         return anqp_send_req(wpa_s, dst_addr, id, num_id);
    4976                 :            : }
    4977                 :            : 
    4978                 :            : 
    4979                 :          7 : static int gas_request(struct wpa_supplicant *wpa_s, char *cmd)
    4980                 :            : {
    4981                 :            :         u8 dst_addr[ETH_ALEN];
    4982                 :          7 :         struct wpabuf *advproto, *query = NULL;
    4983                 :          7 :         int used, ret = -1;
    4984                 :            :         char *pos, *end;
    4985                 :            :         size_t len;
    4986                 :            : 
    4987                 :          7 :         used = hwaddr_aton2(cmd, dst_addr);
    4988         [ -  + ]:          7 :         if (used < 0)
    4989                 :          0 :                 return -1;
    4990                 :            : 
    4991                 :          7 :         pos = cmd + used;
    4992         [ +  + ]:         14 :         while (*pos == ' ')
    4993                 :          7 :                 pos++;
    4994                 :            : 
    4995                 :            :         /* Advertisement Protocol ID */
    4996                 :          7 :         end = os_strchr(pos, ' ');
    4997         [ +  - ]:          7 :         if (end)
    4998                 :          7 :                 len = end - pos;
    4999                 :            :         else
    5000                 :          0 :                 len = os_strlen(pos);
    5001         [ -  + ]:          7 :         if (len & 0x01)
    5002                 :          0 :                 return -1;
    5003                 :          7 :         len /= 2;
    5004         [ -  + ]:          7 :         if (len == 0)
    5005                 :          0 :                 return -1;
    5006                 :          7 :         advproto = wpabuf_alloc(len);
    5007         [ -  + ]:          7 :         if (advproto == NULL)
    5008                 :          0 :                 return -1;
    5009         [ -  + ]:          7 :         if (hexstr2bin(pos, wpabuf_put(advproto, len), len) < 0)
    5010                 :          0 :                 goto fail;
    5011                 :            : 
    5012         [ +  - ]:          7 :         if (end) {
    5013                 :            :                 /* Optional Query Request */
    5014                 :          7 :                 pos = end + 1;
    5015         [ -  + ]:          7 :                 while (*pos == ' ')
    5016                 :          0 :                         pos++;
    5017                 :            : 
    5018                 :          7 :                 len = os_strlen(pos);
    5019         [ +  - ]:          7 :                 if (len) {
    5020         [ -  + ]:          7 :                         if (len & 0x01)
    5021                 :          0 :                                 goto fail;
    5022                 :          7 :                         len /= 2;
    5023         [ -  + ]:          7 :                         if (len == 0)
    5024                 :          0 :                                 goto fail;
    5025                 :          7 :                         query = wpabuf_alloc(len);
    5026         [ -  + ]:          7 :                         if (query == NULL)
    5027                 :          0 :                                 goto fail;
    5028         [ -  + ]:          7 :                         if (hexstr2bin(pos, wpabuf_put(query, len), len) < 0)
    5029                 :          0 :                                 goto fail;
    5030                 :            :                 }
    5031                 :            :         }
    5032                 :            : 
    5033                 :          7 :         ret = gas_send_request(wpa_s, dst_addr, advproto, query);
    5034                 :            : 
    5035                 :            : fail:
    5036                 :          7 :         wpabuf_free(advproto);
    5037                 :          7 :         wpabuf_free(query);
    5038                 :            : 
    5039                 :          7 :         return ret;
    5040                 :            : }
    5041                 :            : 
    5042                 :            : 
    5043                 :          7 : static int gas_response_get(struct wpa_supplicant *wpa_s, char *cmd, char *buf,
    5044                 :            :                             size_t buflen)
    5045                 :            : {
    5046                 :            :         u8 addr[ETH_ALEN];
    5047                 :            :         int dialog_token;
    5048                 :            :         int used;
    5049                 :            :         char *pos;
    5050                 :            :         size_t resp_len, start, requested_len;
    5051                 :            :         struct wpabuf *resp;
    5052                 :            :         int ret;
    5053                 :            : 
    5054                 :          7 :         used = hwaddr_aton2(cmd, addr);
    5055         [ -  + ]:          7 :         if (used < 0)
    5056                 :          0 :                 return -1;
    5057                 :            : 
    5058                 :          7 :         pos = cmd + used;
    5059         [ +  + ]:         14 :         while (*pos == ' ')
    5060                 :          7 :                 pos++;
    5061                 :          7 :         dialog_token = atoi(pos);
    5062                 :            : 
    5063 [ +  - ][ +  - ]:          7 :         if (wpa_s->last_gas_resp &&
    5064         [ +  + ]:          7 :             os_memcmp(addr, wpa_s->last_gas_addr, ETH_ALEN) == 0 &&
    5065                 :          7 :             dialog_token == wpa_s->last_gas_dialog_token)
    5066                 :          6 :                 resp = wpa_s->last_gas_resp;
    5067 [ +  - ][ +  - ]:          1 :         else if (wpa_s->prev_gas_resp &&
    5068         [ +  - ]:          1 :                  os_memcmp(addr, wpa_s->prev_gas_addr, ETH_ALEN) == 0 &&
    5069                 :          1 :                  dialog_token == wpa_s->prev_gas_dialog_token)
    5070                 :          1 :                 resp = wpa_s->prev_gas_resp;
    5071                 :            :         else
    5072                 :          0 :                 return -1;
    5073                 :            : 
    5074                 :          7 :         resp_len = wpabuf_len(resp);
    5075                 :          7 :         start = 0;
    5076                 :          7 :         requested_len = resp_len;
    5077                 :            : 
    5078                 :          7 :         pos = os_strchr(pos, ' ');
    5079         [ -  + ]:          7 :         if (pos) {
    5080                 :          0 :                 start = atoi(pos);
    5081         [ #  # ]:          0 :                 if (start > resp_len)
    5082                 :          0 :                         return os_snprintf(buf, buflen, "FAIL-Invalid range");
    5083                 :          0 :                 pos = os_strchr(pos, ',');
    5084         [ #  # ]:          0 :                 if (pos == NULL)
    5085                 :          0 :                         return -1;
    5086                 :          0 :                 pos++;
    5087                 :          0 :                 requested_len = atoi(pos);
    5088         [ #  # ]:          0 :                 if (start + requested_len > resp_len)
    5089                 :          0 :                         return os_snprintf(buf, buflen, "FAIL-Invalid range");
    5090                 :            :         }
    5091                 :            : 
    5092         [ -  + ]:          7 :         if (requested_len * 2 + 1 > buflen)
    5093                 :          0 :                 return os_snprintf(buf, buflen, "FAIL-Too long response");
    5094                 :            : 
    5095                 :          7 :         ret = wpa_snprintf_hex(buf, buflen, wpabuf_head_u8(resp) + start,
    5096                 :            :                                requested_len);
    5097                 :            : 
    5098         [ +  - ]:          7 :         if (start + requested_len == resp_len) {
    5099                 :            :                 /*
    5100                 :            :                  * Free memory by dropping the response after it has been
    5101                 :            :                  * fetched.
    5102                 :            :                  */
    5103         [ +  + ]:          7 :                 if (resp == wpa_s->prev_gas_resp) {
    5104                 :          1 :                         wpabuf_free(wpa_s->prev_gas_resp);
    5105                 :          1 :                         wpa_s->prev_gas_resp = NULL;
    5106                 :            :                 } else {
    5107                 :          6 :                         wpabuf_free(wpa_s->last_gas_resp);
    5108                 :          6 :                         wpa_s->last_gas_resp = NULL;
    5109                 :            :                 }
    5110                 :            :         }
    5111                 :            : 
    5112                 :          7 :         return ret;
    5113                 :            : }
    5114                 :            : #endif /* CONFIG_INTERWORKING */
    5115                 :            : 
    5116                 :            : 
    5117                 :            : #ifdef CONFIG_HS20
    5118                 :            : 
    5119                 :          0 : static int get_hs20_anqp(struct wpa_supplicant *wpa_s, char *dst)
    5120                 :            : {
    5121                 :            :         u8 dst_addr[ETH_ALEN];
    5122                 :            :         int used;
    5123                 :            :         char *pos;
    5124                 :          0 :         u32 subtypes = 0;
    5125                 :            : 
    5126                 :          0 :         used = hwaddr_aton2(dst, dst_addr);
    5127         [ #  # ]:          0 :         if (used < 0)
    5128                 :          0 :                 return -1;
    5129                 :          0 :         pos = dst + used;
    5130                 :            :         for (;;) {
    5131                 :          0 :                 int num = atoi(pos);
    5132 [ #  # ][ #  # ]:          0 :                 if (num <= 0 || num > 31)
    5133                 :          0 :                         return -1;
    5134                 :          0 :                 subtypes |= BIT(num);
    5135                 :          0 :                 pos = os_strchr(pos + 1, ',');
    5136         [ #  # ]:          0 :                 if (pos == NULL)
    5137                 :          0 :                         break;
    5138                 :          0 :                 pos++;
    5139                 :          0 :         }
    5140                 :            : 
    5141         [ #  # ]:          0 :         if (subtypes == 0)
    5142                 :          0 :                 return -1;
    5143                 :            : 
    5144                 :          0 :         return hs20_anqp_send_req(wpa_s, dst_addr, subtypes, NULL, 0);
    5145                 :            : }
    5146                 :            : 
    5147                 :            : 
    5148                 :          1 : static int hs20_nai_home_realm_list(struct wpa_supplicant *wpa_s,
    5149                 :            :                                     const u8 *addr, const char *realm)
    5150                 :            : {
    5151                 :            :         u8 *buf;
    5152                 :            :         size_t rlen, len;
    5153                 :            :         int ret;
    5154                 :            : 
    5155                 :          1 :         rlen = os_strlen(realm);
    5156                 :          1 :         len = 3 + rlen;
    5157                 :          1 :         buf = os_malloc(len);
    5158         [ -  + ]:          1 :         if (buf == NULL)
    5159                 :          0 :                 return -1;
    5160                 :          1 :         buf[0] = 1; /* NAI Home Realm Count */
    5161                 :          1 :         buf[1] = 0; /* Formatted in accordance with RFC 4282 */
    5162                 :          1 :         buf[2] = rlen;
    5163                 :          1 :         os_memcpy(buf + 3, realm, rlen);
    5164                 :            : 
    5165                 :          1 :         ret = hs20_anqp_send_req(wpa_s, addr,
    5166                 :            :                                  BIT(HS20_STYPE_NAI_HOME_REALM_QUERY),
    5167                 :            :                                  buf, len);
    5168                 :            : 
    5169                 :          1 :         os_free(buf);
    5170                 :            : 
    5171                 :          1 :         return ret;
    5172                 :            : }
    5173                 :            : 
    5174                 :            : 
    5175                 :          1 : static int hs20_get_nai_home_realm_list(struct wpa_supplicant *wpa_s,
    5176                 :            :                                         char *dst)
    5177                 :            : {
    5178                 :          1 :         struct wpa_cred *cred = wpa_s->conf->cred;
    5179                 :            :         u8 dst_addr[ETH_ALEN];
    5180                 :            :         int used;
    5181                 :            :         u8 *buf;
    5182                 :            :         size_t len;
    5183                 :            :         int ret;
    5184                 :            : 
    5185                 :          1 :         used = hwaddr_aton2(dst, dst_addr);
    5186         [ -  + ]:          1 :         if (used < 0)
    5187                 :          0 :                 return -1;
    5188                 :            : 
    5189         [ +  + ]:          2 :         while (dst[used] == ' ')
    5190                 :          1 :                 used++;
    5191         [ +  - ]:          1 :         if (os_strncmp(dst + used, "realm=", 6) == 0)
    5192                 :          1 :                 return hs20_nai_home_realm_list(wpa_s, dst_addr,
    5193                 :          1 :                                                 dst + used + 6);
    5194                 :            : 
    5195                 :          0 :         len = os_strlen(dst + used);
    5196                 :            : 
    5197 [ #  # ][ #  # ]:          0 :         if (len == 0 && cred && cred->realm)
                 [ #  # ]
    5198                 :          0 :                 return hs20_nai_home_realm_list(wpa_s, dst_addr, cred->realm);
    5199                 :            : 
    5200                 :            :         if (len % 1)
    5201                 :            :                 return -1;
    5202                 :          0 :         len /= 2;
    5203                 :          0 :         buf = os_malloc(len);
    5204         [ #  # ]:          0 :         if (buf == NULL)
    5205                 :          0 :                 return -1;
    5206         [ #  # ]:          0 :         if (hexstr2bin(dst + used, buf, len) < 0) {
    5207                 :          0 :                 os_free(buf);
    5208                 :          0 :                 return -1;
    5209                 :            :         }
    5210                 :            : 
    5211                 :          0 :         ret = hs20_anqp_send_req(wpa_s, dst_addr,
    5212                 :            :                                  BIT(HS20_STYPE_NAI_HOME_REALM_QUERY),
    5213                 :            :                                  buf, len);
    5214                 :          0 :         os_free(buf);
    5215                 :            : 
    5216                 :          1 :         return ret;
    5217                 :            : }
    5218                 :            : 
    5219                 :            : 
    5220                 :          0 : static int hs20_icon_request(struct wpa_supplicant *wpa_s, char *cmd)
    5221                 :            : {
    5222                 :            :         u8 dst_addr[ETH_ALEN];
    5223                 :            :         int used;
    5224                 :            :         char *icon;
    5225                 :            : 
    5226                 :          0 :         used = hwaddr_aton2(cmd, dst_addr);
    5227         [ #  # ]:          0 :         if (used < 0)
    5228                 :          0 :                 return -1;
    5229                 :            : 
    5230         [ #  # ]:          0 :         while (cmd[used] == ' ')
    5231                 :          0 :                 used++;
    5232                 :          0 :         icon = &cmd[used];
    5233                 :            : 
    5234                 :          0 :         wpa_s->fetch_osu_icon_in_progress = 0;
    5235                 :          0 :         return hs20_anqp_send_req(wpa_s, dst_addr, BIT(HS20_STYPE_ICON_REQUEST),
    5236                 :            :                                   (u8 *) icon, os_strlen(icon));
    5237                 :            : }
    5238                 :            : 
    5239                 :            : #endif /* CONFIG_HS20 */
    5240                 :            : 
    5241                 :            : 
    5242                 :          0 : static int wpa_supplicant_ctrl_iface_sta_autoconnect(
    5243                 :            :         struct wpa_supplicant *wpa_s, char *cmd)
    5244                 :            : {
    5245                 :          0 :         wpa_s->auto_reconnect_disabled = atoi(cmd) == 0 ? 1 : 0;
    5246                 :          0 :         return 0;
    5247                 :            : }
    5248                 :            : 
    5249                 :            : 
    5250                 :            : #ifdef CONFIG_AUTOSCAN
    5251                 :            : 
    5252                 :          0 : static int wpa_supplicant_ctrl_iface_autoscan(struct wpa_supplicant *wpa_s,
    5253                 :            :                                               char *cmd)
    5254                 :            : {
    5255                 :          0 :         enum wpa_states state = wpa_s->wpa_state;
    5256                 :          0 :         char *new_params = NULL;
    5257                 :            : 
    5258         [ #  # ]:          0 :         if (os_strlen(cmd) > 0) {
    5259                 :          0 :                 new_params = os_strdup(cmd);
    5260         [ #  # ]:          0 :                 if (new_params == NULL)
    5261                 :          0 :                         return -1;
    5262                 :            :         }
    5263                 :            : 
    5264                 :          0 :         os_free(wpa_s->conf->autoscan);
    5265                 :          0 :         wpa_s->conf->autoscan = new_params;
    5266                 :            : 
    5267         [ #  # ]:          0 :         if (wpa_s->conf->autoscan == NULL)
    5268                 :          0 :                 autoscan_deinit(wpa_s);
    5269 [ #  # ][ #  # ]:          0 :         else if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
    5270                 :          0 :                 autoscan_init(wpa_s, 1);
    5271         [ #  # ]:          0 :         else if (state == WPA_SCANNING)
    5272                 :          0 :                 wpa_supplicant_reinit_autoscan(wpa_s);
    5273                 :            : 
    5274                 :          0 :         return 0;
    5275                 :            : }
    5276                 :            : 
    5277                 :            : #endif /* CONFIG_AUTOSCAN */
    5278                 :            : 
    5279                 :            : 
    5280                 :            : #ifdef CONFIG_WNM
    5281                 :            : 
    5282                 :          6 : static int wpas_ctrl_iface_wnm_sleep(struct wpa_supplicant *wpa_s, char *cmd)
    5283                 :            : {
    5284                 :            :         int enter;
    5285                 :          6 :         int intval = 0;
    5286                 :            :         char *pos;
    5287                 :            :         int ret;
    5288                 :          6 :         struct wpabuf *tfs_req = NULL;
    5289                 :            : 
    5290         [ +  + ]:          6 :         if (os_strncmp(cmd, "enter", 5) == 0)
    5291                 :          3 :                 enter = 1;
    5292         [ +  - ]:          3 :         else if (os_strncmp(cmd, "exit", 4) == 0)
    5293                 :          3 :                 enter = 0;
    5294                 :            :         else
    5295                 :          0 :                 return -1;
    5296                 :            : 
    5297                 :          6 :         pos = os_strstr(cmd, " interval=");
    5298         [ -  + ]:          6 :         if (pos)
    5299                 :          0 :                 intval = atoi(pos + 10);
    5300                 :            : 
    5301                 :          6 :         pos = os_strstr(cmd, " tfs_req=");
    5302         [ -  + ]:          6 :         if (pos) {
    5303                 :            :                 char *end;
    5304                 :            :                 size_t len;
    5305                 :          0 :                 pos += 9;
    5306                 :          0 :                 end = os_strchr(pos, ' ');
    5307         [ #  # ]:          0 :                 if (end)
    5308                 :          0 :                         len = end - pos;
    5309                 :            :                 else
    5310                 :          0 :                         len = os_strlen(pos);
    5311         [ #  # ]:          0 :                 if (len & 1)
    5312                 :          0 :                         return -1;
    5313                 :          0 :                 len /= 2;
    5314                 :          0 :                 tfs_req = wpabuf_alloc(len);
    5315         [ #  # ]:          0 :                 if (tfs_req == NULL)
    5316                 :          0 :                         return -1;
    5317         [ #  # ]:          0 :                 if (hexstr2bin(pos, wpabuf_put(tfs_req, len), len) < 0) {
    5318                 :          0 :                         wpabuf_free(tfs_req);
    5319                 :          0 :                         return -1;
    5320                 :            :                 }
    5321                 :            :         }
    5322                 :            : 
    5323                 :          6 :         ret = ieee802_11_send_wnmsleep_req(wpa_s, enter ? WNM_SLEEP_MODE_ENTER :
    5324                 :            :                                            WNM_SLEEP_MODE_EXIT, intval,
    5325                 :            :                                            tfs_req);
    5326                 :          6 :         wpabuf_free(tfs_req);
    5327                 :            : 
    5328                 :          6 :         return ret;
    5329                 :            : }
    5330                 :            : 
    5331                 :            : 
    5332                 :          1 : static int wpas_ctrl_iface_wnm_bss_query(struct wpa_supplicant *wpa_s, char *cmd)
    5333                 :            : {
    5334                 :            :         int query_reason;
    5335                 :            : 
    5336                 :          1 :         query_reason = atoi(cmd);
    5337                 :            : 
    5338                 :          1 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: WNM_BSS_QUERY query_reason=%d",
    5339                 :            :                    query_reason);
    5340                 :            : 
    5341                 :          1 :         return wnm_send_bss_transition_mgmt_query(wpa_s, query_reason);
    5342                 :            : }
    5343                 :            : 
    5344                 :            : #endif /* CONFIG_WNM */
    5345                 :            : 
    5346                 :            : 
    5347                 :            : /* Get string representation of channel width */
    5348                 :          0 : static const char * channel_width_name(enum chan_width width)
    5349                 :            : {
    5350   [ #  #  #  #  :          0 :         switch (width) {
                #  #  # ]
    5351                 :            :         case CHAN_WIDTH_20_NOHT:
    5352                 :          0 :                 return "20 MHz (no HT)";
    5353                 :            :         case CHAN_WIDTH_20:
    5354                 :          0 :                 return "20 MHz";
    5355                 :            :         case CHAN_WIDTH_40:
    5356                 :          0 :                 return "40 MHz";
    5357                 :            :         case CHAN_WIDTH_80:
    5358                 :          0 :                 return "80 MHz";
    5359                 :            :         case CHAN_WIDTH_80P80:
    5360                 :          0 :                 return "80+80 MHz";
    5361                 :            :         case CHAN_WIDTH_160:
    5362                 :          0 :                 return "160 MHz";
    5363                 :            :         default:
    5364                 :          0 :                 return "unknown";
    5365                 :            :         }
    5366                 :            : }
    5367                 :            : 
    5368                 :            : 
    5369                 :          0 : static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf,
    5370                 :            :                                       size_t buflen)
    5371                 :            : {
    5372                 :            :         struct wpa_signal_info si;
    5373                 :            :         int ret;
    5374                 :            :         char *pos, *end;
    5375                 :            : 
    5376                 :          0 :         ret = wpa_drv_signal_poll(wpa_s, &si);
    5377         [ #  # ]:          0 :         if (ret)
    5378                 :          0 :                 return -1;
    5379                 :            : 
    5380                 :          0 :         pos = buf;
    5381                 :          0 :         end = buf + buflen;
    5382                 :            : 
    5383                 :          0 :         ret = os_snprintf(pos, end - pos, "RSSI=%d\nLINKSPEED=%d\n"
    5384                 :            :                           "NOISE=%d\nFREQUENCY=%u\n",
    5385                 :          0 :                           si.current_signal, si.current_txrate / 1000,
    5386                 :            :                           si.current_noise, si.frequency);
    5387 [ #  # ][ #  # ]:          0 :         if (ret < 0 || ret > end - pos)
    5388                 :          0 :                 return -1;
    5389                 :          0 :         pos += ret;
    5390                 :            : 
    5391         [ #  # ]:          0 :         if (si.chanwidth != CHAN_WIDTH_UNKNOWN) {
    5392                 :          0 :                 ret = os_snprintf(pos, end - pos, "WIDTH=%s\n",
    5393                 :            :                                   channel_width_name(si.chanwidth));
    5394 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret > end - pos)
    5395                 :          0 :                         return -1;
    5396                 :          0 :                 pos += ret;
    5397                 :            :         }
    5398                 :            : 
    5399 [ #  # ][ #  # ]:          0 :         if (si.center_frq1 > 0 && si.center_frq2 > 0) {
    5400                 :          0 :                 ret = os_snprintf(pos, end - pos,
    5401                 :            :                                   "CENTER_FRQ1=%d\nCENTER_FRQ2=%d\n",
    5402                 :            :                                   si.center_frq1, si.center_frq2);
    5403 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret > end - pos)
    5404                 :          0 :                         return -1;
    5405                 :          0 :                 pos += ret;
    5406                 :            :         }
    5407                 :            : 
    5408         [ #  # ]:          0 :         if (si.avg_signal) {
    5409                 :          0 :                 ret = os_snprintf(pos, end - pos,
    5410                 :            :                                   "AVG_RSSI=%d\n", si.avg_signal);
    5411 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    5412                 :          0 :                         return -1;
    5413                 :          0 :                 pos += ret;
    5414                 :            :         }
    5415                 :            : 
    5416                 :          0 :         return pos - buf;
    5417                 :            : }
    5418                 :            : 
    5419                 :            : 
    5420                 :          0 : static int wpa_supplicant_pktcnt_poll(struct wpa_supplicant *wpa_s, char *buf,
    5421                 :            :                                       size_t buflen)
    5422                 :            : {
    5423                 :            :         struct hostap_sta_driver_data sta;
    5424                 :            :         int ret;
    5425                 :            : 
    5426                 :          0 :         ret = wpa_drv_pktcnt_poll(wpa_s, &sta);
    5427         [ #  # ]:          0 :         if (ret)
    5428                 :          0 :                 return -1;
    5429                 :            : 
    5430                 :          0 :         ret = os_snprintf(buf, buflen, "TXGOOD=%lu\nTXBAD=%lu\nRXGOOD=%lu\n",
    5431                 :            :                           sta.tx_packets, sta.tx_retry_failed, sta.rx_packets);
    5432 [ #  # ][ #  # ]:          0 :         if (ret < 0 || (size_t) ret > buflen)
    5433                 :          0 :                 return -1;
    5434                 :          0 :         return ret;
    5435                 :            : }
    5436                 :            : 
    5437                 :            : 
    5438                 :            : #ifdef ANDROID
    5439                 :            : static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, char *cmd,
    5440                 :            :                                      char *buf, size_t buflen)
    5441                 :            : {
    5442                 :            :         int ret;
    5443                 :            : 
    5444                 :            :         ret = wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen);
    5445                 :            :         if (ret == 0) {
    5446                 :            :                 if (os_strncasecmp(cmd, "COUNTRY", 7) == 0) {
    5447                 :            :                         struct p2p_data *p2p = wpa_s->global->p2p;
    5448                 :            :                         if (p2p) {
    5449                 :            :                                 char country[3];
    5450                 :            :                                 country[0] = cmd[8];
    5451                 :            :                                 country[1] = cmd[9];
    5452                 :            :                                 country[2] = 0x04;
    5453                 :            :                                 p2p_set_country(p2p, country);
    5454                 :            :                         }
    5455                 :            :                 }
    5456                 :            :                 ret = os_snprintf(buf, buflen, "%s\n", "OK");
    5457                 :            :         }
    5458                 :            :         return ret;
    5459                 :            : }
    5460                 :            : #endif /* ANDROID */
    5461                 :            : 
    5462                 :            : 
    5463                 :       1183 : static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
    5464                 :            : {
    5465                 :       1183 :         wpa_dbg(wpa_s, MSG_DEBUG, "Flush all wpa_supplicant state");
    5466                 :            : 
    5467                 :            : #ifdef CONFIG_P2P
    5468                 :       1183 :         wpas_p2p_stop_find(wpa_s);
    5469                 :       1183 :         p2p_ctrl_flush(wpa_s);
    5470                 :       1183 :         wpas_p2p_group_remove(wpa_s, "*");
    5471                 :       1183 :         wpas_p2p_service_flush(wpa_s);
    5472                 :       1183 :         wpa_s->global->p2p_disabled = 0;
    5473                 :       1183 :         wpa_s->global->p2p_per_sta_psk = 0;
    5474                 :       1183 :         wpa_s->conf->num_sec_device_types = 0;
    5475                 :       1183 :         wpa_s->p2p_disable_ip_addr_req = 0;
    5476                 :            : #endif /* CONFIG_P2P */
    5477                 :            : 
    5478                 :            : #ifdef CONFIG_WPS_TESTING
    5479                 :       1183 :         wps_version_number = 0x20;
    5480                 :       1183 :         wps_testing_dummy_cred = 0;
    5481                 :       1183 :         wps_corrupt_pkhash = 0;
    5482                 :            : #endif /* CONFIG_WPS_TESTING */
    5483                 :            : #ifdef CONFIG_WPS
    5484                 :       1183 :         wpa_s->wps_fragment_size = 0;
    5485                 :       1183 :         wpas_wps_cancel(wpa_s);
    5486                 :            : #endif /* CONFIG_WPS */
    5487                 :       1183 :         wpa_s->after_wps = 0;
    5488                 :       1183 :         wpa_s->known_wps_freq = 0;
    5489                 :            : 
    5490                 :            : #ifdef CONFIG_TDLS
    5491                 :            : #ifdef CONFIG_TDLS_TESTING
    5492                 :            :         extern unsigned int tdls_testing;
    5493                 :       1183 :         tdls_testing = 0;
    5494                 :            : #endif /* CONFIG_TDLS_TESTING */
    5495                 :       1183 :         wpa_drv_tdls_oper(wpa_s, TDLS_ENABLE, NULL);
    5496                 :       1183 :         wpa_tdls_enable(wpa_s->wpa, 1);
    5497                 :            : #endif /* CONFIG_TDLS */
    5498                 :            : 
    5499                 :       1183 :         eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
    5500                 :       1183 :         wpa_supplicant_stop_countermeasures(wpa_s, NULL);
    5501                 :            : 
    5502                 :       1183 :         wpa_s->no_keep_alive = 0;
    5503                 :            : 
    5504                 :       1183 :         os_free(wpa_s->disallow_aps_bssid);
    5505                 :       1183 :         wpa_s->disallow_aps_bssid = NULL;
    5506                 :       1183 :         wpa_s->disallow_aps_bssid_count = 0;
    5507                 :       1183 :         os_free(wpa_s->disallow_aps_ssid);
    5508                 :       1183 :         wpa_s->disallow_aps_ssid = NULL;
    5509                 :       1183 :         wpa_s->disallow_aps_ssid_count = 0;
    5510                 :            : 
    5511                 :       1183 :         wpa_s->set_sta_uapsd = 0;
    5512                 :       1183 :         wpa_s->sta_uapsd = 0;
    5513                 :            : 
    5514                 :       1183 :         wpa_drv_radio_disable(wpa_s, 0);
    5515                 :            : 
    5516                 :       1183 :         wpa_bss_flush(wpa_s);
    5517                 :       1183 :         wpa_blacklist_clear(wpa_s);
    5518                 :       1183 :         wpa_s->extra_blacklist_count = 0;
    5519                 :       1183 :         wpa_supplicant_ctrl_iface_remove_network(wpa_s, "all");
    5520                 :       1183 :         wpa_supplicant_ctrl_iface_remove_cred(wpa_s, "all");
    5521                 :       1183 :         wpa_config_flush_blobs(wpa_s->conf);
    5522                 :       1183 :         wpa_s->conf->auto_interworking = 0;
    5523                 :       1183 :         wpa_s->conf->okc = 0;
    5524                 :            : 
    5525                 :       1183 :         wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME, 43200);
    5526                 :       1183 :         wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD, 70);
    5527                 :       1183 :         wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, 60);
    5528                 :       1183 :         eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
    5529                 :            : 
    5530                 :       1183 :         radio_remove_works(wpa_s, NULL, 1);
    5531                 :            : 
    5532                 :       1183 :         wpa_s->next_ssid = NULL;
    5533                 :            : 
    5534                 :            : #ifdef CONFIG_INTERWORKING
    5535                 :       1183 :         hs20_cancel_fetch_osu(wpa_s);
    5536                 :            : #endif /* CONFIG_INTERWORKING */
    5537                 :       1183 : }
    5538                 :            : 
    5539                 :            : 
    5540                 :          2 : static int wpas_ctrl_radio_work_show(struct wpa_supplicant *wpa_s,
    5541                 :            :                                      char *buf, size_t buflen)
    5542                 :            : {
    5543                 :            :         struct wpa_radio_work *work;
    5544                 :            :         char *pos, *end;
    5545                 :            :         struct os_reltime now, diff;
    5546                 :            : 
    5547                 :          2 :         pos = buf;
    5548                 :          2 :         end = buf + buflen;
    5549                 :            : 
    5550                 :          2 :         os_get_reltime(&now);
    5551                 :            : 
    5552         [ +  + ]:          5 :         dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list)
    5553                 :            :         {
    5554                 :            :                 int ret;
    5555                 :            : 
    5556                 :          3 :                 os_reltime_sub(&now, &work->time, &diff);
    5557                 :          9 :                 ret = os_snprintf(pos, end - pos, "%s@%s:%u:%u:%ld.%06ld\n",
    5558                 :          3 :                                   work->type, work->wpa_s->ifname, work->freq,
    5559                 :          3 :                                   work->started, diff.sec, diff.usec);
    5560 [ +  - ][ +  - ]:          3 :                 if (ret < 0 || ret >= end - pos)
    5561                 :            :                         break;
    5562                 :          3 :                 pos += ret;
    5563                 :            :         }
    5564                 :            : 
    5565                 :          2 :         return pos - buf;
    5566                 :            : }
    5567                 :            : 
    5568                 :            : 
    5569                 :          0 : static void wpas_ctrl_radio_work_timeout(void *eloop_ctx, void *timeout_ctx)
    5570                 :            : {
    5571                 :          0 :         struct wpa_radio_work *work = eloop_ctx;
    5572                 :          0 :         struct wpa_external_work *ework = work->ctx;
    5573                 :            : 
    5574                 :          0 :         wpa_dbg(work->wpa_s, MSG_DEBUG,
    5575                 :            :                 "Timing out external radio work %u (%s)",
    5576                 :            :                 ework->id, work->type);
    5577                 :          0 :         wpa_msg(work->wpa_s, MSG_INFO, EXT_RADIO_WORK_TIMEOUT "%u", ework->id);
    5578                 :          0 :         os_free(ework);
    5579                 :          0 :         radio_work_done(work);
    5580                 :          0 : }
    5581                 :            : 
    5582                 :            : 
    5583                 :          2 : static void wpas_ctrl_radio_work_cb(struct wpa_radio_work *work, int deinit)
    5584                 :            : {
    5585                 :          2 :         struct wpa_external_work *ework = work->ctx;
    5586                 :            : 
    5587         [ -  + ]:          2 :         if (deinit) {
    5588         [ #  # ]:          0 :                 if (work->started)
    5589                 :          0 :                         eloop_cancel_timeout(wpas_ctrl_radio_work_timeout,
    5590                 :            :                                              work, NULL);
    5591                 :            : 
    5592                 :          0 :                 os_free(ework);
    5593                 :          2 :                 return;
    5594                 :            :         }
    5595                 :            : 
    5596                 :          2 :         wpa_dbg(work->wpa_s, MSG_DEBUG, "Starting external radio work %u (%s)",
    5597                 :            :                 ework->id, ework->type);
    5598                 :          2 :         wpa_msg(work->wpa_s, MSG_INFO, EXT_RADIO_WORK_START "%u", ework->id);
    5599         [ +  - ]:          2 :         if (!ework->timeout)
    5600                 :          2 :                 ework->timeout = 10;
    5601                 :          2 :         eloop_register_timeout(ework->timeout, 0, wpas_ctrl_radio_work_timeout,
    5602                 :            :                                work, NULL);
    5603                 :            : }
    5604                 :            : 
    5605                 :            : 
    5606                 :          3 : static int wpas_ctrl_radio_work_add(struct wpa_supplicant *wpa_s, char *cmd,
    5607                 :            :                                     char *buf, size_t buflen)
    5608                 :            : {
    5609                 :            :         struct wpa_external_work *ework;
    5610                 :            :         char *pos, *pos2;
    5611                 :            :         size_t type_len;
    5612                 :            :         int ret;
    5613                 :          3 :         unsigned int freq = 0;
    5614                 :            : 
    5615                 :            :         /* format: <name> [freq=<MHz>] [timeout=<seconds>] */
    5616                 :            : 
    5617                 :          3 :         ework = os_zalloc(sizeof(*ework));
    5618         [ -  + ]:          3 :         if (ework == NULL)
    5619                 :          0 :                 return -1;
    5620                 :            : 
    5621                 :          3 :         pos = os_strchr(cmd, ' ');
    5622         [ +  + ]:          3 :         if (pos) {
    5623                 :          1 :                 type_len = pos - cmd;
    5624                 :          1 :                 pos++;
    5625                 :            : 
    5626                 :          1 :                 pos2 = os_strstr(pos, "freq=");
    5627         [ +  - ]:          1 :                 if (pos2)
    5628                 :          1 :                         freq = atoi(pos2 + 5);
    5629                 :            : 
    5630                 :          1 :                 pos2 = os_strstr(pos, "timeout=");
    5631         [ -  + ]:          1 :                 if (pos2)
    5632                 :          0 :                         ework->timeout = atoi(pos2 + 8);
    5633                 :            :         } else {
    5634                 :          2 :                 type_len = os_strlen(cmd);
    5635                 :            :         }
    5636         [ -  + ]:          3 :         if (4 + type_len >= sizeof(ework->type))
    5637                 :          0 :                 type_len = sizeof(ework->type) - 4 - 1;
    5638                 :          3 :         os_strlcpy(ework->type, "ext:", sizeof(ework->type));
    5639                 :          3 :         os_memcpy(ework->type + 4, cmd, type_len);
    5640                 :          3 :         ework->type[4 + type_len] = '\0';
    5641                 :            : 
    5642                 :          3 :         wpa_s->ext_work_id++;
    5643         [ -  + ]:          3 :         if (wpa_s->ext_work_id == 0)
    5644                 :          0 :                 wpa_s->ext_work_id++;
    5645                 :          3 :         ework->id = wpa_s->ext_work_id;
    5646                 :            : 
    5647         [ -  + ]:          3 :         if (radio_add_work(wpa_s, freq, ework->type, 0, wpas_ctrl_radio_work_cb,
    5648                 :            :                            ework) < 0) {
    5649                 :          0 :                 os_free(ework);
    5650                 :          0 :                 return -1;
    5651                 :            :         }
    5652                 :            : 
    5653                 :          3 :         ret = os_snprintf(buf, buflen, "%u", ework->id);
    5654 [ +  - ][ -  + ]:          3 :         if (ret < 0 || (size_t) ret >= buflen)
    5655                 :          0 :                 return -1;
    5656                 :          3 :         return ret;
    5657                 :            : }
    5658                 :            : 
    5659                 :            : 
    5660                 :          3 : static int wpas_ctrl_radio_work_done(struct wpa_supplicant *wpa_s, char *cmd)
    5661                 :            : {
    5662                 :            :         struct wpa_radio_work *work;
    5663                 :          3 :         unsigned int id = atoi(cmd);
    5664                 :            : 
    5665         [ +  - ]:          4 :         dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list)
    5666                 :            :         {
    5667                 :            :                 struct wpa_external_work *ework;
    5668                 :            : 
    5669         [ -  + ]:          4 :                 if (os_strncmp(work->type, "ext:", 4) != 0)
    5670                 :          0 :                         continue;
    5671                 :          4 :                 ework = work->ctx;
    5672 [ +  - ][ +  + ]:          4 :                 if (id && ework->id != id)
    5673                 :          1 :                         continue;
    5674                 :          3 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    5675                 :            :                         "Completed external radio work %u (%s)",
    5676                 :            :                         ework->id, ework->type);
    5677                 :          3 :                 eloop_cancel_timeout(wpas_ctrl_radio_work_timeout, work, NULL);
    5678                 :          3 :                 os_free(ework);
    5679                 :          3 :                 radio_work_done(work);
    5680                 :          3 :                 return 3; /* "OK\n" */
    5681                 :            :         }
    5682                 :            : 
    5683                 :          3 :         return -1;
    5684                 :            : }
    5685                 :            : 
    5686                 :            : 
    5687                 :          8 : static int wpas_ctrl_radio_work(struct wpa_supplicant *wpa_s, char *cmd,
    5688                 :            :                                 char *buf, size_t buflen)
    5689                 :            : {
    5690         [ +  + ]:          8 :         if (os_strcmp(cmd, "show") == 0)
    5691                 :          2 :                 return wpas_ctrl_radio_work_show(wpa_s, buf, buflen);
    5692         [ +  + ]:          6 :         if (os_strncmp(cmd, "add ", 4) == 0)
    5693                 :          3 :                 return wpas_ctrl_radio_work_add(wpa_s, cmd + 4, buf, buflen);
    5694         [ +  - ]:          3 :         if (os_strncmp(cmd, "done ", 5) == 0)
    5695                 :          3 :                 return wpas_ctrl_radio_work_done(wpa_s, cmd + 4);
    5696                 :          8 :         return -1;
    5697                 :            : }
    5698                 :            : 
    5699                 :            : 
    5700                 :         40 : void wpas_ctrl_radio_work_flush(struct wpa_supplicant *wpa_s)
    5701                 :            : {
    5702                 :            :         struct wpa_radio_work *work, *tmp;
    5703                 :            : 
    5704 [ +  - ][ +  + ]:         40 :         if (!wpa_s || !wpa_s->radio)
    5705                 :         40 :                 return;
    5706                 :            : 
    5707         [ -  + ]:         39 :         dl_list_for_each_safe(work, tmp, &wpa_s->radio->work,
    5708                 :            :                               struct wpa_radio_work, list) {
    5709                 :            :                 struct wpa_external_work *ework;
    5710                 :            : 
    5711         [ #  # ]:          0 :                 if (os_strncmp(work->type, "ext:", 4) != 0)
    5712                 :          0 :                         continue;
    5713                 :          0 :                 ework = work->ctx;
    5714         [ #  # ]:          0 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    5715                 :            :                         "Flushing %sexternal radio work %u (%s)",
    5716                 :            :                         work->started ? " started" : "", ework->id,
    5717                 :            :                         ework->type);
    5718         [ #  # ]:          0 :                 if (work->started)
    5719                 :          0 :                         eloop_cancel_timeout(wpas_ctrl_radio_work_timeout,
    5720                 :            :                                              work, NULL);
    5721                 :          0 :                 os_free(ework);
    5722                 :          0 :                 radio_work_done(work);
    5723                 :            :         }
    5724                 :            : }
    5725                 :            : 
    5726                 :            : 
    5727                 :         12 : static void wpas_ctrl_eapol_response(void *eloop_ctx, void *timeout_ctx)
    5728                 :            : {
    5729                 :         12 :         struct wpa_supplicant *wpa_s = eloop_ctx;
    5730                 :         12 :         eapol_sm_notify_ctrl_response(wpa_s->eapol);
    5731                 :         12 : }
    5732                 :            : 
    5733                 :            : 
    5734                 :         46 : static int set_scan_freqs(struct wpa_supplicant *wpa_s, char *val)
    5735                 :            : {
    5736                 :         46 :         int *freqs = NULL;
    5737                 :            : 
    5738                 :         46 :         freqs = freq_range_to_channel_list(wpa_s, val);
    5739         [ -  + ]:         46 :         if (freqs == NULL)
    5740                 :          0 :                 return -1;
    5741                 :            : 
    5742                 :         46 :         os_free(wpa_s->manual_scan_freqs);
    5743                 :         46 :         wpa_s->manual_scan_freqs = freqs;
    5744                 :            : 
    5745                 :         46 :         return 0;
    5746                 :            : }
    5747                 :            : 
    5748                 :            : 
    5749                 :         54 : static void wpas_ctrl_scan(struct wpa_supplicant *wpa_s, char *params,
    5750                 :            :                            char *reply, int reply_size, int *reply_len)
    5751                 :            : {
    5752                 :            :         char *pos;
    5753                 :            : 
    5754         [ -  + ]:         54 :         if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
    5755                 :          0 :                 *reply_len = -1;
    5756                 :          0 :                 return;
    5757                 :            :         }
    5758                 :            : 
    5759                 :         54 :         wpa_s->manual_scan_passive = 0;
    5760                 :         54 :         wpa_s->manual_scan_use_id = 0;
    5761                 :         54 :         wpa_s->manual_scan_only_new = 0;
    5762                 :            : 
    5763         [ +  + ]:         54 :         if (params) {
    5764         [ +  + ]:         51 :                 if (os_strncasecmp(params, "TYPE=ONLY", 9) == 0)
    5765                 :          7 :                         wpa_s->scan_res_handler = scan_only_handler;
    5766                 :            : 
    5767                 :         51 :                 pos = os_strstr(params, "freq=");
    5768 [ +  + ][ -  + ]:         51 :                 if (pos && set_scan_freqs(wpa_s, pos + 5) < 0) {
    5769                 :          0 :                         *reply_len = -1;
    5770                 :          0 :                         return;
    5771                 :            :                 }
    5772                 :            : 
    5773                 :         51 :                 pos = os_strstr(params, "passive=");
    5774         [ +  + ]:         51 :                 if (pos)
    5775                 :          6 :                         wpa_s->manual_scan_passive = !!atoi(pos + 8);
    5776                 :            : 
    5777                 :         51 :                 pos = os_strstr(params, "use_id=");
    5778         [ +  + ]:         51 :                 if (pos)
    5779                 :         11 :                         wpa_s->manual_scan_use_id = atoi(pos + 7);
    5780                 :            : 
    5781                 :         51 :                 pos = os_strstr(params, "only_new=1");
    5782         [ -  + ]:         51 :                 if (pos)
    5783                 :          0 :                         wpa_s->manual_scan_only_new = 1;
    5784                 :            :         } else {
    5785                 :          3 :                 os_free(wpa_s->manual_scan_freqs);
    5786                 :          3 :                 wpa_s->manual_scan_freqs = NULL;
    5787         [ -  + ]:          3 :                 if (wpa_s->scan_res_handler == scan_only_handler)
    5788                 :          0 :                         wpa_s->scan_res_handler = NULL;
    5789                 :            :         }
    5790                 :            : 
    5791 [ +  - ][ +  - ]:         54 :         if (!wpa_s->sched_scanning && !wpa_s->scanning &&
                 [ +  + ]
    5792         [ +  - ]:          8 :             ((wpa_s->wpa_state <= WPA_SCANNING) ||
    5793                 :          8 :              (wpa_s->wpa_state == WPA_COMPLETED))) {
    5794                 :         54 :                 wpa_s->normal_scans = 0;
    5795                 :         54 :                 wpa_s->scan_req = MANUAL_SCAN_REQ;
    5796                 :         54 :                 wpa_s->after_wps = 0;
    5797                 :         54 :                 wpa_s->known_wps_freq = 0;
    5798                 :         54 :                 wpa_supplicant_req_scan(wpa_s, 0, 0);
    5799         [ +  + ]:         65 :                 if (wpa_s->manual_scan_use_id) {
    5800                 :         11 :                         wpa_s->manual_scan_id++;
    5801                 :         11 :                         wpa_dbg(wpa_s, MSG_DEBUG, "Assigned scan id %u",
    5802                 :            :                                 wpa_s->manual_scan_id);
    5803                 :         11 :                         *reply_len = os_snprintf(reply, reply_size, "%u\n",
    5804                 :            :                                                  wpa_s->manual_scan_id);
    5805                 :            :                 }
    5806         [ #  # ]:          0 :         } else if (wpa_s->sched_scanning) {
    5807                 :          0 :                 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to allow requested full scan to proceed");
    5808                 :          0 :                 wpa_supplicant_cancel_sched_scan(wpa_s);
    5809                 :          0 :                 wpa_s->scan_req = MANUAL_SCAN_REQ;
    5810                 :          0 :                 wpa_supplicant_req_scan(wpa_s, 0, 0);
    5811         [ #  # ]:          0 :                 if (wpa_s->manual_scan_use_id) {
    5812                 :          0 :                         wpa_s->manual_scan_id++;
    5813                 :          0 :                         *reply_len = os_snprintf(reply, reply_size, "%u\n",
    5814                 :            :                                                  wpa_s->manual_scan_id);
    5815                 :          0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "Assigned scan id %u",
    5816                 :            :                                 wpa_s->manual_scan_id);
    5817                 :            :                 }
    5818                 :            :         } else {
    5819                 :          0 :                 wpa_printf(MSG_DEBUG, "Ongoing scan action - reject new request");
    5820                 :         54 :                 *reply_len = os_snprintf(reply, reply_size, "FAIL-BUSY\n");
    5821                 :            :         }
    5822                 :            : }
    5823                 :            : 
    5824                 :            : 
    5825                 :      24765 : char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
    5826                 :            :                                          char *buf, size_t *resp_len)
    5827                 :            : {
    5828                 :            :         char *reply;
    5829                 :      24765 :         const int reply_size = 4096;
    5830                 :            :         int reply_len;
    5831                 :            : 
    5832 [ +  + ][ +  + ]:      24765 :         if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 ||
    5833                 :      24753 :             os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
    5834         [ +  - ]:       3362 :                 if (wpa_debug_show_keys)
    5835                 :       1681 :                         wpa_dbg(wpa_s, MSG_DEBUG,
    5836                 :            :                                 "Control interface command '%s'", buf);
    5837                 :            :                 else
    5838         [ #  # ]:          0 :                         wpa_dbg(wpa_s, MSG_DEBUG,
    5839                 :            :                                 "Control interface command '%s [REMOVED]'",
    5840                 :            :                                 os_strncmp(buf, WPA_CTRL_RSP,
    5841                 :            :                                            os_strlen(WPA_CTRL_RSP)) == 0 ?
    5842                 :            :                                 WPA_CTRL_RSP : "SET_NETWORK");
    5843 [ +  + ][ +  + ]:      23084 :         } else if (os_strncmp(buf, "WPS_NFC_TAG_READ", 16) == 0 ||
    5844         [ -  + ]:      23043 :                    os_strncmp(buf, "NFC_REPORT_HANDOVER", 19) == 0 ||
    5845                 :      23043 :                    os_strncmp(buf, "NFC_RX_HANDOVER_SEL", 19) == 0) {
    5846                 :         41 :                 wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface",
    5847                 :            :                                       (const u8 *) buf, os_strlen(buf));
    5848                 :            :         } else {
    5849                 :      23043 :                 int level = MSG_DEBUG;
    5850         [ +  + ]:      23043 :                 if (os_strcmp(buf, "PING") == 0)
    5851                 :       1175 :                         level = MSG_EXCESSIVE;
    5852                 :      23043 :                 wpa_dbg(wpa_s, level, "Control interface command '%s'", buf);
    5853                 :            :         }
    5854                 :            : 
    5855                 :      24765 :         reply = os_malloc(reply_size);
    5856         [ -  + ]:      24765 :         if (reply == NULL) {
    5857                 :          0 :                 *resp_len = 1;
    5858                 :          0 :                 return NULL;
    5859                 :            :         }
    5860                 :            : 
    5861                 :      24765 :         os_memcpy(reply, "OK\n", 3);
    5862                 :      24765 :         reply_len = 3;
    5863                 :            : 
    5864         [ +  + ]:      24765 :         if (os_strcmp(buf, "PING") == 0) {
    5865                 :       1175 :                 os_memcpy(reply, "PONG\n", 5);
    5866                 :       1175 :                 reply_len = 5;
    5867         [ -  + ]:      23590 :         } else if (os_strcmp(buf, "IFNAME") == 0) {
    5868                 :          0 :                 reply_len = os_strlen(wpa_s->ifname);
    5869                 :          0 :                 os_memcpy(reply, wpa_s->ifname, reply_len);
    5870         [ +  + ]:      23590 :         } else if (os_strncmp(buf, "RELOG", 5) == 0) {
    5871         [ -  + ]:       1179 :                 if (wpa_debug_reopen_file() < 0)
    5872                 :          0 :                         reply_len = -1;
    5873         [ +  + ]:      22411 :         } else if (os_strncmp(buf, "NOTE ", 5) == 0) {
    5874                 :       2334 :                 wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
    5875         [ -  + ]:      20077 :         } else if (os_strcmp(buf, "MIB") == 0) {
    5876                 :          0 :                 reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
    5877         [ #  # ]:          0 :                 if (reply_len >= 0) {
    5878                 :            :                         int res;
    5879                 :          0 :                         res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len,
    5880                 :          0 :                                                reply_size - reply_len);
    5881         [ #  # ]:          0 :                         if (res < 0)
    5882                 :          0 :                                 reply_len = -1;
    5883                 :            :                         else
    5884                 :          0 :                                 reply_len += res;
    5885                 :            :                 }
    5886         [ +  + ]:      20077 :         } else if (os_strncmp(buf, "STATUS", 6) == 0) {
    5887                 :       1710 :                 reply_len = wpa_supplicant_ctrl_iface_status(
    5888                 :            :                         wpa_s, buf + 6, reply, reply_size);
    5889         [ +  + ]:      18367 :         } else if (os_strcmp(buf, "PMKSA") == 0) {
    5890                 :         11 :                 reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, reply,
    5891                 :            :                                                     reply_size);
    5892         [ +  + ]:      18356 :         } else if (os_strncmp(buf, "SET ", 4) == 0) {
    5893         [ +  + ]:      10842 :                 if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4))
    5894                 :          6 :                         reply_len = -1;
    5895         [ +  + ]:       7514 :         } else if (os_strncmp(buf, "GET ", 4) == 0) {
    5896                 :          3 :                 reply_len = wpa_supplicant_ctrl_iface_get(wpa_s, buf + 4,
    5897                 :            :                                                           reply, reply_size);
    5898         [ +  + ]:       7511 :         } else if (os_strcmp(buf, "LOGON") == 0) {
    5899                 :          1 :                 eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
    5900         [ +  + ]:       7510 :         } else if (os_strcmp(buf, "LOGOFF") == 0) {
    5901                 :          1 :                 eapol_sm_notify_logoff(wpa_s->eapol, TRUE);
    5902         [ +  + ]:       7509 :         } else if (os_strcmp(buf, "REASSOCIATE") == 0) {
    5903         [ -  + ]:          1 :                 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
    5904                 :          0 :                         reply_len = -1;
    5905                 :            :                 else
    5906                 :          1 :                         wpas_request_connection(wpa_s);
    5907         [ +  + ]:       7508 :         } else if (os_strcmp(buf, "RECONNECT") == 0) {
    5908         [ -  + ]:          1 :                 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
    5909                 :          0 :                         reply_len = -1;
    5910         [ +  - ]:          1 :                 else if (wpa_s->disconnected)
    5911                 :          1 :                         wpas_request_connection(wpa_s);
    5912                 :            : #ifdef IEEE8021X_EAPOL
    5913         [ +  + ]:       7507 :         } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) {
    5914         [ +  + ]:          2 :                 if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
    5915                 :          1 :                         reply_len = -1;
    5916                 :            : #endif /* IEEE8021X_EAPOL */
    5917                 :            : #ifdef CONFIG_PEERKEY
    5918         [ +  + ]:       7505 :         } else if (os_strncmp(buf, "STKSTART ", 9) == 0) {
    5919         [ +  + ]:          3 :                 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9))
    5920                 :          2 :                         reply_len = -1;
    5921                 :            : #endif /* CONFIG_PEERKEY */
    5922                 :            : #ifdef CONFIG_IEEE80211R
    5923         [ +  + ]:       7502 :         } else if (os_strncmp(buf, "FT_DS ", 6) == 0) {
    5924         [ -  + ]:          6 :                 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6))
    5925                 :          0 :                         reply_len = -1;
    5926                 :            : #endif /* CONFIG_IEEE80211R */
    5927                 :            : #ifdef CONFIG_WPS
    5928         [ +  + ]:       7496 :         } else if (os_strcmp(buf, "WPS_PBC") == 0) {
    5929                 :         18 :                 int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL);
    5930         [ -  + ]:         18 :                 if (res == -2) {
    5931                 :          0 :                         os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
    5932                 :          0 :                         reply_len = 17;
    5933         [ -  + ]:         18 :                 } else if (res)
    5934                 :          0 :                         reply_len = -1;
    5935         [ -  + ]:       7478 :         } else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) {
    5936                 :          0 :                 int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8);
    5937         [ #  # ]:          0 :                 if (res == -2) {
    5938                 :          0 :                         os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
    5939                 :          0 :                         reply_len = 17;
    5940         [ #  # ]:          0 :                 } else if (res)
    5941                 :          0 :                         reply_len = -1;
    5942         [ +  + ]:       7478 :         } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
    5943                 :         41 :                 reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8,
    5944                 :            :                                                               reply,
    5945                 :            :                                                               reply_size);
    5946         [ +  + ]:       7437 :         } else if (os_strncmp(buf, "WPS_CHECK_PIN ", 14) == 0) {
    5947                 :          5 :                 reply_len = wpa_supplicant_ctrl_iface_wps_check_pin(
    5948                 :            :                         wpa_s, buf + 14, reply, reply_size);
    5949         [ +  + ]:       7432 :         } else if (os_strcmp(buf, "WPS_CANCEL") == 0) {
    5950         [ +  + ]:          7 :                 if (wpas_wps_cancel(wpa_s))
    5951                 :          1 :                         reply_len = -1;
    5952                 :            : #ifdef CONFIG_WPS_NFC
    5953         [ +  + ]:       7425 :         } else if (os_strcmp(buf, "WPS_NFC") == 0) {
    5954         [ -  + ]:          3 :                 if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s, NULL))
    5955                 :          0 :                         reply_len = -1;
    5956         [ -  + ]:       7422 :         } else if (os_strncmp(buf, "WPS_NFC ", 8) == 0) {
    5957         [ #  # ]:          0 :                 if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s, buf + 8))
    5958                 :          0 :                         reply_len = -1;
    5959         [ +  + ]:       7422 :         } else if (os_strncmp(buf, "WPS_NFC_CONFIG_TOKEN ", 21) == 0) {
    5960                 :          1 :                 reply_len = wpa_supplicant_ctrl_iface_wps_nfc_config_token(
    5961                 :            :                         wpa_s, buf + 21, reply, reply_size);
    5962         [ +  + ]:       7421 :         } else if (os_strncmp(buf, "WPS_NFC_TOKEN ", 14) == 0) {
    5963                 :          8 :                 reply_len = wpa_supplicant_ctrl_iface_wps_nfc_token(
    5964                 :            :                         wpa_s, buf + 14, reply, reply_size);
    5965         [ +  + ]:       7413 :         } else if (os_strncmp(buf, "WPS_NFC_TAG_READ ", 17) == 0) {
    5966         [ -  + ]:         12 :                 if (wpa_supplicant_ctrl_iface_wps_nfc_tag_read(wpa_s,
    5967                 :            :                                                                buf + 17))
    5968                 :          0 :                         reply_len = -1;
    5969         [ +  + ]:       7401 :         } else if (os_strncmp(buf, "NFC_GET_HANDOVER_REQ ", 21) == 0) {
    5970                 :         17 :                 reply_len = wpas_ctrl_nfc_get_handover_req(
    5971                 :            :                         wpa_s, buf + 21, reply, reply_size);
    5972         [ +  + ]:       7384 :         } else if (os_strncmp(buf, "NFC_GET_HANDOVER_SEL ", 21) == 0) {
    5973                 :         17 :                 reply_len = wpas_ctrl_nfc_get_handover_sel(
    5974                 :            :                         wpa_s, buf + 21, reply, reply_size);
    5975         [ -  + ]:       7367 :         } else if (os_strncmp(buf, "NFC_RX_HANDOVER_SEL ", 20) == 0) {
    5976         [ #  # ]:          0 :                 if (wpas_ctrl_nfc_rx_handover_sel(wpa_s, buf + 20))
    5977                 :          0 :                         reply_len = -1;
    5978         [ +  + ]:       7367 :         } else if (os_strncmp(buf, "NFC_REPORT_HANDOVER ", 20) == 0) {
    5979         [ -  + ]:         29 :                 if (wpas_ctrl_nfc_report_handover(wpa_s, buf + 20))
    5980                 :          0 :                         reply_len = -1;
    5981                 :            : #endif /* CONFIG_WPS_NFC */
    5982         [ +  + ]:       7338 :         } else if (os_strncmp(buf, "WPS_REG ", 8) == 0) {
    5983         [ -  + ]:         28 :                 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8))
    5984                 :          0 :                         reply_len = -1;
    5985                 :            : #ifdef CONFIG_AP
    5986         [ +  + ]:       7310 :         } else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) {
    5987                 :          6 :                 reply_len = wpa_supplicant_ctrl_iface_wps_ap_pin(
    5988                 :            :                         wpa_s, buf + 11, reply, reply_size);
    5989                 :            : #endif /* CONFIG_AP */
    5990                 :            : #ifdef CONFIG_WPS_ER
    5991         [ -  + ]:       7304 :         } else if (os_strcmp(buf, "WPS_ER_START") == 0) {
    5992         [ #  # ]:          0 :                 if (wpas_wps_er_start(wpa_s, NULL))
    5993                 :          0 :                         reply_len = -1;
    5994         [ +  + ]:       7304 :         } else if (os_strncmp(buf, "WPS_ER_START ", 13) == 0) {
    5995         [ -  + ]:          9 :                 if (wpas_wps_er_start(wpa_s, buf + 13))
    5996                 :          0 :                         reply_len = -1;
    5997         [ +  + ]:       7295 :         } else if (os_strcmp(buf, "WPS_ER_STOP") == 0) {
    5998         [ -  + ]:       1176 :                 if (wpas_wps_er_stop(wpa_s))
    5999                 :          0 :                         reply_len = -1;
    6000         [ +  + ]:       6119 :         } else if (os_strncmp(buf, "WPS_ER_PIN ", 11) == 0) {
    6001         [ -  + ]:          4 :                 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s, buf + 11))
    6002                 :          0 :                         reply_len = -1;
    6003         [ +  + ]:       6115 :         } else if (os_strncmp(buf, "WPS_ER_PBC ", 11) == 0) {
    6004                 :          1 :                 int ret = wpas_wps_er_pbc(wpa_s, buf + 11);
    6005         [ -  + ]:          1 :                 if (ret == -2) {
    6006                 :          0 :                         os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
    6007                 :          0 :                         reply_len = 17;
    6008         [ -  + ]:          1 :                 } else if (ret == -3) {
    6009                 :          0 :                         os_memcpy(reply, "FAIL-UNKNOWN-UUID\n", 18);
    6010                 :          0 :                         reply_len = 18;
    6011         [ -  + ]:          1 :                 } else if (ret == -4) {
    6012                 :          0 :                         os_memcpy(reply, "FAIL-NO-AP-SETTINGS\n", 20);
    6013                 :          0 :                         reply_len = 20;
    6014         [ -  + ]:          1 :                 } else if (ret)
    6015                 :          0 :                         reply_len = -1;
    6016         [ +  + ]:       6114 :         } else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) {
    6017         [ -  + ]:          1 :                 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13))
    6018                 :          0 :                         reply_len = -1;
    6019         [ +  + ]:       6113 :         } else if (os_strncmp(buf, "WPS_ER_SET_CONFIG ", 18) == 0) {
    6020         [ -  + ]:          8 :                 if (wpa_supplicant_ctrl_iface_wps_er_set_config(wpa_s,
    6021                 :            :                                                                 buf + 18))
    6022                 :          0 :                         reply_len = -1;
    6023         [ +  + ]:       6105 :         } else if (os_strncmp(buf, "WPS_ER_CONFIG ", 14) == 0) {
    6024         [ -  + ]:          1 :                 if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14))
    6025                 :          0 :                         reply_len = -1;
    6026                 :            : #ifdef CONFIG_WPS_NFC
    6027         [ +  + ]:       6104 :         } else if (os_strncmp(buf, "WPS_ER_NFC_CONFIG_TOKEN ", 24) == 0) {
    6028                 :          1 :                 reply_len = wpa_supplicant_ctrl_iface_wps_er_nfc_config_token(
    6029                 :            :                         wpa_s, buf + 24, reply, reply_size);
    6030                 :            : #endif /* CONFIG_WPS_NFC */
    6031                 :            : #endif /* CONFIG_WPS_ER */
    6032                 :            : #endif /* CONFIG_WPS */
    6033                 :            : #ifdef CONFIG_IBSS_RSN
    6034         [ -  + ]:       6103 :         } else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) {
    6035         [ #  # ]:          0 :                 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9))
    6036                 :          0 :                         reply_len = -1;
    6037                 :            : #endif /* CONFIG_IBSS_RSN */
    6038                 :            : #ifdef CONFIG_P2P
    6039         [ +  + ]:       6103 :         } else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) {
    6040         [ -  + ]:        129 :                 if (p2p_ctrl_find(wpa_s, buf + 9))
    6041                 :          0 :                         reply_len = -1;
    6042         [ +  + ]:       5974 :         } else if (os_strcmp(buf, "P2P_FIND") == 0) {
    6043         [ -  + ]:         22 :                 if (p2p_ctrl_find(wpa_s, ""))
    6044                 :          0 :                         reply_len = -1;
    6045         [ +  + ]:       5952 :         } else if (os_strcmp(buf, "P2P_STOP_FIND") == 0) {
    6046                 :         12 :                 wpas_p2p_stop_find(wpa_s);
    6047         [ +  + ]:       5940 :         } else if (os_strncmp(buf, "P2P_CONNECT ", 12) == 0) {
    6048                 :        118 :                 reply_len = p2p_ctrl_connect(wpa_s, buf + 12, reply,
    6049                 :            :                                              reply_size);
    6050         [ -  + ]:       5822 :         } else if (os_strncmp(buf, "P2P_LISTEN ", 11) == 0) {
    6051         [ #  # ]:          0 :                 if (p2p_ctrl_listen(wpa_s, buf + 11))
    6052                 :          0 :                         reply_len = -1;
    6053         [ +  + ]:       5822 :         } else if (os_strcmp(buf, "P2P_LISTEN") == 0) {
    6054         [ -  + ]:        127 :                 if (p2p_ctrl_listen(wpa_s, ""))
    6055                 :          0 :                         reply_len = -1;
    6056         [ +  + ]:       5695 :         } else if (os_strncmp(buf, "P2P_GROUP_REMOVE ", 17) == 0) {
    6057         [ +  + ]:        100 :                 if (wpas_p2p_group_remove(wpa_s, buf + 17))
    6058                 :         13 :                         reply_len = -1;
    6059         [ +  + ]:       5595 :         } else if (os_strcmp(buf, "P2P_GROUP_ADD") == 0) {
    6060         [ -  + ]:         17 :                 if (wpas_p2p_group_add(wpa_s, 0, 0, 0, 0))
    6061                 :          0 :                         reply_len = -1;
    6062         [ +  + ]:       5578 :         } else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) {
    6063         [ -  + ]:         15 :                 if (p2p_ctrl_group_add(wpa_s, buf + 14))
    6064                 :          0 :                         reply_len = -1;
    6065         [ +  + ]:       5563 :         } else if (os_strncmp(buf, "P2P_PROV_DISC ", 14) == 0) {
    6066         [ +  + ]:          8 :                 if (p2p_ctrl_prov_disc(wpa_s, buf + 14))
    6067                 :          2 :                         reply_len = -1;
    6068         [ -  + ]:       5555 :         } else if (os_strcmp(buf, "P2P_GET_PASSPHRASE") == 0) {
    6069                 :          0 :                 reply_len = p2p_get_passphrase(wpa_s, reply, reply_size);
    6070         [ +  + ]:       5555 :         } else if (os_strncmp(buf, "P2P_SERV_DISC_REQ ", 18) == 0) {
    6071                 :         23 :                 reply_len = p2p_ctrl_serv_disc_req(wpa_s, buf + 18, reply,
    6072                 :            :                                                    reply_size);
    6073         [ +  + ]:       5532 :         } else if (os_strncmp(buf, "P2P_SERV_DISC_CANCEL_REQ ", 25) == 0) {
    6074         [ +  + ]:          5 :                 if (p2p_ctrl_serv_disc_cancel_req(wpa_s, buf + 25) < 0)
    6075                 :          1 :                         reply_len = -1;
    6076         [ -  + ]:       5527 :         } else if (os_strncmp(buf, "P2P_SERV_DISC_RESP ", 19) == 0) {
    6077         [ #  # ]:          0 :                 if (p2p_ctrl_serv_disc_resp(wpa_s, buf + 19) < 0)
    6078                 :          0 :                         reply_len = -1;
    6079         [ -  + ]:       5527 :         } else if (os_strcmp(buf, "P2P_SERVICE_UPDATE") == 0) {
    6080                 :          0 :                 wpas_p2p_sd_service_update(wpa_s);
    6081         [ -  + ]:       5527 :         } else if (os_strncmp(buf, "P2P_SERV_DISC_EXTERNAL ", 23) == 0) {
    6082         [ #  # ]:          0 :                 if (p2p_ctrl_serv_disc_external(wpa_s, buf + 23) < 0)
    6083                 :          0 :                         reply_len = -1;
    6084         [ -  + ]:       5527 :         } else if (os_strcmp(buf, "P2P_SERVICE_FLUSH") == 0) {
    6085                 :          0 :                 wpas_p2p_service_flush(wpa_s);
    6086         [ +  + ]:       5527 :         } else if (os_strncmp(buf, "P2P_SERVICE_ADD ", 16) == 0) {
    6087         [ -  + ]:        335 :                 if (p2p_ctrl_service_add(wpa_s, buf + 16) < 0)
    6088                 :          0 :                         reply_len = -1;
    6089         [ -  + ]:       5192 :         } else if (os_strncmp(buf, "P2P_SERVICE_DEL ", 16) == 0) {
    6090         [ #  # ]:          0 :                 if (p2p_ctrl_service_del(wpa_s, buf + 16) < 0)
    6091                 :          0 :                         reply_len = -1;
    6092         [ +  + ]:       5192 :         } else if (os_strncmp(buf, "P2P_REJECT ", 11) == 0) {
    6093         [ -  + ]:          1 :                 if (p2p_ctrl_reject(wpa_s, buf + 11) < 0)
    6094                 :          0 :                         reply_len = -1;
    6095         [ +  + ]:       5191 :         } else if (os_strncmp(buf, "P2P_INVITE ", 11) == 0) {
    6096         [ -  + ]:         11 :                 if (p2p_ctrl_invite(wpa_s, buf + 11) < 0)
    6097                 :          0 :                         reply_len = -1;
    6098         [ +  + ]:       5180 :         } else if (os_strncmp(buf, "P2P_PEER ", 9) == 0) {
    6099                 :        346 :                 reply_len = p2p_ctrl_peer(wpa_s, buf + 9, reply,
    6100                 :            :                                               reply_size);
    6101         [ +  + ]:       4834 :         } else if (os_strncmp(buf, "P2P_SET ", 8) == 0) {
    6102         [ -  + ]:         12 :                 if (p2p_ctrl_set(wpa_s, buf + 8) < 0)
    6103                 :          0 :                         reply_len = -1;
    6104         [ +  + ]:       4822 :         } else if (os_strcmp(buf, "P2P_FLUSH") == 0) {
    6105                 :         17 :                 p2p_ctrl_flush(wpa_s);
    6106         [ -  + ]:       4805 :         } else if (os_strncmp(buf, "P2P_UNAUTHORIZE ", 16) == 0) {
    6107         [ #  # ]:          0 :                 if (wpas_p2p_unauthorize(wpa_s, buf + 16) < 0)
    6108                 :          0 :                         reply_len = -1;
    6109         [ -  + ]:       4805 :         } else if (os_strcmp(buf, "P2P_CANCEL") == 0) {
    6110         [ #  # ]:          0 :                 if (wpas_p2p_cancel(wpa_s))
    6111                 :          0 :                         reply_len = -1;
    6112         [ +  + ]:       4805 :         } else if (os_strncmp(buf, "P2P_PRESENCE_REQ ", 17) == 0) {
    6113         [ -  + ]:          1 :                 if (p2p_ctrl_presence_req(wpa_s, buf + 17) < 0)
    6114                 :          0 :                         reply_len = -1;
    6115         [ -  + ]:       4804 :         } else if (os_strcmp(buf, "P2P_PRESENCE_REQ") == 0) {
    6116         [ #  # ]:          0 :                 if (p2p_ctrl_presence_req(wpa_s, "") < 0)
    6117                 :          0 :                         reply_len = -1;
    6118         [ -  + ]:       4804 :         } else if (os_strncmp(buf, "P2P_EXT_LISTEN ", 15) == 0) {
    6119         [ #  # ]:          0 :                 if (p2p_ctrl_ext_listen(wpa_s, buf + 15) < 0)
    6120                 :          0 :                         reply_len = -1;
    6121         [ -  + ]:       4804 :         } else if (os_strcmp(buf, "P2P_EXT_LISTEN") == 0) {
    6122         [ #  # ]:          0 :                 if (p2p_ctrl_ext_listen(wpa_s, "") < 0)
    6123                 :          0 :                         reply_len = -1;
    6124         [ +  + ]:       4804 :         } else if (os_strncmp(buf, "P2P_REMOVE_CLIENT ", 18) == 0) {
    6125         [ -  + ]:          4 :                 if (p2p_ctrl_remove_client(wpa_s, buf + 18) < 0)
    6126                 :          0 :                         reply_len = -1;
    6127                 :            : #endif /* CONFIG_P2P */
    6128                 :            : #ifdef CONFIG_WIFI_DISPLAY
    6129         [ +  + ]:       4800 :         } else if (os_strncmp(buf, "WFD_SUBELEM_SET ", 16) == 0) {
    6130         [ -  + ]:          3 :                 if (wifi_display_subelem_set(wpa_s->global, buf + 16) < 0)
    6131                 :          0 :                         reply_len = -1;
    6132         [ +  + ]:       4797 :         } else if (os_strncmp(buf, "WFD_SUBELEM_GET ", 16) == 0) {
    6133                 :          2 :                 reply_len = wifi_display_subelem_get(wpa_s->global, buf + 16,
    6134                 :            :                                                      reply, reply_size);
    6135                 :            : #endif /* CONFIG_WIFI_DISPLAY */
    6136                 :            : #ifdef CONFIG_INTERWORKING
    6137         [ +  + ]:       4795 :         } else if (os_strcmp(buf, "FETCH_ANQP") == 0) {
    6138         [ -  + ]:          5 :                 if (interworking_fetch_anqp(wpa_s) < 0)
    6139                 :          0 :                         reply_len = -1;
    6140         [ -  + ]:       4790 :         } else if (os_strcmp(buf, "STOP_FETCH_ANQP") == 0) {
    6141                 :          0 :                 interworking_stop_fetch_anqp(wpa_s);
    6142         [ +  + ]:       4790 :         } else if (os_strcmp(buf, "INTERWORKING_SELECT") == 0) {
    6143         [ -  + ]:          1 :                 if (ctrl_interworking_select(wpa_s, NULL) < 0)
    6144                 :          0 :                         reply_len = -1;
    6145         [ +  + ]:       4789 :         } else if (os_strncmp(buf, "INTERWORKING_SELECT ", 20) == 0) {
    6146         [ -  + ]:        108 :                 if (ctrl_interworking_select(wpa_s, buf + 20) < 0)
    6147                 :          0 :                         reply_len = -1;
    6148         [ +  + ]:       4681 :         } else if (os_strncmp(buf, "INTERWORKING_CONNECT ", 21) == 0) {
    6149         [ +  + ]:         33 :                 if (ctrl_interworking_connect(wpa_s, buf + 21) < 0)
    6150                 :          1 :                         reply_len = -1;
    6151         [ +  + ]:       4648 :         } else if (os_strncmp(buf, "ANQP_GET ", 9) == 0) {
    6152         [ -  + ]:         18 :                 if (get_anqp(wpa_s, buf + 9) < 0)
    6153                 :          0 :                         reply_len = -1;
    6154         [ +  + ]:       4630 :         } else if (os_strncmp(buf, "GAS_REQUEST ", 12) == 0) {
    6155         [ -  + ]:          7 :                 if (gas_request(wpa_s, buf + 12) < 0)
    6156                 :          0 :                         reply_len = -1;
    6157         [ +  + ]:       4623 :         } else if (os_strncmp(buf, "GAS_RESPONSE_GET ", 17) == 0) {
    6158                 :          7 :                 reply_len = gas_response_get(wpa_s, buf + 17, reply,
    6159                 :            :                                              reply_size);
    6160                 :            : #endif /* CONFIG_INTERWORKING */
    6161                 :            : #ifdef CONFIG_HS20
    6162         [ -  + ]:       4616 :         } else if (os_strncmp(buf, "HS20_ANQP_GET ", 14) == 0) {
    6163         [ #  # ]:          0 :                 if (get_hs20_anqp(wpa_s, buf + 14) < 0)
    6164                 :          0 :                         reply_len = -1;
    6165         [ +  + ]:       4616 :         } else if (os_strncmp(buf, "HS20_GET_NAI_HOME_REALM_LIST ", 29) == 0) {
    6166         [ -  + ]:          1 :                 if (hs20_get_nai_home_realm_list(wpa_s, buf + 29) < 0)
    6167                 :          0 :                         reply_len = -1;
    6168         [ -  + ]:       4615 :         } else if (os_strncmp(buf, "HS20_ICON_REQUEST ", 18) == 0) {
    6169         [ #  # ]:          0 :                 if (hs20_icon_request(wpa_s, buf + 18) < 0)
    6170                 :          0 :                         reply_len = -1;
    6171         [ +  + ]:       4615 :         } else if (os_strcmp(buf, "FETCH_OSU") == 0) {
    6172         [ -  + ]:          1 :                 if (hs20_fetch_osu(wpa_s) < 0)
    6173                 :          0 :                         reply_len = -1;
    6174         [ -  + ]:       4614 :         } else if (os_strcmp(buf, "CANCEL_FETCH_OSU") == 0) {
    6175                 :          0 :                 hs20_cancel_fetch_osu(wpa_s);
    6176                 :            : #endif /* CONFIG_HS20 */
    6177         [ +  + ]:       4614 :         } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0)
    6178                 :            :         {
    6179         [ -  + ]:         12 :                 if (wpa_supplicant_ctrl_iface_ctrl_rsp(
    6180                 :            :                             wpa_s, buf + os_strlen(WPA_CTRL_RSP)))
    6181                 :          0 :                         reply_len = -1;
    6182                 :            :                 else {
    6183                 :            :                         /*
    6184                 :            :                          * Notify response from timeout to allow the control
    6185                 :            :                          * interface response to be sent first.
    6186                 :            :                          */
    6187                 :         12 :                         eloop_register_timeout(0, 0, wpas_ctrl_eapol_response,
    6188                 :            :                                                wpa_s, NULL);
    6189                 :            :                 }
    6190         [ -  + ]:       4602 :         } else if (os_strcmp(buf, "RECONFIGURE") == 0) {
    6191         [ #  # ]:          0 :                 if (wpa_supplicant_reload_configuration(wpa_s))
    6192                 :          0 :                         reply_len = -1;
    6193         [ -  + ]:       4602 :         } else if (os_strcmp(buf, "TERMINATE") == 0) {
    6194                 :          0 :                 wpa_supplicant_terminate_proc(wpa_s->global);
    6195         [ -  + ]:       4602 :         } else if (os_strncmp(buf, "BSSID ", 6) == 0) {
    6196         [ #  # ]:          0 :                 if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6))
    6197                 :          0 :                         reply_len = -1;
    6198         [ -  + ]:       4602 :         } else if (os_strncmp(buf, "BLACKLIST", 9) == 0) {
    6199                 :          0 :                 reply_len = wpa_supplicant_ctrl_iface_blacklist(
    6200                 :            :                         wpa_s, buf + 9, reply, reply_size);
    6201         [ -  + ]:       4602 :         } else if (os_strncmp(buf, "LOG_LEVEL", 9) == 0) {
    6202                 :          0 :                 reply_len = wpa_supplicant_ctrl_iface_log_level(
    6203                 :            :                         wpa_s, buf + 9, reply, reply_size);
    6204         [ +  + ]:       4602 :         } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) {
    6205                 :          7 :                 reply_len = wpa_supplicant_ctrl_iface_list_networks(
    6206                 :            :                         wpa_s, reply, reply_size);
    6207         [ +  + ]:       4595 :         } else if (os_strcmp(buf, "DISCONNECT") == 0) {
    6208                 :            : #ifdef CONFIG_SME
    6209                 :         15 :                 wpa_s->sme.prev_bssid_set = 0;
    6210                 :            : #endif /* CONFIG_SME */
    6211                 :         15 :                 wpa_s->reassociate = 0;
    6212                 :         15 :                 wpa_s->disconnected = 1;
    6213                 :         15 :                 wpa_supplicant_cancel_sched_scan(wpa_s);
    6214                 :         15 :                 wpa_supplicant_cancel_scan(wpa_s);
    6215                 :         15 :                 wpa_supplicant_deauthenticate(wpa_s,
    6216                 :            :                                               WLAN_REASON_DEAUTH_LEAVING);
    6217         [ +  + ]:       4580 :         } else if (os_strcmp(buf, "SCAN") == 0) {
    6218                 :          3 :                 wpas_ctrl_scan(wpa_s, NULL, reply, reply_size, &reply_len);
    6219         [ +  + ]:       4577 :         } else if (os_strncmp(buf, "SCAN ", 5) == 0) {
    6220                 :         51 :                 wpas_ctrl_scan(wpa_s, buf + 5, reply, reply_size, &reply_len);
    6221         [ -  + ]:       4526 :         } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) {
    6222                 :          0 :                 reply_len = wpa_supplicant_ctrl_iface_scan_results(
    6223                 :            :                         wpa_s, reply, reply_size);
    6224         [ +  + ]:       4526 :         } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) {
    6225         [ -  + ]:        325 :                 if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15))
    6226                 :          0 :                         reply_len = -1;
    6227         [ +  + ]:       4201 :         } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) {
    6228         [ -  + ]:          3 :                 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15))
    6229                 :          0 :                         reply_len = -1;
    6230         [ -  + ]:       4198 :         } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) {
    6231         [ #  # ]:          0 :                 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16))
    6232                 :          0 :                         reply_len = -1;
    6233         [ +  + ]:       4198 :         } else if (os_strcmp(buf, "ADD_NETWORK") == 0) {
    6234                 :        327 :                 reply_len = wpa_supplicant_ctrl_iface_add_network(
    6235                 :            :                         wpa_s, reply, reply_size);
    6236         [ +  + ]:       3871 :         } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) {
    6237         [ -  + ]:        151 :                 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15))
    6238                 :          0 :                         reply_len = -1;
    6239         [ +  + ]:       3720 :         } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
    6240         [ +  + ]:       1669 :                 if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12))
    6241                 :         28 :                         reply_len = -1;
    6242         [ +  + ]:       2051 :         } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
    6243                 :         34 :                 reply_len = wpa_supplicant_ctrl_iface_get_network(
    6244                 :            :                         wpa_s, buf + 12, reply, reply_size);
    6245         [ -  + ]:       2017 :         } else if (os_strcmp(buf, "LIST_CREDS") == 0) {
    6246                 :          0 :                 reply_len = wpa_supplicant_ctrl_iface_list_creds(
    6247                 :            :                         wpa_s, reply, reply_size);
    6248         [ +  + ]:       2017 :         } else if (os_strcmp(buf, "ADD_CRED") == 0) {
    6249                 :         93 :                 reply_len = wpa_supplicant_ctrl_iface_add_cred(
    6250                 :            :                         wpa_s, reply, reply_size);
    6251         [ +  + ]:       1924 :         } else if (os_strncmp(buf, "REMOVE_CRED ", 12) == 0) {
    6252         [ +  + ]:         38 :                 if (wpa_supplicant_ctrl_iface_remove_cred(wpa_s, buf + 12))
    6253                 :          1 :                         reply_len = -1;
    6254         [ +  + ]:       1886 :         } else if (os_strncmp(buf, "SET_CRED ", 9) == 0) {
    6255         [ +  + ]:        403 :                 if (wpa_supplicant_ctrl_iface_set_cred(wpa_s, buf + 9))
    6256                 :         13 :                         reply_len = -1;
    6257                 :            : #ifndef CONFIG_NO_CONFIG_WRITE
    6258         [ -  + ]:       1483 :         } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
    6259         [ #  # ]:          0 :                 if (wpa_supplicant_ctrl_iface_save_config(wpa_s))
    6260                 :          0 :                         reply_len = -1;
    6261                 :            : #endif /* CONFIG_NO_CONFIG_WRITE */
    6262         [ +  + ]:       1483 :         } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
    6263                 :          5 :                 reply_len = wpa_supplicant_ctrl_iface_get_capability(
    6264                 :            :                         wpa_s, buf + 15, reply, reply_size);
    6265         [ -  + ]:       1478 :         } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) {
    6266         [ #  # ]:          0 :                 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8))
    6267                 :          0 :                         reply_len = -1;
    6268         [ -  + ]:       1478 :         } else if (os_strncmp(buf, "SCAN_INTERVAL ", 14) == 0) {
    6269         [ #  # ]:          0 :                 if (wpa_supplicant_ctrl_iface_scan_interval(wpa_s, buf + 14))
    6270                 :          0 :                         reply_len = -1;
    6271         [ -  + ]:       1478 :         } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
    6272                 :          0 :                 reply_len = wpa_supplicant_global_iface_list(
    6273                 :            :                         wpa_s->global, reply, reply_size);
    6274         [ -  + ]:       1478 :         } else if (os_strcmp(buf, "INTERFACES") == 0) {
    6275                 :          0 :                 reply_len = wpa_supplicant_global_iface_interfaces(
    6276                 :            :                         wpa_s->global, reply, reply_size);
    6277         [ +  + ]:       1478 :         } else if (os_strncmp(buf, "BSS ", 4) == 0) {
    6278                 :        116 :                 reply_len = wpa_supplicant_ctrl_iface_bss(
    6279                 :            :                         wpa_s, buf + 4, reply, reply_size);
    6280                 :            : #ifdef CONFIG_AP
    6281         [ +  + ]:       1362 :         } else if (os_strcmp(buf, "STA-FIRST") == 0) {
    6282                 :          1 :                 reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
    6283         [ +  + ]:       1361 :         } else if (os_strncmp(buf, "STA ", 4) == 0) {
    6284                 :          1 :                 reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply,
    6285                 :            :                                               reply_size);
    6286         [ +  + ]:       1360 :         } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
    6287                 :          2 :                 reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
    6288                 :            :                                                    reply_size);
    6289         [ +  + ]:       1358 :         } else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) {
    6290         [ -  + ]:          1 :                 if (ap_ctrl_iface_sta_deauthenticate(wpa_s, buf + 15))
    6291                 :          0 :                         reply_len = -1;
    6292         [ +  + ]:       1357 :         } else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) {
    6293         [ -  + ]:          1 :                 if (ap_ctrl_iface_sta_disassociate(wpa_s, buf + 13))
    6294                 :          0 :                         reply_len = -1;
    6295         [ +  + ]:       1356 :         } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
    6296         [ +  - ]:          1 :                 if (ap_ctrl_iface_chanswitch(wpa_s, buf + 12))
    6297                 :          1 :                         reply_len = -1;
    6298                 :            : #endif /* CONFIG_AP */
    6299         [ -  + ]:       1355 :         } else if (os_strcmp(buf, "SUSPEND") == 0) {
    6300                 :          0 :                 wpas_notify_suspend(wpa_s->global);
    6301         [ -  + ]:       1355 :         } else if (os_strcmp(buf, "RESUME") == 0) {
    6302                 :          0 :                 wpas_notify_resume(wpa_s->global);
    6303         [ -  + ]:       1355 :         } else if (os_strcmp(buf, "DROP_SA") == 0) {
    6304                 :          0 :                 wpa_supplicant_ctrl_iface_drop_sa(wpa_s);
    6305         [ +  + ]:       1355 :         } else if (os_strncmp(buf, "ROAM ", 5) == 0) {
    6306         [ -  + ]:         20 :                 if (wpa_supplicant_ctrl_iface_roam(wpa_s, buf + 5))
    6307                 :          0 :                         reply_len = -1;
    6308         [ -  + ]:       1335 :         } else if (os_strncmp(buf, "STA_AUTOCONNECT ", 16) == 0) {
    6309         [ #  # ]:          0 :                 if (wpa_supplicant_ctrl_iface_sta_autoconnect(wpa_s, buf + 16))
    6310                 :          0 :                         reply_len = -1;
    6311         [ -  + ]:       1335 :         } else if (os_strncmp(buf, "BSS_EXPIRE_AGE ", 15) == 0) {
    6312         [ #  # ]:          0 :                 if (wpa_supplicant_ctrl_iface_bss_expire_age(wpa_s, buf + 15))
    6313                 :          0 :                         reply_len = -1;
    6314         [ -  + ]:       1335 :         } else if (os_strncmp(buf, "BSS_EXPIRE_COUNT ", 17) == 0) {
    6315         [ #  # ]:          0 :                 if (wpa_supplicant_ctrl_iface_bss_expire_count(wpa_s,
    6316                 :            :                                                                buf + 17))
    6317                 :          0 :                         reply_len = -1;
    6318         [ +  + ]:       1335 :         } else if (os_strncmp(buf, "BSS_FLUSH ", 10) == 0) {
    6319         [ -  + ]:         81 :                 if (wpa_supplicant_ctrl_iface_bss_flush(wpa_s, buf + 10))
    6320                 :          0 :                         reply_len = -1;
    6321                 :            : #ifdef CONFIG_TDLS
    6322         [ +  + ]:       1254 :         } else if (os_strncmp(buf, "TDLS_DISCOVER ", 14) == 0) {
    6323         [ +  - ]:          2 :                 if (wpa_supplicant_ctrl_iface_tdls_discover(wpa_s, buf + 14))
    6324                 :          2 :                         reply_len = -1;
    6325         [ +  + ]:       1252 :         } else if (os_strncmp(buf, "TDLS_SETUP ", 11) == 0) {
    6326         [ -  + ]:         21 :                 if (wpa_supplicant_ctrl_iface_tdls_setup(wpa_s, buf + 11))
    6327                 :          0 :                         reply_len = -1;
    6328         [ +  + ]:       1231 :         } else if (os_strncmp(buf, "TDLS_TEARDOWN ", 14) == 0) {
    6329         [ -  + ]:          8 :                 if (wpa_supplicant_ctrl_iface_tdls_teardown(wpa_s, buf + 14))
    6330                 :          0 :                         reply_len = -1;
    6331                 :            : #endif /* CONFIG_TDLS */
    6332         [ -  + ]:       1223 :         } else if (os_strncmp(buf, "SIGNAL_POLL", 11) == 0) {
    6333                 :          0 :                 reply_len = wpa_supplicant_signal_poll(wpa_s, reply,
    6334                 :            :                                                        reply_size);
    6335         [ -  + ]:       1223 :         } else if (os_strncmp(buf, "PKTCNT_POLL", 11) == 0) {
    6336                 :          0 :                 reply_len = wpa_supplicant_pktcnt_poll(wpa_s, reply,
    6337                 :            :                                                        reply_size);
    6338                 :            : #ifdef CONFIG_AUTOSCAN
    6339         [ -  + ]:       1223 :         } else if (os_strncmp(buf, "AUTOSCAN ", 9) == 0) {
    6340         [ #  # ]:          0 :                 if (wpa_supplicant_ctrl_iface_autoscan(wpa_s, buf + 9))
    6341                 :          0 :                         reply_len = -1;
    6342                 :            : #endif /* CONFIG_AUTOSCAN */
    6343                 :            : #ifdef ANDROID
    6344                 :            :         } else if (os_strncmp(buf, "DRIVER ", 7) == 0) {
    6345                 :            :                 reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply,
    6346                 :            :                                                       reply_size);
    6347                 :            : #endif /* ANDROID */
    6348         [ +  + ]:       1223 :         } else if (os_strcmp(buf, "REAUTHENTICATE") == 0) {
    6349                 :         25 :                 pmksa_cache_clear_current(wpa_s->wpa);
    6350                 :         25 :                 eapol_sm_request_reauth(wpa_s->eapol);
    6351                 :            : #ifdef CONFIG_WNM
    6352         [ +  + ]:       1198 :         } else if (os_strncmp(buf, "WNM_SLEEP ", 10) == 0) {
    6353         [ -  + ]:          6 :                 if (wpas_ctrl_iface_wnm_sleep(wpa_s, buf + 10))
    6354                 :          0 :                         reply_len = -1;
    6355         [ +  + ]:       1192 :         } else if (os_strncmp(buf, "WNM_BSS_QUERY ", 10) == 0) {
    6356         [ -  + ]:          1 :                 if (wpas_ctrl_iface_wnm_bss_query(wpa_s, buf + 10))
    6357                 :          0 :                                 reply_len = -1;
    6358                 :            : #endif /* CONFIG_WNM */
    6359         [ +  + ]:       1191 :         } else if (os_strcmp(buf, "FLUSH") == 0) {
    6360                 :       1183 :                 wpa_supplicant_ctrl_iface_flush(wpa_s);
    6361         [ +  - ]:          8 :         } else if (os_strncmp(buf, "RADIO_WORK ", 11) == 0) {
    6362                 :          8 :                 reply_len = wpas_ctrl_radio_work(wpa_s, buf + 11, reply,
    6363                 :            :                                                  reply_size);
    6364                 :            :         } else {
    6365                 :          0 :                 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
    6366                 :          0 :                 reply_len = 16;
    6367                 :            :         }
    6368                 :            : 
    6369         [ +  + ]:      24765 :         if (reply_len < 0) {
    6370                 :        187 :                 os_memcpy(reply, "FAIL\n", 5);
    6371                 :        187 :                 reply_len = 5;
    6372                 :            :         }
    6373                 :            : 
    6374                 :      24765 :         *resp_len = reply_len;
    6375                 :      24765 :         return reply;
    6376                 :            : }
    6377                 :            : 
    6378                 :            : 
    6379                 :         13 : static int wpa_supplicant_global_iface_add(struct wpa_global *global,
    6380                 :            :                                            char *cmd)
    6381                 :            : {
    6382                 :            :         struct wpa_interface iface;
    6383                 :            :         char *pos;
    6384                 :            : 
    6385                 :            :         /*
    6386                 :            :          * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
    6387                 :            :          * TAB<bridge_ifname>
    6388                 :            :          */
    6389                 :         13 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd);
    6390                 :            : 
    6391                 :         13 :         os_memset(&iface, 0, sizeof(iface));
    6392                 :            : 
    6393                 :            :         do {
    6394                 :         13 :                 iface.ifname = pos = cmd;
    6395                 :         13 :                 pos = os_strchr(pos, '\t');
    6396         [ +  - ]:         13 :                 if (pos)
    6397                 :         13 :                         *pos++ = '\0';
    6398         [ -  + ]:         13 :                 if (iface.ifname[0] == '\0')
    6399                 :          0 :                         return -1;
    6400         [ -  + ]:         13 :                 if (pos == NULL)
    6401                 :          0 :                         break;
    6402                 :            : 
    6403                 :         13 :                 iface.confname = pos;
    6404                 :         13 :                 pos = os_strchr(pos, '\t');
    6405         [ +  - ]:         13 :                 if (pos)
    6406                 :         13 :                         *pos++ = '\0';
    6407         [ +  - ]:         13 :                 if (iface.confname[0] == '\0')
    6408                 :         13 :                         iface.confname = NULL;
    6409         [ -  + ]:         13 :                 if (pos == NULL)
    6410                 :          0 :                         break;
    6411                 :            : 
    6412                 :         13 :                 iface.driver = pos;
    6413                 :         13 :                 pos = os_strchr(pos, '\t');
    6414         [ +  - ]:         13 :                 if (pos)
    6415                 :         13 :                         *pos++ = '\0';
    6416         [ -  + ]:         13 :                 if (iface.driver[0] == '\0')
    6417                 :          0 :                         iface.driver = NULL;
    6418         [ -  + ]:         13 :                 if (pos == NULL)
    6419                 :          0 :                         break;
    6420                 :            : 
    6421                 :         13 :                 iface.ctrl_interface = pos;
    6422                 :         13 :                 pos = os_strchr(pos, '\t');
    6423         [ +  + ]:         13 :                 if (pos)
    6424                 :          9 :                         *pos++ = '\0';
    6425         [ -  + ]:         13 :                 if (iface.ctrl_interface[0] == '\0')
    6426                 :          0 :                         iface.ctrl_interface = NULL;
    6427         [ +  + ]:         13 :                 if (pos == NULL)
    6428                 :          4 :                         break;
    6429                 :            : 
    6430                 :          9 :                 iface.driver_param = pos;
    6431                 :          9 :                 pos = os_strchr(pos, '\t');
    6432         [ -  + ]:          9 :                 if (pos)
    6433                 :          0 :                         *pos++ = '\0';
    6434         [ -  + ]:          9 :                 if (iface.driver_param[0] == '\0')
    6435                 :          0 :                         iface.driver_param = NULL;
    6436         [ +  - ]:          9 :                 if (pos == NULL)
    6437                 :          9 :                         break;
    6438                 :            : 
    6439                 :          0 :                 iface.bridge_ifname = pos;
    6440                 :          0 :                 pos = os_strchr(pos, '\t');
    6441         [ #  # ]:          0 :                 if (pos)
    6442                 :          0 :                         *pos++ = '\0';
    6443         [ #  # ]:          0 :                 if (iface.bridge_ifname[0] == '\0')
    6444                 :          0 :                         iface.bridge_ifname = NULL;
    6445         [ #  # ]:          0 :                 if (pos == NULL)
    6446                 :          0 :                         break;
    6447                 :            :         } while (0);
    6448                 :            : 
    6449         [ -  + ]:         13 :         if (wpa_supplicant_get_iface(global, iface.ifname))
    6450                 :          0 :                 return -1;
    6451                 :            : 
    6452         [ +  + ]:         13 :         return wpa_supplicant_add_iface(global, &iface) ? 0 : -1;
    6453                 :            : }
    6454                 :            : 
    6455                 :            : 
    6456                 :        390 : static int wpa_supplicant_global_iface_remove(struct wpa_global *global,
    6457                 :            :                                               char *cmd)
    6458                 :            : {
    6459                 :            :         struct wpa_supplicant *wpa_s;
    6460                 :            : 
    6461                 :        390 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd);
    6462                 :            : 
    6463                 :        390 :         wpa_s = wpa_supplicant_get_iface(global, cmd);
    6464         [ +  + ]:        390 :         if (wpa_s == NULL)
    6465                 :        378 :                 return -1;
    6466                 :        390 :         return wpa_supplicant_remove_iface(global, wpa_s, 0);
    6467                 :            : }
    6468                 :            : 
    6469                 :            : 
    6470                 :          0 : static void wpa_free_iface_info(struct wpa_interface_info *iface)
    6471                 :            : {
    6472                 :            :         struct wpa_interface_info *prev;
    6473                 :            : 
    6474         [ #  # ]:          0 :         while (iface) {
    6475                 :          0 :                 prev = iface;
    6476                 :          0 :                 iface = iface->next;
    6477                 :            : 
    6478                 :          0 :                 os_free(prev->ifname);
    6479                 :          0 :                 os_free(prev->desc);
    6480                 :          0 :                 os_free(prev);
    6481                 :            :         }
    6482                 :          0 : }
    6483                 :            : 
    6484                 :            : 
    6485                 :          0 : static int wpa_supplicant_global_iface_list(struct wpa_global *global,
    6486                 :            :                                             char *buf, int len)
    6487                 :            : {
    6488                 :            :         int i, res;
    6489                 :          0 :         struct wpa_interface_info *iface = NULL, *last = NULL, *tmp;
    6490                 :            :         char *pos, *end;
    6491                 :            : 
    6492         [ #  # ]:          0 :         for (i = 0; wpa_drivers[i]; i++) {
    6493                 :          0 :                 struct wpa_driver_ops *drv = wpa_drivers[i];
    6494         [ #  # ]:          0 :                 if (drv->get_interfaces == NULL)
    6495                 :          0 :                         continue;
    6496                 :          0 :                 tmp = drv->get_interfaces(global->drv_priv[i]);
    6497         [ #  # ]:          0 :                 if (tmp == NULL)
    6498                 :          0 :                         continue;
    6499                 :            : 
    6500         [ #  # ]:          0 :                 if (last == NULL)
    6501                 :          0 :                         iface = last = tmp;
    6502                 :            :                 else
    6503                 :          0 :                         last->next = tmp;
    6504         [ #  # ]:          0 :                 while (last->next)
    6505                 :          0 :                         last = last->next;
    6506                 :            :         }
    6507                 :            : 
    6508                 :          0 :         pos = buf;
    6509                 :          0 :         end = buf + len;
    6510         [ #  # ]:          0 :         for (tmp = iface; tmp; tmp = tmp->next) {
    6511         [ #  # ]:          0 :                 res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n",
    6512                 :            :                                   tmp->drv_name, tmp->ifname,
    6513                 :          0 :                                   tmp->desc ? tmp->desc : "");
    6514 [ #  # ][ #  # ]:          0 :                 if (res < 0 || res >= end - pos) {
    6515                 :          0 :                         *pos = '\0';
    6516                 :          0 :                         break;
    6517                 :            :                 }
    6518                 :          0 :                 pos += res;
    6519                 :            :         }
    6520                 :            : 
    6521                 :          0 :         wpa_free_iface_info(iface);
    6522                 :            : 
    6523                 :          0 :         return pos - buf;
    6524                 :            : }
    6525                 :            : 
    6526                 :            : 
    6527                 :          0 : static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
    6528                 :            :                                                   char *buf, int len)
    6529                 :            : {
    6530                 :            :         int res;
    6531                 :            :         char *pos, *end;
    6532                 :            :         struct wpa_supplicant *wpa_s;
    6533                 :            : 
    6534                 :          0 :         wpa_s = global->ifaces;
    6535                 :          0 :         pos = buf;
    6536                 :          0 :         end = buf + len;
    6537                 :            : 
    6538         [ #  # ]:          0 :         while (wpa_s) {
    6539                 :          0 :                 res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname);
    6540 [ #  # ][ #  # ]:          0 :                 if (res < 0 || res >= end - pos) {
    6541                 :          0 :                         *pos = '\0';
    6542                 :          0 :                         break;
    6543                 :            :                 }
    6544                 :          0 :                 pos += res;
    6545                 :          0 :                 wpa_s = wpa_s->next;
    6546                 :            :         }
    6547                 :          0 :         return pos - buf;
    6548                 :            : }
    6549                 :            : 
    6550                 :            : 
    6551                 :          0 : static char * wpas_global_ctrl_iface_ifname(struct wpa_global *global,
    6552                 :            :                                             const char *ifname,
    6553                 :            :                                             char *cmd, size_t *resp_len)
    6554                 :            : {
    6555                 :            :         struct wpa_supplicant *wpa_s;
    6556                 :            : 
    6557         [ #  # ]:          0 :         for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
    6558         [ #  # ]:          0 :                 if (os_strcmp(ifname, wpa_s->ifname) == 0)
    6559                 :          0 :                         break;
    6560                 :            :         }
    6561                 :            : 
    6562         [ #  # ]:          0 :         if (wpa_s == NULL) {
    6563                 :          0 :                 char *resp = os_strdup("FAIL-NO-IFNAME-MATCH\n");
    6564         [ #  # ]:          0 :                 if (resp)
    6565                 :          0 :                         *resp_len = os_strlen(resp);
    6566                 :            :                 else
    6567                 :          0 :                         *resp_len = 1;
    6568                 :          0 :                 return resp;
    6569                 :            :         }
    6570                 :            : 
    6571                 :          0 :         return wpa_supplicant_ctrl_iface_process(wpa_s, cmd, resp_len);
    6572                 :            : }
    6573                 :            : 
    6574                 :            : 
    6575                 :       1306 : static char * wpas_global_ctrl_iface_redir_p2p(struct wpa_global *global,
    6576                 :            :                                                char *buf, size_t *resp_len)
    6577                 :            : {
    6578                 :            : #ifdef CONFIG_P2P
    6579                 :            :         static const char * cmd[] = {
    6580                 :            :                 "LIST_NETWORKS",
    6581                 :            :                 "SAVE_CONFIG",
    6582                 :            :                 "P2P_FIND",
    6583                 :            :                 "P2P_STOP_FIND",
    6584                 :            :                 "P2P_LISTEN",
    6585                 :            :                 "P2P_GROUP_ADD",
    6586                 :            :                 "P2P_GET_PASSPHRASE",
    6587                 :            :                 "P2P_SERVICE_UPDATE",
    6588                 :            :                 "P2P_SERVICE_FLUSH",
    6589                 :            :                 "P2P_FLUSH",
    6590                 :            :                 "P2P_CANCEL",
    6591                 :            :                 "P2P_PRESENCE_REQ",
    6592                 :            :                 "P2P_EXT_LISTEN",
    6593                 :            :                 NULL
    6594                 :            :         };
    6595                 :            :         static const char * prefix[] = {
    6596                 :            : #ifdef ANDROID
    6597                 :            :                 "DRIVER ",
    6598                 :            : #endif /* ANDROID */
    6599                 :            :                 "GET_NETWORK ",
    6600                 :            :                 "REMOVE_NETWORK ",
    6601                 :            :                 "SET ",
    6602                 :            :                 "P2P_FIND ",
    6603                 :            :                 "P2P_CONNECT ",
    6604                 :            :                 "P2P_LISTEN ",
    6605                 :            :                 "P2P_GROUP_REMOVE ",
    6606                 :            :                 "P2P_GROUP_ADD ",
    6607                 :            :                 "P2P_PROV_DISC ",
    6608                 :            :                 "P2P_SERV_DISC_REQ ",
    6609                 :            :                 "P2P_SERV_DISC_CANCEL_REQ ",
    6610                 :            :                 "P2P_SERV_DISC_RESP ",
    6611                 :            :                 "P2P_SERV_DISC_EXTERNAL ",
    6612                 :            :                 "P2P_SERVICE_ADD ",
    6613                 :            :                 "P2P_SERVICE_DEL ",
    6614                 :            :                 "P2P_REJECT ",
    6615                 :            :                 "P2P_INVITE ",
    6616                 :            :                 "P2P_PEER ",
    6617                 :            :                 "P2P_SET ",
    6618                 :            :                 "P2P_UNAUTHORIZE ",
    6619                 :            :                 "P2P_PRESENCE_REQ ",
    6620                 :            :                 "P2P_EXT_LISTEN ",
    6621                 :            :                 "P2P_REMOVE_CLIENT ",
    6622                 :            :                 NULL
    6623                 :            :         };
    6624                 :       1306 :         int found = 0;
    6625                 :            :         int i;
    6626                 :            : 
    6627         [ +  + ]:       1306 :         if (global->p2p_init_wpa_s == NULL)
    6628                 :        391 :                 return NULL;
    6629                 :            : 
    6630 [ +  + ][ +  + ]:      11388 :         for (i = 0; !found && cmd[i]; i++) {
    6631         [ +  + ]:      10473 :                 if (os_strcmp(buf, cmd[i]) == 0)
    6632                 :        173 :                         found = 1;
    6633                 :            :         }
    6634                 :            : 
    6635 [ +  + ][ +  + ]:       9771 :         for (i = 0; !found && prefix[i]; i++) {
    6636         [ +  + ]:       8856 :                 if (os_strncmp(buf, prefix[i], os_strlen(prefix[i])) == 0)
    6637                 :        726 :                         found = 1;
    6638                 :            :         }
    6639                 :            : 
    6640         [ +  + ]:        915 :         if (found)
    6641                 :        899 :                 return wpa_supplicant_ctrl_iface_process(global->p2p_init_wpa_s,
    6642                 :            :                                                          buf, resp_len);
    6643                 :            : #endif /* CONFIG_P2P */
    6644                 :       1306 :         return NULL;
    6645                 :            : }
    6646                 :            : 
    6647                 :            : 
    6648                 :        407 : static char * wpas_global_ctrl_iface_redir_wfd(struct wpa_global *global,
    6649                 :            :                                                char *buf, size_t *resp_len)
    6650                 :            : {
    6651                 :            : #ifdef CONFIG_WIFI_DISPLAY
    6652         [ +  + ]:        407 :         if (global->p2p_init_wpa_s == NULL)
    6653                 :        391 :                 return NULL;
    6654 [ +  - ][ -  + ]:         16 :         if (os_strncmp(buf, "WFD_SUBELEM_SET ", 16) == 0 ||
    6655                 :         16 :             os_strncmp(buf, "WFD_SUBELEM_GET ", 16) == 0)
    6656                 :          0 :                 return wpa_supplicant_ctrl_iface_process(global->p2p_init_wpa_s,
    6657                 :            :                                                          buf, resp_len);
    6658                 :            : #endif /* CONFIG_WIFI_DISPLAY */
    6659                 :        407 :         return NULL;
    6660                 :            : }
    6661                 :            : 
    6662                 :            : 
    6663                 :       1306 : static char * wpas_global_ctrl_iface_redir(struct wpa_global *global,
    6664                 :            :                                            char *buf, size_t *resp_len)
    6665                 :            : {
    6666                 :            :         char *ret;
    6667                 :            : 
    6668                 :       1306 :         ret = wpas_global_ctrl_iface_redir_p2p(global, buf, resp_len);
    6669         [ +  + ]:       1306 :         if (ret)
    6670                 :        899 :                 return ret;
    6671                 :            : 
    6672                 :        407 :         ret = wpas_global_ctrl_iface_redir_wfd(global, buf, resp_len);
    6673         [ -  + ]:        407 :         if (ret)
    6674                 :          0 :                 return ret;
    6675                 :            : 
    6676                 :       1306 :         return NULL;
    6677                 :            : }
    6678                 :            : 
    6679                 :            : 
    6680                 :          0 : static int wpas_global_ctrl_iface_set(struct wpa_global *global, char *cmd)
    6681                 :            : {
    6682                 :            :         char *value;
    6683                 :            : 
    6684                 :          0 :         value = os_strchr(cmd, ' ');
    6685         [ #  # ]:          0 :         if (value == NULL)
    6686                 :          0 :                 return -1;
    6687                 :          0 :         *value++ = '\0';
    6688                 :            : 
    6689                 :          0 :         wpa_printf(MSG_DEBUG, "GLOBAL_CTRL_IFACE SET '%s'='%s'", cmd, value);
    6690                 :            : 
    6691                 :            : #ifdef CONFIG_WIFI_DISPLAY
    6692         [ #  # ]:          0 :         if (os_strcasecmp(cmd, "wifi_display") == 0) {
    6693                 :          0 :                 wifi_display_enable(global, !!atoi(value));
    6694                 :          0 :                 return 0;
    6695                 :            :         }
    6696                 :            : #endif /* CONFIG_WIFI_DISPLAY */
    6697                 :            : 
    6698                 :          0 :         return -1;
    6699                 :            : }
    6700                 :            : 
    6701                 :            : 
    6702                 :            : #ifndef CONFIG_NO_CONFIG_WRITE
    6703                 :          0 : static int wpas_global_ctrl_iface_save_config(struct wpa_global *global)
    6704                 :            : {
    6705                 :          0 :         int ret = 0;
    6706                 :            :         struct wpa_supplicant *wpa_s;
    6707                 :            : 
    6708         [ #  # ]:          0 :         for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
    6709         [ #  # ]:          0 :                 if (!wpa_s->conf->update_config) {
    6710                 :          0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed to update configuration (update_config=0)");
    6711                 :          0 :                         continue;
    6712                 :            :                 }
    6713                 :            : 
    6714         [ #  # ]:          0 :                 if (wpa_config_write(wpa_s->confname, wpa_s->conf)) {
    6715                 :          0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to update configuration");
    6716                 :          0 :                         ret = 1;
    6717                 :            :                 } else {
    6718                 :          0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration updated");
    6719                 :            :                 }
    6720                 :            :         }
    6721                 :            : 
    6722                 :          0 :         return ret;
    6723                 :            : }
    6724                 :            : #endif /* CONFIG_NO_CONFIG_WRITE */
    6725                 :            : 
    6726                 :            : 
    6727                 :          0 : static int wpas_global_ctrl_iface_status(struct wpa_global *global,
    6728                 :            :                                          char *buf, size_t buflen)
    6729                 :            : {
    6730                 :            :         char *pos, *end;
    6731                 :            :         int ret;
    6732                 :            :         struct wpa_supplicant *wpa_s;
    6733                 :            : 
    6734                 :          0 :         pos = buf;
    6735                 :          0 :         end = buf + buflen;
    6736                 :            : 
    6737                 :            : #ifdef CONFIG_P2P
    6738 [ #  # ][ #  # ]:          0 :         if (global->p2p && !global->p2p_disabled) {
    6739                 :          0 :                 ret = os_snprintf(pos, end - pos, "p2p_device_address=" MACSTR
    6740                 :            :                                   "\n"
    6741                 :            :                                   "p2p_state=%s\n",
    6742                 :          0 :                                   MAC2STR(global->p2p_dev_addr),
    6743                 :            :                                   p2p_get_state_txt(global->p2p));
    6744 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    6745                 :          0 :                         return pos - buf;
    6746                 :          0 :                 pos += ret;
    6747         [ #  # ]:          0 :         } else if (global->p2p) {
    6748                 :          0 :                 ret = os_snprintf(pos, end - pos, "p2p_state=DISABLED\n");
    6749 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    6750                 :          0 :                         return pos - buf;
    6751                 :          0 :                 pos += ret;
    6752                 :            :         }
    6753                 :            : #endif /* CONFIG_P2P */
    6754                 :            : 
    6755                 :            : #ifdef CONFIG_WIFI_DISPLAY
    6756                 :          0 :         ret = os_snprintf(pos, end - pos, "wifi_display=%d\n",
    6757                 :          0 :                           !!global->wifi_display);
    6758 [ #  # ][ #  # ]:          0 :         if (ret < 0 || ret >= end - pos)
    6759                 :          0 :                 return pos - buf;
    6760                 :          0 :         pos += ret;
    6761                 :            : #endif /* CONFIG_WIFI_DISPLAY */
    6762                 :            : 
    6763         [ #  # ]:          0 :         for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
    6764                 :          0 :                 ret = os_snprintf(pos, end - pos, "ifname=%s\n"
    6765                 :            :                                   "address=" MACSTR "\n",
    6766                 :          0 :                                   wpa_s->ifname, MAC2STR(wpa_s->own_addr));
    6767 [ #  # ][ #  # ]:          0 :                 if (ret < 0 || ret >= end - pos)
    6768                 :          0 :                         return pos - buf;
    6769                 :          0 :                 pos += ret;
    6770                 :            :         }
    6771                 :            : 
    6772                 :          0 :         return pos - buf;
    6773                 :            : }
    6774                 :            : 
    6775                 :            : 
    6776                 :       1306 : char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
    6777                 :            :                                                 char *buf, size_t *resp_len)
    6778                 :            : {
    6779                 :            :         char *reply;
    6780                 :       1306 :         const int reply_size = 2048;
    6781                 :            :         int reply_len;
    6782                 :       1306 :         int level = MSG_DEBUG;
    6783                 :            : 
    6784         [ -  + ]:       1306 :         if (os_strncmp(buf, "IFNAME=", 7) == 0) {
    6785                 :          0 :                 char *pos = os_strchr(buf + 7, ' ');
    6786         [ #  # ]:          0 :                 if (pos) {
    6787                 :          0 :                         *pos++ = '\0';
    6788                 :          0 :                         return wpas_global_ctrl_iface_ifname(global,
    6789                 :            :                                                              buf + 7, pos,
    6790                 :            :                                                              resp_len);
    6791                 :            :                 }
    6792                 :            :         }
    6793                 :            : 
    6794                 :       1306 :         reply = wpas_global_ctrl_iface_redir(global, buf, resp_len);
    6795         [ +  + ]:       1306 :         if (reply)
    6796                 :        899 :                 return reply;
    6797                 :            : 
    6798         [ +  + ]:        407 :         if (os_strcmp(buf, "PING") == 0)
    6799                 :          3 :                 level = MSG_EXCESSIVE;
    6800                 :        407 :         wpa_hexdump_ascii(level, "RX global ctrl_iface",
    6801                 :            :                           (const u8 *) buf, os_strlen(buf));
    6802                 :            : 
    6803                 :        407 :         reply = os_malloc(reply_size);
    6804         [ -  + ]:        407 :         if (reply == NULL) {
    6805                 :          0 :                 *resp_len = 1;
    6806                 :          0 :                 return NULL;
    6807                 :            :         }
    6808                 :            : 
    6809                 :        407 :         os_memcpy(reply, "OK\n", 3);
    6810                 :        407 :         reply_len = 3;
    6811                 :            : 
    6812         [ +  + ]:        407 :         if (os_strcmp(buf, "PING") == 0) {
    6813                 :          3 :                 os_memcpy(reply, "PONG\n", 5);
    6814                 :          3 :                 reply_len = 5;
    6815         [ +  + ]:        404 :         } else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) {
    6816         [ +  + ]:         13 :                 if (wpa_supplicant_global_iface_add(global, buf + 14))
    6817                 :          1 :                         reply_len = -1;
    6818         [ +  + ]:        391 :         } else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) {
    6819         [ +  + ]:        390 :                 if (wpa_supplicant_global_iface_remove(global, buf + 17))
    6820                 :        378 :                         reply_len = -1;
    6821         [ -  + ]:          1 :         } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
    6822                 :          0 :                 reply_len = wpa_supplicant_global_iface_list(
    6823                 :            :                         global, reply, reply_size);
    6824         [ -  + ]:          1 :         } else if (os_strcmp(buf, "INTERFACES") == 0) {
    6825                 :          0 :                 reply_len = wpa_supplicant_global_iface_interfaces(
    6826                 :            :                         global, reply, reply_size);
    6827         [ -  + ]:          1 :         } else if (os_strcmp(buf, "TERMINATE") == 0) {
    6828                 :          0 :                 wpa_supplicant_terminate_proc(global);
    6829         [ -  + ]:          1 :         } else if (os_strcmp(buf, "SUSPEND") == 0) {
    6830                 :          0 :                 wpas_notify_suspend(global);
    6831         [ -  + ]:          1 :         } else if (os_strcmp(buf, "RESUME") == 0) {
    6832                 :          0 :                 wpas_notify_resume(global);
    6833         [ -  + ]:          1 :         } else if (os_strncmp(buf, "SET ", 4) == 0) {
    6834         [ #  # ]:          0 :                 if (wpas_global_ctrl_iface_set(global, buf + 4))
    6835                 :          0 :                         reply_len = -1;
    6836                 :            : #ifndef CONFIG_NO_CONFIG_WRITE
    6837         [ -  + ]:          1 :         } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
    6838         [ #  # ]:          0 :                 if (wpas_global_ctrl_iface_save_config(global))
    6839                 :          0 :                         reply_len = -1;
    6840                 :            : #endif /* CONFIG_NO_CONFIG_WRITE */
    6841         [ -  + ]:          1 :         } else if (os_strcmp(buf, "STATUS") == 0) {
    6842                 :          0 :                 reply_len = wpas_global_ctrl_iface_status(global, reply,
    6843                 :            :                                                           reply_size);
    6844                 :            : #ifdef CONFIG_MODULE_TESTS
    6845         [ +  - ]:          1 :         } else if (os_strcmp(buf, "MODULE_TESTS") == 0) {
    6846                 :            :                 int wpas_module_tests(void);
    6847         [ -  + ]:          1 :                 if (wpas_module_tests() < 0)
    6848                 :          0 :                         reply_len = -1;
    6849                 :            : #endif /* CONFIG_MODULE_TESTS */
    6850                 :            :         } else {
    6851                 :          0 :                 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
    6852                 :          0 :                 reply_len = 16;
    6853                 :            :         }
    6854                 :            : 
    6855         [ +  + ]:        407 :         if (reply_len < 0) {
    6856                 :        379 :                 os_memcpy(reply, "FAIL\n", 5);
    6857                 :        379 :                 reply_len = 5;
    6858                 :            :         }
    6859                 :            : 
    6860                 :        407 :         *resp_len = reply_len;
    6861                 :       1306 :         return reply;
    6862                 :            : }

Generated by: LCOV version 1.9