From e653b622758d920ddb7589afb3cd8b38281fe403 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 8 Sep 2009 12:58:02 +0300 Subject: [PATCH] Add station table query to wpa_supplicant AP ctrl_iface "wpa_cli all_sta" and "wpa_cli sta " can now be used to fetch information about stations associated with the wpa_supplicant-controlled AP. --- wpa_supplicant/Makefile | 3 ++ wpa_supplicant/ap.c | 31 ++++++++++++++++ wpa_supplicant/ap.h | 6 +++ wpa_supplicant/ctrl_iface.c | 10 +++++ wpa_supplicant/wpa_cli.c | 73 +++++++++++++++++++++++++++++++++++++ 5 files changed, 123 insertions(+) diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index e4bef9680..ea1c26b20 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -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 diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index c4065dc29..7886ee0ba 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -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); +} diff --git a/wpa_supplicant/ap.h b/wpa_supplicant/ap.h index 935dba108..0264a3e4b 100644 --- a/wpa_supplicant/ap.h +++ b/wpa_supplicant/ap.h @@ -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 */ diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 5e2030ec1..f1362b532 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -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; diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index b5b346939..ec103bfb4 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -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, " = request RSN authentication with in IBSS" }, +#ifdef CONFIG_AP + { "sta", wpa_cli_cmd_sta, + cli_cmd_flag_none, + " = 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 } };