hostapd: Allow external management frame processing or testing
authorJouni Malinen <j@w1.fi>
Thu, 26 Dec 2013 06:35:22 +0000 (08:35 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 26 Dec 2013 14:55:45 +0000 (16:55 +0200)
This enables more convenient protocol testing of station side
functionality in various error cases and unexpected sequences without
having to implement each test scenario within hostapd.
ext_mgmt_frame_handle parameter can be set to 1 to move all management
frame processing into an external program through control interface
events (MGMT-RX and MGMT-TX-STATUS) and command (MGMT_TX).

Signed-hostap: Jouni Malinen <j@w1.fi>

hostapd/ctrl_iface.c
src/ap/hostapd.h
src/ap/ieee802_11.c

index 2d0379f..427c054 100644 (file)
@@ -994,6 +994,10 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
                else
                        hapd->gas_frag_limit = val;
 #endif /* CONFIG_INTERWORKING */
+#ifdef CONFIG_TESTING_OPTIONS
+       } else if (os_strcasecmp(cmd, "ext_mgmt_frame_handling") == 0) {
+               hapd->ext_mgmt_frame_handling = atoi(value);
+#endif /* CONFIG_TESTING_OPTIONS */
        } else {
                ret = hostapd_set_iface(hapd->iconf, hapd->conf, cmd, value);
        }
@@ -1051,6 +1055,7 @@ static int hostapd_ctrl_iface_disable(struct hostapd_iface *iface)
 
 
 #ifdef CONFIG_TESTING_OPTIONS
+
 static int hostapd_ctrl_iface_radar(struct hostapd_data *hapd, char *cmd)
 {
        union wpa_event_data data;
@@ -1108,6 +1113,35 @@ static int hostapd_ctrl_iface_radar(struct hostapd_data *hapd, char *cmd)
 
        return 0;
 }
+
+
+static int hostapd_ctrl_iface_mgmt_tx(struct hostapd_data *hapd, char *cmd)
+{
+       size_t len;
+       u8 *buf;
+       int res;
+
+       wpa_printf(MSG_DEBUG, "External MGMT TX: %s", cmd);
+
+       len = os_strlen(cmd);
+       if (len & 1)
+               return -1;
+       len /= 2;
+
+       buf = os_malloc(len);
+       if (buf == NULL)
+               return -1;
+
+       if (hexstr2bin(cmd, buf, len) < 0) {
+               os_free(buf);
+               return -1;
+       }
+
+       res = hostapd_drv_send_mlme(hapd, buf, len, 0);
+       os_free(buf);
+       return res;
+}
+
 #endif /* CONFIG_TESTING_OPTIONS */
 
 
@@ -1312,6 +1346,9 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
        } else if (os_strncmp(buf, "RADAR ", 6) == 0) {
                if (hostapd_ctrl_iface_radar(hapd, buf + 6))
                        reply_len = -1;
+       } else if (os_strncmp(buf, "MGMT_TX ", 8) == 0) {
+               if (hostapd_ctrl_iface_mgmt_tx(hapd, buf + 8))
+                       reply_len = -1;
 #endif /* CONFIG_TESTING_OPTIONS */
        } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
                if (hostapd_ctrl_iface_chan_switch(hapd, buf + 12))
index d4f275e..489ab16 100644 (file)
@@ -240,6 +240,10 @@ struct hostapd_data {
        u8 sae_token_key[8];
        struct os_reltime last_sae_token_key_update;
 #endif /* CONFIG_SAE */
+
+#ifdef CONFIG_TESTING_OPTIONS
+       int ext_mgmt_frame_handling;
+#endif /* CONFIG_TESTING_OPTIONS */
 };
 
 
index 88f575a..7c550e4 100644 (file)
@@ -1725,6 +1725,19 @@ void ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
        int broadcast;
        u16 fc, stype;
 
+#ifdef CONFIG_TESTING_OPTIONS
+       if (hapd->ext_mgmt_frame_handling) {
+               size_t hex_len = 2 * len + 1;
+               char *hex = os_malloc(hex_len);
+               if (hex) {
+                       wpa_snprintf_hex(hex, hex_len, buf, len);
+                       wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-RX %s", hex);
+                       os_free(hex);
+               }
+               return;
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
+
        if (len < 24)
                return;
 
@@ -2074,6 +2087,14 @@ void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len,
        const struct ieee80211_mgmt *mgmt;
        mgmt = (const struct ieee80211_mgmt *) buf;
 
+#ifdef CONFIG_TESTING_OPTIONS
+       if (hapd->ext_mgmt_frame_handling) {
+               wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-TX-STATUS stype=%u ok=%d",
+                       stype, ok);
+               return;
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
+
        switch (stype) {
        case WLAN_FC_STYPE_AUTH:
                wpa_printf(MSG_DEBUG, "mgmt::auth cb");