PMKSA: Show AP/mesh PMKSA list in PMKSA command
[mech_eap.git] / wpa_supplicant / ctrl_iface.c
index b3d6246..98f7e29 100644 (file)
@@ -55,6 +55,7 @@
 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
                                            char *buf, int len);
 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
+                                                 const char *input,
                                                  char *buf, int len);
 static int * freq_range_to_channel_list(struct wpa_supplicant *wpa_s,
                                        char *val);
@@ -490,6 +491,12 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
 #endif /* CONFIG_NO_CONFIG_BLOBS */
        } else if (os_strcasecmp(cmd, "setband") == 0) {
                ret = wpas_ctrl_set_band(wpa_s, value);
+#ifdef CONFIG_MBO
+       } else if (os_strcasecmp(cmd, "non_pref_chan") == 0) {
+               ret = wpas_mbo_update_non_pref_chan(wpa_s, value);
+       } else if (os_strcasecmp(cmd, "mbo_cell_capa") == 0) {
+               wpas_mbo_update_cell_capa(wpa_s, atoi(value));
+#endif /* CONFIG_MBO */
        } else {
                value[-1] = '=';
                ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
@@ -956,7 +963,8 @@ static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
        if (os_strcmp(cmd, "any") == 0)
                _bssid = NULL;
        else if (os_strcmp(cmd, "get") == 0) {
-               ret = wps_generate_pin();
+               if (wps_generate_pin((unsigned int *) &ret) < 0)
+                       return -1;
                goto done;
        } else if (hwaddr_aton(cmd, bssid)) {
                wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
@@ -2719,6 +2727,30 @@ static int wpa_supplicant_ctrl_iface_mesh_group_remove(
        return 0;
 }
 
+
+static int wpa_supplicant_ctrl_iface_mesh_peer_remove(
+       struct wpa_supplicant *wpa_s, char *cmd)
+{
+       u8 addr[ETH_ALEN];
+
+       if (hwaddr_aton(cmd, addr) < 0)
+               return -1;
+
+       return wpas_mesh_peer_remove(wpa_s, addr);
+}
+
+
+static int wpa_supplicant_ctrl_iface_mesh_peer_add(
+       struct wpa_supplicant *wpa_s, char *cmd)
+{
+       u8 addr[ETH_ALEN];
+
+       if (hwaddr_aton(cmd, addr))
+               return -1;
+
+       return wpas_mesh_peer_add(wpa_s, addr);
+}
+
 #endif /* CONFIG_MESH */
 
 
@@ -2968,15 +3000,17 @@ static int wpa_supplicant_ctrl_iface_update_network(
        }
 
        if (os_strcmp(name, "bssid") != 0 &&
-           os_strcmp(name, "priority") != 0)
+           os_strcmp(name, "priority") != 0) {
                wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
 
-       if (wpa_s->current_ssid == ssid || wpa_s->current_ssid == NULL) {
-               /*
-                * Invalidate the EAP session cache if anything in the current
-                * or previously used configuration changes.
-                */
-               eapol_sm_invalidate_cached_session(wpa_s->eapol);
+               if (wpa_s->current_ssid == ssid ||
+                   wpa_s->current_ssid == NULL) {
+                       /*
+                        * Invalidate the EAP session cache if anything in the
+                        * current or previously used configuration changes.
+                        */
+                       eapol_sm_invalidate_cached_session(wpa_s->eapol);
+               }
        }
 
        if ((os_strcmp(name, "psk") == 0 &&
@@ -4712,7 +4746,7 @@ static int p2ps_ctrl_parse_cpt_priority(const char *pos, u8 *cpt)
                        return -1;
                }
 
-               if (isblank(*last)) {
+               if (isblank((unsigned char) *last)) {
                        i++;
                        break;
                }
@@ -5911,8 +5945,15 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
        }
 
        if (os_strcmp(cmd, "listen_channel") == 0) {
-               return p2p_set_listen_channel(wpa_s->global->p2p, 81,
-                                             atoi(param), 1);
+               char *pos;
+               u8 channel, op_class;
+
+               channel = atoi(param);
+               pos = os_strchr(param, ' ');
+               op_class = pos ? atoi(pos) : 81;
+
+               return p2p_set_listen_channel(wpa_s->global->p2p, op_class,
+                                             channel, 1);
        }
 
        if (os_strcmp(cmd, "ssid_postfix") == 0) {
@@ -6719,14 +6760,27 @@ static int wpas_ctrl_iface_wnm_sleep(struct wpa_supplicant *wpa_s, char *cmd)
 
 static int wpas_ctrl_iface_wnm_bss_query(struct wpa_supplicant *wpa_s, char *cmd)
 {
-       int query_reason;
+       int query_reason, list = 0;
 
        query_reason = atoi(cmd);
 
-       wpa_printf(MSG_DEBUG, "CTRL_IFACE: WNM_BSS_QUERY query_reason=%d",
-                  query_reason);
+       cmd = os_strchr(cmd, ' ');
+       if (cmd) {
+               cmd++;
+               if (os_strncmp(cmd, "list", 4) == 0) {
+                       list = 1;
+               } else {
+                       wpa_printf(MSG_DEBUG, "WNM Query: Invalid option %s",
+                                  cmd);
+                       return -1;
+               }
+       }
+
+       wpa_printf(MSG_DEBUG,
+                  "CTRL_IFACE: WNM_BSS_QUERY query_reason=%d%s",
+                  query_reason, list ? " candidate list" : "");
 
-       return wnm_send_bss_transition_mgmt_query(wpa_s, query_reason);
+       return wnm_send_bss_transition_mgmt_query(wpa_s, query_reason, list);
 }
 
 #endif /* CONFIG_WNM */
@@ -6917,13 +6971,13 @@ static int wpa_supplicant_vendor_cmd(struct wpa_supplicant *wpa_s, char *cmd,
 
        /* cmd: <vendor id> <subcommand id> [<hex formatted data>] */
        vendor_id = strtoul(cmd, &pos, 16);
-       if (!isblank(*pos))
+       if (!isblank((unsigned char) *pos))
                return -EINVAL;
 
        subcmd = strtoul(pos, &pos, 10);
 
        if (*pos != '\0') {
-               if (!isblank(*pos++))
+               if (!isblank((unsigned char) *pos++))
                        return -EINVAL;
                data_len = os_strlen(pos);
        }
@@ -7729,6 +7783,8 @@ static int wpas_ctrl_iface_data_test_config(struct wpa_supplicant *wpa_s,
                                            char *cmd)
 {
        int enabled = atoi(cmd);
+       char *pos;
+       const char *ifname;
 
        if (!enabled) {
                if (wpa_s->l2_test) {
@@ -7742,7 +7798,13 @@ static int wpas_ctrl_iface_data_test_config(struct wpa_supplicant *wpa_s,
        if (wpa_s->l2_test)
                return 0;
 
-       wpa_s->l2_test = l2_packet_init(wpa_s->ifname, wpa_s->own_addr,
+       pos = os_strstr(cmd, " ifname=");
+       if (pos)
+               ifname = pos + 8;
+       else
+               ifname = wpa_s->ifname;
+
+       wpa_s->l2_test = l2_packet_init(ifname, wpa_s->own_addr,
                                        ETHERTYPE_IP, wpas_data_test_rx,
                                        wpa_s, 1);
        if (wpa_s->l2_test == NULL)
@@ -8292,6 +8354,20 @@ static int wpas_ctrl_iface_mac_rand_scan(struct wpa_supplicant *wpa_s,
 }
 
 
+static int wpas_ctrl_iface_pmksa(struct wpa_supplicant *wpa_s,
+                                char *buf, size_t buflen)
+{
+       size_t reply_len;
+
+       reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, buf, buflen);
+#ifdef CONFIG_AP
+       reply_len += wpas_ap_pmksa_cache_list(wpa_s, &buf[reply_len],
+                                             buflen - reply_len);
+#endif /* CONFIG_AP */
+       return reply_len;
+}
+
+
 static int wpas_ctrl_cmd_debug_level(const char *cmd)
 {
        if (os_strcmp(cmd, "PING") == 0 ||
@@ -8363,8 +8439,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                reply_len = wpa_supplicant_ctrl_iface_status(
                        wpa_s, buf + 6, reply, reply_size);
        } else if (os_strcmp(buf, "PMKSA") == 0) {
-               reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, reply,
-                                                   reply_size);
+               reply_len = wpas_ctrl_iface_pmksa(wpa_s, reply, reply_size);
        } else if (os_strcmp(buf, "PMKSA_FLUSH") == 0) {
                wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
        } else if (os_strncmp(buf, "SET ", 4) == 0) {
@@ -8534,6 +8609,12 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                if (wpa_supplicant_ctrl_iface_mesh_group_remove(wpa_s,
                                                                buf + 18))
                        reply_len = -1;
+       } else if (os_strncmp(buf, "MESH_PEER_REMOVE ", 17) == 0) {
+               if (wpa_supplicant_ctrl_iface_mesh_peer_remove(wpa_s, buf + 17))
+                       reply_len = -1;
+       } else if (os_strncmp(buf, "MESH_PEER_ADD ", 14) == 0) {
+               if (wpa_supplicant_ctrl_iface_mesh_peer_add(wpa_s, buf + 14))
+                       reply_len = -1;
 #endif /* CONFIG_MESH */
 #ifdef CONFIG_P2P
        } else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) {
@@ -8814,9 +8895,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
        } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
                reply_len = wpa_supplicant_global_iface_list(
                        wpa_s->global, reply, reply_size);
-       } else if (os_strcmp(buf, "INTERFACES") == 0) {
+       } else if (os_strncmp(buf, "INTERFACES", 10) == 0) {
                reply_len = wpa_supplicant_global_iface_interfaces(
-                       wpa_s->global, reply, reply_size);
+                       wpa_s->global, buf + 10, reply, reply_size);
        } else if (os_strncmp(buf, "BSS ", 4) == 0) {
                reply_len = wpa_supplicant_ctrl_iface_bss(
                        wpa_s, buf + 4, reply, reply_size);
@@ -9222,18 +9303,31 @@ static int wpa_supplicant_global_iface_list(struct wpa_global *global,
 
 
 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
+                                                 const char *input,
                                                  char *buf, int len)
 {
        int res;
        char *pos, *end;
        struct wpa_supplicant *wpa_s;
+       int show_ctrl = 0;
+
+       if (input)
+               show_ctrl = !!os_strstr(input, "ctrl");
 
        wpa_s = global->ifaces;
        pos = buf;
        end = buf + len;
 
        while (wpa_s) {
-               res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname);
+               if (show_ctrl)
+                       res = os_snprintf(pos, end - pos, "%s ctrl_iface=%s\n",
+                                         wpa_s->ifname,
+                                         wpa_s->conf->ctrl_interface ?
+                                         wpa_s->conf->ctrl_interface : "N/A");
+               else
+                       res = os_snprintf(pos, end - pos, "%s\n",
+                                         wpa_s->ifname);
+
                if (os_snprintf_error(end - pos, res)) {
                        *pos = '\0';
                        break;
@@ -9622,9 +9716,9 @@ char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
        } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
                reply_len = wpa_supplicant_global_iface_list(
                        global, reply, reply_size);
-       } else if (os_strcmp(buf, "INTERFACES") == 0) {
+       } else if (os_strncmp(buf, "INTERFACES", 10) == 0) {
                reply_len = wpa_supplicant_global_iface_interfaces(
-                       global, reply, reply_size);
+                       global, buf + 10, reply, reply_size);
 #ifdef CONFIG_FST
        } else if (os_strncmp(buf, "FST-ATTACH ", 11) == 0) {
                reply_len = wpas_global_ctrl_iface_fst_attach(global, buf + 11,