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