summaryrefslogtreecommitdiffstats
path: root/contrib/wpa_supplicant/wpa_cli.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/wpa_supplicant/wpa_cli.c')
-rw-r--r--contrib/wpa_supplicant/wpa_cli.c604
1 files changed, 419 insertions, 185 deletions
diff --git a/contrib/wpa_supplicant/wpa_cli.c b/contrib/wpa_supplicant/wpa_cli.c
index c274723..a641249 100644
--- a/contrib/wpa_supplicant/wpa_cli.c
+++ b/contrib/wpa_supplicant/wpa_cli.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant - command line interface for wpa_supplicant daemon
- * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -12,29 +12,26 @@
* See README and COPYING for more details.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-#include <unistd.h>
+#include "includes.h"
+
+#ifdef CONFIG_CTRL_IFACE
+
+#ifdef CONFIG_CTRL_IFACE_UNIX
#include <dirent.h>
-#include <errno.h>
-#include <sys/time.h>
+#endif /* CONFIG_CTRL_IFACE_UNIX */
#ifdef CONFIG_READLINE
#include <readline/readline.h>
#include <readline/history.h>
#endif /* CONFIG_READLINE */
#include "wpa_ctrl.h"
-#ifdef CONFIG_NATIVE_WINDOWS
#include "common.h"
-#endif /* CONFIG_NATIVE_WINDOWS */
#include "version.h"
static const char *wpa_cli_version =
"wpa_cli v" VERSION_STR "\n"
-"Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi> and contributors";
+"Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> and contributors";
static const char *wpa_cli_license =
@@ -56,7 +53,7 @@ static const char *wpa_cli_full_license =
"\n"
"You should have received a copy of the GNU General Public License\n"
"along with this program; if not, write to the Free Software\n"
-"Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n"
+"Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
"\n"
"Alternatively, this software may be distributed under the terms of the\n"
"BSD license.\n"
@@ -129,12 +126,16 @@ static const char *commands_help =
" scan_results = get latest scan results\n"
" get_capability <eap/pairwise/group/key_mgmt/proto/auth_alg> = "
"get capabilies\n"
+" ap_scan <value> = set ap_scan parameter\n"
+" stkstart <addr> = request STK negotiation with <addr>\n"
" terminate = terminate wpa_supplicant\n"
" quit = exit wpa_cli\n";
static struct wpa_ctrl *ctrl_conn;
static int wpa_cli_quit = 0;
static int wpa_cli_attached = 0;
+static int wpa_cli_connected = 0;
+static int wpa_cli_last_id = 0;
static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
static char *ctrl_ifname = NULL;
static const char *pid_file = NULL;
@@ -161,26 +162,26 @@ static void usage(void)
static struct wpa_ctrl * wpa_cli_open_connection(const char *ifname)
{
-#ifdef CONFIG_CTRL_IFACE_UDP
- ctrl_conn = wpa_ctrl_open("");
+#if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
+ ctrl_conn = wpa_ctrl_open(ifname);
return ctrl_conn;
-#else /* CONFIG_CTRL_IFACE_UDP */
+#else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
char *cfile;
int flen;
if (ifname == NULL)
return NULL;
- flen = strlen(ctrl_iface_dir) + strlen(ifname) + 2;
- cfile = malloc(flen);
+ flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
+ cfile = os_malloc(flen);
if (cfile == NULL)
return NULL;
- snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
+ os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
ctrl_conn = wpa_ctrl_open(cfile);
- free(cfile);
+ os_free(cfile);
return ctrl_conn;
-#endif /* CONFIG_CTRL_IFACE_UDP */
+#endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
}
@@ -215,7 +216,7 @@ static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
return -1;
}
len = sizeof(buf) - 1;
- ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
+ ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
wpa_cli_msg_cb);
if (ret == -2) {
printf("'%s' command timed out.\n", cmd);
@@ -240,7 +241,7 @@ static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
- int verbose = argc > 0 && strcmp(argv[0], "verbose") == 0;
+ int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
}
@@ -307,6 +308,7 @@ static void wpa_cli_show_variables(void)
static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
char cmd[256];
+ int res;
if (argc == 0) {
wpa_cli_show_variables();
@@ -319,8 +321,8 @@ static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
return 0;
}
- if (snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]) >=
- sizeof(cmd) - 1) {
+ res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
+ if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long SET command.\n");
return 0;
}
@@ -351,6 +353,7 @@ static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
char cmd[256];
+ int res;
if (argc != 1) {
printf("Invalid PREAUTH command: needs one argument "
@@ -358,8 +361,8 @@ static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
return 0;
}
- if (snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]) >=
- sizeof(cmd) - 1) {
+ res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
+ if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long PREAUTH command.\n");
return 0;
}
@@ -367,15 +370,61 @@ static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
}
+static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+ char cmd[256];
+ int res;
+
+ if (argc != 1) {
+ printf("Invalid AP_SCAN command: needs one argument (ap_scan "
+ "value)\n");
+ return 0;
+ }
+ res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
+ if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+ printf("Too long AP_SCAN command.\n");
+ return 0;
+ }
+ return wpa_ctrl_command(ctrl, cmd);
+}
+
+
+static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ char cmd[256];
+ int res;
+
+ if (argc != 1) {
+ printf("Invalid STKSTART command: needs one argument "
+ "(Peer STA MAC address)\n");
+ return 0;
+ }
+
+ res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
+ if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+ printf("Too long STKSTART command.\n");
+ return 0;
+ }
+ return wpa_ctrl_command(ctrl, cmd);
+}
+
+
static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
char cmd[256];
+ int res;
+
if (argc != 1) {
printf("Invalid LEVEL command: needs one argument (debug "
"level)\n");
return 0;
}
- snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
+ res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
+ if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+ printf("Too long LEVEL command.\n");
+ return 0;
+ }
return wpa_ctrl_command(ctrl, cmd);
}
@@ -383,7 +432,7 @@ static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
char cmd[256], *pos, *end;
- int i;
+ int i, ret;
if (argc < 2) {
printf("Invalid IDENTITY command: needs two arguments "
@@ -393,10 +442,21 @@ static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
end = cmd + sizeof(cmd);
pos = cmd;
- pos += snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
- argv[0], argv[1]);
- for (i = 2; i < argc; i++)
- pos += snprintf(pos, end - pos, " %s", argv[i]);
+ ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
+ argv[0], argv[1]);
+ if (ret < 0 || ret >= end - pos) {
+ printf("Too long IDENTITY command.\n");
+ return 0;
+ }
+ pos += ret;
+ for (i = 2; i < argc; i++) {
+ ret = os_snprintf(pos, end - pos, " %s", argv[i]);
+ if (ret < 0 || ret >= end - pos) {
+ printf("Too long IDENTITY command.\n");
+ return 0;
+ }
+ pos += ret;
+ }
return wpa_ctrl_command(ctrl, cmd);
}
@@ -405,7 +465,7 @@ static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
char cmd[256], *pos, *end;
- int i;
+ int i, ret;
if (argc < 2) {
printf("Invalid PASSWORD command: needs two arguments "
@@ -415,10 +475,21 @@ static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
end = cmd + sizeof(cmd);
pos = cmd;
- pos += snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
- argv[0], argv[1]);
- for (i = 2; i < argc; i++)
- pos += snprintf(pos, end - pos, " %s", argv[i]);
+ ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
+ argv[0], argv[1]);
+ if (ret < 0 || ret >= end - pos) {
+ printf("Too long PASSWORD command.\n");
+ return 0;
+ }
+ pos += ret;
+ for (i = 2; i < argc; i++) {
+ ret = os_snprintf(pos, end - pos, " %s", argv[i]);
+ if (ret < 0 || ret >= end - pos) {
+ printf("Too long PASSWORD command.\n");
+ return 0;
+ }
+ pos += ret;
+ }
return wpa_ctrl_command(ctrl, cmd);
}
@@ -428,7 +499,7 @@ static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
char cmd[256], *pos, *end;
- int i;
+ int i, ret;
if (argc < 2) {
printf("Invalid NEW_PASSWORD command: needs two arguments "
@@ -438,10 +509,21 @@ static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
end = cmd + sizeof(cmd);
pos = cmd;
- pos += snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
- argv[0], argv[1]);
- for (i = 2; i < argc; i++)
- pos += snprintf(pos, end - pos, " %s", argv[i]);
+ ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
+ argv[0], argv[1]);
+ if (ret < 0 || ret >= end - pos) {
+ printf("Too long NEW_PASSWORD command.\n");
+ return 0;
+ }
+ pos += ret;
+ for (i = 2; i < argc; i++) {
+ ret = os_snprintf(pos, end - pos, " %s", argv[i]);
+ if (ret < 0 || ret >= end - pos) {
+ printf("Too long NEW_PASSWORD command.\n");
+ return 0;
+ }
+ pos += ret;
+ }
return wpa_ctrl_command(ctrl, cmd);
}
@@ -450,7 +532,7 @@ static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
char cmd[256], *pos, *end;
- int i;
+ int i, ret;
if (argc < 2) {
printf("Invalid PIN command: needs two arguments "
@@ -460,11 +542,21 @@ static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
end = cmd + sizeof(cmd);
pos = cmd;
- pos += snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
- argv[0], argv[1]);
- for (i = 2; i < argc; i++)
- pos += snprintf(pos, end - pos, " %s", argv[i]);
-
+ ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
+ argv[0], argv[1]);
+ if (ret < 0 || ret >= end - pos) {
+ printf("Too long PIN command.\n");
+ return 0;
+ }
+ pos += ret;
+ for (i = 2; i < argc; i++) {
+ ret = os_snprintf(pos, end - pos, " %s", argv[i]);
+ if (ret < 0 || ret >= end - pos) {
+ printf("Too long PIN command.\n");
+ return 0;
+ }
+ pos += ret;
+ }
return wpa_ctrl_command(ctrl, cmd);
}
@@ -472,7 +564,7 @@ static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
char cmd[256], *pos, *end;
- int i;
+ int i, ret;
if (argc < 2) {
printf("Invalid OTP command: needs two arguments (network "
@@ -482,10 +574,21 @@ static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
end = cmd + sizeof(cmd);
pos = cmd;
- pos += snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
- argv[0], argv[1]);
- for (i = 2; i < argc; i++)
- pos += snprintf(pos, end - pos, " %s", argv[i]);
+ ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
+ argv[0], argv[1]);
+ if (ret < 0 || ret >= end - pos) {
+ printf("Too long OTP command.\n");
+ return 0;
+ }
+ pos += ret;
+ for (i = 2; i < argc; i++) {
+ ret = os_snprintf(pos, end - pos, " %s", argv[i]);
+ if (ret < 0 || ret >= end - pos) {
+ printf("Too long OTP command.\n");
+ return 0;
+ }
+ pos += ret;
+ }
return wpa_ctrl_command(ctrl, cmd);
}
@@ -495,7 +598,7 @@ static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
char cmd[256], *pos, *end;
- int i;
+ int i, ret;
if (argc < 2) {
printf("Invalid PASSPHRASE command: needs two arguments "
@@ -505,10 +608,21 @@ static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
end = cmd + sizeof(cmd);
pos = cmd;
- pos += snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
- argv[0], argv[1]);
- for (i = 2; i < argc; i++)
- pos += snprintf(pos, end - pos, " %s", argv[i]);
+ ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
+ argv[0], argv[1]);
+ if (ret < 0 || ret >= end - pos) {
+ printf("Too long PASSPHRASE command.\n");
+ return 0;
+ }
+ pos += ret;
+ for (i = 2; i < argc; i++) {
+ ret = os_snprintf(pos, end - pos, " %s", argv[i]);
+ if (ret < 0 || ret >= end - pos) {
+ printf("Too long PASSPHRASE command.\n");
+ return 0;
+ }
+ pos += ret;
+ }
return wpa_ctrl_command(ctrl, cmd);
}
@@ -517,7 +631,7 @@ static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
char cmd[256], *pos, *end;
- int i;
+ int i, ret;
if (argc < 2) {
printf("Invalid BSSID command: needs two arguments (network "
@@ -527,9 +641,20 @@ static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
end = cmd + sizeof(cmd);
pos = cmd;
- pos += snprintf(pos, end - pos, "BSSID");
- for (i = 0; i < argc; i++)
- pos += snprintf(pos, end - pos, " %s", argv[i]);
+ ret = os_snprintf(pos, end - pos, "BSSID");
+ if (ret < 0 || ret >= end - pos) {
+ printf("Too long BSSID command.\n");
+ return 0;
+ }
+ pos += ret;
+ for (i = 0; i < argc; i++) {
+ ret = os_snprintf(pos, end - pos, " %s", argv[i]);
+ if (ret < 0 || ret >= end - pos) {
+ printf("Too long BSSID command.\n");
+ return 0;
+ }
+ pos += ret;
+ }
return wpa_ctrl_command(ctrl, cmd);
}
@@ -553,7 +678,8 @@ static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
return 0;
}
- snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
+ os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
+ cmd[sizeof(cmd) - 1] = '\0';
return wpa_ctrl_command(ctrl, cmd);
}
@@ -570,7 +696,8 @@ static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
return 0;
}
- snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
+ os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
+ cmd[sizeof(cmd) - 1] = '\0';
return wpa_ctrl_command(ctrl, cmd);
}
@@ -587,7 +714,8 @@ static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
return 0;
}
- snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
+ os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
+ cmd[sizeof(cmd) - 1] = '\0';
return wpa_ctrl_command(ctrl, cmd);
}
@@ -611,7 +739,8 @@ static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
return 0;
}
- snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
+ os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
+ cmd[sizeof(cmd) - 1] = '\0';
return wpa_ctrl_command(ctrl, cmd);
}
@@ -642,6 +771,7 @@ static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
char cmd[256];
+ int res;
if (argc == 0) {
wpa_cli_show_network_variables();
@@ -654,8 +784,9 @@ static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
return 0;
}
- if (snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
- argv[0], argv[1], argv[2]) >= sizeof(cmd) - 1) {
+ res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
+ argv[0], argv[1], argv[2]);
+ if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long SET_NETWORK command.\n");
return 0;
}
@@ -667,6 +798,7 @@ static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
char cmd[256];
+ int res;
if (argc == 0) {
wpa_cli_show_network_variables();
@@ -679,8 +811,9 @@ static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
return 0;
}
- if (snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
- argv[0], argv[1]) >= sizeof(cmd) - 1) {
+ res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
+ argv[0], argv[1]);
+ if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long GET_NETWORK command.\n");
return 0;
}
@@ -720,37 +853,30 @@ static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
{
char cmd[64];
- if (argc != 1) {
- printf("Invalid GET_CAPABILITY command: needs one argument\n");
+ if (argc < 1 || argc > 2) {
+ printf("Invalid GET_CAPABILITY command: need either one or "
+ "two arguments\n");
+ return 0;
+ }
+
+ if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
+ printf("Invalid GET_CAPABILITY command: second argument, "
+ "if any, must be 'strict'\n");
return 0;
}
- snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s", argv[0]);
+ os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
+ (argc == 2) ? " strict" : "");
+ cmd[sizeof(cmd) - 1] = '\0';
return wpa_ctrl_command(ctrl, cmd);
}
-static void wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
+static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
{
- struct dirent *dent;
- DIR *dir;
-
- dir = opendir(ctrl_iface_dir);
- if (dir == NULL) {
- printf("Control interface directory '%s' could not be "
- "openned.\n", ctrl_iface_dir);
- return;
- }
-
printf("Available interfaces:\n");
- while ((dent = readdir(dir))) {
- if (strcmp(dent->d_name, ".") == 0 ||
- strcmp(dent->d_name, "..") == 0)
- continue;
- printf("%s\n", dent->d_name);
- }
- closedir(dir);
+ return wpa_ctrl_command(ctrl, "INTERFACES");
}
@@ -762,8 +888,8 @@ static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
}
wpa_cli_close_connection();
- free(ctrl_ifname);
- ctrl_ifname = strdup(argv[0]);
+ os_free(ctrl_ifname);
+ ctrl_ifname = os_strdup(argv[0]);
if (wpa_cli_open_connection(ctrl_ifname)) {
printf("Connected to interface '%s.\n", ctrl_ifname);
@@ -804,17 +930,20 @@ static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
printf("Invalid INTERFACE_ADD command: needs at least one "
"argument (interface name)\n"
"All arguments: ifname confname driver ctrl_interface "
- "driver_param\n");
+ "driver_param bridge_name\n");
return 0;
}
/*
* INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
- * <driver_param>
+ * <driver_param>TAB<bridge_name>
*/
- snprintf(cmd, sizeof(cmd), "INTERFACE_ADD %s\t%s\t%s\t%s\t%s", argv[0],
- argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
- argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "");
+ os_snprintf(cmd, sizeof(cmd), "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
+ argv[0],
+ argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
+ argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
+ argc > 5 ? argv[5] : "");
+ cmd[sizeof(cmd) - 1] = '\0';
return wpa_ctrl_command(ctrl, cmd);
}
@@ -830,7 +959,8 @@ static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
return 0;
}
- snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
+ os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
+ cmd[sizeof(cmd) - 1] = '\0';
return wpa_ctrl_command(ctrl, cmd);
}
@@ -879,6 +1009,8 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
{ "terminate", wpa_cli_cmd_terminate },
{ "interface_add", wpa_cli_cmd_interface_add },
{ "interface_remove", wpa_cli_cmd_interface_remove },
+ { "ap_scan", wpa_cli_cmd_ap_scan },
+ { "stkstart", wpa_cli_cmd_stkstart },
{ NULL, NULL }
};
@@ -891,9 +1023,10 @@ static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
count = 0;
cmd = wpa_cli_commands;
while (cmd->cmd) {
- if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0) {
+ if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
+ {
match = cmd;
- if (strcasecmp(cmd->cmd, argv[0]) == 0) {
+ if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
/* we have an exact match */
count = 1;
break;
@@ -907,8 +1040,8 @@ static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
printf("Ambiguous command '%s'; possible commands:", argv[0]);
cmd = wpa_cli_commands;
while (cmd->cmd) {
- if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) ==
- 0) {
+ if (os_strncasecmp(cmd->cmd, argv[0],
+ os_strlen(argv[0])) == 0) {
printf(" %s", cmd->cmd);
}
cmd++;
@@ -924,7 +1057,7 @@ static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
static int str_match(const char *a, const char *b)
{
- return strncmp(a, b, strlen(b)) == 0;
+ return os_strncmp(a, b, os_strlen(b)) == 0;
}
@@ -934,13 +1067,16 @@ static int wpa_cli_exec(const char *program, const char *arg1,
char *cmd;
size_t len;
- len = strlen(program) + strlen(arg1) + strlen(arg2) + 3;
- cmd = malloc(len);
+ len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
+ cmd = os_malloc(len);
if (cmd == NULL)
return -1;
- snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
+ os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
+ cmd[len - 1] = '\0';
+#ifndef _WIN32_WCE
system(cmd);
- free(cmd);
+#endif /* _WIN32_WCE */
+ os_free(cmd);
return 0;
}
@@ -949,11 +1085,12 @@ static int wpa_cli_exec(const char *program, const char *arg1,
static void wpa_cli_action_process(const char *msg)
{
const char *pos;
+ char *copy = NULL, *id, *pos2;
pos = msg;
if (*pos == '<') {
/* skip priority */
- pos = strchr(pos, '>');
+ pos = os_strchr(pos, '>');
if (pos)
pos++;
else
@@ -961,9 +1098,46 @@ static void wpa_cli_action_process(const char *msg)
}
if (str_match(pos, WPA_EVENT_CONNECTED)) {
- wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
+ int new_id = -1;
+ os_unsetenv("WPA_ID");
+ os_unsetenv("WPA_ID_STR");
+ os_unsetenv("WPA_CTRL_DIR");
+
+ pos = os_strstr(pos, "[id=");
+ if (pos)
+ copy = os_strdup(pos + 4);
+
+ if (copy) {
+ pos2 = id = copy;
+ while (*pos2 && *pos2 != ' ')
+ pos2++;
+ *pos2++ = '\0';
+ new_id = atoi(id);
+ os_setenv("WPA_ID", id, 1);
+ while (*pos2 && *pos2 != '=')
+ pos2++;
+ if (*pos2 == '=')
+ pos2++;
+ id = pos2;
+ while (*pos2 && *pos2 != ']')
+ pos2++;
+ *pos2 = '\0';
+ os_setenv("WPA_ID_STR", id, 1);
+ os_free(copy);
+ }
+
+ os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
+
+ if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
+ wpa_cli_connected = 1;
+ wpa_cli_last_id = new_id;
+ wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
+ }
} else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
- wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
+ if (wpa_cli_connected) {
+ wpa_cli_connected = 0;
+ wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
+ }
} else if (str_match(pos, WPA_EVENT_TERMINATING)) {
printf("wpa_supplicant is terminating - stop monitoring\n");
wpa_cli_quit = 1;
@@ -971,19 +1145,39 @@ static void wpa_cli_action_process(const char *msg)
}
+#ifndef CONFIG_ANSI_C_EXTRA
static void wpa_cli_action_cb(char *msg, size_t len)
{
wpa_cli_action_process(msg);
}
+#endif /* CONFIG_ANSI_C_EXTRA */
+
+
+static void wpa_cli_reconnect(void)
+{
+ wpa_cli_close_connection();
+ ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
+ if (ctrl_conn) {
+ printf("Connection to wpa_supplicant re-established\n");
+ if (wpa_ctrl_attach(ctrl_conn) == 0) {
+ wpa_cli_attached = 1;
+ } else {
+ printf("Warning: Failed to attach to "
+ "wpa_supplicant.\n");
+ }
+ }
+}
static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
int action_monitor)
{
int first = 1;
- if (ctrl_conn == NULL)
+ if (ctrl_conn == NULL) {
+ wpa_cli_reconnect();
return;
- while (wpa_ctrl_pending(ctrl)) {
+ }
+ while (wpa_ctrl_pending(ctrl) > 0) {
char buf[256];
size_t len = sizeof(buf) - 1;
if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
@@ -1001,6 +1195,12 @@ static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
break;
}
}
+
+ if (wpa_ctrl_pending(ctrl) < 0) {
+ printf("Connection to wpa_supplicant lost - trying to "
+ "reconnect\n");
+ wpa_cli_reconnect();
+ }
}
@@ -1012,13 +1212,13 @@ static char * wpa_cli_cmd_gen(const char *text, int state)
if (state == 0) {
i = 0;
- len = strlen(text);
+ len = os_strlen(text);
}
while ((cmd = wpa_cli_commands[i].cmd)) {
i++;
- if (strncasecmp(cmd, text, len) == 0)
- return strdup(cmd);
+ if (os_strncasecmp(cmd, text, len) == 0)
+ return os_strdup(cmd);
}
return NULL;
@@ -1055,10 +1255,11 @@ static void wpa_cli_interactive(void)
home = getenv("HOME");
if (home) {
const char *fname = ".wpa_cli_history";
- int hfile_len = strlen(home) + 1 + strlen(fname) + 1;
- hfile = malloc(hfile_len);
+ int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
+ hfile = os_malloc(hfile_len);
if (hfile) {
- snprintf(hfile, hfile_len, "%s/%s", home, fname);
+ os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
+ hfile[hfile_len - 1] = '\0';
read_history(hfile);
stifle_history(100);
}
@@ -1077,7 +1278,7 @@ static void wpa_cli_interactive(void)
while (next_history())
;
h = previous_history();
- if (h == NULL || strcmp(cmd, h->line) != 0)
+ if (h == NULL || os_strcmp(cmd, h->line) != 0)
add_history(cmd);
next_history();
}
@@ -1090,6 +1291,7 @@ static void wpa_cli_interactive(void)
#endif /* CONFIG_NATIVE_WINDOWS */
if (cmd == NULL)
break;
+ wpa_cli_recv_pending(ctrl_conn, 0, 0);
pos = cmd;
while (*pos != '\0') {
if (*pos == '\n') {
@@ -1110,7 +1312,7 @@ static void wpa_cli_interactive(void)
if (argc == max_args)
break;
if (*pos == '"') {
- char *pos2 = strrchr(pos, '"');
+ char *pos2 = os_strrchr(pos, '"');
if (pos2)
pos = pos2 + 1;
}
@@ -1123,7 +1325,7 @@ static void wpa_cli_interactive(void)
wpa_request(ctrl_conn, argc, argv);
if (cmd != cmdbuf)
- free(cmd);
+ os_free(cmd);
} while (!wpa_cli_quit);
#ifdef CONFIG_READLINE
@@ -1137,14 +1339,14 @@ static void wpa_cli_interactive(void)
char *p = h->line;
while (*p == ' ' || *p == '\t')
p++;
- if (strncasecmp(p, "pa", 2) == 0 ||
- strncasecmp(p, "o", 1) == 0 ||
- strncasecmp(p, "n", 1)) {
+ if (os_strncasecmp(p, "pa", 2) == 0 ||
+ os_strncasecmp(p, "o", 1) == 0 ||
+ os_strncasecmp(p, "n", 1)) {
h = remove_history(where_history());
if (h) {
- free(h->line);
- free(h->data);
- free(h);
+ os_free(h->line);
+ os_free(h->data);
+ os_free(h);
}
h = current_history();
} else {
@@ -1152,7 +1354,7 @@ static void wpa_cli_interactive(void)
}
}
write_history(hfile);
- free(hfile);
+ os_free(hfile);
}
#endif /* CONFIG_READLINE */
}
@@ -1160,10 +1362,14 @@ static void wpa_cli_interactive(void)
static void wpa_cli_action(struct wpa_ctrl *ctrl)
{
+#ifdef CONFIG_ANSI_C_EXTRA
+ /* TODO: ANSI C version(?) */
+ printf("Action processing not supported in ANSI C build.\n");
+#else /* CONFIG_ANSI_C_EXTRA */
fd_set rfds;
int fd, res;
struct timeval tv;
- char buf[16];
+ char buf[256]; /* note: large enough to fit in unsolicited messages */
size_t len;
fd = wpa_ctrl_get_fd(ctrl);
@@ -1186,13 +1392,14 @@ static void wpa_cli_action(struct wpa_ctrl *ctrl)
len = sizeof(buf) - 1;
if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
wpa_cli_action_cb) < 0 ||
- len < 4 || memcmp(buf, "PONG", 4) != 0) {
+ len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
printf("wpa_supplicant did not reply to PING "
"command - exiting\n");
break;
}
}
}
+#endif /* CONFIG_ANSI_C_EXTRA */
}
@@ -1200,11 +1407,9 @@ static void wpa_cli_cleanup(void)
{
wpa_cli_close_connection();
if (pid_file)
- unlink(pid_file);
+ os_daemonize_terminate(pid_file);
-#ifdef CONFIG_NATIVE_WINDOWS
- WSACleanup();
-#endif /* CONFIG_NATIVE_WINDOWS */
+ os_program_deinit();
}
static void wpa_cli_terminate(int sig)
@@ -1222,19 +1427,8 @@ static void wpa_cli_alarm(int sig)
"reconnect\n");
wpa_cli_close_connection();
}
- if (!ctrl_conn) {
- ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
- if (ctrl_conn) {
- printf("Connection to wpa_supplicant "
- "re-established\n");
- if (wpa_ctrl_attach(ctrl_conn) == 0) {
- wpa_cli_attached = 1;
- } else {
- printf("Warning: Failed to attach to "
- "wpa_supplicant.\n");
- }
- }
- }
+ if (!ctrl_conn)
+ wpa_cli_reconnect();
if (ctrl_conn)
wpa_cli_recv_pending(ctrl_conn, 1, 0);
alarm(1);
@@ -1242,22 +1436,71 @@ static void wpa_cli_alarm(int sig)
#endif /* CONFIG_NATIVE_WINDOWS */
+static char * wpa_cli_get_default_ifname(void)
+{
+ char *ifname = NULL;
+
+#ifdef CONFIG_CTRL_IFACE_UNIX
+ struct dirent *dent;
+ DIR *dir = opendir(ctrl_iface_dir);
+ if (!dir)
+ return NULL;
+ while ((dent = readdir(dir))) {
+#ifdef _DIRENT_HAVE_D_TYPE
+ /*
+ * Skip the file if it is not a socket. Also accept
+ * DT_UNKNOWN (0) in case the C library or underlying
+ * file system does not support d_type.
+ */
+ if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
+ continue;
+#endif /* _DIRENT_HAVE_D_TYPE */
+ if (os_strcmp(dent->d_name, ".") == 0 ||
+ os_strcmp(dent->d_name, "..") == 0)
+ continue;
+ printf("Selected interface '%s'\n", dent->d_name);
+ ifname = os_strdup(dent->d_name);
+ break;
+ }
+ closedir(dir);
+#endif /* CONFIG_CTRL_IFACE_UNIX */
+
+#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
+ char buf[2048], *pos;
+ size_t len;
+ struct wpa_ctrl *ctrl;
+ int ret;
+
+ ctrl = wpa_ctrl_open(NULL);
+ if (ctrl == NULL)
+ return NULL;
+
+ len = sizeof(buf) - 1;
+ ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
+ if (ret >= 0) {
+ buf[len] = '\0';
+ pos = os_strchr(buf, '\n');
+ if (pos)
+ *pos = '\0';
+ ifname = os_strdup(buf);
+ }
+ wpa_ctrl_close(ctrl);
+#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
+
+ return ifname;
+}
+
+
int main(int argc, char *argv[])
{
int interactive;
int warning_displayed = 0;
int c;
int daemonize = 0;
- FILE *f;
const char *global = NULL;
-#ifdef CONFIG_NATIVE_WINDOWS
- WSADATA wsaData;
- if (WSAStartup(MAKEWORD(2, 0), &wsaData)) {
- printf("Could not find a usable WinSock.dll\n");
+ if (os_program_init())
return -1;
- }
-#endif /* CONFIG_NATIVE_WINDOWS */
for (;;) {
c = getopt(argc, argv, "a:Bg:hi:p:P:v");
@@ -1280,7 +1523,8 @@ int main(int argc, char *argv[])
printf("%s\n", wpa_cli_version);
return 0;
case 'i':
- ctrl_ifname = strdup(optarg);
+ os_free(ctrl_ifname);
+ ctrl_ifname = os_strdup(optarg);
break;
case 'p':
ctrl_iface_dir = optarg;
@@ -1300,7 +1544,11 @@ int main(int argc, char *argv[])
printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
if (global) {
+#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
+ ctrl_conn = wpa_ctrl_open(NULL);
+#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
ctrl_conn = wpa_ctrl_open(global);
+#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
if (ctrl_conn == NULL) {
perror("Failed to connect to wpa_supplicant - "
"wpa_ctrl_open");
@@ -1309,22 +1557,8 @@ int main(int argc, char *argv[])
}
for (; !global;) {
- if (ctrl_ifname == NULL) {
- struct dirent *dent;
- DIR *dir = opendir(ctrl_iface_dir);
- if (dir) {
- while ((dent = readdir(dir))) {
- if (strcmp(dent->d_name, ".") == 0 ||
- strcmp(dent->d_name, "..") == 0)
- continue;
- printf("Selected interface '%s'\n",
- dent->d_name);
- ctrl_ifname = strdup(dent->d_name);
- break;
- }
- closedir(dir);
- }
- }
+ if (ctrl_ifname == NULL)
+ ctrl_ifname = wpa_cli_get_default_ifname();
ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
if (ctrl_conn) {
if (warning_displayed)
@@ -1343,12 +1577,14 @@ int main(int argc, char *argv[])
"re-trying\n");
warning_displayed = 1;
}
- sleep(1);
+ os_sleep(1, 0);
continue;
}
+#ifndef _WIN32_WCE
signal(SIGINT, wpa_cli_terminate);
signal(SIGTERM, wpa_cli_terminate);
+#endif /* _WIN32_WCE */
#ifndef CONFIG_NATIVE_WINDOWS
signal(SIGALRM, wpa_cli_alarm);
#endif /* CONFIG_NATIVE_WINDOWS */
@@ -1364,18 +1600,8 @@ int main(int argc, char *argv[])
}
}
- if (daemonize && daemon(0, 0)) {
- perror("daemon");
+ if (daemonize && os_daemonize(pid_file))
return -1;
- }
-
- if (pid_file) {
- f = fopen(pid_file, "w");
- if (f) {
- fprintf(f, "%u\n", getpid());
- fclose(f);
- }
- }
if (interactive)
wpa_cli_interactive();
@@ -1384,8 +1610,16 @@ int main(int argc, char *argv[])
else
wpa_request(ctrl_conn, argc - optind, &argv[optind]);
- free(ctrl_ifname);
+ os_free(ctrl_ifname);
wpa_cli_cleanup();
return 0;
}
+
+#else /* CONFIG_CTRL_IFACE */
+int main(int argc, char *argv[])
+{
+ printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
+ return -1;
+}
+#endif /* CONFIG_CTRL_IFACE */
OpenPOWER on IntegriCloud