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