OSDN Git Service

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