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