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