wpa_cli: Improved command parameter tab completion
[libeap.git] / wpa_supplicant / wpa_cli.c
1 /*
2  * WPA Supplicant - command line interface for wpa_supplicant daemon
3  * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
4  *
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.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include "includes.h"
16
17 #ifdef CONFIG_CTRL_IFACE
18
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 */
26 #ifdef CONFIG_WPA_CLI_FORK
27 #include <sys/wait.h>
28 #endif /* CONFIG_WPA_CLI_FORK */
29
30 #include "common/wpa_ctrl.h"
31 #include "common.h"
32 #include "common/version.h"
33
34
35 static const char *wpa_cli_version =
36 "wpa_cli v" VERSION_STR "\n"
37 "Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> and contributors";
38
39
40 static const char *wpa_cli_license =
41 "This program is free software. You can distribute it and/or modify it\n"
42 "under the terms of the GNU General Public License version 2.\n"
43 "\n"
44 "Alternatively, this software may be distributed under the terms of the\n"
45 "BSD license. See README and COPYING for more details.\n";
46
47 static const char *wpa_cli_full_license =
48 "This program is free software; you can redistribute it and/or modify\n"
49 "it under the terms of the GNU General Public License version 2 as\n"
50 "published by the Free Software Foundation.\n"
51 "\n"
52 "This program is distributed in the hope that it will be useful,\n"
53 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
54 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
55 "GNU General Public License for more details.\n"
56 "\n"
57 "You should have received a copy of the GNU General Public License\n"
58 "along with this program; if not, write to the Free Software\n"
59 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n"
60 "\n"
61 "Alternatively, this software may be distributed under the terms of the\n"
62 "BSD license.\n"
63 "\n"
64 "Redistribution and use in source and binary forms, with or without\n"
65 "modification, are permitted provided that the following conditions are\n"
66 "met:\n"
67 "\n"
68 "1. Redistributions of source code must retain the above copyright\n"
69 "   notice, this list of conditions and the following disclaimer.\n"
70 "\n"
71 "2. Redistributions in binary form must reproduce the above copyright\n"
72 "   notice, this list of conditions and the following disclaimer in the\n"
73 "   documentation and/or other materials provided with the distribution.\n"
74 "\n"
75 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
76 "   names of its contributors may be used to endorse or promote products\n"
77 "   derived from this software without specific prior written permission.\n"
78 "\n"
79 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
80 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
81 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
82 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
83 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
84 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
85 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
86 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
87 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
88 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
89 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
90 "\n";
91
92 static struct wpa_ctrl *ctrl_conn;
93 static struct wpa_ctrl *mon_conn;
94 #ifdef CONFIG_WPA_CLI_FORK
95 static pid_t mon_pid = 0;
96 #endif /* CONFIG_WPA_CLI_FORK */
97 static int wpa_cli_quit = 0;
98 static int wpa_cli_attached = 0;
99 static int wpa_cli_connected = 0;
100 static int wpa_cli_last_id = 0;
101 static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
102 static char *ctrl_ifname = NULL;
103 static const char *pid_file = NULL;
104 static const char *action_file = NULL;
105 static int ping_interval = 5;
106 static int interactive = 0;
107
108
109 static void print_help();
110
111
112 static void usage(void)
113 {
114         printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
115                "[-a<action file>] \\\n"
116                "        [-P<pid file>] [-g<global ctrl>] [-G<ping interval>]  "
117                "[command..]\n"
118                "  -h = help (show this usage text)\n"
119                "  -v = shown version information\n"
120                "  -a = run in daemon mode executing the action file based on "
121                "events from\n"
122                "       wpa_supplicant\n"
123                "  -B = run a daemon in the background\n"
124                "  default path: /var/run/wpa_supplicant\n"
125                "  default interface: first interface found in socket path\n");
126         print_help();
127 }
128
129
130 #ifdef CONFIG_WPA_CLI_FORK
131 static int in_query = 0;
132
133 static void wpa_cli_monitor_sig(int sig)
134 {
135         if (sig == SIGUSR1)
136                 in_query = 1;
137         else if (sig == SIGUSR2)
138                 in_query = 0;
139 }
140
141 static void wpa_cli_monitor(void)
142 {
143         char buf[256];
144         size_t len = sizeof(buf) - 1;
145         struct timeval tv;
146         fd_set rfds;
147
148         signal(SIGUSR1, wpa_cli_monitor_sig);
149         signal(SIGUSR2, wpa_cli_monitor_sig);
150
151         while (mon_conn) {
152                 int s = wpa_ctrl_get_fd(mon_conn);
153                 tv.tv_sec = 5;
154                 tv.tv_usec = 0;
155                 FD_ZERO(&rfds);
156                 FD_SET(s, &rfds);
157                 if (select(s + 1, &rfds, NULL, NULL, &tv) < 0) {
158                         if (errno == EINTR)
159                                 continue;
160                         perror("select");
161                         break;
162                 }
163                 if (mon_conn == NULL)
164                         break;
165                 if (FD_ISSET(s, &rfds)) {
166                         len = sizeof(buf) - 1;
167                         int res = wpa_ctrl_recv(mon_conn, buf, &len);
168                         if (res < 0) {
169                                 perror("wpa_ctrl_recv");
170                                 break;
171                         }
172                         buf[len] = '\0';
173                         if (in_query)
174                                 printf("\r");
175                         printf("%s\n", buf);
176                         kill(getppid(), SIGUSR1);
177                 }
178         }
179 }
180 #endif /* CONFIG_WPA_CLI_FORK */
181
182
183 static int wpa_cli_open_connection(const char *ifname, int attach)
184 {
185 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
186         ctrl_conn = wpa_ctrl_open(ifname);
187         if (ctrl_conn == NULL)
188                 return -1;
189
190         if (attach && interactive)
191                 mon_conn = wpa_ctrl_open(ifname);
192         else
193                 mon_conn = NULL;
194 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
195         char *cfile;
196         int flen, res;
197
198         if (ifname == NULL)
199                 return -1;
200
201         flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
202         cfile = os_malloc(flen);
203         if (cfile == NULL)
204                 return -1L;
205         res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
206         if (res < 0 || res >= flen) {
207                 os_free(cfile);
208                 return -1;
209         }
210
211         ctrl_conn = wpa_ctrl_open(cfile);
212         if (ctrl_conn == NULL) {
213                 os_free(cfile);
214                 return -1;
215         }
216
217         if (attach && interactive)
218                 mon_conn = wpa_ctrl_open(cfile);
219         else
220                 mon_conn = NULL;
221         os_free(cfile);
222 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
223
224         if (mon_conn) {
225                 if (wpa_ctrl_attach(mon_conn) == 0) {
226                         wpa_cli_attached = 1;
227                 } else {
228                         printf("Warning: Failed to attach to "
229                                "wpa_supplicant.\n");
230                         return -1;
231                 }
232
233 #ifdef CONFIG_WPA_CLI_FORK
234                 {
235                         pid_t p = fork();
236                         if (p < 0) {
237                                 perror("fork");
238                                 return -1;
239                         }
240                         if (p == 0) {
241                                 wpa_cli_monitor();
242                                 exit(0);
243                         } else
244                                 mon_pid = p;
245                 }
246 #endif /* CONFIG_WPA_CLI_FORK */
247         }
248
249         return 0;
250 }
251
252
253 static void wpa_cli_close_connection(void)
254 {
255         if (ctrl_conn == NULL)
256                 return;
257
258 #ifdef CONFIG_WPA_CLI_FORK
259         if (mon_pid) {
260                 int status;
261                 kill(mon_pid, SIGPIPE);
262                 wait(&status);
263                 mon_pid = 0;
264         }
265 #endif /* CONFIG_WPA_CLI_FORK */
266
267         if (wpa_cli_attached) {
268                 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
269                 wpa_cli_attached = 0;
270         }
271         wpa_ctrl_close(ctrl_conn);
272         ctrl_conn = NULL;
273         if (mon_conn) {
274                 wpa_ctrl_close(mon_conn);
275                 mon_conn = NULL;
276         }
277 }
278
279
280 static void wpa_cli_msg_cb(char *msg, size_t len)
281 {
282         printf("%s\n", msg);
283 }
284
285
286 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
287 {
288         char buf[2048];
289         size_t len;
290         int ret;
291
292         if (ctrl_conn == NULL) {
293                 printf("Not connected to wpa_supplicant - command dropped.\n");
294                 return -1;
295         }
296         len = sizeof(buf) - 1;
297         ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
298                                wpa_cli_msg_cb);
299         if (ret == -2) {
300                 printf("'%s' command timed out.\n", cmd);
301                 return -2;
302         } else if (ret < 0) {
303                 printf("'%s' command failed.\n", cmd);
304                 return -1;
305         }
306         if (print) {
307                 buf[len] = '\0';
308                 printf("%s", buf);
309         }
310         return 0;
311 }
312
313
314 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
315 {
316         return _wpa_ctrl_command(ctrl, cmd, 1);
317 }
318
319
320 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
321 {
322         int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
323         return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
324 }
325
326
327 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
328 {
329         return wpa_ctrl_command(ctrl, "PING");
330 }
331
332
333 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
334 {
335         return wpa_ctrl_command(ctrl, "MIB");
336 }
337
338
339 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
340 {
341         return wpa_ctrl_command(ctrl, "PMKSA");
342 }
343
344
345 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
346 {
347         print_help();
348         return 0;
349 }
350
351
352 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
353 {
354         printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
355         return 0;
356 }
357
358
359 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
360 {
361         wpa_cli_quit = 1;
362         return 0;
363 }
364
365
366 static void wpa_cli_show_variables(void)
367 {
368         printf("set variables:\n"
369                "  EAPOL::heldPeriod (EAPOL state machine held period, "
370                "in seconds)\n"
371                "  EAPOL::authPeriod (EAPOL state machine authentication "
372                "period, in seconds)\n"
373                "  EAPOL::startPeriod (EAPOL state machine start period, in "
374                "seconds)\n"
375                "  EAPOL::maxStart (EAPOL state machine maximum start "
376                "attempts)\n");
377         printf("  dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
378                "seconds)\n"
379                "  dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
380                " threshold\n\tpercentage)\n"
381                "  dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
382                "security\n\tassociation in seconds)\n");
383 }
384
385
386 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
387 {
388         char cmd[256];
389         int res;
390
391         if (argc == 0) {
392                 wpa_cli_show_variables();
393                 return 0;
394         }
395
396         if (argc != 2) {
397                 printf("Invalid SET command: needs two arguments (variable "
398                        "name and value)\n");
399                 return -1;
400         }
401
402         res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
403         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
404                 printf("Too long SET command.\n");
405                 return -1;
406         }
407         return wpa_ctrl_command(ctrl, cmd);
408 }
409
410
411 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
412 {
413         return wpa_ctrl_command(ctrl, "LOGOFF");
414 }
415
416
417 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
418 {
419         return wpa_ctrl_command(ctrl, "LOGON");
420 }
421
422
423 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
424                                    char *argv[])
425 {
426         return wpa_ctrl_command(ctrl, "REASSOCIATE");
427 }
428
429
430 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
431                                        char *argv[])
432 {
433         char cmd[256];
434         int res;
435
436         if (argc != 1) {
437                 printf("Invalid PREAUTH command: needs one argument "
438                        "(BSSID)\n");
439                 return -1;
440         }
441
442         res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
443         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
444                 printf("Too long PREAUTH command.\n");
445                 return -1;
446         }
447         return wpa_ctrl_command(ctrl, cmd);
448 }
449
450
451 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
452 {
453         char cmd[256];
454         int res;
455
456         if (argc != 1) {
457                 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
458                        "value)\n");
459                 return -1;
460         }
461         res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
462         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
463                 printf("Too long AP_SCAN command.\n");
464                 return -1;
465         }
466         return wpa_ctrl_command(ctrl, cmd);
467 }
468
469
470 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
471                                 char *argv[])
472 {
473         char cmd[256];
474         int res;
475
476         if (argc != 1) {
477                 printf("Invalid STKSTART command: needs one argument "
478                        "(Peer STA MAC address)\n");
479                 return -1;
480         }
481
482         res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
483         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
484                 printf("Too long STKSTART command.\n");
485                 return -1;
486         }
487         return wpa_ctrl_command(ctrl, cmd);
488 }
489
490
491 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
492 {
493         char cmd[256];
494         int res;
495
496         if (argc != 1) {
497                 printf("Invalid FT_DS command: needs one argument "
498                        "(Target AP MAC address)\n");
499                 return -1;
500         }
501
502         res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
503         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
504                 printf("Too long FT_DS command.\n");
505                 return -1;
506         }
507         return wpa_ctrl_command(ctrl, cmd);
508 }
509
510
511 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
512 {
513         char cmd[256];
514         int res;
515
516         if (argc == 0) {
517                 /* Any BSSID */
518                 return wpa_ctrl_command(ctrl, "WPS_PBC");
519         }
520
521         /* Specific BSSID */
522         res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
523         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
524                 printf("Too long WPS_PBC command.\n");
525                 return -1;
526         }
527         return wpa_ctrl_command(ctrl, cmd);
528 }
529
530
531 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
532 {
533         char cmd[256];
534         int res;
535
536         if (argc == 0) {
537                 printf("Invalid WPS_PIN command: need one or two arguments:\n"
538                        "- BSSID: use 'any' to select any\n"
539                        "- PIN: optional, used only with devices that have no "
540                        "display\n");
541                 return -1;
542         }
543
544         if (argc == 1) {
545                 /* Use dynamically generated PIN (returned as reply) */
546                 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
547                 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
548                         printf("Too long WPS_PIN command.\n");
549                         return -1;
550                 }
551                 return wpa_ctrl_command(ctrl, cmd);
552         }
553
554         /* Use hardcoded PIN from a label */
555         res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
556         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
557                 printf("Too long WPS_PIN command.\n");
558                 return -1;
559         }
560         return wpa_ctrl_command(ctrl, cmd);
561 }
562
563
564 #ifdef CONFIG_WPS_OOB
565 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
566 {
567         char cmd[256];
568         int res;
569
570         if (argc != 3 && argc != 4) {
571                 printf("Invalid WPS_OOB command: need three or four "
572                        "arguments:\n"
573                        "- DEV_TYPE: use 'ufd' or 'nfc'\n"
574                        "- PATH: path of OOB device like '/mnt'\n"
575                        "- METHOD: OOB method 'pin-e' or 'pin-r', "
576                        "'cred'\n"
577                        "- DEV_NAME: (only for NFC) device name like "
578                        "'pn531'\n");
579                 return -1;
580         }
581
582         if (argc == 3)
583                 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
584                                   argv[0], argv[1], argv[2]);
585         else
586                 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
587                                   argv[0], argv[1], argv[2], argv[3]);
588         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
589                 printf("Too long WPS_OOB command.\n");
590                 return -1;
591         }
592         return wpa_ctrl_command(ctrl, cmd);
593 }
594 #endif /* CONFIG_WPS_OOB */
595
596
597 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
598 {
599         char cmd[256];
600         int res;
601
602         if (argc == 2)
603                 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
604                                   argv[0], argv[1]);
605         else if (argc == 6) {
606                 char ssid_hex[2 * 32 + 1];
607                 char key_hex[2 * 64 + 1];
608                 int i;
609
610                 ssid_hex[0] = '\0';
611                 for (i = 0; i < 32; i++) {
612                         if (argv[2][i] == '\0')
613                                 break;
614                         os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
615                 }
616
617                 key_hex[0] = '\0';
618                 for (i = 0; i < 64; i++) {
619                         if (argv[5][i] == '\0')
620                                 break;
621                         os_snprintf(&key_hex[i * 2], 3, "%02x", argv[5][i]);
622                 }
623
624                 res = os_snprintf(cmd, sizeof(cmd),
625                                   "WPS_REG %s %s %s %s %s %s",
626                                   argv[0], argv[1], ssid_hex, argv[3], argv[4],
627                                   key_hex);
628         } else {
629                 printf("Invalid WPS_REG command: need two arguments:\n"
630                        "- BSSID: use 'any' to select any\n"
631                        "- AP PIN\n");
632                 printf("Alternatively, six arguments can be used to "
633                        "reconfigure the AP:\n"
634                        "- BSSID: use 'any' to select any\n"
635                        "- AP PIN\n"
636                        "- new SSID\n"
637                        "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
638                        "- new encr (NONE, WEP, TKIP, CCMP)\n"
639                        "- new key\n");
640                 return -1;
641         }
642
643         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
644                 printf("Too long WPS_REG command.\n");
645                 return -1;
646         }
647         return wpa_ctrl_command(ctrl, cmd);
648 }
649
650
651 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
652                                     char *argv[])
653 {
654         return wpa_ctrl_command(ctrl, "WPS_ER_START");
655
656 }
657
658
659 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
660                                    char *argv[])
661 {
662         return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
663
664 }
665
666
667 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
668                                   char *argv[])
669 {
670         char cmd[256];
671         int res;
672
673         if (argc != 2) {
674                 printf("Invalid WPS_ER_PIN command: need two arguments:\n"
675                        "- UUID: use 'any' to select any\n"
676                        "- PIN: Enrollee PIN\n");
677                 return -1;
678         }
679
680         res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
681                           argv[0], argv[1]);
682         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
683                 printf("Too long WPS_ER_PIN command.\n");
684                 return -1;
685         }
686         return wpa_ctrl_command(ctrl, cmd);
687 }
688
689
690 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
691                                   char *argv[])
692 {
693         char cmd[256];
694         int res;
695
696         if (argc != 1) {
697                 printf("Invalid WPS_ER_PBC command: need one argument:\n"
698                        "- UUID: Specify the Enrollee\n");
699                 return -1;
700         }
701
702         res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
703                           argv[0]);
704         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
705                 printf("Too long WPS_ER_PBC command.\n");
706                 return -1;
707         }
708         return wpa_ctrl_command(ctrl, cmd);
709 }
710
711
712 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
713                                     char *argv[])
714 {
715         char cmd[256];
716         int res;
717
718         if (argc != 2) {
719                 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
720                        "- UUID: specify which AP to use\n"
721                        "- PIN: AP PIN\n");
722                 return -1;
723         }
724
725         res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
726                           argv[0], argv[1]);
727         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
728                 printf("Too long WPS_ER_LEARN command.\n");
729                 return -1;
730         }
731         return wpa_ctrl_command(ctrl, cmd);
732 }
733
734
735 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
736 {
737         char cmd[256];
738         int res;
739
740         if (argc != 1) {
741                 printf("Invalid IBSS_RSN command: needs one argument "
742                        "(Peer STA MAC address)\n");
743                 return -1;
744         }
745
746         res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
747         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
748                 printf("Too long IBSS_RSN command.\n");
749                 return -1;
750         }
751         return wpa_ctrl_command(ctrl, cmd);
752 }
753
754
755 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
756 {
757         char cmd[256];
758         int res;
759
760         if (argc != 1) {
761                 printf("Invalid LEVEL command: needs one argument (debug "
762                        "level)\n");
763                 return -1;
764         }
765         res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
766         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
767                 printf("Too long LEVEL command.\n");
768                 return -1;
769         }
770         return wpa_ctrl_command(ctrl, cmd);
771 }
772
773
774 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
775 {
776         char cmd[256], *pos, *end;
777         int i, ret;
778
779         if (argc < 2) {
780                 printf("Invalid IDENTITY command: needs two arguments "
781                        "(network id and identity)\n");
782                 return -1;
783         }
784
785         end = cmd + sizeof(cmd);
786         pos = cmd;
787         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
788                           argv[0], argv[1]);
789         if (ret < 0 || ret >= end - pos) {
790                 printf("Too long IDENTITY command.\n");
791                 return -1;
792         }
793         pos += ret;
794         for (i = 2; i < argc; i++) {
795                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
796                 if (ret < 0 || ret >= end - pos) {
797                         printf("Too long IDENTITY command.\n");
798                         return -1;
799                 }
800                 pos += ret;
801         }
802
803         return wpa_ctrl_command(ctrl, cmd);
804 }
805
806
807 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
808 {
809         char cmd[256], *pos, *end;
810         int i, ret;
811
812         if (argc < 2) {
813                 printf("Invalid PASSWORD command: needs two arguments "
814                        "(network id and password)\n");
815                 return -1;
816         }
817
818         end = cmd + sizeof(cmd);
819         pos = cmd;
820         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
821                           argv[0], argv[1]);
822         if (ret < 0 || ret >= end - pos) {
823                 printf("Too long PASSWORD command.\n");
824                 return -1;
825         }
826         pos += ret;
827         for (i = 2; i < argc; i++) {
828                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
829                 if (ret < 0 || ret >= end - pos) {
830                         printf("Too long PASSWORD command.\n");
831                         return -1;
832                 }
833                 pos += ret;
834         }
835
836         return wpa_ctrl_command(ctrl, cmd);
837 }
838
839
840 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
841                                     char *argv[])
842 {
843         char cmd[256], *pos, *end;
844         int i, ret;
845
846         if (argc < 2) {
847                 printf("Invalid NEW_PASSWORD command: needs two arguments "
848                        "(network id and password)\n");
849                 return -1;
850         }
851
852         end = cmd + sizeof(cmd);
853         pos = cmd;
854         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
855                           argv[0], argv[1]);
856         if (ret < 0 || ret >= end - pos) {
857                 printf("Too long NEW_PASSWORD command.\n");
858                 return -1;
859         }
860         pos += ret;
861         for (i = 2; i < argc; i++) {
862                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
863                 if (ret < 0 || ret >= end - pos) {
864                         printf("Too long NEW_PASSWORD command.\n");
865                         return -1;
866                 }
867                 pos += ret;
868         }
869
870         return wpa_ctrl_command(ctrl, cmd);
871 }
872
873
874 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
875 {
876         char cmd[256], *pos, *end;
877         int i, ret;
878
879         if (argc < 2) {
880                 printf("Invalid PIN command: needs two arguments "
881                        "(network id and pin)\n");
882                 return -1;
883         }
884
885         end = cmd + sizeof(cmd);
886         pos = cmd;
887         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
888                           argv[0], argv[1]);
889         if (ret < 0 || ret >= end - pos) {
890                 printf("Too long PIN command.\n");
891                 return -1;
892         }
893         pos += ret;
894         for (i = 2; i < argc; i++) {
895                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
896                 if (ret < 0 || ret >= end - pos) {
897                         printf("Too long PIN command.\n");
898                         return -1;
899                 }
900                 pos += ret;
901         }
902         return wpa_ctrl_command(ctrl, cmd);
903 }
904
905
906 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
907 {
908         char cmd[256], *pos, *end;
909         int i, ret;
910
911         if (argc < 2) {
912                 printf("Invalid OTP command: needs two arguments (network "
913                        "id and password)\n");
914                 return -1;
915         }
916
917         end = cmd + sizeof(cmd);
918         pos = cmd;
919         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
920                           argv[0], argv[1]);
921         if (ret < 0 || ret >= end - pos) {
922                 printf("Too long OTP command.\n");
923                 return -1;
924         }
925         pos += ret;
926         for (i = 2; i < argc; i++) {
927                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
928                 if (ret < 0 || ret >= end - pos) {
929                         printf("Too long OTP command.\n");
930                         return -1;
931                 }
932                 pos += ret;
933         }
934
935         return wpa_ctrl_command(ctrl, cmd);
936 }
937
938
939 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
940                                   char *argv[])
941 {
942         char cmd[256], *pos, *end;
943         int i, ret;
944
945         if (argc < 2) {
946                 printf("Invalid PASSPHRASE command: needs two arguments "
947                        "(network id and passphrase)\n");
948                 return -1;
949         }
950
951         end = cmd + sizeof(cmd);
952         pos = cmd;
953         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
954                           argv[0], argv[1]);
955         if (ret < 0 || ret >= end - pos) {
956                 printf("Too long PASSPHRASE command.\n");
957                 return -1;
958         }
959         pos += ret;
960         for (i = 2; i < argc; i++) {
961                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
962                 if (ret < 0 || ret >= end - pos) {
963                         printf("Too long PASSPHRASE command.\n");
964                         return -1;
965                 }
966                 pos += ret;
967         }
968
969         return wpa_ctrl_command(ctrl, cmd);
970 }
971
972
973 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
974 {
975         char cmd[256], *pos, *end;
976         int i, ret;
977
978         if (argc < 2) {
979                 printf("Invalid BSSID command: needs two arguments (network "
980                        "id and BSSID)\n");
981                 return -1;
982         }
983
984         end = cmd + sizeof(cmd);
985         pos = cmd;
986         ret = os_snprintf(pos, end - pos, "BSSID");
987         if (ret < 0 || ret >= end - pos) {
988                 printf("Too long BSSID command.\n");
989                 return -1;
990         }
991         pos += ret;
992         for (i = 0; i < argc; i++) {
993                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
994                 if (ret < 0 || ret >= end - pos) {
995                         printf("Too long BSSID command.\n");
996                         return -1;
997                 }
998                 pos += ret;
999         }
1000
1001         return wpa_ctrl_command(ctrl, cmd);
1002 }
1003
1004
1005 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1006                                      char *argv[])
1007 {
1008         return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1009 }
1010
1011
1012 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1013                                       char *argv[])
1014 {
1015         char cmd[32];
1016         int res;
1017
1018         if (argc < 1) {
1019                 printf("Invalid SELECT_NETWORK command: needs one argument "
1020                        "(network id)\n");
1021                 return -1;
1022         }
1023
1024         res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1025         if (res < 0 || (size_t) res >= sizeof(cmd))
1026                 return -1;
1027         cmd[sizeof(cmd) - 1] = '\0';
1028
1029         return wpa_ctrl_command(ctrl, cmd);
1030 }
1031
1032
1033 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1034                                       char *argv[])
1035 {
1036         char cmd[32];
1037         int res;
1038
1039         if (argc < 1) {
1040                 printf("Invalid ENABLE_NETWORK command: needs one argument "
1041                        "(network id)\n");
1042                 return -1;
1043         }
1044
1045         res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1046         if (res < 0 || (size_t) res >= sizeof(cmd))
1047                 return -1;
1048         cmd[sizeof(cmd) - 1] = '\0';
1049
1050         return wpa_ctrl_command(ctrl, cmd);
1051 }
1052
1053
1054 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1055                                        char *argv[])
1056 {
1057         char cmd[32];
1058         int res;
1059
1060         if (argc < 1) {
1061                 printf("Invalid DISABLE_NETWORK command: needs one argument "
1062                        "(network id)\n");
1063                 return -1;
1064         }
1065
1066         res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1067         if (res < 0 || (size_t) res >= sizeof(cmd))
1068                 return -1;
1069         cmd[sizeof(cmd) - 1] = '\0';
1070
1071         return wpa_ctrl_command(ctrl, cmd);
1072 }
1073
1074
1075 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1076                                    char *argv[])
1077 {
1078         return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1079 }
1080
1081
1082 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1083                                       char *argv[])
1084 {
1085         char cmd[32];
1086         int res;
1087
1088         if (argc < 1) {
1089                 printf("Invalid REMOVE_NETWORK command: needs one argument "
1090                        "(network id)\n");
1091                 return -1;
1092         }
1093
1094         res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1095         if (res < 0 || (size_t) res >= sizeof(cmd))
1096                 return -1;
1097         cmd[sizeof(cmd) - 1] = '\0';
1098
1099         return wpa_ctrl_command(ctrl, cmd);
1100 }
1101
1102
1103 static void wpa_cli_show_network_variables(void)
1104 {
1105         printf("set_network variables:\n"
1106                "  ssid (network name, SSID)\n"
1107                "  psk (WPA passphrase or pre-shared key)\n"
1108                "  key_mgmt (key management protocol)\n"
1109                "  identity (EAP identity)\n"
1110                "  password (EAP password)\n"
1111                "  ...\n"
1112                "\n"
1113                "Note: Values are entered in the same format as the "
1114                "configuration file is using,\n"
1115                "i.e., strings values need to be inside double quotation "
1116                "marks.\n"
1117                "For example: set_network 1 ssid \"network name\"\n"
1118                "\n"
1119                "Please see wpa_supplicant.conf documentation for full list "
1120                "of\navailable variables.\n");
1121 }
1122
1123
1124 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1125                                    char *argv[])
1126 {
1127         char cmd[256];
1128         int res;
1129
1130         if (argc == 0) {
1131                 wpa_cli_show_network_variables();
1132                 return 0;
1133         }
1134
1135         if (argc != 3) {
1136                 printf("Invalid SET_NETWORK command: needs three arguments\n"
1137                        "(network id, variable name, and value)\n");
1138                 return -1;
1139         }
1140
1141         res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1142                           argv[0], argv[1], argv[2]);
1143         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1144                 printf("Too long SET_NETWORK command.\n");
1145                 return -1;
1146         }
1147         return wpa_ctrl_command(ctrl, cmd);
1148 }
1149
1150
1151 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1152                                    char *argv[])
1153 {
1154         char cmd[256];
1155         int res;
1156
1157         if (argc == 0) {
1158                 wpa_cli_show_network_variables();
1159                 return 0;
1160         }
1161
1162         if (argc != 2) {
1163                 printf("Invalid GET_NETWORK command: needs two arguments\n"
1164                        "(network id and variable name)\n");
1165                 return -1;
1166         }
1167
1168         res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1169                           argv[0], argv[1]);
1170         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1171                 printf("Too long GET_NETWORK command.\n");
1172                 return -1;
1173         }
1174         return wpa_ctrl_command(ctrl, cmd);
1175 }
1176
1177
1178 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1179                                   char *argv[])
1180 {
1181         return wpa_ctrl_command(ctrl, "DISCONNECT");
1182 }
1183
1184
1185 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1186                                   char *argv[])
1187 {
1188         return wpa_ctrl_command(ctrl, "RECONNECT");
1189 }
1190
1191
1192 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1193                                    char *argv[])
1194 {
1195         return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1196 }
1197
1198
1199 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1200 {
1201         return wpa_ctrl_command(ctrl, "SCAN");
1202 }
1203
1204
1205 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1206                                     char *argv[])
1207 {
1208         return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1209 }
1210
1211
1212 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1213 {
1214         char cmd[64];
1215         int res;
1216
1217         if (argc != 1) {
1218                 printf("Invalid BSS command: need one argument (index or "
1219                        "BSSID)\n");
1220                 return -1;
1221         }
1222
1223         res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1224         if (res < 0 || (size_t) res >= sizeof(cmd))
1225                 return -1;
1226         cmd[sizeof(cmd) - 1] = '\0';
1227
1228         return wpa_ctrl_command(ctrl, cmd);
1229 }
1230
1231
1232 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1233                                       char *argv[])
1234 {
1235         char cmd[64];
1236         int res;
1237
1238         if (argc < 1 || argc > 2) {
1239                 printf("Invalid GET_CAPABILITY command: need either one or "
1240                        "two arguments\n");
1241                 return -1;
1242         }
1243
1244         if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1245                 printf("Invalid GET_CAPABILITY command: second argument, "
1246                        "if any, must be 'strict'\n");
1247                 return -1;
1248         }
1249
1250         res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1251                           (argc == 2) ? " strict" : "");
1252         if (res < 0 || (size_t) res >= sizeof(cmd))
1253                 return -1;
1254         cmd[sizeof(cmd) - 1] = '\0';
1255
1256         return wpa_ctrl_command(ctrl, cmd);
1257 }
1258
1259
1260 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1261 {
1262         printf("Available interfaces:\n");
1263         return wpa_ctrl_command(ctrl, "INTERFACES");
1264 }
1265
1266
1267 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1268 {
1269         if (argc < 1) {
1270                 wpa_cli_list_interfaces(ctrl);
1271                 return 0;
1272         }
1273
1274         wpa_cli_close_connection();
1275         os_free(ctrl_ifname);
1276         ctrl_ifname = os_strdup(argv[0]);
1277
1278         if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1279                 printf("Connected to interface '%s.\n", ctrl_ifname);
1280         } else {
1281                 printf("Could not connect to interface '%s' - re-trying\n",
1282                        ctrl_ifname);
1283         }
1284         return 0;
1285 }
1286
1287
1288 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1289                                    char *argv[])
1290 {
1291         return wpa_ctrl_command(ctrl, "RECONFIGURE");
1292 }
1293
1294
1295 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1296                                  char *argv[])
1297 {
1298         return wpa_ctrl_command(ctrl, "TERMINATE");
1299 }
1300
1301
1302 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1303                                      char *argv[])
1304 {
1305         char cmd[256];
1306         int res;
1307
1308         if (argc < 1) {
1309                 printf("Invalid INTERFACE_ADD command: needs at least one "
1310                        "argument (interface name)\n"
1311                        "All arguments: ifname confname driver ctrl_interface "
1312                        "driver_param bridge_name\n");
1313                 return -1;
1314         }
1315
1316         /*
1317          * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1318          * <driver_param>TAB<bridge_name>
1319          */
1320         res = os_snprintf(cmd, sizeof(cmd),
1321                           "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1322                           argv[0],
1323                           argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1324                           argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1325                           argc > 5 ? argv[5] : "");
1326         if (res < 0 || (size_t) res >= sizeof(cmd))
1327                 return -1;
1328         cmd[sizeof(cmd) - 1] = '\0';
1329         return wpa_ctrl_command(ctrl, cmd);
1330 }
1331
1332
1333 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1334                                         char *argv[])
1335 {
1336         char cmd[128];
1337         int res;
1338
1339         if (argc != 1) {
1340                 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1341                        "(interface name)\n");
1342                 return -1;
1343         }
1344
1345         res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1346         if (res < 0 || (size_t) res >= sizeof(cmd))
1347                 return -1;
1348         cmd[sizeof(cmd) - 1] = '\0';
1349         return wpa_ctrl_command(ctrl, cmd);
1350 }
1351
1352
1353 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1354                                       char *argv[])
1355 {
1356         return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1357 }
1358
1359
1360 #ifdef CONFIG_AP
1361 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1362 {
1363         char buf[64];
1364         if (argc != 1) {
1365                 printf("Invalid 'sta' command - exactly one argument, STA "
1366                        "address, is required.\n");
1367                 return -1;
1368         }
1369         os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1370         return wpa_ctrl_command(ctrl, buf);
1371 }
1372
1373
1374 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1375                                 char *addr, size_t addr_len)
1376 {
1377         char buf[4096], *pos;
1378         size_t len;
1379         int ret;
1380
1381         if (ctrl_conn == NULL) {
1382                 printf("Not connected to hostapd - command dropped.\n");
1383                 return -1;
1384         }
1385         len = sizeof(buf) - 1;
1386         ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1387                                wpa_cli_msg_cb);
1388         if (ret == -2) {
1389                 printf("'%s' command timed out.\n", cmd);
1390                 return -2;
1391         } else if (ret < 0) {
1392                 printf("'%s' command failed.\n", cmd);
1393                 return -1;
1394         }
1395
1396         buf[len] = '\0';
1397         if (memcmp(buf, "FAIL", 4) == 0)
1398                 return -1;
1399         printf("%s", buf);
1400
1401         pos = buf;
1402         while (*pos != '\0' && *pos != '\n')
1403                 pos++;
1404         *pos = '\0';
1405         os_strlcpy(addr, buf, addr_len);
1406         return 0;
1407 }
1408
1409
1410 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1411 {
1412         char addr[32], cmd[64];
1413
1414         if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1415                 return 0;
1416         do {
1417                 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1418         } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1419
1420         return -1;
1421 }
1422 #endif /* CONFIG_AP */
1423
1424
1425 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1426 {
1427         return wpa_ctrl_command(ctrl, "SUSPEND");
1428 }
1429
1430
1431 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1432 {
1433         return wpa_ctrl_command(ctrl, "RESUME");
1434 }
1435
1436
1437 enum wpa_cli_cmd_flags {
1438         cli_cmd_flag_none               = 0x00,
1439         cli_cmd_flag_sensitive          = 0x01
1440 };
1441
1442 struct wpa_cli_cmd {
1443         const char *cmd;
1444         int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
1445         enum wpa_cli_cmd_flags flags;
1446         const char *usage;
1447 };
1448
1449 static struct wpa_cli_cmd wpa_cli_commands[] = {
1450         { "status", wpa_cli_cmd_status,
1451           cli_cmd_flag_none,
1452           "[verbose] = get current WPA/EAPOL/EAP status" },
1453         { "ping", wpa_cli_cmd_ping,
1454           cli_cmd_flag_none,
1455           "= pings wpa_supplicant" },
1456         { "mib", wpa_cli_cmd_mib,
1457           cli_cmd_flag_none,
1458           "= get MIB variables (dot1x, dot11)" },
1459         { "help", wpa_cli_cmd_help,
1460           cli_cmd_flag_none,
1461           "= show this usage help" },
1462         { "interface", wpa_cli_cmd_interface,
1463           cli_cmd_flag_none,
1464           "[ifname] = show interfaces/select interface" },
1465         { "level", wpa_cli_cmd_level,
1466           cli_cmd_flag_none,
1467           "<debug level> = change debug level" },
1468         { "license", wpa_cli_cmd_license,
1469           cli_cmd_flag_none,
1470           "= show full wpa_cli license" },
1471         { "quit", wpa_cli_cmd_quit,
1472           cli_cmd_flag_none,
1473           "= exit wpa_cli" },
1474         { "set", wpa_cli_cmd_set,
1475           cli_cmd_flag_none,
1476           "= set variables (shows list of variables when run without "
1477           "arguments)" },
1478         { "logon", wpa_cli_cmd_logon,
1479           cli_cmd_flag_none,
1480           "= IEEE 802.1X EAPOL state machine logon" },
1481         { "logoff", wpa_cli_cmd_logoff,
1482           cli_cmd_flag_none,
1483           "= IEEE 802.1X EAPOL state machine logoff" },
1484         { "pmksa", wpa_cli_cmd_pmksa,
1485           cli_cmd_flag_none,
1486           "= show PMKSA cache" },
1487         { "reassociate", wpa_cli_cmd_reassociate,
1488           cli_cmd_flag_none,
1489           "= force reassociation" },
1490         { "preauthenticate", wpa_cli_cmd_preauthenticate,
1491           cli_cmd_flag_none,
1492           "<BSSID> = force preauthentication" },
1493         { "identity", wpa_cli_cmd_identity,
1494           cli_cmd_flag_none,
1495           "<network id> <identity> = configure identity for an SSID" },
1496         { "password", wpa_cli_cmd_password,
1497           cli_cmd_flag_sensitive,
1498           "<network id> <password> = configure password for an SSID" },
1499         { "new_password", wpa_cli_cmd_new_password,
1500           cli_cmd_flag_sensitive,
1501           "<network id> <password> = change password for an SSID" },
1502         { "pin", wpa_cli_cmd_pin,
1503           cli_cmd_flag_sensitive,
1504           "<network id> <pin> = configure pin for an SSID" },
1505         { "otp", wpa_cli_cmd_otp,
1506           cli_cmd_flag_sensitive,
1507           "<network id> <password> = configure one-time-password for an SSID"
1508         },
1509         { "passphrase", wpa_cli_cmd_passphrase,
1510           cli_cmd_flag_sensitive,
1511           "<network id> <passphrase> = configure private key passphrase\n"
1512           "  for an SSID" },
1513         { "bssid", wpa_cli_cmd_bssid,
1514           cli_cmd_flag_none,
1515           "<network id> <BSSID> = set preferred BSSID for an SSID" },
1516         { "list_networks", wpa_cli_cmd_list_networks,
1517           cli_cmd_flag_none,
1518           "= list configured networks" },
1519         { "select_network", wpa_cli_cmd_select_network,
1520           cli_cmd_flag_none,
1521           "<network id> = select a network (disable others)" },
1522         { "enable_network", wpa_cli_cmd_enable_network,
1523           cli_cmd_flag_none,
1524           "<network id> = enable a network" },
1525         { "disable_network", wpa_cli_cmd_disable_network,
1526           cli_cmd_flag_none,
1527           "<network id> = disable a network" },
1528         { "add_network", wpa_cli_cmd_add_network,
1529           cli_cmd_flag_none,
1530           "= add a network" },
1531         { "remove_network", wpa_cli_cmd_remove_network,
1532           cli_cmd_flag_none,
1533           "<network id> = remove a network" },
1534         { "set_network", wpa_cli_cmd_set_network,
1535           cli_cmd_flag_sensitive,
1536           "<network id> <variable> <value> = set network variables (shows\n"
1537           "  list of variables when run without arguments)" },
1538         { "get_network", wpa_cli_cmd_get_network,
1539           cli_cmd_flag_none,
1540           "<network id> <variable> = get network variables" },
1541         { "save_config", wpa_cli_cmd_save_config,
1542           cli_cmd_flag_none,
1543           "= save the current configuration" },
1544         { "disconnect", wpa_cli_cmd_disconnect,
1545           cli_cmd_flag_none,
1546           "= disconnect and wait for reassociate/reconnect command before\n"
1547           "  connecting" },
1548         { "reconnect", wpa_cli_cmd_reconnect,
1549           cli_cmd_flag_none,
1550           "= like reassociate, but only takes effect if already disconnected"
1551         },
1552         { "scan", wpa_cli_cmd_scan,
1553           cli_cmd_flag_none,
1554           "= request new BSS scan" },
1555         { "scan_results", wpa_cli_cmd_scan_results,
1556           cli_cmd_flag_none,
1557           "= get latest scan results" },
1558         { "bss", wpa_cli_cmd_bss,
1559           cli_cmd_flag_none,
1560           "<<idx> | <bssid>> = get detailed scan result info" },
1561         { "get_capability", wpa_cli_cmd_get_capability,
1562           cli_cmd_flag_none,
1563           "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
1564         { "reconfigure", wpa_cli_cmd_reconfigure,
1565           cli_cmd_flag_none,
1566           "= force wpa_supplicant to re-read its configuration file" },
1567         { "terminate", wpa_cli_cmd_terminate,
1568           cli_cmd_flag_none,
1569           "= terminate wpa_supplicant" },
1570         { "interface_add", wpa_cli_cmd_interface_add,
1571           cli_cmd_flag_none,
1572           "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
1573           "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
1574           "  are optional" },
1575         { "interface_remove", wpa_cli_cmd_interface_remove,
1576           cli_cmd_flag_none,
1577           "<ifname> = removes the interface" },
1578         { "interface_list", wpa_cli_cmd_interface_list,
1579           cli_cmd_flag_none,
1580           "= list available interfaces" },
1581         { "ap_scan", wpa_cli_cmd_ap_scan,
1582           cli_cmd_flag_none,
1583           "<value> = set ap_scan parameter" },
1584         { "stkstart", wpa_cli_cmd_stkstart,
1585           cli_cmd_flag_none,
1586           "<addr> = request STK negotiation with <addr>" },
1587         { "ft_ds", wpa_cli_cmd_ft_ds,
1588           cli_cmd_flag_none,
1589           "<addr> = request over-the-DS FT with <addr>" },
1590         { "wps_pbc", wpa_cli_cmd_wps_pbc,
1591           cli_cmd_flag_none,
1592           "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
1593         { "wps_pin", wpa_cli_cmd_wps_pin,
1594           cli_cmd_flag_sensitive,
1595           "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
1596           "hardcoded)" },
1597 #ifdef CONFIG_WPS_OOB
1598         { "wps_oob", wpa_cli_cmd_wps_oob,
1599           cli_cmd_flag_sensitive,
1600           "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
1601 #endif /* CONFIG_WPS_OOB */
1602         { "wps_reg", wpa_cli_cmd_wps_reg,
1603           cli_cmd_flag_sensitive,
1604           "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
1605         { "wps_er_start", wpa_cli_cmd_wps_er_start,
1606           cli_cmd_flag_none,
1607           "= start Wi-Fi Protected Setup External Registrar" },
1608         { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
1609           cli_cmd_flag_none,
1610           "= stop Wi-Fi Protected Setup External Registrar" },
1611         { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
1612           cli_cmd_flag_sensitive,
1613           "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
1614         { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
1615           cli_cmd_flag_none,
1616           "<UUID> = accept an Enrollee PBC using External Registrar" },
1617         { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
1618           cli_cmd_flag_sensitive,
1619           "<UUID> <PIN> = learn AP configuration" },
1620         { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
1621           cli_cmd_flag_none,
1622           "<addr> = request RSN authentication with <addr> in IBSS" },
1623 #ifdef CONFIG_AP
1624         { "sta", wpa_cli_cmd_sta,
1625           cli_cmd_flag_none,
1626           "<addr> = get information about an associated station (AP)" },
1627         { "all_sta", wpa_cli_cmd_all_sta,
1628           cli_cmd_flag_none,
1629           "= get information about all associated stations (AP)" },
1630 #endif /* CONFIG_AP */
1631         { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
1632           "= notification of suspend/hibernate" },
1633         { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
1634           "= notification of resume/thaw" },
1635         { NULL, NULL, cli_cmd_flag_none, NULL }
1636 };
1637
1638
1639 /*
1640  * Prints command usage, lines are padded with the specified string.
1641  */
1642 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
1643 {
1644         char c;
1645         size_t n;
1646
1647         printf("%s%s ", pad, cmd->cmd);
1648         for (n = 0; (c = cmd->usage[n]); n++) {
1649                 printf("%c", c);
1650                 if (c == '\n')
1651                         printf("%s", pad);
1652         }
1653         printf("\n");
1654 }
1655
1656
1657 static void print_help(void)
1658 {
1659         int n;
1660         printf("commands:\n");
1661         for (n = 0; wpa_cli_commands[n].cmd; n++)
1662                 print_cmd_help(&wpa_cli_commands[n], "  ");
1663 }
1664
1665
1666 #ifdef CONFIG_READLINE
1667 static int cmd_has_sensitive_data(const char *cmd)
1668 {
1669         const char *c, *delim;
1670         int n;
1671         size_t len;
1672
1673         delim = os_strchr(cmd, ' ');
1674         if (delim)
1675                 len = delim - cmd;
1676         else
1677                 len = os_strlen(cmd);
1678
1679         for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
1680                 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
1681                         return (wpa_cli_commands[n].flags &
1682                                 cli_cmd_flag_sensitive);
1683         }
1684         return 0;
1685 }
1686 #endif /* CONFIG_READLINE */
1687
1688
1689 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1690 {
1691         struct wpa_cli_cmd *cmd, *match = NULL;
1692         int count;
1693         int ret = 0;
1694
1695         count = 0;
1696         cmd = wpa_cli_commands;
1697         while (cmd->cmd) {
1698                 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1699                 {
1700                         match = cmd;
1701                         if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1702                                 /* we have an exact match */
1703                                 count = 1;
1704                                 break;
1705                         }
1706                         count++;
1707                 }
1708                 cmd++;
1709         }
1710
1711         if (count > 1) {
1712                 printf("Ambiguous command '%s'; possible commands:", argv[0]);
1713                 cmd = wpa_cli_commands;
1714                 while (cmd->cmd) {
1715                         if (os_strncasecmp(cmd->cmd, argv[0],
1716                                            os_strlen(argv[0])) == 0) {
1717                                 printf(" %s", cmd->cmd);
1718                         }
1719                         cmd++;
1720                 }
1721                 printf("\n");
1722                 ret = 1;
1723         } else if (count == 0) {
1724                 printf("Unknown command '%s'\n", argv[0]);
1725                 ret = 1;
1726         } else {
1727                 ret = match->handler(ctrl, argc - 1, &argv[1]);
1728         }
1729
1730         return ret;
1731 }
1732
1733
1734 static int str_match(const char *a, const char *b)
1735 {
1736         return os_strncmp(a, b, os_strlen(b)) == 0;
1737 }
1738
1739
1740 static int wpa_cli_exec(const char *program, const char *arg1,
1741                         const char *arg2)
1742 {
1743         char *cmd;
1744         size_t len;
1745         int res;
1746         int ret = 0;
1747
1748         len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1749         cmd = os_malloc(len);
1750         if (cmd == NULL)
1751                 return -1;
1752         res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1753         if (res < 0 || (size_t) res >= len) {
1754                 os_free(cmd);
1755                 return -1;
1756         }
1757         cmd[len - 1] = '\0';
1758 #ifndef _WIN32_WCE
1759         if (system(cmd) < 0)
1760                 ret = -1;
1761 #endif /* _WIN32_WCE */
1762         os_free(cmd);
1763
1764         return ret;
1765 }
1766
1767
1768 static void wpa_cli_action_process(const char *msg)
1769 {
1770         const char *pos;
1771         char *copy = NULL, *id, *pos2;
1772
1773         pos = msg;
1774         if (*pos == '<') {
1775                 /* skip priority */
1776                 pos = os_strchr(pos, '>');
1777                 if (pos)
1778                         pos++;
1779                 else
1780                         pos = msg;
1781         }
1782
1783         if (str_match(pos, WPA_EVENT_CONNECTED)) {
1784                 int new_id = -1;
1785                 os_unsetenv("WPA_ID");
1786                 os_unsetenv("WPA_ID_STR");
1787                 os_unsetenv("WPA_CTRL_DIR");
1788
1789                 pos = os_strstr(pos, "[id=");
1790                 if (pos)
1791                         copy = os_strdup(pos + 4);
1792
1793                 if (copy) {
1794                         pos2 = id = copy;
1795                         while (*pos2 && *pos2 != ' ')
1796                                 pos2++;
1797                         *pos2++ = '\0';
1798                         new_id = atoi(id);
1799                         os_setenv("WPA_ID", id, 1);
1800                         while (*pos2 && *pos2 != '=')
1801                                 pos2++;
1802                         if (*pos2 == '=')
1803                                 pos2++;
1804                         id = pos2;
1805                         while (*pos2 && *pos2 != ']')
1806                                 pos2++;
1807                         *pos2 = '\0';
1808                         os_setenv("WPA_ID_STR", id, 1);
1809                         os_free(copy);
1810                 }
1811
1812                 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
1813
1814                 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
1815                         wpa_cli_connected = 1;
1816                         wpa_cli_last_id = new_id;
1817                         wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
1818                 }
1819         } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
1820                 if (wpa_cli_connected) {
1821                         wpa_cli_connected = 0;
1822                         wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
1823                 }
1824         } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
1825                 printf("wpa_supplicant is terminating - stop monitoring\n");
1826                 wpa_cli_quit = 1;
1827         }
1828 }
1829
1830
1831 #ifndef CONFIG_ANSI_C_EXTRA
1832 static void wpa_cli_action_cb(char *msg, size_t len)
1833 {
1834         wpa_cli_action_process(msg);
1835 }
1836 #endif /* CONFIG_ANSI_C_EXTRA */
1837
1838
1839 static void wpa_cli_reconnect(void)
1840 {
1841         wpa_cli_close_connection();
1842         wpa_cli_open_connection(ctrl_ifname, 1);
1843 }
1844
1845
1846 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
1847                                  int action_monitor)
1848 {
1849         int first = 1;
1850         if (ctrl_conn == NULL) {
1851                 wpa_cli_reconnect();
1852                 return;
1853         }
1854         while (wpa_ctrl_pending(ctrl) > 0) {
1855                 char buf[256];
1856                 size_t len = sizeof(buf) - 1;
1857                 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
1858                         buf[len] = '\0';
1859                         if (action_monitor)
1860                                 wpa_cli_action_process(buf);
1861                         else {
1862                                 if (in_read && first)
1863                                         printf("\r");
1864                                 first = 0;
1865                                 printf("%s\n", buf);
1866 #ifdef CONFIG_READLINE
1867                                 rl_on_new_line();
1868                                 rl_redisplay();
1869 #endif /* CONFIG_READLINE */
1870                         }
1871                 } else {
1872                         printf("Could not read pending message.\n");
1873                         break;
1874                 }
1875         }
1876
1877         if (wpa_ctrl_pending(ctrl) < 0) {
1878                 printf("Connection to wpa_supplicant lost - trying to "
1879                        "reconnect\n");
1880                 wpa_cli_reconnect();
1881         }
1882 }
1883
1884
1885 #ifdef CONFIG_READLINE
1886 static char * wpa_cli_cmd_gen(const char *text, int state)
1887 {
1888         static int i, len;
1889         const char *cmd;
1890
1891         if (state == 0) {
1892                 i = 0;
1893                 len = os_strlen(text);
1894         }
1895
1896         while ((cmd = wpa_cli_commands[i].cmd)) {
1897                 i++;
1898                 if (os_strncasecmp(cmd, text, len) == 0)
1899                         return strdup(cmd);
1900         }
1901
1902         return NULL;
1903 }
1904
1905
1906 static char * wpa_cli_dummy_gen(const char *text, int state)
1907 {
1908         int i;
1909
1910         for (i = 0; wpa_cli_commands[i].cmd; i++) {
1911                 const char *cmd = wpa_cli_commands[i].cmd;
1912                 size_t len = os_strlen(cmd);
1913                 if (os_strncasecmp(rl_line_buffer, cmd, len) == 0 &&
1914                     rl_line_buffer[len] == ' ') {
1915                         printf("\n%s\n", wpa_cli_commands[i].usage);
1916                         rl_on_new_line();
1917                         rl_redisplay();
1918                         break;
1919                 }
1920         }
1921
1922         rl_attempted_completion_over = 1;
1923         return NULL;
1924 }
1925
1926
1927 static char * wpa_cli_status_gen(const char *text, int state)
1928 {
1929         static int i, len;
1930         char *options[] = {
1931                 "verbose", NULL
1932         };
1933         char *t;
1934
1935         if (state == 0) {
1936                 i = 0;
1937                 len = os_strlen(text);
1938         }
1939
1940         while ((t = options[i])) {
1941                 i++;
1942                 if (os_strncasecmp(t, text, len) == 0)
1943                         return strdup(t);
1944         }
1945
1946         rl_attempted_completion_over = 1;
1947         return NULL;
1948 }
1949
1950
1951 static char ** wpa_cli_completion(const char *text, int start, int end)
1952 {
1953         char * (*func)(const char *text, int state);
1954
1955         if (start == 0)
1956                 func = wpa_cli_cmd_gen;
1957         else if (os_strncasecmp(rl_line_buffer, "status ", 7) == 0)
1958                 func = wpa_cli_status_gen;
1959         else
1960                 func = wpa_cli_dummy_gen;
1961         return rl_completion_matches(text, func);
1962 }
1963 #endif /* CONFIG_READLINE */
1964
1965
1966 static void wpa_cli_interactive(void)
1967 {
1968 #define max_args 10
1969         char cmdbuf[256], *cmd, *argv[max_args], *pos;
1970         int argc;
1971 #ifdef CONFIG_READLINE
1972         char *home, *hfile = NULL;
1973 #endif /* CONFIG_READLINE */
1974
1975         printf("\nInteractive mode\n\n");
1976
1977 #ifdef CONFIG_READLINE
1978         rl_attempted_completion_function = wpa_cli_completion;
1979         home = getenv("HOME");
1980         if (home) {
1981                 const char *fname = ".wpa_cli_history";
1982                 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
1983                 hfile = os_malloc(hfile_len);
1984                 if (hfile) {
1985                         int res;
1986                         res = os_snprintf(hfile, hfile_len, "%s/%s", home,
1987                                           fname);
1988                         if (res >= 0 && res < hfile_len) {
1989                                 hfile[hfile_len - 1] = '\0';
1990                                 read_history(hfile);
1991                                 stifle_history(100);
1992                         }
1993                 }
1994         }
1995 #endif /* CONFIG_READLINE */
1996
1997         do {
1998                 wpa_cli_recv_pending(mon_conn, 0, 0);
1999 #ifndef CONFIG_NATIVE_WINDOWS
2000                 alarm(ping_interval);
2001 #endif /* CONFIG_NATIVE_WINDOWS */
2002 #ifdef CONFIG_WPA_CLI_FORK
2003                 if (mon_pid)
2004                         kill(mon_pid, SIGUSR1);
2005 #endif /* CONFIG_WPA_CLI_FORK */
2006 #ifdef CONFIG_READLINE
2007                 cmd = readline("> ");
2008                 if (cmd && *cmd) {
2009                         HIST_ENTRY *h;
2010                         while (next_history())
2011                                 ;
2012                         h = previous_history();
2013                         if (h == NULL || os_strcmp(cmd, h->line) != 0)
2014                                 add_history(cmd);
2015                         next_history();
2016                 }
2017 #else /* CONFIG_READLINE */
2018                 printf("> ");
2019                 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
2020 #endif /* CONFIG_READLINE */
2021 #ifndef CONFIG_NATIVE_WINDOWS
2022                 alarm(0);
2023 #endif /* CONFIG_NATIVE_WINDOWS */
2024                 if (cmd == NULL)
2025                         break;
2026                 wpa_cli_recv_pending(mon_conn, 0, 0);
2027                 pos = cmd;
2028                 while (*pos != '\0') {
2029                         if (*pos == '\n') {
2030                                 *pos = '\0';
2031                                 break;
2032                         }
2033                         pos++;
2034                 }
2035                 argc = 0;
2036                 pos = cmd;
2037                 for (;;) {
2038                         while (*pos == ' ')
2039                                 pos++;
2040                         if (*pos == '\0')
2041                                 break;
2042                         argv[argc] = pos;
2043                         argc++;
2044                         if (argc == max_args)
2045                                 break;
2046                         if (*pos == '"') {
2047                                 char *pos2 = os_strrchr(pos, '"');
2048                                 if (pos2)
2049                                         pos = pos2 + 1;
2050                         }
2051                         while (*pos != '\0' && *pos != ' ')
2052                                 pos++;
2053                         if (*pos == ' ')
2054                                 *pos++ = '\0';
2055                 }
2056                 if (argc)
2057                         wpa_request(ctrl_conn, argc, argv);
2058
2059                 if (cmd != cmdbuf)
2060                         free(cmd);
2061 #ifdef CONFIG_WPA_CLI_FORK
2062                 if (mon_pid)
2063                         kill(mon_pid, SIGUSR2);
2064 #endif /* CONFIG_WPA_CLI_FORK */
2065         } while (!wpa_cli_quit);
2066
2067 #ifdef CONFIG_READLINE
2068         if (hfile) {
2069                 /* Save command history, excluding lines that may contain
2070                  * passwords. */
2071                 HIST_ENTRY *h;
2072                 history_set_pos(0);
2073                 while ((h = current_history())) {
2074                         char *p = h->line;
2075                         while (*p == ' ' || *p == '\t')
2076                                 p++;
2077                         if (cmd_has_sensitive_data(p)) {
2078                                 h = remove_history(where_history());
2079                                 if (h) {
2080                                         os_free(h->line);
2081                                         os_free(h->data);
2082                                         os_free(h);
2083                                 } else
2084                                         next_history();
2085                         } else
2086                                 next_history();
2087                 }
2088                 write_history(hfile);
2089                 os_free(hfile);
2090         }
2091 #endif /* CONFIG_READLINE */
2092 }
2093
2094
2095 static void wpa_cli_action(struct wpa_ctrl *ctrl)
2096 {
2097 #ifdef CONFIG_ANSI_C_EXTRA
2098         /* TODO: ANSI C version(?) */
2099         printf("Action processing not supported in ANSI C build.\n");
2100 #else /* CONFIG_ANSI_C_EXTRA */
2101         fd_set rfds;
2102         int fd, res;
2103         struct timeval tv;
2104         char buf[256]; /* note: large enough to fit in unsolicited messages */
2105         size_t len;
2106
2107         fd = wpa_ctrl_get_fd(ctrl);
2108
2109         while (!wpa_cli_quit) {
2110                 FD_ZERO(&rfds);
2111                 FD_SET(fd, &rfds);
2112                 tv.tv_sec = ping_interval;
2113                 tv.tv_usec = 0;
2114                 res = select(fd + 1, &rfds, NULL, NULL, &tv);
2115                 if (res < 0 && errno != EINTR) {
2116                         perror("select");
2117                         break;
2118                 }
2119
2120                 if (FD_ISSET(fd, &rfds))
2121                         wpa_cli_recv_pending(ctrl, 0, 1);
2122                 else {
2123                         /* verify that connection is still working */
2124                         len = sizeof(buf) - 1;
2125                         if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
2126                                              wpa_cli_action_cb) < 0 ||
2127                             len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
2128                                 printf("wpa_supplicant did not reply to PING "
2129                                        "command - exiting\n");
2130                                 break;
2131                         }
2132                 }
2133         }
2134 #endif /* CONFIG_ANSI_C_EXTRA */
2135 }
2136
2137
2138 static void wpa_cli_cleanup(void)
2139 {
2140         wpa_cli_close_connection();
2141         if (pid_file)
2142                 os_daemonize_terminate(pid_file);
2143
2144         os_program_deinit();
2145 }
2146
2147 static void wpa_cli_terminate(int sig)
2148 {
2149         wpa_cli_cleanup();
2150         exit(0);
2151 }
2152
2153
2154 #ifdef CONFIG_WPA_CLI_FORK
2155 static void wpa_cli_usr1(int sig)
2156 {
2157 #ifdef CONFIG_READLINE
2158         rl_on_new_line();
2159         rl_redisplay();
2160 #endif /* CONFIG_READLINE */
2161 }
2162 #endif /* CONFIG_WPA_CLI_FORK */
2163
2164
2165 #ifndef CONFIG_NATIVE_WINDOWS
2166 static void wpa_cli_alarm(int sig)
2167 {
2168         if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
2169                 printf("Connection to wpa_supplicant lost - trying to "
2170                        "reconnect\n");
2171                 wpa_cli_close_connection();
2172         }
2173         if (!ctrl_conn)
2174                 wpa_cli_reconnect();
2175         if (mon_conn)
2176                 wpa_cli_recv_pending(mon_conn, 1, 0);
2177         alarm(ping_interval);
2178 }
2179 #endif /* CONFIG_NATIVE_WINDOWS */
2180
2181
2182 static char * wpa_cli_get_default_ifname(void)
2183 {
2184         char *ifname = NULL;
2185
2186 #ifdef CONFIG_CTRL_IFACE_UNIX
2187         struct dirent *dent;
2188         DIR *dir = opendir(ctrl_iface_dir);
2189         if (!dir)
2190                 return NULL;
2191         while ((dent = readdir(dir))) {
2192 #ifdef _DIRENT_HAVE_D_TYPE
2193                 /*
2194                  * Skip the file if it is not a socket. Also accept
2195                  * DT_UNKNOWN (0) in case the C library or underlying
2196                  * file system does not support d_type.
2197                  */
2198                 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
2199                         continue;
2200 #endif /* _DIRENT_HAVE_D_TYPE */
2201                 if (os_strcmp(dent->d_name, ".") == 0 ||
2202                     os_strcmp(dent->d_name, "..") == 0)
2203                         continue;
2204                 printf("Selected interface '%s'\n", dent->d_name);
2205                 ifname = os_strdup(dent->d_name);
2206                 break;
2207         }
2208         closedir(dir);
2209 #endif /* CONFIG_CTRL_IFACE_UNIX */
2210
2211 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2212         char buf[2048], *pos;
2213         size_t len;
2214         struct wpa_ctrl *ctrl;
2215         int ret;
2216
2217         ctrl = wpa_ctrl_open(NULL);
2218         if (ctrl == NULL)
2219                 return NULL;
2220
2221         len = sizeof(buf) - 1;
2222         ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
2223         if (ret >= 0) {
2224                 buf[len] = '\0';
2225                 pos = os_strchr(buf, '\n');
2226                 if (pos)
2227                         *pos = '\0';
2228                 ifname = os_strdup(buf);
2229         }
2230         wpa_ctrl_close(ctrl);
2231 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2232
2233         return ifname;
2234 }
2235
2236
2237 int main(int argc, char *argv[])
2238 {
2239         int warning_displayed = 0;
2240         int c;
2241         int daemonize = 0;
2242         int ret = 0;
2243         const char *global = NULL;
2244
2245         if (os_program_init())
2246                 return -1;
2247
2248         for (;;) {
2249                 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
2250                 if (c < 0)
2251                         break;
2252                 switch (c) {
2253                 case 'a':
2254                         action_file = optarg;
2255                         break;
2256                 case 'B':
2257                         daemonize = 1;
2258                         break;
2259                 case 'g':
2260                         global = optarg;
2261                         break;
2262                 case 'G':
2263                         ping_interval = atoi(optarg);
2264                         break;
2265                 case 'h':
2266                         usage();
2267                         return 0;
2268                 case 'v':
2269                         printf("%s\n", wpa_cli_version);
2270                         return 0;
2271                 case 'i':
2272                         os_free(ctrl_ifname);
2273                         ctrl_ifname = os_strdup(optarg);
2274                         break;
2275                 case 'p':
2276                         ctrl_iface_dir = optarg;
2277                         break;
2278                 case 'P':
2279                         pid_file = optarg;
2280                         break;
2281                 default:
2282                         usage();
2283                         return -1;
2284                 }
2285         }
2286
2287         interactive = (argc == optind) && (action_file == NULL);
2288
2289         if (interactive)
2290                 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
2291
2292         if (global) {
2293 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2294                 ctrl_conn = wpa_ctrl_open(NULL);
2295 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2296                 ctrl_conn = wpa_ctrl_open(global);
2297 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2298                 if (ctrl_conn == NULL) {
2299                         perror("Failed to connect to wpa_supplicant - "
2300                                "wpa_ctrl_open");
2301                         return -1;
2302                 }
2303         }
2304
2305 #ifndef _WIN32_WCE
2306         signal(SIGINT, wpa_cli_terminate);
2307         signal(SIGTERM, wpa_cli_terminate);
2308 #endif /* _WIN32_WCE */
2309 #ifndef CONFIG_NATIVE_WINDOWS
2310         signal(SIGALRM, wpa_cli_alarm);
2311 #endif /* CONFIG_NATIVE_WINDOWS */
2312 #ifdef CONFIG_WPA_CLI_FORK
2313         signal(SIGUSR1, wpa_cli_usr1);
2314 #endif /* CONFIG_WPA_CLI_FORK */
2315
2316         if (ctrl_ifname == NULL)
2317                 ctrl_ifname = wpa_cli_get_default_ifname();
2318
2319         if (interactive) {
2320                 for (; !global;) {
2321                         if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
2322                                 if (warning_displayed)
2323                                         printf("Connection established.\n");
2324                                 break;
2325                         }
2326
2327                         if (!warning_displayed) {
2328                                 printf("Could not connect to wpa_supplicant - "
2329                                        "re-trying\n");
2330                                 warning_displayed = 1;
2331                         }
2332                         os_sleep(1, 0);
2333                         continue;
2334                 }
2335         } else {
2336                 if (!global &&
2337                     wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
2338                         perror("Failed to connect to wpa_supplicant - "
2339                                "wpa_ctrl_open");
2340                         return -1;
2341                 }
2342
2343                 if (action_file) {
2344                         if (wpa_ctrl_attach(ctrl_conn) == 0) {
2345                                 wpa_cli_attached = 1;
2346                         } else {
2347                                 printf("Warning: Failed to attach to "
2348                                        "wpa_supplicant.\n");
2349                                 return -1;
2350                         }
2351                 }
2352         }
2353
2354         if (daemonize && os_daemonize(pid_file))
2355                 return -1;
2356
2357         if (interactive)
2358                 wpa_cli_interactive();
2359         else if (action_file)
2360                 wpa_cli_action(ctrl_conn);
2361         else
2362                 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
2363
2364         os_free(ctrl_ifname);
2365         wpa_cli_cleanup();
2366
2367         return ret;
2368 }
2369
2370 #else /* CONFIG_CTRL_IFACE */
2371 int main(int argc, char *argv[])
2372 {
2373         printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
2374         return -1;
2375 }
2376 #endif /* CONFIG_CTRL_IFACE */