ec103bfb4653134a935d8998cbad591d52e90cb2
[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_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
537 {
538         char cmd[256];
539         int res;
540
541         if (argc != 1) {
542                 printf("Invalid IBSS_RSN command: needs one argument "
543                        "(Peer STA MAC address)\n");
544                 return -1;
545         }
546
547         res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
548         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
549                 printf("Too long IBSS_RSN command.\n");
550                 return -1;
551         }
552         return wpa_ctrl_command(ctrl, cmd);
553 }
554
555
556 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
557 {
558         char cmd[256];
559         int res;
560
561         if (argc != 1) {
562                 printf("Invalid LEVEL command: needs one argument (debug "
563                        "level)\n");
564                 return -1;
565         }
566         res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
567         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
568                 printf("Too long LEVEL command.\n");
569                 return -1;
570         }
571         return wpa_ctrl_command(ctrl, cmd);
572 }
573
574
575 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
576 {
577         char cmd[256], *pos, *end;
578         int i, ret;
579
580         if (argc < 2) {
581                 printf("Invalid IDENTITY command: needs two arguments "
582                        "(network id and identity)\n");
583                 return -1;
584         }
585
586         end = cmd + sizeof(cmd);
587         pos = cmd;
588         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
589                           argv[0], argv[1]);
590         if (ret < 0 || ret >= end - pos) {
591                 printf("Too long IDENTITY command.\n");
592                 return -1;
593         }
594         pos += ret;
595         for (i = 2; i < argc; i++) {
596                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
597                 if (ret < 0 || ret >= end - pos) {
598                         printf("Too long IDENTITY command.\n");
599                         return -1;
600                 }
601                 pos += ret;
602         }
603
604         return wpa_ctrl_command(ctrl, cmd);
605 }
606
607
608 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
609 {
610         char cmd[256], *pos, *end;
611         int i, ret;
612
613         if (argc < 2) {
614                 printf("Invalid PASSWORD command: needs two arguments "
615                        "(network id and password)\n");
616                 return -1;
617         }
618
619         end = cmd + sizeof(cmd);
620         pos = cmd;
621         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
622                           argv[0], argv[1]);
623         if (ret < 0 || ret >= end - pos) {
624                 printf("Too long PASSWORD command.\n");
625                 return -1;
626         }
627         pos += ret;
628         for (i = 2; i < argc; i++) {
629                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
630                 if (ret < 0 || ret >= end - pos) {
631                         printf("Too long PASSWORD command.\n");
632                         return -1;
633                 }
634                 pos += ret;
635         }
636
637         return wpa_ctrl_command(ctrl, cmd);
638 }
639
640
641 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
642                                     char *argv[])
643 {
644         char cmd[256], *pos, *end;
645         int i, ret;
646
647         if (argc < 2) {
648                 printf("Invalid NEW_PASSWORD command: needs two arguments "
649                        "(network id and password)\n");
650                 return -1;
651         }
652
653         end = cmd + sizeof(cmd);
654         pos = cmd;
655         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
656                           argv[0], argv[1]);
657         if (ret < 0 || ret >= end - pos) {
658                 printf("Too long NEW_PASSWORD command.\n");
659                 return -1;
660         }
661         pos += ret;
662         for (i = 2; i < argc; i++) {
663                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
664                 if (ret < 0 || ret >= end - pos) {
665                         printf("Too long NEW_PASSWORD command.\n");
666                         return -1;
667                 }
668                 pos += ret;
669         }
670
671         return wpa_ctrl_command(ctrl, cmd);
672 }
673
674
675 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
676 {
677         char cmd[256], *pos, *end;
678         int i, ret;
679
680         if (argc < 2) {
681                 printf("Invalid PIN command: needs two arguments "
682                        "(network id and pin)\n");
683                 return -1;
684         }
685
686         end = cmd + sizeof(cmd);
687         pos = cmd;
688         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
689                           argv[0], argv[1]);
690         if (ret < 0 || ret >= end - pos) {
691                 printf("Too long PIN command.\n");
692                 return -1;
693         }
694         pos += ret;
695         for (i = 2; i < argc; i++) {
696                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
697                 if (ret < 0 || ret >= end - pos) {
698                         printf("Too long PIN command.\n");
699                         return -1;
700                 }
701                 pos += ret;
702         }
703         return wpa_ctrl_command(ctrl, cmd);
704 }
705
706
707 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
708 {
709         char cmd[256], *pos, *end;
710         int i, ret;
711
712         if (argc < 2) {
713                 printf("Invalid OTP command: needs two arguments (network "
714                        "id and password)\n");
715                 return -1;
716         }
717
718         end = cmd + sizeof(cmd);
719         pos = cmd;
720         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
721                           argv[0], argv[1]);
722         if (ret < 0 || ret >= end - pos) {
723                 printf("Too long OTP command.\n");
724                 return -1;
725         }
726         pos += ret;
727         for (i = 2; i < argc; i++) {
728                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
729                 if (ret < 0 || ret >= end - pos) {
730                         printf("Too long OTP command.\n");
731                         return -1;
732                 }
733                 pos += ret;
734         }
735
736         return wpa_ctrl_command(ctrl, cmd);
737 }
738
739
740 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
741                                   char *argv[])
742 {
743         char cmd[256], *pos, *end;
744         int i, ret;
745
746         if (argc < 2) {
747                 printf("Invalid PASSPHRASE command: needs two arguments "
748                        "(network id and passphrase)\n");
749                 return -1;
750         }
751
752         end = cmd + sizeof(cmd);
753         pos = cmd;
754         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
755                           argv[0], argv[1]);
756         if (ret < 0 || ret >= end - pos) {
757                 printf("Too long PASSPHRASE command.\n");
758                 return -1;
759         }
760         pos += ret;
761         for (i = 2; i < argc; i++) {
762                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
763                 if (ret < 0 || ret >= end - pos) {
764                         printf("Too long PASSPHRASE command.\n");
765                         return -1;
766                 }
767                 pos += ret;
768         }
769
770         return wpa_ctrl_command(ctrl, cmd);
771 }
772
773
774 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
775 {
776         char cmd[256], *pos, *end;
777         int i, ret;
778
779         if (argc < 2) {
780                 printf("Invalid BSSID command: needs two arguments (network "
781                        "id and BSSID)\n");
782                 return -1;
783         }
784
785         end = cmd + sizeof(cmd);
786         pos = cmd;
787         ret = os_snprintf(pos, end - pos, "BSSID");
788         if (ret < 0 || ret >= end - pos) {
789                 printf("Too long BSSID command.\n");
790                 return -1;
791         }
792         pos += ret;
793         for (i = 0; i < argc; i++) {
794                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
795                 if (ret < 0 || ret >= end - pos) {
796                         printf("Too long BSSID command.\n");
797                         return -1;
798                 }
799                 pos += ret;
800         }
801
802         return wpa_ctrl_command(ctrl, cmd);
803 }
804
805
806 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
807                                      char *argv[])
808 {
809         return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
810 }
811
812
813 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
814                                       char *argv[])
815 {
816         char cmd[32];
817         int res;
818
819         if (argc < 1) {
820                 printf("Invalid SELECT_NETWORK command: needs one argument "
821                        "(network id)\n");
822                 return -1;
823         }
824
825         res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
826         if (res < 0 || (size_t) res >= sizeof(cmd))
827                 return -1;
828         cmd[sizeof(cmd) - 1] = '\0';
829
830         return wpa_ctrl_command(ctrl, cmd);
831 }
832
833
834 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
835                                       char *argv[])
836 {
837         char cmd[32];
838         int res;
839
840         if (argc < 1) {
841                 printf("Invalid ENABLE_NETWORK command: needs one argument "
842                        "(network id)\n");
843                 return -1;
844         }
845
846         res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
847         if (res < 0 || (size_t) res >= sizeof(cmd))
848                 return -1;
849         cmd[sizeof(cmd) - 1] = '\0';
850
851         return wpa_ctrl_command(ctrl, cmd);
852 }
853
854
855 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
856                                        char *argv[])
857 {
858         char cmd[32];
859         int res;
860
861         if (argc < 1) {
862                 printf("Invalid DISABLE_NETWORK command: needs one argument "
863                        "(network id)\n");
864                 return -1;
865         }
866
867         res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
868         if (res < 0 || (size_t) res >= sizeof(cmd))
869                 return -1;
870         cmd[sizeof(cmd) - 1] = '\0';
871
872         return wpa_ctrl_command(ctrl, cmd);
873 }
874
875
876 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
877                                    char *argv[])
878 {
879         return wpa_ctrl_command(ctrl, "ADD_NETWORK");
880 }
881
882
883 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
884                                       char *argv[])
885 {
886         char cmd[32];
887         int res;
888
889         if (argc < 1) {
890                 printf("Invalid REMOVE_NETWORK command: needs one argument "
891                        "(network id)\n");
892                 return -1;
893         }
894
895         res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
896         if (res < 0 || (size_t) res >= sizeof(cmd))
897                 return -1;
898         cmd[sizeof(cmd) - 1] = '\0';
899
900         return wpa_ctrl_command(ctrl, cmd);
901 }
902
903
904 static void wpa_cli_show_network_variables(void)
905 {
906         printf("set_network variables:\n"
907                "  ssid (network name, SSID)\n"
908                "  psk (WPA passphrase or pre-shared key)\n"
909                "  key_mgmt (key management protocol)\n"
910                "  identity (EAP identity)\n"
911                "  password (EAP password)\n"
912                "  ...\n"
913                "\n"
914                "Note: Values are entered in the same format as the "
915                "configuration file is using,\n"
916                "i.e., strings values need to be inside double quotation "
917                "marks.\n"
918                "For example: set_network 1 ssid \"network name\"\n"
919                "\n"
920                "Please see wpa_supplicant.conf documentation for full list "
921                "of\navailable variables.\n");
922 }
923
924
925 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
926                                    char *argv[])
927 {
928         char cmd[256];
929         int res;
930
931         if (argc == 0) {
932                 wpa_cli_show_network_variables();
933                 return 0;
934         }
935
936         if (argc != 3) {
937                 printf("Invalid SET_NETWORK command: needs three arguments\n"
938                        "(network id, variable name, and value)\n");
939                 return -1;
940         }
941
942         res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
943                           argv[0], argv[1], argv[2]);
944         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
945                 printf("Too long SET_NETWORK command.\n");
946                 return -1;
947         }
948         return wpa_ctrl_command(ctrl, cmd);
949 }
950
951
952 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
953                                    char *argv[])
954 {
955         char cmd[256];
956         int res;
957
958         if (argc == 0) {
959                 wpa_cli_show_network_variables();
960                 return 0;
961         }
962
963         if (argc != 2) {
964                 printf("Invalid GET_NETWORK command: needs two arguments\n"
965                        "(network id and variable name)\n");
966                 return -1;
967         }
968
969         res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
970                           argv[0], argv[1]);
971         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
972                 printf("Too long GET_NETWORK command.\n");
973                 return -1;
974         }
975         return wpa_ctrl_command(ctrl, cmd);
976 }
977
978
979 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
980                                   char *argv[])
981 {
982         return wpa_ctrl_command(ctrl, "DISCONNECT");
983 }
984
985
986 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
987                                   char *argv[])
988 {
989         return wpa_ctrl_command(ctrl, "RECONNECT");
990 }
991
992
993 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
994                                    char *argv[])
995 {
996         return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
997 }
998
999
1000 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1001 {
1002         return wpa_ctrl_command(ctrl, "SCAN");
1003 }
1004
1005
1006 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1007                                     char *argv[])
1008 {
1009         return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1010 }
1011
1012
1013 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1014 {
1015         char cmd[64];
1016         int res;
1017
1018         if (argc != 1) {
1019                 printf("Invalid BSS command: need one argument (index or "
1020                        "BSSID)\n");
1021                 return -1;
1022         }
1023
1024         res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1025         if (res < 0 || (size_t) res >= sizeof(cmd))
1026                 return -1;
1027         cmd[sizeof(cmd) - 1] = '\0';
1028
1029         return wpa_ctrl_command(ctrl, cmd);
1030 }
1031
1032
1033 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1034                                       char *argv[])
1035 {
1036         char cmd[64];
1037         int res;
1038
1039         if (argc < 1 || argc > 2) {
1040                 printf("Invalid GET_CAPABILITY command: need either one or "
1041                        "two arguments\n");
1042                 return -1;
1043         }
1044
1045         if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1046                 printf("Invalid GET_CAPABILITY command: second argument, "
1047                        "if any, must be 'strict'\n");
1048                 return -1;
1049         }
1050
1051         res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1052                           (argc == 2) ? " strict" : "");
1053         if (res < 0 || (size_t) res >= sizeof(cmd))
1054                 return -1;
1055         cmd[sizeof(cmd) - 1] = '\0';
1056
1057         return wpa_ctrl_command(ctrl, cmd);
1058 }
1059
1060
1061 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1062 {
1063         printf("Available interfaces:\n");
1064         return wpa_ctrl_command(ctrl, "INTERFACES");
1065 }
1066
1067
1068 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1069 {
1070         if (argc < 1) {
1071                 wpa_cli_list_interfaces(ctrl);
1072                 return 0;
1073         }
1074
1075         wpa_cli_close_connection();
1076         os_free(ctrl_ifname);
1077         ctrl_ifname = os_strdup(argv[0]);
1078
1079         if (wpa_cli_open_connection(ctrl_ifname)) {
1080                 printf("Connected to interface '%s.\n", ctrl_ifname);
1081                 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1082                         wpa_cli_attached = 1;
1083                 } else {
1084                         printf("Warning: Failed to attach to "
1085                                "wpa_supplicant.\n");
1086                 }
1087         } else {
1088                 printf("Could not connect to interface '%s' - re-trying\n",
1089                        ctrl_ifname);
1090         }
1091         return 0;
1092 }
1093
1094
1095 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1096                                    char *argv[])
1097 {
1098         return wpa_ctrl_command(ctrl, "RECONFIGURE");
1099 }
1100
1101
1102 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1103                                  char *argv[])
1104 {
1105         return wpa_ctrl_command(ctrl, "TERMINATE");
1106 }
1107
1108
1109 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1110                                      char *argv[])
1111 {
1112         char cmd[256];
1113         int res;
1114
1115         if (argc < 1) {
1116                 printf("Invalid INTERFACE_ADD command: needs at least one "
1117                        "argument (interface name)\n"
1118                        "All arguments: ifname confname driver ctrl_interface "
1119                        "driver_param bridge_name\n");
1120                 return -1;
1121         }
1122
1123         /*
1124          * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1125          * <driver_param>TAB<bridge_name>
1126          */
1127         res = os_snprintf(cmd, sizeof(cmd),
1128                           "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1129                           argv[0],
1130                           argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1131                           argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1132                           argc > 5 ? argv[5] : "");
1133         if (res < 0 || (size_t) res >= sizeof(cmd))
1134                 return -1;
1135         cmd[sizeof(cmd) - 1] = '\0';
1136         return wpa_ctrl_command(ctrl, cmd);
1137 }
1138
1139
1140 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1141                                         char *argv[])
1142 {
1143         char cmd[128];
1144         int res;
1145
1146         if (argc != 1) {
1147                 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1148                        "(interface name)\n");
1149                 return -1;
1150         }
1151
1152         res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1153         if (res < 0 || (size_t) res >= sizeof(cmd))
1154                 return -1;
1155         cmd[sizeof(cmd) - 1] = '\0';
1156         return wpa_ctrl_command(ctrl, cmd);
1157 }
1158
1159
1160 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1161                                       char *argv[])
1162 {
1163         return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1164 }
1165
1166
1167 #ifdef CONFIG_AP
1168 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1169 {
1170         char buf[64];
1171         if (argc != 1) {
1172                 printf("Invalid 'sta' command - exactly one argument, STA "
1173                        "address, is required.\n");
1174                 return -1;
1175         }
1176         snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1177         return wpa_ctrl_command(ctrl, buf);
1178 }
1179
1180
1181 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1182                                 char *addr, size_t addr_len)
1183 {
1184         char buf[4096], *pos;
1185         size_t len;
1186         int ret;
1187
1188         if (ctrl_conn == NULL) {
1189                 printf("Not connected to hostapd - command dropped.\n");
1190                 return -1;
1191         }
1192         len = sizeof(buf) - 1;
1193         ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1194                                wpa_cli_msg_cb);
1195         if (ret == -2) {
1196                 printf("'%s' command timed out.\n", cmd);
1197                 return -2;
1198         } else if (ret < 0) {
1199                 printf("'%s' command failed.\n", cmd);
1200                 return -1;
1201         }
1202
1203         buf[len] = '\0';
1204         if (memcmp(buf, "FAIL", 4) == 0)
1205                 return -1;
1206         printf("%s", buf);
1207
1208         pos = buf;
1209         while (*pos != '\0' && *pos != '\n')
1210                 pos++;
1211         *pos = '\0';
1212         os_strlcpy(addr, buf, addr_len);
1213         return 0;
1214 }
1215
1216
1217 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1218 {
1219         char addr[32], cmd[64];
1220
1221         if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1222                 return 0;
1223         do {
1224                 snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1225         } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1226
1227         return -1;
1228 }
1229 #endif /* CONFIG_AP */
1230
1231
1232 enum wpa_cli_cmd_flags {
1233         cli_cmd_flag_none               = 0x00,
1234         cli_cmd_flag_sensitive          = 0x01
1235 };
1236
1237 struct wpa_cli_cmd {
1238         const char *cmd;
1239         int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
1240         enum wpa_cli_cmd_flags flags;
1241         const char *usage;
1242 };
1243
1244 static struct wpa_cli_cmd wpa_cli_commands[] = {
1245         { "status", wpa_cli_cmd_status,
1246           cli_cmd_flag_none,
1247           "[verbose] = get current WPA/EAPOL/EAP status" },
1248         { "ping", wpa_cli_cmd_ping,
1249           cli_cmd_flag_none,
1250           "= pings wpa_supplicant" },
1251         { "mib", wpa_cli_cmd_mib,
1252           cli_cmd_flag_none,
1253           "= get MIB variables (dot1x, dot11)" },
1254         { "help", wpa_cli_cmd_help,
1255           cli_cmd_flag_none,
1256           "= show this usage help" },
1257         { "interface", wpa_cli_cmd_interface,
1258           cli_cmd_flag_none,
1259           "[ifname] = show interfaces/select interface" },
1260         { "level", wpa_cli_cmd_level,
1261           cli_cmd_flag_none,
1262           "<debug level> = change debug level" },
1263         { "license", wpa_cli_cmd_license,
1264           cli_cmd_flag_none,
1265           "= show full wpa_cli license" },
1266         { "quit", wpa_cli_cmd_quit,
1267           cli_cmd_flag_none,
1268           "= exit wpa_cli" },
1269         { "set", wpa_cli_cmd_set,
1270           cli_cmd_flag_none,
1271           "= set variables (shows list of variables when run without "
1272           "arguments)" },
1273         { "logon", wpa_cli_cmd_logon,
1274           cli_cmd_flag_none,
1275           "= IEEE 802.1X EAPOL state machine logon" },
1276         { "logoff", wpa_cli_cmd_logoff,
1277           cli_cmd_flag_none,
1278           "= IEEE 802.1X EAPOL state machine logoff" },
1279         { "pmksa", wpa_cli_cmd_pmksa,
1280           cli_cmd_flag_none,
1281           "= show PMKSA cache" },
1282         { "reassociate", wpa_cli_cmd_reassociate,
1283           cli_cmd_flag_none,
1284           "= force reassociation" },
1285         { "preauthenticate", wpa_cli_cmd_preauthenticate,
1286           cli_cmd_flag_none,
1287           "<BSSID> = force preauthentication" },
1288         { "identity", wpa_cli_cmd_identity,
1289           cli_cmd_flag_none,
1290           "<network id> <identity> = configure identity for an SSID" },
1291         { "password", wpa_cli_cmd_password,
1292           cli_cmd_flag_sensitive,
1293           "<network id> <password> = configure password for an SSID" },
1294         { "new_password", wpa_cli_cmd_new_password,
1295           cli_cmd_flag_sensitive,
1296           "<network id> <password> = change password for an SSID" },
1297         { "pin", wpa_cli_cmd_pin,
1298           cli_cmd_flag_sensitive,
1299           "<network id> <pin> = configure pin for an SSID" },
1300         { "otp", wpa_cli_cmd_otp,
1301           cli_cmd_flag_sensitive,
1302           "<network id> <password> = configure one-time-password for an SSID"
1303         },
1304         { "passphrase", wpa_cli_cmd_passphrase,
1305           cli_cmd_flag_sensitive,
1306           "<network id> <passphrase> = configure private key passphrase\n"
1307           "  for an SSID" },
1308         { "bssid", wpa_cli_cmd_bssid,
1309           cli_cmd_flag_none,
1310           "<network id> <BSSID> = set preferred BSSID for an SSID" },
1311         { "list_networks", wpa_cli_cmd_list_networks,
1312           cli_cmd_flag_none,
1313           "= list configured networks" },
1314         { "select_network", wpa_cli_cmd_select_network,
1315           cli_cmd_flag_none,
1316           "<network id> = select a network (disable others)" },
1317         { "enable_network", wpa_cli_cmd_enable_network,
1318           cli_cmd_flag_none,
1319           "<network id> = enable a network" },
1320         { "disable_network", wpa_cli_cmd_disable_network,
1321           cli_cmd_flag_none,
1322           "<network id> = disable a network" },
1323         { "add_network", wpa_cli_cmd_add_network,
1324           cli_cmd_flag_none,
1325           "= add a network" },
1326         { "remove_network", wpa_cli_cmd_remove_network,
1327           cli_cmd_flag_none,
1328           "<network id> = remove a network" },
1329         { "set_network", wpa_cli_cmd_set_network,
1330           cli_cmd_flag_sensitive,
1331           "<network id> <variable> <value> = set network variables (shows\n"
1332           "  list of variables when run without arguments)" },
1333         { "get_network", wpa_cli_cmd_get_network,
1334           cli_cmd_flag_none,
1335           "<network id> <variable> = get network variables" },
1336         { "save_config", wpa_cli_cmd_save_config,
1337           cli_cmd_flag_none,
1338           "= save the current configuration" },
1339         { "disconnect", wpa_cli_cmd_disconnect,
1340           cli_cmd_flag_none,
1341           "= disconnect and wait for reassociate/reconnect command before\n"
1342           "  connecting" },
1343         { "reconnect", wpa_cli_cmd_reconnect,
1344           cli_cmd_flag_none,
1345           "= like reassociate, but only takes effect if already disconnected"
1346         },
1347         { "scan", wpa_cli_cmd_scan,
1348           cli_cmd_flag_none,
1349           "= request new BSS scan" },
1350         { "scan_results", wpa_cli_cmd_scan_results,
1351           cli_cmd_flag_none,
1352           "= get latest scan results" },
1353         { "bss", wpa_cli_cmd_bss,
1354           cli_cmd_flag_none,
1355           "<<idx> | <bssid>> = get detailed scan result info" },
1356         { "get_capability", wpa_cli_cmd_get_capability,
1357           cli_cmd_flag_none,
1358           "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
1359         { "reconfigure", wpa_cli_cmd_reconfigure,
1360           cli_cmd_flag_none,
1361           "= force wpa_supplicant to re-read its configuration file" },
1362         { "terminate", wpa_cli_cmd_terminate,
1363           cli_cmd_flag_none,
1364           "= terminate wpa_supplicant" },
1365         { "interface_add", wpa_cli_cmd_interface_add,
1366           cli_cmd_flag_none,
1367           "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
1368           "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
1369           "  are optional" },
1370         { "interface_remove", wpa_cli_cmd_interface_remove,
1371           cli_cmd_flag_none,
1372           "<ifname> = removes the interface" },
1373         { "interface_list", wpa_cli_cmd_interface_list,
1374           cli_cmd_flag_none,
1375           "= list available interfaces" },
1376         { "ap_scan", wpa_cli_cmd_ap_scan,
1377           cli_cmd_flag_none,
1378           "<value> = set ap_scan parameter" },
1379         { "stkstart", wpa_cli_cmd_stkstart,
1380           cli_cmd_flag_none,
1381           "<addr> = request STK negotiation with <addr>" },
1382         { "ft_ds", wpa_cli_cmd_ft_ds,
1383           cli_cmd_flag_none,
1384           "<addr> = request over-the-DS FT with <addr>" },
1385         { "wps_pbc", wpa_cli_cmd_wps_pbc,
1386           cli_cmd_flag_none,
1387           "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
1388         { "wps_pin", wpa_cli_cmd_wps_pin,
1389           cli_cmd_flag_sensitive,
1390           "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
1391           "hardcoded)" },
1392 #ifdef CONFIG_WPS_OOB
1393         { "wps_oob", wpa_cli_cmd_wps_oob,
1394           cli_cmd_flag_sensitive,
1395           "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
1396 #endif /* CONFIG_WPS_OOB */
1397         { "wps_reg", wpa_cli_cmd_wps_reg,
1398           cli_cmd_flag_sensitive,
1399           "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
1400         { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
1401           cli_cmd_flag_none,
1402           "<addr> = request RSN authentication with <addr> in IBSS" },
1403 #ifdef CONFIG_AP
1404         { "sta", wpa_cli_cmd_sta,
1405           cli_cmd_flag_none,
1406           "<addr> = get information about an associated station (AP)" },
1407         { "all_sta", wpa_cli_cmd_all_sta,
1408           cli_cmd_flag_none,
1409           "= get information about all associated stations (AP)" },
1410 #endif /* CONFIG_AP */
1411         { NULL, NULL, cli_cmd_flag_none, NULL }
1412 };
1413
1414
1415 /*
1416  * Prints command usage, lines are padded with the specified string.
1417  */
1418 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
1419 {
1420         char c;
1421         size_t n;
1422
1423         printf("%s%s ", pad, cmd->cmd);
1424         for (n = 0; (c = cmd->usage[n]); n++) {
1425                 printf("%c", c);
1426                 if (c == '\n')
1427                         printf("%s", pad);
1428         }
1429         printf("\n");
1430 }
1431
1432
1433 static void print_help(void)
1434 {
1435         int n;
1436         printf("commands:\n");
1437         for (n = 0; wpa_cli_commands[n].cmd; n++)
1438                 print_cmd_help(&wpa_cli_commands[n], "  ");
1439 }
1440
1441
1442 #ifdef CONFIG_READLINE
1443 static int cmd_has_sensitive_data(const char *cmd)
1444 {
1445         const char *c, *delim;
1446         int n;
1447         size_t len;
1448
1449         delim = os_strchr(cmd, ' ');
1450         if (delim)
1451                 len = delim - cmd;
1452         else
1453                 len = os_strlen(cmd);
1454
1455         for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
1456                 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
1457                         return (wpa_cli_commands[n].flags &
1458                                 cli_cmd_flag_sensitive);
1459         }
1460         return 0;
1461 }
1462 #endif /* CONFIG_READLINE */
1463
1464
1465 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1466 {
1467         struct wpa_cli_cmd *cmd, *match = NULL;
1468         int count;
1469         int ret = 0;
1470
1471         count = 0;
1472         cmd = wpa_cli_commands;
1473         while (cmd->cmd) {
1474                 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1475                 {
1476                         match = cmd;
1477                         if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1478                                 /* we have an exact match */
1479                                 count = 1;
1480                                 break;
1481                         }
1482                         count++;
1483                 }
1484                 cmd++;
1485         }
1486
1487         if (count > 1) {
1488                 printf("Ambiguous command '%s'; possible commands:", argv[0]);
1489                 cmd = wpa_cli_commands;
1490                 while (cmd->cmd) {
1491                         if (os_strncasecmp(cmd->cmd, argv[0],
1492                                            os_strlen(argv[0])) == 0) {
1493                                 printf(" %s", cmd->cmd);
1494                         }
1495                         cmd++;
1496                 }
1497                 printf("\n");
1498                 ret = 1;
1499         } else if (count == 0) {
1500                 printf("Unknown command '%s'\n", argv[0]);
1501                 ret = 1;
1502         } else {
1503                 ret = match->handler(ctrl, argc - 1, &argv[1]);
1504         }
1505
1506         return ret;
1507 }
1508
1509
1510 static int str_match(const char *a, const char *b)
1511 {
1512         return os_strncmp(a, b, os_strlen(b)) == 0;
1513 }
1514
1515
1516 static int wpa_cli_exec(const char *program, const char *arg1,
1517                         const char *arg2)
1518 {
1519         char *cmd;
1520         size_t len;
1521         int res;
1522         int ret = 0;
1523
1524         len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1525         cmd = os_malloc(len);
1526         if (cmd == NULL)
1527                 return -1;
1528         res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1529         if (res < 0 || (size_t) res >= len) {
1530                 os_free(cmd);
1531                 return -1;
1532         }
1533         cmd[len - 1] = '\0';
1534 #ifndef _WIN32_WCE
1535         if (system(cmd) < 0)
1536                 ret = -1;
1537 #endif /* _WIN32_WCE */
1538         os_free(cmd);
1539
1540         return ret;
1541 }
1542
1543
1544 static void wpa_cli_action_process(const char *msg)
1545 {
1546         const char *pos;
1547         char *copy = NULL, *id, *pos2;
1548
1549         pos = msg;
1550         if (*pos == '<') {
1551                 /* skip priority */
1552                 pos = os_strchr(pos, '>');
1553                 if (pos)
1554                         pos++;
1555                 else
1556                         pos = msg;
1557         }
1558
1559         if (str_match(pos, WPA_EVENT_CONNECTED)) {
1560                 int new_id = -1;
1561                 os_unsetenv("WPA_ID");
1562                 os_unsetenv("WPA_ID_STR");
1563                 os_unsetenv("WPA_CTRL_DIR");
1564
1565                 pos = os_strstr(pos, "[id=");
1566                 if (pos)
1567                         copy = os_strdup(pos + 4);
1568
1569                 if (copy) {
1570                         pos2 = id = copy;
1571                         while (*pos2 && *pos2 != ' ')
1572                                 pos2++;
1573                         *pos2++ = '\0';
1574                         new_id = atoi(id);
1575                         os_setenv("WPA_ID", id, 1);
1576                         while (*pos2 && *pos2 != '=')
1577                                 pos2++;
1578                         if (*pos2 == '=')
1579                                 pos2++;
1580                         id = pos2;
1581                         while (*pos2 && *pos2 != ']')
1582                                 pos2++;
1583                         *pos2 = '\0';
1584                         os_setenv("WPA_ID_STR", id, 1);
1585                         os_free(copy);
1586                 }
1587
1588                 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
1589
1590                 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
1591                         wpa_cli_connected = 1;
1592                         wpa_cli_last_id = new_id;
1593                         wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
1594                 }
1595         } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
1596                 if (wpa_cli_connected) {
1597                         wpa_cli_connected = 0;
1598                         wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
1599                 }
1600         } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
1601                 printf("wpa_supplicant is terminating - stop monitoring\n");
1602                 wpa_cli_quit = 1;
1603         }
1604 }
1605
1606
1607 #ifndef CONFIG_ANSI_C_EXTRA
1608 static void wpa_cli_action_cb(char *msg, size_t len)
1609 {
1610         wpa_cli_action_process(msg);
1611 }
1612 #endif /* CONFIG_ANSI_C_EXTRA */
1613
1614
1615 static void wpa_cli_reconnect(void)
1616 {
1617         wpa_cli_close_connection();
1618         ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
1619         if (ctrl_conn) {
1620                 printf("Connection to wpa_supplicant re-established\n");
1621                 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1622                         wpa_cli_attached = 1;
1623                 } else {
1624                         printf("Warning: Failed to attach to "
1625                                "wpa_supplicant.\n");
1626                 }
1627         }
1628 }
1629
1630
1631 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
1632                                  int action_monitor)
1633 {
1634         int first = 1;
1635         if (ctrl_conn == NULL) {
1636                 wpa_cli_reconnect();
1637                 return;
1638         }
1639         while (wpa_ctrl_pending(ctrl) > 0) {
1640                 char buf[256];
1641                 size_t len = sizeof(buf) - 1;
1642                 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
1643                         buf[len] = '\0';
1644                         if (action_monitor)
1645                                 wpa_cli_action_process(buf);
1646                         else {
1647                                 if (in_read && first)
1648                                         printf("\n");
1649                                 first = 0;
1650                                 printf("%s\n", buf);
1651                         }
1652                 } else {
1653                         printf("Could not read pending message.\n");
1654                         break;
1655                 }
1656         }
1657
1658         if (wpa_ctrl_pending(ctrl) < 0) {
1659                 printf("Connection to wpa_supplicant lost - trying to "
1660                        "reconnect\n");
1661                 wpa_cli_reconnect();
1662         }
1663 }
1664
1665
1666 #ifdef CONFIG_READLINE
1667 static char * wpa_cli_cmd_gen(const char *text, int state)
1668 {
1669         static int i, len;
1670         const char *cmd;
1671
1672         if (state == 0) {
1673                 i = 0;
1674                 len = os_strlen(text);
1675         }
1676
1677         while ((cmd = wpa_cli_commands[i].cmd)) {
1678                 i++;
1679                 if (os_strncasecmp(cmd, text, len) == 0)
1680                         return os_strdup(cmd);
1681         }
1682
1683         return NULL;
1684 }
1685
1686
1687 static char * wpa_cli_dummy_gen(const char *text, int state)
1688 {
1689         return NULL;
1690 }
1691
1692
1693 static char ** wpa_cli_completion(const char *text, int start, int end)
1694 {
1695         return rl_completion_matches(text, start == 0 ?
1696                                      wpa_cli_cmd_gen : wpa_cli_dummy_gen);
1697 }
1698 #endif /* CONFIG_READLINE */
1699
1700
1701 static void wpa_cli_interactive(void)
1702 {
1703 #define max_args 10
1704         char cmdbuf[256], *cmd, *argv[max_args], *pos;
1705         int argc;
1706 #ifdef CONFIG_READLINE
1707         char *home, *hfile = NULL;
1708 #endif /* CONFIG_READLINE */
1709
1710         printf("\nInteractive mode\n\n");
1711
1712 #ifdef CONFIG_READLINE
1713         rl_attempted_completion_function = wpa_cli_completion;
1714         home = getenv("HOME");
1715         if (home) {
1716                 const char *fname = ".wpa_cli_history";
1717                 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
1718                 hfile = os_malloc(hfile_len);
1719                 if (hfile) {
1720                         int res;
1721                         res = os_snprintf(hfile, hfile_len, "%s/%s", home,
1722                                           fname);
1723                         if (res >= 0 && res < hfile_len) {
1724                                 hfile[hfile_len - 1] = '\0';
1725                                 read_history(hfile);
1726                                 stifle_history(100);
1727                         }
1728                 }
1729         }
1730 #endif /* CONFIG_READLINE */
1731
1732         do {
1733                 wpa_cli_recv_pending(ctrl_conn, 0, 0);
1734 #ifndef CONFIG_NATIVE_WINDOWS
1735                 alarm(ping_interval);
1736 #endif /* CONFIG_NATIVE_WINDOWS */
1737 #ifdef CONFIG_READLINE
1738                 cmd = readline("> ");
1739                 if (cmd && *cmd) {
1740                         HIST_ENTRY *h;
1741                         while (next_history())
1742                                 ;
1743                         h = previous_history();
1744                         if (h == NULL || os_strcmp(cmd, h->line) != 0)
1745                                 add_history(cmd);
1746                         next_history();
1747                 }
1748 #else /* CONFIG_READLINE */
1749                 printf("> ");
1750                 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
1751 #endif /* CONFIG_READLINE */
1752 #ifndef CONFIG_NATIVE_WINDOWS
1753                 alarm(0);
1754 #endif /* CONFIG_NATIVE_WINDOWS */
1755                 if (cmd == NULL)
1756                         break;
1757                 wpa_cli_recv_pending(ctrl_conn, 0, 0);
1758                 pos = cmd;
1759                 while (*pos != '\0') {
1760                         if (*pos == '\n') {
1761                                 *pos = '\0';
1762                                 break;
1763                         }
1764                         pos++;
1765                 }
1766                 argc = 0;
1767                 pos = cmd;
1768                 for (;;) {
1769                         while (*pos == ' ')
1770                                 pos++;
1771                         if (*pos == '\0')
1772                                 break;
1773                         argv[argc] = pos;
1774                         argc++;
1775                         if (argc == max_args)
1776                                 break;
1777                         if (*pos == '"') {
1778                                 char *pos2 = os_strrchr(pos, '"');
1779                                 if (pos2)
1780                                         pos = pos2 + 1;
1781                         }
1782                         while (*pos != '\0' && *pos != ' ')
1783                                 pos++;
1784                         if (*pos == ' ')
1785                                 *pos++ = '\0';
1786                 }
1787                 if (argc)
1788                         wpa_request(ctrl_conn, argc, argv);
1789
1790                 if (cmd != cmdbuf)
1791                         os_free(cmd);
1792         } while (!wpa_cli_quit);
1793
1794 #ifdef CONFIG_READLINE
1795         if (hfile) {
1796                 /* Save command history, excluding lines that may contain
1797                  * passwords. */
1798                 HIST_ENTRY *h;
1799                 history_set_pos(0);
1800                 while ((h = current_history())) {
1801                         char *p = h->line;
1802                         while (*p == ' ' || *p == '\t')
1803                                 p++;
1804                         if (cmd_has_sensitive_data(p)) {
1805                                 h = remove_history(where_history());
1806                                 if (h) {
1807                                         os_free(h->line);
1808                                         os_free(h->data);
1809                                         os_free(h);
1810                                 } else
1811                                         next_history();
1812                         } else
1813                                 next_history();
1814                 }
1815                 write_history(hfile);
1816                 os_free(hfile);
1817         }
1818 #endif /* CONFIG_READLINE */
1819 }
1820
1821
1822 static void wpa_cli_action(struct wpa_ctrl *ctrl)
1823 {
1824 #ifdef CONFIG_ANSI_C_EXTRA
1825         /* TODO: ANSI C version(?) */
1826         printf("Action processing not supported in ANSI C build.\n");
1827 #else /* CONFIG_ANSI_C_EXTRA */
1828         fd_set rfds;
1829         int fd, res;
1830         struct timeval tv;
1831         char buf[256]; /* note: large enough to fit in unsolicited messages */
1832         size_t len;
1833
1834         fd = wpa_ctrl_get_fd(ctrl);
1835
1836         while (!wpa_cli_quit) {
1837                 FD_ZERO(&rfds);
1838                 FD_SET(fd, &rfds);
1839                 tv.tv_sec = ping_interval;
1840                 tv.tv_usec = 0;
1841                 res = select(fd + 1, &rfds, NULL, NULL, &tv);
1842                 if (res < 0 && errno != EINTR) {
1843                         perror("select");
1844                         break;
1845                 }
1846
1847                 if (FD_ISSET(fd, &rfds))
1848                         wpa_cli_recv_pending(ctrl, 0, 1);
1849                 else {
1850                         /* verify that connection is still working */
1851                         len = sizeof(buf) - 1;
1852                         if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
1853                                              wpa_cli_action_cb) < 0 ||
1854                             len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
1855                                 printf("wpa_supplicant did not reply to PING "
1856                                        "command - exiting\n");
1857                                 break;
1858                         }
1859                 }
1860         }
1861 #endif /* CONFIG_ANSI_C_EXTRA */
1862 }
1863
1864
1865 static void wpa_cli_cleanup(void)
1866 {
1867         wpa_cli_close_connection();
1868         if (pid_file)
1869                 os_daemonize_terminate(pid_file);
1870
1871         os_program_deinit();
1872 }
1873
1874 static void wpa_cli_terminate(int sig)
1875 {
1876         wpa_cli_cleanup();
1877         exit(0);
1878 }
1879
1880
1881 #ifndef CONFIG_NATIVE_WINDOWS
1882 static void wpa_cli_alarm(int sig)
1883 {
1884         if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
1885                 printf("Connection to wpa_supplicant lost - trying to "
1886                        "reconnect\n");
1887                 wpa_cli_close_connection();
1888         }
1889         if (!ctrl_conn)
1890                 wpa_cli_reconnect();
1891         if (ctrl_conn)
1892                 wpa_cli_recv_pending(ctrl_conn, 1, 0);
1893         alarm(ping_interval);
1894 }
1895 #endif /* CONFIG_NATIVE_WINDOWS */
1896
1897
1898 static char * wpa_cli_get_default_ifname(void)
1899 {
1900         char *ifname = NULL;
1901
1902 #ifdef CONFIG_CTRL_IFACE_UNIX
1903         struct dirent *dent;
1904         DIR *dir = opendir(ctrl_iface_dir);
1905         if (!dir)
1906                 return NULL;
1907         while ((dent = readdir(dir))) {
1908 #ifdef _DIRENT_HAVE_D_TYPE
1909                 /*
1910                  * Skip the file if it is not a socket. Also accept
1911                  * DT_UNKNOWN (0) in case the C library or underlying
1912                  * file system does not support d_type.
1913                  */
1914                 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
1915                         continue;
1916 #endif /* _DIRENT_HAVE_D_TYPE */
1917                 if (os_strcmp(dent->d_name, ".") == 0 ||
1918                     os_strcmp(dent->d_name, "..") == 0)
1919                         continue;
1920                 printf("Selected interface '%s'\n", dent->d_name);
1921                 ifname = os_strdup(dent->d_name);
1922                 break;
1923         }
1924         closedir(dir);
1925 #endif /* CONFIG_CTRL_IFACE_UNIX */
1926
1927 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
1928         char buf[2048], *pos;
1929         size_t len;
1930         struct wpa_ctrl *ctrl;
1931         int ret;
1932
1933         ctrl = wpa_ctrl_open(NULL);
1934         if (ctrl == NULL)
1935                 return NULL;
1936
1937         len = sizeof(buf) - 1;
1938         ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
1939         if (ret >= 0) {
1940                 buf[len] = '\0';
1941                 pos = os_strchr(buf, '\n');
1942                 if (pos)
1943                         *pos = '\0';
1944                 ifname = os_strdup(buf);
1945         }
1946         wpa_ctrl_close(ctrl);
1947 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1948
1949         return ifname;
1950 }
1951
1952
1953 int main(int argc, char *argv[])
1954 {
1955         int interactive;
1956         int warning_displayed = 0;
1957         int c;
1958         int daemonize = 0;
1959         int ret = 0;
1960         const char *global = NULL;
1961
1962         if (os_program_init())
1963                 return -1;
1964
1965         for (;;) {
1966                 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
1967                 if (c < 0)
1968                         break;
1969                 switch (c) {
1970                 case 'a':
1971                         action_file = optarg;
1972                         break;
1973                 case 'B':
1974                         daemonize = 1;
1975                         break;
1976                 case 'g':
1977                         global = optarg;
1978                         break;
1979                 case 'G':
1980                         ping_interval = atoi(optarg);
1981                         break;
1982                 case 'h':
1983                         usage();
1984                         return 0;
1985                 case 'v':
1986                         printf("%s\n", wpa_cli_version);
1987                         return 0;
1988                 case 'i':
1989                         os_free(ctrl_ifname);
1990                         ctrl_ifname = os_strdup(optarg);
1991                         break;
1992                 case 'p':
1993                         ctrl_iface_dir = optarg;
1994                         break;
1995                 case 'P':
1996                         pid_file = optarg;
1997                         break;
1998                 default:
1999                         usage();
2000                         return -1;
2001                 }
2002         }
2003
2004         interactive = (argc == optind) && (action_file == NULL);
2005
2006         if (interactive)
2007                 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
2008
2009         if (global) {
2010 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2011                 ctrl_conn = wpa_ctrl_open(NULL);
2012 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2013                 ctrl_conn = wpa_ctrl_open(global);
2014 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2015                 if (ctrl_conn == NULL) {
2016                         perror("Failed to connect to wpa_supplicant - "
2017                                "wpa_ctrl_open");
2018                         return -1;
2019                 }
2020         }
2021
2022         for (; !global;) {
2023                 if (ctrl_ifname == NULL)
2024                         ctrl_ifname = wpa_cli_get_default_ifname();
2025                 ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
2026                 if (ctrl_conn) {
2027                         if (warning_displayed)
2028                                 printf("Connection established.\n");
2029                         break;
2030                 }
2031
2032                 if (!interactive) {
2033                         perror("Failed to connect to wpa_supplicant - "
2034                                "wpa_ctrl_open");
2035                         return -1;
2036                 }
2037
2038                 if (!warning_displayed) {
2039                         printf("Could not connect to wpa_supplicant - "
2040                                "re-trying\n");
2041                         warning_displayed = 1;
2042                 }
2043                 os_sleep(1, 0);
2044                 continue;
2045         }
2046
2047 #ifndef _WIN32_WCE
2048         signal(SIGINT, wpa_cli_terminate);
2049         signal(SIGTERM, wpa_cli_terminate);
2050 #endif /* _WIN32_WCE */
2051 #ifndef CONFIG_NATIVE_WINDOWS
2052         signal(SIGALRM, wpa_cli_alarm);
2053 #endif /* CONFIG_NATIVE_WINDOWS */
2054
2055         if (interactive || action_file) {
2056                 if (wpa_ctrl_attach(ctrl_conn) == 0) {
2057                         wpa_cli_attached = 1;
2058                 } else {
2059                         printf("Warning: Failed to attach to "
2060                                "wpa_supplicant.\n");
2061                         if (!interactive)
2062                                 return -1;
2063                 }
2064         }
2065
2066         if (daemonize && os_daemonize(pid_file))
2067                 return -1;
2068
2069         if (interactive)
2070                 wpa_cli_interactive();
2071         else if (action_file)
2072                 wpa_cli_action(ctrl_conn);
2073         else
2074                 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
2075
2076         os_free(ctrl_ifname);
2077         wpa_cli_cleanup();
2078
2079         return ret;
2080 }
2081
2082 #else /* CONFIG_CTRL_IFACE */
2083 int main(int argc, char *argv[])
2084 {
2085         printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
2086         return -1;
2087 }
2088 #endif /* CONFIG_CTRL_IFACE */