Add station table query to wpa_supplicant AP ctrl_iface

"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.
This commit is contained in:
Jouni Malinen 2009-09-08 12:58:02 +03:00 committed by Jouni Malinen
parent ded30a6b41
commit e653b62275
5 changed files with 123 additions and 0 deletions

View 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

View 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);
}

View 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 */

View 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;

View 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 }
};