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