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