]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
OCV: Allow OCI channel to be overridden for testing (AP)
authorJouni Malinen <jouni@codeaurora.org>
Fri, 29 May 2020 21:04:53 +0000 (00:04 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 29 May 2020 21:04:53 +0000 (00:04 +0300)
Add hostapd configuration parameters oci_freq_override_* to allow the
OCI channel information to be overridden for various frames for testing
purposes. This can be set in the configuration and also updated during
the runtime of a BSS.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
hostapd/config_file.c
hostapd/ctrl_iface.c
src/ap/ap_config.h
src/ap/ieee802_11_shared.c
src/ap/wnm_ap.c
src/ap/wpa_auth.c
src/ap/wpa_auth.h
src/ap/wpa_auth_ft.c
src/ap/wpa_auth_glue.c

index cc1855dcd6ef31428d48db85e80fc42d7c2c1f48..bc650e949ce596ff5a4f84f080dd32cb07744da0 100644 (file)
@@ -4217,6 +4217,20 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                bss->skip_prune_assoc = atoi(pos);
        } else if (os_strcmp(buf, "ft_rsnxe_used") == 0) {
                bss->ft_rsnxe_used = atoi(pos);
+       } else if (os_strcmp(buf, "oci_freq_override_eapol_m3") == 0) {
+               bss->oci_freq_override_eapol_m3 = atoi(pos);
+       } else if (os_strcmp(buf, "oci_freq_override_eapol_g1") == 0) {
+               bss->oci_freq_override_eapol_g1 = atoi(pos);
+       } else if (os_strcmp(buf, "oci_freq_override_saquery_req") == 0) {
+               bss->oci_freq_override_saquery_req = atoi(pos);
+       } else if (os_strcmp(buf, "oci_freq_override_saquery_resp") == 0) {
+               bss->oci_freq_override_saquery_resp = atoi(pos);
+       } else if (os_strcmp(buf, "oci_freq_override_ft_assoc") == 0) {
+               bss->oci_freq_override_ft_assoc = atoi(pos);
+       } else if (os_strcmp(buf, "oci_freq_override_fils_assoc") == 0) {
+               bss->oci_freq_override_fils_assoc = atoi(pos);
+       } else if (os_strcmp(buf, "oci_freq_override_wnm_sleep") == 0) {
+               bss->oci_freq_override_wnm_sleep = atoi(pos);
 #endif /* CONFIG_TESTING_OPTIONS */
 #ifdef CONFIG_SAE
        } else if (os_strcmp(buf, "sae_password") == 0) {
index edc69f4703858e2d33186f904ce273b1d4996897..8a79ef7838969a9ea008d422f54d1124e35846f2 100644 (file)
@@ -1484,6 +1484,22 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
                if (os_strcmp(cmd, "ft_rsnxe_used") == 0)
                        wpa_auth_set_ft_rsnxe_used(hapd->wpa_auth,
                                                   hapd->conf->ft_rsnxe_used);
+               else if (os_strcmp(cmd, "oci_freq_override_eapol_m3") == 0)
+                       wpa_auth_set_ocv_override_freq(
+                               hapd->wpa_auth, WPA_AUTH_OCV_OVERRIDE_EAPOL_M3,
+                               atoi(value));
+               else if (os_strcmp(cmd, "oci_freq_override_eapol_g1") == 0)
+                       wpa_auth_set_ocv_override_freq(
+                               hapd->wpa_auth, WPA_AUTH_OCV_OVERRIDE_EAPOL_G1,
+                               atoi(value));
+               else if (os_strcmp(cmd, "oci_freq_override_ft_assoc") == 0)
+                       wpa_auth_set_ocv_override_freq(
+                               hapd->wpa_auth, WPA_AUTH_OCV_OVERRIDE_FT_ASSOC,
+                               atoi(value));
+               else if (os_strcmp(cmd, "oci_freq_override_fils_assoc") == 0)
+                       wpa_auth_set_ocv_override_freq(
+                               hapd->wpa_auth,
+                               WPA_AUTH_OCV_OVERRIDE_FILS_ASSOC, atoi(value));
 #endif /* CONFIG_TESTING_OPTIONS */
        }
 
index cffa636cc298d272237446565f92987f6a4308f8..c1b4b1bbb5813c9e6ea7dbeb14b7af634268559b 100644 (file)
@@ -687,6 +687,13 @@ struct hostapd_bss_config {
        int no_beacon_rsnxe;
        int skip_prune_assoc;
        int ft_rsnxe_used;
+       unsigned int oci_freq_override_eapol_m3;
+       unsigned int oci_freq_override_eapol_g1;
+       unsigned int oci_freq_override_saquery_req;
+       unsigned int oci_freq_override_saquery_resp;
+       unsigned int oci_freq_override_ft_assoc;
+       unsigned int oci_freq_override_fils_assoc;
+       unsigned int oci_freq_override_wnm_sleep;
 #endif /* CONFIG_TESTING_OPTIONS */
 
 #define MESH_ENABLED BIT(0)
index 45a07085f77e9664d19fc3b68e9b33dc1c91a11c..45683d76e57e7896c58657ff19df12e9813f4cf8 100644 (file)
@@ -73,6 +73,16 @@ void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
                                   "Failed to get channel info for OCI element in SA Query Request");
                        return;
                }
+#ifdef CONFIG_TESTING_OPTIONS
+               if (hapd->conf->oci_freq_override_saquery_req) {
+                       wpa_printf(MSG_INFO,
+                                  "TEST: Override OCI frequency %d -> %u MHz",
+                                  ci.frequency,
+                                  hapd->conf->oci_freq_override_saquery_req);
+                       ci.frequency =
+                               hapd->conf->oci_freq_override_saquery_req;
+               }
+#endif /* CONFIG_TESTING_OPTIONS */
 
                oci_ie_len = OCV_OCI_EXTENDED_LEN;
                oci_ie = os_zalloc(oci_ie_len);
@@ -152,6 +162,16 @@ static void ieee802_11_send_sa_query_resp(struct hostapd_data *hapd,
                                   "Failed to get channel info for OCI element in SA Query Response");
                        return;
                }
+#ifdef CONFIG_TESTING_OPTIONS
+               if (hapd->conf->oci_freq_override_saquery_resp) {
+                       wpa_printf(MSG_INFO,
+                                  "TEST: Override OCI frequency %d -> %u MHz",
+                                  ci.frequency,
+                                  hapd->conf->oci_freq_override_saquery_resp);
+                       ci.frequency =
+                               hapd->conf->oci_freq_override_saquery_resp;
+               }
+#endif /* CONFIG_TESTING_OPTIONS */
 
                oci_ie_len = OCV_OCI_EXTENDED_LEN;
                oci_ie = os_zalloc(oci_ie_len);
index 4a7da95138d4da51d61a5960c8c1178f22b2ea2a..248f5a1cff68ef194aa238f136d83fbe94270e6e 100644 (file)
@@ -103,6 +103,15 @@ static int ieee802_11_send_wnmsleep_resp(struct hostapd_data *hapd,
                        os_free(wnmtfs_ie);
                        return -1;
                }
+#ifdef CONFIG_TESTING_OPTIONS
+               if (hapd->conf->oci_freq_override_wnm_sleep) {
+                       wpa_printf(MSG_INFO,
+                                  "TEST: Override OCI frequency %d -> %u MHz",
+                                  ci.frequency,
+                                  hapd->conf->oci_freq_override_wnm_sleep);
+                       ci.frequency = hapd->conf->oci_freq_override_wnm_sleep;
+               }
+#endif /* CONFIG_TESTING_OPTIONS */
 
                oci_ie_len = OCV_OCI_EXTENDED_LEN;
                oci_ie = os_zalloc(oci_ie_len);
index 50b42646e7d843290bd9888d8fbd7832e2b8ce84..0efa287971e1c138a8d3b8b1ff7bc8c2318a92a9 100644 (file)
@@ -2772,6 +2772,15 @@ static struct wpabuf * fils_prepare_plainbuf(struct wpa_state_machine *sm,
                        wpabuf_clear_free(plain);
                        return NULL;
                }
+#ifdef CONFIG_TESTING_OPTIONS
+               if (conf->oci_freq_override_fils_assoc) {
+                       wpa_printf(MSG_INFO,
+                                  "TEST: Override OCI frequency %d -> %u MHz",
+                                  ci.frequency,
+                                  conf->oci_freq_override_fils_assoc);
+                       ci.frequency = conf->oci_freq_override_fils_assoc;
+               }
+#endif /* CONFIG_TESTING_OPTIONS */
 
                pos = wpabuf_put(plain, OCV_OCI_EXTENDED_LEN);
                if (ocv_insert_extended_oci(&ci, pos) < 0) {
@@ -3237,7 +3246,9 @@ static int ocv_oci_len(struct wpa_state_machine *sm)
        return 0;
 }
 
-static int ocv_oci_add(struct wpa_state_machine *sm, u8 **argpos)
+
+static int ocv_oci_add(struct wpa_state_machine *sm, u8 **argpos,
+                      unsigned int freq)
 {
 #ifdef CONFIG_OCV
        struct wpa_channel_info ci;
@@ -3250,6 +3261,14 @@ static int ocv_oci_add(struct wpa_state_machine *sm, u8 **argpos)
                           "Failed to get channel info for OCI element");
                return -1;
        }
+#ifdef CONFIG_TESTING_OPTIONS
+       if (freq) {
+               wpa_printf(MSG_INFO,
+                          "TEST: Override OCI KDE frequency %d -> %u MHz",
+                          ci.frequency, freq);
+               ci.frequency = freq;
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
 
        return ocv_insert_oci_kde(&ci, argpos);
 #else /* CONFIG_OCV */
@@ -3466,7 +3485,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
                                  gtk, gtk_len);
        }
        pos = ieee80211w_kde_add(sm, pos);
-       if (ocv_oci_add(sm, &pos) < 0)
+       if (ocv_oci_add(sm, &pos, conf->oci_freq_override_eapol_m3) < 0)
                goto done;
 
 #ifdef CONFIG_IEEE80211R_AP
@@ -3816,7 +3835,8 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
                pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2,
                                  gtk, gsm->GTK_len);
                pos = ieee80211w_kde_add(sm, pos);
-               if (ocv_oci_add(sm, &pos) < 0) {
+               if (ocv_oci_add(sm, &pos,
+                               conf->oci_freq_override_eapol_g1) < 0) {
                        os_free(kde_buf);
                        return;
                }
@@ -5299,6 +5319,7 @@ int wpa_auth_resend_m3(struct wpa_state_machine *sm,
        u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde, *pos;
        u8 *opos;
        size_t gtk_len, kde_len;
+       struct wpa_auth_config *conf = &sm->wpa_auth->conf;
        struct wpa_group *gsm = sm->group;
        u8 *wpa_ie;
        int wpa_ie_len, secure, gtkidx, encr = 0;
@@ -5409,7 +5430,7 @@ int wpa_auth_resend_m3(struct wpa_state_machine *sm,
                opos += 2 + RSN_SELECTOR_LEN + 2;
                os_memset(opos, 0, 6); /* clear PN */
        }
-       if (ocv_oci_add(sm, &pos) < 0) {
+       if (ocv_oci_add(sm, &pos, conf->oci_freq_override_eapol_m3) < 0) {
                os_free(kde);
                return -1;
        }
@@ -5417,9 +5438,7 @@ int wpa_auth_resend_m3(struct wpa_state_machine *sm,
 #ifdef CONFIG_IEEE80211R_AP
        if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
                int res;
-               struct wpa_auth_config *conf;
 
-               conf = &sm->wpa_auth->conf;
                if (sm->assoc_resp_ftie &&
                    kde + kde_len - pos >= 2 + sm->assoc_resp_ftie[1]) {
                        os_memcpy(pos, sm->assoc_resp_ftie,
@@ -5476,6 +5495,7 @@ int wpa_auth_resend_group_m1(struct wpa_state_machine *sm,
                             void *ctx1, void *ctx2)
 {
        u8 rsc[WPA_KEY_RSC_LEN];
+       struct wpa_auth_config *conf = &sm->wpa_auth->conf;
        struct wpa_group *gsm = sm->group;
        const u8 *kde;
        u8 *kde_buf = NULL, *pos, hdr[2];
@@ -5510,7 +5530,8 @@ int wpa_auth_resend_group_m1(struct wpa_state_machine *sm,
                        opos += 2 + RSN_SELECTOR_LEN + 2;
                        os_memset(opos, 0, 6); /* clear PN */
                }
-               if (ocv_oci_add(sm, &pos) < 0) {
+               if (ocv_oci_add(sm, &pos,
+                               conf->oci_freq_override_eapol_g1) < 0) {
                        os_free(kde_buf);
                        return -1;
                }
@@ -5552,4 +5573,27 @@ void wpa_auth_set_ft_rsnxe_used(struct wpa_authenticator *wpa_auth, int val)
                wpa_auth->conf.ft_rsnxe_used = val;
 }
 
+
+void wpa_auth_set_ocv_override_freq(struct wpa_authenticator *wpa_auth,
+                                   enum wpa_auth_ocv_override_frame frame,
+                                   unsigned int freq)
+{
+       if (!wpa_auth)
+               return;
+       switch (frame) {
+       case WPA_AUTH_OCV_OVERRIDE_EAPOL_M3:
+               wpa_auth->conf.oci_freq_override_eapol_m3 = freq;
+               break;
+       case WPA_AUTH_OCV_OVERRIDE_EAPOL_G1:
+               wpa_auth->conf.oci_freq_override_eapol_g1 = freq;
+               break;
+       case WPA_AUTH_OCV_OVERRIDE_FT_ASSOC:
+               wpa_auth->conf.oci_freq_override_ft_assoc = freq;
+               break;
+       case WPA_AUTH_OCV_OVERRIDE_FILS_ASSOC:
+               wpa_auth->conf.oci_freq_override_fils_assoc = freq;
+               break;
+       }
+}
+
 #endif /* CONFIG_TESTING_OPTIONS */
index 90b1885995bbe731ae74c5182d98182fa908f958..e059f3db3fcba03b35056e150424b08d2a79193f 100644 (file)
@@ -241,6 +241,10 @@ struct wpa_auth_config {
        unsigned int igtk_rsc_override_set:1;
        int ft_rsnxe_used;
 #endif /* CONFIG_TESTING_OPTIONS */
+       unsigned int oci_freq_override_eapol_m3;
+       unsigned int oci_freq_override_eapol_g1;
+       unsigned int oci_freq_override_ft_assoc;
+       unsigned int oci_freq_override_fils_assoc;
 #ifdef CONFIG_P2P
        u8 ip_addr_go[4];
        u8 ip_addr_mask[4];
@@ -526,4 +530,14 @@ int wpa_auth_rekey_gtk(struct wpa_authenticator *wpa_auth);
 void wpa_auth_set_ptk_rekey_timer(struct wpa_state_machine *sm);
 void wpa_auth_set_ft_rsnxe_used(struct wpa_authenticator *wpa_auth, int val);
 
+enum wpa_auth_ocv_override_frame {
+       WPA_AUTH_OCV_OVERRIDE_EAPOL_M3,
+       WPA_AUTH_OCV_OVERRIDE_EAPOL_G1,
+       WPA_AUTH_OCV_OVERRIDE_FT_ASSOC,
+       WPA_AUTH_OCV_OVERRIDE_FILS_ASSOC,
+};
+void wpa_auth_set_ocv_override_freq(struct wpa_authenticator *wpa_auth,
+                                   enum wpa_auth_ocv_override_frame frame,
+                                   unsigned int freq);
+
 #endif /* WPA_AUTH_H */
index 570e2ee4a58e63347b8aa0f7ad2d5708e95e52c2..db272d41e4d4145ca91334789ef76abef1af03da 100644 (file)
@@ -2661,6 +2661,15 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
                                os_free(subelem);
                                return NULL;
                        }
+#ifdef CONFIG_TESTING_OPTIONS
+                       if (conf->oci_freq_override_ft_assoc) {
+                               wpa_printf(MSG_INFO,
+                                          "TEST: Override OCI frequency %d -> %u MHz",
+                                          ci.frequency,
+                                          conf->oci_freq_override_ft_assoc);
+                               ci.frequency = conf->oci_freq_override_ft_assoc;
+                       }
+#endif /* CONFIG_TESTING_OPTIONS */
 
                        subelem_len += 2 + OCV_OCI_LEN;
                        nbuf = os_realloc(subelem, subelem_len);
index e1da56da91c00067b77a52f6a20c777be621704f..b90c9ef612d2836f62aa33ba3217c6da3c703501 100644 (file)
@@ -175,6 +175,11 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
                wconf->igtk_rsc_override_set = 1;
        }
        wconf->ft_rsnxe_used = conf->ft_rsnxe_used;
+       wconf->oci_freq_override_eapol_m3 = conf->oci_freq_override_eapol_m3;
+       wconf->oci_freq_override_eapol_g1 = conf->oci_freq_override_eapol_g1;
+       wconf->oci_freq_override_ft_assoc = conf->oci_freq_override_ft_assoc;
+       wconf->oci_freq_override_fils_assoc =
+               conf->oci_freq_override_fils_assoc;
 #endif /* CONFIG_TESTING_OPTIONS */
 #ifdef CONFIG_P2P
        os_memcpy(wconf->ip_addr_go, conf->ip_addr_go, 4);