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