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