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