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