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