wpa_cli: Split wpa_cli_interactive() into two versions
[mech_eap.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 static void readline_redraw()
131 {
132 #ifdef CONFIG_READLINE
133         rl_on_new_line();
134         rl_redisplay();
135 #endif /* CONFIG_READLINE */
136 }
137
138
139 static int str_starts(const char *src, const char *match)
140 {
141         return os_strncmp(src, match, os_strlen(match)) == 0;
142 }
143
144
145 static int wpa_cli_show_event(const char *event)
146 {
147         const char *start;
148
149         start = os_strchr(event, '>');
150         if (start == NULL)
151                 return 1;
152
153         start++;
154         /*
155          * Skip BSS added/removed events since they can be relatively frequent
156          * and are likely of not much use for an interactive user.
157          */
158         if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
159             str_starts(start, WPA_EVENT_BSS_REMOVED))
160                 return 0;
161
162         return 1;
163 }
164
165
166 #ifdef CONFIG_WPA_CLI_FORK
167 static int in_query = 0;
168
169 static void wpa_cli_monitor_sig(int sig)
170 {
171         if (sig == SIGUSR1)
172                 in_query = 1;
173         else if (sig == SIGUSR2)
174                 in_query = 0;
175 }
176
177
178 static void wpa_cli_monitor(void)
179 {
180         char buf[256];
181         size_t len = sizeof(buf) - 1;
182         struct timeval tv;
183         fd_set rfds;
184         int ppid;
185
186         signal(SIGUSR1, wpa_cli_monitor_sig);
187         signal(SIGUSR2, wpa_cli_monitor_sig);
188
189         ppid = getppid();
190         while (mon_conn) {
191                 int s = wpa_ctrl_get_fd(mon_conn);
192                 tv.tv_sec = 5;
193                 tv.tv_usec = 0;
194                 FD_ZERO(&rfds);
195                 FD_SET(s, &rfds);
196                 if (select(s + 1, &rfds, NULL, NULL, &tv) < 0) {
197                         if (errno == EINTR)
198                                 continue;
199                         perror("select");
200                         break;
201                 }
202                 if (mon_conn == NULL)
203                         break;
204                 if (FD_ISSET(s, &rfds)) {
205                         len = sizeof(buf) - 1;
206                         int res = wpa_ctrl_recv(mon_conn, buf, &len);
207                         if (res < 0) {
208                                 perror("wpa_ctrl_recv");
209                                 break;
210                         }
211                         buf[len] = '\0';
212                         if (wpa_cli_show_event(buf)) {
213                                 if (in_query)
214                                         printf("\r");
215                                 printf("%s\n", buf);
216                                 kill(ppid, SIGUSR1);
217                         }
218                 }
219         }
220 }
221 #endif /* CONFIG_WPA_CLI_FORK */
222
223
224 static int wpa_cli_open_connection(const char *ifname, int attach)
225 {
226 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
227         ctrl_conn = wpa_ctrl_open(ifname);
228         if (ctrl_conn == NULL)
229                 return -1;
230
231         if (attach && interactive)
232                 mon_conn = wpa_ctrl_open(ifname);
233         else
234                 mon_conn = NULL;
235 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
236         char *cfile;
237         int flen, res;
238
239         if (ifname == NULL)
240                 return -1;
241
242         flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
243         cfile = os_malloc(flen);
244         if (cfile == NULL)
245                 return -1L;
246         res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
247         if (res < 0 || res >= flen) {
248                 os_free(cfile);
249                 return -1;
250         }
251
252         ctrl_conn = wpa_ctrl_open(cfile);
253         if (ctrl_conn == NULL) {
254                 os_free(cfile);
255                 return -1;
256         }
257
258         if (attach && interactive)
259                 mon_conn = wpa_ctrl_open(cfile);
260         else
261                 mon_conn = NULL;
262         os_free(cfile);
263 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
264
265         if (mon_conn) {
266                 if (wpa_ctrl_attach(mon_conn) == 0) {
267                         wpa_cli_attached = 1;
268                 } else {
269                         printf("Warning: Failed to attach to "
270                                "wpa_supplicant.\n");
271                         return -1;
272                 }
273
274 #ifdef CONFIG_WPA_CLI_FORK
275                 {
276                         pid_t p = fork();
277                         if (p < 0) {
278                                 perror("fork");
279                                 return -1;
280                         }
281                         if (p == 0) {
282                                 wpa_cli_monitor();
283                                 exit(0);
284                         } else
285                                 mon_pid = p;
286                 }
287 #endif /* CONFIG_WPA_CLI_FORK */
288         }
289
290         return 0;
291 }
292
293
294 static void wpa_cli_close_connection(void)
295 {
296         if (ctrl_conn == NULL)
297                 return;
298
299 #ifdef CONFIG_WPA_CLI_FORK
300         if (mon_pid) {
301                 int status;
302                 kill(mon_pid, SIGPIPE);
303                 wait(&status);
304                 mon_pid = 0;
305         }
306 #endif /* CONFIG_WPA_CLI_FORK */
307
308         if (wpa_cli_attached) {
309                 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
310                 wpa_cli_attached = 0;
311         }
312         wpa_ctrl_close(ctrl_conn);
313         ctrl_conn = NULL;
314         if (mon_conn) {
315                 wpa_ctrl_close(mon_conn);
316                 mon_conn = NULL;
317         }
318 }
319
320
321 static void wpa_cli_msg_cb(char *msg, size_t len)
322 {
323         printf("%s\n", msg);
324 }
325
326
327 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
328 {
329         char buf[2048];
330         size_t len;
331         int ret;
332
333         if (ctrl_conn == NULL) {
334                 printf("Not connected to wpa_supplicant - command dropped.\n");
335                 return -1;
336         }
337         len = sizeof(buf) - 1;
338         ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
339                                wpa_cli_msg_cb);
340         if (ret == -2) {
341                 printf("'%s' command timed out.\n", cmd);
342                 return -2;
343         } else if (ret < 0) {
344                 printf("'%s' command failed.\n", cmd);
345                 return -1;
346         }
347         if (print) {
348                 buf[len] = '\0';
349                 printf("%s", buf);
350         }
351         return 0;
352 }
353
354
355 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
356 {
357         return _wpa_ctrl_command(ctrl, cmd, 1);
358 }
359
360
361 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
362 {
363         int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
364         return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
365 }
366
367
368 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
369 {
370         return wpa_ctrl_command(ctrl, "PING");
371 }
372
373
374 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
375 {
376         char cmd[256];
377         int ret;
378         if (argc == 0)
379                 return -1;
380         ret = os_snprintf(cmd, sizeof(cmd), "NOTE %s", argv[0]);
381         if (ret < 0 || (size_t) ret >= sizeof(cmd))
382                 return -1;
383         return wpa_ctrl_command(ctrl, cmd);
384 }
385
386
387 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
388 {
389         return wpa_ctrl_command(ctrl, "MIB");
390 }
391
392
393 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
394 {
395         return wpa_ctrl_command(ctrl, "PMKSA");
396 }
397
398
399 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
400 {
401         print_help();
402         return 0;
403 }
404
405
406 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
407 {
408         printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
409         return 0;
410 }
411
412
413 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
414 {
415         wpa_cli_quit = 1;
416         return 0;
417 }
418
419
420 static void wpa_cli_show_variables(void)
421 {
422         printf("set variables:\n"
423                "  EAPOL::heldPeriod (EAPOL state machine held period, "
424                "in seconds)\n"
425                "  EAPOL::authPeriod (EAPOL state machine authentication "
426                "period, in seconds)\n"
427                "  EAPOL::startPeriod (EAPOL state machine start period, in "
428                "seconds)\n"
429                "  EAPOL::maxStart (EAPOL state machine maximum start "
430                "attempts)\n");
431         printf("  dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
432                "seconds)\n"
433                "  dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
434                " threshold\n\tpercentage)\n"
435                "  dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
436                "security\n\tassociation in seconds)\n");
437 }
438
439
440 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
441 {
442         char cmd[256];
443         int res;
444
445         if (argc == 0) {
446                 wpa_cli_show_variables();
447                 return 0;
448         }
449
450         if (argc != 2) {
451                 printf("Invalid SET command: needs two arguments (variable "
452                        "name and value)\n");
453                 return -1;
454         }
455
456         res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
457         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
458                 printf("Too long SET command.\n");
459                 return -1;
460         }
461         return wpa_ctrl_command(ctrl, cmd);
462 }
463
464
465 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
466 {
467         char cmd[256];
468         int res;
469
470         if (argc != 1) {
471                 printf("Invalid GET command: need one argument (variable "
472                        "name)\n");
473                 return -1;
474         }
475
476         res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
477         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
478                 printf("Too long GET command.\n");
479                 return -1;
480         }
481         return wpa_ctrl_command(ctrl, cmd);
482 }
483
484
485 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
486 {
487         return wpa_ctrl_command(ctrl, "LOGOFF");
488 }
489
490
491 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
492 {
493         return wpa_ctrl_command(ctrl, "LOGON");
494 }
495
496
497 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
498                                    char *argv[])
499 {
500         return wpa_ctrl_command(ctrl, "REASSOCIATE");
501 }
502
503
504 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
505                                        char *argv[])
506 {
507         char cmd[256];
508         int res;
509
510         if (argc != 1) {
511                 printf("Invalid PREAUTH command: needs one argument "
512                        "(BSSID)\n");
513                 return -1;
514         }
515
516         res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
517         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
518                 printf("Too long PREAUTH command.\n");
519                 return -1;
520         }
521         return wpa_ctrl_command(ctrl, cmd);
522 }
523
524
525 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
526 {
527         char cmd[256];
528         int res;
529
530         if (argc != 1) {
531                 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
532                        "value)\n");
533                 return -1;
534         }
535         res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
536         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
537                 printf("Too long AP_SCAN command.\n");
538                 return -1;
539         }
540         return wpa_ctrl_command(ctrl, cmd);
541 }
542
543
544 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
545                                 char *argv[])
546 {
547         char cmd[256];
548         int res;
549
550         if (argc != 1) {
551                 printf("Invalid STKSTART command: needs one argument "
552                        "(Peer STA MAC address)\n");
553                 return -1;
554         }
555
556         res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
557         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
558                 printf("Too long STKSTART command.\n");
559                 return -1;
560         }
561         return wpa_ctrl_command(ctrl, cmd);
562 }
563
564
565 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
566 {
567         char cmd[256];
568         int res;
569
570         if (argc != 1) {
571                 printf("Invalid FT_DS command: needs one argument "
572                        "(Target AP MAC address)\n");
573                 return -1;
574         }
575
576         res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
577         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
578                 printf("Too long FT_DS command.\n");
579                 return -1;
580         }
581         return wpa_ctrl_command(ctrl, cmd);
582 }
583
584
585 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
586 {
587         char cmd[256];
588         int res;
589
590         if (argc == 0) {
591                 /* Any BSSID */
592                 return wpa_ctrl_command(ctrl, "WPS_PBC");
593         }
594
595         /* Specific BSSID */
596         res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
597         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
598                 printf("Too long WPS_PBC command.\n");
599                 return -1;
600         }
601         return wpa_ctrl_command(ctrl, cmd);
602 }
603
604
605 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
606 {
607         char cmd[256];
608         int res;
609
610         if (argc == 0) {
611                 printf("Invalid WPS_PIN command: need one or two arguments:\n"
612                        "- BSSID: use 'any' to select any\n"
613                        "- PIN: optional, used only with devices that have no "
614                        "display\n");
615                 return -1;
616         }
617
618         if (argc == 1) {
619                 /* Use dynamically generated PIN (returned as reply) */
620                 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
621                 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
622                         printf("Too long WPS_PIN command.\n");
623                         return -1;
624                 }
625                 return wpa_ctrl_command(ctrl, cmd);
626         }
627
628         /* Use hardcoded PIN from a label */
629         res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
630         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
631                 printf("Too long WPS_PIN command.\n");
632                 return -1;
633         }
634         return wpa_ctrl_command(ctrl, cmd);
635 }
636
637
638 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
639                                      char *argv[])
640 {
641         char cmd[256];
642         int res;
643
644         if (argc != 1 && argc != 2) {
645                 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
646                        "- PIN to be verified\n");
647                 return -1;
648         }
649
650         if (argc == 2)
651                 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
652                                   argv[0], argv[1]);
653         else
654                 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
655                                   argv[0]);
656         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
657                 printf("Too long WPS_CHECK_PIN command.\n");
658                 return -1;
659         }
660         return wpa_ctrl_command(ctrl, cmd);
661 }
662
663
664 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
665                                   char *argv[])
666 {
667         return wpa_ctrl_command(ctrl, "WPS_CANCEL");
668 }
669
670
671 #ifdef CONFIG_WPS_OOB
672 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
673 {
674         char cmd[256];
675         int res;
676
677         if (argc != 3 && argc != 4) {
678                 printf("Invalid WPS_OOB command: need three or four "
679                        "arguments:\n"
680                        "- DEV_TYPE: use 'ufd' or 'nfc'\n"
681                        "- PATH: path of OOB device like '/mnt'\n"
682                        "- METHOD: OOB method 'pin-e' or 'pin-r', "
683                        "'cred'\n"
684                        "- DEV_NAME: (only for NFC) device name like "
685                        "'pn531'\n");
686                 return -1;
687         }
688
689         if (argc == 3)
690                 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
691                                   argv[0], argv[1], argv[2]);
692         else
693                 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
694                                   argv[0], argv[1], argv[2], argv[3]);
695         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
696                 printf("Too long WPS_OOB command.\n");
697                 return -1;
698         }
699         return wpa_ctrl_command(ctrl, cmd);
700 }
701 #endif /* CONFIG_WPS_OOB */
702
703
704 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
705 {
706         char cmd[256];
707         int res;
708
709         if (argc == 2)
710                 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
711                                   argv[0], argv[1]);
712         else if (argc == 5 || argc == 6) {
713                 char ssid_hex[2 * 32 + 1];
714                 char key_hex[2 * 64 + 1];
715                 int i;
716
717                 ssid_hex[0] = '\0';
718                 for (i = 0; i < 32; i++) {
719                         if (argv[2][i] == '\0')
720                                 break;
721                         os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
722                 }
723
724                 key_hex[0] = '\0';
725                 if (argc == 6) {
726                         for (i = 0; i < 64; i++) {
727                                 if (argv[5][i] == '\0')
728                                         break;
729                                 os_snprintf(&key_hex[i * 2], 3, "%02x",
730                                             argv[5][i]);
731                         }
732                 }
733
734                 res = os_snprintf(cmd, sizeof(cmd),
735                                   "WPS_REG %s %s %s %s %s %s",
736                                   argv[0], argv[1], ssid_hex, argv[3], argv[4],
737                                   key_hex);
738         } else {
739                 printf("Invalid WPS_REG command: need two arguments:\n"
740                        "- BSSID of the target AP\n"
741                        "- AP PIN\n");
742                 printf("Alternatively, six arguments can be used to "
743                        "reconfigure the AP:\n"
744                        "- BSSID of the target AP\n"
745                        "- AP PIN\n"
746                        "- new SSID\n"
747                        "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
748                        "- new encr (NONE, WEP, TKIP, CCMP)\n"
749                        "- new key\n");
750                 return -1;
751         }
752
753         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
754                 printf("Too long WPS_REG command.\n");
755                 return -1;
756         }
757         return wpa_ctrl_command(ctrl, cmd);
758 }
759
760
761 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
762                                     char *argv[])
763 {
764         char cmd[100];
765         if (argc > 0) {
766                 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
767                 return wpa_ctrl_command(ctrl, cmd);
768         }
769         return wpa_ctrl_command(ctrl, "WPS_ER_START");
770 }
771
772
773 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
774                                    char *argv[])
775 {
776         return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
777
778 }
779
780
781 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
782                                   char *argv[])
783 {
784         char cmd[256];
785         int res;
786
787         if (argc < 2) {
788                 printf("Invalid WPS_ER_PIN command: need at least two "
789                        "arguments:\n"
790                        "- UUID: use 'any' to select any\n"
791                        "- PIN: Enrollee PIN\n"
792                        "optional: - Enrollee MAC address\n");
793                 return -1;
794         }
795
796         if (argc > 2)
797                 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
798                                   argv[0], argv[1], argv[2]);
799         else
800                 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
801                                   argv[0], argv[1]);
802         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
803                 printf("Too long WPS_ER_PIN command.\n");
804                 return -1;
805         }
806         return wpa_ctrl_command(ctrl, cmd);
807 }
808
809
810 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
811                                   char *argv[])
812 {
813         char cmd[256];
814         int res;
815
816         if (argc != 1) {
817                 printf("Invalid WPS_ER_PBC command: need one argument:\n"
818                        "- UUID: Specify the Enrollee\n");
819                 return -1;
820         }
821
822         res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
823                           argv[0]);
824         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
825                 printf("Too long WPS_ER_PBC command.\n");
826                 return -1;
827         }
828         return wpa_ctrl_command(ctrl, cmd);
829 }
830
831
832 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
833                                     char *argv[])
834 {
835         char cmd[256];
836         int res;
837
838         if (argc != 2) {
839                 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
840                        "- UUID: specify which AP to use\n"
841                        "- PIN: AP PIN\n");
842                 return -1;
843         }
844
845         res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
846                           argv[0], argv[1]);
847         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
848                 printf("Too long WPS_ER_LEARN command.\n");
849                 return -1;
850         }
851         return wpa_ctrl_command(ctrl, cmd);
852 }
853
854
855 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
856                                          char *argv[])
857 {
858         char cmd[256];
859         int res;
860
861         if (argc != 2) {
862                 printf("Invalid WPS_ER_SET_CONFIG command: need two "
863                        "arguments:\n"
864                        "- UUID: specify which AP to use\n"
865                        "- Network configuration id\n");
866                 return -1;
867         }
868
869         res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_SET_CONFIG %s %s",
870                           argv[0], argv[1]);
871         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
872                 printf("Too long WPS_ER_SET_CONFIG command.\n");
873                 return -1;
874         }
875         return wpa_ctrl_command(ctrl, cmd);
876 }
877
878
879 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
880                                      char *argv[])
881 {
882         char cmd[256];
883         int res;
884
885         if (argc == 5 || argc == 6) {
886                 char ssid_hex[2 * 32 + 1];
887                 char key_hex[2 * 64 + 1];
888                 int i;
889
890                 ssid_hex[0] = '\0';
891                 for (i = 0; i < 32; i++) {
892                         if (argv[2][i] == '\0')
893                                 break;
894                         os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
895                 }
896
897                 key_hex[0] = '\0';
898                 if (argc == 6) {
899                         for (i = 0; i < 64; i++) {
900                                 if (argv[5][i] == '\0')
901                                         break;
902                                 os_snprintf(&key_hex[i * 2], 3, "%02x",
903                                             argv[5][i]);
904                         }
905                 }
906
907                 res = os_snprintf(cmd, sizeof(cmd),
908                                   "WPS_ER_CONFIG %s %s %s %s %s %s",
909                                   argv[0], argv[1], ssid_hex, argv[3], argv[4],
910                                   key_hex);
911         } else {
912                 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
913                        "- AP UUID\n"
914                        "- AP PIN\n"
915                        "- new SSID\n"
916                        "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
917                        "- new encr (NONE, WEP, TKIP, CCMP)\n"
918                        "- new key\n");
919                 return -1;
920         }
921
922         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
923                 printf("Too long WPS_ER_CONFIG command.\n");
924                 return -1;
925         }
926         return wpa_ctrl_command(ctrl, cmd);
927 }
928
929
930 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
931 {
932         char cmd[256];
933         int res;
934
935         if (argc != 1) {
936                 printf("Invalid IBSS_RSN command: needs one argument "
937                        "(Peer STA MAC address)\n");
938                 return -1;
939         }
940
941         res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
942         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
943                 printf("Too long IBSS_RSN command.\n");
944                 return -1;
945         }
946         return wpa_ctrl_command(ctrl, cmd);
947 }
948
949
950 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
951 {
952         char cmd[256];
953         int res;
954
955         if (argc != 1) {
956                 printf("Invalid LEVEL command: needs one argument (debug "
957                        "level)\n");
958                 return -1;
959         }
960         res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
961         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
962                 printf("Too long LEVEL command.\n");
963                 return -1;
964         }
965         return wpa_ctrl_command(ctrl, cmd);
966 }
967
968
969 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
970 {
971         char cmd[256], *pos, *end;
972         int i, ret;
973
974         if (argc < 2) {
975                 printf("Invalid IDENTITY command: needs two arguments "
976                        "(network id and identity)\n");
977                 return -1;
978         }
979
980         end = cmd + sizeof(cmd);
981         pos = cmd;
982         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
983                           argv[0], argv[1]);
984         if (ret < 0 || ret >= end - pos) {
985                 printf("Too long IDENTITY command.\n");
986                 return -1;
987         }
988         pos += ret;
989         for (i = 2; i < argc; i++) {
990                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
991                 if (ret < 0 || ret >= end - pos) {
992                         printf("Too long IDENTITY command.\n");
993                         return -1;
994                 }
995                 pos += ret;
996         }
997
998         return wpa_ctrl_command(ctrl, cmd);
999 }
1000
1001
1002 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1003 {
1004         char cmd[256], *pos, *end;
1005         int i, ret;
1006
1007         if (argc < 2) {
1008                 printf("Invalid PASSWORD command: needs two arguments "
1009                        "(network id and password)\n");
1010                 return -1;
1011         }
1012
1013         end = cmd + sizeof(cmd);
1014         pos = cmd;
1015         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1016                           argv[0], argv[1]);
1017         if (ret < 0 || ret >= end - pos) {
1018                 printf("Too long PASSWORD command.\n");
1019                 return -1;
1020         }
1021         pos += ret;
1022         for (i = 2; i < argc; i++) {
1023                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1024                 if (ret < 0 || ret >= end - pos) {
1025                         printf("Too long PASSWORD command.\n");
1026                         return -1;
1027                 }
1028                 pos += ret;
1029         }
1030
1031         return wpa_ctrl_command(ctrl, cmd);
1032 }
1033
1034
1035 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1036                                     char *argv[])
1037 {
1038         char cmd[256], *pos, *end;
1039         int i, ret;
1040
1041         if (argc < 2) {
1042                 printf("Invalid NEW_PASSWORD command: needs two arguments "
1043                        "(network id and password)\n");
1044                 return -1;
1045         }
1046
1047         end = cmd + sizeof(cmd);
1048         pos = cmd;
1049         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1050                           argv[0], argv[1]);
1051         if (ret < 0 || ret >= end - pos) {
1052                 printf("Too long NEW_PASSWORD command.\n");
1053                 return -1;
1054         }
1055         pos += ret;
1056         for (i = 2; i < argc; i++) {
1057                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1058                 if (ret < 0 || ret >= end - pos) {
1059                         printf("Too long NEW_PASSWORD command.\n");
1060                         return -1;
1061                 }
1062                 pos += ret;
1063         }
1064
1065         return wpa_ctrl_command(ctrl, cmd);
1066 }
1067
1068
1069 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1070 {
1071         char cmd[256], *pos, *end;
1072         int i, ret;
1073
1074         if (argc < 2) {
1075                 printf("Invalid PIN command: needs two arguments "
1076                        "(network id and pin)\n");
1077                 return -1;
1078         }
1079
1080         end = cmd + sizeof(cmd);
1081         pos = cmd;
1082         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1083                           argv[0], argv[1]);
1084         if (ret < 0 || ret >= end - pos) {
1085                 printf("Too long PIN command.\n");
1086                 return -1;
1087         }
1088         pos += ret;
1089         for (i = 2; i < argc; i++) {
1090                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1091                 if (ret < 0 || ret >= end - pos) {
1092                         printf("Too long PIN command.\n");
1093                         return -1;
1094                 }
1095                 pos += ret;
1096         }
1097         return wpa_ctrl_command(ctrl, cmd);
1098 }
1099
1100
1101 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1102 {
1103         char cmd[256], *pos, *end;
1104         int i, ret;
1105
1106         if (argc < 2) {
1107                 printf("Invalid OTP command: needs two arguments (network "
1108                        "id and password)\n");
1109                 return -1;
1110         }
1111
1112         end = cmd + sizeof(cmd);
1113         pos = cmd;
1114         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1115                           argv[0], argv[1]);
1116         if (ret < 0 || ret >= end - pos) {
1117                 printf("Too long OTP command.\n");
1118                 return -1;
1119         }
1120         pos += ret;
1121         for (i = 2; i < argc; i++) {
1122                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1123                 if (ret < 0 || ret >= end - pos) {
1124                         printf("Too long OTP command.\n");
1125                         return -1;
1126                 }
1127                 pos += ret;
1128         }
1129
1130         return wpa_ctrl_command(ctrl, cmd);
1131 }
1132
1133
1134 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1135                                   char *argv[])
1136 {
1137         char cmd[256], *pos, *end;
1138         int i, ret;
1139
1140         if (argc < 2) {
1141                 printf("Invalid PASSPHRASE command: needs two arguments "
1142                        "(network id and passphrase)\n");
1143                 return -1;
1144         }
1145
1146         end = cmd + sizeof(cmd);
1147         pos = cmd;
1148         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1149                           argv[0], argv[1]);
1150         if (ret < 0 || ret >= end - pos) {
1151                 printf("Too long PASSPHRASE command.\n");
1152                 return -1;
1153         }
1154         pos += ret;
1155         for (i = 2; i < argc; i++) {
1156                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1157                 if (ret < 0 || ret >= end - pos) {
1158                         printf("Too long PASSPHRASE command.\n");
1159                         return -1;
1160                 }
1161                 pos += ret;
1162         }
1163
1164         return wpa_ctrl_command(ctrl, cmd);
1165 }
1166
1167
1168 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1169 {
1170         char cmd[256], *pos, *end;
1171         int i, ret;
1172
1173         if (argc < 2) {
1174                 printf("Invalid BSSID command: needs two arguments (network "
1175                        "id and BSSID)\n");
1176                 return -1;
1177         }
1178
1179         end = cmd + sizeof(cmd);
1180         pos = cmd;
1181         ret = os_snprintf(pos, end - pos, "BSSID");
1182         if (ret < 0 || ret >= end - pos) {
1183                 printf("Too long BSSID command.\n");
1184                 return -1;
1185         }
1186         pos += ret;
1187         for (i = 0; i < argc; i++) {
1188                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1189                 if (ret < 0 || ret >= end - pos) {
1190                         printf("Too long BSSID command.\n");
1191                         return -1;
1192                 }
1193                 pos += ret;
1194         }
1195
1196         return wpa_ctrl_command(ctrl, cmd);
1197 }
1198
1199
1200 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1201                                      char *argv[])
1202 {
1203         return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1204 }
1205
1206
1207 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1208                                       char *argv[])
1209 {
1210         char cmd[32];
1211         int res;
1212
1213         if (argc < 1) {
1214                 printf("Invalid SELECT_NETWORK command: needs one argument "
1215                        "(network id)\n");
1216                 return -1;
1217         }
1218
1219         res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1220         if (res < 0 || (size_t) res >= sizeof(cmd))
1221                 return -1;
1222         cmd[sizeof(cmd) - 1] = '\0';
1223
1224         return wpa_ctrl_command(ctrl, cmd);
1225 }
1226
1227
1228 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1229                                       char *argv[])
1230 {
1231         char cmd[32];
1232         int res;
1233
1234         if (argc < 1) {
1235                 printf("Invalid ENABLE_NETWORK command: needs one argument "
1236                        "(network id)\n");
1237                 return -1;
1238         }
1239
1240         res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1241         if (res < 0 || (size_t) res >= sizeof(cmd))
1242                 return -1;
1243         cmd[sizeof(cmd) - 1] = '\0';
1244
1245         return wpa_ctrl_command(ctrl, cmd);
1246 }
1247
1248
1249 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1250                                        char *argv[])
1251 {
1252         char cmd[32];
1253         int res;
1254
1255         if (argc < 1) {
1256                 printf("Invalid DISABLE_NETWORK command: needs one argument "
1257                        "(network id)\n");
1258                 return -1;
1259         }
1260
1261         res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1262         if (res < 0 || (size_t) res >= sizeof(cmd))
1263                 return -1;
1264         cmd[sizeof(cmd) - 1] = '\0';
1265
1266         return wpa_ctrl_command(ctrl, cmd);
1267 }
1268
1269
1270 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1271                                    char *argv[])
1272 {
1273         return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1274 }
1275
1276
1277 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1278                                       char *argv[])
1279 {
1280         char cmd[32];
1281         int res;
1282
1283         if (argc < 1) {
1284                 printf("Invalid REMOVE_NETWORK command: needs one argument "
1285                        "(network id)\n");
1286                 return -1;
1287         }
1288
1289         res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1290         if (res < 0 || (size_t) res >= sizeof(cmd))
1291                 return -1;
1292         cmd[sizeof(cmd) - 1] = '\0';
1293
1294         return wpa_ctrl_command(ctrl, cmd);
1295 }
1296
1297
1298 static void wpa_cli_show_network_variables(void)
1299 {
1300         printf("set_network variables:\n"
1301                "  ssid (network name, SSID)\n"
1302                "  psk (WPA passphrase or pre-shared key)\n"
1303                "  key_mgmt (key management protocol)\n"
1304                "  identity (EAP identity)\n"
1305                "  password (EAP password)\n"
1306                "  ...\n"
1307                "\n"
1308                "Note: Values are entered in the same format as the "
1309                "configuration file is using,\n"
1310                "i.e., strings values need to be inside double quotation "
1311                "marks.\n"
1312                "For example: set_network 1 ssid \"network name\"\n"
1313                "\n"
1314                "Please see wpa_supplicant.conf documentation for full list "
1315                "of\navailable variables.\n");
1316 }
1317
1318
1319 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1320                                    char *argv[])
1321 {
1322         char cmd[256];
1323         int res;
1324
1325         if (argc == 0) {
1326                 wpa_cli_show_network_variables();
1327                 return 0;
1328         }
1329
1330         if (argc != 3) {
1331                 printf("Invalid SET_NETWORK command: needs three arguments\n"
1332                        "(network id, variable name, and value)\n");
1333                 return -1;
1334         }
1335
1336         res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1337                           argv[0], argv[1], argv[2]);
1338         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1339                 printf("Too long SET_NETWORK command.\n");
1340                 return -1;
1341         }
1342         return wpa_ctrl_command(ctrl, cmd);
1343 }
1344
1345
1346 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1347                                    char *argv[])
1348 {
1349         char cmd[256];
1350         int res;
1351
1352         if (argc == 0) {
1353                 wpa_cli_show_network_variables();
1354                 return 0;
1355         }
1356
1357         if (argc != 2) {
1358                 printf("Invalid GET_NETWORK command: needs two arguments\n"
1359                        "(network id and variable name)\n");
1360                 return -1;
1361         }
1362
1363         res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1364                           argv[0], argv[1]);
1365         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1366                 printf("Too long GET_NETWORK command.\n");
1367                 return -1;
1368         }
1369         return wpa_ctrl_command(ctrl, cmd);
1370 }
1371
1372
1373 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1374                                   char *argv[])
1375 {
1376         return wpa_ctrl_command(ctrl, "DISCONNECT");
1377 }
1378
1379
1380 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1381                                   char *argv[])
1382 {
1383         return wpa_ctrl_command(ctrl, "RECONNECT");
1384 }
1385
1386
1387 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1388                                    char *argv[])
1389 {
1390         return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1391 }
1392
1393
1394 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1395 {
1396         return wpa_ctrl_command(ctrl, "SCAN");
1397 }
1398
1399
1400 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1401                                     char *argv[])
1402 {
1403         return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1404 }
1405
1406
1407 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1408 {
1409         char cmd[64];
1410         int res;
1411
1412         if (argc != 1) {
1413                 printf("Invalid BSS command: need one argument (index or "
1414                        "BSSID)\n");
1415                 return -1;
1416         }
1417
1418         res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1419         if (res < 0 || (size_t) res >= sizeof(cmd))
1420                 return -1;
1421         cmd[sizeof(cmd) - 1] = '\0';
1422
1423         return wpa_ctrl_command(ctrl, cmd);
1424 }
1425
1426
1427 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1428                                       char *argv[])
1429 {
1430         char cmd[64];
1431         int res;
1432
1433         if (argc < 1 || argc > 2) {
1434                 printf("Invalid GET_CAPABILITY command: need either one or "
1435                        "two arguments\n");
1436                 return -1;
1437         }
1438
1439         if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1440                 printf("Invalid GET_CAPABILITY command: second argument, "
1441                        "if any, must be 'strict'\n");
1442                 return -1;
1443         }
1444
1445         res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1446                           (argc == 2) ? " strict" : "");
1447         if (res < 0 || (size_t) res >= sizeof(cmd))
1448                 return -1;
1449         cmd[sizeof(cmd) - 1] = '\0';
1450
1451         return wpa_ctrl_command(ctrl, cmd);
1452 }
1453
1454
1455 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1456 {
1457         printf("Available interfaces:\n");
1458         return wpa_ctrl_command(ctrl, "INTERFACES");
1459 }
1460
1461
1462 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1463 {
1464         if (argc < 1) {
1465                 wpa_cli_list_interfaces(ctrl);
1466                 return 0;
1467         }
1468
1469         wpa_cli_close_connection();
1470         os_free(ctrl_ifname);
1471         ctrl_ifname = os_strdup(argv[0]);
1472
1473         if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1474                 printf("Connected to interface '%s.\n", ctrl_ifname);
1475         } else {
1476                 printf("Could not connect to interface '%s' - re-trying\n",
1477                        ctrl_ifname);
1478         }
1479         return 0;
1480 }
1481
1482
1483 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1484                                    char *argv[])
1485 {
1486         return wpa_ctrl_command(ctrl, "RECONFIGURE");
1487 }
1488
1489
1490 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1491                                  char *argv[])
1492 {
1493         return wpa_ctrl_command(ctrl, "TERMINATE");
1494 }
1495
1496
1497 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1498                                      char *argv[])
1499 {
1500         char cmd[256];
1501         int res;
1502
1503         if (argc < 1) {
1504                 printf("Invalid INTERFACE_ADD command: needs at least one "
1505                        "argument (interface name)\n"
1506                        "All arguments: ifname confname driver ctrl_interface "
1507                        "driver_param bridge_name\n");
1508                 return -1;
1509         }
1510
1511         /*
1512          * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1513          * <driver_param>TAB<bridge_name>
1514          */
1515         res = os_snprintf(cmd, sizeof(cmd),
1516                           "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1517                           argv[0],
1518                           argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1519                           argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1520                           argc > 5 ? argv[5] : "");
1521         if (res < 0 || (size_t) res >= sizeof(cmd))
1522                 return -1;
1523         cmd[sizeof(cmd) - 1] = '\0';
1524         return wpa_ctrl_command(ctrl, cmd);
1525 }
1526
1527
1528 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1529                                         char *argv[])
1530 {
1531         char cmd[128];
1532         int res;
1533
1534         if (argc != 1) {
1535                 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1536                        "(interface name)\n");
1537                 return -1;
1538         }
1539
1540         res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1541         if (res < 0 || (size_t) res >= sizeof(cmd))
1542                 return -1;
1543         cmd[sizeof(cmd) - 1] = '\0';
1544         return wpa_ctrl_command(ctrl, cmd);
1545 }
1546
1547
1548 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1549                                       char *argv[])
1550 {
1551         return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1552 }
1553
1554
1555 #ifdef CONFIG_AP
1556 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1557 {
1558         char buf[64];
1559         if (argc != 1) {
1560                 printf("Invalid 'sta' command - exactly one argument, STA "
1561                        "address, is required.\n");
1562                 return -1;
1563         }
1564         os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1565         return wpa_ctrl_command(ctrl, buf);
1566 }
1567
1568
1569 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1570                                 char *addr, size_t addr_len)
1571 {
1572         char buf[4096], *pos;
1573         size_t len;
1574         int ret;
1575
1576         if (ctrl_conn == NULL) {
1577                 printf("Not connected to hostapd - command dropped.\n");
1578                 return -1;
1579         }
1580         len = sizeof(buf) - 1;
1581         ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1582                                wpa_cli_msg_cb);
1583         if (ret == -2) {
1584                 printf("'%s' command timed out.\n", cmd);
1585                 return -2;
1586         } else if (ret < 0) {
1587                 printf("'%s' command failed.\n", cmd);
1588                 return -1;
1589         }
1590
1591         buf[len] = '\0';
1592         if (memcmp(buf, "FAIL", 4) == 0)
1593                 return -1;
1594         printf("%s", buf);
1595
1596         pos = buf;
1597         while (*pos != '\0' && *pos != '\n')
1598                 pos++;
1599         *pos = '\0';
1600         os_strlcpy(addr, buf, addr_len);
1601         return 0;
1602 }
1603
1604
1605 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1606 {
1607         char addr[32], cmd[64];
1608
1609         if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1610                 return 0;
1611         do {
1612                 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1613         } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1614
1615         return -1;
1616 }
1617 #endif /* CONFIG_AP */
1618
1619
1620 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1621 {
1622         return wpa_ctrl_command(ctrl, "SUSPEND");
1623 }
1624
1625
1626 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1627 {
1628         return wpa_ctrl_command(ctrl, "RESUME");
1629 }
1630
1631
1632 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1633 {
1634         return wpa_ctrl_command(ctrl, "DROP_SA");
1635 }
1636
1637
1638 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1639 {
1640         char cmd[128];
1641         int res;
1642
1643         if (argc != 1) {
1644                 printf("Invalid ROAM command: needs one argument "
1645                        "(target AP's BSSID)\n");
1646                 return -1;
1647         }
1648
1649         res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1650         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1651                 printf("Too long ROAM command.\n");
1652                 return -1;
1653         }
1654         return wpa_ctrl_command(ctrl, cmd);
1655 }
1656
1657
1658 #ifdef CONFIG_P2P
1659
1660 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1661 {
1662         char cmd[128];
1663         int res;
1664
1665         if (argc == 0)
1666                 return wpa_ctrl_command(ctrl, "P2P_FIND");
1667
1668         if (argc > 1)
1669                 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
1670                                   argv[0], argv[1]);
1671         else
1672                 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
1673         if (res < 0 || (size_t) res >= sizeof(cmd))
1674                 return -1;
1675         cmd[sizeof(cmd) - 1] = '\0';
1676         return wpa_ctrl_command(ctrl, cmd);
1677 }
1678
1679
1680 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1681                                      char *argv[])
1682 {
1683         return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1684 }
1685
1686
1687 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1688                                    char *argv[])
1689 {
1690         char cmd[128];
1691         int res;
1692
1693         if (argc < 2) {
1694                 printf("Invalid P2P_CONNECT command: needs at least two "
1695                        "arguments (address and pbc/PIN)\n");
1696                 return -1;
1697         }
1698
1699         if (argc > 4)
1700                 res = os_snprintf(cmd, sizeof(cmd),
1701                                   "P2P_CONNECT %s %s %s %s %s",
1702                                   argv[0], argv[1], argv[2], argv[3],
1703                                   argv[4]);
1704         else if (argc > 3)
1705                 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
1706                                   argv[0], argv[1], argv[2], argv[3]);
1707         else if (argc > 2)
1708                 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
1709                                   argv[0], argv[1], argv[2]);
1710         else
1711                 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1712                                   argv[0], argv[1]);
1713         if (res < 0 || (size_t) res >= sizeof(cmd))
1714                 return -1;
1715         cmd[sizeof(cmd) - 1] = '\0';
1716         return wpa_ctrl_command(ctrl, cmd);
1717 }
1718
1719
1720 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1721                                   char *argv[])
1722 {
1723         char cmd[128];
1724         int res;
1725
1726         if (argc == 0)
1727                 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
1728
1729         res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
1730         if (res < 0 || (size_t) res >= sizeof(cmd))
1731                 return -1;
1732         cmd[sizeof(cmd) - 1] = '\0';
1733         return wpa_ctrl_command(ctrl, cmd);
1734 }
1735
1736
1737 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1738                                         char *argv[])
1739 {
1740         char cmd[128];
1741         int res;
1742
1743         if (argc != 1) {
1744                 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
1745                        "(interface name)\n");
1746                 return -1;
1747         }
1748
1749         res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
1750         if (res < 0 || (size_t) res >= sizeof(cmd))
1751                 return -1;
1752         cmd[sizeof(cmd) - 1] = '\0';
1753         return wpa_ctrl_command(ctrl, cmd);
1754 }
1755
1756
1757 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1758                                         char *argv[])
1759 {
1760         char cmd[128];
1761         int res;
1762
1763         if (argc == 0)
1764                 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
1765
1766         res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s", argv[0]);
1767         if (res < 0 || (size_t) res >= sizeof(cmd))
1768                 return -1;
1769         cmd[sizeof(cmd) - 1] = '\0';
1770         return wpa_ctrl_command(ctrl, cmd);
1771 }
1772
1773
1774 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1775                                      char *argv[])
1776 {
1777         char cmd[128];
1778         int res;
1779
1780         if (argc != 2) {
1781                 printf("Invalid P2P_PROV_DISC command: needs two arguments "
1782                        "(address and config method\n"
1783                        "(display, keypad, or pbc)\n");
1784                 return -1;
1785         }
1786
1787         res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
1788                           argv[0], argv[1]);
1789         if (res < 0 || (size_t) res >= sizeof(cmd))
1790                 return -1;
1791         cmd[sizeof(cmd) - 1] = '\0';
1792         return wpa_ctrl_command(ctrl, cmd);
1793 }
1794
1795
1796 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1797                                           char *argv[])
1798 {
1799         return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1800 }
1801
1802
1803 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1804                                          char *argv[])
1805 {
1806         char cmd[4096];
1807         int res;
1808
1809         if (argc != 2 && argc != 4) {
1810                 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1811                        "arguments (address and TLVs) or four arguments "
1812                        "(address, \"upnp\", version, search target "
1813                        "(SSDP ST:)\n");
1814                 return -1;
1815         }
1816
1817         if (argc == 4)
1818                 res = os_snprintf(cmd, sizeof(cmd),
1819                                   "P2P_SERV_DISC_REQ %s %s %s %s",
1820                                   argv[0], argv[1], argv[2], argv[3]);
1821         else
1822                 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
1823                                   argv[0], argv[1]);
1824         if (res < 0 || (size_t) res >= sizeof(cmd))
1825                 return -1;
1826         cmd[sizeof(cmd) - 1] = '\0';
1827         return wpa_ctrl_command(ctrl, cmd);
1828 }
1829
1830
1831 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1832                                                 int argc, char *argv[])
1833 {
1834         char cmd[128];
1835         int res;
1836
1837         if (argc != 1) {
1838                 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
1839                        "argument (pending request identifier)\n");
1840                 return -1;
1841         }
1842
1843         res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
1844                           argv[0]);
1845         if (res < 0 || (size_t) res >= sizeof(cmd))
1846                 return -1;
1847         cmd[sizeof(cmd) - 1] = '\0';
1848         return wpa_ctrl_command(ctrl, cmd);
1849 }
1850
1851
1852 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1853                                           char *argv[])
1854 {
1855         char cmd[4096];
1856         int res;
1857
1858         if (argc != 4) {
1859                 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1860                        "arguments (freq, address, dialog token, and TLVs)\n");
1861                 return -1;
1862         }
1863
1864         res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1865                           argv[0], argv[1], argv[2], argv[3]);
1866         if (res < 0 || (size_t) res >= sizeof(cmd))
1867                 return -1;
1868         cmd[sizeof(cmd) - 1] = '\0';
1869         return wpa_ctrl_command(ctrl, cmd);
1870 }
1871
1872
1873 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1874                                           char *argv[])
1875 {
1876         return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1877 }
1878
1879
1880 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1881                                               int argc, char *argv[])
1882 {
1883         char cmd[128];
1884         int res;
1885
1886         if (argc != 1) {
1887                 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
1888                        "argument (external processing: 0/1)\n");
1889                 return -1;
1890         }
1891
1892         res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
1893                           argv[0]);
1894         if (res < 0 || (size_t) res >= sizeof(cmd))
1895                 return -1;
1896         cmd[sizeof(cmd) - 1] = '\0';
1897         return wpa_ctrl_command(ctrl, cmd);
1898 }
1899
1900
1901 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1902                                          char *argv[])
1903 {
1904         return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1905 }
1906
1907
1908 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1909                                        char *argv[])
1910 {
1911         char cmd[4096];
1912         int res;
1913
1914         if (argc != 3 && argc != 4) {
1915                 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1916                        "arguments\n");
1917                 return -1;
1918         }
1919
1920         if (argc == 4)
1921                 res = os_snprintf(cmd, sizeof(cmd),
1922                                   "P2P_SERVICE_ADD %s %s %s %s",
1923                                   argv[0], argv[1], argv[2], argv[3]);
1924         else
1925                 res = os_snprintf(cmd, sizeof(cmd),
1926                                   "P2P_SERVICE_ADD %s %s %s",
1927                                   argv[0], argv[1], argv[2]);
1928         if (res < 0 || (size_t) res >= sizeof(cmd))
1929                 return -1;
1930         cmd[sizeof(cmd) - 1] = '\0';
1931         return wpa_ctrl_command(ctrl, cmd);
1932 }
1933
1934
1935 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
1936                                        char *argv[])
1937 {
1938         char cmd[4096];
1939         int res;
1940
1941         if (argc != 2 && argc != 3) {
1942                 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1943                        "arguments\n");
1944                 return -1;
1945         }
1946
1947         if (argc == 3)
1948                 res = os_snprintf(cmd, sizeof(cmd),
1949                                   "P2P_SERVICE_DEL %s %s %s",
1950                                   argv[0], argv[1], argv[2]);
1951         else
1952                 res = os_snprintf(cmd, sizeof(cmd),
1953                                   "P2P_SERVICE_DEL %s %s",
1954                                   argv[0], argv[1]);
1955         if (res < 0 || (size_t) res >= sizeof(cmd))
1956                 return -1;
1957         cmd[sizeof(cmd) - 1] = '\0';
1958         return wpa_ctrl_command(ctrl, cmd);
1959 }
1960
1961
1962 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
1963                                   int argc, char *argv[])
1964 {
1965         char cmd[128];
1966         int res;
1967
1968         if (argc != 1) {
1969                 printf("Invalid P2P_REJECT command: needs one argument "
1970                        "(peer address)\n");
1971                 return -1;
1972         }
1973
1974         res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
1975         if (res < 0 || (size_t) res >= sizeof(cmd))
1976                 return -1;
1977         cmd[sizeof(cmd) - 1] = '\0';
1978         return wpa_ctrl_command(ctrl, cmd);
1979 }
1980
1981
1982 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
1983                                   int argc, char *argv[])
1984 {
1985         char cmd[128];
1986         int res;
1987
1988         if (argc < 1) {
1989                 printf("Invalid P2P_INVITE command: needs at least one "
1990                        "argument\n");
1991                 return -1;
1992         }
1993
1994         if (argc > 2)
1995                 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
1996                                   argv[0], argv[1], argv[2]);
1997         else if (argc > 1)
1998                 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
1999                                   argv[0], argv[1]);
2000         else
2001                 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
2002         if (res < 0 || (size_t) res >= sizeof(cmd))
2003                 return -1;
2004         cmd[sizeof(cmd) - 1] = '\0';
2005         return wpa_ctrl_command(ctrl, cmd);
2006 }
2007
2008
2009 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2010 {
2011         char buf[64];
2012         if (argc != 1) {
2013                 printf("Invalid 'p2p_peer' command - exactly one argument, "
2014                        "P2P peer device address, is required.\n");
2015                 return -1;
2016         }
2017         os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
2018         return wpa_ctrl_command(ctrl, buf);
2019 }
2020
2021
2022 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2023                                      char *addr, size_t addr_len,
2024                                      int discovered)
2025 {
2026         char buf[4096], *pos;
2027         size_t len;
2028         int ret;
2029
2030         if (ctrl_conn == NULL)
2031                 return -1;
2032         len = sizeof(buf) - 1;
2033         ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
2034                                wpa_cli_msg_cb);
2035         if (ret == -2) {
2036                 printf("'%s' command timed out.\n", cmd);
2037                 return -2;
2038         } else if (ret < 0) {
2039                 printf("'%s' command failed.\n", cmd);
2040                 return -1;
2041         }
2042
2043         buf[len] = '\0';
2044         if (memcmp(buf, "FAIL", 4) == 0)
2045                 return -1;
2046
2047         pos = buf;
2048         while (*pos != '\0' && *pos != '\n')
2049                 pos++;
2050         *pos++ = '\0';
2051         os_strlcpy(addr, buf, addr_len);
2052         if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2053                 printf("%s\n", addr);
2054         return 0;
2055 }
2056
2057
2058 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2059 {
2060         char addr[32], cmd[64];
2061         int discovered;
2062
2063         discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2064
2065         if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2066                                       addr, sizeof(addr), discovered))
2067                 return 0;
2068         do {
2069                 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2070         } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2071                          discovered) == 0);
2072
2073         return -1;
2074 }
2075
2076
2077 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2078 {
2079         char cmd[100];
2080         int res;
2081
2082         if (argc != 2) {
2083                 printf("Invalid P2P_SET command: needs two arguments (field, "
2084                        "value)\n");
2085                 return -1;
2086         }
2087
2088         res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2089         if (res < 0 || (size_t) res >= sizeof(cmd))
2090                 return -1;
2091         cmd[sizeof(cmd) - 1] = '\0';
2092         return wpa_ctrl_command(ctrl, cmd);
2093 }
2094
2095
2096 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2097 {
2098         return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2099 }
2100
2101
2102 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2103                                   char *argv[])
2104 {
2105         return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2106 }
2107
2108
2109 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2110                                         char *argv[])
2111 {
2112         char cmd[100];
2113         int res;
2114
2115         if (argc != 0 && argc != 2 && argc != 4) {
2116                 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2117                        "(preferred duration, interval; in microsecods).\n"
2118                        "Optional second pair can be used to provide "
2119                        "acceptable values.\n");
2120                 return -1;
2121         }
2122
2123         if (argc == 4)
2124                 res = os_snprintf(cmd, sizeof(cmd),
2125                                   "P2P_PRESENCE_REQ %s %s %s %s",
2126                                   argv[0], argv[1], argv[2], argv[3]);
2127         else if (argc == 2)
2128                 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2129                                   argv[0], argv[1]);
2130         else
2131                 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2132         if (res < 0 || (size_t) res >= sizeof(cmd))
2133                 return -1;
2134         cmd[sizeof(cmd) - 1] = '\0';
2135         return wpa_ctrl_command(ctrl, cmd);
2136 }
2137
2138
2139 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2140                                       char *argv[])
2141 {
2142         char cmd[100];
2143         int res;
2144
2145         if (argc != 0 && argc != 2) {
2146                 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2147                        "(availability period, availability interval; in "
2148                        "millisecods).\n"
2149                        "Extended Listen Timing can be cancelled with this "
2150                        "command when used without parameters.\n");
2151                 return -1;
2152         }
2153
2154         if (argc == 2)
2155                 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2156                                   argv[0], argv[1]);
2157         else
2158                 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2159         if (res < 0 || (size_t) res >= sizeof(cmd))
2160                 return -1;
2161         cmd[sizeof(cmd) - 1] = '\0';
2162         return wpa_ctrl_command(ctrl, cmd);
2163 }
2164
2165 #endif /* CONFIG_P2P */
2166
2167
2168 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2169                                        char *argv[])
2170 {
2171         char cmd[256];
2172         int res;
2173
2174         if (argc != 1) {
2175                 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2176                        "(0/1 = disable/enable automatic reconnection)\n");
2177                 return -1;
2178         }
2179         res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2180         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2181                 printf("Too long STA_AUTOCONNECT command.\n");
2182                 return -1;
2183         }
2184         return wpa_ctrl_command(ctrl, cmd);
2185 }
2186
2187
2188 enum wpa_cli_cmd_flags {
2189         cli_cmd_flag_none               = 0x00,
2190         cli_cmd_flag_sensitive          = 0x01
2191 };
2192
2193 struct wpa_cli_cmd {
2194         const char *cmd;
2195         int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2196         enum wpa_cli_cmd_flags flags;
2197         const char *usage;
2198 };
2199
2200 static struct wpa_cli_cmd wpa_cli_commands[] = {
2201         { "status", wpa_cli_cmd_status,
2202           cli_cmd_flag_none,
2203           "[verbose] = get current WPA/EAPOL/EAP status" },
2204         { "ping", wpa_cli_cmd_ping,
2205           cli_cmd_flag_none,
2206           "= pings wpa_supplicant" },
2207         { "note", wpa_cli_cmd_note,
2208           cli_cmd_flag_none,
2209           "<text> = add a note to wpa_supplicant debug log" },
2210         { "mib", wpa_cli_cmd_mib,
2211           cli_cmd_flag_none,
2212           "= get MIB variables (dot1x, dot11)" },
2213         { "help", wpa_cli_cmd_help,
2214           cli_cmd_flag_none,
2215           "= show this usage help" },
2216         { "interface", wpa_cli_cmd_interface,
2217           cli_cmd_flag_none,
2218           "[ifname] = show interfaces/select interface" },
2219         { "level", wpa_cli_cmd_level,
2220           cli_cmd_flag_none,
2221           "<debug level> = change debug level" },
2222         { "license", wpa_cli_cmd_license,
2223           cli_cmd_flag_none,
2224           "= show full wpa_cli license" },
2225         { "quit", wpa_cli_cmd_quit,
2226           cli_cmd_flag_none,
2227           "= exit wpa_cli" },
2228         { "set", wpa_cli_cmd_set,
2229           cli_cmd_flag_none,
2230           "= set variables (shows list of variables when run without "
2231           "arguments)" },
2232         { "get", wpa_cli_cmd_get,
2233           cli_cmd_flag_none,
2234           "<name> = get information" },
2235         { "logon", wpa_cli_cmd_logon,
2236           cli_cmd_flag_none,
2237           "= IEEE 802.1X EAPOL state machine logon" },
2238         { "logoff", wpa_cli_cmd_logoff,
2239           cli_cmd_flag_none,
2240           "= IEEE 802.1X EAPOL state machine logoff" },
2241         { "pmksa", wpa_cli_cmd_pmksa,
2242           cli_cmd_flag_none,
2243           "= show PMKSA cache" },
2244         { "reassociate", wpa_cli_cmd_reassociate,
2245           cli_cmd_flag_none,
2246           "= force reassociation" },
2247         { "preauthenticate", wpa_cli_cmd_preauthenticate,
2248           cli_cmd_flag_none,
2249           "<BSSID> = force preauthentication" },
2250         { "identity", wpa_cli_cmd_identity,
2251           cli_cmd_flag_none,
2252           "<network id> <identity> = configure identity for an SSID" },
2253         { "password", wpa_cli_cmd_password,
2254           cli_cmd_flag_sensitive,
2255           "<network id> <password> = configure password for an SSID" },
2256         { "new_password", wpa_cli_cmd_new_password,
2257           cli_cmd_flag_sensitive,
2258           "<network id> <password> = change password for an SSID" },
2259         { "pin", wpa_cli_cmd_pin,
2260           cli_cmd_flag_sensitive,
2261           "<network id> <pin> = configure pin for an SSID" },
2262         { "otp", wpa_cli_cmd_otp,
2263           cli_cmd_flag_sensitive,
2264           "<network id> <password> = configure one-time-password for an SSID"
2265         },
2266         { "passphrase", wpa_cli_cmd_passphrase,
2267           cli_cmd_flag_sensitive,
2268           "<network id> <passphrase> = configure private key passphrase\n"
2269           "  for an SSID" },
2270         { "bssid", wpa_cli_cmd_bssid,
2271           cli_cmd_flag_none,
2272           "<network id> <BSSID> = set preferred BSSID for an SSID" },
2273         { "list_networks", wpa_cli_cmd_list_networks,
2274           cli_cmd_flag_none,
2275           "= list configured networks" },
2276         { "select_network", wpa_cli_cmd_select_network,
2277           cli_cmd_flag_none,
2278           "<network id> = select a network (disable others)" },
2279         { "enable_network", wpa_cli_cmd_enable_network,
2280           cli_cmd_flag_none,
2281           "<network id> = enable a network" },
2282         { "disable_network", wpa_cli_cmd_disable_network,
2283           cli_cmd_flag_none,
2284           "<network id> = disable a network" },
2285         { "add_network", wpa_cli_cmd_add_network,
2286           cli_cmd_flag_none,
2287           "= add a network" },
2288         { "remove_network", wpa_cli_cmd_remove_network,
2289           cli_cmd_flag_none,
2290           "<network id> = remove a network" },
2291         { "set_network", wpa_cli_cmd_set_network,
2292           cli_cmd_flag_sensitive,
2293           "<network id> <variable> <value> = set network variables (shows\n"
2294           "  list of variables when run without arguments)" },
2295         { "get_network", wpa_cli_cmd_get_network,
2296           cli_cmd_flag_none,
2297           "<network id> <variable> = get network variables" },
2298         { "save_config", wpa_cli_cmd_save_config,
2299           cli_cmd_flag_none,
2300           "= save the current configuration" },
2301         { "disconnect", wpa_cli_cmd_disconnect,
2302           cli_cmd_flag_none,
2303           "= disconnect and wait for reassociate/reconnect command before\n"
2304           "  connecting" },
2305         { "reconnect", wpa_cli_cmd_reconnect,
2306           cli_cmd_flag_none,
2307           "= like reassociate, but only takes effect if already disconnected"
2308         },
2309         { "scan", wpa_cli_cmd_scan,
2310           cli_cmd_flag_none,
2311           "= request new BSS scan" },
2312         { "scan_results", wpa_cli_cmd_scan_results,
2313           cli_cmd_flag_none,
2314           "= get latest scan results" },
2315         { "bss", wpa_cli_cmd_bss,
2316           cli_cmd_flag_none,
2317           "<<idx> | <bssid>> = get detailed scan result info" },
2318         { "get_capability", wpa_cli_cmd_get_capability,
2319           cli_cmd_flag_none,
2320           "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2321         { "reconfigure", wpa_cli_cmd_reconfigure,
2322           cli_cmd_flag_none,
2323           "= force wpa_supplicant to re-read its configuration file" },
2324         { "terminate", wpa_cli_cmd_terminate,
2325           cli_cmd_flag_none,
2326           "= terminate wpa_supplicant" },
2327         { "interface_add", wpa_cli_cmd_interface_add,
2328           cli_cmd_flag_none,
2329           "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2330           "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
2331           "  are optional" },
2332         { "interface_remove", wpa_cli_cmd_interface_remove,
2333           cli_cmd_flag_none,
2334           "<ifname> = removes the interface" },
2335         { "interface_list", wpa_cli_cmd_interface_list,
2336           cli_cmd_flag_none,
2337           "= list available interfaces" },
2338         { "ap_scan", wpa_cli_cmd_ap_scan,
2339           cli_cmd_flag_none,
2340           "<value> = set ap_scan parameter" },
2341         { "stkstart", wpa_cli_cmd_stkstart,
2342           cli_cmd_flag_none,
2343           "<addr> = request STK negotiation with <addr>" },
2344         { "ft_ds", wpa_cli_cmd_ft_ds,
2345           cli_cmd_flag_none,
2346           "<addr> = request over-the-DS FT with <addr>" },
2347         { "wps_pbc", wpa_cli_cmd_wps_pbc,
2348           cli_cmd_flag_none,
2349           "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2350         { "wps_pin", wpa_cli_cmd_wps_pin,
2351           cli_cmd_flag_sensitive,
2352           "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2353           "hardcoded)" },
2354         { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
2355           cli_cmd_flag_sensitive,
2356           "<PIN> = verify PIN checksum" },
2357         { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2358           "Cancels the pending WPS operation" },
2359 #ifdef CONFIG_WPS_OOB
2360         { "wps_oob", wpa_cli_cmd_wps_oob,
2361           cli_cmd_flag_sensitive,
2362           "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2363 #endif /* CONFIG_WPS_OOB */
2364         { "wps_reg", wpa_cli_cmd_wps_reg,
2365           cli_cmd_flag_sensitive,
2366           "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2367         { "wps_er_start", wpa_cli_cmd_wps_er_start,
2368           cli_cmd_flag_none,
2369           "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2370         { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2371           cli_cmd_flag_none,
2372           "= stop Wi-Fi Protected Setup External Registrar" },
2373         { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2374           cli_cmd_flag_sensitive,
2375           "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2376         { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2377           cli_cmd_flag_none,
2378           "<UUID> = accept an Enrollee PBC using External Registrar" },
2379         { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2380           cli_cmd_flag_sensitive,
2381           "<UUID> <PIN> = learn AP configuration" },
2382         { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
2383           cli_cmd_flag_none,
2384           "<UUID> <network id> = set AP configuration for enrolling" },
2385         { "wps_er_config", wpa_cli_cmd_wps_er_config,
2386           cli_cmd_flag_sensitive,
2387           "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2388         { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2389           cli_cmd_flag_none,
2390           "<addr> = request RSN authentication with <addr> in IBSS" },
2391 #ifdef CONFIG_AP
2392         { "sta", wpa_cli_cmd_sta,
2393           cli_cmd_flag_none,
2394           "<addr> = get information about an associated station (AP)" },
2395         { "all_sta", wpa_cli_cmd_all_sta,
2396           cli_cmd_flag_none,
2397           "= get information about all associated stations (AP)" },
2398 #endif /* CONFIG_AP */
2399         { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2400           "= notification of suspend/hibernate" },
2401         { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2402           "= notification of resume/thaw" },
2403         { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2404           "= drop SA without deauth/disassoc (test command)" },
2405         { "roam", wpa_cli_cmd_roam,
2406           cli_cmd_flag_none,
2407           "<addr> = roam to the specified BSS" },
2408 #ifdef CONFIG_P2P
2409         { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2410           "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2411         { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2412           "= stop P2P Devices search" },
2413         { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2414           "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2415         { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2416           "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2417         { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2418           "<ifname> = remote P2P group interface (terminate group if GO)" },
2419         { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2420           "= add a new P2P group (local end as GO)" },
2421         { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2422           "<addr> <method> = request provisioning discovery" },
2423         { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2424           cli_cmd_flag_none,
2425           "= get the passphrase for a group (GO only)" },
2426         { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2427           cli_cmd_flag_none,
2428           "<addr> <TLVs> = schedule service discovery request" },
2429         { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2430           cli_cmd_flag_none,
2431           "<id> = cancel pending service discovery request" },
2432         { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2433           cli_cmd_flag_none,
2434           "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2435         { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2436           cli_cmd_flag_none,
2437           "= indicate change in local services" },
2438         { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2439           cli_cmd_flag_none,
2440           "<external> = set external processing of service discovery" },
2441         { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2442           cli_cmd_flag_none,
2443           "= remove all stored service entries" },
2444         { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2445           cli_cmd_flag_none,
2446           "<bonjour|upnp> <query|version> <response|service> = add a local "
2447           "service" },
2448         { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2449           cli_cmd_flag_none,
2450           "<bonjour|upnp> <query|version> [|service] = remove a local "
2451           "service" },
2452         { "p2p_reject", wpa_cli_cmd_p2p_reject,
2453           cli_cmd_flag_none,
2454           "<addr> = reject connection attempts from a specific peer" },
2455         { "p2p_invite", wpa_cli_cmd_p2p_invite,
2456           cli_cmd_flag_none,
2457           "<cmd> [peer=addr] = invite peer" },
2458         { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2459           "[discovered] = list known (optionally, only fully discovered) P2P "
2460           "peers" },
2461         { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2462           "<address> = show information about known P2P peer" },
2463         { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2464           "<field> <value> = set a P2P parameter" },
2465         { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2466           "= flush P2P state" },
2467         { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
2468           "= cancel P2P group formation" },
2469         { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2470           "[<duration> <interval>] [<duration> <interval>] = request GO "
2471           "presence" },
2472         { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2473           "[<period> <interval>] = set extended listen timing" },
2474 #endif /* CONFIG_P2P */
2475         { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
2476           "<0/1> = disable/enable automatic reconnection" },
2477         { NULL, NULL, cli_cmd_flag_none, NULL }
2478 };
2479
2480
2481 /*
2482  * Prints command usage, lines are padded with the specified string.
2483  */
2484 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2485 {
2486         char c;
2487         size_t n;
2488
2489         printf("%s%s ", pad, cmd->cmd);
2490         for (n = 0; (c = cmd->usage[n]); n++) {
2491                 printf("%c", c);
2492                 if (c == '\n')
2493                         printf("%s", pad);
2494         }
2495         printf("\n");
2496 }
2497
2498
2499 static void print_help(void)
2500 {
2501         int n;
2502         printf("commands:\n");
2503         for (n = 0; wpa_cli_commands[n].cmd; n++)
2504                 print_cmd_help(&wpa_cli_commands[n], "  ");
2505 }
2506
2507
2508 #ifdef CONFIG_READLINE
2509 static int cmd_has_sensitive_data(const char *cmd)
2510 {
2511         const char *c, *delim;
2512         int n;
2513         size_t len;
2514
2515         delim = os_strchr(cmd, ' ');
2516         if (delim)
2517                 len = delim - cmd;
2518         else
2519                 len = os_strlen(cmd);
2520
2521         for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2522                 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2523                         return (wpa_cli_commands[n].flags &
2524                                 cli_cmd_flag_sensitive);
2525         }
2526         return 0;
2527 }
2528 #endif /* CONFIG_READLINE */
2529
2530
2531 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
2532 {
2533         struct wpa_cli_cmd *cmd, *match = NULL;
2534         int count;
2535         int ret = 0;
2536
2537         count = 0;
2538         cmd = wpa_cli_commands;
2539         while (cmd->cmd) {
2540                 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
2541                 {
2542                         match = cmd;
2543                         if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
2544                                 /* we have an exact match */
2545                                 count = 1;
2546                                 break;
2547                         }
2548                         count++;
2549                 }
2550                 cmd++;
2551         }
2552
2553         if (count > 1) {
2554                 printf("Ambiguous command '%s'; possible commands:", argv[0]);
2555                 cmd = wpa_cli_commands;
2556                 while (cmd->cmd) {
2557                         if (os_strncasecmp(cmd->cmd, argv[0],
2558                                            os_strlen(argv[0])) == 0) {
2559                                 printf(" %s", cmd->cmd);
2560                         }
2561                         cmd++;
2562                 }
2563                 printf("\n");
2564                 ret = 1;
2565         } else if (count == 0) {
2566                 printf("Unknown command '%s'\n", argv[0]);
2567                 ret = 1;
2568         } else {
2569                 ret = match->handler(ctrl, argc - 1, &argv[1]);
2570         }
2571
2572         return ret;
2573 }
2574
2575
2576 static int str_match(const char *a, const char *b)
2577 {
2578         return os_strncmp(a, b, os_strlen(b)) == 0;
2579 }
2580
2581
2582 static int wpa_cli_exec(const char *program, const char *arg1,
2583                         const char *arg2)
2584 {
2585         char *cmd;
2586         size_t len;
2587         int res;
2588         int ret = 0;
2589
2590         len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
2591         cmd = os_malloc(len);
2592         if (cmd == NULL)
2593                 return -1;
2594         res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
2595         if (res < 0 || (size_t) res >= len) {
2596                 os_free(cmd);
2597                 return -1;
2598         }
2599         cmd[len - 1] = '\0';
2600 #ifndef _WIN32_WCE
2601         if (system(cmd) < 0)
2602                 ret = -1;
2603 #endif /* _WIN32_WCE */
2604         os_free(cmd);
2605
2606         return ret;
2607 }
2608
2609
2610 static void wpa_cli_action_process(const char *msg)
2611 {
2612         const char *pos;
2613         char *copy = NULL, *id, *pos2;
2614
2615         pos = msg;
2616         if (*pos == '<') {
2617                 /* skip priority */
2618                 pos = os_strchr(pos, '>');
2619                 if (pos)
2620                         pos++;
2621                 else
2622                         pos = msg;
2623         }
2624
2625         if (str_match(pos, WPA_EVENT_CONNECTED)) {
2626                 int new_id = -1;
2627                 os_unsetenv("WPA_ID");
2628                 os_unsetenv("WPA_ID_STR");
2629                 os_unsetenv("WPA_CTRL_DIR");
2630
2631                 pos = os_strstr(pos, "[id=");
2632                 if (pos)
2633                         copy = os_strdup(pos + 4);
2634
2635                 if (copy) {
2636                         pos2 = id = copy;
2637                         while (*pos2 && *pos2 != ' ')
2638                                 pos2++;
2639                         *pos2++ = '\0';
2640                         new_id = atoi(id);
2641                         os_setenv("WPA_ID", id, 1);
2642                         while (*pos2 && *pos2 != '=')
2643                                 pos2++;
2644                         if (*pos2 == '=')
2645                                 pos2++;
2646                         id = pos2;
2647                         while (*pos2 && *pos2 != ']')
2648                                 pos2++;
2649                         *pos2 = '\0';
2650                         os_setenv("WPA_ID_STR", id, 1);
2651                         os_free(copy);
2652                 }
2653
2654                 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
2655
2656                 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
2657                         wpa_cli_connected = 1;
2658                         wpa_cli_last_id = new_id;
2659                         wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
2660                 }
2661         } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
2662                 if (wpa_cli_connected) {
2663                         wpa_cli_connected = 0;
2664                         wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
2665                 }
2666         } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
2667                 wpa_cli_exec(action_file, ctrl_ifname, pos);
2668         } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
2669                 wpa_cli_exec(action_file, ctrl_ifname, pos);
2670         } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
2671                 wpa_cli_exec(action_file, ctrl_ifname, pos);
2672         } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
2673                 wpa_cli_exec(action_file, ctrl_ifname, pos);
2674         } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
2675                 wpa_cli_exec(action_file, ctrl_ifname, pos);
2676         } else if (str_match(pos, WPS_EVENT_FAIL)) {
2677                 wpa_cli_exec(action_file, ctrl_ifname, pos);
2678         } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
2679                 printf("wpa_supplicant is terminating - stop monitoring\n");
2680                 wpa_cli_quit = 1;
2681         }
2682 }
2683
2684
2685 #ifndef CONFIG_ANSI_C_EXTRA
2686 static void wpa_cli_action_cb(char *msg, size_t len)
2687 {
2688         wpa_cli_action_process(msg);
2689 }
2690 #endif /* CONFIG_ANSI_C_EXTRA */
2691
2692
2693 static void wpa_cli_reconnect(void)
2694 {
2695         wpa_cli_close_connection();
2696         wpa_cli_open_connection(ctrl_ifname, 1);
2697 }
2698
2699
2700 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
2701                                  int action_monitor)
2702 {
2703         int first = 1;
2704         if (ctrl_conn == NULL) {
2705                 wpa_cli_reconnect();
2706                 return;
2707         }
2708         while (wpa_ctrl_pending(ctrl) > 0) {
2709                 char buf[256];
2710                 size_t len = sizeof(buf) - 1;
2711                 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
2712                         buf[len] = '\0';
2713                         if (action_monitor)
2714                                 wpa_cli_action_process(buf);
2715                         else {
2716                                 if (wpa_cli_show_event(buf)) {
2717                                         if (in_read && first)
2718                                                 printf("\r");
2719                                         first = 0;
2720                                         printf("%s\n", buf);
2721                                         readline_redraw();
2722                                 }
2723                         }
2724                 } else {
2725                         printf("Could not read pending message.\n");
2726                         break;
2727                 }
2728         }
2729
2730         if (wpa_ctrl_pending(ctrl) < 0) {
2731                 printf("Connection to wpa_supplicant lost - trying to "
2732                        "reconnect\n");
2733                 wpa_cli_reconnect();
2734         }
2735 }
2736
2737 #define max_args 10
2738
2739 static int tokenize_cmd(char *cmd, char *argv[])
2740 {
2741         char *pos;
2742         int argc = 0;
2743
2744         pos = cmd;
2745         for (;;) {
2746                 while (*pos == ' ')
2747                         pos++;
2748                 if (*pos == '\0')
2749                         break;
2750                 argv[argc] = pos;
2751                 argc++;
2752                 if (argc == max_args)
2753                         break;
2754                 if (*pos == '"') {
2755                         char *pos2 = os_strrchr(pos, '"');
2756                         if (pos2)
2757                                 pos = pos2 + 1;
2758                 }
2759                 while (*pos != '\0' && *pos != ' ')
2760                         pos++;
2761                 if (*pos == ' ')
2762                         *pos++ = '\0';
2763         }
2764
2765         return argc;
2766 }
2767
2768
2769 static void trunc_nl(char *str)
2770 {
2771         char *pos = str;
2772         while (*pos != '\0') {
2773                 if (*pos == '\n') {
2774                         *pos = '\0';
2775                         break;
2776                 }
2777                 pos++;
2778         }
2779 }
2780
2781
2782 #ifdef CONFIG_READLINE
2783
2784 static char * wpa_cli_cmd_gen(const char *text, int state)
2785 {
2786         static int i, len;
2787         const char *cmd;
2788
2789         if (state == 0) {
2790                 i = 0;
2791                 len = os_strlen(text);
2792         }
2793
2794         while ((cmd = wpa_cli_commands[i].cmd)) {
2795                 i++;
2796                 if (os_strncasecmp(cmd, text, len) == 0)
2797                         return strdup(cmd);
2798         }
2799
2800         return NULL;
2801 }
2802
2803
2804 static char * wpa_cli_dummy_gen(const char *text, int state)
2805 {
2806         int i;
2807
2808         for (i = 0; wpa_cli_commands[i].cmd; i++) {
2809                 const char *cmd = wpa_cli_commands[i].cmd;
2810                 size_t len = os_strlen(cmd);
2811                 if (os_strncasecmp(rl_line_buffer, cmd, len) == 0 &&
2812                     rl_line_buffer[len] == ' ') {
2813                         printf("\n%s\n", wpa_cli_commands[i].usage);
2814                         readline_redraw();
2815                         break;
2816                 }
2817         }
2818
2819         rl_attempted_completion_over = 1;
2820         return NULL;
2821 }
2822
2823
2824 static char * wpa_cli_status_gen(const char *text, int state)
2825 {
2826         static int i, len;
2827         char *options[] = {
2828                 "verbose", NULL
2829         };
2830         char *t;
2831
2832         if (state == 0) {
2833                 i = 0;
2834                 len = os_strlen(text);
2835         }
2836
2837         while ((t = options[i])) {
2838                 i++;
2839                 if (os_strncasecmp(t, text, len) == 0)
2840                         return strdup(t);
2841         }
2842
2843         rl_attempted_completion_over = 1;
2844         return NULL;
2845 }
2846
2847
2848 static char ** wpa_cli_completion(const char *text, int start, int end)
2849 {
2850         char * (*func)(const char *text, int state);
2851
2852         if (start == 0)
2853                 func = wpa_cli_cmd_gen;
2854         else if (os_strncasecmp(rl_line_buffer, "status ", 7) == 0)
2855                 func = wpa_cli_status_gen;
2856         else
2857                 func = wpa_cli_dummy_gen;
2858         return rl_completion_matches(text, func);
2859 }
2860
2861
2862 static void wpa_cli_interactive(void)
2863 {
2864         char cmdbuf[256], *cmd, *argv[max_args];
2865         int argc;
2866         char *home, *hfile = NULL;
2867
2868         printf("\nInteractive mode\n\n");
2869
2870         rl_attempted_completion_function = wpa_cli_completion;
2871         home = getenv("HOME");
2872         if (home) {
2873                 const char *fname = ".wpa_cli_history";
2874                 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
2875                 hfile = os_malloc(hfile_len);
2876                 if (hfile) {
2877                         int res;
2878                         res = os_snprintf(hfile, hfile_len, "%s/%s", home,
2879                                           fname);
2880                         if (res >= 0 && res < hfile_len) {
2881                                 hfile[hfile_len - 1] = '\0';
2882                                 read_history(hfile);
2883                                 stifle_history(100);
2884                         }
2885                 }
2886         }
2887
2888         do {
2889                 wpa_cli_recv_pending(mon_conn, 0, 0);
2890 #ifndef CONFIG_NATIVE_WINDOWS
2891                 alarm(ping_interval);
2892 #endif /* CONFIG_NATIVE_WINDOWS */
2893 #ifdef CONFIG_WPA_CLI_FORK
2894                 if (mon_pid)
2895                         kill(mon_pid, SIGUSR1);
2896 #endif /* CONFIG_WPA_CLI_FORK */
2897                 cmd = readline("> ");
2898                 if (cmd && *cmd) {
2899                         HIST_ENTRY *h;
2900                         while (next_history())
2901                                 ;
2902                         h = previous_history();
2903                         if (h == NULL || os_strcmp(cmd, h->line) != 0)
2904                                 add_history(cmd);
2905                         next_history();
2906                 }
2907 #ifndef CONFIG_NATIVE_WINDOWS
2908                 alarm(0);
2909 #endif /* CONFIG_NATIVE_WINDOWS */
2910                 if (cmd == NULL)
2911                         break;
2912                 wpa_cli_recv_pending(mon_conn, 0, 0);
2913                 trunc_nl(cmd);
2914                 argc = tokenize_cmd(cmd, argv);
2915                 if (argc)
2916                         wpa_request(ctrl_conn, argc, argv);
2917
2918                 if (cmd != cmdbuf)
2919                         free(cmd);
2920 #ifdef CONFIG_WPA_CLI_FORK
2921                 if (mon_pid)
2922                         kill(mon_pid, SIGUSR2);
2923 #endif /* CONFIG_WPA_CLI_FORK */
2924         } while (!wpa_cli_quit);
2925
2926         if (hfile) {
2927                 /* Save command history, excluding lines that may contain
2928                  * passwords. */
2929                 HIST_ENTRY *h;
2930                 history_set_pos(0);
2931                 while ((h = current_history())) {
2932                         char *p = h->line;
2933                         while (*p == ' ' || *p == '\t')
2934                                 p++;
2935                         if (cmd_has_sensitive_data(p)) {
2936                                 h = remove_history(where_history());
2937                                 if (h) {
2938                                         os_free(h->line);
2939                                         os_free(h->data);
2940                                         os_free(h);
2941                                 } else
2942                                         next_history();
2943                         } else
2944                                 next_history();
2945                 }
2946                 write_history(hfile);
2947                 os_free(hfile);
2948         }
2949 }
2950
2951 #else /* CONFIG_READLINE */
2952
2953 static void wpa_cli_interactive(void)
2954 {
2955         char cmdbuf[256], *cmd, *argv[max_args];
2956         int argc;
2957
2958         printf("\nInteractive mode\n\n");
2959
2960         do {
2961                 wpa_cli_recv_pending(mon_conn, 0, 0);
2962 #ifndef CONFIG_NATIVE_WINDOWS
2963                 alarm(ping_interval);
2964 #endif /* CONFIG_NATIVE_WINDOWS */
2965 #ifdef CONFIG_WPA_CLI_FORK
2966                 if (mon_pid)
2967                         kill(mon_pid, SIGUSR1);
2968 #endif /* CONFIG_WPA_CLI_FORK */
2969                 printf("> ");
2970                 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
2971 #ifndef CONFIG_NATIVE_WINDOWS
2972                 alarm(0);
2973 #endif /* CONFIG_NATIVE_WINDOWS */
2974                 if (cmd == NULL)
2975                         break;
2976                 wpa_cli_recv_pending(mon_conn, 0, 0);
2977                 trunc_nl(cmd);
2978                 argc = tokenize_cmd(cmd, argv);
2979                 if (argc)
2980                         wpa_request(ctrl_conn, argc, argv);
2981
2982                 if (cmd != cmdbuf)
2983                         free(cmd);
2984 #ifdef CONFIG_WPA_CLI_FORK
2985                 if (mon_pid)
2986                         kill(mon_pid, SIGUSR2);
2987 #endif /* CONFIG_WPA_CLI_FORK */
2988         } while (!wpa_cli_quit);
2989 }
2990
2991 #endif /* CONFIG_READLINE */
2992
2993
2994 static void wpa_cli_action(struct wpa_ctrl *ctrl)
2995 {
2996 #ifdef CONFIG_ANSI_C_EXTRA
2997         /* TODO: ANSI C version(?) */
2998         printf("Action processing not supported in ANSI C build.\n");
2999 #else /* CONFIG_ANSI_C_EXTRA */
3000         fd_set rfds;
3001         int fd, res;
3002         struct timeval tv;
3003         char buf[256]; /* note: large enough to fit in unsolicited messages */
3004         size_t len;
3005
3006         fd = wpa_ctrl_get_fd(ctrl);
3007
3008         while (!wpa_cli_quit) {
3009                 FD_ZERO(&rfds);
3010                 FD_SET(fd, &rfds);
3011                 tv.tv_sec = ping_interval;
3012                 tv.tv_usec = 0;
3013                 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3014                 if (res < 0 && errno != EINTR) {
3015                         perror("select");
3016                         break;
3017                 }
3018
3019                 if (FD_ISSET(fd, &rfds))
3020                         wpa_cli_recv_pending(ctrl, 0, 1);
3021                 else {
3022                         /* verify that connection is still working */
3023                         len = sizeof(buf) - 1;
3024                         if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3025                                              wpa_cli_action_cb) < 0 ||
3026                             len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3027                                 printf("wpa_supplicant did not reply to PING "
3028                                        "command - exiting\n");
3029                                 break;
3030                         }
3031                 }
3032         }
3033 #endif /* CONFIG_ANSI_C_EXTRA */
3034 }
3035
3036
3037 static void wpa_cli_cleanup(void)
3038 {
3039         wpa_cli_close_connection();
3040         if (pid_file)
3041                 os_daemonize_terminate(pid_file);
3042
3043         os_program_deinit();
3044 }
3045
3046 static void wpa_cli_terminate(int sig)
3047 {
3048         wpa_cli_cleanup();
3049         exit(0);
3050 }
3051
3052
3053 #ifdef CONFIG_WPA_CLI_FORK
3054 static void wpa_cli_usr1(int sig)
3055 {
3056         readline_redraw();
3057 }
3058 #endif /* CONFIG_WPA_CLI_FORK */
3059
3060
3061 #ifndef CONFIG_NATIVE_WINDOWS
3062 static void wpa_cli_alarm(int sig)
3063 {
3064         if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3065                 printf("Connection to wpa_supplicant lost - trying to "
3066                        "reconnect\n");
3067                 wpa_cli_close_connection();
3068         }
3069         if (!ctrl_conn)
3070                 wpa_cli_reconnect();
3071         if (mon_conn)
3072                 wpa_cli_recv_pending(mon_conn, 1, 0);
3073         alarm(ping_interval);
3074 }
3075 #endif /* CONFIG_NATIVE_WINDOWS */
3076
3077
3078 static char * wpa_cli_get_default_ifname(void)
3079 {
3080         char *ifname = NULL;
3081
3082 #ifdef CONFIG_CTRL_IFACE_UNIX
3083         struct dirent *dent;
3084         DIR *dir = opendir(ctrl_iface_dir);
3085         if (!dir)
3086                 return NULL;
3087         while ((dent = readdir(dir))) {
3088 #ifdef _DIRENT_HAVE_D_TYPE
3089                 /*
3090                  * Skip the file if it is not a socket. Also accept
3091                  * DT_UNKNOWN (0) in case the C library or underlying
3092                  * file system does not support d_type.
3093                  */
3094                 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3095                         continue;
3096 #endif /* _DIRENT_HAVE_D_TYPE */
3097                 if (os_strcmp(dent->d_name, ".") == 0 ||
3098                     os_strcmp(dent->d_name, "..") == 0)
3099                         continue;
3100                 printf("Selected interface '%s'\n", dent->d_name);
3101                 ifname = os_strdup(dent->d_name);
3102                 break;
3103         }
3104         closedir(dir);
3105 #endif /* CONFIG_CTRL_IFACE_UNIX */
3106
3107 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3108         char buf[2048], *pos;
3109         size_t len;
3110         struct wpa_ctrl *ctrl;
3111         int ret;
3112
3113         ctrl = wpa_ctrl_open(NULL);
3114         if (ctrl == NULL)
3115                 return NULL;
3116
3117         len = sizeof(buf) - 1;
3118         ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3119         if (ret >= 0) {
3120                 buf[len] = '\0';
3121                 pos = os_strchr(buf, '\n');
3122                 if (pos)
3123                         *pos = '\0';
3124                 ifname = os_strdup(buf);
3125         }
3126         wpa_ctrl_close(ctrl);
3127 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3128
3129         return ifname;
3130 }
3131
3132
3133 int main(int argc, char *argv[])
3134 {
3135         int warning_displayed = 0;
3136         int c;
3137         int daemonize = 0;
3138         int ret = 0;
3139         const char *global = NULL;
3140
3141         if (os_program_init())
3142                 return -1;
3143
3144         for (;;) {
3145                 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3146                 if (c < 0)
3147                         break;
3148                 switch (c) {
3149                 case 'a':
3150                         action_file = optarg;
3151                         break;
3152                 case 'B':
3153                         daemonize = 1;
3154                         break;
3155                 case 'g':
3156                         global = optarg;
3157                         break;
3158                 case 'G':
3159                         ping_interval = atoi(optarg);
3160                         break;
3161                 case 'h':
3162                         usage();
3163                         return 0;
3164                 case 'v':
3165                         printf("%s\n", wpa_cli_version);
3166                         return 0;
3167                 case 'i':
3168                         os_free(ctrl_ifname);
3169                         ctrl_ifname = os_strdup(optarg);
3170                         break;
3171                 case 'p':
3172                         ctrl_iface_dir = optarg;
3173                         break;
3174                 case 'P':
3175                         pid_file = optarg;
3176                         break;
3177                 default:
3178                         usage();
3179                         return -1;
3180                 }
3181         }
3182
3183         interactive = (argc == optind) && (action_file == NULL);
3184
3185         if (interactive)
3186                 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3187
3188         if (global) {
3189 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3190                 ctrl_conn = wpa_ctrl_open(NULL);
3191 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3192                 ctrl_conn = wpa_ctrl_open(global);
3193 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3194                 if (ctrl_conn == NULL) {
3195                         perror("Failed to connect to wpa_supplicant - "
3196                                "wpa_ctrl_open");
3197                         return -1;
3198                 }
3199         }
3200
3201 #ifndef _WIN32_WCE
3202         signal(SIGINT, wpa_cli_terminate);
3203         signal(SIGTERM, wpa_cli_terminate);
3204 #endif /* _WIN32_WCE */
3205 #ifndef CONFIG_NATIVE_WINDOWS
3206         signal(SIGALRM, wpa_cli_alarm);
3207 #endif /* CONFIG_NATIVE_WINDOWS */
3208 #ifdef CONFIG_WPA_CLI_FORK
3209         signal(SIGUSR1, wpa_cli_usr1);
3210 #endif /* CONFIG_WPA_CLI_FORK */
3211
3212         if (ctrl_ifname == NULL)
3213                 ctrl_ifname = wpa_cli_get_default_ifname();
3214
3215         if (interactive) {
3216                 for (; !global;) {
3217                         if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3218                                 if (warning_displayed)
3219                                         printf("Connection established.\n");
3220                                 break;
3221                         }
3222
3223                         if (!warning_displayed) {
3224                                 printf("Could not connect to wpa_supplicant - "
3225                                        "re-trying\n");
3226                                 warning_displayed = 1;
3227                         }
3228                         os_sleep(1, 0);
3229                         continue;
3230                 }
3231         } else {
3232                 if (!global &&
3233                     wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3234                         perror("Failed to connect to wpa_supplicant - "
3235                                "wpa_ctrl_open");
3236                         return -1;
3237                 }
3238
3239                 if (action_file) {
3240                         if (wpa_ctrl_attach(ctrl_conn) == 0) {
3241                                 wpa_cli_attached = 1;
3242                         } else {
3243                                 printf("Warning: Failed to attach to "
3244                                        "wpa_supplicant.\n");
3245                                 return -1;
3246                         }
3247                 }
3248         }
3249
3250         if (daemonize && os_daemonize(pid_file))
3251                 return -1;
3252
3253         if (interactive)
3254                 wpa_cli_interactive();
3255         else if (action_file)
3256                 wpa_cli_action(ctrl_conn);
3257         else
3258                 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3259
3260         os_free(ctrl_ifname);
3261         wpa_cli_cleanup();
3262
3263         return ret;
3264 }
3265
3266 #else /* CONFIG_CTRL_IFACE */
3267 int main(int argc, char *argv[])
3268 {
3269         printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3270         return -1;
3271 }
3272 #endif /* CONFIG_CTRL_IFACE */