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