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