blob: 7453a54660107f2b73f9c962305e1d360a5968cd [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
Dmitry Shmidt0716c122011-04-08 15:03:17 -07002355static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
2356{
2357 char cmd[256];
2358 int i;
2359 int len;
2360
2361 if (argc < 1) {
2362 printf("Invalid DRIVER command: needs one argument (cmd)\n");
2363 return -1;
2364 }
2365
2366 len = os_snprintf(cmd, sizeof(cmd), "DRIVER %s", argv[0]);
2367 for (i=1; i < argc; i++)
2368 len += os_snprintf(cmd + len, sizeof(cmd) - len, " %s", argv[i]);
2369 cmd[sizeof(cmd) - 1] = '\0';
2370 printf("%s: %s\n", __func__, cmd);
2371 return wpa_ctrl_command(ctrl, cmd);
2372}
2373
2374
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002375enum wpa_cli_cmd_flags {
2376 cli_cmd_flag_none = 0x00,
2377 cli_cmd_flag_sensitive = 0x01
2378};
2379
2380struct wpa_cli_cmd {
2381 const char *cmd;
2382 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2383 enum wpa_cli_cmd_flags flags;
2384 const char *usage;
2385};
2386
2387static struct wpa_cli_cmd wpa_cli_commands[] = {
2388 { "status", wpa_cli_cmd_status,
2389 cli_cmd_flag_none,
2390 "[verbose] = get current WPA/EAPOL/EAP status" },
2391 { "ping", wpa_cli_cmd_ping,
2392 cli_cmd_flag_none,
2393 "= pings wpa_supplicant" },
2394 { "relog", wpa_cli_cmd_relog,
2395 cli_cmd_flag_none,
2396 "= re-open log-file (allow rolling logs)" },
2397 { "note", wpa_cli_cmd_note,
2398 cli_cmd_flag_none,
2399 "<text> = add a note to wpa_supplicant debug log" },
2400 { "mib", wpa_cli_cmd_mib,
2401 cli_cmd_flag_none,
2402 "= get MIB variables (dot1x, dot11)" },
2403 { "help", wpa_cli_cmd_help,
2404 cli_cmd_flag_none,
2405 "= show this usage help" },
2406 { "interface", wpa_cli_cmd_interface,
2407 cli_cmd_flag_none,
2408 "[ifname] = show interfaces/select interface" },
2409 { "level", wpa_cli_cmd_level,
2410 cli_cmd_flag_none,
2411 "<debug level> = change debug level" },
2412 { "license", wpa_cli_cmd_license,
2413 cli_cmd_flag_none,
2414 "= show full wpa_cli license" },
2415 { "quit", wpa_cli_cmd_quit,
2416 cli_cmd_flag_none,
2417 "= exit wpa_cli" },
2418 { "set", wpa_cli_cmd_set,
2419 cli_cmd_flag_none,
2420 "= set variables (shows list of variables when run without "
2421 "arguments)" },
2422 { "get", wpa_cli_cmd_get,
2423 cli_cmd_flag_none,
2424 "<name> = get information" },
2425 { "logon", wpa_cli_cmd_logon,
2426 cli_cmd_flag_none,
2427 "= IEEE 802.1X EAPOL state machine logon" },
2428 { "logoff", wpa_cli_cmd_logoff,
2429 cli_cmd_flag_none,
2430 "= IEEE 802.1X EAPOL state machine logoff" },
2431 { "pmksa", wpa_cli_cmd_pmksa,
2432 cli_cmd_flag_none,
2433 "= show PMKSA cache" },
2434 { "reassociate", wpa_cli_cmd_reassociate,
2435 cli_cmd_flag_none,
2436 "= force reassociation" },
2437 { "preauthenticate", wpa_cli_cmd_preauthenticate,
2438 cli_cmd_flag_none,
2439 "<BSSID> = force preauthentication" },
2440 { "identity", wpa_cli_cmd_identity,
2441 cli_cmd_flag_none,
2442 "<network id> <identity> = configure identity for an SSID" },
2443 { "password", wpa_cli_cmd_password,
2444 cli_cmd_flag_sensitive,
2445 "<network id> <password> = configure password for an SSID" },
2446 { "new_password", wpa_cli_cmd_new_password,
2447 cli_cmd_flag_sensitive,
2448 "<network id> <password> = change password for an SSID" },
2449 { "pin", wpa_cli_cmd_pin,
2450 cli_cmd_flag_sensitive,
2451 "<network id> <pin> = configure pin for an SSID" },
2452 { "otp", wpa_cli_cmd_otp,
2453 cli_cmd_flag_sensitive,
2454 "<network id> <password> = configure one-time-password for an SSID"
2455 },
2456 { "passphrase", wpa_cli_cmd_passphrase,
2457 cli_cmd_flag_sensitive,
2458 "<network id> <passphrase> = configure private key passphrase\n"
2459 " for an SSID" },
2460 { "bssid", wpa_cli_cmd_bssid,
2461 cli_cmd_flag_none,
2462 "<network id> <BSSID> = set preferred BSSID for an SSID" },
Dmitry Shmidt696359e2011-03-16 15:04:31 -07002463 { "blacklist", wpa_cli_cmd_blacklist,
2464 cli_cmd_flag_none,
2465 "<BSSID> = add a BSSID to the blacklist\n"
2466 "blacklist clear = clear the blacklist\n"
2467 "blacklist = display the blacklist" },
2468 { "log_level", wpa_cli_cmd_log_level,
2469 cli_cmd_flag_none,
2470 "<level> [<timestamp>] = update the log level/timestamp of wpa_supplicant\n"
2471 "log_level = display the current log level and log options" },
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002472 { "list_networks", wpa_cli_cmd_list_networks,
2473 cli_cmd_flag_none,
2474 "= list configured networks" },
2475 { "select_network", wpa_cli_cmd_select_network,
2476 cli_cmd_flag_none,
2477 "<network id> = select a network (disable others)" },
2478 { "enable_network", wpa_cli_cmd_enable_network,
2479 cli_cmd_flag_none,
2480 "<network id> = enable a network" },
2481 { "disable_network", wpa_cli_cmd_disable_network,
2482 cli_cmd_flag_none,
2483 "<network id> = disable a network" },
2484 { "add_network", wpa_cli_cmd_add_network,
2485 cli_cmd_flag_none,
2486 "= add a network" },
2487 { "remove_network", wpa_cli_cmd_remove_network,
2488 cli_cmd_flag_none,
2489 "<network id> = remove a network" },
2490 { "set_network", wpa_cli_cmd_set_network,
2491 cli_cmd_flag_sensitive,
2492 "<network id> <variable> <value> = set network variables (shows\n"
2493 " list of variables when run without arguments)" },
2494 { "get_network", wpa_cli_cmd_get_network,
2495 cli_cmd_flag_none,
2496 "<network id> <variable> = get network variables" },
2497 { "save_config", wpa_cli_cmd_save_config,
2498 cli_cmd_flag_none,
2499 "= save the current configuration" },
2500 { "disconnect", wpa_cli_cmd_disconnect,
2501 cli_cmd_flag_none,
2502 "= disconnect and wait for reassociate/reconnect command before\n"
2503 " connecting" },
2504 { "reconnect", wpa_cli_cmd_reconnect,
2505 cli_cmd_flag_none,
2506 "= like reassociate, but only takes effect if already disconnected"
2507 },
2508 { "scan", wpa_cli_cmd_scan,
2509 cli_cmd_flag_none,
2510 "= request new BSS scan" },
2511 { "scan_results", wpa_cli_cmd_scan_results,
2512 cli_cmd_flag_none,
2513 "= get latest scan results" },
2514 { "bss", wpa_cli_cmd_bss,
2515 cli_cmd_flag_none,
2516 "<<idx> | <bssid>> = get detailed scan result info" },
2517 { "get_capability", wpa_cli_cmd_get_capability,
2518 cli_cmd_flag_none,
2519 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2520 { "reconfigure", wpa_cli_cmd_reconfigure,
2521 cli_cmd_flag_none,
2522 "= force wpa_supplicant to re-read its configuration file" },
2523 { "terminate", wpa_cli_cmd_terminate,
2524 cli_cmd_flag_none,
2525 "= terminate wpa_supplicant" },
2526 { "interface_add", wpa_cli_cmd_interface_add,
2527 cli_cmd_flag_none,
2528 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2529 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2530 " are optional" },
2531 { "interface_remove", wpa_cli_cmd_interface_remove,
2532 cli_cmd_flag_none,
2533 "<ifname> = removes the interface" },
2534 { "interface_list", wpa_cli_cmd_interface_list,
2535 cli_cmd_flag_none,
2536 "= list available interfaces" },
2537 { "ap_scan", wpa_cli_cmd_ap_scan,
2538 cli_cmd_flag_none,
2539 "<value> = set ap_scan parameter" },
2540 { "scan_interval", wpa_cli_cmd_scan_interval,
2541 cli_cmd_flag_none,
2542 "<value> = set scan_interval parameter (in seconds)" },
2543 { "bss_expire_age", wpa_cli_cmd_bss_expire_age,
2544 cli_cmd_flag_none,
2545 "<value> = set BSS expiration age parameter" },
2546 { "bss_expire_count", wpa_cli_cmd_bss_expire_count,
2547 cli_cmd_flag_none,
2548 "<value> = set BSS expiration scan count parameter" },
2549 { "stkstart", wpa_cli_cmd_stkstart,
2550 cli_cmd_flag_none,
2551 "<addr> = request STK negotiation with <addr>" },
2552 { "ft_ds", wpa_cli_cmd_ft_ds,
2553 cli_cmd_flag_none,
2554 "<addr> = request over-the-DS FT with <addr>" },
2555 { "wps_pbc", wpa_cli_cmd_wps_pbc,
2556 cli_cmd_flag_none,
2557 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2558 { "wps_pin", wpa_cli_cmd_wps_pin,
2559 cli_cmd_flag_sensitive,
2560 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2561 "hardcoded)" },
2562 { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
2563 cli_cmd_flag_sensitive,
2564 "<PIN> = verify PIN checksum" },
2565 { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2566 "Cancels the pending WPS operation" },
2567#ifdef CONFIG_WPS_OOB
2568 { "wps_oob", wpa_cli_cmd_wps_oob,
2569 cli_cmd_flag_sensitive,
2570 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2571#endif /* CONFIG_WPS_OOB */
2572 { "wps_reg", wpa_cli_cmd_wps_reg,
2573 cli_cmd_flag_sensitive,
2574 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2575 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
2576 cli_cmd_flag_sensitive,
2577 "[params..] = enable/disable AP PIN" },
2578 { "wps_er_start", wpa_cli_cmd_wps_er_start,
2579 cli_cmd_flag_none,
2580 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2581 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2582 cli_cmd_flag_none,
2583 "= stop Wi-Fi Protected Setup External Registrar" },
2584 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2585 cli_cmd_flag_sensitive,
2586 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2587 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2588 cli_cmd_flag_none,
2589 "<UUID> = accept an Enrollee PBC using External Registrar" },
2590 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2591 cli_cmd_flag_sensitive,
2592 "<UUID> <PIN> = learn AP configuration" },
2593 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
2594 cli_cmd_flag_none,
2595 "<UUID> <network id> = set AP configuration for enrolling" },
2596 { "wps_er_config", wpa_cli_cmd_wps_er_config,
2597 cli_cmd_flag_sensitive,
2598 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2599 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2600 cli_cmd_flag_none,
2601 "<addr> = request RSN authentication with <addr> in IBSS" },
2602#ifdef CONFIG_AP
2603 { "sta", wpa_cli_cmd_sta,
2604 cli_cmd_flag_none,
2605 "<addr> = get information about an associated station (AP)" },
2606 { "all_sta", wpa_cli_cmd_all_sta,
2607 cli_cmd_flag_none,
2608 "= get information about all associated stations (AP)" },
2609#endif /* CONFIG_AP */
2610 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2611 "= notification of suspend/hibernate" },
2612 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2613 "= notification of resume/thaw" },
2614 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2615 "= drop SA without deauth/disassoc (test command)" },
2616 { "roam", wpa_cli_cmd_roam,
2617 cli_cmd_flag_none,
2618 "<addr> = roam to the specified BSS" },
2619#ifdef CONFIG_P2P
2620 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2621 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2622 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2623 "= stop P2P Devices search" },
2624 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2625 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2626 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2627 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2628 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2629 "<ifname> = remove P2P group interface (terminate group if GO)" },
2630 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2631 "= add a new P2P group (local end as GO)" },
2632 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2633 "<addr> <method> = request provisioning discovery" },
2634 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2635 cli_cmd_flag_none,
2636 "= get the passphrase for a group (GO only)" },
2637 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2638 cli_cmd_flag_none,
2639 "<addr> <TLVs> = schedule service discovery request" },
2640 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2641 cli_cmd_flag_none,
2642 "<id> = cancel pending service discovery request" },
2643 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2644 cli_cmd_flag_none,
2645 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2646 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2647 cli_cmd_flag_none,
2648 "= indicate change in local services" },
2649 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2650 cli_cmd_flag_none,
2651 "<external> = set external processing of service discovery" },
2652 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2653 cli_cmd_flag_none,
2654 "= remove all stored service entries" },
2655 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2656 cli_cmd_flag_none,
2657 "<bonjour|upnp> <query|version> <response|service> = add a local "
2658 "service" },
2659 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2660 cli_cmd_flag_none,
2661 "<bonjour|upnp> <query|version> [|service] = remove a local "
2662 "service" },
2663 { "p2p_reject", wpa_cli_cmd_p2p_reject,
2664 cli_cmd_flag_none,
2665 "<addr> = reject connection attempts from a specific peer" },
2666 { "p2p_invite", wpa_cli_cmd_p2p_invite,
2667 cli_cmd_flag_none,
2668 "<cmd> [peer=addr] = invite peer" },
2669 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2670 "[discovered] = list known (optionally, only fully discovered) P2P "
2671 "peers" },
2672 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2673 "<address> = show information about known P2P peer" },
2674 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2675 "<field> <value> = set a P2P parameter" },
2676 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2677 "= flush P2P state" },
2678 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
2679 "= cancel P2P group formation" },
2680 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none,
2681 "<address> = unauthorize a peer" },
2682 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2683 "[<duration> <interval>] [<duration> <interval>] = request GO "
2684 "presence" },
2685 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2686 "[<period> <interval>] = set extended listen timing" },
2687#endif /* CONFIG_P2P */
2688 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
2689 "<0/1> = disable/enable automatic reconnection" },
2690 { "tdls_discover", wpa_cli_cmd_tdls_discover,
2691 cli_cmd_flag_none,
2692 "<addr> = request TDLS discovery with <addr>" },
2693 { "tdls_setup", wpa_cli_cmd_tdls_setup,
2694 cli_cmd_flag_none,
2695 "<addr> = request TDLS setup with <addr>" },
2696 { "tdls_teardown", wpa_cli_cmd_tdls_teardown,
2697 cli_cmd_flag_none,
2698 "<addr> = tear down TDLS with <addr>" },
2699 { "signal_poll", wpa_cli_cmd_signal_poll,
2700 cli_cmd_flag_none,
2701 "= get signal parameters" },
Dmitry Shmidt0716c122011-04-08 15:03:17 -07002702 { "driver", wpa_cli_cmd_driver,
2703 cli_cmd_flag_none,
2704 "<command> = driver private commands" },
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002705 { NULL, NULL, cli_cmd_flag_none, NULL }
2706};
2707
2708
2709/*
2710 * Prints command usage, lines are padded with the specified string.
2711 */
2712static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2713{
2714 char c;
2715 size_t n;
2716
2717 printf("%s%s ", pad, cmd->cmd);
2718 for (n = 0; (c = cmd->usage[n]); n++) {
2719 printf("%c", c);
2720 if (c == '\n')
2721 printf("%s", pad);
2722 }
2723 printf("\n");
2724}
2725
2726
2727static void print_help(void)
2728{
2729 int n;
2730 printf("commands:\n");
2731 for (n = 0; wpa_cli_commands[n].cmd; n++)
2732 print_cmd_help(&wpa_cli_commands[n], " ");
2733}
2734
2735
2736static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
2737{
2738 const char *c, *delim;
2739 int n;
2740 size_t len;
2741
2742 delim = os_strchr(cmd, ' ');
2743 if (delim)
2744 len = delim - cmd;
2745 else
2746 len = os_strlen(cmd);
2747
2748 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2749 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2750 return (wpa_cli_commands[n].flags &
2751 cli_cmd_flag_sensitive);
2752 }
2753 return 0;
2754}
2755
2756
2757static char ** wpa_list_cmd_list(void)
2758{
2759 char **res;
2760 int i, count;
2761
2762 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
2763 res = os_zalloc(count * sizeof(char *));
2764 if (res == NULL)
2765 return NULL;
2766
2767 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2768 res[i] = os_strdup(wpa_cli_commands[i].cmd);
2769 if (res[i] == NULL)
2770 break;
2771 }
2772
2773 return res;
2774}
2775
2776
2777static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
2778 int pos)
2779{
2780 int i;
2781
2782 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2783 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
2784 edit_clear_line();
2785 printf("\r%s\n", wpa_cli_commands[i].usage);
2786 edit_redraw();
2787 break;
2788 }
2789 }
2790
2791 return NULL;
2792}
2793
2794
2795static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
2796{
2797 char **res;
2798 const char *end;
2799 char *cmd;
2800
2801 end = os_strchr(str, ' ');
2802 if (end == NULL || str + pos < end)
2803 return wpa_list_cmd_list();
2804
2805 cmd = os_malloc(pos + 1);
2806 if (cmd == NULL)
2807 return NULL;
2808 os_memcpy(cmd, str, pos);
2809 cmd[end - str] = '\0';
2810 res = wpa_cli_cmd_completion(cmd, str, pos);
2811 os_free(cmd);
2812 return res;
2813}
2814
2815
2816static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
2817{
2818 struct wpa_cli_cmd *cmd, *match = NULL;
2819 int count;
2820 int ret = 0;
2821
2822 count = 0;
2823 cmd = wpa_cli_commands;
2824 while (cmd->cmd) {
2825 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
2826 {
2827 match = cmd;
2828 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
2829 /* we have an exact match */
2830 count = 1;
2831 break;
2832 }
2833 count++;
2834 }
2835 cmd++;
2836 }
2837
2838 if (count > 1) {
2839 printf("Ambiguous command '%s'; possible commands:", argv[0]);
2840 cmd = wpa_cli_commands;
2841 while (cmd->cmd) {
2842 if (os_strncasecmp(cmd->cmd, argv[0],
2843 os_strlen(argv[0])) == 0) {
2844 printf(" %s", cmd->cmd);
2845 }
2846 cmd++;
2847 }
2848 printf("\n");
2849 ret = 1;
2850 } else if (count == 0) {
2851 printf("Unknown command '%s'\n", argv[0]);
2852 ret = 1;
2853 } else {
2854 ret = match->handler(ctrl, argc - 1, &argv[1]);
2855 }
2856
2857 return ret;
2858}
2859
2860
2861static int str_match(const char *a, const char *b)
2862{
2863 return os_strncmp(a, b, os_strlen(b)) == 0;
2864}
2865
2866
2867static int wpa_cli_exec(const char *program, const char *arg1,
2868 const char *arg2)
2869{
2870 char *cmd;
2871 size_t len;
2872 int res;
2873 int ret = 0;
2874
2875 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
2876 cmd = os_malloc(len);
2877 if (cmd == NULL)
2878 return -1;
2879 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
2880 if (res < 0 || (size_t) res >= len) {
2881 os_free(cmd);
2882 return -1;
2883 }
2884 cmd[len - 1] = '\0';
2885#ifndef _WIN32_WCE
2886 if (system(cmd) < 0)
2887 ret = -1;
2888#endif /* _WIN32_WCE */
2889 os_free(cmd);
2890
2891 return ret;
2892}
2893
2894
2895static void wpa_cli_action_process(const char *msg)
2896{
2897 const char *pos;
2898 char *copy = NULL, *id, *pos2;
2899
2900 pos = msg;
2901 if (*pos == '<') {
2902 /* skip priority */
2903 pos = os_strchr(pos, '>');
2904 if (pos)
2905 pos++;
2906 else
2907 pos = msg;
2908 }
2909
2910 if (str_match(pos, WPA_EVENT_CONNECTED)) {
2911 int new_id = -1;
2912 os_unsetenv("WPA_ID");
2913 os_unsetenv("WPA_ID_STR");
2914 os_unsetenv("WPA_CTRL_DIR");
2915
2916 pos = os_strstr(pos, "[id=");
2917 if (pos)
2918 copy = os_strdup(pos + 4);
2919
2920 if (copy) {
2921 pos2 = id = copy;
2922 while (*pos2 && *pos2 != ' ')
2923 pos2++;
2924 *pos2++ = '\0';
2925 new_id = atoi(id);
2926 os_setenv("WPA_ID", id, 1);
2927 while (*pos2 && *pos2 != '=')
2928 pos2++;
2929 if (*pos2 == '=')
2930 pos2++;
2931 id = pos2;
2932 while (*pos2 && *pos2 != ']')
2933 pos2++;
2934 *pos2 = '\0';
2935 os_setenv("WPA_ID_STR", id, 1);
2936 os_free(copy);
2937 }
2938
2939 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
2940
2941 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
2942 wpa_cli_connected = 1;
2943 wpa_cli_last_id = new_id;
2944 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
2945 }
2946 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
2947 if (wpa_cli_connected) {
2948 wpa_cli_connected = 0;
2949 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
2950 }
2951 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
2952 wpa_cli_exec(action_file, ctrl_ifname, pos);
2953 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
2954 wpa_cli_exec(action_file, ctrl_ifname, pos);
2955 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
2956 wpa_cli_exec(action_file, ctrl_ifname, pos);
2957 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
2958 wpa_cli_exec(action_file, ctrl_ifname, pos);
2959 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
2960 wpa_cli_exec(action_file, ctrl_ifname, pos);
2961 } else if (str_match(pos, WPS_EVENT_FAIL)) {
2962 wpa_cli_exec(action_file, ctrl_ifname, pos);
2963 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
2964 printf("wpa_supplicant is terminating - stop monitoring\n");
2965 wpa_cli_quit = 1;
2966 }
2967}
2968
2969
2970#ifndef CONFIG_ANSI_C_EXTRA
2971static void wpa_cli_action_cb(char *msg, size_t len)
2972{
2973 wpa_cli_action_process(msg);
2974}
2975#endif /* CONFIG_ANSI_C_EXTRA */
2976
2977
2978static void wpa_cli_reconnect(void)
2979{
2980 wpa_cli_close_connection();
2981 wpa_cli_open_connection(ctrl_ifname, 1);
2982}
2983
2984
2985static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
2986{
2987 if (ctrl_conn == NULL) {
2988 wpa_cli_reconnect();
2989 return;
2990 }
2991 while (wpa_ctrl_pending(ctrl) > 0) {
2992 char buf[256];
2993 size_t len = sizeof(buf) - 1;
2994 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
2995 buf[len] = '\0';
2996 if (action_monitor)
2997 wpa_cli_action_process(buf);
2998 else {
2999 if (wpa_cli_show_event(buf)) {
3000 edit_clear_line();
3001 printf("\r%s\n", buf);
3002 edit_redraw();
3003 }
3004 }
3005 } else {
3006 printf("Could not read pending message.\n");
3007 break;
3008 }
3009 }
3010
3011 if (wpa_ctrl_pending(ctrl) < 0) {
3012 printf("Connection to wpa_supplicant lost - trying to "
3013 "reconnect\n");
3014 wpa_cli_reconnect();
3015 }
3016}
3017
3018#define max_args 10
3019
3020static int tokenize_cmd(char *cmd, char *argv[])
3021{
3022 char *pos;
3023 int argc = 0;
3024
3025 pos = cmd;
3026 for (;;) {
3027 while (*pos == ' ')
3028 pos++;
3029 if (*pos == '\0')
3030 break;
3031 argv[argc] = pos;
3032 argc++;
3033 if (argc == max_args)
3034 break;
3035 if (*pos == '"') {
3036 char *pos2 = os_strrchr(pos, '"');
3037 if (pos2)
3038 pos = pos2 + 1;
3039 }
3040 while (*pos != '\0' && *pos != ' ')
3041 pos++;
3042 if (*pos == ' ')
3043 *pos++ = '\0';
3044 }
3045
3046 return argc;
3047}
3048
3049
3050static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3051{
3052 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3053 printf("Connection to wpa_supplicant lost - trying to "
3054 "reconnect\n");
3055 wpa_cli_close_connection();
3056 }
3057 if (!ctrl_conn)
3058 wpa_cli_reconnect();
3059 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3060}
3061
3062
3063static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
3064{
3065 eloop_terminate();
3066}
3067
3068
3069static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3070{
3071 wpa_cli_recv_pending(mon_conn, 0);
3072}
3073
3074
3075static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3076{
3077 char *argv[max_args];
3078 int argc;
3079 argc = tokenize_cmd(cmd, argv);
3080 if (argc)
3081 wpa_request(ctrl_conn, argc, argv);
3082}
3083
3084
3085static void wpa_cli_edit_eof_cb(void *ctx)
3086{
3087 eloop_terminate();
3088}
3089
3090
3091static void wpa_cli_interactive(void)
3092{
3093 char *home, *hfile = NULL;
3094
3095 printf("\nInteractive mode\n\n");
3096
3097 home = getenv("HOME");
3098 if (home) {
3099 const char *fname = ".wpa_cli_history";
3100 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3101 hfile = os_malloc(hfile_len);
3102 if (hfile)
3103 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3104 }
3105
3106 eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
3107 edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3108 wpa_cli_edit_completion_cb, NULL, hfile);
3109 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3110
3111 eloop_run();
3112
3113 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3114 os_free(hfile);
3115 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3116 wpa_cli_close_connection();
3117}
3118
3119
3120static void wpa_cli_action(struct wpa_ctrl *ctrl)
3121{
3122#ifdef CONFIG_ANSI_C_EXTRA
3123 /* TODO: ANSI C version(?) */
3124 printf("Action processing not supported in ANSI C build.\n");
3125#else /* CONFIG_ANSI_C_EXTRA */
3126 fd_set rfds;
3127 int fd, res;
3128 struct timeval tv;
3129 char buf[256]; /* note: large enough to fit in unsolicited messages */
3130 size_t len;
3131
3132 fd = wpa_ctrl_get_fd(ctrl);
3133
3134 while (!wpa_cli_quit) {
3135 FD_ZERO(&rfds);
3136 FD_SET(fd, &rfds);
3137 tv.tv_sec = ping_interval;
3138 tv.tv_usec = 0;
3139 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3140 if (res < 0 && errno != EINTR) {
3141 perror("select");
3142 break;
3143 }
3144
3145 if (FD_ISSET(fd, &rfds))
3146 wpa_cli_recv_pending(ctrl, 1);
3147 else {
3148 /* verify that connection is still working */
3149 len = sizeof(buf) - 1;
3150 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3151 wpa_cli_action_cb) < 0 ||
3152 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3153 printf("wpa_supplicant did not reply to PING "
3154 "command - exiting\n");
3155 break;
3156 }
3157 }
3158 }
3159#endif /* CONFIG_ANSI_C_EXTRA */
3160}
3161
3162
3163static void wpa_cli_cleanup(void)
3164{
3165 wpa_cli_close_connection();
3166 if (pid_file)
3167 os_daemonize_terminate(pid_file);
3168
3169 os_program_deinit();
3170}
3171
3172static void wpa_cli_terminate(int sig)
3173{
3174 wpa_cli_cleanup();
3175 exit(0);
3176}
3177
3178
3179static char * wpa_cli_get_default_ifname(void)
3180{
3181 char *ifname = NULL;
3182
3183#ifdef CONFIG_CTRL_IFACE_UNIX
3184 struct dirent *dent;
3185 DIR *dir = opendir(ctrl_iface_dir);
3186 if (!dir) {
3187#ifdef ANDROID
3188 char ifprop[PROPERTY_VALUE_MAX];
3189 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3190 ifname = os_strdup(ifprop);
3191 printf("Using interface '%s'\n", ifname);
3192 return ifname;
3193 }
3194#endif /* ANDROID */
3195 return NULL;
3196 }
3197 while ((dent = readdir(dir))) {
3198#ifdef _DIRENT_HAVE_D_TYPE
3199 /*
3200 * Skip the file if it is not a socket. Also accept
3201 * DT_UNKNOWN (0) in case the C library or underlying
3202 * file system does not support d_type.
3203 */
3204 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3205 continue;
3206#endif /* _DIRENT_HAVE_D_TYPE */
3207 if (os_strcmp(dent->d_name, ".") == 0 ||
3208 os_strcmp(dent->d_name, "..") == 0)
3209 continue;
3210 printf("Selected interface '%s'\n", dent->d_name);
3211 ifname = os_strdup(dent->d_name);
3212 break;
3213 }
3214 closedir(dir);
3215#endif /* CONFIG_CTRL_IFACE_UNIX */
3216
3217#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3218 char buf[2048], *pos;
3219 size_t len;
3220 struct wpa_ctrl *ctrl;
3221 int ret;
3222
3223 ctrl = wpa_ctrl_open(NULL);
3224 if (ctrl == NULL)
3225 return NULL;
3226
3227 len = sizeof(buf) - 1;
3228 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3229 if (ret >= 0) {
3230 buf[len] = '\0';
3231 pos = os_strchr(buf, '\n');
3232 if (pos)
3233 *pos = '\0';
3234 ifname = os_strdup(buf);
3235 }
3236 wpa_ctrl_close(ctrl);
3237#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3238
3239 return ifname;
3240}
3241
3242
3243int main(int argc, char *argv[])
3244{
3245 int warning_displayed = 0;
3246 int c;
3247 int daemonize = 0;
3248 int ret = 0;
3249 const char *global = NULL;
3250
3251 if (os_program_init())
3252 return -1;
3253
3254 for (;;) {
3255 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3256 if (c < 0)
3257 break;
3258 switch (c) {
3259 case 'a':
3260 action_file = optarg;
3261 break;
3262 case 'B':
3263 daemonize = 1;
3264 break;
3265 case 'g':
3266 global = optarg;
3267 break;
3268 case 'G':
3269 ping_interval = atoi(optarg);
3270 break;
3271 case 'h':
3272 usage();
3273 return 0;
3274 case 'v':
3275 printf("%s\n", wpa_cli_version);
3276 return 0;
3277 case 'i':
3278 os_free(ctrl_ifname);
3279 ctrl_ifname = os_strdup(optarg);
3280 break;
3281 case 'p':
3282 ctrl_iface_dir = optarg;
3283 break;
3284 case 'P':
3285 pid_file = optarg;
3286 break;
3287 default:
3288 usage();
3289 return -1;
3290 }
3291 }
3292
3293 interactive = (argc == optind) && (action_file == NULL);
3294
3295 if (interactive)
3296 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3297
3298 if (eloop_init())
3299 return -1;
3300
3301 if (global) {
3302#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3303 ctrl_conn = wpa_ctrl_open(NULL);
3304#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3305 ctrl_conn = wpa_ctrl_open(global);
3306#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3307 if (ctrl_conn == NULL) {
3308 perror("Failed to connect to wpa_supplicant - "
3309 "wpa_ctrl_open");
3310 return -1;
3311 }
3312 }
3313
3314#ifndef _WIN32_WCE
3315 signal(SIGINT, wpa_cli_terminate);
3316 signal(SIGTERM, wpa_cli_terminate);
3317#endif /* _WIN32_WCE */
3318
3319 if (ctrl_ifname == NULL)
3320 ctrl_ifname = wpa_cli_get_default_ifname();
3321
3322 if (interactive) {
3323 for (; !global;) {
3324 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3325 if (warning_displayed)
3326 printf("Connection established.\n");
3327 break;
3328 }
3329
3330 if (!warning_displayed) {
3331 printf("Could not connect to wpa_supplicant - "
3332 "re-trying\n");
3333 warning_displayed = 1;
3334 }
3335 os_sleep(1, 0);
3336 continue;
3337 }
3338 } else {
3339 if (!global &&
3340 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3341 perror("Failed to connect to wpa_supplicant - "
3342 "wpa_ctrl_open");
3343 return -1;
3344 }
3345
3346 if (action_file) {
3347 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3348 wpa_cli_attached = 1;
3349 } else {
3350 printf("Warning: Failed to attach to "
3351 "wpa_supplicant.\n");
3352 return -1;
3353 }
3354 }
3355 }
3356
3357 if (daemonize && os_daemonize(pid_file))
3358 return -1;
3359
3360 if (interactive)
3361 wpa_cli_interactive();
3362 else if (action_file)
3363 wpa_cli_action(ctrl_conn);
3364 else
3365 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3366
3367 os_free(ctrl_ifname);
3368 eloop_destroy();
3369 wpa_cli_cleanup();
3370
3371 return ret;
3372}
3373
3374#else /* CONFIG_CTRL_IFACE */
3375int main(int argc, char *argv[])
3376{
3377 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3378 return -1;
3379}
3380#endif /* CONFIG_CTRL_IFACE */