Remove the GPL notification from files contributed by Jouni Malinen
[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         res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1468         if (res < 0 || (size_t) res >= sizeof(cmd))
1469                 return -1;
1470         cmd[sizeof(cmd) - 1] = '\0';
1471
1472         return wpa_ctrl_command(ctrl, cmd);
1473 }
1474
1475
1476 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1477                                        char *argv[])
1478 {
1479         char cmd[32];
1480         int res;
1481
1482         if (argc < 1) {
1483                 printf("Invalid DISABLE_NETWORK command: needs one argument "
1484                        "(network id)\n");
1485                 return -1;
1486         }
1487
1488         res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1489         if (res < 0 || (size_t) res >= sizeof(cmd))
1490                 return -1;
1491         cmd[sizeof(cmd) - 1] = '\0';
1492
1493         return wpa_ctrl_command(ctrl, cmd);
1494 }
1495
1496
1497 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1498                                    char *argv[])
1499 {
1500         return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1501 }
1502
1503
1504 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1505                                       char *argv[])
1506 {
1507         char cmd[32];
1508         int res;
1509
1510         if (argc < 1) {
1511                 printf("Invalid REMOVE_NETWORK command: needs one argument "
1512                        "(network id)\n");
1513                 return -1;
1514         }
1515
1516         res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1517         if (res < 0 || (size_t) res >= sizeof(cmd))
1518                 return -1;
1519         cmd[sizeof(cmd) - 1] = '\0';
1520
1521         return wpa_ctrl_command(ctrl, cmd);
1522 }
1523
1524
1525 static void wpa_cli_show_network_variables(void)
1526 {
1527         printf("set_network variables:\n"
1528                "  ssid (network name, SSID)\n"
1529                "  psk (WPA passphrase or pre-shared key)\n"
1530                "  key_mgmt (key management protocol)\n"
1531                "  identity (EAP identity)\n"
1532                "  password (EAP password)\n"
1533                "  ...\n"
1534                "\n"
1535                "Note: Values are entered in the same format as the "
1536                "configuration file is using,\n"
1537                "i.e., strings values need to be inside double quotation "
1538                "marks.\n"
1539                "For example: set_network 1 ssid \"network name\"\n"
1540                "\n"
1541                "Please see wpa_supplicant.conf documentation for full list "
1542                "of\navailable variables.\n");
1543 }
1544
1545
1546 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1547                                    char *argv[])
1548 {
1549         char cmd[256];
1550         int res;
1551
1552         if (argc == 0) {
1553                 wpa_cli_show_network_variables();
1554                 return 0;
1555         }
1556
1557         if (argc != 3) {
1558                 printf("Invalid SET_NETWORK command: needs three arguments\n"
1559                        "(network id, variable name, and value)\n");
1560                 return -1;
1561         }
1562
1563         res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1564                           argv[0], argv[1], argv[2]);
1565         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1566                 printf("Too long SET_NETWORK command.\n");
1567                 return -1;
1568         }
1569         return wpa_ctrl_command(ctrl, cmd);
1570 }
1571
1572
1573 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1574                                    char *argv[])
1575 {
1576         char cmd[256];
1577         int res;
1578
1579         if (argc == 0) {
1580                 wpa_cli_show_network_variables();
1581                 return 0;
1582         }
1583
1584         if (argc != 2) {
1585                 printf("Invalid GET_NETWORK command: needs two arguments\n"
1586                        "(network id and variable name)\n");
1587                 return -1;
1588         }
1589
1590         res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1591                           argv[0], argv[1]);
1592         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1593                 printf("Too long GET_NETWORK command.\n");
1594                 return -1;
1595         }
1596         return wpa_ctrl_command(ctrl, cmd);
1597 }
1598
1599
1600 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1601                                   char *argv[])
1602 {
1603         return wpa_ctrl_command(ctrl, "DISCONNECT");
1604 }
1605
1606
1607 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1608                                   char *argv[])
1609 {
1610         return wpa_ctrl_command(ctrl, "RECONNECT");
1611 }
1612
1613
1614 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1615                                    char *argv[])
1616 {
1617         return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1618 }
1619
1620
1621 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1622 {
1623         return wpa_ctrl_command(ctrl, "SCAN");
1624 }
1625
1626
1627 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1628                                     char *argv[])
1629 {
1630         return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1631 }
1632
1633
1634 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1635 {
1636         char cmd[64];
1637         int res;
1638
1639         if (argc != 1) {
1640                 printf("Invalid BSS command: need one argument (index or "
1641                        "BSSID)\n");
1642                 return -1;
1643         }
1644
1645         res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1646         if (res < 0 || (size_t) res >= sizeof(cmd))
1647                 return -1;
1648         cmd[sizeof(cmd) - 1] = '\0';
1649
1650         return wpa_ctrl_command(ctrl, cmd);
1651 }
1652
1653
1654 static char ** wpa_cli_complete_bss(const char *str, int pos)
1655 {
1656         int arg = get_cmd_arg_num(str, pos);
1657         char **res = NULL;
1658
1659         switch (arg) {
1660         case 1:
1661                 res = cli_txt_list_array(&bsses);
1662                 break;
1663         }
1664
1665         return res;
1666 }
1667
1668
1669 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1670                                       char *argv[])
1671 {
1672         char cmd[64];
1673         int res;
1674
1675         if (argc < 1 || argc > 2) {
1676                 printf("Invalid GET_CAPABILITY command: need either one or "
1677                        "two arguments\n");
1678                 return -1;
1679         }
1680
1681         if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1682                 printf("Invalid GET_CAPABILITY command: second argument, "
1683                        "if any, must be 'strict'\n");
1684                 return -1;
1685         }
1686
1687         res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1688                           (argc == 2) ? " strict" : "");
1689         if (res < 0 || (size_t) res >= sizeof(cmd))
1690                 return -1;
1691         cmd[sizeof(cmd) - 1] = '\0';
1692
1693         return wpa_ctrl_command(ctrl, cmd);
1694 }
1695
1696
1697 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1698 {
1699         printf("Available interfaces:\n");
1700         return wpa_ctrl_command(ctrl, "INTERFACES");
1701 }
1702
1703
1704 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1705 {
1706         if (argc < 1) {
1707                 wpa_cli_list_interfaces(ctrl);
1708                 return 0;
1709         }
1710
1711         wpa_cli_close_connection();
1712         os_free(ctrl_ifname);
1713         ctrl_ifname = os_strdup(argv[0]);
1714
1715         if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1716                 printf("Connected to interface '%s.\n", ctrl_ifname);
1717         } else {
1718                 printf("Could not connect to interface '%s' - re-trying\n",
1719                        ctrl_ifname);
1720         }
1721         return 0;
1722 }
1723
1724
1725 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1726                                    char *argv[])
1727 {
1728         return wpa_ctrl_command(ctrl, "RECONFIGURE");
1729 }
1730
1731
1732 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1733                                  char *argv[])
1734 {
1735         return wpa_ctrl_command(ctrl, "TERMINATE");
1736 }
1737
1738
1739 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1740                                      char *argv[])
1741 {
1742         char cmd[256];
1743         int res;
1744
1745         if (argc < 1) {
1746                 printf("Invalid INTERFACE_ADD command: needs at least one "
1747                        "argument (interface name)\n"
1748                        "All arguments: ifname confname driver ctrl_interface "
1749                        "driver_param bridge_name\n");
1750                 return -1;
1751         }
1752
1753         /*
1754          * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1755          * <driver_param>TAB<bridge_name>
1756          */
1757         res = os_snprintf(cmd, sizeof(cmd),
1758                           "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1759                           argv[0],
1760                           argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1761                           argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1762                           argc > 5 ? argv[5] : "");
1763         if (res < 0 || (size_t) res >= sizeof(cmd))
1764                 return -1;
1765         cmd[sizeof(cmd) - 1] = '\0';
1766         return wpa_ctrl_command(ctrl, cmd);
1767 }
1768
1769
1770 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1771                                         char *argv[])
1772 {
1773         char cmd[128];
1774         int res;
1775
1776         if (argc != 1) {
1777                 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1778                        "(interface name)\n");
1779                 return -1;
1780         }
1781
1782         res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1783         if (res < 0 || (size_t) res >= sizeof(cmd))
1784                 return -1;
1785         cmd[sizeof(cmd) - 1] = '\0';
1786         return wpa_ctrl_command(ctrl, cmd);
1787 }
1788
1789
1790 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1791                                       char *argv[])
1792 {
1793         return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1794 }
1795
1796
1797 #ifdef CONFIG_AP
1798 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1799 {
1800         char buf[64];
1801         if (argc != 1) {
1802                 printf("Invalid 'sta' command - exactly one argument, STA "
1803                        "address, is required.\n");
1804                 return -1;
1805         }
1806         os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1807         return wpa_ctrl_command(ctrl, buf);
1808 }
1809
1810
1811 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1812                                 char *addr, size_t addr_len)
1813 {
1814         char buf[4096], *pos;
1815         size_t len;
1816         int ret;
1817
1818         if (ctrl_conn == NULL) {
1819                 printf("Not connected to hostapd - command dropped.\n");
1820                 return -1;
1821         }
1822         len = sizeof(buf) - 1;
1823         ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1824                                wpa_cli_msg_cb);
1825         if (ret == -2) {
1826                 printf("'%s' command timed out.\n", cmd);
1827                 return -2;
1828         } else if (ret < 0) {
1829                 printf("'%s' command failed.\n", cmd);
1830                 return -1;
1831         }
1832
1833         buf[len] = '\0';
1834         if (memcmp(buf, "FAIL", 4) == 0)
1835                 return -1;
1836         printf("%s", buf);
1837
1838         pos = buf;
1839         while (*pos != '\0' && *pos != '\n')
1840                 pos++;
1841         *pos = '\0';
1842         os_strlcpy(addr, buf, addr_len);
1843         return 0;
1844 }
1845
1846
1847 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1848 {
1849         char addr[32], cmd[64];
1850
1851         if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1852                 return 0;
1853         do {
1854                 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1855         } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1856
1857         return -1;
1858 }
1859 #endif /* CONFIG_AP */
1860
1861
1862 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1863 {
1864         return wpa_ctrl_command(ctrl, "SUSPEND");
1865 }
1866
1867
1868 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1869 {
1870         return wpa_ctrl_command(ctrl, "RESUME");
1871 }
1872
1873
1874 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1875 {
1876         return wpa_ctrl_command(ctrl, "DROP_SA");
1877 }
1878
1879
1880 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1881 {
1882         char cmd[128];
1883         int res;
1884
1885         if (argc != 1) {
1886                 printf("Invalid ROAM command: needs one argument "
1887                        "(target AP's BSSID)\n");
1888                 return -1;
1889         }
1890
1891         res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1892         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1893                 printf("Too long ROAM command.\n");
1894                 return -1;
1895         }
1896         return wpa_ctrl_command(ctrl, cmd);
1897 }
1898
1899
1900 #ifdef CONFIG_P2P
1901
1902 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1903 {
1904         char cmd[128];
1905         int res;
1906
1907         if (argc == 0)
1908                 return wpa_ctrl_command(ctrl, "P2P_FIND");
1909
1910         if (argc > 2)
1911                 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s %s",
1912                                   argv[0], argv[1], argv[2]);
1913         else if (argc > 1)
1914                 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
1915                                   argv[0], argv[1]);
1916         else
1917                 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
1918         if (res < 0 || (size_t) res >= sizeof(cmd))
1919                 return -1;
1920         cmd[sizeof(cmd) - 1] = '\0';
1921         return wpa_ctrl_command(ctrl, cmd);
1922 }
1923
1924
1925 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1926                                      char *argv[])
1927 {
1928         return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1929 }
1930
1931
1932 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1933                                    char *argv[])
1934 {
1935         char cmd[128];
1936         int res;
1937
1938         if (argc < 2) {
1939                 printf("Invalid P2P_CONNECT command: needs at least two "
1940                        "arguments (address and pbc/PIN)\n");
1941                 return -1;
1942         }
1943
1944         if (argc > 4)
1945                 res = os_snprintf(cmd, sizeof(cmd),
1946                                   "P2P_CONNECT %s %s %s %s %s",
1947                                   argv[0], argv[1], argv[2], argv[3],
1948                                   argv[4]);
1949         else if (argc > 3)
1950                 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
1951                                   argv[0], argv[1], argv[2], argv[3]);
1952         else if (argc > 2)
1953                 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
1954                                   argv[0], argv[1], argv[2]);
1955         else
1956                 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1957                                   argv[0], argv[1]);
1958         if (res < 0 || (size_t) res >= sizeof(cmd))
1959                 return -1;
1960         cmd[sizeof(cmd) - 1] = '\0';
1961         return wpa_ctrl_command(ctrl, cmd);
1962 }
1963
1964
1965 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1966 {
1967         int arg = get_cmd_arg_num(str, pos);
1968         char **res = NULL;
1969
1970         switch (arg) {
1971         case 1:
1972                 res = cli_txt_list_array(&p2p_peers);
1973                 break;
1974         }
1975
1976         return res;
1977 }
1978
1979
1980 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1981                                   char *argv[])
1982 {
1983         char cmd[128];
1984         int res;
1985
1986         if (argc == 0)
1987                 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
1988
1989         res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
1990         if (res < 0 || (size_t) res >= sizeof(cmd))
1991                 return -1;
1992         cmd[sizeof(cmd) - 1] = '\0';
1993         return wpa_ctrl_command(ctrl, cmd);
1994 }
1995
1996
1997 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1998                                         char *argv[])
1999 {
2000         char cmd[128];
2001         int res;
2002
2003         if (argc != 1) {
2004                 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
2005                        "(interface name)\n");
2006                 return -1;
2007         }
2008
2009         res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
2010         if (res < 0 || (size_t) res >= sizeof(cmd))
2011                 return -1;
2012         cmd[sizeof(cmd) - 1] = '\0';
2013         return wpa_ctrl_command(ctrl, cmd);
2014 }
2015
2016
2017 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
2018 {
2019         int arg = get_cmd_arg_num(str, pos);
2020         char **res = NULL;
2021
2022         switch (arg) {
2023         case 1:
2024                 res = cli_txt_list_array(&p2p_groups);
2025                 break;
2026         }
2027
2028         return res;
2029 }
2030
2031
2032 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
2033                                         char *argv[])
2034 {
2035         char cmd[128];
2036         int res;
2037
2038         if (argc == 0)
2039                 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
2040
2041         if (argc > 1)
2042                 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s %s",
2043                                   argv[0], argv[1]);
2044         else
2045                 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s",
2046                                   argv[0]);
2047         if (res < 0 || (size_t) res >= sizeof(cmd))
2048                 return -1;
2049         cmd[sizeof(cmd) - 1] = '\0';
2050         return wpa_ctrl_command(ctrl, cmd);
2051 }
2052
2053
2054 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
2055                                      char *argv[])
2056 {
2057         char cmd[128];
2058         int res;
2059
2060         if (argc != 2 && argc != 3) {
2061                 printf("Invalid P2P_PROV_DISC command: needs at least "
2062                        "two arguments, address and config method\n"
2063                        "(display, keypad, or pbc) and an optional join\n");
2064                 return -1;
2065         }
2066
2067         if (argc == 3)
2068                 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s %s",
2069                                   argv[0], argv[1], argv[2]);
2070         else
2071                 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
2072                                   argv[0], argv[1]);
2073         if (res < 0 || (size_t) res >= sizeof(cmd))
2074                 return -1;
2075         cmd[sizeof(cmd) - 1] = '\0';
2076         return wpa_ctrl_command(ctrl, cmd);
2077 }
2078
2079
2080 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
2081                                           char *argv[])
2082 {
2083         return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
2084 }
2085
2086
2087 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
2088                                          char *argv[])
2089 {
2090         char cmd[4096];
2091         int res;
2092
2093         if (argc != 2 && argc != 4) {
2094                 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2095                        "arguments (address and TLVs) or four arguments "
2096                        "(address, \"upnp\", version, search target "
2097                        "(SSDP ST:)\n");
2098                 return -1;
2099         }
2100
2101         if (argc == 4)
2102                 res = os_snprintf(cmd, sizeof(cmd),
2103                                   "P2P_SERV_DISC_REQ %s %s %s %s",
2104                                   argv[0], argv[1], argv[2], argv[3]);
2105         else
2106                 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
2107                                   argv[0], argv[1]);
2108         if (res < 0 || (size_t) res >= sizeof(cmd))
2109                 return -1;
2110         cmd[sizeof(cmd) - 1] = '\0';
2111         return wpa_ctrl_command(ctrl, cmd);
2112 }
2113
2114
2115 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
2116                                                 int argc, char *argv[])
2117 {
2118         char cmd[128];
2119         int res;
2120
2121         if (argc != 1) {
2122                 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
2123                        "argument (pending request identifier)\n");
2124                 return -1;
2125         }
2126
2127         res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
2128                           argv[0]);
2129         if (res < 0 || (size_t) res >= sizeof(cmd))
2130                 return -1;
2131         cmd[sizeof(cmd) - 1] = '\0';
2132         return wpa_ctrl_command(ctrl, cmd);
2133 }
2134
2135
2136 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
2137                                           char *argv[])
2138 {
2139         char cmd[4096];
2140         int res;
2141
2142         if (argc != 4) {
2143                 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2144                        "arguments (freq, address, dialog token, and TLVs)\n");
2145                 return -1;
2146         }
2147
2148         res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2149                           argv[0], argv[1], argv[2], argv[3]);
2150         if (res < 0 || (size_t) res >= sizeof(cmd))
2151                 return -1;
2152         cmd[sizeof(cmd) - 1] = '\0';
2153         return wpa_ctrl_command(ctrl, cmd);
2154 }
2155
2156
2157 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2158                                           char *argv[])
2159 {
2160         return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
2161 }
2162
2163
2164 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2165                                               int argc, char *argv[])
2166 {
2167         char cmd[128];
2168         int res;
2169
2170         if (argc != 1) {
2171                 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
2172                        "argument (external processing: 0/1)\n");
2173                 return -1;
2174         }
2175
2176         res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
2177                           argv[0]);
2178         if (res < 0 || (size_t) res >= sizeof(cmd))
2179                 return -1;
2180         cmd[sizeof(cmd) - 1] = '\0';
2181         return wpa_ctrl_command(ctrl, cmd);
2182 }
2183
2184
2185 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2186                                          char *argv[])
2187 {
2188         return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
2189 }
2190
2191
2192 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2193                                        char *argv[])
2194 {
2195         char cmd[4096];
2196         int res;
2197
2198         if (argc != 3 && argc != 4) {
2199                 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
2200                        "arguments\n");
2201                 return -1;
2202         }
2203
2204         if (argc == 4)
2205                 res = os_snprintf(cmd, sizeof(cmd),
2206                                   "P2P_SERVICE_ADD %s %s %s %s",
2207                                   argv[0], argv[1], argv[2], argv[3]);
2208         else
2209                 res = os_snprintf(cmd, sizeof(cmd),
2210                                   "P2P_SERVICE_ADD %s %s %s",
2211                                   argv[0], argv[1], argv[2]);
2212         if (res < 0 || (size_t) res >= sizeof(cmd))
2213                 return -1;
2214         cmd[sizeof(cmd) - 1] = '\0';
2215         return wpa_ctrl_command(ctrl, cmd);
2216 }
2217
2218
2219 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2220                                        char *argv[])
2221 {
2222         char cmd[4096];
2223         int res;
2224
2225         if (argc != 2 && argc != 3) {
2226                 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2227                        "arguments\n");
2228                 return -1;
2229         }
2230
2231         if (argc == 3)
2232                 res = os_snprintf(cmd, sizeof(cmd),
2233                                   "P2P_SERVICE_DEL %s %s %s",
2234                                   argv[0], argv[1], argv[2]);
2235         else
2236                 res = os_snprintf(cmd, sizeof(cmd),
2237                                   "P2P_SERVICE_DEL %s %s",
2238                                   argv[0], argv[1]);
2239         if (res < 0 || (size_t) res >= sizeof(cmd))
2240                 return -1;
2241         cmd[sizeof(cmd) - 1] = '\0';
2242         return wpa_ctrl_command(ctrl, cmd);
2243 }
2244
2245
2246 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2247                                   int argc, char *argv[])
2248 {
2249         char cmd[128];
2250         int res;
2251
2252         if (argc != 1) {
2253                 printf("Invalid P2P_REJECT command: needs one argument "
2254                        "(peer address)\n");
2255                 return -1;
2256         }
2257
2258         res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
2259         if (res < 0 || (size_t) res >= sizeof(cmd))
2260                 return -1;
2261         cmd[sizeof(cmd) - 1] = '\0';
2262         return wpa_ctrl_command(ctrl, cmd);
2263 }
2264
2265
2266 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2267                                   int argc, char *argv[])
2268 {
2269         char cmd[128];
2270         int res;
2271
2272         if (argc < 1) {
2273                 printf("Invalid P2P_INVITE command: needs at least one "
2274                        "argument\n");
2275                 return -1;
2276         }
2277
2278         if (argc > 2)
2279                 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
2280                                   argv[0], argv[1], argv[2]);
2281         else if (argc > 1)
2282                 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
2283                                   argv[0], argv[1]);
2284         else
2285                 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
2286         if (res < 0 || (size_t) res >= sizeof(cmd))
2287                 return -1;
2288         cmd[sizeof(cmd) - 1] = '\0';
2289         return wpa_ctrl_command(ctrl, cmd);
2290 }
2291
2292
2293 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2294 {
2295         char buf[64];
2296         if (argc != 1) {
2297                 printf("Invalid 'p2p_peer' command - exactly one argument, "
2298                        "P2P peer device address, is required.\n");
2299                 return -1;
2300         }
2301         os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
2302         return wpa_ctrl_command(ctrl, buf);
2303 }
2304
2305
2306 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2307 {
2308         int arg = get_cmd_arg_num(str, pos);
2309         char **res = NULL;
2310
2311         switch (arg) {
2312         case 1:
2313                 res = cli_txt_list_array(&p2p_peers);
2314                 break;
2315         }
2316
2317         return res;
2318 }
2319
2320
2321 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2322                                      char *addr, size_t addr_len,
2323                                      int discovered)
2324 {
2325         char buf[4096], *pos;
2326         size_t len;
2327         int ret;
2328
2329         if (ctrl_conn == NULL)
2330                 return -1;
2331         len = sizeof(buf) - 1;
2332         ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
2333                                wpa_cli_msg_cb);
2334         if (ret == -2) {
2335                 printf("'%s' command timed out.\n", cmd);
2336                 return -2;
2337         } else if (ret < 0) {
2338                 printf("'%s' command failed.\n", cmd);
2339                 return -1;
2340         }
2341
2342         buf[len] = '\0';
2343         if (memcmp(buf, "FAIL", 4) == 0)
2344                 return -1;
2345
2346         pos = buf;
2347         while (*pos != '\0' && *pos != '\n')
2348                 pos++;
2349         *pos++ = '\0';
2350         os_strlcpy(addr, buf, addr_len);
2351         if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2352                 printf("%s\n", addr);
2353         return 0;
2354 }
2355
2356
2357 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2358 {
2359         char addr[32], cmd[64];
2360         int discovered;
2361
2362         discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2363
2364         if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2365                                       addr, sizeof(addr), discovered))
2366                 return -1;
2367         do {
2368                 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2369         } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2370                          discovered) == 0);
2371
2372         return 0;
2373 }
2374
2375
2376 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2377 {
2378         char cmd[100];
2379         int res;
2380
2381         if (argc != 2) {
2382                 printf("Invalid P2P_SET command: needs two arguments (field, "
2383                        "value)\n");
2384                 return -1;
2385         }
2386
2387         res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2388         if (res < 0 || (size_t) res >= sizeof(cmd))
2389                 return -1;
2390         cmd[sizeof(cmd) - 1] = '\0';
2391         return wpa_ctrl_command(ctrl, cmd);
2392 }
2393
2394
2395 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2396 {
2397         return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2398 }
2399
2400
2401 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2402                                   char *argv[])
2403 {
2404         return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2405 }
2406
2407
2408 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2409                                        char *argv[])
2410 {
2411         char cmd[100];
2412         int res;
2413
2414         if (argc != 1) {
2415                 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2416                        "(peer address)\n");
2417                 return -1;
2418         }
2419
2420         res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]);
2421
2422         if (res < 0 || (size_t) res >= sizeof(cmd))
2423                 return -1;
2424
2425         cmd[sizeof(cmd) - 1] = '\0';
2426         return wpa_ctrl_command(ctrl, cmd);
2427 }
2428
2429
2430 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2431                                         char *argv[])
2432 {
2433         char cmd[100];
2434         int res;
2435
2436         if (argc != 0 && argc != 2 && argc != 4) {
2437                 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2438                        "(preferred duration, interval; in microsecods).\n"
2439                        "Optional second pair can be used to provide "
2440                        "acceptable values.\n");
2441                 return -1;
2442         }
2443
2444         if (argc == 4)
2445                 res = os_snprintf(cmd, sizeof(cmd),
2446                                   "P2P_PRESENCE_REQ %s %s %s %s",
2447                                   argv[0], argv[1], argv[2], argv[3]);
2448         else if (argc == 2)
2449                 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2450                                   argv[0], argv[1]);
2451         else
2452                 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2453         if (res < 0 || (size_t) res >= sizeof(cmd))
2454                 return -1;
2455         cmd[sizeof(cmd) - 1] = '\0';
2456         return wpa_ctrl_command(ctrl, cmd);
2457 }
2458
2459
2460 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2461                                       char *argv[])
2462 {
2463         char cmd[100];
2464         int res;
2465
2466         if (argc != 0 && argc != 2) {
2467                 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2468                        "(availability period, availability interval; in "
2469                        "millisecods).\n"
2470                        "Extended Listen Timing can be cancelled with this "
2471                        "command when used without parameters.\n");
2472                 return -1;
2473         }
2474
2475         if (argc == 2)
2476                 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2477                                   argv[0], argv[1]);
2478         else
2479                 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2480         if (res < 0 || (size_t) res >= sizeof(cmd))
2481                 return -1;
2482         cmd[sizeof(cmd) - 1] = '\0';
2483         return wpa_ctrl_command(ctrl, cmd);
2484 }
2485
2486 #endif /* CONFIG_P2P */
2487
2488
2489 #ifdef CONFIG_INTERWORKING
2490 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2491                                   char *argv[])
2492 {
2493         return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2494 }
2495
2496
2497 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2498                                        char *argv[])
2499 {
2500         return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2501 }
2502
2503
2504 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2505                                            char *argv[])
2506 {
2507         char cmd[100];
2508         int res;
2509
2510         if (argc == 0)
2511                 return wpa_ctrl_command(ctrl, "INTERWORKING_SELECT");
2512
2513         res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_SELECT %s", argv[0]);
2514         if (res < 0 || (size_t) res >= sizeof(cmd))
2515                 return -1;
2516         cmd[sizeof(cmd) - 1] = '\0';
2517         return wpa_ctrl_command(ctrl, cmd);
2518 }
2519
2520
2521 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2522                                             char *argv[])
2523 {
2524         char cmd[100];
2525         int res;
2526
2527         if (argc != 1) {
2528                 printf("Invalid INTERWORKING_CONNECT commands: needs one "
2529                        "argument (BSSID)\n");
2530                 return -1;
2531         }
2532
2533         res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_CONNECT %s",
2534                           argv[0]);
2535         if (res < 0 || (size_t) res >= sizeof(cmd))
2536                 return -1;
2537         cmd[sizeof(cmd) - 1] = '\0';
2538         return wpa_ctrl_command(ctrl, cmd);
2539 }
2540
2541
2542 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2543 {
2544         char cmd[100];
2545         int res;
2546
2547         if (argc != 2) {
2548                 printf("Invalid ANQP_GET command: needs two arguments "
2549                        "(addr and info id list)\n");
2550                 return -1;
2551         }
2552
2553         res = os_snprintf(cmd, sizeof(cmd), "ANQP_GET %s %s",
2554                           argv[0], argv[1]);
2555         if (res < 0 || (size_t) res >= sizeof(cmd))
2556                 return -1;
2557         cmd[sizeof(cmd) - 1] = '\0';
2558         return wpa_ctrl_command(ctrl, cmd);
2559 }
2560 #endif /* CONFIG_INTERWORKING */
2561
2562
2563 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2564                                        char *argv[])
2565 {
2566         char cmd[256];
2567         int res;
2568
2569         if (argc != 1) {
2570                 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2571                        "(0/1 = disable/enable automatic reconnection)\n");
2572                 return -1;
2573         }
2574         res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2575         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2576                 printf("Too long STA_AUTOCONNECT command.\n");
2577                 return -1;
2578         }
2579         return wpa_ctrl_command(ctrl, cmd);
2580 }
2581
2582
2583 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2584                                      char *argv[])
2585 {
2586         char cmd[256];
2587         int res;
2588
2589         if (argc != 1) {
2590                 printf("Invalid TDLS_DISCOVER command: needs one argument "
2591                        "(Peer STA MAC address)\n");
2592                 return -1;
2593         }
2594
2595         res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]);
2596         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2597                 printf("Too long TDLS_DISCOVER command.\n");
2598                 return -1;
2599         }
2600         return wpa_ctrl_command(ctrl, cmd);
2601 }
2602
2603
2604 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2605                                   char *argv[])
2606 {
2607         char cmd[256];
2608         int res;
2609
2610         if (argc != 1) {
2611                 printf("Invalid TDLS_SETUP command: needs one argument "
2612                        "(Peer STA MAC address)\n");
2613                 return -1;
2614         }
2615
2616         res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]);
2617         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2618                 printf("Too long TDLS_SETUP command.\n");
2619                 return -1;
2620         }
2621         return wpa_ctrl_command(ctrl, cmd);
2622 }
2623
2624
2625 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2626                                      char *argv[])
2627 {
2628         char cmd[256];
2629         int res;
2630
2631         if (argc != 1) {
2632                 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2633                        "(Peer STA MAC address)\n");
2634                 return -1;
2635         }
2636
2637         res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]);
2638         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2639                 printf("Too long TDLS_TEARDOWN command.\n");
2640                 return -1;
2641         }
2642         return wpa_ctrl_command(ctrl, cmd);
2643 }
2644
2645
2646 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2647                                    char *argv[])
2648 {
2649         return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2650 }
2651
2652
2653 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2654                                       char *argv[])
2655 {
2656         return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2657 }
2658
2659
2660 enum wpa_cli_cmd_flags {
2661         cli_cmd_flag_none               = 0x00,
2662         cli_cmd_flag_sensitive          = 0x01
2663 };
2664
2665 struct wpa_cli_cmd {
2666         const char *cmd;
2667         int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2668         enum wpa_cli_cmd_flags flags;
2669         const char *usage;
2670 };
2671
2672 static struct wpa_cli_cmd wpa_cli_commands[] = {
2673         { "status", wpa_cli_cmd_status,
2674           cli_cmd_flag_none,
2675           "[verbose] = get current WPA/EAPOL/EAP status" },
2676         { "ping", wpa_cli_cmd_ping,
2677           cli_cmd_flag_none,
2678           "= pings wpa_supplicant" },
2679         { "relog", wpa_cli_cmd_relog,
2680           cli_cmd_flag_none,
2681           "= re-open log-file (allow rolling logs)" },
2682         { "note", wpa_cli_cmd_note,
2683           cli_cmd_flag_none,
2684           "<text> = add a note to wpa_supplicant debug log" },
2685         { "mib", wpa_cli_cmd_mib,
2686           cli_cmd_flag_none,
2687           "= get MIB variables (dot1x, dot11)" },
2688         { "help", wpa_cli_cmd_help,
2689           cli_cmd_flag_none,
2690           "= show this usage help" },
2691         { "interface", wpa_cli_cmd_interface,
2692           cli_cmd_flag_none,
2693           "[ifname] = show interfaces/select interface" },
2694         { "level", wpa_cli_cmd_level,
2695           cli_cmd_flag_none,
2696           "<debug level> = change debug level" },
2697         { "license", wpa_cli_cmd_license,
2698           cli_cmd_flag_none,
2699           "= show full wpa_cli license" },
2700         { "quit", wpa_cli_cmd_quit,
2701           cli_cmd_flag_none,
2702           "= exit wpa_cli" },
2703         { "set", wpa_cli_cmd_set,
2704           cli_cmd_flag_none,
2705           "= set variables (shows list of variables when run without "
2706           "arguments)" },
2707         { "get", wpa_cli_cmd_get,
2708           cli_cmd_flag_none,
2709           "<name> = get information" },
2710         { "logon", wpa_cli_cmd_logon,
2711           cli_cmd_flag_none,
2712           "= IEEE 802.1X EAPOL state machine logon" },
2713         { "logoff", wpa_cli_cmd_logoff,
2714           cli_cmd_flag_none,
2715           "= IEEE 802.1X EAPOL state machine logoff" },
2716         { "pmksa", wpa_cli_cmd_pmksa,
2717           cli_cmd_flag_none,
2718           "= show PMKSA cache" },
2719         { "reassociate", wpa_cli_cmd_reassociate,
2720           cli_cmd_flag_none,
2721           "= force reassociation" },
2722         { "preauthenticate", wpa_cli_cmd_preauthenticate,
2723           cli_cmd_flag_none,
2724           "<BSSID> = force preauthentication" },
2725         { "identity", wpa_cli_cmd_identity,
2726           cli_cmd_flag_none,
2727           "<network id> <identity> = configure identity for an SSID" },
2728         { "password", wpa_cli_cmd_password,
2729           cli_cmd_flag_sensitive,
2730           "<network id> <password> = configure password for an SSID" },
2731         { "new_password", wpa_cli_cmd_new_password,
2732           cli_cmd_flag_sensitive,
2733           "<network id> <password> = change password for an SSID" },
2734         { "pin", wpa_cli_cmd_pin,
2735           cli_cmd_flag_sensitive,
2736           "<network id> <pin> = configure pin for an SSID" },
2737         { "otp", wpa_cli_cmd_otp,
2738           cli_cmd_flag_sensitive,
2739           "<network id> <password> = configure one-time-password for an SSID"
2740         },
2741         { "passphrase", wpa_cli_cmd_passphrase,
2742           cli_cmd_flag_sensitive,
2743           "<network id> <passphrase> = configure private key passphrase\n"
2744           "  for an SSID" },
2745         { "bssid", wpa_cli_cmd_bssid,
2746           cli_cmd_flag_none,
2747           "<network id> <BSSID> = set preferred BSSID for an SSID" },
2748         { "blacklist", wpa_cli_cmd_blacklist,
2749           cli_cmd_flag_none,
2750           "<BSSID> = add a BSSID to the blacklist\n"
2751           "blacklist clear = clear the blacklist\n"
2752           "blacklist = display the blacklist" },
2753         { "log_level", wpa_cli_cmd_log_level,
2754           cli_cmd_flag_none,
2755           "<level> [<timestamp>] = update the log level/timestamp\n"
2756           "log_level = display the current log level and log options" },
2757         { "list_networks", wpa_cli_cmd_list_networks,
2758           cli_cmd_flag_none,
2759           "= list configured networks" },
2760         { "select_network", wpa_cli_cmd_select_network,
2761           cli_cmd_flag_none,
2762           "<network id> = select a network (disable others)" },
2763         { "enable_network", wpa_cli_cmd_enable_network,
2764           cli_cmd_flag_none,
2765           "<network id> = enable a network" },
2766         { "disable_network", wpa_cli_cmd_disable_network,
2767           cli_cmd_flag_none,
2768           "<network id> = disable a network" },
2769         { "add_network", wpa_cli_cmd_add_network,
2770           cli_cmd_flag_none,
2771           "= add a network" },
2772         { "remove_network", wpa_cli_cmd_remove_network,
2773           cli_cmd_flag_none,
2774           "<network id> = remove a network" },
2775         { "set_network", wpa_cli_cmd_set_network,
2776           cli_cmd_flag_sensitive,
2777           "<network id> <variable> <value> = set network variables (shows\n"
2778           "  list of variables when run without arguments)" },
2779         { "get_network", wpa_cli_cmd_get_network,
2780           cli_cmd_flag_none,
2781           "<network id> <variable> = get network variables" },
2782         { "save_config", wpa_cli_cmd_save_config,
2783           cli_cmd_flag_none,
2784           "= save the current configuration" },
2785         { "disconnect", wpa_cli_cmd_disconnect,
2786           cli_cmd_flag_none,
2787           "= disconnect and wait for reassociate/reconnect command before\n"
2788           "  connecting" },
2789         { "reconnect", wpa_cli_cmd_reconnect,
2790           cli_cmd_flag_none,
2791           "= like reassociate, but only takes effect if already disconnected"
2792         },
2793         { "scan", wpa_cli_cmd_scan,
2794           cli_cmd_flag_none,
2795           "= request new BSS scan" },
2796         { "scan_results", wpa_cli_cmd_scan_results,
2797           cli_cmd_flag_none,
2798           "= get latest scan results" },
2799         { "bss", wpa_cli_cmd_bss,
2800           cli_cmd_flag_none,
2801           "<<idx> | <bssid>> = get detailed scan result info" },
2802         { "get_capability", wpa_cli_cmd_get_capability,
2803           cli_cmd_flag_none,
2804           "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2805         { "reconfigure", wpa_cli_cmd_reconfigure,
2806           cli_cmd_flag_none,
2807           "= force wpa_supplicant to re-read its configuration file" },
2808         { "terminate", wpa_cli_cmd_terminate,
2809           cli_cmd_flag_none,
2810           "= terminate wpa_supplicant" },
2811         { "interface_add", wpa_cli_cmd_interface_add,
2812           cli_cmd_flag_none,
2813           "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2814           "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
2815           "  are optional" },
2816         { "interface_remove", wpa_cli_cmd_interface_remove,
2817           cli_cmd_flag_none,
2818           "<ifname> = removes the interface" },
2819         { "interface_list", wpa_cli_cmd_interface_list,
2820           cli_cmd_flag_none,
2821           "= list available interfaces" },
2822         { "ap_scan", wpa_cli_cmd_ap_scan,
2823           cli_cmd_flag_none,
2824           "<value> = set ap_scan parameter" },
2825         { "scan_interval", wpa_cli_cmd_scan_interval,
2826           cli_cmd_flag_none,
2827           "<value> = set scan_interval parameter (in seconds)" },
2828         { "bss_expire_age", wpa_cli_cmd_bss_expire_age,
2829           cli_cmd_flag_none,
2830           "<value> = set BSS expiration age parameter" },
2831         { "bss_expire_count", wpa_cli_cmd_bss_expire_count,
2832           cli_cmd_flag_none,
2833           "<value> = set BSS expiration scan count parameter" },
2834         { "stkstart", wpa_cli_cmd_stkstart,
2835           cli_cmd_flag_none,
2836           "<addr> = request STK negotiation with <addr>" },
2837         { "ft_ds", wpa_cli_cmd_ft_ds,
2838           cli_cmd_flag_none,
2839           "<addr> = request over-the-DS FT with <addr>" },
2840         { "wps_pbc", wpa_cli_cmd_wps_pbc,
2841           cli_cmd_flag_none,
2842           "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2843         { "wps_pin", wpa_cli_cmd_wps_pin,
2844           cli_cmd_flag_sensitive,
2845           "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2846           "hardcoded)" },
2847         { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
2848           cli_cmd_flag_sensitive,
2849           "<PIN> = verify PIN checksum" },
2850         { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2851           "Cancels the pending WPS operation" },
2852 #ifdef CONFIG_WPS_OOB
2853         { "wps_oob", wpa_cli_cmd_wps_oob,
2854           cli_cmd_flag_sensitive,
2855           "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2856 #endif /* CONFIG_WPS_OOB */
2857         { "wps_reg", wpa_cli_cmd_wps_reg,
2858           cli_cmd_flag_sensitive,
2859           "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2860         { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
2861           cli_cmd_flag_sensitive,
2862           "[params..] = enable/disable AP PIN" },
2863         { "wps_er_start", wpa_cli_cmd_wps_er_start,
2864           cli_cmd_flag_none,
2865           "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2866         { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2867           cli_cmd_flag_none,
2868           "= stop Wi-Fi Protected Setup External Registrar" },
2869         { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2870           cli_cmd_flag_sensitive,
2871           "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2872         { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2873           cli_cmd_flag_none,
2874           "<UUID> = accept an Enrollee PBC using External Registrar" },
2875         { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2876           cli_cmd_flag_sensitive,
2877           "<UUID> <PIN> = learn AP configuration" },
2878         { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
2879           cli_cmd_flag_none,
2880           "<UUID> <network id> = set AP configuration for enrolling" },
2881         { "wps_er_config", wpa_cli_cmd_wps_er_config,
2882           cli_cmd_flag_sensitive,
2883           "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2884         { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2885           cli_cmd_flag_none,
2886           "<addr> = request RSN authentication with <addr> in IBSS" },
2887 #ifdef CONFIG_AP
2888         { "sta", wpa_cli_cmd_sta,
2889           cli_cmd_flag_none,
2890           "<addr> = get information about an associated station (AP)" },
2891         { "all_sta", wpa_cli_cmd_all_sta,
2892           cli_cmd_flag_none,
2893           "= get information about all associated stations (AP)" },
2894 #endif /* CONFIG_AP */
2895         { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2896           "= notification of suspend/hibernate" },
2897         { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2898           "= notification of resume/thaw" },
2899         { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2900           "= drop SA without deauth/disassoc (test command)" },
2901         { "roam", wpa_cli_cmd_roam,
2902           cli_cmd_flag_none,
2903           "<addr> = roam to the specified BSS" },
2904 #ifdef CONFIG_P2P
2905         { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2906           "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2907         { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2908           "= stop P2P Devices search" },
2909         { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2910           "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2911         { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2912           "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2913         { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2914           "<ifname> = remove P2P group interface (terminate group if GO)" },
2915         { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2916           "= add a new P2P group (local end as GO)" },
2917         { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2918           "<addr> <method> = request provisioning discovery" },
2919         { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2920           cli_cmd_flag_none,
2921           "= get the passphrase for a group (GO only)" },
2922         { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2923           cli_cmd_flag_none,
2924           "<addr> <TLVs> = schedule service discovery request" },
2925         { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2926           cli_cmd_flag_none,
2927           "<id> = cancel pending service discovery request" },
2928         { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2929           cli_cmd_flag_none,
2930           "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2931         { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2932           cli_cmd_flag_none,
2933           "= indicate change in local services" },
2934         { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2935           cli_cmd_flag_none,
2936           "<external> = set external processing of service discovery" },
2937         { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2938           cli_cmd_flag_none,
2939           "= remove all stored service entries" },
2940         { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2941           cli_cmd_flag_none,
2942           "<bonjour|upnp> <query|version> <response|service> = add a local "
2943           "service" },
2944         { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2945           cli_cmd_flag_none,
2946           "<bonjour|upnp> <query|version> [|service] = remove a local "
2947           "service" },
2948         { "p2p_reject", wpa_cli_cmd_p2p_reject,
2949           cli_cmd_flag_none,
2950           "<addr> = reject connection attempts from a specific peer" },
2951         { "p2p_invite", wpa_cli_cmd_p2p_invite,
2952           cli_cmd_flag_none,
2953           "<cmd> [peer=addr] = invite peer" },
2954         { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2955           "[discovered] = list known (optionally, only fully discovered) P2P "
2956           "peers" },
2957         { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2958           "<address> = show information about known P2P peer" },
2959         { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2960           "<field> <value> = set a P2P parameter" },
2961         { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2962           "= flush P2P state" },
2963         { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
2964           "= cancel P2P group formation" },
2965         { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none,
2966           "<address> = unauthorize a peer" },
2967         { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2968           "[<duration> <interval>] [<duration> <interval>] = request GO "
2969           "presence" },
2970         { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2971           "[<period> <interval>] = set extended listen timing" },
2972 #endif /* CONFIG_P2P */
2973
2974 #ifdef CONFIG_INTERWORKING
2975         { "fetch_anqp", wpa_cli_cmd_fetch_anqp, cli_cmd_flag_none,
2976           "= fetch ANQP information for all APs" },
2977         { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, cli_cmd_flag_none,
2978           "= stop fetch_anqp operation" },
2979         { "interworking_select", wpa_cli_cmd_interworking_select,
2980           cli_cmd_flag_none,
2981           "[auto] = perform Interworking network selection" },
2982         { "interworking_connect", wpa_cli_cmd_interworking_connect,
2983           cli_cmd_flag_none,
2984           "<BSSID> = connect using Interworking credentials" },
2985         { "anqp_get", wpa_cli_cmd_anqp_get, cli_cmd_flag_none,
2986           "<addr> <info id>[,<info id>]... = request ANQP information" },
2987 #endif /* CONFIG_INTERWORKING */
2988         { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
2989           "<0/1> = disable/enable automatic reconnection" },
2990         { "tdls_discover", wpa_cli_cmd_tdls_discover,
2991           cli_cmd_flag_none,
2992           "<addr> = request TDLS discovery with <addr>" },
2993         { "tdls_setup", wpa_cli_cmd_tdls_setup,
2994           cli_cmd_flag_none,
2995           "<addr> = request TDLS setup with <addr>" },
2996         { "tdls_teardown", wpa_cli_cmd_tdls_teardown,
2997           cli_cmd_flag_none,
2998           "<addr> = tear down TDLS with <addr>" },
2999         { "signal_poll", wpa_cli_cmd_signal_poll,
3000           cli_cmd_flag_none,
3001           "= get signal parameters" },
3002         { "reauthenticate", wpa_cli_cmd_reauthenticate, cli_cmd_flag_none,
3003           "= trigger IEEE 802.1X/EAPOL reauthentication" },
3004         { NULL, NULL, cli_cmd_flag_none, NULL }
3005 };
3006
3007
3008 /*
3009  * Prints command usage, lines are padded with the specified string.
3010  */
3011 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
3012 {
3013         char c;
3014         size_t n;
3015
3016         printf("%s%s ", pad, cmd->cmd);
3017         for (n = 0; (c = cmd->usage[n]); n++) {
3018                 printf("%c", c);
3019                 if (c == '\n')
3020                         printf("%s", pad);
3021         }
3022         printf("\n");
3023 }
3024
3025
3026 static void print_help(void)
3027 {
3028         int n;
3029         printf("commands:\n");
3030         for (n = 0; wpa_cli_commands[n].cmd; n++)
3031                 print_cmd_help(&wpa_cli_commands[n], "  ");
3032 }
3033
3034
3035 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
3036 {
3037         const char *c, *delim;
3038         int n;
3039         size_t len;
3040
3041         delim = os_strchr(cmd, ' ');
3042         if (delim)
3043                 len = delim - cmd;
3044         else
3045                 len = os_strlen(cmd);
3046
3047         for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
3048                 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
3049                         return (wpa_cli_commands[n].flags &
3050                                 cli_cmd_flag_sensitive);
3051         }
3052         return 0;
3053 }
3054
3055
3056 static char ** wpa_list_cmd_list(void)
3057 {
3058         char **res;
3059         int i, count;
3060
3061         count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
3062         res = os_zalloc(count * sizeof(char *));
3063         if (res == NULL)
3064                 return NULL;
3065
3066         for (i = 0; wpa_cli_commands[i].cmd; i++) {
3067                 res[i] = os_strdup(wpa_cli_commands[i].cmd);
3068                 if (res[i] == NULL)
3069                         break;
3070         }
3071
3072         return res;
3073 }
3074
3075
3076 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3077                                       int pos)
3078 {
3079         int i;
3080
3081         if (os_strcasecmp(cmd, "bss") == 0)
3082                 return wpa_cli_complete_bss(str, pos);
3083 #ifdef CONFIG_P2P
3084         if (os_strcasecmp(cmd, "p2p_connect") == 0)
3085                 return wpa_cli_complete_p2p_connect(str, pos);
3086         if (os_strcasecmp(cmd, "p2p_peer") == 0)
3087                 return wpa_cli_complete_p2p_peer(str, pos);
3088         if (os_strcasecmp(cmd, "p2p_group_remove") == 0)
3089                 return wpa_cli_complete_p2p_group_remove(str, pos);
3090 #endif /* CONFIG_P2P */
3091
3092         for (i = 0; wpa_cli_commands[i].cmd; i++) {
3093                 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3094                         edit_clear_line();
3095                         printf("\r%s\n", wpa_cli_commands[i].usage);
3096                         edit_redraw();
3097                         break;
3098                 }
3099         }
3100
3101         return NULL;
3102 }
3103
3104
3105 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3106 {
3107         char **res;
3108         const char *end;
3109         char *cmd;
3110
3111         end = os_strchr(str, ' ');
3112         if (end == NULL || str + pos < end)
3113                 return wpa_list_cmd_list();
3114
3115         cmd = os_malloc(pos + 1);
3116         if (cmd == NULL)
3117                 return NULL;
3118         os_memcpy(cmd, str, pos);
3119         cmd[end - str] = '\0';
3120         res = wpa_cli_cmd_completion(cmd, str, pos);
3121         os_free(cmd);
3122         return res;
3123 }
3124
3125
3126 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3127 {
3128         struct wpa_cli_cmd *cmd, *match = NULL;
3129         int count;
3130         int ret = 0;
3131
3132         count = 0;
3133         cmd = wpa_cli_commands;
3134         while (cmd->cmd) {
3135                 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3136                 {
3137                         match = cmd;
3138                         if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3139                                 /* we have an exact match */
3140                                 count = 1;
3141                                 break;
3142                         }
3143                         count++;
3144                 }
3145                 cmd++;
3146         }
3147
3148         if (count > 1) {
3149                 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3150                 cmd = wpa_cli_commands;
3151                 while (cmd->cmd) {
3152                         if (os_strncasecmp(cmd->cmd, argv[0],
3153                                            os_strlen(argv[0])) == 0) {
3154                                 printf(" %s", cmd->cmd);
3155                         }
3156                         cmd++;
3157                 }
3158                 printf("\n");
3159                 ret = 1;
3160         } else if (count == 0) {
3161                 printf("Unknown command '%s'\n", argv[0]);
3162                 ret = 1;
3163         } else {
3164                 ret = match->handler(ctrl, argc - 1, &argv[1]);
3165         }
3166
3167         return ret;
3168 }
3169
3170
3171 static int str_match(const char *a, const char *b)
3172 {
3173         return os_strncmp(a, b, os_strlen(b)) == 0;
3174 }
3175
3176
3177 static int wpa_cli_exec(const char *program, const char *arg1,
3178                         const char *arg2)
3179 {
3180         char *cmd;
3181         size_t len;
3182         int res;
3183         int ret = 0;
3184
3185         len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
3186         cmd = os_malloc(len);
3187         if (cmd == NULL)
3188                 return -1;
3189         res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
3190         if (res < 0 || (size_t) res >= len) {
3191                 os_free(cmd);
3192                 return -1;
3193         }
3194         cmd[len - 1] = '\0';
3195 #ifndef _WIN32_WCE
3196         if (system(cmd) < 0)
3197                 ret = -1;
3198 #endif /* _WIN32_WCE */
3199         os_free(cmd);
3200
3201         return ret;
3202 }
3203
3204
3205 static void wpa_cli_action_process(const char *msg)
3206 {
3207         const char *pos;
3208         char *copy = NULL, *id, *pos2;
3209
3210         pos = msg;
3211         if (*pos == '<') {
3212                 /* skip priority */
3213                 pos = os_strchr(pos, '>');
3214                 if (pos)
3215                         pos++;
3216                 else
3217                         pos = msg;
3218         }
3219
3220         if (str_match(pos, WPA_EVENT_CONNECTED)) {
3221                 int new_id = -1;
3222                 os_unsetenv("WPA_ID");
3223                 os_unsetenv("WPA_ID_STR");
3224                 os_unsetenv("WPA_CTRL_DIR");
3225
3226                 pos = os_strstr(pos, "[id=");
3227                 if (pos)
3228                         copy = os_strdup(pos + 4);
3229
3230                 if (copy) {
3231                         pos2 = id = copy;
3232                         while (*pos2 && *pos2 != ' ')
3233                                 pos2++;
3234                         *pos2++ = '\0';
3235                         new_id = atoi(id);
3236                         os_setenv("WPA_ID", id, 1);
3237                         while (*pos2 && *pos2 != '=')
3238                                 pos2++;
3239                         if (*pos2 == '=')
3240                                 pos2++;
3241                         id = pos2;
3242                         while (*pos2 && *pos2 != ']')
3243                                 pos2++;
3244                         *pos2 = '\0';
3245                         os_setenv("WPA_ID_STR", id, 1);
3246                         os_free(copy);
3247                 }
3248
3249                 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3250
3251                 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
3252                         wpa_cli_connected = 1;
3253                         wpa_cli_last_id = new_id;
3254                         wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3255                 }
3256         } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3257                 if (wpa_cli_connected) {
3258                         wpa_cli_connected = 0;
3259                         wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3260                 }
3261         } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3262                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3263         } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3264                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3265         } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3266                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3267         } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3268                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3269         } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3270                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3271         } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3272                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3273         } else if (str_match(pos, WPS_EVENT_FAIL)) {
3274                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3275         } else if (str_match(pos, AP_STA_CONNECTED)) {
3276                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3277         } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3278                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3279         } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3280                 printf("wpa_supplicant is terminating - stop monitoring\n");
3281                 wpa_cli_quit = 1;
3282         }
3283 }
3284
3285
3286 #ifndef CONFIG_ANSI_C_EXTRA
3287 static void wpa_cli_action_cb(char *msg, size_t len)
3288 {
3289         wpa_cli_action_process(msg);
3290 }
3291 #endif /* CONFIG_ANSI_C_EXTRA */
3292
3293
3294 static void wpa_cli_reconnect(void)
3295 {
3296         wpa_cli_close_connection();
3297         wpa_cli_open_connection(ctrl_ifname, 1);
3298 }
3299
3300
3301 static void cli_event(const char *str)
3302 {
3303         const char *start, *s;
3304
3305         start = os_strchr(str, '>');
3306         if (start == NULL)
3307                 return;
3308
3309         start++;
3310
3311         if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3312                 s = os_strchr(start, ' ');
3313                 if (s == NULL)
3314                         return;
3315                 s = os_strchr(s + 1, ' ');
3316                 if (s == NULL)
3317                         return;
3318                 cli_txt_list_add(&bsses, s + 1);
3319                 return;
3320         }
3321
3322         if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3323                 s = os_strchr(start, ' ');
3324                 if (s == NULL)
3325                         return;
3326                 s = os_strchr(s + 1, ' ');
3327                 if (s == NULL)
3328                         return;
3329                 cli_txt_list_del_addr(&bsses, s + 1);
3330                 return;
3331         }
3332
3333 #ifdef CONFIG_P2P
3334         if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3335                 s = os_strstr(start, " p2p_dev_addr=");
3336                 if (s == NULL)
3337                         return;
3338                 cli_txt_list_add_addr(&p2p_peers, s + 14);
3339                 return;
3340         }
3341
3342         if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3343                 s = os_strstr(start, " p2p_dev_addr=");
3344                 if (s == NULL)
3345                         return;
3346                 cli_txt_list_del_addr(&p2p_peers, s + 14);
3347                 return;
3348         }
3349
3350         if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3351                 s = os_strchr(start, ' ');
3352                 if (s == NULL)
3353                         return;
3354                 cli_txt_list_add_word(&p2p_groups, s + 1);
3355                 return;
3356         }
3357
3358         if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3359                 s = os_strchr(start, ' ');
3360                 if (s == NULL)
3361                         return;
3362                 cli_txt_list_del_word(&p2p_groups, s + 1);
3363                 return;
3364         }
3365 #endif /* CONFIG_P2P */
3366 }
3367
3368
3369 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3370 {
3371         if (ctrl_conn == NULL) {
3372                 wpa_cli_reconnect();
3373                 return;
3374         }
3375         while (wpa_ctrl_pending(ctrl) > 0) {
3376                 char buf[256];
3377                 size_t len = sizeof(buf) - 1;
3378                 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3379                         buf[len] = '\0';
3380                         if (action_monitor)
3381                                 wpa_cli_action_process(buf);
3382                         else {
3383                                 cli_event(buf);
3384                                 if (wpa_cli_show_event(buf)) {
3385                                         edit_clear_line();
3386                                         printf("\r%s\n", buf);
3387                                         edit_redraw();
3388                                 }
3389                         }
3390                 } else {
3391                         printf("Could not read pending message.\n");
3392                         break;
3393                 }
3394         }
3395
3396         if (wpa_ctrl_pending(ctrl) < 0) {
3397                 printf("Connection to wpa_supplicant lost - trying to "
3398                        "reconnect\n");
3399                 wpa_cli_reconnect();
3400         }
3401 }
3402
3403 #define max_args 10
3404
3405 static int tokenize_cmd(char *cmd, char *argv[])
3406 {
3407         char *pos;
3408         int argc = 0;
3409
3410         pos = cmd;
3411         for (;;) {
3412                 while (*pos == ' ')
3413                         pos++;
3414                 if (*pos == '\0')
3415                         break;
3416                 argv[argc] = pos;
3417                 argc++;
3418                 if (argc == max_args)
3419                         break;
3420                 if (*pos == '"') {
3421                         char *pos2 = os_strrchr(pos, '"');
3422                         if (pos2)
3423                                 pos = pos2 + 1;
3424                 }
3425                 while (*pos != '\0' && *pos != ' ')
3426                         pos++;
3427                 if (*pos == ' ')
3428                         *pos++ = '\0';
3429         }
3430
3431         return argc;
3432 }
3433
3434
3435 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3436 {
3437         if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3438                 printf("Connection to wpa_supplicant lost - trying to "
3439                        "reconnect\n");
3440                 wpa_cli_close_connection();
3441         }
3442         if (!ctrl_conn)
3443                 wpa_cli_reconnect();
3444         eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3445 }
3446
3447
3448 static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
3449 {
3450         eloop_terminate();
3451 }
3452
3453
3454 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3455 {
3456         wpa_cli_recv_pending(mon_conn, 0);
3457 }
3458
3459
3460 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3461 {
3462         char *argv[max_args];
3463         int argc;
3464         argc = tokenize_cmd(cmd, argv);
3465         if (argc)
3466                 wpa_request(ctrl_conn, argc, argv);
3467 }
3468
3469
3470 static void wpa_cli_edit_eof_cb(void *ctx)
3471 {
3472         eloop_terminate();
3473 }
3474
3475
3476 static void wpa_cli_interactive(void)
3477 {
3478         char *home, *hfile = NULL;
3479
3480         printf("\nInteractive mode\n\n");
3481
3482         home = getenv("HOME");
3483         if (home) {
3484                 const char *fname = ".wpa_cli_history";
3485                 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3486                 hfile = os_malloc(hfile_len);
3487                 if (hfile)
3488                         os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3489         }
3490
3491         eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
3492         edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3493                   wpa_cli_edit_completion_cb, NULL, hfile);
3494         eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3495
3496         eloop_run();
3497
3498         cli_txt_list_flush(&p2p_peers);
3499         cli_txt_list_flush(&p2p_groups);
3500         cli_txt_list_flush(&bsses);
3501         edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3502         os_free(hfile);
3503         eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3504         wpa_cli_close_connection();
3505 }
3506
3507
3508 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3509 {
3510 #ifdef CONFIG_ANSI_C_EXTRA
3511         /* TODO: ANSI C version(?) */
3512         printf("Action processing not supported in ANSI C build.\n");
3513 #else /* CONFIG_ANSI_C_EXTRA */
3514         fd_set rfds;
3515         int fd, res;
3516         struct timeval tv;
3517         char buf[256]; /* note: large enough to fit in unsolicited messages */
3518         size_t len;
3519
3520         fd = wpa_ctrl_get_fd(ctrl);
3521
3522         while (!wpa_cli_quit) {
3523                 FD_ZERO(&rfds);
3524                 FD_SET(fd, &rfds);
3525                 tv.tv_sec = ping_interval;
3526                 tv.tv_usec = 0;
3527                 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3528                 if (res < 0 && errno != EINTR) {
3529                         perror("select");
3530                         break;
3531                 }
3532
3533                 if (FD_ISSET(fd, &rfds))
3534                         wpa_cli_recv_pending(ctrl, 1);
3535                 else {
3536                         /* verify that connection is still working */
3537                         len = sizeof(buf) - 1;
3538                         if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3539                                              wpa_cli_action_cb) < 0 ||
3540                             len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3541                                 printf("wpa_supplicant did not reply to PING "
3542                                        "command - exiting\n");
3543                                 break;
3544                         }
3545                 }
3546         }
3547 #endif /* CONFIG_ANSI_C_EXTRA */
3548 }
3549
3550
3551 static void wpa_cli_cleanup(void)
3552 {
3553         wpa_cli_close_connection();
3554         if (pid_file)
3555                 os_daemonize_terminate(pid_file);
3556
3557         os_program_deinit();
3558 }
3559
3560 static void wpa_cli_terminate(int sig)
3561 {
3562         wpa_cli_cleanup();
3563         exit(0);
3564 }
3565
3566
3567 static char * wpa_cli_get_default_ifname(void)
3568 {
3569         char *ifname = NULL;
3570
3571 #ifdef CONFIG_CTRL_IFACE_UNIX
3572         struct dirent *dent;
3573         DIR *dir = opendir(ctrl_iface_dir);
3574         if (!dir) {
3575 #ifdef ANDROID
3576                 char ifprop[PROPERTY_VALUE_MAX];
3577                 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3578                         ifname = os_strdup(ifprop);
3579                         printf("Using interface '%s'\n", ifname);
3580                         return ifname;
3581                 }
3582 #endif /* ANDROID */
3583                 return NULL;
3584         }
3585         while ((dent = readdir(dir))) {
3586 #ifdef _DIRENT_HAVE_D_TYPE
3587                 /*
3588                  * Skip the file if it is not a socket. Also accept
3589                  * DT_UNKNOWN (0) in case the C library or underlying
3590                  * file system does not support d_type.
3591                  */
3592                 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3593                         continue;
3594 #endif /* _DIRENT_HAVE_D_TYPE */
3595                 if (os_strcmp(dent->d_name, ".") == 0 ||
3596                     os_strcmp(dent->d_name, "..") == 0)
3597                         continue;
3598                 printf("Selected interface '%s'\n", dent->d_name);
3599                 ifname = os_strdup(dent->d_name);
3600                 break;
3601         }
3602         closedir(dir);
3603 #endif /* CONFIG_CTRL_IFACE_UNIX */
3604
3605 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3606         char buf[2048], *pos;
3607         size_t len;
3608         struct wpa_ctrl *ctrl;
3609         int ret;
3610
3611         ctrl = wpa_ctrl_open(NULL);
3612         if (ctrl == NULL)
3613                 return NULL;
3614
3615         len = sizeof(buf) - 1;
3616         ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3617         if (ret >= 0) {
3618                 buf[len] = '\0';
3619                 pos = os_strchr(buf, '\n');
3620                 if (pos)
3621                         *pos = '\0';
3622                 ifname = os_strdup(buf);
3623         }
3624         wpa_ctrl_close(ctrl);
3625 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3626
3627         return ifname;
3628 }
3629
3630
3631 int main(int argc, char *argv[])
3632 {
3633         int warning_displayed = 0;
3634         int c;
3635         int daemonize = 0;
3636         int ret = 0;
3637         const char *global = NULL;
3638
3639         if (os_program_init())
3640                 return -1;
3641
3642         for (;;) {
3643                 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3644                 if (c < 0)
3645                         break;
3646                 switch (c) {
3647                 case 'a':
3648                         action_file = optarg;
3649                         break;
3650                 case 'B':
3651                         daemonize = 1;
3652                         break;
3653                 case 'g':
3654                         global = optarg;
3655                         break;
3656                 case 'G':
3657                         ping_interval = atoi(optarg);
3658                         break;
3659                 case 'h':
3660                         usage();
3661                         return 0;
3662                 case 'v':
3663                         printf("%s\n", wpa_cli_version);
3664                         return 0;
3665                 case 'i':
3666                         os_free(ctrl_ifname);
3667                         ctrl_ifname = os_strdup(optarg);
3668                         break;
3669                 case 'p':
3670                         ctrl_iface_dir = optarg;
3671                         break;
3672                 case 'P':
3673                         pid_file = optarg;
3674                         break;
3675                 default:
3676                         usage();
3677                         return -1;
3678                 }
3679         }
3680
3681         interactive = (argc == optind) && (action_file == NULL);
3682
3683         if (interactive)
3684                 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3685
3686         if (eloop_init())
3687                 return -1;
3688
3689         if (global) {
3690 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3691                 ctrl_conn = wpa_ctrl_open(NULL);
3692 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3693                 ctrl_conn = wpa_ctrl_open(global);
3694 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3695                 if (ctrl_conn == NULL) {
3696                         perror("Failed to connect to wpa_supplicant - "
3697                                "wpa_ctrl_open");
3698                         return -1;
3699                 }
3700         }
3701
3702 #ifndef _WIN32_WCE
3703         signal(SIGINT, wpa_cli_terminate);
3704         signal(SIGTERM, wpa_cli_terminate);
3705 #endif /* _WIN32_WCE */
3706
3707         if (ctrl_ifname == NULL)
3708                 ctrl_ifname = wpa_cli_get_default_ifname();
3709
3710         if (interactive) {
3711                 for (; !global;) {
3712                         if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3713                                 if (warning_displayed)
3714                                         printf("Connection established.\n");
3715                                 break;
3716                         }
3717
3718                         if (!warning_displayed) {
3719                                 printf("Could not connect to wpa_supplicant - "
3720                                        "re-trying\n");
3721                                 warning_displayed = 1;
3722                         }
3723                         os_sleep(1, 0);
3724                         continue;
3725                 }
3726         } else {
3727                 if (!global &&
3728                     wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3729                         perror("Failed to connect to wpa_supplicant - "
3730                                "wpa_ctrl_open");
3731                         return -1;
3732                 }
3733
3734                 if (action_file) {
3735                         if (wpa_ctrl_attach(ctrl_conn) == 0) {
3736                                 wpa_cli_attached = 1;
3737                         } else {
3738                                 printf("Warning: Failed to attach to "
3739                                        "wpa_supplicant.\n");
3740                                 return -1;
3741                         }
3742                 }
3743         }
3744
3745         if (daemonize && os_daemonize(pid_file))
3746                 return -1;
3747
3748         if (interactive)
3749                 wpa_cli_interactive();
3750         else if (action_file)
3751                 wpa_cli_action(ctrl_conn);
3752         else
3753                 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3754
3755         os_free(ctrl_ifname);
3756         eloop_destroy();
3757         wpa_cli_cleanup();
3758
3759         return ret;
3760 }
3761
3762 #else /* CONFIG_CTRL_IFACE */
3763 int main(int argc, char *argv[])
3764 {
3765         printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3766         return -1;
3767 }
3768 #endif /* CONFIG_CTRL_IFACE */