2
* WPA Supplicant - command line interface for wpa_supplicant daemon
3
* Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 2 as
7
* published by the Free Software Foundation.
9
* Alternatively, this software may be distributed under the terms of BSD
12
* See README and COPYING for more details.
17
#ifdef CONFIG_CTRL_IFACE
19
#ifdef CONFIG_CTRL_IFACE_UNIX
21
#endif /* CONFIG_CTRL_IFACE_UNIX */
22
#ifdef CONFIG_READLINE
23
#include <readline/readline.h>
24
#include <readline/history.h>
25
#endif /* CONFIG_READLINE */
32
static const char *wpa_cli_version =
33
"wpa_cli v" VERSION_STR "\n"
34
"Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> and contributors";
37
static const char *wpa_cli_license =
38
"This program is free software. You can distribute it and/or modify it\n"
39
"under the terms of the GNU General Public License version 2.\n"
41
"Alternatively, this software may be distributed under the terms of the\n"
42
"BSD license. See README and COPYING for more details.\n";
44
static const char *wpa_cli_full_license =
45
"This program is free software; you can redistribute it and/or modify\n"
46
"it under the terms of the GNU General Public License version 2 as\n"
47
"published by the Free Software Foundation.\n"
49
"This program is distributed in the hope that it will be useful,\n"
50
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
51
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
52
"GNU General Public License for more details.\n"
54
"You should have received a copy of the GNU General Public License\n"
55
"along with this program; if not, write to the Free Software\n"
56
"Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
58
"Alternatively, this software may be distributed under the terms of the\n"
61
"Redistribution and use in source and binary forms, with or without\n"
62
"modification, are permitted provided that the following conditions are\n"
65
"1. Redistributions of source code must retain the above copyright\n"
66
" notice, this list of conditions and the following disclaimer.\n"
68
"2. Redistributions in binary form must reproduce the above copyright\n"
69
" notice, this list of conditions and the following disclaimer in the\n"
70
" documentation and/or other materials provided with the distribution.\n"
72
"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
73
" names of its contributors may be used to endorse or promote products\n"
74
" derived from this software without specific prior written permission.\n"
76
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
77
"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
78
"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
79
"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
80
"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
81
"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
82
"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
83
"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
84
"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
85
"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
86
"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
89
static const char *commands_help =
91
" status [verbose] = get current WPA/EAPOL/EAP status\n"
92
" mib = get MIB variables (dot1x, dot11)\n"
93
" help = show this usage help\n"
94
" interface [ifname] = show interfaces/select interface\n"
95
" level <debug level> = change debug level\n"
96
" license = show full wpa_cli license\n"
97
" logoff = IEEE 802.1X EAPOL state machine logoff\n"
98
" logon = IEEE 802.1X EAPOL state machine logon\n"
99
" set = set variables (shows list of variables when run without arguments)\n"
100
" pmksa = show PMKSA cache\n"
101
" reassociate = force reassociation\n"
102
" reconfigure = force wpa_supplicant to re-read its configuration file\n"
103
" preauthenticate <BSSID> = force preauthentication\n"
104
" identity <network id> <identity> = configure identity for an SSID\n"
105
" password <network id> <password> = configure password for an SSID\n"
106
" new_password <network id> <password> = change password for an SSID\n"
107
" pin <network id> <pin> = configure pin for an SSID\n"
108
" otp <network id> <password> = configure one-time-password for an SSID\n"
109
" passphrase <network id> <passphrase> = configure private key passphrase\n"
111
" bssid <network id> <BSSID> = set preferred BSSID for an SSID\n"
112
" list_networks = list configured networks\n"
113
" select_network <network id> = select a network (disable others)\n"
114
" enable_network <network id> = enable a network\n"
115
" disable_network <network id> = disable a network\n"
116
" add_network = add a network\n"
117
" remove_network <network id> = remove a network\n"
118
" set_network <network id> <variable> <value> = set network variables "
120
" list of variables when run without arguments)\n"
121
" get_network <network id> <variable> = get network variables\n"
122
" save_config = save the current configuration\n"
123
" disconnect = disconnect and wait for reassociate command before "
125
" scan = request new BSS scan\n"
126
" scan_results = get latest scan results\n"
127
" get_capability <eap/pairwise/group/key_mgmt/proto/auth_alg> = "
129
" ap_scan <value> = set ap_scan parameter\n"
130
" stkstart <addr> = request STK negotiation with <addr>\n"
131
" terminate = terminate wpa_supplicant\n"
132
" quit = exit wpa_cli\n";
134
static struct wpa_ctrl *ctrl_conn;
135
static int wpa_cli_quit = 0;
136
static int wpa_cli_attached = 0;
137
static int wpa_cli_connected = 0;
138
static int wpa_cli_last_id = 0;
139
static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
140
static char *ctrl_ifname = NULL;
141
static const char *pid_file = NULL;
142
static const char *action_file = NULL;
145
static void usage(void)
147
printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
148
"[-a<action file>] \\\n"
149
" [-P<pid file>] [-g<global ctrl>] [command..]\n"
150
" -h = help (show this usage text)\n"
151
" -v = shown version information\n"
152
" -a = run in daemon mode executing the action file based on "
155
" -B = run a daemon in the background\n"
156
" default path: /var/run/wpa_supplicant\n"
157
" default interface: first interface found in socket path\n"
163
static struct wpa_ctrl * wpa_cli_open_connection(const char *ifname)
165
#if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
166
ctrl_conn = wpa_ctrl_open(ifname);
168
#else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
175
flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
176
cfile = os_malloc(flen);
179
os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
181
ctrl_conn = wpa_ctrl_open(cfile);
184
#endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
188
static void wpa_cli_close_connection(void)
190
if (ctrl_conn == NULL)
193
if (wpa_cli_attached) {
194
wpa_ctrl_detach(ctrl_conn);
195
wpa_cli_attached = 0;
197
wpa_ctrl_close(ctrl_conn);
202
static void wpa_cli_msg_cb(char *msg, size_t len)
208
static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
214
if (ctrl_conn == NULL) {
215
printf("Not connected to wpa_supplicant - command dropped.\n");
218
len = sizeof(buf) - 1;
219
ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
222
printf("'%s' command timed out.\n", cmd);
224
} else if (ret < 0) {
225
printf("'%s' command failed.\n", cmd);
236
static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
238
return _wpa_ctrl_command(ctrl, cmd, 1);
242
static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
244
int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
245
return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
249
static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
251
return wpa_ctrl_command(ctrl, "PING");
255
static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
257
return wpa_ctrl_command(ctrl, "MIB");
261
static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
263
return wpa_ctrl_command(ctrl, "PMKSA");
267
static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
269
printf("%s", commands_help);
274
static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
276
printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
281
static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
288
static void wpa_cli_show_variables(void)
290
printf("set variables:\n"
291
" EAPOL::heldPeriod (EAPOL state machine held period, "
293
" EAPOL::authPeriod (EAPOL state machine authentication "
294
"period, in seconds)\n"
295
" EAPOL::startPeriod (EAPOL state machine start period, in "
297
" EAPOL::maxStart (EAPOL state machine maximum start "
299
printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
301
" dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
302
" threshold\n\tpercentage)\n"
303
" dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
304
"security\n\tassociation in seconds)\n");
308
static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
314
wpa_cli_show_variables();
319
printf("Invalid SET command: needs two arguments (variable "
320
"name and value)\n");
324
res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
325
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
326
printf("Too long SET command.\n");
329
return wpa_ctrl_command(ctrl, cmd);
333
static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
335
return wpa_ctrl_command(ctrl, "LOGOFF");
339
static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
341
return wpa_ctrl_command(ctrl, "LOGON");
345
static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
348
return wpa_ctrl_command(ctrl, "REASSOCIATE");
352
static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
359
printf("Invalid PREAUTH command: needs one argument "
364
res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
365
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
366
printf("Too long PREAUTH command.\n");
369
return wpa_ctrl_command(ctrl, cmd);
373
static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
379
printf("Invalid AP_SCAN command: needs one argument (ap_scan "
383
res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
384
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
385
printf("Too long AP_SCAN command.\n");
388
return wpa_ctrl_command(ctrl, cmd);
392
static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
399
printf("Invalid STKSTART command: needs one argument "
400
"(Peer STA MAC address)\n");
404
res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
405
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
406
printf("Too long STKSTART command.\n");
409
return wpa_ctrl_command(ctrl, cmd);
413
static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
419
printf("Invalid LEVEL command: needs one argument (debug "
423
res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
424
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
425
printf("Too long LEVEL command.\n");
428
return wpa_ctrl_command(ctrl, cmd);
432
static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
434
char cmd[256], *pos, *end;
438
printf("Invalid IDENTITY command: needs two arguments "
439
"(network id and identity)\n");
443
end = cmd + sizeof(cmd);
445
ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
447
if (ret < 0 || ret >= end - pos) {
448
printf("Too long IDENTITY command.\n");
452
for (i = 2; i < argc; i++) {
453
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
454
if (ret < 0 || ret >= end - pos) {
455
printf("Too long IDENTITY command.\n");
461
return wpa_ctrl_command(ctrl, cmd);
465
static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
467
char cmd[256], *pos, *end;
471
printf("Invalid PASSWORD command: needs two arguments "
472
"(network id and password)\n");
476
end = cmd + sizeof(cmd);
478
ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
480
if (ret < 0 || ret >= end - pos) {
481
printf("Too long PASSWORD command.\n");
485
for (i = 2; i < argc; i++) {
486
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
487
if (ret < 0 || ret >= end - pos) {
488
printf("Too long PASSWORD command.\n");
494
return wpa_ctrl_command(ctrl, cmd);
498
static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
501
char cmd[256], *pos, *end;
505
printf("Invalid NEW_PASSWORD command: needs two arguments "
506
"(network id and password)\n");
510
end = cmd + sizeof(cmd);
512
ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
514
if (ret < 0 || ret >= end - pos) {
515
printf("Too long NEW_PASSWORD command.\n");
519
for (i = 2; i < argc; i++) {
520
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
521
if (ret < 0 || ret >= end - pos) {
522
printf("Too long NEW_PASSWORD command.\n");
528
return wpa_ctrl_command(ctrl, cmd);
532
static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
534
char cmd[256], *pos, *end;
538
printf("Invalid PIN command: needs two arguments "
539
"(network id and pin)\n");
543
end = cmd + sizeof(cmd);
545
ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
547
if (ret < 0 || ret >= end - pos) {
548
printf("Too long PIN command.\n");
552
for (i = 2; i < argc; i++) {
553
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
554
if (ret < 0 || ret >= end - pos) {
555
printf("Too long PIN command.\n");
560
return wpa_ctrl_command(ctrl, cmd);
564
static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
566
char cmd[256], *pos, *end;
570
printf("Invalid OTP command: needs two arguments (network "
571
"id and password)\n");
575
end = cmd + sizeof(cmd);
577
ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
579
if (ret < 0 || ret >= end - pos) {
580
printf("Too long OTP command.\n");
584
for (i = 2; i < argc; i++) {
585
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
586
if (ret < 0 || ret >= end - pos) {
587
printf("Too long OTP command.\n");
593
return wpa_ctrl_command(ctrl, cmd);
597
static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
600
char cmd[256], *pos, *end;
604
printf("Invalid PASSPHRASE command: needs two arguments "
605
"(network id and passphrase)\n");
609
end = cmd + sizeof(cmd);
611
ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
613
if (ret < 0 || ret >= end - pos) {
614
printf("Too long PASSPHRASE command.\n");
618
for (i = 2; i < argc; i++) {
619
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
620
if (ret < 0 || ret >= end - pos) {
621
printf("Too long PASSPHRASE command.\n");
627
return wpa_ctrl_command(ctrl, cmd);
631
static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
633
char cmd[256], *pos, *end;
637
printf("Invalid BSSID command: needs two arguments (network "
642
end = cmd + sizeof(cmd);
644
ret = os_snprintf(pos, end - pos, "BSSID");
645
if (ret < 0 || ret >= end - pos) {
646
printf("Too long BSSID command.\n");
650
for (i = 0; i < argc; i++) {
651
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
652
if (ret < 0 || ret >= end - pos) {
653
printf("Too long BSSID command.\n");
659
return wpa_ctrl_command(ctrl, cmd);
663
static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
666
return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
670
static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
676
printf("Invalid SELECT_NETWORK command: needs one argument "
681
os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
682
cmd[sizeof(cmd) - 1] = '\0';
684
return wpa_ctrl_command(ctrl, cmd);
688
static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
694
printf("Invalid ENABLE_NETWORK command: needs one argument "
699
os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
700
cmd[sizeof(cmd) - 1] = '\0';
702
return wpa_ctrl_command(ctrl, cmd);
706
static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
712
printf("Invalid DISABLE_NETWORK command: needs one argument "
717
os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
718
cmd[sizeof(cmd) - 1] = '\0';
720
return wpa_ctrl_command(ctrl, cmd);
724
static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
727
return wpa_ctrl_command(ctrl, "ADD_NETWORK");
731
static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
737
printf("Invalid REMOVE_NETWORK command: needs one argument "
742
os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
743
cmd[sizeof(cmd) - 1] = '\0';
745
return wpa_ctrl_command(ctrl, cmd);
749
static void wpa_cli_show_network_variables(void)
751
printf("set_network variables:\n"
752
" ssid (network name, SSID)\n"
753
" psk (WPA passphrase or pre-shared key)\n"
754
" key_mgmt (key management protocol)\n"
755
" identity (EAP identity)\n"
756
" password (EAP password)\n"
759
"Note: Values are entered in the same format as the "
760
"configuration file is using,\n"
761
"i.e., strings values need to be inside double quotation "
763
"For example: set_network 1 ssid \"network name\"\n"
765
"Please see wpa_supplicant.conf documentation for full list "
766
"of\navailable variables.\n");
770
static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
777
wpa_cli_show_network_variables();
782
printf("Invalid SET_NETWORK command: needs three arguments\n"
783
"(network id, variable name, and value)\n");
787
res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
788
argv[0], argv[1], argv[2]);
789
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
790
printf("Too long SET_NETWORK command.\n");
793
return wpa_ctrl_command(ctrl, cmd);
797
static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
804
wpa_cli_show_network_variables();
809
printf("Invalid GET_NETWORK command: needs two arguments\n"
810
"(network id and variable name)\n");
814
res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
816
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
817
printf("Too long GET_NETWORK command.\n");
820
return wpa_ctrl_command(ctrl, cmd);
824
static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
827
return wpa_ctrl_command(ctrl, "DISCONNECT");
831
static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
834
return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
838
static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
840
return wpa_ctrl_command(ctrl, "SCAN");
844
static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
847
return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
851
static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
856
if (argc < 1 || argc > 2) {
857
printf("Invalid GET_CAPABILITY command: need either one or "
862
if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
863
printf("Invalid GET_CAPABILITY command: second argument, "
864
"if any, must be 'strict'\n");
868
os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
869
(argc == 2) ? " strict" : "");
870
cmd[sizeof(cmd) - 1] = '\0';
872
return wpa_ctrl_command(ctrl, cmd);
876
static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
878
printf("Available interfaces:\n");
879
return wpa_ctrl_command(ctrl, "INTERFACES");
883
static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
886
wpa_cli_list_interfaces(ctrl);
890
wpa_cli_close_connection();
891
os_free(ctrl_ifname);
892
ctrl_ifname = os_strdup(argv[0]);
894
if (wpa_cli_open_connection(ctrl_ifname)) {
895
printf("Connected to interface '%s.\n", ctrl_ifname);
896
if (wpa_ctrl_attach(ctrl_conn) == 0) {
897
wpa_cli_attached = 1;
899
printf("Warning: Failed to attach to "
900
"wpa_supplicant.\n");
903
printf("Could not connect to interface '%s' - re-trying\n",
910
static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
913
return wpa_ctrl_command(ctrl, "RECONFIGURE");
917
static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
920
return wpa_ctrl_command(ctrl, "TERMINATE");
924
static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
930
printf("Invalid INTERFACE_ADD command: needs at least one "
931
"argument (interface name)\n"
932
"All arguments: ifname confname driver ctrl_interface "
933
"driver_param bridge_name\n");
938
* INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
939
* <driver_param>TAB<bridge_name>
941
os_snprintf(cmd, sizeof(cmd), "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
943
argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
944
argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
945
argc > 5 ? argv[5] : "");
946
cmd[sizeof(cmd) - 1] = '\0';
947
return wpa_ctrl_command(ctrl, cmd);
951
static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
957
printf("Invalid INTERFACE_REMOVE command: needs one argument "
958
"(interface name)\n");
962
os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
963
cmd[sizeof(cmd) - 1] = '\0';
964
return wpa_ctrl_command(ctrl, cmd);
970
int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
973
static struct wpa_cli_cmd wpa_cli_commands[] = {
974
{ "status", wpa_cli_cmd_status },
975
{ "ping", wpa_cli_cmd_ping },
976
{ "mib", wpa_cli_cmd_mib },
977
{ "help", wpa_cli_cmd_help },
978
{ "interface", wpa_cli_cmd_interface },
979
{ "level", wpa_cli_cmd_level },
980
{ "license", wpa_cli_cmd_license },
981
{ "quit", wpa_cli_cmd_quit },
982
{ "set", wpa_cli_cmd_set },
983
{ "logon", wpa_cli_cmd_logon },
984
{ "logoff", wpa_cli_cmd_logoff },
985
{ "pmksa", wpa_cli_cmd_pmksa },
986
{ "reassociate", wpa_cli_cmd_reassociate },
987
{ "preauthenticate", wpa_cli_cmd_preauthenticate },
988
{ "identity", wpa_cli_cmd_identity },
989
{ "password", wpa_cli_cmd_password },
990
{ "new_password", wpa_cli_cmd_new_password },
991
{ "pin", wpa_cli_cmd_pin },
992
{ "otp", wpa_cli_cmd_otp },
993
{ "passphrase", wpa_cli_cmd_passphrase },
994
{ "bssid", wpa_cli_cmd_bssid },
995
{ "list_networks", wpa_cli_cmd_list_networks },
996
{ "select_network", wpa_cli_cmd_select_network },
997
{ "enable_network", wpa_cli_cmd_enable_network },
998
{ "disable_network", wpa_cli_cmd_disable_network },
999
{ "add_network", wpa_cli_cmd_add_network },
1000
{ "remove_network", wpa_cli_cmd_remove_network },
1001
{ "set_network", wpa_cli_cmd_set_network },
1002
{ "get_network", wpa_cli_cmd_get_network },
1003
{ "save_config", wpa_cli_cmd_save_config },
1004
{ "disconnect", wpa_cli_cmd_disconnect },
1005
{ "scan", wpa_cli_cmd_scan },
1006
{ "scan_results", wpa_cli_cmd_scan_results },
1007
{ "get_capability", wpa_cli_cmd_get_capability },
1008
{ "reconfigure", wpa_cli_cmd_reconfigure },
1009
{ "terminate", wpa_cli_cmd_terminate },
1010
{ "interface_add", wpa_cli_cmd_interface_add },
1011
{ "interface_remove", wpa_cli_cmd_interface_remove },
1012
{ "ap_scan", wpa_cli_cmd_ap_scan },
1013
{ "stkstart", wpa_cli_cmd_stkstart },
1018
static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1020
struct wpa_cli_cmd *cmd, *match = NULL;
1024
cmd = wpa_cli_commands;
1026
if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1029
if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1030
/* we have an exact match */
1040
printf("Ambiguous command '%s'; possible commands:", argv[0]);
1041
cmd = wpa_cli_commands;
1043
if (os_strncasecmp(cmd->cmd, argv[0],
1044
os_strlen(argv[0])) == 0) {
1045
printf(" %s", cmd->cmd);
1050
} else if (count == 0) {
1051
printf("Unknown command '%s'\n", argv[0]);
1053
match->handler(ctrl, argc - 1, &argv[1]);
1058
static int str_match(const char *a, const char *b)
1060
return os_strncmp(a, b, os_strlen(b)) == 0;
1064
static int wpa_cli_exec(const char *program, const char *arg1,
1070
len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1071
cmd = os_malloc(len);
1074
os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1075
cmd[len - 1] = '\0';
1078
#endif /* _WIN32_WCE */
1085
static void wpa_cli_action_process(const char *msg)
1088
char *copy = NULL, *id, *pos2;
1093
pos = os_strchr(pos, '>');
1100
if (str_match(pos, WPA_EVENT_CONNECTED)) {
1102
os_unsetenv("WPA_ID");
1103
os_unsetenv("WPA_ID_STR");
1104
os_unsetenv("WPA_CTRL_DIR");
1106
pos = os_strstr(pos, "[id=");
1108
copy = os_strdup(pos + 4);
1112
while (*pos2 && *pos2 != ' ')
1116
os_setenv("WPA_ID", id, 1);
1117
while (*pos2 && *pos2 != '=')
1122
while (*pos2 && *pos2 != ']')
1125
os_setenv("WPA_ID_STR", id, 1);
1129
os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
1131
if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
1132
wpa_cli_connected = 1;
1133
wpa_cli_last_id = new_id;
1134
wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
1136
} else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
1137
if (wpa_cli_connected) {
1138
wpa_cli_connected = 0;
1139
wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
1141
} else if (str_match(pos, WPA_EVENT_TERMINATING)) {
1142
printf("wpa_supplicant is terminating - stop monitoring\n");
1148
#ifndef CONFIG_ANSI_C_EXTRA
1149
static void wpa_cli_action_cb(char *msg, size_t len)
1151
wpa_cli_action_process(msg);
1153
#endif /* CONFIG_ANSI_C_EXTRA */
1156
static void wpa_cli_reconnect(void)
1158
wpa_cli_close_connection();
1159
ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
1161
printf("Connection to wpa_supplicant re-established\n");
1162
if (wpa_ctrl_attach(ctrl_conn) == 0) {
1163
wpa_cli_attached = 1;
1165
printf("Warning: Failed to attach to "
1166
"wpa_supplicant.\n");
1172
static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
1176
if (ctrl_conn == NULL) {
1177
wpa_cli_reconnect();
1180
while (wpa_ctrl_pending(ctrl) > 0) {
1182
size_t len = sizeof(buf) - 1;
1183
if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
1186
wpa_cli_action_process(buf);
1188
if (in_read && first)
1191
printf("%s\n", buf);
1194
printf("Could not read pending message.\n");
1199
if (wpa_ctrl_pending(ctrl) < 0) {
1200
printf("Connection to wpa_supplicant lost - trying to "
1202
wpa_cli_reconnect();
1207
#ifdef CONFIG_READLINE
1208
static char * wpa_cli_cmd_gen(const char *text, int state)
1215
len = os_strlen(text);
1218
while ((cmd = wpa_cli_commands[i].cmd)) {
1220
if (os_strncasecmp(cmd, text, len) == 0)
1221
return os_strdup(cmd);
1228
static char * wpa_cli_dummy_gen(const char *text, int state)
1234
static char ** wpa_cli_completion(const char *text, int start, int end)
1236
return rl_completion_matches(text, start == 0 ?
1237
wpa_cli_cmd_gen : wpa_cli_dummy_gen);
1239
#endif /* CONFIG_READLINE */
1242
static void wpa_cli_interactive(void)
1245
char cmdbuf[256], *cmd, *argv[max_args], *pos;
1247
#ifdef CONFIG_READLINE
1248
char *home, *hfile = NULL;
1249
#endif /* CONFIG_READLINE */
1251
printf("\nInteractive mode\n\n");
1253
#ifdef CONFIG_READLINE
1254
rl_attempted_completion_function = wpa_cli_completion;
1255
home = getenv("HOME");
1257
const char *fname = ".wpa_cli_history";
1258
int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
1259
hfile = os_malloc(hfile_len);
1261
os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
1262
hfile[hfile_len - 1] = '\0';
1263
read_history(hfile);
1264
stifle_history(100);
1267
#endif /* CONFIG_READLINE */
1270
wpa_cli_recv_pending(ctrl_conn, 0, 0);
1271
#ifndef CONFIG_NATIVE_WINDOWS
1273
#endif /* CONFIG_NATIVE_WINDOWS */
1274
#ifdef CONFIG_READLINE
1275
cmd = readline("> ");
1278
while (next_history())
1280
h = previous_history();
1281
if (h == NULL || os_strcmp(cmd, h->line) != 0)
1285
#else /* CONFIG_READLINE */
1287
cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
1288
#endif /* CONFIG_READLINE */
1289
#ifndef CONFIG_NATIVE_WINDOWS
1291
#endif /* CONFIG_NATIVE_WINDOWS */
1294
wpa_cli_recv_pending(ctrl_conn, 0, 0);
1296
while (*pos != '\0') {
1312
if (argc == max_args)
1315
char *pos2 = os_strrchr(pos, '"');
1319
while (*pos != '\0' && *pos != ' ')
1325
wpa_request(ctrl_conn, argc, argv);
1329
} while (!wpa_cli_quit);
1331
#ifdef CONFIG_READLINE
1333
/* Save command history, excluding lines that may contain
1340
while (*p == ' ' || *p == '\t')
1342
if (os_strncasecmp(p, "pa", 2) == 0 ||
1343
os_strncasecmp(p, "o", 1) == 0 ||
1344
os_strncasecmp(p, "n", 1)) {
1345
h = remove_history(where_history());
1351
h = current_history();
1356
write_history(hfile);
1359
#endif /* CONFIG_READLINE */
1363
static void wpa_cli_action(struct wpa_ctrl *ctrl)
1365
#ifdef CONFIG_ANSI_C_EXTRA
1366
/* TODO: ANSI C version(?) */
1367
printf("Action processing not supported in ANSI C build.\n");
1368
#else /* CONFIG_ANSI_C_EXTRA */
1372
char buf[256]; /* note: large enough to fit in unsolicited messages */
1375
fd = wpa_ctrl_get_fd(ctrl);
1377
while (!wpa_cli_quit) {
1382
res = select(fd + 1, &rfds, NULL, NULL, &tv);
1383
if (res < 0 && errno != EINTR) {
1388
if (FD_ISSET(fd, &rfds))
1389
wpa_cli_recv_pending(ctrl, 0, 1);
1391
/* verify that connection is still working */
1392
len = sizeof(buf) - 1;
1393
if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
1394
wpa_cli_action_cb) < 0 ||
1395
len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
1396
printf("wpa_supplicant did not reply to PING "
1397
"command - exiting\n");
1402
#endif /* CONFIG_ANSI_C_EXTRA */
1406
static void wpa_cli_cleanup(void)
1408
wpa_cli_close_connection();
1410
os_daemonize_terminate(pid_file);
1412
os_program_deinit();
1415
static void wpa_cli_terminate(int sig)
1422
#ifndef CONFIG_NATIVE_WINDOWS
1423
static void wpa_cli_alarm(int sig)
1425
if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
1426
printf("Connection to wpa_supplicant lost - trying to "
1428
wpa_cli_close_connection();
1431
wpa_cli_reconnect();
1433
wpa_cli_recv_pending(ctrl_conn, 1, 0);
1436
#endif /* CONFIG_NATIVE_WINDOWS */
1439
static char * wpa_cli_get_default_ifname(void)
1441
char *ifname = NULL;
1443
#ifdef CONFIG_CTRL_IFACE_UNIX
1444
struct dirent *dent;
1445
DIR *dir = opendir(ctrl_iface_dir);
1448
while ((dent = readdir(dir))) {
1449
#ifdef _DIRENT_HAVE_D_TYPE
1451
* Skip the file if it is not a socket. Also accept
1452
* DT_UNKNOWN (0) in case the C library or underlying
1453
* file system does not support d_type.
1455
if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
1457
#endif /* _DIRENT_HAVE_D_TYPE */
1458
if (os_strcmp(dent->d_name, ".") == 0 ||
1459
os_strcmp(dent->d_name, "..") == 0)
1461
printf("Selected interface '%s'\n", dent->d_name);
1462
ifname = os_strdup(dent->d_name);
1466
#endif /* CONFIG_CTRL_IFACE_UNIX */
1468
#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
1469
char buf[2048], *pos;
1471
struct wpa_ctrl *ctrl;
1474
ctrl = wpa_ctrl_open(NULL);
1478
len = sizeof(buf) - 1;
1479
ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
1482
pos = os_strchr(buf, '\n');
1485
ifname = os_strdup(buf);
1487
wpa_ctrl_close(ctrl);
1488
#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1494
int main(int argc, char *argv[])
1497
int warning_displayed = 0;
1500
const char *global = NULL;
1502
if (os_program_init())
1506
c = getopt(argc, argv, "a:Bg:hi:p:P:v");
1511
action_file = optarg;
1523
printf("%s\n", wpa_cli_version);
1526
os_free(ctrl_ifname);
1527
ctrl_ifname = os_strdup(optarg);
1530
ctrl_iface_dir = optarg;
1541
interactive = (argc == optind) && (action_file == NULL);
1544
printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
1547
#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
1548
ctrl_conn = wpa_ctrl_open(NULL);
1549
#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1550
ctrl_conn = wpa_ctrl_open(global);
1551
#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1552
if (ctrl_conn == NULL) {
1553
perror("Failed to connect to wpa_supplicant - "
1560
if (ctrl_ifname == NULL)
1561
ctrl_ifname = wpa_cli_get_default_ifname();
1562
ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
1564
if (warning_displayed)
1565
printf("Connection established.\n");
1570
perror("Failed to connect to wpa_supplicant - "
1575
if (!warning_displayed) {
1576
printf("Could not connect to wpa_supplicant - "
1578
warning_displayed = 1;
1585
signal(SIGINT, wpa_cli_terminate);
1586
signal(SIGTERM, wpa_cli_terminate);
1587
#endif /* _WIN32_WCE */
1588
#ifndef CONFIG_NATIVE_WINDOWS
1589
signal(SIGALRM, wpa_cli_alarm);
1590
#endif /* CONFIG_NATIVE_WINDOWS */
1592
if (interactive || action_file) {
1593
if (wpa_ctrl_attach(ctrl_conn) == 0) {
1594
wpa_cli_attached = 1;
1596
printf("Warning: Failed to attach to "
1597
"wpa_supplicant.\n");
1603
if (daemonize && os_daemonize(pid_file))
1607
wpa_cli_interactive();
1608
else if (action_file)
1609
wpa_cli_action(ctrl_conn);
1611
wpa_request(ctrl_conn, argc - optind, &argv[optind]);
1613
os_free(ctrl_ifname);
1619
#else /* CONFIG_CTRL_IFACE */
1620
int main(int argc, char *argv[])
1622
printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
1625
#endif /* CONFIG_CTRL_IFACE */