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