Add station table query to wpa_supplicant AP ctrl_iface
authorJouni Malinen <jouni.malinen@atheros.com>
Tue, 8 Sep 2009 09:58:02 +0000 (12:58 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 8 Sep 2009 09:58:02 +0000 (12:58 +0300)
"wpa_cli all_sta" and "wpa_cli sta <addr>" can now be used to fetch
information about stations associated with the
wpa_supplicant-controlled AP.

wpa_supplicant/Makefile
wpa_supplicant/ap.c
wpa_supplicant/ap.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/wpa_cli.c

index e4bef96..ea1c26b 100644 (file)
@@ -525,6 +525,9 @@ OBJS += ../hostapd/ieee802_1x.o
 OBJS += ../hostapd/eapol_sm.o
 OBJS += ../hostapd/ieee802_11_auth.o
 OBJS += ../hostapd/drv_callbacks.o
+ifdef CONFIG_CTRL_IFACE
+OBJS += ../hostapd/ctrl_iface_ap.o
+endif
 ifdef CONFIG_IEEE80211R
 OBJS += ../hostapd/wpa_ft.o
 endif
index c4065dc..7886ee0 100644 (file)
@@ -22,6 +22,7 @@
 #include "../hostapd/ieee802_11.h"
 #endif /* NEED_AP_MLME */
 #include "../hostapd/wps_hostapd.h"
+#include "../hostapd/ctrl_iface_ap.h"
 #include "eap_common/eap_defs.h"
 #include "eap_server/eap_methods.h"
 #include "eap_common/eap_wsc_common.h"
@@ -551,3 +552,33 @@ int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
 }
 
 #endif /* CONFIG_WPS */
+
+
+int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s,
+                           char *buf, size_t buflen)
+{
+       if (wpa_s->ap_iface == NULL)
+               return -1;
+       return hostapd_ctrl_iface_sta_first(wpa_s->ap_iface->bss[0],
+                                           buf, buflen);
+}
+
+
+int ap_ctrl_iface_sta(struct wpa_supplicant *wpa_s, const char *txtaddr,
+                     char *buf, size_t buflen)
+{
+       if (wpa_s->ap_iface == NULL)
+               return -1;
+       return hostapd_ctrl_iface_sta(wpa_s->ap_iface->bss[0], txtaddr,
+                                     buf, buflen);
+}
+
+
+int ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr,
+                          char *buf, size_t buflen)
+{
+       if (wpa_s->ap_iface == NULL)
+               return -1;
+       return hostapd_ctrl_iface_sta_next(wpa_s->ap_iface->bss[0], txtaddr,
+                                          buf, buflen);
+}
index 935dba1..0264a3e 100644 (file)
@@ -24,5 +24,11 @@ void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
 int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid);
 int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
                              const char *pin, char *buf, size_t buflen);
+int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s,
+                           char *buf, size_t buflen);
+int ap_ctrl_iface_sta(struct wpa_supplicant *wpa_s, const char *txtaddr,
+                     char *buf, size_t buflen);
+int ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr,
+                          char *buf, size_t buflen);
 
 #endif /* AP_H */
index 5e2030e..f1362b5 100644 (file)
@@ -1735,6 +1735,16 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
        } else if (os_strncmp(buf, "BSS ", 4) == 0) {
                reply_len = wpa_supplicant_ctrl_iface_bss(
                        wpa_s, buf + 4, reply, reply_size);
+#ifdef CONFIG_AP
+       } else if (os_strcmp(buf, "STA-FIRST") == 0) {
+               reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
+       } else if (os_strncmp(buf, "STA ", 4) == 0) {
+               reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply,
+                                             reply_size);
+       } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
+               reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
+                                                  reply_size);
+#endif /* CONFIG_AP */
        } else {
                os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
                reply_len = 16;
index b5b3469..ec103bf 100644 (file)
@@ -1164,6 +1164,71 @@ static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
 }
 
 
+#ifdef CONFIG_AP
+static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+       char buf[64];
+       if (argc != 1) {
+               printf("Invalid 'sta' command - exactly one argument, STA "
+                      "address, is required.\n");
+               return -1;
+       }
+       snprintf(buf, sizeof(buf), "STA %s", argv[0]);
+       return wpa_ctrl_command(ctrl, buf);
+}
+
+
+static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
+                               char *addr, size_t addr_len)
+{
+       char buf[4096], *pos;
+       size_t len;
+       int ret;
+
+       if (ctrl_conn == NULL) {
+               printf("Not connected to hostapd - command dropped.\n");
+               return -1;
+       }
+       len = sizeof(buf) - 1;
+       ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
+                              wpa_cli_msg_cb);
+       if (ret == -2) {
+               printf("'%s' command timed out.\n", cmd);
+               return -2;
+       } else if (ret < 0) {
+               printf("'%s' command failed.\n", cmd);
+               return -1;
+       }
+
+       buf[len] = '\0';
+       if (memcmp(buf, "FAIL", 4) == 0)
+               return -1;
+       printf("%s", buf);
+
+       pos = buf;
+       while (*pos != '\0' && *pos != '\n')
+               pos++;
+       *pos = '\0';
+       os_strlcpy(addr, buf, addr_len);
+       return 0;
+}
+
+
+static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+       char addr[32], cmd[64];
+
+       if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
+               return 0;
+       do {
+               snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
+       } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
+
+       return -1;
+}
+#endif /* CONFIG_AP */
+
+
 enum wpa_cli_cmd_flags {
        cli_cmd_flag_none               = 0x00,
        cli_cmd_flag_sensitive          = 0x01
@@ -1335,6 +1400,14 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
        { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
          cli_cmd_flag_none,
          "<addr> = request RSN authentication with <addr> in IBSS" },
+#ifdef CONFIG_AP
+       { "sta", wpa_cli_cmd_sta,
+         cli_cmd_flag_none,
+         "<addr> = get information about an associated station (AP)" },
+       { "all_sta", wpa_cli_cmd_all_sta,
+         cli_cmd_flag_none,
+         "= get information about all associated stations (AP)" },
+#endif /* CONFIG_AP */
        { NULL, NULL, cli_cmd_flag_none, NULL }
 };