LCOV - code coverage report
Current view: top level - wpa_supplicant - ctrl_iface.c (source / functions) Hit Total Coverage
Test: wpa_supplicant hwsim test run 1388240082 Lines: 1541 3610 42.7 %
Date: 2013-12-28 Functions: 72 140 51.4 %
Branches: 958 2698 35.5 %

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

Generated by: LCOV version 1.9