MFC: An off-by-one malloc size was corrupting the installer's memory,
[dragonfly.git] / contrib / wpa_supplicant-0.5.8 / wpa_cli.c
bloba641249bb8869081d1da1c8bfa48e066039a03bd
1 /*
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
10 * license.
12 * See README and COPYING for more details.
15 #include "includes.h"
17 #ifdef CONFIG_CTRL_IFACE
19 #ifdef CONFIG_CTRL_IFACE_UNIX
20 #include <dirent.h>
21 #endif /* CONFIG_CTRL_IFACE_UNIX */
22 #ifdef CONFIG_READLINE
23 #include <readline/readline.h>
24 #include <readline/history.h>
25 #endif /* CONFIG_READLINE */
27 #include "wpa_ctrl.h"
28 #include "common.h"
29 #include "version.h"
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"
40 "\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"
48 "\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"
53 "\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"
57 "\n"
58 "Alternatively, this software may be distributed under the terms of the\n"
59 "BSD license.\n"
60 "\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"
63 "met:\n"
64 "\n"
65 "1. Redistributions of source code must retain the above copyright\n"
66 " notice, this list of conditions and the following disclaimer.\n"
67 "\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"
71 "\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"
75 "\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"
87 "\n";
89 static const char *commands_help =
90 "commands:\n"
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"
110 " for an SSID\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 "
119 "(shows\n"
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 "
124 "connecting\n"
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> = "
128 "get capabilies\n"
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 "
153 "events from\n"
154 " wpa_supplicant\n"
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"
158 "%s",
159 commands_help);
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);
167 return ctrl_conn;
168 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
169 char *cfile;
170 int flen;
172 if (ifname == NULL)
173 return NULL;
175 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
176 cfile = os_malloc(flen);
177 if (cfile == NULL)
178 return NULL;
179 os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
181 ctrl_conn = wpa_ctrl_open(cfile);
182 os_free(cfile);
183 return ctrl_conn;
184 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
188 static void wpa_cli_close_connection(void)
190 if (ctrl_conn == NULL)
191 return;
193 if (wpa_cli_attached) {
194 wpa_ctrl_detach(ctrl_conn);
195 wpa_cli_attached = 0;
197 wpa_ctrl_close(ctrl_conn);
198 ctrl_conn = NULL;
202 static void wpa_cli_msg_cb(char *msg, size_t len)
204 printf("%s\n", msg);
208 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
210 char buf[2048];
211 size_t len;
212 int ret;
214 if (ctrl_conn == NULL) {
215 printf("Not connected to wpa_supplicant - command dropped.\n");
216 return -1;
218 len = sizeof(buf) - 1;
219 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
220 wpa_cli_msg_cb);
221 if (ret == -2) {
222 printf("'%s' command timed out.\n", cmd);
223 return -2;
224 } else if (ret < 0) {
225 printf("'%s' command failed.\n", cmd);
226 return -1;
228 if (print) {
229 buf[len] = '\0';
230 printf("%s", buf);
232 return 0;
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);
270 return 0;
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);
277 return 0;
281 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
283 wpa_cli_quit = 1;
284 return 0;
288 static void wpa_cli_show_variables(void)
290 printf("set variables:\n"
291 " EAPOL::heldPeriod (EAPOL state machine held period, "
292 "in seconds)\n"
293 " EAPOL::authPeriod (EAPOL state machine authentication "
294 "period, in seconds)\n"
295 " EAPOL::startPeriod (EAPOL state machine start period, in "
296 "seconds)\n"
297 " EAPOL::maxStart (EAPOL state machine maximum start "
298 "attempts)\n");
299 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
300 "seconds)\n"
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[])
310 char cmd[256];
311 int res;
313 if (argc == 0) {
314 wpa_cli_show_variables();
315 return 0;
318 if (argc != 2) {
319 printf("Invalid SET command: needs two arguments (variable "
320 "name and value)\n");
321 return 0;
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");
327 return 0;
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,
346 char *argv[])
348 return wpa_ctrl_command(ctrl, "REASSOCIATE");
352 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
353 char *argv[])
355 char cmd[256];
356 int res;
358 if (argc != 1) {
359 printf("Invalid PREAUTH command: needs one argument "
360 "(BSSID)\n");
361 return 0;
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");
367 return 0;
369 return wpa_ctrl_command(ctrl, cmd);
373 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
375 char cmd[256];
376 int res;
378 if (argc != 1) {
379 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
380 "value)\n");
381 return 0;
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");
386 return 0;
388 return wpa_ctrl_command(ctrl, cmd);
392 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
393 char *argv[])
395 char cmd[256];
396 int res;
398 if (argc != 1) {
399 printf("Invalid STKSTART command: needs one argument "
400 "(Peer STA MAC address)\n");
401 return 0;
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");
407 return 0;
409 return wpa_ctrl_command(ctrl, cmd);
413 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
415 char cmd[256];
416 int res;
418 if (argc != 1) {
419 printf("Invalid LEVEL command: needs one argument (debug "
420 "level)\n");
421 return 0;
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");
426 return 0;
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;
435 int i, ret;
437 if (argc < 2) {
438 printf("Invalid IDENTITY command: needs two arguments "
439 "(network id and identity)\n");
440 return 0;
443 end = cmd + sizeof(cmd);
444 pos = cmd;
445 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
446 argv[0], argv[1]);
447 if (ret < 0 || ret >= end - pos) {
448 printf("Too long IDENTITY command.\n");
449 return 0;
451 pos += ret;
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");
456 return 0;
458 pos += ret;
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;
468 int i, ret;
470 if (argc < 2) {
471 printf("Invalid PASSWORD command: needs two arguments "
472 "(network id and password)\n");
473 return 0;
476 end = cmd + sizeof(cmd);
477 pos = cmd;
478 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
479 argv[0], argv[1]);
480 if (ret < 0 || ret >= end - pos) {
481 printf("Too long PASSWORD command.\n");
482 return 0;
484 pos += ret;
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");
489 return 0;
491 pos += ret;
494 return wpa_ctrl_command(ctrl, cmd);
498 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
499 char *argv[])
501 char cmd[256], *pos, *end;
502 int i, ret;
504 if (argc < 2) {
505 printf("Invalid NEW_PASSWORD command: needs two arguments "
506 "(network id and password)\n");
507 return 0;
510 end = cmd + sizeof(cmd);
511 pos = cmd;
512 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
513 argv[0], argv[1]);
514 if (ret < 0 || ret >= end - pos) {
515 printf("Too long NEW_PASSWORD command.\n");
516 return 0;
518 pos += ret;
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");
523 return 0;
525 pos += ret;
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;
535 int i, ret;
537 if (argc < 2) {
538 printf("Invalid PIN command: needs two arguments "
539 "(network id and pin)\n");
540 return 0;
543 end = cmd + sizeof(cmd);
544 pos = cmd;
545 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
546 argv[0], argv[1]);
547 if (ret < 0 || ret >= end - pos) {
548 printf("Too long PIN command.\n");
549 return 0;
551 pos += ret;
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");
556 return 0;
558 pos += ret;
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;
567 int i, ret;
569 if (argc < 2) {
570 printf("Invalid OTP command: needs two arguments (network "
571 "id and password)\n");
572 return 0;
575 end = cmd + sizeof(cmd);
576 pos = cmd;
577 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
578 argv[0], argv[1]);
579 if (ret < 0 || ret >= end - pos) {
580 printf("Too long OTP command.\n");
581 return 0;
583 pos += ret;
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");
588 return 0;
590 pos += ret;
593 return wpa_ctrl_command(ctrl, cmd);
597 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
598 char *argv[])
600 char cmd[256], *pos, *end;
601 int i, ret;
603 if (argc < 2) {
604 printf("Invalid PASSPHRASE command: needs two arguments "
605 "(network id and passphrase)\n");
606 return 0;
609 end = cmd + sizeof(cmd);
610 pos = cmd;
611 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
612 argv[0], argv[1]);
613 if (ret < 0 || ret >= end - pos) {
614 printf("Too long PASSPHRASE command.\n");
615 return 0;
617 pos += ret;
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");
622 return 0;
624 pos += ret;
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;
634 int i, ret;
636 if (argc < 2) {
637 printf("Invalid BSSID command: needs two arguments (network "
638 "id and BSSID)\n");
639 return 0;
642 end = cmd + sizeof(cmd);
643 pos = cmd;
644 ret = os_snprintf(pos, end - pos, "BSSID");
645 if (ret < 0 || ret >= end - pos) {
646 printf("Too long BSSID command.\n");
647 return 0;
649 pos += ret;
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");
654 return 0;
656 pos += ret;
659 return wpa_ctrl_command(ctrl, cmd);
663 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
664 char *argv[])
666 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
670 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
671 char *argv[])
673 char cmd[32];
675 if (argc < 1) {
676 printf("Invalid SELECT_NETWORK command: needs one argument "
677 "(network id)\n");
678 return 0;
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,
689 char *argv[])
691 char cmd[32];
693 if (argc < 1) {
694 printf("Invalid ENABLE_NETWORK command: needs one argument "
695 "(network id)\n");
696 return 0;
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,
707 char *argv[])
709 char cmd[32];
711 if (argc < 1) {
712 printf("Invalid DISABLE_NETWORK command: needs one argument "
713 "(network id)\n");
714 return 0;
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,
725 char *argv[])
727 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
731 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
732 char *argv[])
734 char cmd[32];
736 if (argc < 1) {
737 printf("Invalid REMOVE_NETWORK command: needs one argument "
738 "(network id)\n");
739 return 0;
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"
757 " ...\n"
758 "\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 "
762 "marks.\n"
763 "For example: set_network 1 ssid \"network name\"\n"
764 "\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,
771 char *argv[])
773 char cmd[256];
774 int res;
776 if (argc == 0) {
777 wpa_cli_show_network_variables();
778 return 0;
781 if (argc != 3) {
782 printf("Invalid SET_NETWORK command: needs three arguments\n"
783 "(network id, variable name, and value)\n");
784 return 0;
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");
791 return 0;
793 return wpa_ctrl_command(ctrl, cmd);
797 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
798 char *argv[])
800 char cmd[256];
801 int res;
803 if (argc == 0) {
804 wpa_cli_show_network_variables();
805 return 0;
808 if (argc != 2) {
809 printf("Invalid GET_NETWORK command: needs two arguments\n"
810 "(network id and variable name)\n");
811 return 0;
814 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
815 argv[0], argv[1]);
816 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
817 printf("Too long GET_NETWORK command.\n");
818 return 0;
820 return wpa_ctrl_command(ctrl, cmd);
824 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
825 char *argv[])
827 return wpa_ctrl_command(ctrl, "DISCONNECT");
831 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
832 char *argv[])
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,
845 char *argv[])
847 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
851 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
852 char *argv[])
854 char cmd[64];
856 if (argc < 1 || argc > 2) {
857 printf("Invalid GET_CAPABILITY command: need either one or "
858 "two arguments\n");
859 return 0;
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");
865 return 0;
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[])
885 if (argc < 1) {
886 wpa_cli_list_interfaces(ctrl);
887 return 0;
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;
898 } else {
899 printf("Warning: Failed to attach to "
900 "wpa_supplicant.\n");
902 } else {
903 printf("Could not connect to interface '%s' - re-trying\n",
904 ctrl_ifname);
906 return 0;
910 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
911 char *argv[])
913 return wpa_ctrl_command(ctrl, "RECONFIGURE");
917 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
918 char *argv[])
920 return wpa_ctrl_command(ctrl, "TERMINATE");
924 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
925 char *argv[])
927 char cmd[256];
929 if (argc < 1) {
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");
934 return 0;
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",
942 argv[0],
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,
952 char *argv[])
954 char cmd[128];
956 if (argc != 1) {
957 printf("Invalid INTERFACE_REMOVE command: needs one argument "
958 "(interface name)\n");
959 return 0;
962 os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
963 cmd[sizeof(cmd) - 1] = '\0';
964 return wpa_ctrl_command(ctrl, cmd);
968 struct wpa_cli_cmd {
969 const char *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 },
1014 { NULL, NULL }
1018 static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1020 struct wpa_cli_cmd *cmd, *match = NULL;
1021 int count;
1023 count = 0;
1024 cmd = wpa_cli_commands;
1025 while (cmd->cmd) {
1026 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1028 match = cmd;
1029 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1030 /* we have an exact match */
1031 count = 1;
1032 break;
1034 count++;
1036 cmd++;
1039 if (count > 1) {
1040 printf("Ambiguous command '%s'; possible commands:", argv[0]);
1041 cmd = wpa_cli_commands;
1042 while (cmd->cmd) {
1043 if (os_strncasecmp(cmd->cmd, argv[0],
1044 os_strlen(argv[0])) == 0) {
1045 printf(" %s", cmd->cmd);
1047 cmd++;
1049 printf("\n");
1050 } else if (count == 0) {
1051 printf("Unknown command '%s'\n", argv[0]);
1052 } else {
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,
1065 const char *arg2)
1067 char *cmd;
1068 size_t len;
1070 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1071 cmd = os_malloc(len);
1072 if (cmd == NULL)
1073 return -1;
1074 os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1075 cmd[len - 1] = '\0';
1076 #ifndef _WIN32_WCE
1077 system(cmd);
1078 #endif /* _WIN32_WCE */
1079 os_free(cmd);
1081 return 0;
1085 static void wpa_cli_action_process(const char *msg)
1087 const char *pos;
1088 char *copy = NULL, *id, *pos2;
1090 pos = msg;
1091 if (*pos == '<') {
1092 /* skip priority */
1093 pos = os_strchr(pos, '>');
1094 if (pos)
1095 pos++;
1096 else
1097 pos = msg;
1100 if (str_match(pos, WPA_EVENT_CONNECTED)) {
1101 int new_id = -1;
1102 os_unsetenv("WPA_ID");
1103 os_unsetenv("WPA_ID_STR");
1104 os_unsetenv("WPA_CTRL_DIR");
1106 pos = os_strstr(pos, "[id=");
1107 if (pos)
1108 copy = os_strdup(pos + 4);
1110 if (copy) {
1111 pos2 = id = copy;
1112 while (*pos2 && *pos2 != ' ')
1113 pos2++;
1114 *pos2++ = '\0';
1115 new_id = atoi(id);
1116 os_setenv("WPA_ID", id, 1);
1117 while (*pos2 && *pos2 != '=')
1118 pos2++;
1119 if (*pos2 == '=')
1120 pos2++;
1121 id = pos2;
1122 while (*pos2 && *pos2 != ']')
1123 pos2++;
1124 *pos2 = '\0';
1125 os_setenv("WPA_ID_STR", id, 1);
1126 os_free(copy);
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");
1143 wpa_cli_quit = 1;
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);
1160 if (ctrl_conn) {
1161 printf("Connection to wpa_supplicant re-established\n");
1162 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1163 wpa_cli_attached = 1;
1164 } else {
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,
1173 int action_monitor)
1175 int first = 1;
1176 if (ctrl_conn == NULL) {
1177 wpa_cli_reconnect();
1178 return;
1180 while (wpa_ctrl_pending(ctrl) > 0) {
1181 char buf[256];
1182 size_t len = sizeof(buf) - 1;
1183 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
1184 buf[len] = '\0';
1185 if (action_monitor)
1186 wpa_cli_action_process(buf);
1187 else {
1188 if (in_read && first)
1189 printf("\n");
1190 first = 0;
1191 printf("%s\n", buf);
1193 } else {
1194 printf("Could not read pending message.\n");
1195 break;
1199 if (wpa_ctrl_pending(ctrl) < 0) {
1200 printf("Connection to wpa_supplicant lost - trying to "
1201 "reconnect\n");
1202 wpa_cli_reconnect();
1207 #ifdef CONFIG_READLINE
1208 static char * wpa_cli_cmd_gen(const char *text, int state)
1210 static int i, len;
1211 const char *cmd;
1213 if (state == 0) {
1214 i = 0;
1215 len = os_strlen(text);
1218 while ((cmd = wpa_cli_commands[i].cmd)) {
1219 i++;
1220 if (os_strncasecmp(cmd, text, len) == 0)
1221 return os_strdup(cmd);
1224 return NULL;
1228 static char * wpa_cli_dummy_gen(const char *text, int state)
1230 return NULL;
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)
1244 #define max_args 10
1245 char cmdbuf[256], *cmd, *argv[max_args], *pos;
1246 int argc;
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");
1256 if (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);
1260 if (hfile) {
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 */
1269 do {
1270 wpa_cli_recv_pending(ctrl_conn, 0, 0);
1271 #ifndef CONFIG_NATIVE_WINDOWS
1272 alarm(1);
1273 #endif /* CONFIG_NATIVE_WINDOWS */
1274 #ifdef CONFIG_READLINE
1275 cmd = readline("> ");
1276 if (cmd && *cmd) {
1277 HIST_ENTRY *h;
1278 while (next_history())
1280 h = previous_history();
1281 if (h == NULL || os_strcmp(cmd, h->line) != 0)
1282 add_history(cmd);
1283 next_history();
1285 #else /* CONFIG_READLINE */
1286 printf("> ");
1287 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
1288 #endif /* CONFIG_READLINE */
1289 #ifndef CONFIG_NATIVE_WINDOWS
1290 alarm(0);
1291 #endif /* CONFIG_NATIVE_WINDOWS */
1292 if (cmd == NULL)
1293 break;
1294 wpa_cli_recv_pending(ctrl_conn, 0, 0);
1295 pos = cmd;
1296 while (*pos != '\0') {
1297 if (*pos == '\n') {
1298 *pos = '\0';
1299 break;
1301 pos++;
1303 argc = 0;
1304 pos = cmd;
1305 for (;;) {
1306 while (*pos == ' ')
1307 pos++;
1308 if (*pos == '\0')
1309 break;
1310 argv[argc] = pos;
1311 argc++;
1312 if (argc == max_args)
1313 break;
1314 if (*pos == '"') {
1315 char *pos2 = os_strrchr(pos, '"');
1316 if (pos2)
1317 pos = pos2 + 1;
1319 while (*pos != '\0' && *pos != ' ')
1320 pos++;
1321 if (*pos == ' ')
1322 *pos++ = '\0';
1324 if (argc)
1325 wpa_request(ctrl_conn, argc, argv);
1327 if (cmd != cmdbuf)
1328 os_free(cmd);
1329 } while (!wpa_cli_quit);
1331 #ifdef CONFIG_READLINE
1332 if (hfile) {
1333 /* Save command history, excluding lines that may contain
1334 * passwords. */
1335 HIST_ENTRY *h;
1336 history_set_pos(0);
1337 h = next_history();
1338 while (h) {
1339 char *p = h->line;
1340 while (*p == ' ' || *p == '\t')
1341 p++;
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());
1346 if (h) {
1347 os_free(h->line);
1348 os_free(h->data);
1349 os_free(h);
1351 h = current_history();
1352 } else {
1353 h = next_history();
1356 write_history(hfile);
1357 os_free(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 */
1369 fd_set rfds;
1370 int fd, res;
1371 struct timeval tv;
1372 char buf[256]; /* note: large enough to fit in unsolicited messages */
1373 size_t len;
1375 fd = wpa_ctrl_get_fd(ctrl);
1377 while (!wpa_cli_quit) {
1378 FD_ZERO(&rfds);
1379 FD_SET(fd, &rfds);
1380 tv.tv_sec = 2;
1381 tv.tv_usec = 0;
1382 res = select(fd + 1, &rfds, NULL, NULL, &tv);
1383 if (res < 0 && errno != EINTR) {
1384 perror("select");
1385 break;
1388 if (FD_ISSET(fd, &rfds))
1389 wpa_cli_recv_pending(ctrl, 0, 1);
1390 else {
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");
1398 break;
1402 #endif /* CONFIG_ANSI_C_EXTRA */
1406 static void wpa_cli_cleanup(void)
1408 wpa_cli_close_connection();
1409 if (pid_file)
1410 os_daemonize_terminate(pid_file);
1412 os_program_deinit();
1415 static void wpa_cli_terminate(int sig)
1417 wpa_cli_cleanup();
1418 exit(0);
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 "
1427 "reconnect\n");
1428 wpa_cli_close_connection();
1430 if (!ctrl_conn)
1431 wpa_cli_reconnect();
1432 if (ctrl_conn)
1433 wpa_cli_recv_pending(ctrl_conn, 1, 0);
1434 alarm(1);
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);
1446 if (!dir)
1447 return NULL;
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)
1456 continue;
1457 #endif /* _DIRENT_HAVE_D_TYPE */
1458 if (os_strcmp(dent->d_name, ".") == 0 ||
1459 os_strcmp(dent->d_name, "..") == 0)
1460 continue;
1461 printf("Selected interface '%s'\n", dent->d_name);
1462 ifname = os_strdup(dent->d_name);
1463 break;
1465 closedir(dir);
1466 #endif /* CONFIG_CTRL_IFACE_UNIX */
1468 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
1469 char buf[2048], *pos;
1470 size_t len;
1471 struct wpa_ctrl *ctrl;
1472 int ret;
1474 ctrl = wpa_ctrl_open(NULL);
1475 if (ctrl == NULL)
1476 return NULL;
1478 len = sizeof(buf) - 1;
1479 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
1480 if (ret >= 0) {
1481 buf[len] = '\0';
1482 pos = os_strchr(buf, '\n');
1483 if (pos)
1484 *pos = '\0';
1485 ifname = os_strdup(buf);
1487 wpa_ctrl_close(ctrl);
1488 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1490 return ifname;
1494 int main(int argc, char *argv[])
1496 int interactive;
1497 int warning_displayed = 0;
1498 int c;
1499 int daemonize = 0;
1500 const char *global = NULL;
1502 if (os_program_init())
1503 return -1;
1505 for (;;) {
1506 c = getopt(argc, argv, "a:Bg:hi:p:P:v");
1507 if (c < 0)
1508 break;
1509 switch (c) {
1510 case 'a':
1511 action_file = optarg;
1512 break;
1513 case 'B':
1514 daemonize = 1;
1515 break;
1516 case 'g':
1517 global = optarg;
1518 break;
1519 case 'h':
1520 usage();
1521 return 0;
1522 case 'v':
1523 printf("%s\n", wpa_cli_version);
1524 return 0;
1525 case 'i':
1526 os_free(ctrl_ifname);
1527 ctrl_ifname = os_strdup(optarg);
1528 break;
1529 case 'p':
1530 ctrl_iface_dir = optarg;
1531 break;
1532 case 'P':
1533 pid_file = optarg;
1534 break;
1535 default:
1536 usage();
1537 return -1;
1541 interactive = (argc == optind) && (action_file == NULL);
1543 if (interactive)
1544 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
1546 if (global) {
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 - "
1554 "wpa_ctrl_open");
1555 return -1;
1559 for (; !global;) {
1560 if (ctrl_ifname == NULL)
1561 ctrl_ifname = wpa_cli_get_default_ifname();
1562 ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
1563 if (ctrl_conn) {
1564 if (warning_displayed)
1565 printf("Connection established.\n");
1566 break;
1569 if (!interactive) {
1570 perror("Failed to connect to wpa_supplicant - "
1571 "wpa_ctrl_open");
1572 return -1;
1575 if (!warning_displayed) {
1576 printf("Could not connect to wpa_supplicant - "
1577 "re-trying\n");
1578 warning_displayed = 1;
1580 os_sleep(1, 0);
1581 continue;
1584 #ifndef _WIN32_WCE
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;
1595 } else {
1596 printf("Warning: Failed to attach to "
1597 "wpa_supplicant.\n");
1598 if (!interactive)
1599 return -1;
1603 if (daemonize && os_daemonize(pid_file))
1604 return -1;
1606 if (interactive)
1607 wpa_cli_interactive();
1608 else if (action_file)
1609 wpa_cli_action(ctrl_conn);
1610 else
1611 wpa_request(ctrl_conn, argc - optind, &argv[optind]);
1613 os_free(ctrl_ifname);
1614 wpa_cli_cleanup();
1616 return 0;
1619 #else /* CONFIG_CTRL_IFACE */
1620 int main(int argc, char *argv[])
1622 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
1623 return -1;
1625 #endif /* CONFIG_CTRL_IFACE */