WPS ER: Add preliminary PBC support
[libeap.git] / wpa_supplicant / wpa_cli.c
1 /*
2  * WPA Supplicant - command line interface for wpa_supplicant daemon
3  * Copyright (c) 2004-2009, 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 #ifdef CONFIG_READLINE
23 #include <readline/readline.h>
24 #include <readline/history.h>
25 #endif /* CONFIG_READLINE */
26
27 #include "wpa_ctrl.h"
28 #include "common.h"
29 #include "version.h"
30
31
32 static const char *wpa_cli_version =
33 "wpa_cli v" VERSION_STR "\n"
34 "Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> and contributors";
35
36
37 static const char *wpa_cli_license =
38 "This program is free software. You can distribute it and/or modify it\n"
39 "under the terms of the GNU General Public License version 2.\n"
40 "\n"
41 "Alternatively, this software may be distributed under the terms of the\n"
42 "BSD license. See README and COPYING for more details.\n";
43
44 static const char *wpa_cli_full_license =
45 "This program is free software; you can redistribute it and/or modify\n"
46 "it under the terms of the GNU General Public License version 2 as\n"
47 "published by the Free Software Foundation.\n"
48 "\n"
49 "This program is distributed in the hope that it will be useful,\n"
50 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
51 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
52 "GNU General Public License for more details.\n"
53 "\n"
54 "You should have received a copy of the GNU General Public License\n"
55 "along with this program; if not, write to the Free Software\n"
56 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n"
57 "\n"
58 "Alternatively, this software may be distributed under the terms of the\n"
59 "BSD license.\n"
60 "\n"
61 "Redistribution and use in source and binary forms, with or without\n"
62 "modification, are permitted provided that the following conditions are\n"
63 "met:\n"
64 "\n"
65 "1. Redistributions of source code must retain the above copyright\n"
66 "   notice, this list of conditions and the following disclaimer.\n"
67 "\n"
68 "2. Redistributions in binary form must reproduce the above copyright\n"
69 "   notice, this list of conditions and the following disclaimer in the\n"
70 "   documentation and/or other materials provided with the distribution.\n"
71 "\n"
72 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
73 "   names of its contributors may be used to endorse or promote products\n"
74 "   derived from this software without specific prior written permission.\n"
75 "\n"
76 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
77 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
78 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
79 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
80 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
81 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
82 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
83 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
84 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
85 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
86 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
87 "\n";
88
89 static struct wpa_ctrl *ctrl_conn;
90 static int wpa_cli_quit = 0;
91 static int wpa_cli_attached = 0;
92 static int wpa_cli_connected = 0;
93 static int wpa_cli_last_id = 0;
94 static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
95 static char *ctrl_ifname = NULL;
96 static const char *pid_file = NULL;
97 static const char *action_file = NULL;
98 static int ping_interval = 5;
99
100
101 static void print_help();
102
103
104 static void usage(void)
105 {
106         printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
107                "[-a<action file>] \\\n"
108                "        [-P<pid file>] [-g<global ctrl>] [-G<ping interval>]  "
109                "[command..]\n"
110                "  -h = help (show this usage text)\n"
111                "  -v = shown version information\n"
112                "  -a = run in daemon mode executing the action file based on "
113                "events from\n"
114                "       wpa_supplicant\n"
115                "  -B = run a daemon in the background\n"
116                "  default path: /var/run/wpa_supplicant\n"
117                "  default interface: first interface found in socket path\n");
118         print_help();
119 }
120
121
122 static struct wpa_ctrl * wpa_cli_open_connection(const char *ifname)
123 {
124 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
125         ctrl_conn = wpa_ctrl_open(ifname);
126         return ctrl_conn;
127 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
128         char *cfile;
129         int flen, res;
130
131         if (ifname == NULL)
132                 return NULL;
133
134         flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
135         cfile = os_malloc(flen);
136         if (cfile == NULL)
137                 return NULL;
138         res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
139         if (res < 0 || res >= flen) {
140                 os_free(cfile);
141                 return NULL;
142         }
143
144         ctrl_conn = wpa_ctrl_open(cfile);
145         os_free(cfile);
146         return ctrl_conn;
147 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
148 }
149
150
151 static void wpa_cli_close_connection(void)
152 {
153         if (ctrl_conn == NULL)
154                 return;
155
156         if (wpa_cli_attached) {
157                 wpa_ctrl_detach(ctrl_conn);
158                 wpa_cli_attached = 0;
159         }
160         wpa_ctrl_close(ctrl_conn);
161         ctrl_conn = NULL;
162 }
163
164
165 static void wpa_cli_msg_cb(char *msg, size_t len)
166 {
167         printf("%s\n", msg);
168 }
169
170
171 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
172 {
173         char buf[2048];
174         size_t len;
175         int ret;
176
177         if (ctrl_conn == NULL) {
178                 printf("Not connected to wpa_supplicant - command dropped.\n");
179                 return -1;
180         }
181         len = sizeof(buf) - 1;
182         ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
183                                wpa_cli_msg_cb);
184         if (ret == -2) {
185                 printf("'%s' command timed out.\n", cmd);
186                 return -2;
187         } else if (ret < 0) {
188                 printf("'%s' command failed.\n", cmd);
189                 return -1;
190         }
191         if (print) {
192                 buf[len] = '\0';
193                 printf("%s", buf);
194         }
195         return 0;
196 }
197
198
199 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
200 {
201         return _wpa_ctrl_command(ctrl, cmd, 1);
202 }
203
204
205 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
206 {
207         int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
208         return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
209 }
210
211
212 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
213 {
214         return wpa_ctrl_command(ctrl, "PING");
215 }
216
217
218 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
219 {
220         return wpa_ctrl_command(ctrl, "MIB");
221 }
222
223
224 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
225 {
226         return wpa_ctrl_command(ctrl, "PMKSA");
227 }
228
229
230 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
231 {
232         print_help();
233         return 0;
234 }
235
236
237 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
238 {
239         printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
240         return 0;
241 }
242
243
244 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
245 {
246         wpa_cli_quit = 1;
247         return 0;
248 }
249
250
251 static void wpa_cli_show_variables(void)
252 {
253         printf("set variables:\n"
254                "  EAPOL::heldPeriod (EAPOL state machine held period, "
255                "in seconds)\n"
256                "  EAPOL::authPeriod (EAPOL state machine authentication "
257                "period, in seconds)\n"
258                "  EAPOL::startPeriod (EAPOL state machine start period, in "
259                "seconds)\n"
260                "  EAPOL::maxStart (EAPOL state machine maximum start "
261                "attempts)\n");
262         printf("  dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
263                "seconds)\n"
264                "  dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
265                " threshold\n\tpercentage)\n"
266                "  dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
267                "security\n\tassociation in seconds)\n");
268 }
269
270
271 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
272 {
273         char cmd[256];
274         int res;
275
276         if (argc == 0) {
277                 wpa_cli_show_variables();
278                 return 0;
279         }
280
281         if (argc != 2) {
282                 printf("Invalid SET command: needs two arguments (variable "
283                        "name and value)\n");
284                 return -1;
285         }
286
287         res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
288         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
289                 printf("Too long SET command.\n");
290                 return -1;
291         }
292         return wpa_ctrl_command(ctrl, cmd);
293 }
294
295
296 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
297 {
298         return wpa_ctrl_command(ctrl, "LOGOFF");
299 }
300
301
302 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
303 {
304         return wpa_ctrl_command(ctrl, "LOGON");
305 }
306
307
308 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
309                                    char *argv[])
310 {
311         return wpa_ctrl_command(ctrl, "REASSOCIATE");
312 }
313
314
315 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
316                                        char *argv[])
317 {
318         char cmd[256];
319         int res;
320
321         if (argc != 1) {
322                 printf("Invalid PREAUTH command: needs one argument "
323                        "(BSSID)\n");
324                 return -1;
325         }
326
327         res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
328         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
329                 printf("Too long PREAUTH command.\n");
330                 return -1;
331         }
332         return wpa_ctrl_command(ctrl, cmd);
333 }
334
335
336 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
337 {
338         char cmd[256];
339         int res;
340
341         if (argc != 1) {
342                 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
343                        "value)\n");
344                 return -1;
345         }
346         res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
347         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
348                 printf("Too long AP_SCAN command.\n");
349                 return -1;
350         }
351         return wpa_ctrl_command(ctrl, cmd);
352 }
353
354
355 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
356                                 char *argv[])
357 {
358         char cmd[256];
359         int res;
360
361         if (argc != 1) {
362                 printf("Invalid STKSTART command: needs one argument "
363                        "(Peer STA MAC address)\n");
364                 return -1;
365         }
366
367         res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
368         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
369                 printf("Too long STKSTART command.\n");
370                 return -1;
371         }
372         return wpa_ctrl_command(ctrl, cmd);
373 }
374
375
376 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
377 {
378         char cmd[256];
379         int res;
380
381         if (argc != 1) {
382                 printf("Invalid FT_DS command: needs one argument "
383                        "(Target AP MAC address)\n");
384                 return -1;
385         }
386
387         res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
388         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
389                 printf("Too long FT_DS command.\n");
390                 return -1;
391         }
392         return wpa_ctrl_command(ctrl, cmd);
393 }
394
395
396 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
397 {
398         char cmd[256];
399         int res;
400
401         if (argc == 0) {
402                 /* Any BSSID */
403                 return wpa_ctrl_command(ctrl, "WPS_PBC");
404         }
405
406         /* Specific BSSID */
407         res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
408         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
409                 printf("Too long WPS_PBC command.\n");
410                 return -1;
411         }
412         return wpa_ctrl_command(ctrl, cmd);
413 }
414
415
416 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
417 {
418         char cmd[256];
419         int res;
420
421         if (argc == 0) {
422                 printf("Invalid WPS_PIN command: need one or two arguments:\n"
423                        "- BSSID: use 'any' to select any\n"
424                        "- PIN: optional, used only with devices that have no "
425                        "display\n");
426                 return -1;
427         }
428
429         if (argc == 1) {
430                 /* Use dynamically generated PIN (returned as reply) */
431                 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
432                 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
433                         printf("Too long WPS_PIN command.\n");
434                         return -1;
435                 }
436                 return wpa_ctrl_command(ctrl, cmd);
437         }
438
439         /* Use hardcoded PIN from a label */
440         res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
441         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
442                 printf("Too long WPS_PIN command.\n");
443                 return -1;
444         }
445         return wpa_ctrl_command(ctrl, cmd);
446 }
447
448
449 #ifdef CONFIG_WPS_OOB
450 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
451 {
452         char cmd[256];
453         int res;
454
455         if (argc != 3 && argc != 4) {
456                 printf("Invalid WPS_OOB command: need three or four "
457                        "arguments:\n"
458                        "- DEV_TYPE: use 'ufd' or 'nfc'\n"
459                        "- PATH: path of OOB device like '/mnt'\n"
460                        "- METHOD: OOB method 'pin-e' or 'pin-r', "
461                        "'cred'\n"
462                        "- DEV_NAME: (only for NFC) device name like "
463                        "'pn531'\n");
464                 return -1;
465         }
466
467         if (argc == 3)
468                 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
469                                   argv[0], argv[1], argv[2]);
470         else
471                 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
472                                   argv[0], argv[1], argv[2], argv[3]);
473         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
474                 printf("Too long WPS_OOB command.\n");
475                 return -1;
476         }
477         return wpa_ctrl_command(ctrl, cmd);
478 }
479 #endif /* CONFIG_WPS_OOB */
480
481
482 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
483 {
484         char cmd[256];
485         int res;
486
487         if (argc == 2)
488                 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
489                                   argv[0], argv[1]);
490         else if (argc == 6) {
491                 char ssid_hex[2 * 32 + 1];
492                 char key_hex[2 * 64 + 1];
493                 int i;
494
495                 ssid_hex[0] = '\0';
496                 for (i = 0; i < 32; i++) {
497                         if (argv[2][i] == '\0')
498                                 break;
499                         os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
500                 }
501
502                 key_hex[0] = '\0';
503                 for (i = 0; i < 64; i++) {
504                         if (argv[5][i] == '\0')
505                                 break;
506                         os_snprintf(&key_hex[i * 2], 3, "%02x", argv[5][i]);
507                 }
508
509                 res = os_snprintf(cmd, sizeof(cmd),
510                                   "WPS_REG %s %s %s %s %s %s",
511                                   argv[0], argv[1], ssid_hex, argv[3], argv[4],
512                                   key_hex);
513         } else {
514                 printf("Invalid WPS_REG command: need two arguments:\n"
515                        "- BSSID: use 'any' to select any\n"
516                        "- AP PIN\n");
517                 printf("Alternatively, six arguments can be used to "
518                        "reconfigure the AP:\n"
519                        "- BSSID: use 'any' to select any\n"
520                        "- AP PIN\n"
521                        "- new SSID\n"
522                        "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
523                        "- new encr (NONE, WEP, TKIP, CCMP)\n"
524                        "- new key\n");
525                 return -1;
526         }
527
528         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
529                 printf("Too long WPS_REG command.\n");
530                 return -1;
531         }
532         return wpa_ctrl_command(ctrl, cmd);
533 }
534
535
536 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
537                                     char *argv[])
538 {
539         return wpa_ctrl_command(ctrl, "WPS_ER_START");
540
541 }
542
543
544 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
545                                    char *argv[])
546 {
547         return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
548
549 }
550
551
552 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
553                                   char *argv[])
554 {
555         char cmd[256];
556         int res;
557
558         if (argc != 2) {
559                 printf("Invalid WPS_ER_PIN command: need two arguments:\n"
560                        "- UUID: use 'any' to select any\n"
561                        "- PIN: Enrollee PIN\n");
562                 return -1;
563         }
564
565         res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
566                           argv[0], argv[1]);
567         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
568                 printf("Too long WPS_ER_PIN command.\n");
569                 return -1;
570         }
571         return wpa_ctrl_command(ctrl, cmd);
572 }
573
574
575 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
576                                   char *argv[])
577 {
578         char cmd[256];
579         int res;
580
581         if (argc != 1) {
582                 printf("Invalid WPS_ER_PBC command: need one argument:\n"
583                        "- UUID: Specify the Enrollee\n");
584                 return -1;
585         }
586
587         res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
588                           argv[0]);
589         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
590                 printf("Too long WPS_ER_PBC command.\n");
591                 return -1;
592         }
593         return wpa_ctrl_command(ctrl, cmd);
594 }
595
596
597 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
598 {
599         char cmd[256];
600         int res;
601
602         if (argc != 1) {
603                 printf("Invalid IBSS_RSN command: needs one argument "
604                        "(Peer STA MAC address)\n");
605                 return -1;
606         }
607
608         res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
609         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
610                 printf("Too long IBSS_RSN command.\n");
611                 return -1;
612         }
613         return wpa_ctrl_command(ctrl, cmd);
614 }
615
616
617 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
618 {
619         char cmd[256];
620         int res;
621
622         if (argc != 1) {
623                 printf("Invalid LEVEL command: needs one argument (debug "
624                        "level)\n");
625                 return -1;
626         }
627         res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
628         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
629                 printf("Too long LEVEL command.\n");
630                 return -1;
631         }
632         return wpa_ctrl_command(ctrl, cmd);
633 }
634
635
636 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
637 {
638         char cmd[256], *pos, *end;
639         int i, ret;
640
641         if (argc < 2) {
642                 printf("Invalid IDENTITY command: needs two arguments "
643                        "(network id and identity)\n");
644                 return -1;
645         }
646
647         end = cmd + sizeof(cmd);
648         pos = cmd;
649         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
650                           argv[0], argv[1]);
651         if (ret < 0 || ret >= end - pos) {
652                 printf("Too long IDENTITY command.\n");
653                 return -1;
654         }
655         pos += ret;
656         for (i = 2; i < argc; i++) {
657                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
658                 if (ret < 0 || ret >= end - pos) {
659                         printf("Too long IDENTITY command.\n");
660                         return -1;
661                 }
662                 pos += ret;
663         }
664
665         return wpa_ctrl_command(ctrl, cmd);
666 }
667
668
669 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
670 {
671         char cmd[256], *pos, *end;
672         int i, ret;
673
674         if (argc < 2) {
675                 printf("Invalid PASSWORD command: needs two arguments "
676                        "(network id and password)\n");
677                 return -1;
678         }
679
680         end = cmd + sizeof(cmd);
681         pos = cmd;
682         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
683                           argv[0], argv[1]);
684         if (ret < 0 || ret >= end - pos) {
685                 printf("Too long PASSWORD command.\n");
686                 return -1;
687         }
688         pos += ret;
689         for (i = 2; i < argc; i++) {
690                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
691                 if (ret < 0 || ret >= end - pos) {
692                         printf("Too long PASSWORD command.\n");
693                         return -1;
694                 }
695                 pos += ret;
696         }
697
698         return wpa_ctrl_command(ctrl, cmd);
699 }
700
701
702 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
703                                     char *argv[])
704 {
705         char cmd[256], *pos, *end;
706         int i, ret;
707
708         if (argc < 2) {
709                 printf("Invalid NEW_PASSWORD command: needs two arguments "
710                        "(network id and password)\n");
711                 return -1;
712         }
713
714         end = cmd + sizeof(cmd);
715         pos = cmd;
716         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
717                           argv[0], argv[1]);
718         if (ret < 0 || ret >= end - pos) {
719                 printf("Too long NEW_PASSWORD command.\n");
720                 return -1;
721         }
722         pos += ret;
723         for (i = 2; i < argc; i++) {
724                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
725                 if (ret < 0 || ret >= end - pos) {
726                         printf("Too long NEW_PASSWORD command.\n");
727                         return -1;
728                 }
729                 pos += ret;
730         }
731
732         return wpa_ctrl_command(ctrl, cmd);
733 }
734
735
736 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
737 {
738         char cmd[256], *pos, *end;
739         int i, ret;
740
741         if (argc < 2) {
742                 printf("Invalid PIN command: needs two arguments "
743                        "(network id and pin)\n");
744                 return -1;
745         }
746
747         end = cmd + sizeof(cmd);
748         pos = cmd;
749         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
750                           argv[0], argv[1]);
751         if (ret < 0 || ret >= end - pos) {
752                 printf("Too long PIN command.\n");
753                 return -1;
754         }
755         pos += ret;
756         for (i = 2; i < argc; i++) {
757                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
758                 if (ret < 0 || ret >= end - pos) {
759                         printf("Too long PIN command.\n");
760                         return -1;
761                 }
762                 pos += ret;
763         }
764         return wpa_ctrl_command(ctrl, cmd);
765 }
766
767
768 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
769 {
770         char cmd[256], *pos, *end;
771         int i, ret;
772
773         if (argc < 2) {
774                 printf("Invalid OTP command: needs two arguments (network "
775                        "id and password)\n");
776                 return -1;
777         }
778
779         end = cmd + sizeof(cmd);
780         pos = cmd;
781         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
782                           argv[0], argv[1]);
783         if (ret < 0 || ret >= end - pos) {
784                 printf("Too long OTP command.\n");
785                 return -1;
786         }
787         pos += ret;
788         for (i = 2; i < argc; i++) {
789                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
790                 if (ret < 0 || ret >= end - pos) {
791                         printf("Too long OTP command.\n");
792                         return -1;
793                 }
794                 pos += ret;
795         }
796
797         return wpa_ctrl_command(ctrl, cmd);
798 }
799
800
801 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
802                                   char *argv[])
803 {
804         char cmd[256], *pos, *end;
805         int i, ret;
806
807         if (argc < 2) {
808                 printf("Invalid PASSPHRASE command: needs two arguments "
809                        "(network id and passphrase)\n");
810                 return -1;
811         }
812
813         end = cmd + sizeof(cmd);
814         pos = cmd;
815         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
816                           argv[0], argv[1]);
817         if (ret < 0 || ret >= end - pos) {
818                 printf("Too long PASSPHRASE command.\n");
819                 return -1;
820         }
821         pos += ret;
822         for (i = 2; i < argc; i++) {
823                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
824                 if (ret < 0 || ret >= end - pos) {
825                         printf("Too long PASSPHRASE command.\n");
826                         return -1;
827                 }
828                 pos += ret;
829         }
830
831         return wpa_ctrl_command(ctrl, cmd);
832 }
833
834
835 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
836 {
837         char cmd[256], *pos, *end;
838         int i, ret;
839
840         if (argc < 2) {
841                 printf("Invalid BSSID command: needs two arguments (network "
842                        "id and BSSID)\n");
843                 return -1;
844         }
845
846         end = cmd + sizeof(cmd);
847         pos = cmd;
848         ret = os_snprintf(pos, end - pos, "BSSID");
849         if (ret < 0 || ret >= end - pos) {
850                 printf("Too long BSSID command.\n");
851                 return -1;
852         }
853         pos += ret;
854         for (i = 0; i < argc; i++) {
855                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
856                 if (ret < 0 || ret >= end - pos) {
857                         printf("Too long BSSID command.\n");
858                         return -1;
859                 }
860                 pos += ret;
861         }
862
863         return wpa_ctrl_command(ctrl, cmd);
864 }
865
866
867 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
868                                      char *argv[])
869 {
870         return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
871 }
872
873
874 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
875                                       char *argv[])
876 {
877         char cmd[32];
878         int res;
879
880         if (argc < 1) {
881                 printf("Invalid SELECT_NETWORK command: needs one argument "
882                        "(network id)\n");
883                 return -1;
884         }
885
886         res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
887         if (res < 0 || (size_t) res >= sizeof(cmd))
888                 return -1;
889         cmd[sizeof(cmd) - 1] = '\0';
890
891         return wpa_ctrl_command(ctrl, cmd);
892 }
893
894
895 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
896                                       char *argv[])
897 {
898         char cmd[32];
899         int res;
900
901         if (argc < 1) {
902                 printf("Invalid ENABLE_NETWORK command: needs one argument "
903                        "(network id)\n");
904                 return -1;
905         }
906
907         res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
908         if (res < 0 || (size_t) res >= sizeof(cmd))
909                 return -1;
910         cmd[sizeof(cmd) - 1] = '\0';
911
912         return wpa_ctrl_command(ctrl, cmd);
913 }
914
915
916 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
917                                        char *argv[])
918 {
919         char cmd[32];
920         int res;
921
922         if (argc < 1) {
923                 printf("Invalid DISABLE_NETWORK command: needs one argument "
924                        "(network id)\n");
925                 return -1;
926         }
927
928         res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
929         if (res < 0 || (size_t) res >= sizeof(cmd))
930                 return -1;
931         cmd[sizeof(cmd) - 1] = '\0';
932
933         return wpa_ctrl_command(ctrl, cmd);
934 }
935
936
937 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
938                                    char *argv[])
939 {
940         return wpa_ctrl_command(ctrl, "ADD_NETWORK");
941 }
942
943
944 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
945                                       char *argv[])
946 {
947         char cmd[32];
948         int res;
949
950         if (argc < 1) {
951                 printf("Invalid REMOVE_NETWORK command: needs one argument "
952                        "(network id)\n");
953                 return -1;
954         }
955
956         res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
957         if (res < 0 || (size_t) res >= sizeof(cmd))
958                 return -1;
959         cmd[sizeof(cmd) - 1] = '\0';
960
961         return wpa_ctrl_command(ctrl, cmd);
962 }
963
964
965 static void wpa_cli_show_network_variables(void)
966 {
967         printf("set_network variables:\n"
968                "  ssid (network name, SSID)\n"
969                "  psk (WPA passphrase or pre-shared key)\n"
970                "  key_mgmt (key management protocol)\n"
971                "  identity (EAP identity)\n"
972                "  password (EAP password)\n"
973                "  ...\n"
974                "\n"
975                "Note: Values are entered in the same format as the "
976                "configuration file is using,\n"
977                "i.e., strings values need to be inside double quotation "
978                "marks.\n"
979                "For example: set_network 1 ssid \"network name\"\n"
980                "\n"
981                "Please see wpa_supplicant.conf documentation for full list "
982                "of\navailable variables.\n");
983 }
984
985
986 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
987                                    char *argv[])
988 {
989         char cmd[256];
990         int res;
991
992         if (argc == 0) {
993                 wpa_cli_show_network_variables();
994                 return 0;
995         }
996
997         if (argc != 3) {
998                 printf("Invalid SET_NETWORK command: needs three arguments\n"
999                        "(network id, variable name, and value)\n");
1000                 return -1;
1001         }
1002
1003         res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1004                           argv[0], argv[1], argv[2]);
1005         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1006                 printf("Too long SET_NETWORK command.\n");
1007                 return -1;
1008         }
1009         return wpa_ctrl_command(ctrl, cmd);
1010 }
1011
1012
1013 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1014                                    char *argv[])
1015 {
1016         char cmd[256];
1017         int res;
1018
1019         if (argc == 0) {
1020                 wpa_cli_show_network_variables();
1021                 return 0;
1022         }
1023
1024         if (argc != 2) {
1025                 printf("Invalid GET_NETWORK command: needs two arguments\n"
1026                        "(network id and variable name)\n");
1027                 return -1;
1028         }
1029
1030         res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1031                           argv[0], argv[1]);
1032         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1033                 printf("Too long GET_NETWORK command.\n");
1034                 return -1;
1035         }
1036         return wpa_ctrl_command(ctrl, cmd);
1037 }
1038
1039
1040 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1041                                   char *argv[])
1042 {
1043         return wpa_ctrl_command(ctrl, "DISCONNECT");
1044 }
1045
1046
1047 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1048                                   char *argv[])
1049 {
1050         return wpa_ctrl_command(ctrl, "RECONNECT");
1051 }
1052
1053
1054 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1055                                    char *argv[])
1056 {
1057         return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1058 }
1059
1060
1061 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1062 {
1063         return wpa_ctrl_command(ctrl, "SCAN");
1064 }
1065
1066
1067 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1068                                     char *argv[])
1069 {
1070         return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1071 }
1072
1073
1074 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1075 {
1076         char cmd[64];
1077         int res;
1078
1079         if (argc != 1) {
1080                 printf("Invalid BSS command: need one argument (index or "
1081                        "BSSID)\n");
1082                 return -1;
1083         }
1084
1085         res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1086         if (res < 0 || (size_t) res >= sizeof(cmd))
1087                 return -1;
1088         cmd[sizeof(cmd) - 1] = '\0';
1089
1090         return wpa_ctrl_command(ctrl, cmd);
1091 }
1092
1093
1094 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1095                                       char *argv[])
1096 {
1097         char cmd[64];
1098         int res;
1099
1100         if (argc < 1 || argc > 2) {
1101                 printf("Invalid GET_CAPABILITY command: need either one or "
1102                        "two arguments\n");
1103                 return -1;
1104         }
1105
1106         if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1107                 printf("Invalid GET_CAPABILITY command: second argument, "
1108                        "if any, must be 'strict'\n");
1109                 return -1;
1110         }
1111
1112         res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1113                           (argc == 2) ? " strict" : "");
1114         if (res < 0 || (size_t) res >= sizeof(cmd))
1115                 return -1;
1116         cmd[sizeof(cmd) - 1] = '\0';
1117
1118         return wpa_ctrl_command(ctrl, cmd);
1119 }
1120
1121
1122 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1123 {
1124         printf("Available interfaces:\n");
1125         return wpa_ctrl_command(ctrl, "INTERFACES");
1126 }
1127
1128
1129 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1130 {
1131         if (argc < 1) {
1132                 wpa_cli_list_interfaces(ctrl);
1133                 return 0;
1134         }
1135
1136         wpa_cli_close_connection();
1137         os_free(ctrl_ifname);
1138         ctrl_ifname = os_strdup(argv[0]);
1139
1140         if (wpa_cli_open_connection(ctrl_ifname)) {
1141                 printf("Connected to interface '%s.\n", ctrl_ifname);
1142                 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1143                         wpa_cli_attached = 1;
1144                 } else {
1145                         printf("Warning: Failed to attach to "
1146                                "wpa_supplicant.\n");
1147                 }
1148         } else {
1149                 printf("Could not connect to interface '%s' - re-trying\n",
1150                        ctrl_ifname);
1151         }
1152         return 0;
1153 }
1154
1155
1156 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1157                                    char *argv[])
1158 {
1159         return wpa_ctrl_command(ctrl, "RECONFIGURE");
1160 }
1161
1162
1163 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1164                                  char *argv[])
1165 {
1166         return wpa_ctrl_command(ctrl, "TERMINATE");
1167 }
1168
1169
1170 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1171                                      char *argv[])
1172 {
1173         char cmd[256];
1174         int res;
1175
1176         if (argc < 1) {
1177                 printf("Invalid INTERFACE_ADD command: needs at least one "
1178                        "argument (interface name)\n"
1179                        "All arguments: ifname confname driver ctrl_interface "
1180                        "driver_param bridge_name\n");
1181                 return -1;
1182         }
1183
1184         /*
1185          * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1186          * <driver_param>TAB<bridge_name>
1187          */
1188         res = os_snprintf(cmd, sizeof(cmd),
1189                           "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1190                           argv[0],
1191                           argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1192                           argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1193                           argc > 5 ? argv[5] : "");
1194         if (res < 0 || (size_t) res >= sizeof(cmd))
1195                 return -1;
1196         cmd[sizeof(cmd) - 1] = '\0';
1197         return wpa_ctrl_command(ctrl, cmd);
1198 }
1199
1200
1201 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1202                                         char *argv[])
1203 {
1204         char cmd[128];
1205         int res;
1206
1207         if (argc != 1) {
1208                 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1209                        "(interface name)\n");
1210                 return -1;
1211         }
1212
1213         res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1214         if (res < 0 || (size_t) res >= sizeof(cmd))
1215                 return -1;
1216         cmd[sizeof(cmd) - 1] = '\0';
1217         return wpa_ctrl_command(ctrl, cmd);
1218 }
1219
1220
1221 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1222                                       char *argv[])
1223 {
1224         return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1225 }
1226
1227
1228 #ifdef CONFIG_AP
1229 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1230 {
1231         char buf[64];
1232         if (argc != 1) {
1233                 printf("Invalid 'sta' command - exactly one argument, STA "
1234                        "address, is required.\n");
1235                 return -1;
1236         }
1237         snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1238         return wpa_ctrl_command(ctrl, buf);
1239 }
1240
1241
1242 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1243                                 char *addr, size_t addr_len)
1244 {
1245         char buf[4096], *pos;
1246         size_t len;
1247         int ret;
1248
1249         if (ctrl_conn == NULL) {
1250                 printf("Not connected to hostapd - command dropped.\n");
1251                 return -1;
1252         }
1253         len = sizeof(buf) - 1;
1254         ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1255                                wpa_cli_msg_cb);
1256         if (ret == -2) {
1257                 printf("'%s' command timed out.\n", cmd);
1258                 return -2;
1259         } else if (ret < 0) {
1260                 printf("'%s' command failed.\n", cmd);
1261                 return -1;
1262         }
1263
1264         buf[len] = '\0';
1265         if (memcmp(buf, "FAIL", 4) == 0)
1266                 return -1;
1267         printf("%s", buf);
1268
1269         pos = buf;
1270         while (*pos != '\0' && *pos != '\n')
1271                 pos++;
1272         *pos = '\0';
1273         os_strlcpy(addr, buf, addr_len);
1274         return 0;
1275 }
1276
1277
1278 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1279 {
1280         char addr[32], cmd[64];
1281
1282         if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1283                 return 0;
1284         do {
1285                 snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1286         } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1287
1288         return -1;
1289 }
1290 #endif /* CONFIG_AP */
1291
1292
1293 enum wpa_cli_cmd_flags {
1294         cli_cmd_flag_none               = 0x00,
1295         cli_cmd_flag_sensitive          = 0x01
1296 };
1297
1298 struct wpa_cli_cmd {
1299         const char *cmd;
1300         int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
1301         enum wpa_cli_cmd_flags flags;
1302         const char *usage;
1303 };
1304
1305 static struct wpa_cli_cmd wpa_cli_commands[] = {
1306         { "status", wpa_cli_cmd_status,
1307           cli_cmd_flag_none,
1308           "[verbose] = get current WPA/EAPOL/EAP status" },
1309         { "ping", wpa_cli_cmd_ping,
1310           cli_cmd_flag_none,
1311           "= pings wpa_supplicant" },
1312         { "mib", wpa_cli_cmd_mib,
1313           cli_cmd_flag_none,
1314           "= get MIB variables (dot1x, dot11)" },
1315         { "help", wpa_cli_cmd_help,
1316           cli_cmd_flag_none,
1317           "= show this usage help" },
1318         { "interface", wpa_cli_cmd_interface,
1319           cli_cmd_flag_none,
1320           "[ifname] = show interfaces/select interface" },
1321         { "level", wpa_cli_cmd_level,
1322           cli_cmd_flag_none,
1323           "<debug level> = change debug level" },
1324         { "license", wpa_cli_cmd_license,
1325           cli_cmd_flag_none,
1326           "= show full wpa_cli license" },
1327         { "quit", wpa_cli_cmd_quit,
1328           cli_cmd_flag_none,
1329           "= exit wpa_cli" },
1330         { "set", wpa_cli_cmd_set,
1331           cli_cmd_flag_none,
1332           "= set variables (shows list of variables when run without "
1333           "arguments)" },
1334         { "logon", wpa_cli_cmd_logon,
1335           cli_cmd_flag_none,
1336           "= IEEE 802.1X EAPOL state machine logon" },
1337         { "logoff", wpa_cli_cmd_logoff,
1338           cli_cmd_flag_none,
1339           "= IEEE 802.1X EAPOL state machine logoff" },
1340         { "pmksa", wpa_cli_cmd_pmksa,
1341           cli_cmd_flag_none,
1342           "= show PMKSA cache" },
1343         { "reassociate", wpa_cli_cmd_reassociate,
1344           cli_cmd_flag_none,
1345           "= force reassociation" },
1346         { "preauthenticate", wpa_cli_cmd_preauthenticate,
1347           cli_cmd_flag_none,
1348           "<BSSID> = force preauthentication" },
1349         { "identity", wpa_cli_cmd_identity,
1350           cli_cmd_flag_none,
1351           "<network id> <identity> = configure identity for an SSID" },
1352         { "password", wpa_cli_cmd_password,
1353           cli_cmd_flag_sensitive,
1354           "<network id> <password> = configure password for an SSID" },
1355         { "new_password", wpa_cli_cmd_new_password,
1356           cli_cmd_flag_sensitive,
1357           "<network id> <password> = change password for an SSID" },
1358         { "pin", wpa_cli_cmd_pin,
1359           cli_cmd_flag_sensitive,
1360           "<network id> <pin> = configure pin for an SSID" },
1361         { "otp", wpa_cli_cmd_otp,
1362           cli_cmd_flag_sensitive,
1363           "<network id> <password> = configure one-time-password for an SSID"
1364         },
1365         { "passphrase", wpa_cli_cmd_passphrase,
1366           cli_cmd_flag_sensitive,
1367           "<network id> <passphrase> = configure private key passphrase\n"
1368           "  for an SSID" },
1369         { "bssid", wpa_cli_cmd_bssid,
1370           cli_cmd_flag_none,
1371           "<network id> <BSSID> = set preferred BSSID for an SSID" },
1372         { "list_networks", wpa_cli_cmd_list_networks,
1373           cli_cmd_flag_none,
1374           "= list configured networks" },
1375         { "select_network", wpa_cli_cmd_select_network,
1376           cli_cmd_flag_none,
1377           "<network id> = select a network (disable others)" },
1378         { "enable_network", wpa_cli_cmd_enable_network,
1379           cli_cmd_flag_none,
1380           "<network id> = enable a network" },
1381         { "disable_network", wpa_cli_cmd_disable_network,
1382           cli_cmd_flag_none,
1383           "<network id> = disable a network" },
1384         { "add_network", wpa_cli_cmd_add_network,
1385           cli_cmd_flag_none,
1386           "= add a network" },
1387         { "remove_network", wpa_cli_cmd_remove_network,
1388           cli_cmd_flag_none,
1389           "<network id> = remove a network" },
1390         { "set_network", wpa_cli_cmd_set_network,
1391           cli_cmd_flag_sensitive,
1392           "<network id> <variable> <value> = set network variables (shows\n"
1393           "  list of variables when run without arguments)" },
1394         { "get_network", wpa_cli_cmd_get_network,
1395           cli_cmd_flag_none,
1396           "<network id> <variable> = get network variables" },
1397         { "save_config", wpa_cli_cmd_save_config,
1398           cli_cmd_flag_none,
1399           "= save the current configuration" },
1400         { "disconnect", wpa_cli_cmd_disconnect,
1401           cli_cmd_flag_none,
1402           "= disconnect and wait for reassociate/reconnect command before\n"
1403           "  connecting" },
1404         { "reconnect", wpa_cli_cmd_reconnect,
1405           cli_cmd_flag_none,
1406           "= like reassociate, but only takes effect if already disconnected"
1407         },
1408         { "scan", wpa_cli_cmd_scan,
1409           cli_cmd_flag_none,
1410           "= request new BSS scan" },
1411         { "scan_results", wpa_cli_cmd_scan_results,
1412           cli_cmd_flag_none,
1413           "= get latest scan results" },
1414         { "bss", wpa_cli_cmd_bss,
1415           cli_cmd_flag_none,
1416           "<<idx> | <bssid>> = get detailed scan result info" },
1417         { "get_capability", wpa_cli_cmd_get_capability,
1418           cli_cmd_flag_none,
1419           "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
1420         { "reconfigure", wpa_cli_cmd_reconfigure,
1421           cli_cmd_flag_none,
1422           "= force wpa_supplicant to re-read its configuration file" },
1423         { "terminate", wpa_cli_cmd_terminate,
1424           cli_cmd_flag_none,
1425           "= terminate wpa_supplicant" },
1426         { "interface_add", wpa_cli_cmd_interface_add,
1427           cli_cmd_flag_none,
1428           "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
1429           "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
1430           "  are optional" },
1431         { "interface_remove", wpa_cli_cmd_interface_remove,
1432           cli_cmd_flag_none,
1433           "<ifname> = removes the interface" },
1434         { "interface_list", wpa_cli_cmd_interface_list,
1435           cli_cmd_flag_none,
1436           "= list available interfaces" },
1437         { "ap_scan", wpa_cli_cmd_ap_scan,
1438           cli_cmd_flag_none,
1439           "<value> = set ap_scan parameter" },
1440         { "stkstart", wpa_cli_cmd_stkstart,
1441           cli_cmd_flag_none,
1442           "<addr> = request STK negotiation with <addr>" },
1443         { "ft_ds", wpa_cli_cmd_ft_ds,
1444           cli_cmd_flag_none,
1445           "<addr> = request over-the-DS FT with <addr>" },
1446         { "wps_pbc", wpa_cli_cmd_wps_pbc,
1447           cli_cmd_flag_none,
1448           "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
1449         { "wps_pin", wpa_cli_cmd_wps_pin,
1450           cli_cmd_flag_sensitive,
1451           "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
1452           "hardcoded)" },
1453 #ifdef CONFIG_WPS_OOB
1454         { "wps_oob", wpa_cli_cmd_wps_oob,
1455           cli_cmd_flag_sensitive,
1456           "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
1457 #endif /* CONFIG_WPS_OOB */
1458         { "wps_reg", wpa_cli_cmd_wps_reg,
1459           cli_cmd_flag_sensitive,
1460           "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
1461         { "wps_er_start", wpa_cli_cmd_wps_er_start,
1462           cli_cmd_flag_none,
1463           "= start Wi-Fi Protected Setup External Registrar" },
1464         { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
1465           cli_cmd_flag_none,
1466           "= stop Wi-Fi Protected Setup External Registrar" },
1467         { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
1468           cli_cmd_flag_sensitive,
1469           "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
1470         { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
1471           cli_cmd_flag_none,
1472           "<UUID> = accept an Enrollee PBC using External Registrar" },
1473         { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
1474           cli_cmd_flag_none,
1475           "<addr> = request RSN authentication with <addr> in IBSS" },
1476 #ifdef CONFIG_AP
1477         { "sta", wpa_cli_cmd_sta,
1478           cli_cmd_flag_none,
1479           "<addr> = get information about an associated station (AP)" },
1480         { "all_sta", wpa_cli_cmd_all_sta,
1481           cli_cmd_flag_none,
1482           "= get information about all associated stations (AP)" },
1483 #endif /* CONFIG_AP */
1484         { NULL, NULL, cli_cmd_flag_none, NULL }
1485 };
1486
1487
1488 /*
1489  * Prints command usage, lines are padded with the specified string.
1490  */
1491 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
1492 {
1493         char c;
1494         size_t n;
1495
1496         printf("%s%s ", pad, cmd->cmd);
1497         for (n = 0; (c = cmd->usage[n]); n++) {
1498                 printf("%c", c);
1499                 if (c == '\n')
1500                         printf("%s", pad);
1501         }
1502         printf("\n");
1503 }
1504
1505
1506 static void print_help(void)
1507 {
1508         int n;
1509         printf("commands:\n");
1510         for (n = 0; wpa_cli_commands[n].cmd; n++)
1511                 print_cmd_help(&wpa_cli_commands[n], "  ");
1512 }
1513
1514
1515 #ifdef CONFIG_READLINE
1516 static int cmd_has_sensitive_data(const char *cmd)
1517 {
1518         const char *c, *delim;
1519         int n;
1520         size_t len;
1521
1522         delim = os_strchr(cmd, ' ');
1523         if (delim)
1524                 len = delim - cmd;
1525         else
1526                 len = os_strlen(cmd);
1527
1528         for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
1529                 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
1530                         return (wpa_cli_commands[n].flags &
1531                                 cli_cmd_flag_sensitive);
1532         }
1533         return 0;
1534 }
1535 #endif /* CONFIG_READLINE */
1536
1537
1538 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1539 {
1540         struct wpa_cli_cmd *cmd, *match = NULL;
1541         int count;
1542         int ret = 0;
1543
1544         count = 0;
1545         cmd = wpa_cli_commands;
1546         while (cmd->cmd) {
1547                 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1548                 {
1549                         match = cmd;
1550                         if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1551                                 /* we have an exact match */
1552                                 count = 1;
1553                                 break;
1554                         }
1555                         count++;
1556                 }
1557                 cmd++;
1558         }
1559
1560         if (count > 1) {
1561                 printf("Ambiguous command '%s'; possible commands:", argv[0]);
1562                 cmd = wpa_cli_commands;
1563                 while (cmd->cmd) {
1564                         if (os_strncasecmp(cmd->cmd, argv[0],
1565                                            os_strlen(argv[0])) == 0) {
1566                                 printf(" %s", cmd->cmd);
1567                         }
1568                         cmd++;
1569                 }
1570                 printf("\n");
1571                 ret = 1;
1572         } else if (count == 0) {
1573                 printf("Unknown command '%s'\n", argv[0]);
1574                 ret = 1;
1575         } else {
1576                 ret = match->handler(ctrl, argc - 1, &argv[1]);
1577         }
1578
1579         return ret;
1580 }
1581
1582
1583 static int str_match(const char *a, const char *b)
1584 {
1585         return os_strncmp(a, b, os_strlen(b)) == 0;
1586 }
1587
1588
1589 static int wpa_cli_exec(const char *program, const char *arg1,
1590                         const char *arg2)
1591 {
1592         char *cmd;
1593         size_t len;
1594         int res;
1595         int ret = 0;
1596
1597         len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1598         cmd = os_malloc(len);
1599         if (cmd == NULL)
1600                 return -1;
1601         res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1602         if (res < 0 || (size_t) res >= len) {
1603                 os_free(cmd);
1604                 return -1;
1605         }
1606         cmd[len - 1] = '\0';
1607 #ifndef _WIN32_WCE
1608         if (system(cmd) < 0)
1609                 ret = -1;
1610 #endif /* _WIN32_WCE */
1611         os_free(cmd);
1612
1613         return ret;
1614 }
1615
1616
1617 static void wpa_cli_action_process(const char *msg)
1618 {
1619         const char *pos;
1620         char *copy = NULL, *id, *pos2;
1621
1622         pos = msg;
1623         if (*pos == '<') {
1624                 /* skip priority */
1625                 pos = os_strchr(pos, '>');
1626                 if (pos)
1627                         pos++;
1628                 else
1629                         pos = msg;
1630         }
1631
1632         if (str_match(pos, WPA_EVENT_CONNECTED)) {
1633                 int new_id = -1;
1634                 os_unsetenv("WPA_ID");
1635                 os_unsetenv("WPA_ID_STR");
1636                 os_unsetenv("WPA_CTRL_DIR");
1637
1638                 pos = os_strstr(pos, "[id=");
1639                 if (pos)
1640                         copy = os_strdup(pos + 4);
1641
1642                 if (copy) {
1643                         pos2 = id = copy;
1644                         while (*pos2 && *pos2 != ' ')
1645                                 pos2++;
1646                         *pos2++ = '\0';
1647                         new_id = atoi(id);
1648                         os_setenv("WPA_ID", id, 1);
1649                         while (*pos2 && *pos2 != '=')
1650                                 pos2++;
1651                         if (*pos2 == '=')
1652                                 pos2++;
1653                         id = pos2;
1654                         while (*pos2 && *pos2 != ']')
1655                                 pos2++;
1656                         *pos2 = '\0';
1657                         os_setenv("WPA_ID_STR", id, 1);
1658                         os_free(copy);
1659                 }
1660
1661                 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
1662
1663                 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
1664                         wpa_cli_connected = 1;
1665                         wpa_cli_last_id = new_id;
1666                         wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
1667                 }
1668         } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
1669                 if (wpa_cli_connected) {
1670                         wpa_cli_connected = 0;
1671                         wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
1672                 }
1673         } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
1674                 printf("wpa_supplicant is terminating - stop monitoring\n");
1675                 wpa_cli_quit = 1;
1676         }
1677 }
1678
1679
1680 #ifndef CONFIG_ANSI_C_EXTRA
1681 static void wpa_cli_action_cb(char *msg, size_t len)
1682 {
1683         wpa_cli_action_process(msg);
1684 }
1685 #endif /* CONFIG_ANSI_C_EXTRA */
1686
1687
1688 static void wpa_cli_reconnect(void)
1689 {
1690         wpa_cli_close_connection();
1691         ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
1692         if (ctrl_conn) {
1693                 printf("Connection to wpa_supplicant re-established\n");
1694                 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1695                         wpa_cli_attached = 1;
1696                 } else {
1697                         printf("Warning: Failed to attach to "
1698                                "wpa_supplicant.\n");
1699                 }
1700         }
1701 }
1702
1703
1704 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
1705                                  int action_monitor)
1706 {
1707         int first = 1;
1708         if (ctrl_conn == NULL) {
1709                 wpa_cli_reconnect();
1710                 return;
1711         }
1712         while (wpa_ctrl_pending(ctrl) > 0) {
1713                 char buf[256];
1714                 size_t len = sizeof(buf) - 1;
1715                 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
1716                         buf[len] = '\0';
1717                         if (action_monitor)
1718                                 wpa_cli_action_process(buf);
1719                         else {
1720                                 if (in_read && first)
1721                                         printf("\n");
1722                                 first = 0;
1723                                 printf("%s\n", buf);
1724                         }
1725                 } else {
1726                         printf("Could not read pending message.\n");
1727                         break;
1728                 }
1729         }
1730
1731         if (wpa_ctrl_pending(ctrl) < 0) {
1732                 printf("Connection to wpa_supplicant lost - trying to "
1733                        "reconnect\n");
1734                 wpa_cli_reconnect();
1735         }
1736 }
1737
1738
1739 #ifdef CONFIG_READLINE
1740 static char * wpa_cli_cmd_gen(const char *text, int state)
1741 {
1742         static int i, len;
1743         const char *cmd;
1744
1745         if (state == 0) {
1746                 i = 0;
1747                 len = os_strlen(text);
1748         }
1749
1750         while ((cmd = wpa_cli_commands[i].cmd)) {
1751                 i++;
1752                 if (os_strncasecmp(cmd, text, len) == 0)
1753                         return os_strdup(cmd);
1754         }
1755
1756         return NULL;
1757 }
1758
1759
1760 static char * wpa_cli_dummy_gen(const char *text, int state)
1761 {
1762         return NULL;
1763 }
1764
1765
1766 static char ** wpa_cli_completion(const char *text, int start, int end)
1767 {
1768         return rl_completion_matches(text, start == 0 ?
1769                                      wpa_cli_cmd_gen : wpa_cli_dummy_gen);
1770 }
1771 #endif /* CONFIG_READLINE */
1772
1773
1774 static void wpa_cli_interactive(void)
1775 {
1776 #define max_args 10
1777         char cmdbuf[256], *cmd, *argv[max_args], *pos;
1778         int argc;
1779 #ifdef CONFIG_READLINE
1780         char *home, *hfile = NULL;
1781 #endif /* CONFIG_READLINE */
1782
1783         printf("\nInteractive mode\n\n");
1784
1785 #ifdef CONFIG_READLINE
1786         rl_attempted_completion_function = wpa_cli_completion;
1787         home = getenv("HOME");
1788         if (home) {
1789                 const char *fname = ".wpa_cli_history";
1790                 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
1791                 hfile = os_malloc(hfile_len);
1792                 if (hfile) {
1793                         int res;
1794                         res = os_snprintf(hfile, hfile_len, "%s/%s", home,
1795                                           fname);
1796                         if (res >= 0 && res < hfile_len) {
1797                                 hfile[hfile_len - 1] = '\0';
1798                                 read_history(hfile);
1799                                 stifle_history(100);
1800                         }
1801                 }
1802         }
1803 #endif /* CONFIG_READLINE */
1804
1805         do {
1806                 wpa_cli_recv_pending(ctrl_conn, 0, 0);
1807 #ifndef CONFIG_NATIVE_WINDOWS
1808                 alarm(ping_interval);
1809 #endif /* CONFIG_NATIVE_WINDOWS */
1810 #ifdef CONFIG_READLINE
1811                 cmd = readline("> ");
1812                 if (cmd && *cmd) {
1813                         HIST_ENTRY *h;
1814                         while (next_history())
1815                                 ;
1816                         h = previous_history();
1817                         if (h == NULL || os_strcmp(cmd, h->line) != 0)
1818                                 add_history(cmd);
1819                         next_history();
1820                 }
1821 #else /* CONFIG_READLINE */
1822                 printf("> ");
1823                 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
1824 #endif /* CONFIG_READLINE */
1825 #ifndef CONFIG_NATIVE_WINDOWS
1826                 alarm(0);
1827 #endif /* CONFIG_NATIVE_WINDOWS */
1828                 if (cmd == NULL)
1829                         break;
1830                 wpa_cli_recv_pending(ctrl_conn, 0, 0);
1831                 pos = cmd;
1832                 while (*pos != '\0') {
1833                         if (*pos == '\n') {
1834                                 *pos = '\0';
1835                                 break;
1836                         }
1837                         pos++;
1838                 }
1839                 argc = 0;
1840                 pos = cmd;
1841                 for (;;) {
1842                         while (*pos == ' ')
1843                                 pos++;
1844                         if (*pos == '\0')
1845                                 break;
1846                         argv[argc] = pos;
1847                         argc++;
1848                         if (argc == max_args)
1849                                 break;
1850                         if (*pos == '"') {
1851                                 char *pos2 = os_strrchr(pos, '"');
1852                                 if (pos2)
1853                                         pos = pos2 + 1;
1854                         }
1855                         while (*pos != '\0' && *pos != ' ')
1856                                 pos++;
1857                         if (*pos == ' ')
1858                                 *pos++ = '\0';
1859                 }
1860                 if (argc)
1861                         wpa_request(ctrl_conn, argc, argv);
1862
1863                 if (cmd != cmdbuf)
1864                         os_free(cmd);
1865         } while (!wpa_cli_quit);
1866
1867 #ifdef CONFIG_READLINE
1868         if (hfile) {
1869                 /* Save command history, excluding lines that may contain
1870                  * passwords. */
1871                 HIST_ENTRY *h;
1872                 history_set_pos(0);
1873                 while ((h = current_history())) {
1874                         char *p = h->line;
1875                         while (*p == ' ' || *p == '\t')
1876                                 p++;
1877                         if (cmd_has_sensitive_data(p)) {
1878                                 h = remove_history(where_history());
1879                                 if (h) {
1880                                         os_free(h->line);
1881                                         os_free(h->data);
1882                                         os_free(h);
1883                                 } else
1884                                         next_history();
1885                         } else
1886                                 next_history();
1887                 }
1888                 write_history(hfile);
1889                 os_free(hfile);
1890         }
1891 #endif /* CONFIG_READLINE */
1892 }
1893
1894
1895 static void wpa_cli_action(struct wpa_ctrl *ctrl)
1896 {
1897 #ifdef CONFIG_ANSI_C_EXTRA
1898         /* TODO: ANSI C version(?) */
1899         printf("Action processing not supported in ANSI C build.\n");
1900 #else /* CONFIG_ANSI_C_EXTRA */
1901         fd_set rfds;
1902         int fd, res;
1903         struct timeval tv;
1904         char buf[256]; /* note: large enough to fit in unsolicited messages */
1905         size_t len;
1906
1907         fd = wpa_ctrl_get_fd(ctrl);
1908
1909         while (!wpa_cli_quit) {
1910                 FD_ZERO(&rfds);
1911                 FD_SET(fd, &rfds);
1912                 tv.tv_sec = ping_interval;
1913                 tv.tv_usec = 0;
1914                 res = select(fd + 1, &rfds, NULL, NULL, &tv);
1915                 if (res < 0 && errno != EINTR) {
1916                         perror("select");
1917                         break;
1918                 }
1919
1920                 if (FD_ISSET(fd, &rfds))
1921                         wpa_cli_recv_pending(ctrl, 0, 1);
1922                 else {
1923                         /* verify that connection is still working */
1924                         len = sizeof(buf) - 1;
1925                         if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
1926                                              wpa_cli_action_cb) < 0 ||
1927                             len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
1928                                 printf("wpa_supplicant did not reply to PING "
1929                                        "command - exiting\n");
1930                                 break;
1931                         }
1932                 }
1933         }
1934 #endif /* CONFIG_ANSI_C_EXTRA */
1935 }
1936
1937
1938 static void wpa_cli_cleanup(void)
1939 {
1940         wpa_cli_close_connection();
1941         if (pid_file)
1942                 os_daemonize_terminate(pid_file);
1943
1944         os_program_deinit();
1945 }
1946
1947 static void wpa_cli_terminate(int sig)
1948 {
1949         wpa_cli_cleanup();
1950         exit(0);
1951 }
1952
1953
1954 #ifndef CONFIG_NATIVE_WINDOWS
1955 static void wpa_cli_alarm(int sig)
1956 {
1957         if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
1958                 printf("Connection to wpa_supplicant lost - trying to "
1959                        "reconnect\n");
1960                 wpa_cli_close_connection();
1961         }
1962         if (!ctrl_conn)
1963                 wpa_cli_reconnect();
1964         if (ctrl_conn)
1965                 wpa_cli_recv_pending(ctrl_conn, 1, 0);
1966         alarm(ping_interval);
1967 }
1968 #endif /* CONFIG_NATIVE_WINDOWS */
1969
1970
1971 static char * wpa_cli_get_default_ifname(void)
1972 {
1973         char *ifname = NULL;
1974
1975 #ifdef CONFIG_CTRL_IFACE_UNIX
1976         struct dirent *dent;
1977         DIR *dir = opendir(ctrl_iface_dir);
1978         if (!dir)
1979                 return NULL;
1980         while ((dent = readdir(dir))) {
1981 #ifdef _DIRENT_HAVE_D_TYPE
1982                 /*
1983                  * Skip the file if it is not a socket. Also accept
1984                  * DT_UNKNOWN (0) in case the C library or underlying
1985                  * file system does not support d_type.
1986                  */
1987                 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
1988                         continue;
1989 #endif /* _DIRENT_HAVE_D_TYPE */
1990                 if (os_strcmp(dent->d_name, ".") == 0 ||
1991                     os_strcmp(dent->d_name, "..") == 0)
1992                         continue;
1993                 printf("Selected interface '%s'\n", dent->d_name);
1994                 ifname = os_strdup(dent->d_name);
1995                 break;
1996         }
1997         closedir(dir);
1998 #endif /* CONFIG_CTRL_IFACE_UNIX */
1999
2000 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2001         char buf[2048], *pos;
2002         size_t len;
2003         struct wpa_ctrl *ctrl;
2004         int ret;
2005
2006         ctrl = wpa_ctrl_open(NULL);
2007         if (ctrl == NULL)
2008                 return NULL;
2009
2010         len = sizeof(buf) - 1;
2011         ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
2012         if (ret >= 0) {
2013                 buf[len] = '\0';
2014                 pos = os_strchr(buf, '\n');
2015                 if (pos)
2016                         *pos = '\0';
2017                 ifname = os_strdup(buf);
2018         }
2019         wpa_ctrl_close(ctrl);
2020 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2021
2022         return ifname;
2023 }
2024
2025
2026 int main(int argc, char *argv[])
2027 {
2028         int interactive;
2029         int warning_displayed = 0;
2030         int c;
2031         int daemonize = 0;
2032         int ret = 0;
2033         const char *global = NULL;
2034
2035         if (os_program_init())
2036                 return -1;
2037
2038         for (;;) {
2039                 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
2040                 if (c < 0)
2041                         break;
2042                 switch (c) {
2043                 case 'a':
2044                         action_file = optarg;
2045                         break;
2046                 case 'B':
2047                         daemonize = 1;
2048                         break;
2049                 case 'g':
2050                         global = optarg;
2051                         break;
2052                 case 'G':
2053                         ping_interval = atoi(optarg);
2054                         break;
2055                 case 'h':
2056                         usage();
2057                         return 0;
2058                 case 'v':
2059                         printf("%s\n", wpa_cli_version);
2060                         return 0;
2061                 case 'i':
2062                         os_free(ctrl_ifname);
2063                         ctrl_ifname = os_strdup(optarg);
2064                         break;
2065                 case 'p':
2066                         ctrl_iface_dir = optarg;
2067                         break;
2068                 case 'P':
2069                         pid_file = optarg;
2070                         break;
2071                 default:
2072                         usage();
2073                         return -1;
2074                 }
2075         }
2076
2077         interactive = (argc == optind) && (action_file == NULL);
2078
2079         if (interactive)
2080                 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
2081
2082         if (global) {
2083 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2084                 ctrl_conn = wpa_ctrl_open(NULL);
2085 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2086                 ctrl_conn = wpa_ctrl_open(global);
2087 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2088                 if (ctrl_conn == NULL) {
2089                         perror("Failed to connect to wpa_supplicant - "
2090                                "wpa_ctrl_open");
2091                         return -1;
2092                 }
2093         }
2094
2095         for (; !global;) {
2096                 if (ctrl_ifname == NULL)
2097                         ctrl_ifname = wpa_cli_get_default_ifname();
2098                 ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
2099                 if (ctrl_conn) {
2100                         if (warning_displayed)
2101                                 printf("Connection established.\n");
2102                         break;
2103                 }
2104
2105                 if (!interactive) {
2106                         perror("Failed to connect to wpa_supplicant - "
2107                                "wpa_ctrl_open");
2108                         return -1;
2109                 }
2110
2111                 if (!warning_displayed) {
2112                         printf("Could not connect to wpa_supplicant - "
2113                                "re-trying\n");
2114                         warning_displayed = 1;
2115                 }
2116                 os_sleep(1, 0);
2117                 continue;
2118         }
2119
2120 #ifndef _WIN32_WCE
2121         signal(SIGINT, wpa_cli_terminate);
2122         signal(SIGTERM, wpa_cli_terminate);
2123 #endif /* _WIN32_WCE */
2124 #ifndef CONFIG_NATIVE_WINDOWS
2125         signal(SIGALRM, wpa_cli_alarm);
2126 #endif /* CONFIG_NATIVE_WINDOWS */
2127
2128         if (interactive || action_file) {
2129                 if (wpa_ctrl_attach(ctrl_conn) == 0) {
2130                         wpa_cli_attached = 1;
2131                 } else {
2132                         printf("Warning: Failed to attach to "
2133                                "wpa_supplicant.\n");
2134                         if (!interactive)
2135                                 return -1;
2136                 }
2137         }
2138
2139         if (daemonize && os_daemonize(pid_file))
2140                 return -1;
2141
2142         if (interactive)
2143                 wpa_cli_interactive();
2144         else if (action_file)
2145                 wpa_cli_action(ctrl_conn);
2146         else
2147                 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
2148
2149         os_free(ctrl_ifname);
2150         wpa_cli_cleanup();
2151
2152         return ret;
2153 }
2154
2155 #else /* CONFIG_CTRL_IFACE */
2156 int main(int argc, char *argv[])
2157 {
2158         printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
2159         return -1;
2160 }
2161 #endif /* CONFIG_CTRL_IFACE */