]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - wpa_supplicant/ctrl_iface.c
Update wpa_supplicant channel list on FLUSH
[thirdparty/hostap.git] / wpa_supplicant / ctrl_iface.c
index 89cacc649e0ce5a479651574b7f1fa4f1c574bec..42a5e886dd2e39782a15ee60bf47ea2e7a44689f 100644 (file)
@@ -20,6 +20,9 @@
 #include "common/ieee802_11_defs.h"
 #include "common/ieee802_11_common.h"
 #include "common/wpa_ctrl.h"
+#ifdef CONFIG_DPP
+#include "common/dpp.h"
+#endif /* CONFIG_DPP */
 #include "crypto/tls.h"
 #include "ap/hostapd.h"
 #include "eap_peer/eap.h"
@@ -53,6 +56,7 @@
 #include "drivers/driver.h"
 #include "mesh.h"
 #include "dpp_supplicant.h"
+#include "sme.h"
 
 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
                                            char *buf, int len);
@@ -63,28 +67,6 @@ static int * freq_range_to_channel_list(struct wpa_supplicant *wpa_s,
                                        char *val);
 
 
-#ifdef CONFIG_FILS
-
-static int wpa_is_fils_supported(struct wpa_supplicant *wpa_s)
-{
-       return (((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
-                (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SUPPORT_FILS)) ||
-               (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
-                (wpa_s->drv_flags & WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD)));
-}
-
-
-#ifdef CONFIG_FILS_SK_PFS
-static int wpa_is_fils_sk_pfs_supported(struct wpa_supplicant *wpa_s)
-{
-       return (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
-               (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SUPPORT_FILS);
-}
-#endif /* CONFIG_FILS_SK_PFS */
-
-#endif /* CONFIG_FILS */
-
-
 static int set_bssid_filter(struct wpa_supplicant *wpa_s, char *val)
 {
        char *pos;
@@ -604,6 +586,54 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
        } else if (os_strcasecmp(cmd, "dpp_configurator_params") == 0) {
                os_free(wpa_s->dpp_configurator_params);
                wpa_s->dpp_configurator_params = os_strdup(value);
+       } else if (os_strcasecmp(cmd, "dpp_init_max_tries") == 0) {
+               wpa_s->dpp_init_max_tries = atoi(value);
+       } else if (os_strcasecmp(cmd, "dpp_init_retry_time") == 0) {
+               wpa_s->dpp_init_retry_time = atoi(value);
+       } else if (os_strcasecmp(cmd, "dpp_resp_wait_time") == 0) {
+               wpa_s->dpp_resp_wait_time = atoi(value);
+       } else if (os_strcasecmp(cmd, "dpp_resp_max_tries") == 0) {
+               wpa_s->dpp_resp_max_tries = atoi(value);
+       } else if (os_strcasecmp(cmd, "dpp_resp_retry_time") == 0) {
+               wpa_s->dpp_resp_retry_time = atoi(value);
+#ifdef CONFIG_TESTING_OPTIONS
+       } else if (os_strcasecmp(cmd, "dpp_pkex_own_mac_override") == 0) {
+               if (hwaddr_aton(value, dpp_pkex_own_mac_override))
+                       ret = -1;
+       } else if (os_strcasecmp(cmd, "dpp_pkex_peer_mac_override") == 0) {
+               if (hwaddr_aton(value, dpp_pkex_peer_mac_override))
+                       ret = -1;
+       } else if (os_strcasecmp(cmd, "dpp_pkex_ephemeral_key_override") == 0) {
+               size_t hex_len = os_strlen(value);
+
+               if (hex_len >
+                   2 * sizeof(dpp_pkex_ephemeral_key_override))
+                       ret = -1;
+               else if (hexstr2bin(value, dpp_pkex_ephemeral_key_override,
+                                   hex_len / 2))
+                       ret = -1;
+               else
+                       dpp_pkex_ephemeral_key_override_len = hex_len / 2;
+       } else if (os_strcasecmp(cmd, "dpp_protocol_key_override") == 0) {
+               size_t hex_len = os_strlen(value);
+
+               if (hex_len > 2 * sizeof(dpp_protocol_key_override))
+                       ret = -1;
+               else if (hexstr2bin(value, dpp_protocol_key_override,
+                                   hex_len / 2))
+                       ret = -1;
+               else
+                       dpp_protocol_key_override_len = hex_len / 2;
+       } else if (os_strcasecmp(cmd, "dpp_nonce_override") == 0) {
+               size_t hex_len = os_strlen(value);
+
+               if (hex_len > 2 * sizeof(dpp_nonce_override))
+                       ret = -1;
+               else if (hexstr2bin(value, dpp_nonce_override, hex_len / 2))
+                       ret = -1;
+               else
+                       dpp_nonce_override_len = hex_len / 2;
+#endif /* CONFIG_TESTING_OPTIONS */
 #endif /* CONFIG_DPP */
 #ifdef CONFIG_TESTING_OPTIONS
        } else if (os_strcasecmp(cmd, "ext_mgmt_frame_handling") == 0) {
@@ -645,18 +675,35 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
 #ifdef CONFIG_DPP
        } else if (os_strcasecmp(cmd, "dpp_config_obj_override") == 0) {
                os_free(wpa_s->dpp_config_obj_override);
-               wpa_s->dpp_config_obj_override = os_strdup(value);
+               if (value[0] == '\0')
+                       wpa_s->dpp_config_obj_override = NULL;
+               else
+                       wpa_s->dpp_config_obj_override = os_strdup(value);
        } else if (os_strcasecmp(cmd, "dpp_discovery_override") == 0) {
                os_free(wpa_s->dpp_discovery_override);
-               wpa_s->dpp_discovery_override = os_strdup(value);
+               if (value[0] == '\0')
+                       wpa_s->dpp_discovery_override = NULL;
+               else
+                       wpa_s->dpp_discovery_override = os_strdup(value);
        } else if (os_strcasecmp(cmd, "dpp_groups_override") == 0) {
                os_free(wpa_s->dpp_groups_override);
-               wpa_s->dpp_groups_override = os_strdup(value);
+               if (value[0] == '\0')
+                       wpa_s->dpp_groups_override = NULL;
+               else
+                       wpa_s->dpp_groups_override = os_strdup(value);
        } else if (os_strcasecmp(cmd,
                                 "dpp_ignore_netaccesskey_mismatch") == 0) {
                wpa_s->dpp_ignore_netaccesskey_mismatch = atoi(value);
+       } else if (os_strcasecmp(cmd, "dpp_test") == 0) {
+               dpp_test = atoi(value);
 #endif /* CONFIG_DPP */
 #endif /* CONFIG_TESTING_OPTIONS */
+#ifdef CONFIG_FILS
+       } else if (os_strcasecmp(cmd, "disable_fils") == 0) {
+               wpa_s->disable_fils = !!atoi(value);
+               wpa_drv_disable_fils(wpa_s, wpa_s->disable_fils);
+               wpa_supplicant_set_default_scan_ies(wpa_s);
+#endif /* CONFIG_FILS */
 #ifndef CONFIG_NO_CONFIG_BLOBS
        } else if (os_strcmp(cmd, "blob") == 0) {
                ret = wpas_ctrl_set_blob(wpa_s, value);
@@ -704,6 +751,15 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
                ret = wpas_ctrl_iface_set_ric_ies(wpa_s, value);
        } else if (os_strcasecmp(cmd, "roaming") == 0) {
                ret = wpa_drv_roaming(wpa_s, atoi(value), NULL);
+#ifdef CONFIG_WNM
+       } else if (os_strcasecmp(cmd, "coloc_intf_elems") == 0) {
+               struct wpabuf *elems;
+
+               elems = wpabuf_parse_bin(value);
+               if (!elems)
+                       return -1;
+               wnm_set_coloc_intf_elems(wpa_s, elems);
+#endif /* CONFIG_WNM */
        } else {
                value[-1] = '=';
                ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
@@ -749,6 +805,12 @@ static int wpa_supplicant_ctrl_iface_get(struct wpa_supplicant *wpa_s,
 #endif /* CONFIG_TESTING_GET_GTK */
        } else if (os_strcmp(cmd, "tls_library") == 0) {
                res = tls_get_library_version(buf, buflen);
+#ifdef CONFIG_TESTING_OPTIONS
+       } else if (os_strcmp(cmd, "anonce") == 0) {
+               return wpa_snprintf_hex(buf, buflen,
+                                       wpa_sm_get_anonce(wpa_s->wpa),
+                                       WPA_NONCE_LEN);
+#endif /* CONFIG_TESTING_OPTIONS */
        } else {
                res = wpa_config_get_value(cmd, wpa_s->conf, buf, buflen);
        }
@@ -2240,6 +2302,13 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
        }
 #endif /* CONFIG_WPS */
 
+       if (wpa_s->ieee80211ac) {
+               ret = os_snprintf(pos, end - pos, "ieee80211ac=1\n");
+               if (os_snprintf_error(end - pos, ret))
+                       return pos - buf;
+               pos += ret;
+       }
+
 #ifdef ANDROID
        /*
         * Allow using the STATUS command with default behavior, say for debug,
@@ -3919,6 +3988,14 @@ static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
        }
 #endif /* CONFIG_IEEE80211R */
 #endif /* CONFIG_FILS */
+#ifdef CONFIG_SAE
+       if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE) {
+               ret = os_snprintf(pos, end - pos, " SAE");
+               if (os_snprintf_error(end - pos, ret))
+                       return pos - buf;
+               pos += ret;
+       }
+#endif /* CONFIG_SAE */
 
        return pos - buf;
 }
@@ -4319,6 +4396,13 @@ static int wpa_supplicant_ctrl_iface_get_capability(
        }
 #endif /* CONFIG_FILS */
 
+       if (os_strcmp(field, "multibss") == 0 && wpa_s->multi_bss_support) {
+               res = os_snprintf(buf, buflen, "MULTIBSS-STA");
+               if (os_snprintf_error(buflen, res))
+                       return -1;
+               return res;
+       }
+
        wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
                   field);
 
@@ -4748,6 +4832,10 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
                                   anqp->hs20_operating_class);
                pos = anqp_add_hex(pos, end, "hs20_osu_providers_list",
                                   anqp->hs20_osu_providers_list);
+               pos = anqp_add_hex(pos, end, "hs20_operator_icon_metadata",
+                                  anqp->hs20_operator_icon_metadata);
+               pos = anqp_add_hex(pos, end, "hs20_osu_providers_nai_list",
+                                  anqp->hs20_osu_providers_nai_list);
 #endif /* CONFIG_HS20 */
 
                dl_list_for_each(elem, &anqp->anqp_elems,
@@ -6223,13 +6311,21 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
        int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
        int max_oper_chwidth, chwidth = 0, freq2 = 0;
        char *token, *context = NULL;
+#ifdef CONFIG_ACS
+       int acs = 0;
+#endif /* CONFIG_ACS */
 
        while ((token = str_token(cmd, " ", &context))) {
-               if (sscanf(token, "freq=%d", &freq) == 1 ||
-                   sscanf(token, "freq2=%d", &freq2) == 1 ||
+               if (sscanf(token, "freq2=%d", &freq2) == 1 ||
                    sscanf(token, "persistent=%d", &group_id) == 1 ||
                    sscanf(token, "max_oper_chwidth=%d", &chwidth) == 1) {
                        continue;
+#ifdef CONFIG_ACS
+               } else if (os_strcmp(token, "freq=acs") == 0) {
+                       acs = 1;
+#endif /* CONFIG_ACS */
+               } else if (sscanf(token, "freq=%d", &freq) == 1) {
+                       continue;
                } else if (os_strcmp(token, "ht40") == 0) {
                        ht40 = 1;
                } else if (os_strcmp(token, "vht") == 0) {
@@ -6245,6 +6341,24 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
                }
        }
 
+#ifdef CONFIG_ACS
+       if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) &&
+           (acs || freq == 2 || freq == 5)) {
+               if (freq == 2 && wpa_s->best_24_freq <= 0) {
+                       wpa_s->p2p_go_acs_band = HOSTAPD_MODE_IEEE80211G;
+                       wpa_s->p2p_go_do_acs = 1;
+                       freq = 0;
+               } else if (freq == 5 && wpa_s->best_5_freq <= 0) {
+                       wpa_s->p2p_go_acs_band = HOSTAPD_MODE_IEEE80211A;
+                       wpa_s->p2p_go_do_acs = 1;
+                       freq = 0;
+               } else {
+                       wpa_s->p2p_go_acs_band = HOSTAPD_MODE_IEEE80211ANY;
+                       wpa_s->p2p_go_do_acs = 1;
+               }
+       }
+#endif /* CONFIG_ACS */
+
        max_oper_chwidth = parse_freq(chwidth, freq2);
        if (max_oper_chwidth < 0)
                return -1;
@@ -7348,6 +7462,22 @@ static int wpas_ctrl_iface_wnm_bss_query(struct wpa_supplicant *wpa_s, char *cmd
                                                  list);
 }
 
+
+static int wpas_ctrl_iface_coloc_intf_report(struct wpa_supplicant *wpa_s,
+                                            char *cmd)
+{
+       struct wpabuf *elems;
+       int ret;
+
+       elems = wpabuf_parse_bin(cmd);
+       if (!elems)
+               return -1;
+
+       ret = wnm_send_coloc_intf_report(wpa_s, 0, elems);
+       wpabuf_free(elems);
+       return ret;
+}
+
 #endif /* CONFIG_WNM */
 
 
@@ -7381,10 +7511,17 @@ static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf,
                pos += ret;
        }
 
-       if (si.center_frq1 > 0 && si.center_frq2 > 0) {
-               ret = os_snprintf(pos, end - pos,
-                                 "CENTER_FRQ1=%d\nCENTER_FRQ2=%d\n",
-                                 si.center_frq1, si.center_frq2);
+       if (si.center_frq1 > 0) {
+               ret = os_snprintf(pos, end - pos, "CENTER_FRQ1=%d\n",
+                                 si.center_frq1);
+               if (os_snprintf_error(end - pos, ret))
+                       return -1;
+               pos += ret;
+       }
+
+       if (si.center_frq2 > 0) {
+               ret = os_snprintf(pos, end - pos, "CENTER_FRQ2=%d\n",
+                                 si.center_frq2);
                if (os_snprintf_error(end - pos, ret))
                        return -1;
                pos += ret;
@@ -7702,6 +7839,18 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
 
 #ifdef CONFIG_DPP
        wpas_dpp_deinit(wpa_s);
+       wpa_s->dpp_init_max_tries = 0;
+       wpa_s->dpp_init_retry_time = 0;
+       wpa_s->dpp_resp_wait_time = 0;
+       wpa_s->dpp_resp_max_tries = 0;
+       wpa_s->dpp_resp_retry_time = 0;
+#ifdef CONFIG_TESTING_OPTIONS
+       os_memset(dpp_pkex_own_mac_override, 0, ETH_ALEN);
+       os_memset(dpp_pkex_peer_mac_override, 0, ETH_ALEN);
+       dpp_pkex_ephemeral_key_override_len = 0;
+       dpp_protocol_key_override_len = 0;
+       dpp_nonce_override_len = 0;
+#endif /* CONFIG_TESTING_OPTIONS */
 #endif /* CONFIG_DPP */
 
 #ifdef CONFIG_TDLS
@@ -7765,12 +7914,22 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
        wpa_s->p2p_go_csa_on_inv = 0;
        wpa_s->ignore_auth_resp = 0;
        wpa_s->ignore_assoc_disallow = 0;
+       wpa_s->testing_resend_assoc = 0;
        wpa_s->reject_btm_req_reason = 0;
        wpa_sm_set_test_assoc_ie(wpa_s->wpa, NULL);
        os_free(wpa_s->get_pref_freq_list_override);
        wpa_s->get_pref_freq_list_override = NULL;
        wpabuf_free(wpa_s->sae_commit_override);
        wpa_s->sae_commit_override = NULL;
+#ifdef CONFIG_DPP
+       os_free(wpa_s->dpp_config_obj_override);
+       wpa_s->dpp_config_obj_override = NULL;
+       os_free(wpa_s->dpp_discovery_override);
+       wpa_s->dpp_discovery_override = NULL;
+       os_free(wpa_s->dpp_groups_override);
+       wpa_s->dpp_groups_override = NULL;
+       dpp_test = DPP_TEST_DISABLED;
+#endif /* CONFIG_DPP */
 #endif /* CONFIG_TESTING_OPTIONS */
 
        wpa_s->disconnected = 0;
@@ -7798,6 +7957,8 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
 
        wpabuf_free(wpa_s->ric_ies);
        wpa_s->ric_ies = NULL;
+
+       wpa_supplicant_update_channel_list(wpa_s, NULL);
 }
 
 
@@ -8620,26 +8781,39 @@ static void wpas_data_test_rx(void *ctx, const u8 *src_addr, const u8 *buf,
        struct iphdr ip;
        const u8 *pos;
        unsigned int i;
+       char extra[30];
 
-       if (len != HWSIM_PACKETLEN)
+       if (len < sizeof(*eth) + sizeof(ip) || len > HWSIM_PACKETLEN) {
+               wpa_printf(MSG_DEBUG,
+                          "test data: RX - ignore unexpected length %d",
+                          (int) len);
                return;
+       }
 
        eth = (const struct ether_header *) buf;
        os_memcpy(&ip, eth + 1, sizeof(ip));
        pos = &buf[sizeof(*eth) + sizeof(ip)];
 
        if (ip.ihl != 5 || ip.version != 4 ||
-           ntohs(ip.tot_len) != HWSIM_IP_LEN)
+           ntohs(ip.tot_len) > HWSIM_IP_LEN) {
+               wpa_printf(MSG_DEBUG,
+                          "test data: RX - ignore unexpect IP header");
                return;
+       }
 
-       for (i = 0; i < HWSIM_IP_LEN - sizeof(ip); i++) {
-               if (*pos != (u8) i)
+       for (i = 0; i < ntohs(ip.tot_len) - sizeof(ip); i++) {
+               if (*pos != (u8) i) {
+                       wpa_printf(MSG_DEBUG,
+                                  "test data: RX - ignore mismatching payload");
                        return;
+               }
                pos++;
        }
-
-       wpa_msg(wpa_s, MSG_INFO, "DATA-TEST-RX " MACSTR " " MACSTR,
-               MAC2STR(eth->ether_dhost), MAC2STR(eth->ether_shost));
+       extra[0] = '\0';
+       if (ntohs(ip.tot_len) != HWSIM_IP_LEN)
+               os_snprintf(extra, sizeof(extra), " len=%d", ntohs(ip.tot_len));
+       wpa_msg(wpa_s, MSG_INFO, "DATA-TEST-RX " MACSTR " " MACSTR "%s",
+               MAC2STR(eth->ether_dhost), MAC2STR(eth->ether_shost), extra);
 }
 
 
@@ -8683,7 +8857,7 @@ static int wpas_ctrl_iface_data_test_config(struct wpa_supplicant *wpa_s,
 static int wpas_ctrl_iface_data_test_tx(struct wpa_supplicant *wpa_s, char *cmd)
 {
        u8 dst[ETH_ALEN], src[ETH_ALEN];
-       char *pos;
+       char *pos, *pos2;
        int used;
        long int val;
        u8 tos;
@@ -8692,11 +8866,12 @@ static int wpas_ctrl_iface_data_test_tx(struct wpa_supplicant *wpa_s, char *cmd)
        struct iphdr *ip;
        u8 *dpos;
        unsigned int i;
+       size_t send_len = HWSIM_IP_LEN;
 
        if (wpa_s->l2_test == NULL)
                return -1;
 
-       /* format: <dst> <src> <tos> */
+       /* format: <dst> <src> <tos> [len=<length>] */
 
        pos = cmd;
        used = hwaddr_aton2(pos, dst);
@@ -8710,11 +8885,19 @@ static int wpas_ctrl_iface_data_test_tx(struct wpa_supplicant *wpa_s, char *cmd)
                return -1;
        pos += used;
 
-       val = strtol(pos, NULL, 0);
+       val = strtol(pos, &pos2, 0);
        if (val < 0 || val > 0xff)
                return -1;
        tos = val;
 
+       pos = os_strstr(pos2, " len=");
+       if (pos) {
+               i = atoi(pos + 5);
+               if (i < sizeof(*ip) || i > HWSIM_IP_LEN)
+                       return -1;
+               send_len = i;
+       }
+
        eth = (struct ether_header *) &buf[2];
        os_memcpy(eth->ether_dhost, dst, ETH_ALEN);
        os_memcpy(eth->ether_shost, src, ETH_ALEN);
@@ -8725,17 +8908,17 @@ static int wpas_ctrl_iface_data_test_tx(struct wpa_supplicant *wpa_s, char *cmd)
        ip->version = 4;
        ip->ttl = 64;
        ip->tos = tos;
-       ip->tot_len = htons(HWSIM_IP_LEN);
+       ip->tot_len = htons(send_len);
        ip->protocol = 1;
        ip->saddr = htonl(192U << 24 | 168 << 16 | 1 << 8 | 1);
        ip->daddr = htonl(192U << 24 | 168 << 16 | 1 << 8 | 2);
        ip->check = ipv4_hdr_checksum(ip, sizeof(*ip));
        dpos = (u8 *) (ip + 1);
-       for (i = 0; i < HWSIM_IP_LEN - sizeof(*ip); i++)
+       for (i = 0; i < send_len - sizeof(*ip); i++)
                *dpos++ = i;
 
        if (l2_packet_send(wpa_s->l2_test, dst, ETHERTYPE_IP, &buf[2],
-                          HWSIM_PACKETLEN) < 0)
+                          sizeof(struct ether_header) + send_len) < 0)
                return -1;
 
        wpa_dbg(wpa_s, MSG_DEBUG, "test data: TX dst=" MACSTR " src=" MACSTR
@@ -8907,6 +9090,79 @@ static int wpas_ctrl_test_assoc_ie(struct wpa_supplicant *wpa_s,
        return 0;
 }
 
+
+static int wpas_ctrl_reset_pn(struct wpa_supplicant *wpa_s)
+{
+       u8 zero[WPA_TK_MAX_LEN];
+
+       if (wpa_s->last_tk_alg == WPA_ALG_NONE)
+               return -1;
+
+       wpa_printf(MSG_INFO, "TESTING: Reset PN");
+       os_memset(zero, 0, sizeof(zero));
+
+       /* First, use a zero key to avoid any possible duplicate key avoidance
+        * in the driver. */
+       if (wpa_drv_set_key(wpa_s, wpa_s->last_tk_alg, wpa_s->last_tk_addr,
+                           wpa_s->last_tk_key_idx, 1, zero, 6,
+                           zero, wpa_s->last_tk_len) < 0)
+               return -1;
+
+       /* Set the previously configured key to reset its TSC/RSC */
+       return wpa_drv_set_key(wpa_s, wpa_s->last_tk_alg, wpa_s->last_tk_addr,
+                              wpa_s->last_tk_key_idx, 1, zero, 6,
+                              wpa_s->last_tk, wpa_s->last_tk_len);
+}
+
+
+static int wpas_ctrl_key_request(struct wpa_supplicant *wpa_s, const char *cmd)
+{
+       const char *pos = cmd;
+       int error, pairwise;
+
+       error = atoi(pos);
+       pos = os_strchr(pos, ' ');
+       if (!pos)
+               return -1;
+       pairwise = atoi(pos);
+       wpa_sm_key_request(wpa_s->wpa, error, pairwise);
+       return 0;
+}
+
+
+static int wpas_ctrl_resend_assoc(struct wpa_supplicant *wpa_s)
+{
+#ifdef CONFIG_SME
+       struct wpa_driver_associate_params params;
+       int ret;
+
+       os_memset(&params, 0, sizeof(params));
+       params.bssid = wpa_s->bssid;
+       params.ssid = wpa_s->sme.ssid;
+       params.ssid_len = wpa_s->sme.ssid_len;
+       params.freq.freq = wpa_s->sme.freq;
+       if (wpa_s->last_assoc_req_wpa_ie) {
+               params.wpa_ie = wpabuf_head(wpa_s->last_assoc_req_wpa_ie);
+               params.wpa_ie_len = wpabuf_len(wpa_s->last_assoc_req_wpa_ie);
+       }
+       params.pairwise_suite = wpa_s->pairwise_cipher;
+       params.group_suite = wpa_s->group_cipher;
+       params.mgmt_group_suite = wpa_s->mgmt_group_cipher;
+       params.key_mgmt_suite = wpa_s->key_mgmt;
+       params.wpa_proto = wpa_s->wpa_proto;
+       params.mgmt_frame_protection = wpa_s->sme.mfp;
+       params.rrm_used = wpa_s->rrm.rrm_used;
+       if (wpa_s->sme.prev_bssid_set)
+               params.prev_bssid = wpa_s->sme.prev_bssid;
+       wpa_printf(MSG_INFO, "TESTING: Resend association request");
+       ret = wpa_drv_associate(wpa_s, &params);
+       wpa_s->testing_resend_assoc = 1;
+       return ret;
+#else /* CONFIG_SME */
+       return -1;
+#endif /* CONFIG_SME */
+}
+
 #endif /* CONFIG_TESTING_OPTIONS */
 
 
@@ -9642,6 +9898,11 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                        reply_len += eapol_sm_get_mib(wpa_s->eapol,
                                                      reply + reply_len,
                                                      reply_size - reply_len);
+#ifdef CONFIG_MACSEC
+                       reply_len += ieee802_1x_kay_get_mib(
+                               wpa_s->kay, reply + reply_len,
+                               reply_size - reply_len);
+#endif /* CONFIG_MACSEC */
                }
        } else if (os_strncmp(buf, "STATUS", 6) == 0) {
                reply_len = wpa_supplicant_ctrl_iface_status(
@@ -10232,6 +10493,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
        } else if (os_strncmp(buf, "WNM_BSS_QUERY ", 14) == 0) {
                if (wpas_ctrl_iface_wnm_bss_query(wpa_s, buf + 14))
                                reply_len = -1;
+       } else if (os_strncmp(buf, "COLOC_INTF_REPORT ", 18) == 0) {
+               if (wpas_ctrl_iface_coloc_intf_report(wpa_s, buf + 18))
+                       reply_len = -1;
 #endif /* CONFIG_WNM */
        } else if (os_strcmp(buf, "FLUSH") == 0) {
                wpa_supplicant_ctrl_iface_flush(wpa_s);
@@ -10278,6 +10542,19 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
        } else if (os_strncmp(buf, "TEST_ASSOC_IE ", 14) == 0) {
                if (wpas_ctrl_test_assoc_ie(wpa_s, buf + 14) < 0)
                        reply_len = -1;
+       } else if (os_strcmp(buf, "RESET_PN") == 0) {
+               if (wpas_ctrl_reset_pn(wpa_s) < 0)
+                       reply_len = -1;
+       } else if (os_strncmp(buf, "KEY_REQUEST ", 12) == 0) {
+               if (wpas_ctrl_key_request(wpa_s, buf + 12) < 0)
+                       reply_len = -1;
+       } else if (os_strcmp(buf, "RESEND_ASSOC") == 0) {
+               if (wpas_ctrl_resend_assoc(wpa_s) < 0)
+                       reply_len = -1;
+       } else if (os_strcmp(buf, "UNPROT_DEAUTH") == 0) {
+               sme_event_unprot_disconnect(
+                       wpa_s, wpa_s->bssid, NULL,
+                       WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
 #endif /* CONFIG_TESTING_OPTIONS */
        } else if (os_strncmp(buf, "VENDOR_ELEM_ADD ", 16) == 0) {
                if (wpas_ctrl_vendor_elem_add(wpa_s, buf + 16) < 0)
@@ -10353,6 +10630,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                if (wpas_dpp_listen(wpa_s, buf + 11) < 0)
                        reply_len = -1;
        } else if (os_strcmp(buf, "DPP_STOP_LISTEN") == 0) {
+               wpas_dpp_stop(wpa_s);
                wpas_dpp_listen_stop(wpa_s);
        } else if (os_strncmp(buf, "DPP_CONFIGURATOR_ADD", 20) == 0) {
                int res;
@@ -10369,8 +10647,11 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                if (wpas_dpp_configurator_remove(wpa_s, buf + 24) < 0)
                        reply_len = -1;
        } else if (os_strncmp(buf, "DPP_CONFIGURATOR_SIGN ", 22) == 0) {
-               if (wpas_dpp_configurator_sign(wpa_s, buf + 22) < 0)
+               if (wpas_dpp_configurator_sign(wpa_s, buf + 21) < 0)
                        reply_len = -1;
+       } else if (os_strncmp(buf, "DPP_CONFIGURATOR_GET_KEY ", 25) == 0) {
+               reply_len = wpas_dpp_configurator_get_key(wpa_s, atoi(buf + 25),
+                                                         reply, reply_size);
        } else if (os_strncmp(buf, "DPP_PKEX_ADD ", 13) == 0) {
                int res;