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