OSDN Git Service

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