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