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 1388613141 Lines: 1682 3620 46.5 %
Date: 2014-01-02 Functions: 78 140 55.7 %
Branches: 1046 2702 38.7 %

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

Generated by: LCOV version 1.9