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