Added ctrl_interface command for sending a SA Query request
authorJouni Malinen <jouni.malinen@atheros.com>
Tue, 30 Dec 2008 16:04:29 +0000 (18:04 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 30 Dec 2008 16:04:29 +0000 (18:04 +0200)
This can be useful for testing IEEE 802.11w functionality, so provide
means for manual request to send a SA Query request.

hostapd/ctrl_iface.c
hostapd/hostapd_cli.c
hostapd/ieee802_11.c
hostapd/ieee802_11.h
hostapd/sta_info.c

index f8b3a1d..7afd859 100644 (file)
@@ -218,6 +218,26 @@ static int hostapd_ctrl_iface_new_sta(struct hostapd_data *hapd,
 }
 
 
+#ifdef CONFIG_IEEE80211W
+static int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd,
+                                      const char *txtaddr)
+{
+       u8 addr[ETH_ALEN];
+       u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];
+
+       wpa_printf(MSG_DEBUG, "CTRL_IFACE SA_QUERY %s", txtaddr);
+
+       if (hwaddr_aton(txtaddr, addr))
+               return -1;
+
+       os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN);
+       ieee802_11_send_sa_query_req(hapd, addr, trans_id);
+
+       return 0;
+}
+#endif /* CONFIG_IEEE80211W */
+
+
 #ifdef CONFIG_WPS
 static int hostapd_ctrl_iface_wps_pin(struct hostapd_data *hapd, char *txt)
 {
@@ -313,6 +333,11 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
        } else if (os_strncmp(buf, "NEW_STA ", 8) == 0) {
                if (hostapd_ctrl_iface_new_sta(hapd, buf + 8))
                        reply_len = -1;
+#ifdef CONFIG_IEEE80211W
+       } else if (os_strncmp(buf, "SA_QUERY ", 9) == 0) {
+               if (hostapd_ctrl_iface_sa_query(hapd, buf + 9))
+                       reply_len = -1;
+#endif /* CONFIG_IEEE80211W */
 #ifdef CONFIG_WPS
        } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
                if (hostapd_ctrl_iface_wps_pin(hapd, buf + 8))
index e5285ae..68ff091 100644 (file)
@@ -83,6 +83,9 @@ static const char *commands_help =
 "   sta <addr>           get MIB variables for one station\n"
 "   all_sta              get MIB variables for all stations\n"
 "   new_sta <addr>       add a new station\n"
+#ifdef CONFIG_IEEE80211W
+"   sa_query <addr>      send SA Query to a station\n"
+#endif /* CONFIG_IEEE80211W */
 #ifdef CONFIG_WPS
 "   wps_pin <uuid> <pin> add WPS Enrollee PIN (Device Password)\n"
 "   wps_pbc              indicate button pushed to initiate PBC\n"
@@ -234,6 +237,22 @@ static int hostapd_cli_cmd_new_sta(struct wpa_ctrl *ctrl, int argc,
 }
 
 
+#ifdef CONFIG_IEEE80211W
+static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc,
+                                   char *argv[])
+{
+       char buf[64];
+       if (argc != 1) {
+               printf("Invalid 'sa_query' command - exactly one argument, "
+                      "STA address, is required.\n");
+               return -1;
+       }
+       snprintf(buf, sizeof(buf), "SA_QUERY %s", argv[0]);
+       return wpa_ctrl_command(ctrl, buf);
+}
+#endif /* CONFIG_IEEE80211W */
+
+
 #ifdef CONFIG_WPS
 static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc,
                                   char *argv[])
@@ -405,6 +424,9 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = {
        { "sta", hostapd_cli_cmd_sta },
        { "all_sta", hostapd_cli_cmd_all_sta },
        { "new_sta", hostapd_cli_cmd_new_sta },
+#ifdef CONFIG_IEEE80211W
+       { "sa_query", hostapd_cli_cmd_sa_query },
+#endif /* CONFIG_IEEE80211W */
 #ifdef CONFIG_WPS
        { "wps_pin", hostapd_cli_cmd_wps_pin },
        { "wps_pbc", hostapd_cli_cmd_wps_pbc },
index 904b789..dc79a91 100644 (file)
@@ -1250,6 +1250,31 @@ static void handle_beacon(struct hostapd_data *hapd,
 
 
 #ifdef CONFIG_IEEE80211W
+
+/* MLME-SAQuery.request */
+void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
+                                 const u8 *addr, const u8 *trans_id)
+{
+       struct ieee80211_mgmt mgmt;
+       u8 *end;
+
+       os_memset(&mgmt, 0, sizeof(mgmt));
+       mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
+                                         WLAN_FC_STYPE_ACTION);
+       os_memcpy(mgmt.da, addr, ETH_ALEN);
+       os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
+       os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
+       mgmt.u.action.category = WLAN_ACTION_SA_QUERY;
+       mgmt.u.action.u.sa_query_req.action = WLAN_SA_QUERY_REQUEST;
+       os_memcpy(mgmt.u.action.u.sa_query_req.trans_id, trans_id,
+                 WLAN_SA_QUERY_TR_ID_LEN);
+       end = mgmt.u.action.u.sa_query_req.trans_id + WLAN_SA_QUERY_TR_ID_LEN;
+       if (hostapd_send_mgmt_frame(hapd, &mgmt, IEEE80211_HDRLEN +
+                                   end - (u8 *) &mgmt, 0) < 0)
+               perror("ieee802_11_send_sa_query_req: send");
+}
+
+
 static void hostapd_sa_query_action(struct hostapd_data *hapd,
                                    struct ieee80211_mgmt *mgmt, size_t len)
 {
index bb88ede..ca8ef93 100644 (file)
@@ -50,5 +50,7 @@ u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_ht_capabilities_info(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid);
 int hostapd_ht_operation_update(struct hostapd_iface *iface);
+void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
+                                 const u8 *addr, const u8 *trans_id);
 
 #endif /* IEEE802_11_H */
index df11901..55745e8 100644 (file)
@@ -613,30 +613,6 @@ int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta,
 
 #ifdef CONFIG_IEEE80211W
 
-/* MLME-SAQuery.request */
-static void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
-                                        const u8 *addr, const u8 *trans_id)
-{
-       struct ieee80211_mgmt mgmt;
-       u8 *end;
-
-       os_memset(&mgmt, 0, sizeof(mgmt));
-       mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
-                                         WLAN_FC_STYPE_ACTION);
-       os_memcpy(mgmt.da, addr, ETH_ALEN);
-       os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
-       os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
-       mgmt.u.action.category = WLAN_ACTION_SA_QUERY;
-       mgmt.u.action.u.sa_query_req.action = WLAN_SA_QUERY_REQUEST;
-       os_memcpy(mgmt.u.action.u.sa_query_req.trans_id, trans_id,
-                 WLAN_SA_QUERY_TR_ID_LEN);
-       end = mgmt.u.action.u.sa_query_req.trans_id + WLAN_SA_QUERY_TR_ID_LEN;
-       if (hostapd_send_mgmt_frame(hapd, &mgmt, IEEE80211_HDRLEN +
-                                   end - (u8 *) &mgmt, 0) < 0)
-               perror("ieee802_11_send_sa_query_req: send");
-}
-
-
 int ap_check_sa_query_timeout(struct hostapd_data *hapd, struct sta_info *sta)
 {
        u32 tu;