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