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