blob: f09a6f07415c8de171ab5f2ff4114d6eeb8a829e [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{
Dmitry Shmidtc97d8bf2011-08-30 11:10:13 -0700253 char buf[4096];
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700254 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
Dmitry Shmidtc55524a2011-07-07 11:18:38 -07001841 if (argc > 1)
1842 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s %s",
1843 argv[0], argv[1]);
1844 else
1845 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s",
1846 argv[0]);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001847 if (res < 0 || (size_t) res >= sizeof(cmd))
1848 return -1;
1849 cmd[sizeof(cmd) - 1] = '\0';
1850 return wpa_ctrl_command(ctrl, cmd);
1851}
1852
1853
1854static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1855 char *argv[])
1856{
1857 char cmd[128];
1858 int res;
1859
1860 if (argc != 2) {
1861 printf("Invalid P2P_PROV_DISC command: needs two arguments "
1862 "(address and config method\n"
1863 "(display, keypad, or pbc)\n");
1864 return -1;
1865 }
1866
1867 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
1868 argv[0], argv[1]);
1869 if (res < 0 || (size_t) res >= sizeof(cmd))
1870 return -1;
1871 cmd[sizeof(cmd) - 1] = '\0';
1872 return wpa_ctrl_command(ctrl, cmd);
1873}
1874
1875
1876static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1877 char *argv[])
1878{
1879 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1880}
1881
1882
1883static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1884 char *argv[])
1885{
1886 char cmd[4096];
1887 int res;
1888
1889 if (argc != 2 && argc != 4) {
1890 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1891 "arguments (address and TLVs) or four arguments "
1892 "(address, \"upnp\", version, search target "
1893 "(SSDP ST:)\n");
1894 return -1;
1895 }
1896
1897 if (argc == 4)
1898 res = os_snprintf(cmd, sizeof(cmd),
1899 "P2P_SERV_DISC_REQ %s %s %s %s",
1900 argv[0], argv[1], argv[2], argv[3]);
1901 else
1902 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
1903 argv[0], argv[1]);
1904 if (res < 0 || (size_t) res >= sizeof(cmd))
1905 return -1;
1906 cmd[sizeof(cmd) - 1] = '\0';
1907 return wpa_ctrl_command(ctrl, cmd);
1908}
1909
1910
1911static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1912 int argc, char *argv[])
1913{
1914 char cmd[128];
1915 int res;
1916
1917 if (argc != 1) {
1918 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
1919 "argument (pending request identifier)\n");
1920 return -1;
1921 }
1922
1923 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
1924 argv[0]);
1925 if (res < 0 || (size_t) res >= sizeof(cmd))
1926 return -1;
1927 cmd[sizeof(cmd) - 1] = '\0';
1928 return wpa_ctrl_command(ctrl, cmd);
1929}
1930
1931
1932static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1933 char *argv[])
1934{
1935 char cmd[4096];
1936 int res;
1937
1938 if (argc != 4) {
1939 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1940 "arguments (freq, address, dialog token, and TLVs)\n");
1941 return -1;
1942 }
1943
1944 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1945 argv[0], argv[1], argv[2], argv[3]);
1946 if (res < 0 || (size_t) res >= sizeof(cmd))
1947 return -1;
1948 cmd[sizeof(cmd) - 1] = '\0';
1949 return wpa_ctrl_command(ctrl, cmd);
1950}
1951
1952
1953static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1954 char *argv[])
1955{
1956 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1957}
1958
1959
1960static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1961 int argc, char *argv[])
1962{
1963 char cmd[128];
1964 int res;
1965
1966 if (argc != 1) {
1967 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
1968 "argument (external processing: 0/1)\n");
1969 return -1;
1970 }
1971
1972 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
1973 argv[0]);
1974 if (res < 0 || (size_t) res >= sizeof(cmd))
1975 return -1;
1976 cmd[sizeof(cmd) - 1] = '\0';
1977 return wpa_ctrl_command(ctrl, cmd);
1978}
1979
1980
1981static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1982 char *argv[])
1983{
1984 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1985}
1986
1987
1988static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1989 char *argv[])
1990{
1991 char cmd[4096];
1992 int res;
1993
1994 if (argc != 3 && argc != 4) {
1995 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1996 "arguments\n");
1997 return -1;
1998 }
1999
2000 if (argc == 4)
2001 res = os_snprintf(cmd, sizeof(cmd),
2002 "P2P_SERVICE_ADD %s %s %s %s",
2003 argv[0], argv[1], argv[2], argv[3]);
2004 else
2005 res = os_snprintf(cmd, sizeof(cmd),
2006 "P2P_SERVICE_ADD %s %s %s",
2007 argv[0], argv[1], argv[2]);
2008 if (res < 0 || (size_t) res >= sizeof(cmd))
2009 return -1;
2010 cmd[sizeof(cmd) - 1] = '\0';
2011 return wpa_ctrl_command(ctrl, cmd);
2012}
2013
2014
2015static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2016 char *argv[])
2017{
2018 char cmd[4096];
2019 int res;
2020
2021 if (argc != 2 && argc != 3) {
2022 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2023 "arguments\n");
2024 return -1;
2025 }
2026
2027 if (argc == 3)
2028 res = os_snprintf(cmd, sizeof(cmd),
2029 "P2P_SERVICE_DEL %s %s %s",
2030 argv[0], argv[1], argv[2]);
2031 else
2032 res = os_snprintf(cmd, sizeof(cmd),
2033 "P2P_SERVICE_DEL %s %s",
2034 argv[0], argv[1]);
2035 if (res < 0 || (size_t) res >= sizeof(cmd))
2036 return -1;
2037 cmd[sizeof(cmd) - 1] = '\0';
2038 return wpa_ctrl_command(ctrl, cmd);
2039}
2040
2041
2042static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2043 int argc, char *argv[])
2044{
2045 char cmd[128];
2046 int res;
2047
2048 if (argc != 1) {
2049 printf("Invalid P2P_REJECT command: needs one argument "
2050 "(peer address)\n");
2051 return -1;
2052 }
2053
2054 res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
2055 if (res < 0 || (size_t) res >= sizeof(cmd))
2056 return -1;
2057 cmd[sizeof(cmd) - 1] = '\0';
2058 return wpa_ctrl_command(ctrl, cmd);
2059}
2060
2061
2062static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2063 int argc, char *argv[])
2064{
2065 char cmd[128];
2066 int res;
2067
2068 if (argc < 1) {
2069 printf("Invalid P2P_INVITE command: needs at least one "
2070 "argument\n");
2071 return -1;
2072 }
2073
2074 if (argc > 2)
2075 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
2076 argv[0], argv[1], argv[2]);
2077 else if (argc > 1)
2078 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
2079 argv[0], argv[1]);
2080 else
2081 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
2082 if (res < 0 || (size_t) res >= sizeof(cmd))
2083 return -1;
2084 cmd[sizeof(cmd) - 1] = '\0';
2085 return wpa_ctrl_command(ctrl, cmd);
2086}
2087
2088
2089static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2090{
2091 char buf[64];
2092 if (argc != 1) {
2093 printf("Invalid 'p2p_peer' command - exactly one argument, "
2094 "P2P peer device address, is required.\n");
2095 return -1;
2096 }
2097 os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
2098 return wpa_ctrl_command(ctrl, buf);
2099}
2100
2101
2102static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2103 char *addr, size_t addr_len,
2104 int discovered)
2105{
2106 char buf[4096], *pos;
2107 size_t len;
2108 int ret;
2109
2110 if (ctrl_conn == NULL)
2111 return -1;
2112 len = sizeof(buf) - 1;
2113 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
2114 wpa_cli_msg_cb);
2115 if (ret == -2) {
2116 printf("'%s' command timed out.\n", cmd);
2117 return -2;
2118 } else if (ret < 0) {
2119 printf("'%s' command failed.\n", cmd);
2120 return -1;
2121 }
2122
2123 buf[len] = '\0';
2124 if (memcmp(buf, "FAIL", 4) == 0)
2125 return -1;
2126
2127 pos = buf;
2128 while (*pos != '\0' && *pos != '\n')
2129 pos++;
2130 *pos++ = '\0';
2131 os_strlcpy(addr, buf, addr_len);
2132 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2133 printf("%s\n", addr);
2134 return 0;
2135}
2136
2137
2138static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2139{
2140 char addr[32], cmd[64];
2141 int discovered;
2142
2143 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2144
2145 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2146 addr, sizeof(addr), discovered))
2147 return 0;
2148 do {
2149 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2150 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2151 discovered) == 0);
2152
2153 return -1;
2154}
2155
2156
2157static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2158{
2159 char cmd[100];
2160 int res;
2161
2162 if (argc != 2) {
2163 printf("Invalid P2P_SET command: needs two arguments (field, "
2164 "value)\n");
2165 return -1;
2166 }
2167
2168 res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2169 if (res < 0 || (size_t) res >= sizeof(cmd))
2170 return -1;
2171 cmd[sizeof(cmd) - 1] = '\0';
2172 return wpa_ctrl_command(ctrl, cmd);
2173}
2174
2175
2176static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2177{
2178 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2179}
2180
2181
2182static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2183 char *argv[])
2184{
2185 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2186}
2187
2188
2189static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2190 char *argv[])
2191{
2192 char cmd[100];
2193 int res;
2194
2195 if (argc != 1) {
2196 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2197 "(peer address)\n");
2198 return -1;
2199 }
2200
2201 res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]);
2202
2203 if (res < 0 || (size_t) res >= sizeof(cmd))
2204 return -1;
2205
2206 cmd[sizeof(cmd) - 1] = '\0';
2207 return wpa_ctrl_command(ctrl, cmd);
2208}
2209
2210
2211static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2212 char *argv[])
2213{
2214 char cmd[100];
2215 int res;
2216
2217 if (argc != 0 && argc != 2 && argc != 4) {
2218 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2219 "(preferred duration, interval; in microsecods).\n"
2220 "Optional second pair can be used to provide "
2221 "acceptable values.\n");
2222 return -1;
2223 }
2224
2225 if (argc == 4)
2226 res = os_snprintf(cmd, sizeof(cmd),
2227 "P2P_PRESENCE_REQ %s %s %s %s",
2228 argv[0], argv[1], argv[2], argv[3]);
2229 else if (argc == 2)
2230 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2231 argv[0], argv[1]);
2232 else
2233 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2234 if (res < 0 || (size_t) res >= sizeof(cmd))
2235 return -1;
2236 cmd[sizeof(cmd) - 1] = '\0';
2237 return wpa_ctrl_command(ctrl, cmd);
2238}
2239
2240
2241static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2242 char *argv[])
2243{
2244 char cmd[100];
2245 int res;
2246
2247 if (argc != 0 && argc != 2) {
2248 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2249 "(availability period, availability interval; in "
2250 "millisecods).\n"
2251 "Extended Listen Timing can be cancelled with this "
2252 "command when used without parameters.\n");
2253 return -1;
2254 }
2255
2256 if (argc == 2)
2257 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2258 argv[0], argv[1]);
2259 else
2260 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2261 if (res < 0 || (size_t) res >= sizeof(cmd))
2262 return -1;
2263 cmd[sizeof(cmd) - 1] = '\0';
2264 return wpa_ctrl_command(ctrl, cmd);
2265}
2266
2267#endif /* CONFIG_P2P */
2268
2269
2270static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2271 char *argv[])
2272{
2273 char cmd[256];
2274 int res;
2275
2276 if (argc != 1) {
2277 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2278 "(0/1 = disable/enable automatic reconnection)\n");
2279 return -1;
2280 }
2281 res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2282 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2283 printf("Too long STA_AUTOCONNECT command.\n");
2284 return -1;
2285 }
2286 return wpa_ctrl_command(ctrl, cmd);
2287}
2288
2289
2290static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2291 char *argv[])
2292{
2293 char cmd[256];
2294 int res;
2295
2296 if (argc != 1) {
2297 printf("Invalid TDLS_DISCOVER command: needs one argument "
2298 "(Peer STA MAC address)\n");
2299 return -1;
2300 }
2301
2302 res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]);
2303 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2304 printf("Too long TDLS_DISCOVER command.\n");
2305 return -1;
2306 }
2307 return wpa_ctrl_command(ctrl, cmd);
2308}
2309
2310
2311static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2312 char *argv[])
2313{
2314 char cmd[256];
2315 int res;
2316
2317 if (argc != 1) {
2318 printf("Invalid TDLS_SETUP command: needs one argument "
2319 "(Peer STA MAC address)\n");
2320 return -1;
2321 }
2322
2323 res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]);
2324 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2325 printf("Too long TDLS_SETUP command.\n");
2326 return -1;
2327 }
2328 return wpa_ctrl_command(ctrl, cmd);
2329}
2330
2331
2332static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2333 char *argv[])
2334{
2335 char cmd[256];
2336 int res;
2337
2338 if (argc != 1) {
2339 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2340 "(Peer STA MAC address)\n");
2341 return -1;
2342 }
2343
2344 res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]);
2345 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2346 printf("Too long TDLS_TEARDOWN command.\n");
2347 return -1;
2348 }
2349 return wpa_ctrl_command(ctrl, cmd);
2350}
2351
2352
2353static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2354 char *argv[])
2355{
2356 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2357}
2358
2359
Dmitry Shmidt0716c122011-04-08 15:03:17 -07002360static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
2361{
2362 char cmd[256];
2363 int i;
2364 int len;
2365
2366 if (argc < 1) {
2367 printf("Invalid DRIVER command: needs one argument (cmd)\n");
2368 return -1;
2369 }
2370
2371 len = os_snprintf(cmd, sizeof(cmd), "DRIVER %s", argv[0]);
2372 for (i=1; i < argc; i++)
2373 len += os_snprintf(cmd + len, sizeof(cmd) - len, " %s", argv[i]);
2374 cmd[sizeof(cmd) - 1] = '\0';
2375 printf("%s: %s\n", __func__, cmd);
2376 return wpa_ctrl_command(ctrl, cmd);
2377}
2378
2379
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002380enum wpa_cli_cmd_flags {
2381 cli_cmd_flag_none = 0x00,
2382 cli_cmd_flag_sensitive = 0x01
2383};
2384
2385struct wpa_cli_cmd {
2386 const char *cmd;
2387 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2388 enum wpa_cli_cmd_flags flags;
2389 const char *usage;
2390};
2391
2392static struct wpa_cli_cmd wpa_cli_commands[] = {
2393 { "status", wpa_cli_cmd_status,
2394 cli_cmd_flag_none,
2395 "[verbose] = get current WPA/EAPOL/EAP status" },
2396 { "ping", wpa_cli_cmd_ping,
2397 cli_cmd_flag_none,
2398 "= pings wpa_supplicant" },
2399 { "relog", wpa_cli_cmd_relog,
2400 cli_cmd_flag_none,
2401 "= re-open log-file (allow rolling logs)" },
2402 { "note", wpa_cli_cmd_note,
2403 cli_cmd_flag_none,
2404 "<text> = add a note to wpa_supplicant debug log" },
2405 { "mib", wpa_cli_cmd_mib,
2406 cli_cmd_flag_none,
2407 "= get MIB variables (dot1x, dot11)" },
2408 { "help", wpa_cli_cmd_help,
2409 cli_cmd_flag_none,
2410 "= show this usage help" },
2411 { "interface", wpa_cli_cmd_interface,
2412 cli_cmd_flag_none,
2413 "[ifname] = show interfaces/select interface" },
2414 { "level", wpa_cli_cmd_level,
2415 cli_cmd_flag_none,
2416 "<debug level> = change debug level" },
2417 { "license", wpa_cli_cmd_license,
2418 cli_cmd_flag_none,
2419 "= show full wpa_cli license" },
2420 { "quit", wpa_cli_cmd_quit,
2421 cli_cmd_flag_none,
2422 "= exit wpa_cli" },
2423 { "set", wpa_cli_cmd_set,
2424 cli_cmd_flag_none,
2425 "= set variables (shows list of variables when run without "
2426 "arguments)" },
2427 { "get", wpa_cli_cmd_get,
2428 cli_cmd_flag_none,
2429 "<name> = get information" },
2430 { "logon", wpa_cli_cmd_logon,
2431 cli_cmd_flag_none,
2432 "= IEEE 802.1X EAPOL state machine logon" },
2433 { "logoff", wpa_cli_cmd_logoff,
2434 cli_cmd_flag_none,
2435 "= IEEE 802.1X EAPOL state machine logoff" },
2436 { "pmksa", wpa_cli_cmd_pmksa,
2437 cli_cmd_flag_none,
2438 "= show PMKSA cache" },
2439 { "reassociate", wpa_cli_cmd_reassociate,
2440 cli_cmd_flag_none,
2441 "= force reassociation" },
2442 { "preauthenticate", wpa_cli_cmd_preauthenticate,
2443 cli_cmd_flag_none,
2444 "<BSSID> = force preauthentication" },
2445 { "identity", wpa_cli_cmd_identity,
2446 cli_cmd_flag_none,
2447 "<network id> <identity> = configure identity for an SSID" },
2448 { "password", wpa_cli_cmd_password,
2449 cli_cmd_flag_sensitive,
2450 "<network id> <password> = configure password for an SSID" },
2451 { "new_password", wpa_cli_cmd_new_password,
2452 cli_cmd_flag_sensitive,
2453 "<network id> <password> = change password for an SSID" },
2454 { "pin", wpa_cli_cmd_pin,
2455 cli_cmd_flag_sensitive,
2456 "<network id> <pin> = configure pin for an SSID" },
2457 { "otp", wpa_cli_cmd_otp,
2458 cli_cmd_flag_sensitive,
2459 "<network id> <password> = configure one-time-password for an SSID"
2460 },
2461 { "passphrase", wpa_cli_cmd_passphrase,
2462 cli_cmd_flag_sensitive,
2463 "<network id> <passphrase> = configure private key passphrase\n"
2464 " for an SSID" },
2465 { "bssid", wpa_cli_cmd_bssid,
2466 cli_cmd_flag_none,
2467 "<network id> <BSSID> = set preferred BSSID for an SSID" },
Dmitry Shmidt696359e2011-03-16 15:04:31 -07002468 { "blacklist", wpa_cli_cmd_blacklist,
2469 cli_cmd_flag_none,
2470 "<BSSID> = add a BSSID to the blacklist\n"
2471 "blacklist clear = clear the blacklist\n"
2472 "blacklist = display the blacklist" },
2473 { "log_level", wpa_cli_cmd_log_level,
2474 cli_cmd_flag_none,
2475 "<level> [<timestamp>] = update the log level/timestamp of wpa_supplicant\n"
2476 "log_level = display the current log level and log options" },
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002477 { "list_networks", wpa_cli_cmd_list_networks,
2478 cli_cmd_flag_none,
2479 "= list configured networks" },
2480 { "select_network", wpa_cli_cmd_select_network,
2481 cli_cmd_flag_none,
2482 "<network id> = select a network (disable others)" },
2483 { "enable_network", wpa_cli_cmd_enable_network,
2484 cli_cmd_flag_none,
2485 "<network id> = enable a network" },
2486 { "disable_network", wpa_cli_cmd_disable_network,
2487 cli_cmd_flag_none,
2488 "<network id> = disable a network" },
2489 { "add_network", wpa_cli_cmd_add_network,
2490 cli_cmd_flag_none,
2491 "= add a network" },
2492 { "remove_network", wpa_cli_cmd_remove_network,
2493 cli_cmd_flag_none,
2494 "<network id> = remove a network" },
2495 { "set_network", wpa_cli_cmd_set_network,
2496 cli_cmd_flag_sensitive,
2497 "<network id> <variable> <value> = set network variables (shows\n"
2498 " list of variables when run without arguments)" },
2499 { "get_network", wpa_cli_cmd_get_network,
2500 cli_cmd_flag_none,
2501 "<network id> <variable> = get network variables" },
2502 { "save_config", wpa_cli_cmd_save_config,
2503 cli_cmd_flag_none,
2504 "= save the current configuration" },
2505 { "disconnect", wpa_cli_cmd_disconnect,
2506 cli_cmd_flag_none,
2507 "= disconnect and wait for reassociate/reconnect command before\n"
2508 " connecting" },
2509 { "reconnect", wpa_cli_cmd_reconnect,
2510 cli_cmd_flag_none,
2511 "= like reassociate, but only takes effect if already disconnected"
2512 },
2513 { "scan", wpa_cli_cmd_scan,
2514 cli_cmd_flag_none,
2515 "= request new BSS scan" },
2516 { "scan_results", wpa_cli_cmd_scan_results,
2517 cli_cmd_flag_none,
2518 "= get latest scan results" },
2519 { "bss", wpa_cli_cmd_bss,
2520 cli_cmd_flag_none,
2521 "<<idx> | <bssid>> = get detailed scan result info" },
2522 { "get_capability", wpa_cli_cmd_get_capability,
2523 cli_cmd_flag_none,
2524 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2525 { "reconfigure", wpa_cli_cmd_reconfigure,
2526 cli_cmd_flag_none,
2527 "= force wpa_supplicant to re-read its configuration file" },
2528 { "terminate", wpa_cli_cmd_terminate,
2529 cli_cmd_flag_none,
2530 "= terminate wpa_supplicant" },
2531 { "interface_add", wpa_cli_cmd_interface_add,
2532 cli_cmd_flag_none,
2533 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2534 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2535 " are optional" },
2536 { "interface_remove", wpa_cli_cmd_interface_remove,
2537 cli_cmd_flag_none,
2538 "<ifname> = removes the interface" },
2539 { "interface_list", wpa_cli_cmd_interface_list,
2540 cli_cmd_flag_none,
2541 "= list available interfaces" },
2542 { "ap_scan", wpa_cli_cmd_ap_scan,
2543 cli_cmd_flag_none,
2544 "<value> = set ap_scan parameter" },
2545 { "scan_interval", wpa_cli_cmd_scan_interval,
2546 cli_cmd_flag_none,
2547 "<value> = set scan_interval parameter (in seconds)" },
2548 { "bss_expire_age", wpa_cli_cmd_bss_expire_age,
2549 cli_cmd_flag_none,
2550 "<value> = set BSS expiration age parameter" },
2551 { "bss_expire_count", wpa_cli_cmd_bss_expire_count,
2552 cli_cmd_flag_none,
2553 "<value> = set BSS expiration scan count parameter" },
2554 { "stkstart", wpa_cli_cmd_stkstart,
2555 cli_cmd_flag_none,
2556 "<addr> = request STK negotiation with <addr>" },
2557 { "ft_ds", wpa_cli_cmd_ft_ds,
2558 cli_cmd_flag_none,
2559 "<addr> = request over-the-DS FT with <addr>" },
2560 { "wps_pbc", wpa_cli_cmd_wps_pbc,
2561 cli_cmd_flag_none,
2562 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2563 { "wps_pin", wpa_cli_cmd_wps_pin,
2564 cli_cmd_flag_sensitive,
2565 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2566 "hardcoded)" },
2567 { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
2568 cli_cmd_flag_sensitive,
2569 "<PIN> = verify PIN checksum" },
2570 { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2571 "Cancels the pending WPS operation" },
2572#ifdef CONFIG_WPS_OOB
2573 { "wps_oob", wpa_cli_cmd_wps_oob,
2574 cli_cmd_flag_sensitive,
2575 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2576#endif /* CONFIG_WPS_OOB */
2577 { "wps_reg", wpa_cli_cmd_wps_reg,
2578 cli_cmd_flag_sensitive,
2579 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2580 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
2581 cli_cmd_flag_sensitive,
2582 "[params..] = enable/disable AP PIN" },
2583 { "wps_er_start", wpa_cli_cmd_wps_er_start,
2584 cli_cmd_flag_none,
2585 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2586 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2587 cli_cmd_flag_none,
2588 "= stop Wi-Fi Protected Setup External Registrar" },
2589 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2590 cli_cmd_flag_sensitive,
2591 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2592 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2593 cli_cmd_flag_none,
2594 "<UUID> = accept an Enrollee PBC using External Registrar" },
2595 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2596 cli_cmd_flag_sensitive,
2597 "<UUID> <PIN> = learn AP configuration" },
2598 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
2599 cli_cmd_flag_none,
2600 "<UUID> <network id> = set AP configuration for enrolling" },
2601 { "wps_er_config", wpa_cli_cmd_wps_er_config,
2602 cli_cmd_flag_sensitive,
2603 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2604 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2605 cli_cmd_flag_none,
2606 "<addr> = request RSN authentication with <addr> in IBSS" },
2607#ifdef CONFIG_AP
2608 { "sta", wpa_cli_cmd_sta,
2609 cli_cmd_flag_none,
2610 "<addr> = get information about an associated station (AP)" },
2611 { "all_sta", wpa_cli_cmd_all_sta,
2612 cli_cmd_flag_none,
2613 "= get information about all associated stations (AP)" },
2614#endif /* CONFIG_AP */
2615 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2616 "= notification of suspend/hibernate" },
2617 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2618 "= notification of resume/thaw" },
2619 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2620 "= drop SA without deauth/disassoc (test command)" },
2621 { "roam", wpa_cli_cmd_roam,
2622 cli_cmd_flag_none,
2623 "<addr> = roam to the specified BSS" },
2624#ifdef CONFIG_P2P
2625 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2626 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2627 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2628 "= stop P2P Devices search" },
2629 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2630 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2631 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2632 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2633 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2634 "<ifname> = remove P2P group interface (terminate group if GO)" },
2635 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2636 "= add a new P2P group (local end as GO)" },
2637 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2638 "<addr> <method> = request provisioning discovery" },
2639 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2640 cli_cmd_flag_none,
2641 "= get the passphrase for a group (GO only)" },
2642 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2643 cli_cmd_flag_none,
2644 "<addr> <TLVs> = schedule service discovery request" },
2645 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2646 cli_cmd_flag_none,
2647 "<id> = cancel pending service discovery request" },
2648 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2649 cli_cmd_flag_none,
2650 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2651 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2652 cli_cmd_flag_none,
2653 "= indicate change in local services" },
2654 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2655 cli_cmd_flag_none,
2656 "<external> = set external processing of service discovery" },
2657 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2658 cli_cmd_flag_none,
2659 "= remove all stored service entries" },
2660 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2661 cli_cmd_flag_none,
2662 "<bonjour|upnp> <query|version> <response|service> = add a local "
2663 "service" },
2664 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2665 cli_cmd_flag_none,
2666 "<bonjour|upnp> <query|version> [|service] = remove a local "
2667 "service" },
2668 { "p2p_reject", wpa_cli_cmd_p2p_reject,
2669 cli_cmd_flag_none,
2670 "<addr> = reject connection attempts from a specific peer" },
2671 { "p2p_invite", wpa_cli_cmd_p2p_invite,
2672 cli_cmd_flag_none,
2673 "<cmd> [peer=addr] = invite peer" },
2674 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2675 "[discovered] = list known (optionally, only fully discovered) P2P "
2676 "peers" },
2677 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2678 "<address> = show information about known P2P peer" },
2679 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2680 "<field> <value> = set a P2P parameter" },
2681 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2682 "= flush P2P state" },
2683 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
2684 "= cancel P2P group formation" },
2685 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none,
2686 "<address> = unauthorize a peer" },
2687 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2688 "[<duration> <interval>] [<duration> <interval>] = request GO "
2689 "presence" },
2690 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2691 "[<period> <interval>] = set extended listen timing" },
2692#endif /* CONFIG_P2P */
2693 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
2694 "<0/1> = disable/enable automatic reconnection" },
2695 { "tdls_discover", wpa_cli_cmd_tdls_discover,
2696 cli_cmd_flag_none,
2697 "<addr> = request TDLS discovery with <addr>" },
2698 { "tdls_setup", wpa_cli_cmd_tdls_setup,
2699 cli_cmd_flag_none,
2700 "<addr> = request TDLS setup with <addr>" },
2701 { "tdls_teardown", wpa_cli_cmd_tdls_teardown,
2702 cli_cmd_flag_none,
2703 "<addr> = tear down TDLS with <addr>" },
2704 { "signal_poll", wpa_cli_cmd_signal_poll,
2705 cli_cmd_flag_none,
2706 "= get signal parameters" },
Dmitry Shmidt0716c122011-04-08 15:03:17 -07002707 { "driver", wpa_cli_cmd_driver,
2708 cli_cmd_flag_none,
2709 "<command> = driver private commands" },
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002710 { NULL, NULL, cli_cmd_flag_none, NULL }
2711};
2712
2713
2714/*
2715 * Prints command usage, lines are padded with the specified string.
2716 */
2717static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2718{
2719 char c;
2720 size_t n;
2721
2722 printf("%s%s ", pad, cmd->cmd);
2723 for (n = 0; (c = cmd->usage[n]); n++) {
2724 printf("%c", c);
2725 if (c == '\n')
2726 printf("%s", pad);
2727 }
2728 printf("\n");
2729}
2730
2731
2732static void print_help(void)
2733{
2734 int n;
2735 printf("commands:\n");
2736 for (n = 0; wpa_cli_commands[n].cmd; n++)
2737 print_cmd_help(&wpa_cli_commands[n], " ");
2738}
2739
2740
2741static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
2742{
2743 const char *c, *delim;
2744 int n;
2745 size_t len;
2746
2747 delim = os_strchr(cmd, ' ');
2748 if (delim)
2749 len = delim - cmd;
2750 else
2751 len = os_strlen(cmd);
2752
2753 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2754 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2755 return (wpa_cli_commands[n].flags &
2756 cli_cmd_flag_sensitive);
2757 }
2758 return 0;
2759}
2760
2761
2762static char ** wpa_list_cmd_list(void)
2763{
2764 char **res;
2765 int i, count;
2766
2767 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
2768 res = os_zalloc(count * sizeof(char *));
2769 if (res == NULL)
2770 return NULL;
2771
2772 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2773 res[i] = os_strdup(wpa_cli_commands[i].cmd);
2774 if (res[i] == NULL)
2775 break;
2776 }
2777
2778 return res;
2779}
2780
2781
2782static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
2783 int pos)
2784{
2785 int i;
2786
2787 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2788 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
2789 edit_clear_line();
2790 printf("\r%s\n", wpa_cli_commands[i].usage);
2791 edit_redraw();
2792 break;
2793 }
2794 }
2795
2796 return NULL;
2797}
2798
2799
2800static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
2801{
2802 char **res;
2803 const char *end;
2804 char *cmd;
2805
2806 end = os_strchr(str, ' ');
2807 if (end == NULL || str + pos < end)
2808 return wpa_list_cmd_list();
2809
2810 cmd = os_malloc(pos + 1);
2811 if (cmd == NULL)
2812 return NULL;
2813 os_memcpy(cmd, str, pos);
2814 cmd[end - str] = '\0';
2815 res = wpa_cli_cmd_completion(cmd, str, pos);
2816 os_free(cmd);
2817 return res;
2818}
2819
2820
2821static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
2822{
2823 struct wpa_cli_cmd *cmd, *match = NULL;
2824 int count;
2825 int ret = 0;
2826
2827 count = 0;
2828 cmd = wpa_cli_commands;
2829 while (cmd->cmd) {
2830 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
2831 {
2832 match = cmd;
2833 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
2834 /* we have an exact match */
2835 count = 1;
2836 break;
2837 }
2838 count++;
2839 }
2840 cmd++;
2841 }
2842
2843 if (count > 1) {
2844 printf("Ambiguous command '%s'; possible commands:", argv[0]);
2845 cmd = wpa_cli_commands;
2846 while (cmd->cmd) {
2847 if (os_strncasecmp(cmd->cmd, argv[0],
2848 os_strlen(argv[0])) == 0) {
2849 printf(" %s", cmd->cmd);
2850 }
2851 cmd++;
2852 }
2853 printf("\n");
2854 ret = 1;
2855 } else if (count == 0) {
2856 printf("Unknown command '%s'\n", argv[0]);
2857 ret = 1;
2858 } else {
2859 ret = match->handler(ctrl, argc - 1, &argv[1]);
2860 }
2861
2862 return ret;
2863}
2864
2865
2866static int str_match(const char *a, const char *b)
2867{
2868 return os_strncmp(a, b, os_strlen(b)) == 0;
2869}
2870
2871
2872static int wpa_cli_exec(const char *program, const char *arg1,
2873 const char *arg2)
2874{
2875 char *cmd;
2876 size_t len;
2877 int res;
2878 int ret = 0;
2879
2880 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
2881 cmd = os_malloc(len);
2882 if (cmd == NULL)
2883 return -1;
2884 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
2885 if (res < 0 || (size_t) res >= len) {
2886 os_free(cmd);
2887 return -1;
2888 }
2889 cmd[len - 1] = '\0';
2890#ifndef _WIN32_WCE
2891 if (system(cmd) < 0)
2892 ret = -1;
2893#endif /* _WIN32_WCE */
2894 os_free(cmd);
2895
2896 return ret;
2897}
2898
2899
2900static void wpa_cli_action_process(const char *msg)
2901{
2902 const char *pos;
2903 char *copy = NULL, *id, *pos2;
2904
2905 pos = msg;
2906 if (*pos == '<') {
2907 /* skip priority */
2908 pos = os_strchr(pos, '>');
2909 if (pos)
2910 pos++;
2911 else
2912 pos = msg;
2913 }
2914
2915 if (str_match(pos, WPA_EVENT_CONNECTED)) {
2916 int new_id = -1;
2917 os_unsetenv("WPA_ID");
2918 os_unsetenv("WPA_ID_STR");
2919 os_unsetenv("WPA_CTRL_DIR");
2920
2921 pos = os_strstr(pos, "[id=");
2922 if (pos)
2923 copy = os_strdup(pos + 4);
2924
2925 if (copy) {
2926 pos2 = id = copy;
2927 while (*pos2 && *pos2 != ' ')
2928 pos2++;
2929 *pos2++ = '\0';
2930 new_id = atoi(id);
2931 os_setenv("WPA_ID", id, 1);
2932 while (*pos2 && *pos2 != '=')
2933 pos2++;
2934 if (*pos2 == '=')
2935 pos2++;
2936 id = pos2;
2937 while (*pos2 && *pos2 != ']')
2938 pos2++;
2939 *pos2 = '\0';
2940 os_setenv("WPA_ID_STR", id, 1);
2941 os_free(copy);
2942 }
2943
2944 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
2945
2946 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
2947 wpa_cli_connected = 1;
2948 wpa_cli_last_id = new_id;
2949 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
2950 }
2951 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
2952 if (wpa_cli_connected) {
2953 wpa_cli_connected = 0;
2954 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
2955 }
2956 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
2957 wpa_cli_exec(action_file, ctrl_ifname, pos);
2958 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
2959 wpa_cli_exec(action_file, ctrl_ifname, pos);
2960 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
2961 wpa_cli_exec(action_file, ctrl_ifname, pos);
2962 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
2963 wpa_cli_exec(action_file, ctrl_ifname, pos);
2964 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
2965 wpa_cli_exec(action_file, ctrl_ifname, pos);
2966 } else if (str_match(pos, WPS_EVENT_FAIL)) {
2967 wpa_cli_exec(action_file, ctrl_ifname, pos);
2968 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
2969 printf("wpa_supplicant is terminating - stop monitoring\n");
2970 wpa_cli_quit = 1;
2971 }
Dmitry Shmidt44da0252011-08-23 12:30:30 -07002972#ifdef ANDROID_BRCM_P2P_PATCH
2973 else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
2974 wpa_cli_exec(action_file, ctrl_ifname, pos);
2975 }
2976#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002977}
2978
2979
2980#ifndef CONFIG_ANSI_C_EXTRA
2981static void wpa_cli_action_cb(char *msg, size_t len)
2982{
2983 wpa_cli_action_process(msg);
2984}
2985#endif /* CONFIG_ANSI_C_EXTRA */
2986
2987
2988static void wpa_cli_reconnect(void)
2989{
2990 wpa_cli_close_connection();
2991 wpa_cli_open_connection(ctrl_ifname, 1);
2992}
2993
2994
2995static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
2996{
2997 if (ctrl_conn == NULL) {
2998 wpa_cli_reconnect();
2999 return;
3000 }
3001 while (wpa_ctrl_pending(ctrl) > 0) {
3002 char buf[256];
3003 size_t len = sizeof(buf) - 1;
3004 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3005 buf[len] = '\0';
3006 if (action_monitor)
3007 wpa_cli_action_process(buf);
3008 else {
3009 if (wpa_cli_show_event(buf)) {
3010 edit_clear_line();
3011 printf("\r%s\n", buf);
3012 edit_redraw();
3013 }
3014 }
3015 } else {
3016 printf("Could not read pending message.\n");
3017 break;
3018 }
3019 }
3020
3021 if (wpa_ctrl_pending(ctrl) < 0) {
3022 printf("Connection to wpa_supplicant lost - trying to "
3023 "reconnect\n");
3024 wpa_cli_reconnect();
3025 }
3026}
3027
3028#define max_args 10
3029
3030static int tokenize_cmd(char *cmd, char *argv[])
3031{
3032 char *pos;
3033 int argc = 0;
3034
3035 pos = cmd;
3036 for (;;) {
3037 while (*pos == ' ')
3038 pos++;
3039 if (*pos == '\0')
3040 break;
3041 argv[argc] = pos;
3042 argc++;
3043 if (argc == max_args)
3044 break;
3045 if (*pos == '"') {
3046 char *pos2 = os_strrchr(pos, '"');
3047 if (pos2)
3048 pos = pos2 + 1;
3049 }
3050 while (*pos != '\0' && *pos != ' ')
3051 pos++;
3052 if (*pos == ' ')
3053 *pos++ = '\0';
3054 }
3055
3056 return argc;
3057}
3058
3059
3060static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3061{
3062 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3063 printf("Connection to wpa_supplicant lost - trying to "
3064 "reconnect\n");
3065 wpa_cli_close_connection();
3066 }
3067 if (!ctrl_conn)
3068 wpa_cli_reconnect();
3069 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3070}
3071
3072
3073static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
3074{
3075 eloop_terminate();
3076}
3077
3078
3079static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3080{
3081 wpa_cli_recv_pending(mon_conn, 0);
3082}
3083
3084
3085static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3086{
3087 char *argv[max_args];
3088 int argc;
3089 argc = tokenize_cmd(cmd, argv);
3090 if (argc)
3091 wpa_request(ctrl_conn, argc, argv);
3092}
3093
3094
3095static void wpa_cli_edit_eof_cb(void *ctx)
3096{
3097 eloop_terminate();
3098}
3099
3100
3101static void wpa_cli_interactive(void)
3102{
3103 char *home, *hfile = NULL;
3104
3105 printf("\nInteractive mode\n\n");
3106
3107 home = getenv("HOME");
3108 if (home) {
3109 const char *fname = ".wpa_cli_history";
3110 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3111 hfile = os_malloc(hfile_len);
3112 if (hfile)
3113 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3114 }
3115
3116 eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
3117 edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3118 wpa_cli_edit_completion_cb, NULL, hfile);
3119 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3120
3121 eloop_run();
3122
3123 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3124 os_free(hfile);
3125 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3126 wpa_cli_close_connection();
3127}
3128
3129
3130static void wpa_cli_action(struct wpa_ctrl *ctrl)
3131{
3132#ifdef CONFIG_ANSI_C_EXTRA
3133 /* TODO: ANSI C version(?) */
3134 printf("Action processing not supported in ANSI C build.\n");
3135#else /* CONFIG_ANSI_C_EXTRA */
3136 fd_set rfds;
3137 int fd, res;
3138 struct timeval tv;
3139 char buf[256]; /* note: large enough to fit in unsolicited messages */
3140 size_t len;
3141
3142 fd = wpa_ctrl_get_fd(ctrl);
3143
3144 while (!wpa_cli_quit) {
3145 FD_ZERO(&rfds);
3146 FD_SET(fd, &rfds);
3147 tv.tv_sec = ping_interval;
3148 tv.tv_usec = 0;
3149 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3150 if (res < 0 && errno != EINTR) {
3151 perror("select");
3152 break;
3153 }
3154
3155 if (FD_ISSET(fd, &rfds))
3156 wpa_cli_recv_pending(ctrl, 1);
3157 else {
3158 /* verify that connection is still working */
3159 len = sizeof(buf) - 1;
3160 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3161 wpa_cli_action_cb) < 0 ||
3162 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3163 printf("wpa_supplicant did not reply to PING "
3164 "command - exiting\n");
3165 break;
3166 }
3167 }
3168 }
3169#endif /* CONFIG_ANSI_C_EXTRA */
3170}
3171
3172
3173static void wpa_cli_cleanup(void)
3174{
3175 wpa_cli_close_connection();
3176 if (pid_file)
3177 os_daemonize_terminate(pid_file);
3178
3179 os_program_deinit();
3180}
3181
3182static void wpa_cli_terminate(int sig)
3183{
3184 wpa_cli_cleanup();
3185 exit(0);
3186}
3187
3188
3189static char * wpa_cli_get_default_ifname(void)
3190{
3191 char *ifname = NULL;
3192
3193#ifdef CONFIG_CTRL_IFACE_UNIX
3194 struct dirent *dent;
3195 DIR *dir = opendir(ctrl_iface_dir);
3196 if (!dir) {
3197#ifdef ANDROID
3198 char ifprop[PROPERTY_VALUE_MAX];
3199 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3200 ifname = os_strdup(ifprop);
3201 printf("Using interface '%s'\n", ifname);
3202 return ifname;
3203 }
3204#endif /* ANDROID */
3205 return NULL;
3206 }
3207 while ((dent = readdir(dir))) {
3208#ifdef _DIRENT_HAVE_D_TYPE
3209 /*
3210 * Skip the file if it is not a socket. Also accept
3211 * DT_UNKNOWN (0) in case the C library or underlying
3212 * file system does not support d_type.
3213 */
3214 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3215 continue;
3216#endif /* _DIRENT_HAVE_D_TYPE */
3217 if (os_strcmp(dent->d_name, ".") == 0 ||
3218 os_strcmp(dent->d_name, "..") == 0)
3219 continue;
3220 printf("Selected interface '%s'\n", dent->d_name);
3221 ifname = os_strdup(dent->d_name);
3222 break;
3223 }
3224 closedir(dir);
3225#endif /* CONFIG_CTRL_IFACE_UNIX */
3226
3227#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
Dmitry Shmidtc97d8bf2011-08-30 11:10:13 -07003228 char buf[4096], *pos;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003229 size_t len;
3230 struct wpa_ctrl *ctrl;
3231 int ret;
3232
3233 ctrl = wpa_ctrl_open(NULL);
3234 if (ctrl == NULL)
3235 return NULL;
3236
3237 len = sizeof(buf) - 1;
3238 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3239 if (ret >= 0) {
3240 buf[len] = '\0';
3241 pos = os_strchr(buf, '\n');
3242 if (pos)
3243 *pos = '\0';
3244 ifname = os_strdup(buf);
3245 }
3246 wpa_ctrl_close(ctrl);
3247#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3248
3249 return ifname;
3250}
3251
3252
3253int main(int argc, char *argv[])
3254{
3255 int warning_displayed = 0;
3256 int c;
3257 int daemonize = 0;
3258 int ret = 0;
3259 const char *global = NULL;
3260
3261 if (os_program_init())
3262 return -1;
3263
3264 for (;;) {
3265 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3266 if (c < 0)
3267 break;
3268 switch (c) {
3269 case 'a':
3270 action_file = optarg;
3271 break;
3272 case 'B':
3273 daemonize = 1;
3274 break;
3275 case 'g':
3276 global = optarg;
3277 break;
3278 case 'G':
3279 ping_interval = atoi(optarg);
3280 break;
3281 case 'h':
3282 usage();
3283 return 0;
3284 case 'v':
3285 printf("%s\n", wpa_cli_version);
3286 return 0;
3287 case 'i':
3288 os_free(ctrl_ifname);
3289 ctrl_ifname = os_strdup(optarg);
3290 break;
3291 case 'p':
3292 ctrl_iface_dir = optarg;
3293 break;
3294 case 'P':
3295 pid_file = optarg;
3296 break;
3297 default:
3298 usage();
3299 return -1;
3300 }
3301 }
3302
3303 interactive = (argc == optind) && (action_file == NULL);
3304
3305 if (interactive)
3306 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3307
3308 if (eloop_init())
3309 return -1;
3310
3311 if (global) {
3312#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3313 ctrl_conn = wpa_ctrl_open(NULL);
3314#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3315 ctrl_conn = wpa_ctrl_open(global);
3316#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3317 if (ctrl_conn == NULL) {
3318 perror("Failed to connect to wpa_supplicant - "
3319 "wpa_ctrl_open");
3320 return -1;
3321 }
3322 }
3323
3324#ifndef _WIN32_WCE
3325 signal(SIGINT, wpa_cli_terminate);
3326 signal(SIGTERM, wpa_cli_terminate);
3327#endif /* _WIN32_WCE */
3328
3329 if (ctrl_ifname == NULL)
3330 ctrl_ifname = wpa_cli_get_default_ifname();
3331
3332 if (interactive) {
3333 for (; !global;) {
3334 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3335 if (warning_displayed)
3336 printf("Connection established.\n");
3337 break;
3338 }
3339
3340 if (!warning_displayed) {
3341 printf("Could not connect to wpa_supplicant - "
3342 "re-trying\n");
3343 warning_displayed = 1;
3344 }
3345 os_sleep(1, 0);
3346 continue;
3347 }
3348 } else {
3349 if (!global &&
3350 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3351 perror("Failed to connect to wpa_supplicant - "
3352 "wpa_ctrl_open");
3353 return -1;
3354 }
3355
3356 if (action_file) {
3357 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3358 wpa_cli_attached = 1;
3359 } else {
3360 printf("Warning: Failed to attach to "
3361 "wpa_supplicant.\n");
3362 return -1;
3363 }
3364 }
3365 }
3366
3367 if (daemonize && os_daemonize(pid_file))
3368 return -1;
3369
3370 if (interactive)
3371 wpa_cli_interactive();
3372 else if (action_file)
3373 wpa_cli_action(ctrl_conn);
3374 else
3375 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3376
3377 os_free(ctrl_ifname);
3378 eloop_destroy();
3379 wpa_cli_cleanup();
3380
3381 return ret;
3382}
3383
3384#else /* CONFIG_CTRL_IFACE */
3385int main(int argc, char *argv[])
3386{
3387 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3388 return -1;
3389}
3390#endif /* CONFIG_CTRL_IFACE */