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