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