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