blob: 1d27f335c7fcdfaa18eedff95eb536b2b47741a6 [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2011, 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
23#include "common/wpa_ctrl.h"
24#include "utils/common.h"
25#include "utils/eloop.h"
26#include "utils/edit.h"
27#include "common/version.h"
28#ifdef ANDROID
29#include <cutils/properties.h>
30#endif /* ANDROID */
31
32
33static const char *wpa_cli_version =
34"wpa_cli v" VERSION_STR "\n"
35"Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi> and contributors";
36
37
38static const char *wpa_cli_license =
39"This program is free software. You can distribute it and/or modify it\n"
40"under the terms of the GNU General Public License version 2.\n"
41"\n"
42"Alternatively, this software may be distributed under the terms of the\n"
43"BSD license. See README and COPYING for more details.\n";
44
45static const char *wpa_cli_full_license =
46"This program is free software; you can redistribute it and/or modify\n"
47"it under the terms of the GNU General Public License version 2 as\n"
48"published by the Free Software Foundation.\n"
49"\n"
50"This program is distributed in the hope that it will be useful,\n"
51"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
52"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
53"GNU General Public License for more details.\n"
54"\n"
55"You should have received a copy of the GNU General Public License\n"
56"along with this program; if not, write to the Free Software\n"
57"Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
58"\n"
59"Alternatively, this software may be distributed under the terms of the\n"
60"BSD license.\n"
61"\n"
62"Redistribution and use in source and binary forms, with or without\n"
63"modification, are permitted provided that the following conditions are\n"
64"met:\n"
65"\n"
66"1. Redistributions of source code must retain the above copyright\n"
67" notice, this list of conditions and the following disclaimer.\n"
68"\n"
69"2. Redistributions in binary form must reproduce the above copyright\n"
70" notice, this list of conditions and the following disclaimer in the\n"
71" documentation and/or other materials provided with the distribution.\n"
72"\n"
73"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
74" names of its contributors may be used to endorse or promote products\n"
75" derived from this software without specific prior written permission.\n"
76"\n"
77"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
78"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
79"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
80"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
81"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
82"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
83"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
84"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
85"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
86"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
87"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
88"\n";
89
90static struct wpa_ctrl *ctrl_conn;
91static struct wpa_ctrl *mon_conn;
92static int wpa_cli_quit = 0;
93static int wpa_cli_attached = 0;
94static int wpa_cli_connected = 0;
95static int wpa_cli_last_id = 0;
96#ifndef CONFIG_CTRL_IFACE_DIR
97#define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
98#endif /* CONFIG_CTRL_IFACE_DIR */
99static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
100static char *ctrl_ifname = NULL;
101static const char *pid_file = NULL;
102static const char *action_file = NULL;
103static int ping_interval = 5;
104static int interactive = 0;
105
106
107static void print_help(void);
108static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
109
110
111static void usage(void)
112{
113 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
114 "[-a<action file>] \\\n"
115 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
116 "[command..]\n"
117 " -h = help (show this usage text)\n"
118 " -v = shown version information\n"
119 " -a = run in daemon mode executing the action file based on "
120 "events from\n"
121 " wpa_supplicant\n"
122 " -B = run a daemon in the background\n"
123 " default path: " CONFIG_CTRL_IFACE_DIR "\n"
124 " default interface: first interface found in socket path\n");
125 print_help();
126}
127
128
129static int str_starts(const char *src, const char *match)
130{
131 return os_strncmp(src, match, os_strlen(match)) == 0;
132}
133
134
135static int wpa_cli_show_event(const char *event)
136{
137 const char *start;
138
139 start = os_strchr(event, '>');
140 if (start == NULL)
141 return 1;
142
143 start++;
144 /*
145 * Skip BSS added/removed events since they can be relatively frequent
146 * and are likely of not much use for an interactive user.
147 */
148 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
149 str_starts(start, WPA_EVENT_BSS_REMOVED))
150 return 0;
151
152 return 1;
153}
154
155
156static int wpa_cli_open_connection(const char *ifname, int attach)
157{
158#if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
159 ctrl_conn = wpa_ctrl_open(ifname);
160 if (ctrl_conn == NULL)
161 return -1;
162
163 if (attach && interactive)
164 mon_conn = wpa_ctrl_open(ifname);
165 else
166 mon_conn = NULL;
167#else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
168 char *cfile = NULL;
169 int flen, res;
170
171 if (ifname == NULL)
172 return -1;
173
174#ifdef ANDROID
175 if (access(ctrl_iface_dir, F_OK) < 0) {
176 cfile = os_strdup(ifname);
177 if (cfile == NULL)
178 return -1;
179 }
180#endif /* ANDROID */
181
182 if (cfile == NULL) {
183 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
184 cfile = os_malloc(flen);
185 if (cfile == NULL)
186 return -1;
187 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
188 ifname);
189 if (res < 0 || res >= flen) {
190 os_free(cfile);
191 return -1;
192 }
193 }
194
195 ctrl_conn = wpa_ctrl_open(cfile);
196 if (ctrl_conn == NULL) {
197 os_free(cfile);
198 return -1;
199 }
200
201 if (attach && interactive)
202 mon_conn = wpa_ctrl_open(cfile);
203 else
204 mon_conn = NULL;
205 os_free(cfile);
206#endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
207
208 if (mon_conn) {
209 if (wpa_ctrl_attach(mon_conn) == 0) {
210 wpa_cli_attached = 1;
211 if (interactive)
212 eloop_register_read_sock(
213 wpa_ctrl_get_fd(mon_conn),
214 wpa_cli_mon_receive, NULL, NULL);
215 } else {
216 printf("Warning: Failed to attach to "
217 "wpa_supplicant.\n");
218 return -1;
219 }
220 }
221
222 return 0;
223}
224
225
226static void wpa_cli_close_connection(void)
227{
228 if (ctrl_conn == NULL)
229 return;
230
231 if (wpa_cli_attached) {
232 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
233 wpa_cli_attached = 0;
234 }
235 wpa_ctrl_close(ctrl_conn);
236 ctrl_conn = NULL;
237 if (mon_conn) {
238 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
239 wpa_ctrl_close(mon_conn);
240 mon_conn = NULL;
241 }
242}
243
244
245static void wpa_cli_msg_cb(char *msg, size_t len)
246{
247 printf("%s\n", msg);
248}
249
250
251static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
252{
253 char buf[2048];
254 size_t len;
255 int ret;
256
257 if (ctrl_conn == NULL) {
258 printf("Not connected to wpa_supplicant - command dropped.\n");
259 return -1;
260 }
261 len = sizeof(buf) - 1;
262 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
263 wpa_cli_msg_cb);
264 if (ret == -2) {
265 printf("'%s' command timed out.\n", cmd);
266 return -2;
267 } else if (ret < 0) {
268 printf("'%s' command failed.\n", cmd);
269 return -1;
270 }
271 if (print) {
272 buf[len] = '\0';
273 printf("%s", buf);
274 if (interactive && len > 0 && buf[len - 1] != '\n')
275 printf("\n");
276 }
277 return 0;
278}
279
280
281static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
282{
283 return _wpa_ctrl_command(ctrl, cmd, 1);
284}
285
286
287static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
288{
289 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
290 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
291}
292
293
294static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
295{
296 return wpa_ctrl_command(ctrl, "PING");
297}
298
299
300static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
301{
302 return wpa_ctrl_command(ctrl, "RELOG");
303}
304
305
306static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
307{
308 char cmd[256];
309 int ret;
310 if (argc == 0)
311 return -1;
312 ret = os_snprintf(cmd, sizeof(cmd), "NOTE %s", argv[0]);
313 if (ret < 0 || (size_t) ret >= sizeof(cmd))
314 return -1;
315 return wpa_ctrl_command(ctrl, cmd);
316}
317
318
319static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
320{
321 return wpa_ctrl_command(ctrl, "MIB");
322}
323
324
325static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
326{
327 return wpa_ctrl_command(ctrl, "PMKSA");
328}
329
330
331static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
332{
333 print_help();
334 return 0;
335}
336
337
338static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
339{
340 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
341 return 0;
342}
343
344
345static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
346{
347 wpa_cli_quit = 1;
348 if (interactive)
349 eloop_terminate();
350 return 0;
351}
352
353
354static void wpa_cli_show_variables(void)
355{
356 printf("set variables:\n"
357 " EAPOL::heldPeriod (EAPOL state machine held period, "
358 "in seconds)\n"
359 " EAPOL::authPeriod (EAPOL state machine authentication "
360 "period, in seconds)\n"
361 " EAPOL::startPeriod (EAPOL state machine start period, in "
362 "seconds)\n"
363 " EAPOL::maxStart (EAPOL state machine maximum start "
364 "attempts)\n");
365 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
366 "seconds)\n"
367 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
368 " threshold\n\tpercentage)\n"
369 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
370 "security\n\tassociation in seconds)\n");
371}
372
373
374static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
375{
376 char cmd[256];
377 int res;
378
379 if (argc == 0) {
380 wpa_cli_show_variables();
381 return 0;
382 }
383
384 if (argc != 2) {
385 printf("Invalid SET command: needs two arguments (variable "
386 "name and value)\n");
387 return -1;
388 }
389
390 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
391 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
392 printf("Too long SET command.\n");
393 return -1;
394 }
395 return wpa_ctrl_command(ctrl, cmd);
396}
397
398
399static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
400{
401 char cmd[256];
402 int res;
403
404 if (argc != 1) {
405 printf("Invalid GET command: need one argument (variable "
406 "name)\n");
407 return -1;
408 }
409
410 res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
411 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
412 printf("Too long GET command.\n");
413 return -1;
414 }
415 return wpa_ctrl_command(ctrl, cmd);
416}
417
418
419static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
420{
421 return wpa_ctrl_command(ctrl, "LOGOFF");
422}
423
424
425static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
426{
427 return wpa_ctrl_command(ctrl, "LOGON");
428}
429
430
431static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
432 char *argv[])
433{
434 return wpa_ctrl_command(ctrl, "REASSOCIATE");
435}
436
437
438static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
439 char *argv[])
440{
441 char cmd[256];
442 int res;
443
444 if (argc != 1) {
445 printf("Invalid PREAUTH command: needs one argument "
446 "(BSSID)\n");
447 return -1;
448 }
449
450 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
451 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
452 printf("Too long PREAUTH command.\n");
453 return -1;
454 }
455 return wpa_ctrl_command(ctrl, cmd);
456}
457
458
459static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
460{
461 char cmd[256];
462 int res;
463
464 if (argc != 1) {
465 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
466 "value)\n");
467 return -1;
468 }
469 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
470 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
471 printf("Too long AP_SCAN command.\n");
472 return -1;
473 }
474 return wpa_ctrl_command(ctrl, cmd);
475}
476
477
478static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
479 char *argv[])
480{
481 char cmd[256];
482 int res;
483
484 if (argc != 1) {
485 printf("Invalid SCAN_INTERVAL command: needs one argument "
486 "scan_interval value)\n");
487 return -1;
488 }
489 res = os_snprintf(cmd, sizeof(cmd), "SCAN_INTERVAL %s", argv[0]);
490 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
491 printf("Too long SCAN_INTERVAL command.\n");
492 return -1;
493 }
494 return wpa_ctrl_command(ctrl, cmd);
495}
496
497
498static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
499 char *argv[])
500{
501 char cmd[256];
502 int res;
503
504 if (argc != 1) {
505 printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
506 "(bss_expire_age value)\n");
507 return -1;
508 }
509 res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_AGE %s", argv[0]);
510 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
511 printf("Too long BSS_EXPIRE_AGE command.\n");
512 return -1;
513 }
514 return wpa_ctrl_command(ctrl, cmd);
515}
516
517
518static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
519 char *argv[])
520{
521 char cmd[256];
522 int res;
523
524 if (argc != 1) {
525 printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
526 "(bss_expire_count value)\n");
527 return -1;
528 }
529 res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_COUNT %s", argv[0]);
530 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
531 printf("Too long BSS_EXPIRE_COUNT command.\n");
532 return -1;
533 }
534 return wpa_ctrl_command(ctrl, cmd);
535}
536
537
538static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
539 char *argv[])
540{
541 char cmd[256];
542 int res;
543
544 if (argc != 1) {
545 printf("Invalid STKSTART command: needs one argument "
546 "(Peer STA MAC address)\n");
547 return -1;
548 }
549
550 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
551 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
552 printf("Too long STKSTART command.\n");
553 return -1;
554 }
555 return wpa_ctrl_command(ctrl, cmd);
556}
557
558
559static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
560{
561 char cmd[256];
562 int res;
563
564 if (argc != 1) {
565 printf("Invalid FT_DS command: needs one argument "
566 "(Target AP MAC address)\n");
567 return -1;
568 }
569
570 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
571 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
572 printf("Too long FT_DS command.\n");
573 return -1;
574 }
575 return wpa_ctrl_command(ctrl, cmd);
576}
577
578
579static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
580{
581 char cmd[256];
582 int res;
583
584 if (argc == 0) {
585 /* Any BSSID */
586 return wpa_ctrl_command(ctrl, "WPS_PBC");
587 }
588
589 /* Specific BSSID */
590 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
591 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
592 printf("Too long WPS_PBC command.\n");
593 return -1;
594 }
595 return wpa_ctrl_command(ctrl, cmd);
596}
597
598
599static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
600{
601 char cmd[256];
602 int res;
603
604 if (argc == 0) {
605 printf("Invalid WPS_PIN command: need one or two arguments:\n"
606 "- BSSID: use 'any' to select any\n"
607 "- PIN: optional, used only with devices that have no "
608 "display\n");
609 return -1;
610 }
611
612 if (argc == 1) {
613 /* Use dynamically generated PIN (returned as reply) */
614 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
615 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
616 printf("Too long WPS_PIN command.\n");
617 return -1;
618 }
619 return wpa_ctrl_command(ctrl, cmd);
620 }
621
622 /* Use hardcoded PIN from a label */
623 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
624 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
625 printf("Too long WPS_PIN command.\n");
626 return -1;
627 }
628 return wpa_ctrl_command(ctrl, cmd);
629}
630
631
632static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
633 char *argv[])
634{
635 char cmd[256];
636 int res;
637
638 if (argc != 1 && argc != 2) {
639 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
640 "- PIN to be verified\n");
641 return -1;
642 }
643
644 if (argc == 2)
645 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
646 argv[0], argv[1]);
647 else
648 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
649 argv[0]);
650 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
651 printf("Too long WPS_CHECK_PIN command.\n");
652 return -1;
653 }
654 return wpa_ctrl_command(ctrl, cmd);
655}
656
657
658static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
659 char *argv[])
660{
661 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
662}
663
664
665#ifdef CONFIG_WPS_OOB
666static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
667{
668 char cmd[256];
669 int res;
670
671 if (argc != 3 && argc != 4) {
672 printf("Invalid WPS_OOB command: need three or four "
673 "arguments:\n"
674 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
675 "- PATH: path of OOB device like '/mnt'\n"
676 "- METHOD: OOB method 'pin-e' or 'pin-r', "
677 "'cred'\n"
678 "- DEV_NAME: (only for NFC) device name like "
679 "'pn531'\n");
680 return -1;
681 }
682
683 if (argc == 3)
684 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
685 argv[0], argv[1], argv[2]);
686 else
687 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
688 argv[0], argv[1], argv[2], argv[3]);
689 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
690 printf("Too long WPS_OOB command.\n");
691 return -1;
692 }
693 return wpa_ctrl_command(ctrl, cmd);
694}
695#endif /* CONFIG_WPS_OOB */
696
697
698static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
699{
700 char cmd[256];
701 int res;
702
703 if (argc == 2)
704 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
705 argv[0], argv[1]);
706 else if (argc == 5 || argc == 6) {
707 char ssid_hex[2 * 32 + 1];
708 char key_hex[2 * 64 + 1];
709 int i;
710
711 ssid_hex[0] = '\0';
712 for (i = 0; i < 32; i++) {
713 if (argv[2][i] == '\0')
714 break;
715 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
716 }
717
718 key_hex[0] = '\0';
719 if (argc == 6) {
720 for (i = 0; i < 64; i++) {
721 if (argv[5][i] == '\0')
722 break;
723 os_snprintf(&key_hex[i * 2], 3, "%02x",
724 argv[5][i]);
725 }
726 }
727
728 res = os_snprintf(cmd, sizeof(cmd),
729 "WPS_REG %s %s %s %s %s %s",
730 argv[0], argv[1], ssid_hex, argv[3], argv[4],
731 key_hex);
732 } else {
733 printf("Invalid WPS_REG command: need two arguments:\n"
734 "- BSSID of the target AP\n"
735 "- AP PIN\n");
736 printf("Alternatively, six arguments can be used to "
737 "reconfigure the AP:\n"
738 "- BSSID of the target AP\n"
739 "- AP PIN\n"
740 "- new SSID\n"
741 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
742 "- new encr (NONE, WEP, TKIP, CCMP)\n"
743 "- new key\n");
744 return -1;
745 }
746
747 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
748 printf("Too long WPS_REG command.\n");
749 return -1;
750 }
751 return wpa_ctrl_command(ctrl, cmd);
752}
753
754
755static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
756 char *argv[])
757{
758 char cmd[256];
759 int res;
760
761 if (argc < 1) {
762 printf("Invalid WPS_AP_PIN command: needs at least one "
763 "argument\n");
764 return -1;
765 }
766
767 if (argc > 2)
768 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s %s",
769 argv[0], argv[1], argv[2]);
770 else if (argc > 1)
771 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s",
772 argv[0], argv[1]);
773 else
774 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s",
775 argv[0]);
776 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
777 printf("Too long WPS_AP_PIN command.\n");
778 return -1;
779 }
780 return wpa_ctrl_command(ctrl, cmd);
781}
782
783
784static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
785 char *argv[])
786{
787 char cmd[100];
788 if (argc > 0) {
789 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
790 return wpa_ctrl_command(ctrl, cmd);
791 }
792 return wpa_ctrl_command(ctrl, "WPS_ER_START");
793}
794
795
796static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
797 char *argv[])
798{
799 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
800
801}
802
803
804static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
805 char *argv[])
806{
807 char cmd[256];
808 int res;
809
810 if (argc < 2) {
811 printf("Invalid WPS_ER_PIN command: need at least two "
812 "arguments:\n"
813 "- UUID: use 'any' to select any\n"
814 "- PIN: Enrollee PIN\n"
815 "optional: - Enrollee MAC address\n");
816 return -1;
817 }
818
819 if (argc > 2)
820 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
821 argv[0], argv[1], argv[2]);
822 else
823 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
824 argv[0], argv[1]);
825 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
826 printf("Too long WPS_ER_PIN command.\n");
827 return -1;
828 }
829 return wpa_ctrl_command(ctrl, cmd);
830}
831
832
833static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
834 char *argv[])
835{
836 char cmd[256];
837 int res;
838
839 if (argc != 1) {
840 printf("Invalid WPS_ER_PBC command: need one argument:\n"
841 "- UUID: Specify the Enrollee\n");
842 return -1;
843 }
844
845 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
846 argv[0]);
847 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
848 printf("Too long WPS_ER_PBC command.\n");
849 return -1;
850 }
851 return wpa_ctrl_command(ctrl, cmd);
852}
853
854
855static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
856 char *argv[])
857{
858 char cmd[256];
859 int res;
860
861 if (argc != 2) {
862 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
863 "- UUID: specify which AP to use\n"
864 "- PIN: AP PIN\n");
865 return -1;
866 }
867
868 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
869 argv[0], argv[1]);
870 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
871 printf("Too long WPS_ER_LEARN command.\n");
872 return -1;
873 }
874 return wpa_ctrl_command(ctrl, cmd);
875}
876
877
878static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
879 char *argv[])
880{
881 char cmd[256];
882 int res;
883
884 if (argc != 2) {
885 printf("Invalid WPS_ER_SET_CONFIG command: need two "
886 "arguments:\n"
887 "- UUID: specify which AP to use\n"
888 "- Network configuration id\n");
889 return -1;
890 }
891
892 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_SET_CONFIG %s %s",
893 argv[0], argv[1]);
894 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
895 printf("Too long WPS_ER_SET_CONFIG command.\n");
896 return -1;
897 }
898 return wpa_ctrl_command(ctrl, cmd);
899}
900
901
902static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
903 char *argv[])
904{
905 char cmd[256];
906 int res;
907
908 if (argc == 5 || argc == 6) {
909 char ssid_hex[2 * 32 + 1];
910 char key_hex[2 * 64 + 1];
911 int i;
912
913 ssid_hex[0] = '\0';
914 for (i = 0; i < 32; i++) {
915 if (argv[2][i] == '\0')
916 break;
917 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
918 }
919
920 key_hex[0] = '\0';
921 if (argc == 6) {
922 for (i = 0; i < 64; i++) {
923 if (argv[5][i] == '\0')
924 break;
925 os_snprintf(&key_hex[i * 2], 3, "%02x",
926 argv[5][i]);
927 }
928 }
929
930 res = os_snprintf(cmd, sizeof(cmd),
931 "WPS_ER_CONFIG %s %s %s %s %s %s",
932 argv[0], argv[1], ssid_hex, argv[3], argv[4],
933 key_hex);
934 } else {
935 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
936 "- AP UUID\n"
937 "- AP PIN\n"
938 "- new SSID\n"
939 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
940 "- new encr (NONE, WEP, TKIP, CCMP)\n"
941 "- new key\n");
942 return -1;
943 }
944
945 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
946 printf("Too long WPS_ER_CONFIG command.\n");
947 return -1;
948 }
949 return wpa_ctrl_command(ctrl, cmd);
950}
951
952
953static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
954{
955 char cmd[256];
956 int res;
957
958 if (argc != 1) {
959 printf("Invalid IBSS_RSN command: needs one argument "
960 "(Peer STA MAC address)\n");
961 return -1;
962 }
963
964 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
965 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
966 printf("Too long IBSS_RSN command.\n");
967 return -1;
968 }
969 return wpa_ctrl_command(ctrl, cmd);
970}
971
972
973static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
974{
975 char cmd[256];
976 int res;
977
978 if (argc != 1) {
979 printf("Invalid LEVEL command: needs one argument (debug "
980 "level)\n");
981 return -1;
982 }
983 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
984 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
985 printf("Too long LEVEL command.\n");
986 return -1;
987 }
988 return wpa_ctrl_command(ctrl, cmd);
989}
990
991
992static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
993{
994 char cmd[256], *pos, *end;
995 int i, ret;
996
997 if (argc < 2) {
998 printf("Invalid IDENTITY command: needs two arguments "
999 "(network id and identity)\n");
1000 return -1;
1001 }
1002
1003 end = cmd + sizeof(cmd);
1004 pos = cmd;
1005 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1006 argv[0], argv[1]);
1007 if (ret < 0 || ret >= end - pos) {
1008 printf("Too long IDENTITY command.\n");
1009 return -1;
1010 }
1011 pos += ret;
1012 for (i = 2; i < argc; i++) {
1013 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1014 if (ret < 0 || ret >= end - pos) {
1015 printf("Too long IDENTITY command.\n");
1016 return -1;
1017 }
1018 pos += ret;
1019 }
1020
1021 return wpa_ctrl_command(ctrl, cmd);
1022}
1023
1024
1025static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1026{
1027 char cmd[256], *pos, *end;
1028 int i, ret;
1029
1030 if (argc < 2) {
1031 printf("Invalid PASSWORD command: needs two arguments "
1032 "(network id and password)\n");
1033 return -1;
1034 }
1035
1036 end = cmd + sizeof(cmd);
1037 pos = cmd;
1038 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1039 argv[0], argv[1]);
1040 if (ret < 0 || ret >= end - pos) {
1041 printf("Too long PASSWORD command.\n");
1042 return -1;
1043 }
1044 pos += ret;
1045 for (i = 2; i < argc; i++) {
1046 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1047 if (ret < 0 || ret >= end - pos) {
1048 printf("Too long PASSWORD command.\n");
1049 return -1;
1050 }
1051 pos += ret;
1052 }
1053
1054 return wpa_ctrl_command(ctrl, cmd);
1055}
1056
1057
1058static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1059 char *argv[])
1060{
1061 char cmd[256], *pos, *end;
1062 int i, ret;
1063
1064 if (argc < 2) {
1065 printf("Invalid NEW_PASSWORD command: needs two arguments "
1066 "(network id and password)\n");
1067 return -1;
1068 }
1069
1070 end = cmd + sizeof(cmd);
1071 pos = cmd;
1072 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1073 argv[0], argv[1]);
1074 if (ret < 0 || ret >= end - pos) {
1075 printf("Too long NEW_PASSWORD command.\n");
1076 return -1;
1077 }
1078 pos += ret;
1079 for (i = 2; i < argc; i++) {
1080 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1081 if (ret < 0 || ret >= end - pos) {
1082 printf("Too long NEW_PASSWORD command.\n");
1083 return -1;
1084 }
1085 pos += ret;
1086 }
1087
1088 return wpa_ctrl_command(ctrl, cmd);
1089}
1090
1091
1092static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1093{
1094 char cmd[256], *pos, *end;
1095 int i, ret;
1096
1097 if (argc < 2) {
1098 printf("Invalid PIN command: needs two arguments "
1099 "(network id and pin)\n");
1100 return -1;
1101 }
1102
1103 end = cmd + sizeof(cmd);
1104 pos = cmd;
1105 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1106 argv[0], argv[1]);
1107 if (ret < 0 || ret >= end - pos) {
1108 printf("Too long PIN command.\n");
1109 return -1;
1110 }
1111 pos += ret;
1112 for (i = 2; i < argc; i++) {
1113 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1114 if (ret < 0 || ret >= end - pos) {
1115 printf("Too long PIN command.\n");
1116 return -1;
1117 }
1118 pos += ret;
1119 }
1120 return wpa_ctrl_command(ctrl, cmd);
1121}
1122
1123
1124static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1125{
1126 char cmd[256], *pos, *end;
1127 int i, ret;
1128
1129 if (argc < 2) {
1130 printf("Invalid OTP command: needs two arguments (network "
1131 "id and password)\n");
1132 return -1;
1133 }
1134
1135 end = cmd + sizeof(cmd);
1136 pos = cmd;
1137 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1138 argv[0], argv[1]);
1139 if (ret < 0 || ret >= end - pos) {
1140 printf("Too long OTP command.\n");
1141 return -1;
1142 }
1143 pos += ret;
1144 for (i = 2; i < argc; i++) {
1145 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1146 if (ret < 0 || ret >= end - pos) {
1147 printf("Too long OTP command.\n");
1148 return -1;
1149 }
1150 pos += ret;
1151 }
1152
1153 return wpa_ctrl_command(ctrl, cmd);
1154}
1155
1156
1157static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1158 char *argv[])
1159{
1160 char cmd[256], *pos, *end;
1161 int i, ret;
1162
1163 if (argc < 2) {
1164 printf("Invalid PASSPHRASE command: needs two arguments "
1165 "(network id and passphrase)\n");
1166 return -1;
1167 }
1168
1169 end = cmd + sizeof(cmd);
1170 pos = cmd;
1171 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1172 argv[0], argv[1]);
1173 if (ret < 0 || ret >= end - pos) {
1174 printf("Too long PASSPHRASE command.\n");
1175 return -1;
1176 }
1177 pos += ret;
1178 for (i = 2; i < argc; i++) {
1179 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1180 if (ret < 0 || ret >= end - pos) {
1181 printf("Too long PASSPHRASE command.\n");
1182 return -1;
1183 }
1184 pos += ret;
1185 }
1186
1187 return wpa_ctrl_command(ctrl, cmd);
1188}
1189
1190
1191static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1192{
1193 char cmd[256], *pos, *end;
1194 int i, ret;
1195
1196 if (argc < 2) {
1197 printf("Invalid BSSID command: needs two arguments (network "
1198 "id and BSSID)\n");
1199 return -1;
1200 }
1201
1202 end = cmd + sizeof(cmd);
1203 pos = cmd;
1204 ret = os_snprintf(pos, end - pos, "BSSID");
1205 if (ret < 0 || ret >= end - pos) {
1206 printf("Too long BSSID command.\n");
1207 return -1;
1208 }
1209 pos += ret;
1210 for (i = 0; i < argc; i++) {
1211 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1212 if (ret < 0 || ret >= end - pos) {
1213 printf("Too long BSSID command.\n");
1214 return -1;
1215 }
1216 pos += ret;
1217 }
1218
1219 return wpa_ctrl_command(ctrl, cmd);
1220}
1221
1222
Dmitry Shmidt696359e2011-03-16 15:04:31 -07001223static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1224{
1225 char cmd[256], *pos, *end;
1226 int i, ret;
1227
1228 end = cmd + sizeof(cmd);
1229 pos = cmd;
1230 ret = os_snprintf(pos, end - pos, "BLACKLIST");
1231 if (ret < 0 || ret >= end - pos) {
1232 printf("Too long BLACKLIST command.\n");
1233 return -1;
1234 }
1235 pos += ret;
1236 for (i = 0; i < argc; i++) {
1237 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1238 if (ret < 0 || ret >= end - pos) {
1239 printf("Too long BLACKLIST command.\n");
1240 return -1;
1241 }
1242 pos += ret;
1243 }
1244
1245 return wpa_ctrl_command(ctrl, cmd);
1246}
1247
1248
1249static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1250{
1251 char cmd[256], *pos, *end;
1252 int i, ret;
1253
1254 end = cmd + sizeof(cmd);
1255 pos = cmd;
1256 ret = os_snprintf(pos, end - pos, "LOG_LEVEL");
1257 if (ret < 0 || ret >= end - pos) {
1258 printf("Too long LOG_LEVEL command.\n");
1259 return -1;
1260 }
1261 pos += ret;
1262 for (i = 0; i < argc; i++) {
1263 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1264 if (ret < 0 || ret >= end - pos) {
1265 printf("Too long LOG_LEVEL command.\n");
1266 return -1;
1267 }
1268 pos += ret;
1269 }
1270
1271 return wpa_ctrl_command(ctrl, cmd);
1272}
1273
1274
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001275static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1276 char *argv[])
1277{
1278 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1279}
1280
1281
1282static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1283 char *argv[])
1284{
1285 char cmd[32];
1286 int res;
1287
1288 if (argc < 1) {
1289 printf("Invalid SELECT_NETWORK command: needs one argument "
1290 "(network id)\n");
1291 return -1;
1292 }
1293
1294 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1295 if (res < 0 || (size_t) res >= sizeof(cmd))
1296 return -1;
1297 cmd[sizeof(cmd) - 1] = '\0';
1298
1299 return wpa_ctrl_command(ctrl, cmd);
1300}
1301
1302
1303static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1304 char *argv[])
1305{
1306 char cmd[32];
1307 int res;
1308
1309 if (argc < 1) {
1310 printf("Invalid ENABLE_NETWORK command: needs one argument "
1311 "(network id)\n");
1312 return -1;
1313 }
1314
1315 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1316 if (res < 0 || (size_t) res >= sizeof(cmd))
1317 return -1;
1318 cmd[sizeof(cmd) - 1] = '\0';
1319
1320 return wpa_ctrl_command(ctrl, cmd);
1321}
1322
1323
1324static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1325 char *argv[])
1326{
1327 char cmd[32];
1328 int res;
1329
1330 if (argc < 1) {
1331 printf("Invalid DISABLE_NETWORK command: needs one argument "
1332 "(network id)\n");
1333 return -1;
1334 }
1335
1336 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1337 if (res < 0 || (size_t) res >= sizeof(cmd))
1338 return -1;
1339 cmd[sizeof(cmd) - 1] = '\0';
1340
1341 return wpa_ctrl_command(ctrl, cmd);
1342}
1343
1344
1345static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1346 char *argv[])
1347{
1348 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1349}
1350
1351
1352static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1353 char *argv[])
1354{
1355 char cmd[32];
1356 int res;
1357
1358 if (argc < 1) {
1359 printf("Invalid REMOVE_NETWORK command: needs one argument "
1360 "(network id)\n");
1361 return -1;
1362 }
1363
1364 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1365 if (res < 0 || (size_t) res >= sizeof(cmd))
1366 return -1;
1367 cmd[sizeof(cmd) - 1] = '\0';
1368
1369 return wpa_ctrl_command(ctrl, cmd);
1370}
1371
1372
1373static void wpa_cli_show_network_variables(void)
1374{
1375 printf("set_network variables:\n"
1376 " ssid (network name, SSID)\n"
1377 " psk (WPA passphrase or pre-shared key)\n"
1378 " key_mgmt (key management protocol)\n"
1379 " identity (EAP identity)\n"
1380 " password (EAP password)\n"
1381 " ...\n"
1382 "\n"
1383 "Note: Values are entered in the same format as the "
1384 "configuration file is using,\n"
1385 "i.e., strings values need to be inside double quotation "
1386 "marks.\n"
1387 "For example: set_network 1 ssid \"network name\"\n"
1388 "\n"
1389 "Please see wpa_supplicant.conf documentation for full list "
1390 "of\navailable variables.\n");
1391}
1392
1393
1394static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1395 char *argv[])
1396{
1397 char cmd[256];
1398 int res;
1399
1400 if (argc == 0) {
1401 wpa_cli_show_network_variables();
1402 return 0;
1403 }
1404
1405 if (argc != 3) {
1406 printf("Invalid SET_NETWORK command: needs three arguments\n"
1407 "(network id, variable name, and value)\n");
1408 return -1;
1409 }
1410
1411 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1412 argv[0], argv[1], argv[2]);
1413 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1414 printf("Too long SET_NETWORK command.\n");
1415 return -1;
1416 }
1417 return wpa_ctrl_command(ctrl, cmd);
1418}
1419
1420
1421static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1422 char *argv[])
1423{
1424 char cmd[256];
1425 int res;
1426
1427 if (argc == 0) {
1428 wpa_cli_show_network_variables();
1429 return 0;
1430 }
1431
1432 if (argc != 2) {
1433 printf("Invalid GET_NETWORK command: needs two arguments\n"
1434 "(network id and variable name)\n");
1435 return -1;
1436 }
1437
1438 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1439 argv[0], argv[1]);
1440 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1441 printf("Too long GET_NETWORK command.\n");
1442 return -1;
1443 }
1444 return wpa_ctrl_command(ctrl, cmd);
1445}
1446
1447
1448static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1449 char *argv[])
1450{
1451 return wpa_ctrl_command(ctrl, "DISCONNECT");
1452}
1453
1454
1455static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1456 char *argv[])
1457{
1458 return wpa_ctrl_command(ctrl, "RECONNECT");
1459}
1460
1461
1462static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1463 char *argv[])
1464{
1465 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1466}
1467
1468
1469static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1470{
1471 return wpa_ctrl_command(ctrl, "SCAN");
1472}
1473
1474
1475static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1476 char *argv[])
1477{
1478 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1479}
1480
1481
1482static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1483{
1484 char cmd[64];
1485 int res;
1486
1487 if (argc != 1) {
1488 printf("Invalid BSS command: need one argument (index or "
1489 "BSSID)\n");
1490 return -1;
1491 }
1492
1493 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1494 if (res < 0 || (size_t) res >= sizeof(cmd))
1495 return -1;
1496 cmd[sizeof(cmd) - 1] = '\0';
1497
1498 return wpa_ctrl_command(ctrl, cmd);
1499}
1500
1501
1502static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1503 char *argv[])
1504{
1505 char cmd[64];
1506 int res;
1507
1508 if (argc < 1 || argc > 2) {
1509 printf("Invalid GET_CAPABILITY command: need either one or "
1510 "two arguments\n");
1511 return -1;
1512 }
1513
1514 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1515 printf("Invalid GET_CAPABILITY command: second argument, "
1516 "if any, must be 'strict'\n");
1517 return -1;
1518 }
1519
1520 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1521 (argc == 2) ? " strict" : "");
1522 if (res < 0 || (size_t) res >= sizeof(cmd))
1523 return -1;
1524 cmd[sizeof(cmd) - 1] = '\0';
1525
1526 return wpa_ctrl_command(ctrl, cmd);
1527}
1528
1529
1530static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1531{
1532 printf("Available interfaces:\n");
1533 return wpa_ctrl_command(ctrl, "INTERFACES");
1534}
1535
1536
1537static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1538{
1539 if (argc < 1) {
1540 wpa_cli_list_interfaces(ctrl);
1541 return 0;
1542 }
1543
1544 wpa_cli_close_connection();
1545 os_free(ctrl_ifname);
1546 ctrl_ifname = os_strdup(argv[0]);
1547
1548 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1549 printf("Connected to interface '%s.\n", ctrl_ifname);
1550 } else {
1551 printf("Could not connect to interface '%s' - re-trying\n",
1552 ctrl_ifname);
1553 }
1554 return 0;
1555}
1556
1557
1558static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1559 char *argv[])
1560{
1561 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1562}
1563
1564
1565static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1566 char *argv[])
1567{
1568 return wpa_ctrl_command(ctrl, "TERMINATE");
1569}
1570
1571
1572static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1573 char *argv[])
1574{
1575 char cmd[256];
1576 int res;
1577
1578 if (argc < 1) {
1579 printf("Invalid INTERFACE_ADD command: needs at least one "
1580 "argument (interface name)\n"
1581 "All arguments: ifname confname driver ctrl_interface "
1582 "driver_param bridge_name\n");
1583 return -1;
1584 }
1585
1586 /*
1587 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1588 * <driver_param>TAB<bridge_name>
1589 */
1590 res = os_snprintf(cmd, sizeof(cmd),
1591 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1592 argv[0],
1593 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1594 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1595 argc > 5 ? argv[5] : "");
1596 if (res < 0 || (size_t) res >= sizeof(cmd))
1597 return -1;
1598 cmd[sizeof(cmd) - 1] = '\0';
1599 return wpa_ctrl_command(ctrl, cmd);
1600}
1601
1602
1603static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1604 char *argv[])
1605{
1606 char cmd[128];
1607 int res;
1608
1609 if (argc != 1) {
1610 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1611 "(interface name)\n");
1612 return -1;
1613 }
1614
1615 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1616 if (res < 0 || (size_t) res >= sizeof(cmd))
1617 return -1;
1618 cmd[sizeof(cmd) - 1] = '\0';
1619 return wpa_ctrl_command(ctrl, cmd);
1620}
1621
1622
1623static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1624 char *argv[])
1625{
1626 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1627}
1628
1629
1630#ifdef CONFIG_AP
1631static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1632{
1633 char buf[64];
1634 if (argc != 1) {
1635 printf("Invalid 'sta' command - exactly one argument, STA "
1636 "address, is required.\n");
1637 return -1;
1638 }
1639 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1640 return wpa_ctrl_command(ctrl, buf);
1641}
1642
1643
1644static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1645 char *addr, size_t addr_len)
1646{
1647 char buf[4096], *pos;
1648 size_t len;
1649 int ret;
1650
1651 if (ctrl_conn == NULL) {
1652 printf("Not connected to hostapd - command dropped.\n");
1653 return -1;
1654 }
1655 len = sizeof(buf) - 1;
1656 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1657 wpa_cli_msg_cb);
1658 if (ret == -2) {
1659 printf("'%s' command timed out.\n", cmd);
1660 return -2;
1661 } else if (ret < 0) {
1662 printf("'%s' command failed.\n", cmd);
1663 return -1;
1664 }
1665
1666 buf[len] = '\0';
1667 if (memcmp(buf, "FAIL", 4) == 0)
1668 return -1;
1669 printf("%s", buf);
1670
1671 pos = buf;
1672 while (*pos != '\0' && *pos != '\n')
1673 pos++;
1674 *pos = '\0';
1675 os_strlcpy(addr, buf, addr_len);
1676 return 0;
1677}
1678
1679
1680static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1681{
1682 char addr[32], cmd[64];
1683
1684 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1685 return 0;
1686 do {
1687 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1688 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1689
1690 return -1;
1691}
1692#endif /* CONFIG_AP */
1693
1694
1695static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1696{
1697 return wpa_ctrl_command(ctrl, "SUSPEND");
1698}
1699
1700
1701static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1702{
1703 return wpa_ctrl_command(ctrl, "RESUME");
1704}
1705
1706
1707static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1708{
1709 return wpa_ctrl_command(ctrl, "DROP_SA");
1710}
1711
1712
1713static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1714{
1715 char cmd[128];
1716 int res;
1717
1718 if (argc != 1) {
1719 printf("Invalid ROAM command: needs one argument "
1720 "(target AP's BSSID)\n");
1721 return -1;
1722 }
1723
1724 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1725 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1726 printf("Too long ROAM command.\n");
1727 return -1;
1728 }
1729 return wpa_ctrl_command(ctrl, cmd);
1730}
1731
1732
1733#ifdef CONFIG_P2P
1734
1735static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1736{
1737 char cmd[128];
1738 int res;
1739
1740 if (argc == 0)
1741 return wpa_ctrl_command(ctrl, "P2P_FIND");
1742
1743 if (argc > 1)
1744 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
1745 argv[0], argv[1]);
1746 else
1747 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
1748 if (res < 0 || (size_t) res >= sizeof(cmd))
1749 return -1;
1750 cmd[sizeof(cmd) - 1] = '\0';
1751 return wpa_ctrl_command(ctrl, cmd);
1752}
1753
1754
1755static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1756 char *argv[])
1757{
1758 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1759}
1760
1761
1762static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1763 char *argv[])
1764{
1765 char cmd[128];
1766 int res;
1767
1768 if (argc < 2) {
1769 printf("Invalid P2P_CONNECT command: needs at least two "
1770 "arguments (address and pbc/PIN)\n");
1771 return -1;
1772 }
1773
1774 if (argc > 4)
1775 res = os_snprintf(cmd, sizeof(cmd),
1776 "P2P_CONNECT %s %s %s %s %s",
1777 argv[0], argv[1], argv[2], argv[3],
1778 argv[4]);
1779 else if (argc > 3)
1780 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
1781 argv[0], argv[1], argv[2], argv[3]);
1782 else if (argc > 2)
1783 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
1784 argv[0], argv[1], argv[2]);
1785 else
1786 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1787 argv[0], argv[1]);
1788 if (res < 0 || (size_t) res >= sizeof(cmd))
1789 return -1;
1790 cmd[sizeof(cmd) - 1] = '\0';
1791 return wpa_ctrl_command(ctrl, cmd);
1792}
1793
1794
1795static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1796 char *argv[])
1797{
1798 char cmd[128];
1799 int res;
1800
1801 if (argc == 0)
1802 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
1803
1804 res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
1805 if (res < 0 || (size_t) res >= sizeof(cmd))
1806 return -1;
1807 cmd[sizeof(cmd) - 1] = '\0';
1808 return wpa_ctrl_command(ctrl, cmd);
1809}
1810
1811
1812static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1813 char *argv[])
1814{
1815 char cmd[128];
1816 int res;
1817
1818 if (argc != 1) {
1819 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
1820 "(interface name)\n");
1821 return -1;
1822 }
1823
1824 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
1825 if (res < 0 || (size_t) res >= sizeof(cmd))
1826 return -1;
1827 cmd[sizeof(cmd) - 1] = '\0';
1828 return wpa_ctrl_command(ctrl, cmd);
1829}
1830
1831
1832static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1833 char *argv[])
1834{
1835 char cmd[128];
1836 int res;
1837
1838 if (argc == 0)
1839 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
1840
1841 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s", argv[0]);
1842 if (res < 0 || (size_t) res >= sizeof(cmd))
1843 return -1;
1844 cmd[sizeof(cmd) - 1] = '\0';
1845 return wpa_ctrl_command(ctrl, cmd);
1846}
1847
1848
1849static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1850 char *argv[])
1851{
1852 char cmd[128];
1853 int res;
1854
1855 if (argc != 2) {
1856 printf("Invalid P2P_PROV_DISC command: needs two arguments "
1857 "(address and config method\n"
1858 "(display, keypad, or pbc)\n");
1859 return -1;
1860 }
1861
1862 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
1863 argv[0], argv[1]);
1864 if (res < 0 || (size_t) res >= sizeof(cmd))
1865 return -1;
1866 cmd[sizeof(cmd) - 1] = '\0';
1867 return wpa_ctrl_command(ctrl, cmd);
1868}
1869
1870
1871static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1872 char *argv[])
1873{
1874 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1875}
1876
1877
1878static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1879 char *argv[])
1880{
1881 char cmd[4096];
1882 int res;
1883
1884 if (argc != 2 && argc != 4) {
1885 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1886 "arguments (address and TLVs) or four arguments "
1887 "(address, \"upnp\", version, search target "
1888 "(SSDP ST:)\n");
1889 return -1;
1890 }
1891
1892 if (argc == 4)
1893 res = os_snprintf(cmd, sizeof(cmd),
1894 "P2P_SERV_DISC_REQ %s %s %s %s",
1895 argv[0], argv[1], argv[2], argv[3]);
1896 else
1897 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
1898 argv[0], argv[1]);
1899 if (res < 0 || (size_t) res >= sizeof(cmd))
1900 return -1;
1901 cmd[sizeof(cmd) - 1] = '\0';
1902 return wpa_ctrl_command(ctrl, cmd);
1903}
1904
1905
1906static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1907 int argc, char *argv[])
1908{
1909 char cmd[128];
1910 int res;
1911
1912 if (argc != 1) {
1913 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
1914 "argument (pending request identifier)\n");
1915 return -1;
1916 }
1917
1918 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
1919 argv[0]);
1920 if (res < 0 || (size_t) res >= sizeof(cmd))
1921 return -1;
1922 cmd[sizeof(cmd) - 1] = '\0';
1923 return wpa_ctrl_command(ctrl, cmd);
1924}
1925
1926
1927static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1928 char *argv[])
1929{
1930 char cmd[4096];
1931 int res;
1932
1933 if (argc != 4) {
1934 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1935 "arguments (freq, address, dialog token, and TLVs)\n");
1936 return -1;
1937 }
1938
1939 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1940 argv[0], argv[1], argv[2], argv[3]);
1941 if (res < 0 || (size_t) res >= sizeof(cmd))
1942 return -1;
1943 cmd[sizeof(cmd) - 1] = '\0';
1944 return wpa_ctrl_command(ctrl, cmd);
1945}
1946
1947
1948static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1949 char *argv[])
1950{
1951 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1952}
1953
1954
1955static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1956 int argc, char *argv[])
1957{
1958 char cmd[128];
1959 int res;
1960
1961 if (argc != 1) {
1962 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
1963 "argument (external processing: 0/1)\n");
1964 return -1;
1965 }
1966
1967 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
1968 argv[0]);
1969 if (res < 0 || (size_t) res >= sizeof(cmd))
1970 return -1;
1971 cmd[sizeof(cmd) - 1] = '\0';
1972 return wpa_ctrl_command(ctrl, cmd);
1973}
1974
1975
1976static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1977 char *argv[])
1978{
1979 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1980}
1981
1982
1983static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1984 char *argv[])
1985{
1986 char cmd[4096];
1987 int res;
1988
1989 if (argc != 3 && argc != 4) {
1990 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1991 "arguments\n");
1992 return -1;
1993 }
1994
1995 if (argc == 4)
1996 res = os_snprintf(cmd, sizeof(cmd),
1997 "P2P_SERVICE_ADD %s %s %s %s",
1998 argv[0], argv[1], argv[2], argv[3]);
1999 else
2000 res = os_snprintf(cmd, sizeof(cmd),
2001 "P2P_SERVICE_ADD %s %s %s",
2002 argv[0], argv[1], argv[2]);
2003 if (res < 0 || (size_t) res >= sizeof(cmd))
2004 return -1;
2005 cmd[sizeof(cmd) - 1] = '\0';
2006 return wpa_ctrl_command(ctrl, cmd);
2007}
2008
2009
2010static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2011 char *argv[])
2012{
2013 char cmd[4096];
2014 int res;
2015
2016 if (argc != 2 && argc != 3) {
2017 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2018 "arguments\n");
2019 return -1;
2020 }
2021
2022 if (argc == 3)
2023 res = os_snprintf(cmd, sizeof(cmd),
2024 "P2P_SERVICE_DEL %s %s %s",
2025 argv[0], argv[1], argv[2]);
2026 else
2027 res = os_snprintf(cmd, sizeof(cmd),
2028 "P2P_SERVICE_DEL %s %s",
2029 argv[0], argv[1]);
2030 if (res < 0 || (size_t) res >= sizeof(cmd))
2031 return -1;
2032 cmd[sizeof(cmd) - 1] = '\0';
2033 return wpa_ctrl_command(ctrl, cmd);
2034}
2035
2036
2037static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2038 int argc, char *argv[])
2039{
2040 char cmd[128];
2041 int res;
2042
2043 if (argc != 1) {
2044 printf("Invalid P2P_REJECT command: needs one argument "
2045 "(peer address)\n");
2046 return -1;
2047 }
2048
2049 res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
2050 if (res < 0 || (size_t) res >= sizeof(cmd))
2051 return -1;
2052 cmd[sizeof(cmd) - 1] = '\0';
2053 return wpa_ctrl_command(ctrl, cmd);
2054}
2055
2056
2057static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2058 int argc, char *argv[])
2059{
2060 char cmd[128];
2061 int res;
2062
2063 if (argc < 1) {
2064 printf("Invalid P2P_INVITE command: needs at least one "
2065 "argument\n");
2066 return -1;
2067 }
2068
2069 if (argc > 2)
2070 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
2071 argv[0], argv[1], argv[2]);
2072 else if (argc > 1)
2073 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
2074 argv[0], argv[1]);
2075 else
2076 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
2077 if (res < 0 || (size_t) res >= sizeof(cmd))
2078 return -1;
2079 cmd[sizeof(cmd) - 1] = '\0';
2080 return wpa_ctrl_command(ctrl, cmd);
2081}
2082
2083
2084static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2085{
2086 char buf[64];
2087 if (argc != 1) {
2088 printf("Invalid 'p2p_peer' command - exactly one argument, "
2089 "P2P peer device address, is required.\n");
2090 return -1;
2091 }
2092 os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
2093 return wpa_ctrl_command(ctrl, buf);
2094}
2095
2096
2097static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2098 char *addr, size_t addr_len,
2099 int discovered)
2100{
2101 char buf[4096], *pos;
2102 size_t len;
2103 int ret;
2104
2105 if (ctrl_conn == NULL)
2106 return -1;
2107 len = sizeof(buf) - 1;
2108 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
2109 wpa_cli_msg_cb);
2110 if (ret == -2) {
2111 printf("'%s' command timed out.\n", cmd);
2112 return -2;
2113 } else if (ret < 0) {
2114 printf("'%s' command failed.\n", cmd);
2115 return -1;
2116 }
2117
2118 buf[len] = '\0';
2119 if (memcmp(buf, "FAIL", 4) == 0)
2120 return -1;
2121
2122 pos = buf;
2123 while (*pos != '\0' && *pos != '\n')
2124 pos++;
2125 *pos++ = '\0';
2126 os_strlcpy(addr, buf, addr_len);
2127 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2128 printf("%s\n", addr);
2129 return 0;
2130}
2131
2132
2133static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2134{
2135 char addr[32], cmd[64];
2136 int discovered;
2137
2138 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2139
2140 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2141 addr, sizeof(addr), discovered))
2142 return 0;
2143 do {
2144 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2145 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2146 discovered) == 0);
2147
2148 return -1;
2149}
2150
2151
2152static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2153{
2154 char cmd[100];
2155 int res;
2156
2157 if (argc != 2) {
2158 printf("Invalid P2P_SET command: needs two arguments (field, "
2159 "value)\n");
2160 return -1;
2161 }
2162
2163 res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2164 if (res < 0 || (size_t) res >= sizeof(cmd))
2165 return -1;
2166 cmd[sizeof(cmd) - 1] = '\0';
2167 return wpa_ctrl_command(ctrl, cmd);
2168}
2169
2170
2171static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2172{
2173 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2174}
2175
2176
2177static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2178 char *argv[])
2179{
2180 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2181}
2182
2183
2184static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2185 char *argv[])
2186{
2187 char cmd[100];
2188 int res;
2189
2190 if (argc != 1) {
2191 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2192 "(peer address)\n");
2193 return -1;
2194 }
2195
2196 res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]);
2197
2198 if (res < 0 || (size_t) res >= sizeof(cmd))
2199 return -1;
2200
2201 cmd[sizeof(cmd) - 1] = '\0';
2202 return wpa_ctrl_command(ctrl, cmd);
2203}
2204
2205
2206static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2207 char *argv[])
2208{
2209 char cmd[100];
2210 int res;
2211
2212 if (argc != 0 && argc != 2 && argc != 4) {
2213 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2214 "(preferred duration, interval; in microsecods).\n"
2215 "Optional second pair can be used to provide "
2216 "acceptable values.\n");
2217 return -1;
2218 }
2219
2220 if (argc == 4)
2221 res = os_snprintf(cmd, sizeof(cmd),
2222 "P2P_PRESENCE_REQ %s %s %s %s",
2223 argv[0], argv[1], argv[2], argv[3]);
2224 else if (argc == 2)
2225 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2226 argv[0], argv[1]);
2227 else
2228 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2229 if (res < 0 || (size_t) res >= sizeof(cmd))
2230 return -1;
2231 cmd[sizeof(cmd) - 1] = '\0';
2232 return wpa_ctrl_command(ctrl, cmd);
2233}
2234
2235
2236static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2237 char *argv[])
2238{
2239 char cmd[100];
2240 int res;
2241
2242 if (argc != 0 && argc != 2) {
2243 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2244 "(availability period, availability interval; in "
2245 "millisecods).\n"
2246 "Extended Listen Timing can be cancelled with this "
2247 "command when used without parameters.\n");
2248 return -1;
2249 }
2250
2251 if (argc == 2)
2252 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2253 argv[0], argv[1]);
2254 else
2255 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2256 if (res < 0 || (size_t) res >= sizeof(cmd))
2257 return -1;
2258 cmd[sizeof(cmd) - 1] = '\0';
2259 return wpa_ctrl_command(ctrl, cmd);
2260}
2261
2262#endif /* CONFIG_P2P */
2263
2264
2265static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2266 char *argv[])
2267{
2268 char cmd[256];
2269 int res;
2270
2271 if (argc != 1) {
2272 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2273 "(0/1 = disable/enable automatic reconnection)\n");
2274 return -1;
2275 }
2276 res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2277 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2278 printf("Too long STA_AUTOCONNECT command.\n");
2279 return -1;
2280 }
2281 return wpa_ctrl_command(ctrl, cmd);
2282}
2283
2284
2285static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2286 char *argv[])
2287{
2288 char cmd[256];
2289 int res;
2290
2291 if (argc != 1) {
2292 printf("Invalid TDLS_DISCOVER command: needs one argument "
2293 "(Peer STA MAC address)\n");
2294 return -1;
2295 }
2296
2297 res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]);
2298 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2299 printf("Too long TDLS_DISCOVER command.\n");
2300 return -1;
2301 }
2302 return wpa_ctrl_command(ctrl, cmd);
2303}
2304
2305
2306static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2307 char *argv[])
2308{
2309 char cmd[256];
2310 int res;
2311
2312 if (argc != 1) {
2313 printf("Invalid TDLS_SETUP command: needs one argument "
2314 "(Peer STA MAC address)\n");
2315 return -1;
2316 }
2317
2318 res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]);
2319 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2320 printf("Too long TDLS_SETUP command.\n");
2321 return -1;
2322 }
2323 return wpa_ctrl_command(ctrl, cmd);
2324}
2325
2326
2327static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2328 char *argv[])
2329{
2330 char cmd[256];
2331 int res;
2332
2333 if (argc != 1) {
2334 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2335 "(Peer STA MAC address)\n");
2336 return -1;
2337 }
2338
2339 res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]);
2340 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2341 printf("Too long TDLS_TEARDOWN command.\n");
2342 return -1;
2343 }
2344 return wpa_ctrl_command(ctrl, cmd);
2345}
2346
2347
2348static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2349 char *argv[])
2350{
2351 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2352}
2353
2354
2355enum wpa_cli_cmd_flags {
2356 cli_cmd_flag_none = 0x00,
2357 cli_cmd_flag_sensitive = 0x01
2358};
2359
2360struct wpa_cli_cmd {
2361 const char *cmd;
2362 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2363 enum wpa_cli_cmd_flags flags;
2364 const char *usage;
2365};
2366
2367static struct wpa_cli_cmd wpa_cli_commands[] = {
2368 { "status", wpa_cli_cmd_status,
2369 cli_cmd_flag_none,
2370 "[verbose] = get current WPA/EAPOL/EAP status" },
2371 { "ping", wpa_cli_cmd_ping,
2372 cli_cmd_flag_none,
2373 "= pings wpa_supplicant" },
2374 { "relog", wpa_cli_cmd_relog,
2375 cli_cmd_flag_none,
2376 "= re-open log-file (allow rolling logs)" },
2377 { "note", wpa_cli_cmd_note,
2378 cli_cmd_flag_none,
2379 "<text> = add a note to wpa_supplicant debug log" },
2380 { "mib", wpa_cli_cmd_mib,
2381 cli_cmd_flag_none,
2382 "= get MIB variables (dot1x, dot11)" },
2383 { "help", wpa_cli_cmd_help,
2384 cli_cmd_flag_none,
2385 "= show this usage help" },
2386 { "interface", wpa_cli_cmd_interface,
2387 cli_cmd_flag_none,
2388 "[ifname] = show interfaces/select interface" },
2389 { "level", wpa_cli_cmd_level,
2390 cli_cmd_flag_none,
2391 "<debug level> = change debug level" },
2392 { "license", wpa_cli_cmd_license,
2393 cli_cmd_flag_none,
2394 "= show full wpa_cli license" },
2395 { "quit", wpa_cli_cmd_quit,
2396 cli_cmd_flag_none,
2397 "= exit wpa_cli" },
2398 { "set", wpa_cli_cmd_set,
2399 cli_cmd_flag_none,
2400 "= set variables (shows list of variables when run without "
2401 "arguments)" },
2402 { "get", wpa_cli_cmd_get,
2403 cli_cmd_flag_none,
2404 "<name> = get information" },
2405 { "logon", wpa_cli_cmd_logon,
2406 cli_cmd_flag_none,
2407 "= IEEE 802.1X EAPOL state machine logon" },
2408 { "logoff", wpa_cli_cmd_logoff,
2409 cli_cmd_flag_none,
2410 "= IEEE 802.1X EAPOL state machine logoff" },
2411 { "pmksa", wpa_cli_cmd_pmksa,
2412 cli_cmd_flag_none,
2413 "= show PMKSA cache" },
2414 { "reassociate", wpa_cli_cmd_reassociate,
2415 cli_cmd_flag_none,
2416 "= force reassociation" },
2417 { "preauthenticate", wpa_cli_cmd_preauthenticate,
2418 cli_cmd_flag_none,
2419 "<BSSID> = force preauthentication" },
2420 { "identity", wpa_cli_cmd_identity,
2421 cli_cmd_flag_none,
2422 "<network id> <identity> = configure identity for an SSID" },
2423 { "password", wpa_cli_cmd_password,
2424 cli_cmd_flag_sensitive,
2425 "<network id> <password> = configure password for an SSID" },
2426 { "new_password", wpa_cli_cmd_new_password,
2427 cli_cmd_flag_sensitive,
2428 "<network id> <password> = change password for an SSID" },
2429 { "pin", wpa_cli_cmd_pin,
2430 cli_cmd_flag_sensitive,
2431 "<network id> <pin> = configure pin for an SSID" },
2432 { "otp", wpa_cli_cmd_otp,
2433 cli_cmd_flag_sensitive,
2434 "<network id> <password> = configure one-time-password for an SSID"
2435 },
2436 { "passphrase", wpa_cli_cmd_passphrase,
2437 cli_cmd_flag_sensitive,
2438 "<network id> <passphrase> = configure private key passphrase\n"
2439 " for an SSID" },
2440 { "bssid", wpa_cli_cmd_bssid,
2441 cli_cmd_flag_none,
2442 "<network id> <BSSID> = set preferred BSSID for an SSID" },
Dmitry Shmidt696359e2011-03-16 15:04:31 -07002443 { "blacklist", wpa_cli_cmd_blacklist,
2444 cli_cmd_flag_none,
2445 "<BSSID> = add a BSSID to the blacklist\n"
2446 "blacklist clear = clear the blacklist\n"
2447 "blacklist = display the blacklist" },
2448 { "log_level", wpa_cli_cmd_log_level,
2449 cli_cmd_flag_none,
2450 "<level> [<timestamp>] = update the log level/timestamp of wpa_supplicant\n"
2451 "log_level = display the current log level and log options" },
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002452 { "list_networks", wpa_cli_cmd_list_networks,
2453 cli_cmd_flag_none,
2454 "= list configured networks" },
2455 { "select_network", wpa_cli_cmd_select_network,
2456 cli_cmd_flag_none,
2457 "<network id> = select a network (disable others)" },
2458 { "enable_network", wpa_cli_cmd_enable_network,
2459 cli_cmd_flag_none,
2460 "<network id> = enable a network" },
2461 { "disable_network", wpa_cli_cmd_disable_network,
2462 cli_cmd_flag_none,
2463 "<network id> = disable a network" },
2464 { "add_network", wpa_cli_cmd_add_network,
2465 cli_cmd_flag_none,
2466 "= add a network" },
2467 { "remove_network", wpa_cli_cmd_remove_network,
2468 cli_cmd_flag_none,
2469 "<network id> = remove a network" },
2470 { "set_network", wpa_cli_cmd_set_network,
2471 cli_cmd_flag_sensitive,
2472 "<network id> <variable> <value> = set network variables (shows\n"
2473 " list of variables when run without arguments)" },
2474 { "get_network", wpa_cli_cmd_get_network,
2475 cli_cmd_flag_none,
2476 "<network id> <variable> = get network variables" },
2477 { "save_config", wpa_cli_cmd_save_config,
2478 cli_cmd_flag_none,
2479 "= save the current configuration" },
2480 { "disconnect", wpa_cli_cmd_disconnect,
2481 cli_cmd_flag_none,
2482 "= disconnect and wait for reassociate/reconnect command before\n"
2483 " connecting" },
2484 { "reconnect", wpa_cli_cmd_reconnect,
2485 cli_cmd_flag_none,
2486 "= like reassociate, but only takes effect if already disconnected"
2487 },
2488 { "scan", wpa_cli_cmd_scan,
2489 cli_cmd_flag_none,
2490 "= request new BSS scan" },
2491 { "scan_results", wpa_cli_cmd_scan_results,
2492 cli_cmd_flag_none,
2493 "= get latest scan results" },
2494 { "bss", wpa_cli_cmd_bss,
2495 cli_cmd_flag_none,
2496 "<<idx> | <bssid>> = get detailed scan result info" },
2497 { "get_capability", wpa_cli_cmd_get_capability,
2498 cli_cmd_flag_none,
2499 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2500 { "reconfigure", wpa_cli_cmd_reconfigure,
2501 cli_cmd_flag_none,
2502 "= force wpa_supplicant to re-read its configuration file" },
2503 { "terminate", wpa_cli_cmd_terminate,
2504 cli_cmd_flag_none,
2505 "= terminate wpa_supplicant" },
2506 { "interface_add", wpa_cli_cmd_interface_add,
2507 cli_cmd_flag_none,
2508 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2509 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2510 " are optional" },
2511 { "interface_remove", wpa_cli_cmd_interface_remove,
2512 cli_cmd_flag_none,
2513 "<ifname> = removes the interface" },
2514 { "interface_list", wpa_cli_cmd_interface_list,
2515 cli_cmd_flag_none,
2516 "= list available interfaces" },
2517 { "ap_scan", wpa_cli_cmd_ap_scan,
2518 cli_cmd_flag_none,
2519 "<value> = set ap_scan parameter" },
2520 { "scan_interval", wpa_cli_cmd_scan_interval,
2521 cli_cmd_flag_none,
2522 "<value> = set scan_interval parameter (in seconds)" },
2523 { "bss_expire_age", wpa_cli_cmd_bss_expire_age,
2524 cli_cmd_flag_none,
2525 "<value> = set BSS expiration age parameter" },
2526 { "bss_expire_count", wpa_cli_cmd_bss_expire_count,
2527 cli_cmd_flag_none,
2528 "<value> = set BSS expiration scan count parameter" },
2529 { "stkstart", wpa_cli_cmd_stkstart,
2530 cli_cmd_flag_none,
2531 "<addr> = request STK negotiation with <addr>" },
2532 { "ft_ds", wpa_cli_cmd_ft_ds,
2533 cli_cmd_flag_none,
2534 "<addr> = request over-the-DS FT with <addr>" },
2535 { "wps_pbc", wpa_cli_cmd_wps_pbc,
2536 cli_cmd_flag_none,
2537 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2538 { "wps_pin", wpa_cli_cmd_wps_pin,
2539 cli_cmd_flag_sensitive,
2540 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2541 "hardcoded)" },
2542 { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
2543 cli_cmd_flag_sensitive,
2544 "<PIN> = verify PIN checksum" },
2545 { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2546 "Cancels the pending WPS operation" },
2547#ifdef CONFIG_WPS_OOB
2548 { "wps_oob", wpa_cli_cmd_wps_oob,
2549 cli_cmd_flag_sensitive,
2550 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2551#endif /* CONFIG_WPS_OOB */
2552 { "wps_reg", wpa_cli_cmd_wps_reg,
2553 cli_cmd_flag_sensitive,
2554 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2555 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
2556 cli_cmd_flag_sensitive,
2557 "[params..] = enable/disable AP PIN" },
2558 { "wps_er_start", wpa_cli_cmd_wps_er_start,
2559 cli_cmd_flag_none,
2560 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2561 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2562 cli_cmd_flag_none,
2563 "= stop Wi-Fi Protected Setup External Registrar" },
2564 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2565 cli_cmd_flag_sensitive,
2566 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2567 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2568 cli_cmd_flag_none,
2569 "<UUID> = accept an Enrollee PBC using External Registrar" },
2570 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2571 cli_cmd_flag_sensitive,
2572 "<UUID> <PIN> = learn AP configuration" },
2573 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
2574 cli_cmd_flag_none,
2575 "<UUID> <network id> = set AP configuration for enrolling" },
2576 { "wps_er_config", wpa_cli_cmd_wps_er_config,
2577 cli_cmd_flag_sensitive,
2578 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2579 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2580 cli_cmd_flag_none,
2581 "<addr> = request RSN authentication with <addr> in IBSS" },
2582#ifdef CONFIG_AP
2583 { "sta", wpa_cli_cmd_sta,
2584 cli_cmd_flag_none,
2585 "<addr> = get information about an associated station (AP)" },
2586 { "all_sta", wpa_cli_cmd_all_sta,
2587 cli_cmd_flag_none,
2588 "= get information about all associated stations (AP)" },
2589#endif /* CONFIG_AP */
2590 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2591 "= notification of suspend/hibernate" },
2592 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2593 "= notification of resume/thaw" },
2594 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2595 "= drop SA without deauth/disassoc (test command)" },
2596 { "roam", wpa_cli_cmd_roam,
2597 cli_cmd_flag_none,
2598 "<addr> = roam to the specified BSS" },
2599#ifdef CONFIG_P2P
2600 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2601 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2602 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2603 "= stop P2P Devices search" },
2604 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2605 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2606 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2607 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2608 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2609 "<ifname> = remove P2P group interface (terminate group if GO)" },
2610 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2611 "= add a new P2P group (local end as GO)" },
2612 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2613 "<addr> <method> = request provisioning discovery" },
2614 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2615 cli_cmd_flag_none,
2616 "= get the passphrase for a group (GO only)" },
2617 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2618 cli_cmd_flag_none,
2619 "<addr> <TLVs> = schedule service discovery request" },
2620 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2621 cli_cmd_flag_none,
2622 "<id> = cancel pending service discovery request" },
2623 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2624 cli_cmd_flag_none,
2625 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2626 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2627 cli_cmd_flag_none,
2628 "= indicate change in local services" },
2629 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2630 cli_cmd_flag_none,
2631 "<external> = set external processing of service discovery" },
2632 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2633 cli_cmd_flag_none,
2634 "= remove all stored service entries" },
2635 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2636 cli_cmd_flag_none,
2637 "<bonjour|upnp> <query|version> <response|service> = add a local "
2638 "service" },
2639 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2640 cli_cmd_flag_none,
2641 "<bonjour|upnp> <query|version> [|service] = remove a local "
2642 "service" },
2643 { "p2p_reject", wpa_cli_cmd_p2p_reject,
2644 cli_cmd_flag_none,
2645 "<addr> = reject connection attempts from a specific peer" },
2646 { "p2p_invite", wpa_cli_cmd_p2p_invite,
2647 cli_cmd_flag_none,
2648 "<cmd> [peer=addr] = invite peer" },
2649 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2650 "[discovered] = list known (optionally, only fully discovered) P2P "
2651 "peers" },
2652 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2653 "<address> = show information about known P2P peer" },
2654 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2655 "<field> <value> = set a P2P parameter" },
2656 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2657 "= flush P2P state" },
2658 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
2659 "= cancel P2P group formation" },
2660 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none,
2661 "<address> = unauthorize a peer" },
2662 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2663 "[<duration> <interval>] [<duration> <interval>] = request GO "
2664 "presence" },
2665 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2666 "[<period> <interval>] = set extended listen timing" },
2667#endif /* CONFIG_P2P */
2668 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
2669 "<0/1> = disable/enable automatic reconnection" },
2670 { "tdls_discover", wpa_cli_cmd_tdls_discover,
2671 cli_cmd_flag_none,
2672 "<addr> = request TDLS discovery with <addr>" },
2673 { "tdls_setup", wpa_cli_cmd_tdls_setup,
2674 cli_cmd_flag_none,
2675 "<addr> = request TDLS setup with <addr>" },
2676 { "tdls_teardown", wpa_cli_cmd_tdls_teardown,
2677 cli_cmd_flag_none,
2678 "<addr> = tear down TDLS with <addr>" },
2679 { "signal_poll", wpa_cli_cmd_signal_poll,
2680 cli_cmd_flag_none,
2681 "= get signal parameters" },
2682 { NULL, NULL, cli_cmd_flag_none, NULL }
2683};
2684
2685
2686/*
2687 * Prints command usage, lines are padded with the specified string.
2688 */
2689static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2690{
2691 char c;
2692 size_t n;
2693
2694 printf("%s%s ", pad, cmd->cmd);
2695 for (n = 0; (c = cmd->usage[n]); n++) {
2696 printf("%c", c);
2697 if (c == '\n')
2698 printf("%s", pad);
2699 }
2700 printf("\n");
2701}
2702
2703
2704static void print_help(void)
2705{
2706 int n;
2707 printf("commands:\n");
2708 for (n = 0; wpa_cli_commands[n].cmd; n++)
2709 print_cmd_help(&wpa_cli_commands[n], " ");
2710}
2711
2712
2713static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
2714{
2715 const char *c, *delim;
2716 int n;
2717 size_t len;
2718
2719 delim = os_strchr(cmd, ' ');
2720 if (delim)
2721 len = delim - cmd;
2722 else
2723 len = os_strlen(cmd);
2724
2725 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2726 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2727 return (wpa_cli_commands[n].flags &
2728 cli_cmd_flag_sensitive);
2729 }
2730 return 0;
2731}
2732
2733
2734static char ** wpa_list_cmd_list(void)
2735{
2736 char **res;
2737 int i, count;
2738
2739 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
2740 res = os_zalloc(count * sizeof(char *));
2741 if (res == NULL)
2742 return NULL;
2743
2744 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2745 res[i] = os_strdup(wpa_cli_commands[i].cmd);
2746 if (res[i] == NULL)
2747 break;
2748 }
2749
2750 return res;
2751}
2752
2753
2754static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
2755 int pos)
2756{
2757 int i;
2758
2759 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2760 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
2761 edit_clear_line();
2762 printf("\r%s\n", wpa_cli_commands[i].usage);
2763 edit_redraw();
2764 break;
2765 }
2766 }
2767
2768 return NULL;
2769}
2770
2771
2772static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
2773{
2774 char **res;
2775 const char *end;
2776 char *cmd;
2777
2778 end = os_strchr(str, ' ');
2779 if (end == NULL || str + pos < end)
2780 return wpa_list_cmd_list();
2781
2782 cmd = os_malloc(pos + 1);
2783 if (cmd == NULL)
2784 return NULL;
2785 os_memcpy(cmd, str, pos);
2786 cmd[end - str] = '\0';
2787 res = wpa_cli_cmd_completion(cmd, str, pos);
2788 os_free(cmd);
2789 return res;
2790}
2791
2792
2793static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
2794{
2795 struct wpa_cli_cmd *cmd, *match = NULL;
2796 int count;
2797 int ret = 0;
2798
2799 count = 0;
2800 cmd = wpa_cli_commands;
2801 while (cmd->cmd) {
2802 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
2803 {
2804 match = cmd;
2805 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
2806 /* we have an exact match */
2807 count = 1;
2808 break;
2809 }
2810 count++;
2811 }
2812 cmd++;
2813 }
2814
2815 if (count > 1) {
2816 printf("Ambiguous command '%s'; possible commands:", argv[0]);
2817 cmd = wpa_cli_commands;
2818 while (cmd->cmd) {
2819 if (os_strncasecmp(cmd->cmd, argv[0],
2820 os_strlen(argv[0])) == 0) {
2821 printf(" %s", cmd->cmd);
2822 }
2823 cmd++;
2824 }
2825 printf("\n");
2826 ret = 1;
2827 } else if (count == 0) {
2828 printf("Unknown command '%s'\n", argv[0]);
2829 ret = 1;
2830 } else {
2831 ret = match->handler(ctrl, argc - 1, &argv[1]);
2832 }
2833
2834 return ret;
2835}
2836
2837
2838static int str_match(const char *a, const char *b)
2839{
2840 return os_strncmp(a, b, os_strlen(b)) == 0;
2841}
2842
2843
2844static int wpa_cli_exec(const char *program, const char *arg1,
2845 const char *arg2)
2846{
2847 char *cmd;
2848 size_t len;
2849 int res;
2850 int ret = 0;
2851
2852 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
2853 cmd = os_malloc(len);
2854 if (cmd == NULL)
2855 return -1;
2856 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
2857 if (res < 0 || (size_t) res >= len) {
2858 os_free(cmd);
2859 return -1;
2860 }
2861 cmd[len - 1] = '\0';
2862#ifndef _WIN32_WCE
2863 if (system(cmd) < 0)
2864 ret = -1;
2865#endif /* _WIN32_WCE */
2866 os_free(cmd);
2867
2868 return ret;
2869}
2870
2871
2872static void wpa_cli_action_process(const char *msg)
2873{
2874 const char *pos;
2875 char *copy = NULL, *id, *pos2;
2876
2877 pos = msg;
2878 if (*pos == '<') {
2879 /* skip priority */
2880 pos = os_strchr(pos, '>');
2881 if (pos)
2882 pos++;
2883 else
2884 pos = msg;
2885 }
2886
2887 if (str_match(pos, WPA_EVENT_CONNECTED)) {
2888 int new_id = -1;
2889 os_unsetenv("WPA_ID");
2890 os_unsetenv("WPA_ID_STR");
2891 os_unsetenv("WPA_CTRL_DIR");
2892
2893 pos = os_strstr(pos, "[id=");
2894 if (pos)
2895 copy = os_strdup(pos + 4);
2896
2897 if (copy) {
2898 pos2 = id = copy;
2899 while (*pos2 && *pos2 != ' ')
2900 pos2++;
2901 *pos2++ = '\0';
2902 new_id = atoi(id);
2903 os_setenv("WPA_ID", id, 1);
2904 while (*pos2 && *pos2 != '=')
2905 pos2++;
2906 if (*pos2 == '=')
2907 pos2++;
2908 id = pos2;
2909 while (*pos2 && *pos2 != ']')
2910 pos2++;
2911 *pos2 = '\0';
2912 os_setenv("WPA_ID_STR", id, 1);
2913 os_free(copy);
2914 }
2915
2916 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
2917
2918 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
2919 wpa_cli_connected = 1;
2920 wpa_cli_last_id = new_id;
2921 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
2922 }
2923 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
2924 if (wpa_cli_connected) {
2925 wpa_cli_connected = 0;
2926 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
2927 }
2928 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
2929 wpa_cli_exec(action_file, ctrl_ifname, pos);
2930 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
2931 wpa_cli_exec(action_file, ctrl_ifname, pos);
2932 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
2933 wpa_cli_exec(action_file, ctrl_ifname, pos);
2934 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
2935 wpa_cli_exec(action_file, ctrl_ifname, pos);
2936 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
2937 wpa_cli_exec(action_file, ctrl_ifname, pos);
2938 } else if (str_match(pos, WPS_EVENT_FAIL)) {
2939 wpa_cli_exec(action_file, ctrl_ifname, pos);
2940 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
2941 printf("wpa_supplicant is terminating - stop monitoring\n");
2942 wpa_cli_quit = 1;
2943 }
2944}
2945
2946
2947#ifndef CONFIG_ANSI_C_EXTRA
2948static void wpa_cli_action_cb(char *msg, size_t len)
2949{
2950 wpa_cli_action_process(msg);
2951}
2952#endif /* CONFIG_ANSI_C_EXTRA */
2953
2954
2955static void wpa_cli_reconnect(void)
2956{
2957 wpa_cli_close_connection();
2958 wpa_cli_open_connection(ctrl_ifname, 1);
2959}
2960
2961
2962static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
2963{
2964 if (ctrl_conn == NULL) {
2965 wpa_cli_reconnect();
2966 return;
2967 }
2968 while (wpa_ctrl_pending(ctrl) > 0) {
2969 char buf[256];
2970 size_t len = sizeof(buf) - 1;
2971 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
2972 buf[len] = '\0';
2973 if (action_monitor)
2974 wpa_cli_action_process(buf);
2975 else {
2976 if (wpa_cli_show_event(buf)) {
2977 edit_clear_line();
2978 printf("\r%s\n", buf);
2979 edit_redraw();
2980 }
2981 }
2982 } else {
2983 printf("Could not read pending message.\n");
2984 break;
2985 }
2986 }
2987
2988 if (wpa_ctrl_pending(ctrl) < 0) {
2989 printf("Connection to wpa_supplicant lost - trying to "
2990 "reconnect\n");
2991 wpa_cli_reconnect();
2992 }
2993}
2994
2995#define max_args 10
2996
2997static int tokenize_cmd(char *cmd, char *argv[])
2998{
2999 char *pos;
3000 int argc = 0;
3001
3002 pos = cmd;
3003 for (;;) {
3004 while (*pos == ' ')
3005 pos++;
3006 if (*pos == '\0')
3007 break;
3008 argv[argc] = pos;
3009 argc++;
3010 if (argc == max_args)
3011 break;
3012 if (*pos == '"') {
3013 char *pos2 = os_strrchr(pos, '"');
3014 if (pos2)
3015 pos = pos2 + 1;
3016 }
3017 while (*pos != '\0' && *pos != ' ')
3018 pos++;
3019 if (*pos == ' ')
3020 *pos++ = '\0';
3021 }
3022
3023 return argc;
3024}
3025
3026
3027static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3028{
3029 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3030 printf("Connection to wpa_supplicant lost - trying to "
3031 "reconnect\n");
3032 wpa_cli_close_connection();
3033 }
3034 if (!ctrl_conn)
3035 wpa_cli_reconnect();
3036 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3037}
3038
3039
3040static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
3041{
3042 eloop_terminate();
3043}
3044
3045
3046static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3047{
3048 wpa_cli_recv_pending(mon_conn, 0);
3049}
3050
3051
3052static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3053{
3054 char *argv[max_args];
3055 int argc;
3056 argc = tokenize_cmd(cmd, argv);
3057 if (argc)
3058 wpa_request(ctrl_conn, argc, argv);
3059}
3060
3061
3062static void wpa_cli_edit_eof_cb(void *ctx)
3063{
3064 eloop_terminate();
3065}
3066
3067
3068static void wpa_cli_interactive(void)
3069{
3070 char *home, *hfile = NULL;
3071
3072 printf("\nInteractive mode\n\n");
3073
3074 home = getenv("HOME");
3075 if (home) {
3076 const char *fname = ".wpa_cli_history";
3077 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3078 hfile = os_malloc(hfile_len);
3079 if (hfile)
3080 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3081 }
3082
3083 eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
3084 edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3085 wpa_cli_edit_completion_cb, NULL, hfile);
3086 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3087
3088 eloop_run();
3089
3090 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3091 os_free(hfile);
3092 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3093 wpa_cli_close_connection();
3094}
3095
3096
3097static void wpa_cli_action(struct wpa_ctrl *ctrl)
3098{
3099#ifdef CONFIG_ANSI_C_EXTRA
3100 /* TODO: ANSI C version(?) */
3101 printf("Action processing not supported in ANSI C build.\n");
3102#else /* CONFIG_ANSI_C_EXTRA */
3103 fd_set rfds;
3104 int fd, res;
3105 struct timeval tv;
3106 char buf[256]; /* note: large enough to fit in unsolicited messages */
3107 size_t len;
3108
3109 fd = wpa_ctrl_get_fd(ctrl);
3110
3111 while (!wpa_cli_quit) {
3112 FD_ZERO(&rfds);
3113 FD_SET(fd, &rfds);
3114 tv.tv_sec = ping_interval;
3115 tv.tv_usec = 0;
3116 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3117 if (res < 0 && errno != EINTR) {
3118 perror("select");
3119 break;
3120 }
3121
3122 if (FD_ISSET(fd, &rfds))
3123 wpa_cli_recv_pending(ctrl, 1);
3124 else {
3125 /* verify that connection is still working */
3126 len = sizeof(buf) - 1;
3127 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3128 wpa_cli_action_cb) < 0 ||
3129 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3130 printf("wpa_supplicant did not reply to PING "
3131 "command - exiting\n");
3132 break;
3133 }
3134 }
3135 }
3136#endif /* CONFIG_ANSI_C_EXTRA */
3137}
3138
3139
3140static void wpa_cli_cleanup(void)
3141{
3142 wpa_cli_close_connection();
3143 if (pid_file)
3144 os_daemonize_terminate(pid_file);
3145
3146 os_program_deinit();
3147}
3148
3149static void wpa_cli_terminate(int sig)
3150{
3151 wpa_cli_cleanup();
3152 exit(0);
3153}
3154
3155
3156static char * wpa_cli_get_default_ifname(void)
3157{
3158 char *ifname = NULL;
3159
3160#ifdef CONFIG_CTRL_IFACE_UNIX
3161 struct dirent *dent;
3162 DIR *dir = opendir(ctrl_iface_dir);
3163 if (!dir) {
3164#ifdef ANDROID
3165 char ifprop[PROPERTY_VALUE_MAX];
3166 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3167 ifname = os_strdup(ifprop);
3168 printf("Using interface '%s'\n", ifname);
3169 return ifname;
3170 }
3171#endif /* ANDROID */
3172 return NULL;
3173 }
3174 while ((dent = readdir(dir))) {
3175#ifdef _DIRENT_HAVE_D_TYPE
3176 /*
3177 * Skip the file if it is not a socket. Also accept
3178 * DT_UNKNOWN (0) in case the C library or underlying
3179 * file system does not support d_type.
3180 */
3181 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3182 continue;
3183#endif /* _DIRENT_HAVE_D_TYPE */
3184 if (os_strcmp(dent->d_name, ".") == 0 ||
3185 os_strcmp(dent->d_name, "..") == 0)
3186 continue;
3187 printf("Selected interface '%s'\n", dent->d_name);
3188 ifname = os_strdup(dent->d_name);
3189 break;
3190 }
3191 closedir(dir);
3192#endif /* CONFIG_CTRL_IFACE_UNIX */
3193
3194#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3195 char buf[2048], *pos;
3196 size_t len;
3197 struct wpa_ctrl *ctrl;
3198 int ret;
3199
3200 ctrl = wpa_ctrl_open(NULL);
3201 if (ctrl == NULL)
3202 return NULL;
3203
3204 len = sizeof(buf) - 1;
3205 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3206 if (ret >= 0) {
3207 buf[len] = '\0';
3208 pos = os_strchr(buf, '\n');
3209 if (pos)
3210 *pos = '\0';
3211 ifname = os_strdup(buf);
3212 }
3213 wpa_ctrl_close(ctrl);
3214#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3215
3216 return ifname;
3217}
3218
3219
3220int main(int argc, char *argv[])
3221{
3222 int warning_displayed = 0;
3223 int c;
3224 int daemonize = 0;
3225 int ret = 0;
3226 const char *global = NULL;
3227
3228 if (os_program_init())
3229 return -1;
3230
3231 for (;;) {
3232 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3233 if (c < 0)
3234 break;
3235 switch (c) {
3236 case 'a':
3237 action_file = optarg;
3238 break;
3239 case 'B':
3240 daemonize = 1;
3241 break;
3242 case 'g':
3243 global = optarg;
3244 break;
3245 case 'G':
3246 ping_interval = atoi(optarg);
3247 break;
3248 case 'h':
3249 usage();
3250 return 0;
3251 case 'v':
3252 printf("%s\n", wpa_cli_version);
3253 return 0;
3254 case 'i':
3255 os_free(ctrl_ifname);
3256 ctrl_ifname = os_strdup(optarg);
3257 break;
3258 case 'p':
3259 ctrl_iface_dir = optarg;
3260 break;
3261 case 'P':
3262 pid_file = optarg;
3263 break;
3264 default:
3265 usage();
3266 return -1;
3267 }
3268 }
3269
3270 interactive = (argc == optind) && (action_file == NULL);
3271
3272 if (interactive)
3273 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3274
3275 if (eloop_init())
3276 return -1;
3277
3278 if (global) {
3279#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3280 ctrl_conn = wpa_ctrl_open(NULL);
3281#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3282 ctrl_conn = wpa_ctrl_open(global);
3283#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3284 if (ctrl_conn == NULL) {
3285 perror("Failed to connect to wpa_supplicant - "
3286 "wpa_ctrl_open");
3287 return -1;
3288 }
3289 }
3290
3291#ifndef _WIN32_WCE
3292 signal(SIGINT, wpa_cli_terminate);
3293 signal(SIGTERM, wpa_cli_terminate);
3294#endif /* _WIN32_WCE */
3295
3296 if (ctrl_ifname == NULL)
3297 ctrl_ifname = wpa_cli_get_default_ifname();
3298
3299 if (interactive) {
3300 for (; !global;) {
3301 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3302 if (warning_displayed)
3303 printf("Connection established.\n");
3304 break;
3305 }
3306
3307 if (!warning_displayed) {
3308 printf("Could not connect to wpa_supplicant - "
3309 "re-trying\n");
3310 warning_displayed = 1;
3311 }
3312 os_sleep(1, 0);
3313 continue;
3314 }
3315 } else {
3316 if (!global &&
3317 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3318 perror("Failed to connect to wpa_supplicant - "
3319 "wpa_ctrl_open");
3320 return -1;
3321 }
3322
3323 if (action_file) {
3324 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3325 wpa_cli_attached = 1;
3326 } else {
3327 printf("Warning: Failed to attach to "
3328 "wpa_supplicant.\n");
3329 return -1;
3330 }
3331 }
3332 }
3333
3334 if (daemonize && os_daemonize(pid_file))
3335 return -1;
3336
3337 if (interactive)
3338 wpa_cli_interactive();
3339 else if (action_file)
3340 wpa_cli_action(ctrl_conn);
3341 else
3342 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3343
3344 os_free(ctrl_ifname);
3345 eloop_destroy();
3346 wpa_cli_cleanup();
3347
3348 return ret;
3349}
3350
3351#else /* CONFIG_CTRL_IFACE */
3352int main(int argc, char *argv[])
3353{
3354 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3355 return -1;
3356}
3357#endif /* CONFIG_CTRL_IFACE */