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