]> git.ipfire.org Git - thirdparty/hostap.git/blame - wpa_supplicant/wpa_cli.c
Fix MCS set field to be based on driver info
[thirdparty/hostap.git] / wpa_supplicant / wpa_cli.c
CommitLineData
6fc6879b
JM
1/*
2 * WPA Supplicant - command line interface for wpa_supplicant daemon
6f78f2fb 3 * Copyright (c) 2004-2009, 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 */
22#ifdef CONFIG_READLINE
23#include <readline/readline.h>
24#include <readline/history.h>
25#endif /* CONFIG_READLINE */
26
27#include "wpa_ctrl.h"
28#include "common.h"
29#include "version.h"
30
31
32static const char *wpa_cli_version =
33"wpa_cli v" VERSION_STR "\n"
6f78f2fb 34"Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> and contributors";
6fc6879b
JM
35
36
37static const char *wpa_cli_license =
38"This program is free software. You can distribute it and/or modify it\n"
39"under the terms of the GNU General Public License version 2.\n"
40"\n"
41"Alternatively, this software may be distributed under the terms of the\n"
42"BSD license. See README and COPYING for more details.\n";
43
44static const char *wpa_cli_full_license =
45"This program is free software; you can redistribute it and/or modify\n"
46"it under the terms of the GNU General Public License version 2 as\n"
47"published by the Free Software Foundation.\n"
48"\n"
49"This program is distributed in the hope that it will be useful,\n"
50"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
51"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
52"GNU General Public License for more details.\n"
53"\n"
54"You should have received a copy of the GNU General Public License\n"
55"along with this program; if not, write to the Free Software\n"
56"Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
57"\n"
58"Alternatively, this software may be distributed under the terms of the\n"
59"BSD license.\n"
60"\n"
61"Redistribution and use in source and binary forms, with or without\n"
62"modification, are permitted provided that the following conditions are\n"
63"met:\n"
64"\n"
65"1. Redistributions of source code must retain the above copyright\n"
66" notice, this list of conditions and the following disclaimer.\n"
67"\n"
68"2. Redistributions in binary form must reproduce the above copyright\n"
69" notice, this list of conditions and the following disclaimer in the\n"
70" documentation and/or other materials provided with the distribution.\n"
71"\n"
72"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
73" names of its contributors may be used to endorse or promote products\n"
74" derived from this software without specific prior written permission.\n"
75"\n"
76"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
77"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
78"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
79"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
80"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
81"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
82"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
83"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
84"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
85"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
86"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
87"\n";
88
6fc6879b
JM
89static struct wpa_ctrl *ctrl_conn;
90static int wpa_cli_quit = 0;
91static int wpa_cli_attached = 0;
92static int wpa_cli_connected = 0;
93static int wpa_cli_last_id = 0;
94static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
95static char *ctrl_ifname = NULL;
96static const char *pid_file = NULL;
97static const char *action_file = NULL;
1cc84c1c 98static int ping_interval = 5;
6fc6879b
JM
99
100
dfa141b1
ER
101static void print_help();
102
103
6fc6879b
JM
104static void usage(void)
105{
106 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
107 "[-a<action file>] \\\n"
1cc84c1c
JM
108 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
109 "[command..]\n"
6fc6879b
JM
110 " -h = help (show this usage text)\n"
111 " -v = shown version information\n"
112 " -a = run in daemon mode executing the action file based on "
113 "events from\n"
114 " wpa_supplicant\n"
115 " -B = run a daemon in the background\n"
116 " default path: /var/run/wpa_supplicant\n"
dfa141b1
ER
117 " default interface: first interface found in socket path\n");
118 print_help();
6fc6879b
JM
119}
120
121
122static struct wpa_ctrl * wpa_cli_open_connection(const char *ifname)
123{
124#if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
125 ctrl_conn = wpa_ctrl_open(ifname);
126 return ctrl_conn;
127#else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
128 char *cfile;
129 int flen, res;
130
131 if (ifname == NULL)
132 return NULL;
133
134 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
135 cfile = os_malloc(flen);
136 if (cfile == NULL)
137 return NULL;
138 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
139 if (res < 0 || res >= flen) {
140 os_free(cfile);
141 return NULL;
142 }
143
144 ctrl_conn = wpa_ctrl_open(cfile);
145 os_free(cfile);
146 return ctrl_conn;
147#endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
148}
149
150
151static void wpa_cli_close_connection(void)
152{
153 if (ctrl_conn == NULL)
154 return;
155
156 if (wpa_cli_attached) {
157 wpa_ctrl_detach(ctrl_conn);
158 wpa_cli_attached = 0;
159 }
160 wpa_ctrl_close(ctrl_conn);
161 ctrl_conn = NULL;
162}
163
164
165static void wpa_cli_msg_cb(char *msg, size_t len)
166{
167 printf("%s\n", msg);
168}
169
170
171static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
172{
173 char buf[2048];
174 size_t len;
175 int ret;
176
177 if (ctrl_conn == NULL) {
178 printf("Not connected to wpa_supplicant - command dropped.\n");
179 return -1;
180 }
181 len = sizeof(buf) - 1;
182 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
183 wpa_cli_msg_cb);
184 if (ret == -2) {
185 printf("'%s' command timed out.\n", cmd);
186 return -2;
187 } else if (ret < 0) {
188 printf("'%s' command failed.\n", cmd);
189 return -1;
190 }
191 if (print) {
192 buf[len] = '\0';
193 printf("%s", buf);
194 }
195 return 0;
196}
197
198
199static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
200{
201 return _wpa_ctrl_command(ctrl, cmd, 1);
202}
203
204
205static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
206{
207 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
208 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
209}
210
211
212static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
213{
214 return wpa_ctrl_command(ctrl, "PING");
215}
216
217
218static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
219{
220 return wpa_ctrl_command(ctrl, "MIB");
221}
222
223
224static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
225{
226 return wpa_ctrl_command(ctrl, "PMKSA");
227}
228
229
230static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
231{
dfa141b1 232 print_help();
6fc6879b
JM
233 return 0;
234}
235
236
237static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
238{
239 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
240 return 0;
241}
242
243
244static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
245{
246 wpa_cli_quit = 1;
247 return 0;
248}
249
250
251static void wpa_cli_show_variables(void)
252{
253 printf("set variables:\n"
254 " EAPOL::heldPeriod (EAPOL state machine held period, "
255 "in seconds)\n"
256 " EAPOL::authPeriod (EAPOL state machine authentication "
257 "period, in seconds)\n"
258 " EAPOL::startPeriod (EAPOL state machine start period, in "
259 "seconds)\n"
260 " EAPOL::maxStart (EAPOL state machine maximum start "
261 "attempts)\n");
262 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
263 "seconds)\n"
264 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
265 " threshold\n\tpercentage)\n"
266 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
267 "security\n\tassociation in seconds)\n");
268}
269
270
271static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
272{
273 char cmd[256];
274 int res;
275
276 if (argc == 0) {
277 wpa_cli_show_variables();
278 return 0;
279 }
280
281 if (argc != 2) {
282 printf("Invalid SET command: needs two arguments (variable "
283 "name and value)\n");
284 return -1;
285 }
286
287 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
288 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
289 printf("Too long SET command.\n");
290 return -1;
291 }
292 return wpa_ctrl_command(ctrl, cmd);
293}
294
295
296static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
297{
298 return wpa_ctrl_command(ctrl, "LOGOFF");
299}
300
301
302static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
303{
304 return wpa_ctrl_command(ctrl, "LOGON");
305}
306
307
308static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
309 char *argv[])
310{
311 return wpa_ctrl_command(ctrl, "REASSOCIATE");
312}
313
314
315static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
316 char *argv[])
317{
318 char cmd[256];
319 int res;
320
321 if (argc != 1) {
322 printf("Invalid PREAUTH command: needs one argument "
323 "(BSSID)\n");
324 return -1;
325 }
326
327 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
328 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
329 printf("Too long PREAUTH command.\n");
330 return -1;
331 }
332 return wpa_ctrl_command(ctrl, cmd);
333}
334
335
336static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
337{
338 char cmd[256];
339 int res;
340
341 if (argc != 1) {
342 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
343 "value)\n");
344 return -1;
345 }
346 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
347 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
348 printf("Too long AP_SCAN command.\n");
349 return -1;
350 }
351 return wpa_ctrl_command(ctrl, cmd);
352}
353
354
355static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
356 char *argv[])
357{
358 char cmd[256];
359 int res;
360
361 if (argc != 1) {
362 printf("Invalid STKSTART command: needs one argument "
363 "(Peer STA MAC address)\n");
364 return -1;
365 }
366
367 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
368 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
369 printf("Too long STKSTART command.\n");
370 return -1;
371 }
372 return wpa_ctrl_command(ctrl, cmd);
373}
374
375
376static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
377{
378 char cmd[256];
379 int res;
380
381 if (argc != 1) {
382 printf("Invalid FT_DS command: needs one argument "
383 "(Target AP MAC address)\n");
384 return -1;
385 }
386
387 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
388 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
389 printf("Too long FT_DS command.\n");
390 return -1;
391 }
392 return wpa_ctrl_command(ctrl, cmd);
393}
394
395
fcc60db4
JM
396static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
397{
398 char cmd[256];
399 int res;
400
401 if (argc == 0) {
402 /* Any BSSID */
403 return wpa_ctrl_command(ctrl, "WPS_PBC");
404 }
405
406 /* Specific BSSID */
407 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
408 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
409 printf("Too long WPS_PBC command.\n");
410 return -1;
411 }
412 return wpa_ctrl_command(ctrl, cmd);
413}
414
415
416static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
417{
418 char cmd[256];
419 int res;
420
421 if (argc == 0) {
422 printf("Invalid WPS_PIN command: need one or two arguments:\n"
423 "- BSSID: use 'any' to select any\n"
424 "- PIN: optional, used only with devices that have no "
425 "display\n");
426 return -1;
427 }
428
429 if (argc == 1) {
430 /* Use dynamically generated PIN (returned as reply) */
431 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
432 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
433 printf("Too long WPS_PIN command.\n");
434 return -1;
435 }
436 return wpa_ctrl_command(ctrl, cmd);
437 }
438
439 /* Use hardcoded PIN from a label */
440 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
441 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
442 printf("Too long WPS_PIN command.\n");
443 return -1;
444 }
445 return wpa_ctrl_command(ctrl, cmd);
446}
447
448
116f7bb0 449#ifdef CONFIG_WPS_OOB
46bdb83a
MH
450static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
451{
452 char cmd[256];
453 int res;
454
e1ee6b60
MH
455 if (argc != 3 && argc != 4) {
456 printf("Invalid WPS_OOB command: need three or four "
457 "arguments:\n"
458 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
459 "- PATH: path of OOB device like '/mnt'\n"
460 "- METHOD: OOB method 'pin-e' or 'pin-r', "
461 "'cred'\n"
462 "- DEV_NAME: (only for NFC) device name like "
463 "'pn531'\n");
46bdb83a
MH
464 return -1;
465 }
466
e1ee6b60
MH
467 if (argc == 3)
468 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
469 argv[0], argv[1], argv[2]);
470 else
471 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
472 argv[0], argv[1], argv[2], argv[3]);
46bdb83a
MH
473 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
474 printf("Too long WPS_OOB command.\n");
475 return -1;
476 }
477 return wpa_ctrl_command(ctrl, cmd);
478}
116f7bb0 479#endif /* CONFIG_WPS_OOB */
46bdb83a
MH
480
481
fcc60db4
JM
482static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
483{
484 char cmd[256];
485 int res;
486
52eb293d
JM
487 if (argc == 2)
488 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
489 argv[0], argv[1]);
490 else if (argc == 6) {
491 char ssid_hex[2 * 32 + 1];
492 char key_hex[2 * 64 + 1];
493 int i;
494
495 ssid_hex[0] = '\0';
496 for (i = 0; i < 32; i++) {
497 if (argv[2][i] == '\0')
498 break;
499 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
500 }
501
502 key_hex[0] = '\0';
503 for (i = 0; i < 64; i++) {
504 if (argv[5][i] == '\0')
505 break;
506 os_snprintf(&key_hex[i * 2], 3, "%02x", argv[5][i]);
507 }
508
509 res = os_snprintf(cmd, sizeof(cmd),
510 "WPS_REG %s %s %s %s %s %s",
511 argv[0], argv[1], ssid_hex, argv[3], argv[4],
512 key_hex);
513 } else {
fcc60db4
JM
514 printf("Invalid WPS_REG command: need two arguments:\n"
515 "- BSSID: use 'any' to select any\n"
516 "- AP PIN\n");
52eb293d
JM
517 printf("Alternatively, six arguments can be used to "
518 "reconfigure the AP:\n"
519 "- BSSID: use 'any' to select any\n"
520 "- AP PIN\n"
521 "- new SSID\n"
522 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
523 "- new encr (NONE, WEP, TKIP, CCMP)\n"
524 "- new key\n");
fcc60db4
JM
525 return -1;
526 }
527
fcc60db4
JM
528 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
529 printf("Too long WPS_REG command.\n");
530 return -1;
531 }
532 return wpa_ctrl_command(ctrl, cmd);
533}
534
535
11ef8d35
JM
536static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
537{
538 char cmd[256];
539 int res;
540
541 if (argc != 1) {
542 printf("Invalid IBSS_RSN command: needs one argument "
543 "(Peer STA MAC address)\n");
544 return -1;
545 }
546
547 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
548 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
549 printf("Too long IBSS_RSN command.\n");
550 return -1;
551 }
552 return wpa_ctrl_command(ctrl, cmd);
553}
554
555
6fc6879b
JM
556static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
557{
558 char cmd[256];
559 int res;
560
561 if (argc != 1) {
562 printf("Invalid LEVEL command: needs one argument (debug "
563 "level)\n");
564 return -1;
565 }
566 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
567 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
568 printf("Too long LEVEL command.\n");
569 return -1;
570 }
571 return wpa_ctrl_command(ctrl, cmd);
572}
573
574
575static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
576{
577 char cmd[256], *pos, *end;
578 int i, ret;
579
580 if (argc < 2) {
581 printf("Invalid IDENTITY command: needs two arguments "
582 "(network id and identity)\n");
583 return -1;
584 }
585
586 end = cmd + sizeof(cmd);
587 pos = cmd;
588 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
589 argv[0], argv[1]);
590 if (ret < 0 || ret >= end - pos) {
591 printf("Too long IDENTITY command.\n");
592 return -1;
593 }
594 pos += ret;
595 for (i = 2; i < argc; i++) {
596 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
597 if (ret < 0 || ret >= end - pos) {
598 printf("Too long IDENTITY command.\n");
599 return -1;
600 }
601 pos += ret;
602 }
603
604 return wpa_ctrl_command(ctrl, cmd);
605}
606
607
608static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
609{
610 char cmd[256], *pos, *end;
611 int i, ret;
612
613 if (argc < 2) {
614 printf("Invalid PASSWORD command: needs two arguments "
615 "(network id and password)\n");
616 return -1;
617 }
618
619 end = cmd + sizeof(cmd);
620 pos = cmd;
621 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
622 argv[0], argv[1]);
623 if (ret < 0 || ret >= end - pos) {
624 printf("Too long PASSWORD command.\n");
625 return -1;
626 }
627 pos += ret;
628 for (i = 2; i < argc; i++) {
629 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
630 if (ret < 0 || ret >= end - pos) {
631 printf("Too long PASSWORD command.\n");
632 return -1;
633 }
634 pos += ret;
635 }
636
637 return wpa_ctrl_command(ctrl, cmd);
638}
639
640
641static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
642 char *argv[])
643{
644 char cmd[256], *pos, *end;
645 int i, ret;
646
647 if (argc < 2) {
648 printf("Invalid NEW_PASSWORD command: needs two arguments "
649 "(network id and password)\n");
650 return -1;
651 }
652
653 end = cmd + sizeof(cmd);
654 pos = cmd;
655 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
656 argv[0], argv[1]);
657 if (ret < 0 || ret >= end - pos) {
658 printf("Too long NEW_PASSWORD command.\n");
659 return -1;
660 }
661 pos += ret;
662 for (i = 2; i < argc; i++) {
663 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
664 if (ret < 0 || ret >= end - pos) {
665 printf("Too long NEW_PASSWORD command.\n");
666 return -1;
667 }
668 pos += ret;
669 }
670
671 return wpa_ctrl_command(ctrl, cmd);
672}
673
674
675static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
676{
677 char cmd[256], *pos, *end;
678 int i, ret;
679
680 if (argc < 2) {
681 printf("Invalid PIN command: needs two arguments "
682 "(network id and pin)\n");
683 return -1;
684 }
685
686 end = cmd + sizeof(cmd);
687 pos = cmd;
688 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
689 argv[0], argv[1]);
690 if (ret < 0 || ret >= end - pos) {
691 printf("Too long PIN command.\n");
692 return -1;
693 }
694 pos += ret;
695 for (i = 2; i < argc; i++) {
696 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
697 if (ret < 0 || ret >= end - pos) {
698 printf("Too long PIN command.\n");
699 return -1;
700 }
701 pos += ret;
702 }
703 return wpa_ctrl_command(ctrl, cmd);
704}
705
706
707static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
708{
709 char cmd[256], *pos, *end;
710 int i, ret;
711
712 if (argc < 2) {
713 printf("Invalid OTP command: needs two arguments (network "
714 "id and password)\n");
715 return -1;
716 }
717
718 end = cmd + sizeof(cmd);
719 pos = cmd;
720 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
721 argv[0], argv[1]);
722 if (ret < 0 || ret >= end - pos) {
723 printf("Too long OTP command.\n");
724 return -1;
725 }
726 pos += ret;
727 for (i = 2; i < argc; i++) {
728 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
729 if (ret < 0 || ret >= end - pos) {
730 printf("Too long OTP command.\n");
731 return -1;
732 }
733 pos += ret;
734 }
735
736 return wpa_ctrl_command(ctrl, cmd);
737}
738
739
740static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
741 char *argv[])
742{
743 char cmd[256], *pos, *end;
744 int i, ret;
745
746 if (argc < 2) {
747 printf("Invalid PASSPHRASE command: needs two arguments "
748 "(network id and passphrase)\n");
749 return -1;
750 }
751
752 end = cmd + sizeof(cmd);
753 pos = cmd;
754 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
755 argv[0], argv[1]);
756 if (ret < 0 || ret >= end - pos) {
757 printf("Too long PASSPHRASE command.\n");
758 return -1;
759 }
760 pos += ret;
761 for (i = 2; i < argc; i++) {
762 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
763 if (ret < 0 || ret >= end - pos) {
764 printf("Too long PASSPHRASE command.\n");
765 return -1;
766 }
767 pos += ret;
768 }
769
770 return wpa_ctrl_command(ctrl, cmd);
771}
772
773
774static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
775{
776 char cmd[256], *pos, *end;
777 int i, ret;
778
779 if (argc < 2) {
780 printf("Invalid BSSID command: needs two arguments (network "
781 "id and BSSID)\n");
782 return -1;
783 }
784
785 end = cmd + sizeof(cmd);
786 pos = cmd;
787 ret = os_snprintf(pos, end - pos, "BSSID");
788 if (ret < 0 || ret >= end - pos) {
789 printf("Too long BSSID command.\n");
790 return -1;
791 }
792 pos += ret;
793 for (i = 0; i < argc; i++) {
794 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
795 if (ret < 0 || ret >= end - pos) {
796 printf("Too long BSSID command.\n");
797 return -1;
798 }
799 pos += ret;
800 }
801
802 return wpa_ctrl_command(ctrl, cmd);
803}
804
805
806static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
807 char *argv[])
808{
809 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
810}
811
812
813static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
814 char *argv[])
815{
816 char cmd[32];
817 int res;
818
819 if (argc < 1) {
820 printf("Invalid SELECT_NETWORK command: needs one argument "
821 "(network id)\n");
822 return -1;
823 }
824
825 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
826 if (res < 0 || (size_t) res >= sizeof(cmd))
827 return -1;
828 cmd[sizeof(cmd) - 1] = '\0';
829
830 return wpa_ctrl_command(ctrl, cmd);
831}
832
833
834static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
835 char *argv[])
836{
837 char cmd[32];
838 int res;
839
840 if (argc < 1) {
841 printf("Invalid ENABLE_NETWORK command: needs one argument "
842 "(network id)\n");
843 return -1;
844 }
845
846 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
847 if (res < 0 || (size_t) res >= sizeof(cmd))
848 return -1;
849 cmd[sizeof(cmd) - 1] = '\0';
850
851 return wpa_ctrl_command(ctrl, cmd);
852}
853
854
855static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
856 char *argv[])
857{
858 char cmd[32];
859 int res;
860
861 if (argc < 1) {
862 printf("Invalid DISABLE_NETWORK command: needs one argument "
863 "(network id)\n");
864 return -1;
865 }
866
867 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
868 if (res < 0 || (size_t) res >= sizeof(cmd))
869 return -1;
870 cmd[sizeof(cmd) - 1] = '\0';
871
872 return wpa_ctrl_command(ctrl, cmd);
873}
874
875
876static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
877 char *argv[])
878{
879 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
880}
881
882
883static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
884 char *argv[])
885{
886 char cmd[32];
887 int res;
888
889 if (argc < 1) {
890 printf("Invalid REMOVE_NETWORK command: needs one argument "
891 "(network id)\n");
892 return -1;
893 }
894
895 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
896 if (res < 0 || (size_t) res >= sizeof(cmd))
897 return -1;
898 cmd[sizeof(cmd) - 1] = '\0';
899
900 return wpa_ctrl_command(ctrl, cmd);
901}
902
903
904static void wpa_cli_show_network_variables(void)
905{
906 printf("set_network variables:\n"
907 " ssid (network name, SSID)\n"
908 " psk (WPA passphrase or pre-shared key)\n"
909 " key_mgmt (key management protocol)\n"
910 " identity (EAP identity)\n"
911 " password (EAP password)\n"
912 " ...\n"
913 "\n"
914 "Note: Values are entered in the same format as the "
915 "configuration file is using,\n"
916 "i.e., strings values need to be inside double quotation "
917 "marks.\n"
918 "For example: set_network 1 ssid \"network name\"\n"
919 "\n"
920 "Please see wpa_supplicant.conf documentation for full list "
921 "of\navailable variables.\n");
922}
923
924
925static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
926 char *argv[])
927{
928 char cmd[256];
929 int res;
930
931 if (argc == 0) {
932 wpa_cli_show_network_variables();
933 return 0;
934 }
935
936 if (argc != 3) {
937 printf("Invalid SET_NETWORK command: needs three arguments\n"
938 "(network id, variable name, and value)\n");
939 return -1;
940 }
941
942 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
943 argv[0], argv[1], argv[2]);
944 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
945 printf("Too long SET_NETWORK command.\n");
946 return -1;
947 }
948 return wpa_ctrl_command(ctrl, cmd);
949}
950
951
952static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
953 char *argv[])
954{
955 char cmd[256];
956 int res;
957
958 if (argc == 0) {
959 wpa_cli_show_network_variables();
960 return 0;
961 }
962
963 if (argc != 2) {
964 printf("Invalid GET_NETWORK command: needs two arguments\n"
965 "(network id and variable name)\n");
966 return -1;
967 }
968
969 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
970 argv[0], argv[1]);
971 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
972 printf("Too long GET_NETWORK command.\n");
973 return -1;
974 }
975 return wpa_ctrl_command(ctrl, cmd);
976}
977
978
979static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
980 char *argv[])
981{
982 return wpa_ctrl_command(ctrl, "DISCONNECT");
983}
984
985
986static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
987 char *argv[])
988{
989 return wpa_ctrl_command(ctrl, "RECONNECT");
990}
991
992
993static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
994 char *argv[])
995{
996 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
997}
998
999
1000static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1001{
1002 return wpa_ctrl_command(ctrl, "SCAN");
1003}
1004
1005
1006static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1007 char *argv[])
1008{
1009 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1010}
1011
1012
1013static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1014{
1015 char cmd[64];
1016 int res;
1017
1018 if (argc != 1) {
1019 printf("Invalid BSS command: need one argument (index or "
1020 "BSSID)\n");
1021 return -1;
1022 }
1023
1024 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1025 if (res < 0 || (size_t) res >= sizeof(cmd))
1026 return -1;
1027 cmd[sizeof(cmd) - 1] = '\0';
1028
1029 return wpa_ctrl_command(ctrl, cmd);
1030}
1031
1032
1033static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1034 char *argv[])
1035{
1036 char cmd[64];
1037 int res;
1038
1039 if (argc < 1 || argc > 2) {
1040 printf("Invalid GET_CAPABILITY command: need either one or "
1041 "two arguments\n");
1042 return -1;
1043 }
1044
1045 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1046 printf("Invalid GET_CAPABILITY command: second argument, "
1047 "if any, must be 'strict'\n");
1048 return -1;
1049 }
1050
1051 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1052 (argc == 2) ? " strict" : "");
1053 if (res < 0 || (size_t) res >= sizeof(cmd))
1054 return -1;
1055 cmd[sizeof(cmd) - 1] = '\0';
1056
1057 return wpa_ctrl_command(ctrl, cmd);
1058}
1059
1060
1061static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1062{
1063 printf("Available interfaces:\n");
1064 return wpa_ctrl_command(ctrl, "INTERFACES");
1065}
1066
1067
1068static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1069{
1070 if (argc < 1) {
1071 wpa_cli_list_interfaces(ctrl);
1072 return 0;
1073 }
1074
1075 wpa_cli_close_connection();
1076 os_free(ctrl_ifname);
1077 ctrl_ifname = os_strdup(argv[0]);
1078
1079 if (wpa_cli_open_connection(ctrl_ifname)) {
1080 printf("Connected to interface '%s.\n", ctrl_ifname);
1081 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1082 wpa_cli_attached = 1;
1083 } else {
1084 printf("Warning: Failed to attach to "
1085 "wpa_supplicant.\n");
1086 }
1087 } else {
1088 printf("Could not connect to interface '%s' - re-trying\n",
1089 ctrl_ifname);
1090 }
1091 return 0;
1092}
1093
1094
1095static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1096 char *argv[])
1097{
1098 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1099}
1100
1101
1102static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1103 char *argv[])
1104{
1105 return wpa_ctrl_command(ctrl, "TERMINATE");
1106}
1107
1108
1109static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1110 char *argv[])
1111{
1112 char cmd[256];
1113 int res;
1114
1115 if (argc < 1) {
1116 printf("Invalid INTERFACE_ADD command: needs at least one "
1117 "argument (interface name)\n"
1118 "All arguments: ifname confname driver ctrl_interface "
1119 "driver_param bridge_name\n");
1120 return -1;
1121 }
1122
1123 /*
1124 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1125 * <driver_param>TAB<bridge_name>
1126 */
1127 res = os_snprintf(cmd, sizeof(cmd),
1128 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1129 argv[0],
1130 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1131 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1132 argc > 5 ? argv[5] : "");
1133 if (res < 0 || (size_t) res >= sizeof(cmd))
1134 return -1;
1135 cmd[sizeof(cmd) - 1] = '\0';
1136 return wpa_ctrl_command(ctrl, cmd);
1137}
1138
1139
1140static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1141 char *argv[])
1142{
1143 char cmd[128];
1144 int res;
1145
1146 if (argc != 1) {
1147 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1148 "(interface name)\n");
1149 return -1;
1150 }
1151
1152 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1153 if (res < 0 || (size_t) res >= sizeof(cmd))
1154 return -1;
1155 cmd[sizeof(cmd) - 1] = '\0';
1156 return wpa_ctrl_command(ctrl, cmd);
1157}
1158
1159
4b4a8ae5
JM
1160static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1161 char *argv[])
1162{
1163 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1164}
1165
1166
e653b622
JM
1167#ifdef CONFIG_AP
1168static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1169{
1170 char buf[64];
1171 if (argc != 1) {
1172 printf("Invalid 'sta' command - exactly one argument, STA "
1173 "address, is required.\n");
1174 return -1;
1175 }
1176 snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1177 return wpa_ctrl_command(ctrl, buf);
1178}
1179
1180
1181static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1182 char *addr, size_t addr_len)
1183{
1184 char buf[4096], *pos;
1185 size_t len;
1186 int ret;
1187
1188 if (ctrl_conn == NULL) {
1189 printf("Not connected to hostapd - command dropped.\n");
1190 return -1;
1191 }
1192 len = sizeof(buf) - 1;
1193 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1194 wpa_cli_msg_cb);
1195 if (ret == -2) {
1196 printf("'%s' command timed out.\n", cmd);
1197 return -2;
1198 } else if (ret < 0) {
1199 printf("'%s' command failed.\n", cmd);
1200 return -1;
1201 }
1202
1203 buf[len] = '\0';
1204 if (memcmp(buf, "FAIL", 4) == 0)
1205 return -1;
1206 printf("%s", buf);
1207
1208 pos = buf;
1209 while (*pos != '\0' && *pos != '\n')
1210 pos++;
1211 *pos = '\0';
1212 os_strlcpy(addr, buf, addr_len);
1213 return 0;
1214}
1215
1216
1217static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1218{
1219 char addr[32], cmd[64];
1220
1221 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1222 return 0;
1223 do {
1224 snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1225 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1226
1227 return -1;
1228}
1229#endif /* CONFIG_AP */
1230
1231
40fd868c
ER
1232enum wpa_cli_cmd_flags {
1233 cli_cmd_flag_none = 0x00,
1234 cli_cmd_flag_sensitive = 0x01
1235};
1236
6fc6879b
JM
1237struct wpa_cli_cmd {
1238 const char *cmd;
1239 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
40fd868c 1240 enum wpa_cli_cmd_flags flags;
dfa141b1 1241 const char *usage;
6fc6879b
JM
1242};
1243
1244static struct wpa_cli_cmd wpa_cli_commands[] = {
40fd868c 1245 { "status", wpa_cli_cmd_status,
dfa141b1
ER
1246 cli_cmd_flag_none,
1247 "[verbose] = get current WPA/EAPOL/EAP status" },
40fd868c 1248 { "ping", wpa_cli_cmd_ping,
dfa141b1
ER
1249 cli_cmd_flag_none,
1250 "= pings wpa_supplicant" },
40fd868c 1251 { "mib", wpa_cli_cmd_mib,
dfa141b1
ER
1252 cli_cmd_flag_none,
1253 "= get MIB variables (dot1x, dot11)" },
40fd868c 1254 { "help", wpa_cli_cmd_help,
dfa141b1
ER
1255 cli_cmd_flag_none,
1256 "= show this usage help" },
40fd868c 1257 { "interface", wpa_cli_cmd_interface,
dfa141b1
ER
1258 cli_cmd_flag_none,
1259 "[ifname] = show interfaces/select interface" },
40fd868c 1260 { "level", wpa_cli_cmd_level,
dfa141b1
ER
1261 cli_cmd_flag_none,
1262 "<debug level> = change debug level" },
40fd868c 1263 { "license", wpa_cli_cmd_license,
dfa141b1
ER
1264 cli_cmd_flag_none,
1265 "= show full wpa_cli license" },
40fd868c 1266 { "quit", wpa_cli_cmd_quit,
dfa141b1
ER
1267 cli_cmd_flag_none,
1268 "= exit wpa_cli" },
40fd868c 1269 { "set", wpa_cli_cmd_set,
dfa141b1
ER
1270 cli_cmd_flag_none,
1271 "= set variables (shows list of variables when run without "
1272 "arguments)" },
40fd868c 1273 { "logon", wpa_cli_cmd_logon,
dfa141b1
ER
1274 cli_cmd_flag_none,
1275 "= IEEE 802.1X EAPOL state machine logon" },
40fd868c 1276 { "logoff", wpa_cli_cmd_logoff,
dfa141b1
ER
1277 cli_cmd_flag_none,
1278 "= IEEE 802.1X EAPOL state machine logoff" },
40fd868c 1279 { "pmksa", wpa_cli_cmd_pmksa,
dfa141b1
ER
1280 cli_cmd_flag_none,
1281 "= show PMKSA cache" },
40fd868c 1282 { "reassociate", wpa_cli_cmd_reassociate,
dfa141b1
ER
1283 cli_cmd_flag_none,
1284 "= force reassociation" },
40fd868c 1285 { "preauthenticate", wpa_cli_cmd_preauthenticate,
dfa141b1
ER
1286 cli_cmd_flag_none,
1287 "<BSSID> = force preauthentication" },
40fd868c 1288 { "identity", wpa_cli_cmd_identity,
dfa141b1
ER
1289 cli_cmd_flag_none,
1290 "<network id> <identity> = configure identity for an SSID" },
40fd868c 1291 { "password", wpa_cli_cmd_password,
dfa141b1
ER
1292 cli_cmd_flag_sensitive,
1293 "<network id> <password> = configure password for an SSID" },
40fd868c 1294 { "new_password", wpa_cli_cmd_new_password,
dfa141b1
ER
1295 cli_cmd_flag_sensitive,
1296 "<network id> <password> = change password for an SSID" },
40fd868c 1297 { "pin", wpa_cli_cmd_pin,
dfa141b1
ER
1298 cli_cmd_flag_sensitive,
1299 "<network id> <pin> = configure pin for an SSID" },
40fd868c 1300 { "otp", wpa_cli_cmd_otp,
dfa141b1
ER
1301 cli_cmd_flag_sensitive,
1302 "<network id> <password> = configure one-time-password for an SSID"
1303 },
40fd868c 1304 { "passphrase", wpa_cli_cmd_passphrase,
dfa141b1
ER
1305 cli_cmd_flag_sensitive,
1306 "<network id> <passphrase> = configure private key passphrase\n"
1307 " for an SSID" },
40fd868c 1308 { "bssid", wpa_cli_cmd_bssid,
dfa141b1
ER
1309 cli_cmd_flag_none,
1310 "<network id> <BSSID> = set preferred BSSID for an SSID" },
40fd868c 1311 { "list_networks", wpa_cli_cmd_list_networks,
dfa141b1
ER
1312 cli_cmd_flag_none,
1313 "= list configured networks" },
40fd868c 1314 { "select_network", wpa_cli_cmd_select_network,
dfa141b1
ER
1315 cli_cmd_flag_none,
1316 "<network id> = select a network (disable others)" },
40fd868c 1317 { "enable_network", wpa_cli_cmd_enable_network,
dfa141b1
ER
1318 cli_cmd_flag_none,
1319 "<network id> = enable a network" },
40fd868c 1320 { "disable_network", wpa_cli_cmd_disable_network,
dfa141b1
ER
1321 cli_cmd_flag_none,
1322 "<network id> = disable a network" },
40fd868c 1323 { "add_network", wpa_cli_cmd_add_network,
dfa141b1
ER
1324 cli_cmd_flag_none,
1325 "= add a network" },
40fd868c 1326 { "remove_network", wpa_cli_cmd_remove_network,
dfa141b1
ER
1327 cli_cmd_flag_none,
1328 "<network id> = remove a network" },
40fd868c 1329 { "set_network", wpa_cli_cmd_set_network,
dfa141b1
ER
1330 cli_cmd_flag_sensitive,
1331 "<network id> <variable> <value> = set network variables (shows\n"
1332 " list of variables when run without arguments)" },
40fd868c 1333 { "get_network", wpa_cli_cmd_get_network,
dfa141b1
ER
1334 cli_cmd_flag_none,
1335 "<network id> <variable> = get network variables" },
40fd868c 1336 { "save_config", wpa_cli_cmd_save_config,
dfa141b1
ER
1337 cli_cmd_flag_none,
1338 "= save the current configuration" },
40fd868c 1339 { "disconnect", wpa_cli_cmd_disconnect,
dfa141b1
ER
1340 cli_cmd_flag_none,
1341 "= disconnect and wait for reassociate/reconnect command before\n"
1342 " connecting" },
40fd868c 1343 { "reconnect", wpa_cli_cmd_reconnect,
dfa141b1
ER
1344 cli_cmd_flag_none,
1345 "= like reassociate, but only takes effect if already disconnected"
1346 },
40fd868c 1347 { "scan", wpa_cli_cmd_scan,
dfa141b1
ER
1348 cli_cmd_flag_none,
1349 "= request new BSS scan" },
40fd868c 1350 { "scan_results", wpa_cli_cmd_scan_results,
dfa141b1
ER
1351 cli_cmd_flag_none,
1352 "= get latest scan results" },
40fd868c 1353 { "bss", wpa_cli_cmd_bss,
dfa141b1
ER
1354 cli_cmd_flag_none,
1355 "<<idx> | <bssid>> = get detailed scan result info" },
40fd868c 1356 { "get_capability", wpa_cli_cmd_get_capability,
dfa141b1
ER
1357 cli_cmd_flag_none,
1358 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
40fd868c 1359 { "reconfigure", wpa_cli_cmd_reconfigure,
dfa141b1
ER
1360 cli_cmd_flag_none,
1361 "= force wpa_supplicant to re-read its configuration file" },
40fd868c 1362 { "terminate", wpa_cli_cmd_terminate,
dfa141b1
ER
1363 cli_cmd_flag_none,
1364 "= terminate wpa_supplicant" },
40fd868c 1365 { "interface_add", wpa_cli_cmd_interface_add,
dfa141b1
ER
1366 cli_cmd_flag_none,
1367 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
1368 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
1369 " are optional" },
40fd868c 1370 { "interface_remove", wpa_cli_cmd_interface_remove,
dfa141b1
ER
1371 cli_cmd_flag_none,
1372 "<ifname> = removes the interface" },
40fd868c 1373 { "interface_list", wpa_cli_cmd_interface_list,
dfa141b1
ER
1374 cli_cmd_flag_none,
1375 "= list available interfaces" },
40fd868c 1376 { "ap_scan", wpa_cli_cmd_ap_scan,
dfa141b1
ER
1377 cli_cmd_flag_none,
1378 "<value> = set ap_scan parameter" },
40fd868c 1379 { "stkstart", wpa_cli_cmd_stkstart,
dfa141b1
ER
1380 cli_cmd_flag_none,
1381 "<addr> = request STK negotiation with <addr>" },
40fd868c 1382 { "ft_ds", wpa_cli_cmd_ft_ds,
dfa141b1
ER
1383 cli_cmd_flag_none,
1384 "<addr> = request over-the-DS FT with <addr>" },
40fd868c 1385 { "wps_pbc", wpa_cli_cmd_wps_pbc,
dfa141b1
ER
1386 cli_cmd_flag_none,
1387 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
40fd868c 1388 { "wps_pin", wpa_cli_cmd_wps_pin,
dfa141b1
ER
1389 cli_cmd_flag_sensitive,
1390 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
1391 "hardcoded)" },
116f7bb0 1392#ifdef CONFIG_WPS_OOB
46bdb83a
MH
1393 { "wps_oob", wpa_cli_cmd_wps_oob,
1394 cli_cmd_flag_sensitive,
e1ee6b60 1395 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
116f7bb0 1396#endif /* CONFIG_WPS_OOB */
40fd868c 1397 { "wps_reg", wpa_cli_cmd_wps_reg,
dfa141b1
ER
1398 cli_cmd_flag_sensitive,
1399 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
11ef8d35
JM
1400 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
1401 cli_cmd_flag_none,
1402 "<addr> = request RSN authentication with <addr> in IBSS" },
e653b622
JM
1403#ifdef CONFIG_AP
1404 { "sta", wpa_cli_cmd_sta,
1405 cli_cmd_flag_none,
1406 "<addr> = get information about an associated station (AP)" },
1407 { "all_sta", wpa_cli_cmd_all_sta,
1408 cli_cmd_flag_none,
1409 "= get information about all associated stations (AP)" },
1410#endif /* CONFIG_AP */
dfa141b1 1411 { NULL, NULL, cli_cmd_flag_none, NULL }
6fc6879b
JM
1412};
1413
1414
dfa141b1
ER
1415/*
1416 * Prints command usage, lines are padded with the specified string.
1417 */
1418static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
1419{
1420 char c;
1421 size_t n;
1422
1423 printf("%s%s ", pad, cmd->cmd);
1424 for (n = 0; (c = cmd->usage[n]); n++) {
1425 printf("%c", c);
1426 if (c == '\n')
1427 printf("%s", pad);
1428 }
1429 printf("\n");
1430}
1431
1432
1433static void print_help(void)
1434{
1435 int n;
1436 printf("commands:\n");
1437 for (n = 0; wpa_cli_commands[n].cmd; n++)
1438 print_cmd_help(&wpa_cli_commands[n], " ");
1439}
1440
1441
40fd868c
ER
1442#ifdef CONFIG_READLINE
1443static int cmd_has_sensitive_data(const char *cmd)
1444{
1445 const char *c, *delim;
1446 int n;
1447 size_t len;
1448
1449 delim = os_strchr(cmd, ' ');
1450 if (delim)
1451 len = delim - cmd;
1452 else
1453 len = os_strlen(cmd);
1454
1455 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
1456 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
1457 return (wpa_cli_commands[n].flags &
1458 cli_cmd_flag_sensitive);
1459 }
1460 return 0;
1461}
1462#endif /* CONFIG_READLINE */
1463
1464
6fc6879b
JM
1465static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1466{
1467 struct wpa_cli_cmd *cmd, *match = NULL;
1468 int count;
1469 int ret = 0;
1470
1471 count = 0;
1472 cmd = wpa_cli_commands;
1473 while (cmd->cmd) {
1474 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1475 {
1476 match = cmd;
1477 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1478 /* we have an exact match */
1479 count = 1;
1480 break;
1481 }
1482 count++;
1483 }
1484 cmd++;
1485 }
1486
1487 if (count > 1) {
1488 printf("Ambiguous command '%s'; possible commands:", argv[0]);
1489 cmd = wpa_cli_commands;
1490 while (cmd->cmd) {
1491 if (os_strncasecmp(cmd->cmd, argv[0],
1492 os_strlen(argv[0])) == 0) {
1493 printf(" %s", cmd->cmd);
1494 }
1495 cmd++;
1496 }
1497 printf("\n");
1498 ret = 1;
1499 } else if (count == 0) {
1500 printf("Unknown command '%s'\n", argv[0]);
1501 ret = 1;
1502 } else {
1503 ret = match->handler(ctrl, argc - 1, &argv[1]);
1504 }
1505
1506 return ret;
1507}
1508
1509
1510static int str_match(const char *a, const char *b)
1511{
1512 return os_strncmp(a, b, os_strlen(b)) == 0;
1513}
1514
1515
1516static int wpa_cli_exec(const char *program, const char *arg1,
1517 const char *arg2)
1518{
1519 char *cmd;
1520 size_t len;
1521 int res;
308a4ec8 1522 int ret = 0;
6fc6879b
JM
1523
1524 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1525 cmd = os_malloc(len);
1526 if (cmd == NULL)
1527 return -1;
1528 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1529 if (res < 0 || (size_t) res >= len) {
1530 os_free(cmd);
1531 return -1;
1532 }
1533 cmd[len - 1] = '\0';
1534#ifndef _WIN32_WCE
308a4ec8
JM
1535 if (system(cmd) < 0)
1536 ret = -1;
6fc6879b
JM
1537#endif /* _WIN32_WCE */
1538 os_free(cmd);
1539
308a4ec8 1540 return ret;
6fc6879b
JM
1541}
1542
1543
1544static void wpa_cli_action_process(const char *msg)
1545{
1546 const char *pos;
1547 char *copy = NULL, *id, *pos2;
1548
1549 pos = msg;
1550 if (*pos == '<') {
1551 /* skip priority */
1552 pos = os_strchr(pos, '>');
1553 if (pos)
1554 pos++;
1555 else
1556 pos = msg;
1557 }
1558
1559 if (str_match(pos, WPA_EVENT_CONNECTED)) {
1560 int new_id = -1;
1561 os_unsetenv("WPA_ID");
1562 os_unsetenv("WPA_ID_STR");
1563 os_unsetenv("WPA_CTRL_DIR");
1564
1565 pos = os_strstr(pos, "[id=");
1566 if (pos)
1567 copy = os_strdup(pos + 4);
1568
1569 if (copy) {
1570 pos2 = id = copy;
1571 while (*pos2 && *pos2 != ' ')
1572 pos2++;
1573 *pos2++ = '\0';
1574 new_id = atoi(id);
1575 os_setenv("WPA_ID", id, 1);
1576 while (*pos2 && *pos2 != '=')
1577 pos2++;
1578 if (*pos2 == '=')
1579 pos2++;
1580 id = pos2;
1581 while (*pos2 && *pos2 != ']')
1582 pos2++;
1583 *pos2 = '\0';
1584 os_setenv("WPA_ID_STR", id, 1);
1585 os_free(copy);
1586 }
1587
1588 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
1589
1590 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
1591 wpa_cli_connected = 1;
1592 wpa_cli_last_id = new_id;
1593 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
1594 }
1595 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
1596 if (wpa_cli_connected) {
1597 wpa_cli_connected = 0;
1598 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
1599 }
1600 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
1601 printf("wpa_supplicant is terminating - stop monitoring\n");
1602 wpa_cli_quit = 1;
1603 }
1604}
1605
1606
1607#ifndef CONFIG_ANSI_C_EXTRA
1608static void wpa_cli_action_cb(char *msg, size_t len)
1609{
1610 wpa_cli_action_process(msg);
1611}
1612#endif /* CONFIG_ANSI_C_EXTRA */
1613
1614
1615static void wpa_cli_reconnect(void)
1616{
1617 wpa_cli_close_connection();
1618 ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
1619 if (ctrl_conn) {
1620 printf("Connection to wpa_supplicant re-established\n");
1621 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1622 wpa_cli_attached = 1;
1623 } else {
1624 printf("Warning: Failed to attach to "
1625 "wpa_supplicant.\n");
1626 }
1627 }
1628}
1629
1630
1631static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
1632 int action_monitor)
1633{
1634 int first = 1;
1635 if (ctrl_conn == NULL) {
1636 wpa_cli_reconnect();
1637 return;
1638 }
1639 while (wpa_ctrl_pending(ctrl) > 0) {
1640 char buf[256];
1641 size_t len = sizeof(buf) - 1;
1642 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
1643 buf[len] = '\0';
1644 if (action_monitor)
1645 wpa_cli_action_process(buf);
1646 else {
1647 if (in_read && first)
1648 printf("\n");
1649 first = 0;
1650 printf("%s\n", buf);
1651 }
1652 } else {
1653 printf("Could not read pending message.\n");
1654 break;
1655 }
1656 }
1657
1658 if (wpa_ctrl_pending(ctrl) < 0) {
1659 printf("Connection to wpa_supplicant lost - trying to "
1660 "reconnect\n");
1661 wpa_cli_reconnect();
1662 }
1663}
1664
1665
1666#ifdef CONFIG_READLINE
1667static char * wpa_cli_cmd_gen(const char *text, int state)
1668{
1669 static int i, len;
1670 const char *cmd;
1671
1672 if (state == 0) {
1673 i = 0;
1674 len = os_strlen(text);
1675 }
1676
1677 while ((cmd = wpa_cli_commands[i].cmd)) {
1678 i++;
1679 if (os_strncasecmp(cmd, text, len) == 0)
1680 return os_strdup(cmd);
1681 }
1682
1683 return NULL;
1684}
1685
1686
1687static char * wpa_cli_dummy_gen(const char *text, int state)
1688{
1689 return NULL;
1690}
1691
1692
1693static char ** wpa_cli_completion(const char *text, int start, int end)
1694{
1695 return rl_completion_matches(text, start == 0 ?
1696 wpa_cli_cmd_gen : wpa_cli_dummy_gen);
1697}
1698#endif /* CONFIG_READLINE */
1699
1700
1701static void wpa_cli_interactive(void)
1702{
1703#define max_args 10
1704 char cmdbuf[256], *cmd, *argv[max_args], *pos;
1705 int argc;
1706#ifdef CONFIG_READLINE
1707 char *home, *hfile = NULL;
1708#endif /* CONFIG_READLINE */
1709
1710 printf("\nInteractive mode\n\n");
1711
1712#ifdef CONFIG_READLINE
1713 rl_attempted_completion_function = wpa_cli_completion;
1714 home = getenv("HOME");
1715 if (home) {
1716 const char *fname = ".wpa_cli_history";
1717 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
1718 hfile = os_malloc(hfile_len);
1719 if (hfile) {
1720 int res;
1721 res = os_snprintf(hfile, hfile_len, "%s/%s", home,
1722 fname);
1723 if (res >= 0 && res < hfile_len) {
1724 hfile[hfile_len - 1] = '\0';
1725 read_history(hfile);
1726 stifle_history(100);
1727 }
1728 }
1729 }
1730#endif /* CONFIG_READLINE */
1731
1732 do {
1733 wpa_cli_recv_pending(ctrl_conn, 0, 0);
1734#ifndef CONFIG_NATIVE_WINDOWS
1cc84c1c 1735 alarm(ping_interval);
6fc6879b
JM
1736#endif /* CONFIG_NATIVE_WINDOWS */
1737#ifdef CONFIG_READLINE
1738 cmd = readline("> ");
1739 if (cmd && *cmd) {
1740 HIST_ENTRY *h;
1741 while (next_history())
1742 ;
1743 h = previous_history();
1744 if (h == NULL || os_strcmp(cmd, h->line) != 0)
1745 add_history(cmd);
1746 next_history();
1747 }
1748#else /* CONFIG_READLINE */
1749 printf("> ");
1750 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
1751#endif /* CONFIG_READLINE */
1752#ifndef CONFIG_NATIVE_WINDOWS
1753 alarm(0);
1754#endif /* CONFIG_NATIVE_WINDOWS */
1755 if (cmd == NULL)
1756 break;
1757 wpa_cli_recv_pending(ctrl_conn, 0, 0);
1758 pos = cmd;
1759 while (*pos != '\0') {
1760 if (*pos == '\n') {
1761 *pos = '\0';
1762 break;
1763 }
1764 pos++;
1765 }
1766 argc = 0;
1767 pos = cmd;
1768 for (;;) {
1769 while (*pos == ' ')
1770 pos++;
1771 if (*pos == '\0')
1772 break;
1773 argv[argc] = pos;
1774 argc++;
1775 if (argc == max_args)
1776 break;
1777 if (*pos == '"') {
1778 char *pos2 = os_strrchr(pos, '"');
1779 if (pos2)
1780 pos = pos2 + 1;
1781 }
1782 while (*pos != '\0' && *pos != ' ')
1783 pos++;
1784 if (*pos == ' ')
1785 *pos++ = '\0';
1786 }
1787 if (argc)
1788 wpa_request(ctrl_conn, argc, argv);
1789
1790 if (cmd != cmdbuf)
1791 os_free(cmd);
1792 } while (!wpa_cli_quit);
1793
1794#ifdef CONFIG_READLINE
1795 if (hfile) {
1796 /* Save command history, excluding lines that may contain
1797 * passwords. */
1798 HIST_ENTRY *h;
1799 history_set_pos(0);
413653e8 1800 while ((h = current_history())) {
6fc6879b
JM
1801 char *p = h->line;
1802 while (*p == ' ' || *p == '\t')
1803 p++;
40fd868c 1804 if (cmd_has_sensitive_data(p)) {
6fc6879b
JM
1805 h = remove_history(where_history());
1806 if (h) {
1807 os_free(h->line);
1808 os_free(h->data);
1809 os_free(h);
413653e8
ER
1810 } else
1811 next_history();
1812 } else
1813 next_history();
6fc6879b
JM
1814 }
1815 write_history(hfile);
1816 os_free(hfile);
1817 }
1818#endif /* CONFIG_READLINE */
1819}
1820
1821
1822static void wpa_cli_action(struct wpa_ctrl *ctrl)
1823{
1824#ifdef CONFIG_ANSI_C_EXTRA
1825 /* TODO: ANSI C version(?) */
1826 printf("Action processing not supported in ANSI C build.\n");
1827#else /* CONFIG_ANSI_C_EXTRA */
1828 fd_set rfds;
1829 int fd, res;
1830 struct timeval tv;
1831 char buf[256]; /* note: large enough to fit in unsolicited messages */
1832 size_t len;
1833
1834 fd = wpa_ctrl_get_fd(ctrl);
1835
1836 while (!wpa_cli_quit) {
1837 FD_ZERO(&rfds);
1838 FD_SET(fd, &rfds);
1cc84c1c 1839 tv.tv_sec = ping_interval;
6fc6879b
JM
1840 tv.tv_usec = 0;
1841 res = select(fd + 1, &rfds, NULL, NULL, &tv);
1842 if (res < 0 && errno != EINTR) {
1843 perror("select");
1844 break;
1845 }
1846
1847 if (FD_ISSET(fd, &rfds))
1848 wpa_cli_recv_pending(ctrl, 0, 1);
1849 else {
1850 /* verify that connection is still working */
1851 len = sizeof(buf) - 1;
1852 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
1853 wpa_cli_action_cb) < 0 ||
1854 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
1855 printf("wpa_supplicant did not reply to PING "
1856 "command - exiting\n");
1857 break;
1858 }
1859 }
1860 }
1861#endif /* CONFIG_ANSI_C_EXTRA */
1862}
1863
1864
1865static void wpa_cli_cleanup(void)
1866{
1867 wpa_cli_close_connection();
1868 if (pid_file)
1869 os_daemonize_terminate(pid_file);
1870
1871 os_program_deinit();
1872}
1873
1874static void wpa_cli_terminate(int sig)
1875{
1876 wpa_cli_cleanup();
1877 exit(0);
1878}
1879
1880
1881#ifndef CONFIG_NATIVE_WINDOWS
1882static void wpa_cli_alarm(int sig)
1883{
1884 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
1885 printf("Connection to wpa_supplicant lost - trying to "
1886 "reconnect\n");
1887 wpa_cli_close_connection();
1888 }
1889 if (!ctrl_conn)
1890 wpa_cli_reconnect();
1891 if (ctrl_conn)
1892 wpa_cli_recv_pending(ctrl_conn, 1, 0);
1cc84c1c 1893 alarm(ping_interval);
6fc6879b
JM
1894}
1895#endif /* CONFIG_NATIVE_WINDOWS */
1896
1897
1898static char * wpa_cli_get_default_ifname(void)
1899{
1900 char *ifname = NULL;
1901
1902#ifdef CONFIG_CTRL_IFACE_UNIX
1903 struct dirent *dent;
1904 DIR *dir = opendir(ctrl_iface_dir);
1905 if (!dir)
1906 return NULL;
1907 while ((dent = readdir(dir))) {
1908#ifdef _DIRENT_HAVE_D_TYPE
1909 /*
1910 * Skip the file if it is not a socket. Also accept
1911 * DT_UNKNOWN (0) in case the C library or underlying
1912 * file system does not support d_type.
1913 */
1914 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
1915 continue;
1916#endif /* _DIRENT_HAVE_D_TYPE */
1917 if (os_strcmp(dent->d_name, ".") == 0 ||
1918 os_strcmp(dent->d_name, "..") == 0)
1919 continue;
1920 printf("Selected interface '%s'\n", dent->d_name);
1921 ifname = os_strdup(dent->d_name);
1922 break;
1923 }
1924 closedir(dir);
1925#endif /* CONFIG_CTRL_IFACE_UNIX */
1926
1927#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
1928 char buf[2048], *pos;
1929 size_t len;
1930 struct wpa_ctrl *ctrl;
1931 int ret;
1932
1933 ctrl = wpa_ctrl_open(NULL);
1934 if (ctrl == NULL)
1935 return NULL;
1936
1937 len = sizeof(buf) - 1;
1938 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
1939 if (ret >= 0) {
1940 buf[len] = '\0';
1941 pos = os_strchr(buf, '\n');
1942 if (pos)
1943 *pos = '\0';
1944 ifname = os_strdup(buf);
1945 }
1946 wpa_ctrl_close(ctrl);
1947#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1948
1949 return ifname;
1950}
1951
1952
1953int main(int argc, char *argv[])
1954{
1955 int interactive;
1956 int warning_displayed = 0;
1957 int c;
1958 int daemonize = 0;
1959 int ret = 0;
1960 const char *global = NULL;
1961
1962 if (os_program_init())
1963 return -1;
1964
1965 for (;;) {
1cc84c1c 1966 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
6fc6879b
JM
1967 if (c < 0)
1968 break;
1969 switch (c) {
1970 case 'a':
1971 action_file = optarg;
1972 break;
1973 case 'B':
1974 daemonize = 1;
1975 break;
1976 case 'g':
1977 global = optarg;
1978 break;
1cc84c1c
JM
1979 case 'G':
1980 ping_interval = atoi(optarg);
1981 break;
6fc6879b
JM
1982 case 'h':
1983 usage();
1984 return 0;
1985 case 'v':
1986 printf("%s\n", wpa_cli_version);
1987 return 0;
1988 case 'i':
1989 os_free(ctrl_ifname);
1990 ctrl_ifname = os_strdup(optarg);
1991 break;
1992 case 'p':
1993 ctrl_iface_dir = optarg;
1994 break;
1995 case 'P':
1996 pid_file = optarg;
1997 break;
1998 default:
1999 usage();
2000 return -1;
2001 }
2002 }
2003
2004 interactive = (argc == optind) && (action_file == NULL);
2005
2006 if (interactive)
2007 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
2008
2009 if (global) {
2010#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2011 ctrl_conn = wpa_ctrl_open(NULL);
2012#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2013 ctrl_conn = wpa_ctrl_open(global);
2014#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2015 if (ctrl_conn == NULL) {
2016 perror("Failed to connect to wpa_supplicant - "
2017 "wpa_ctrl_open");
2018 return -1;
2019 }
2020 }
2021
2022 for (; !global;) {
2023 if (ctrl_ifname == NULL)
2024 ctrl_ifname = wpa_cli_get_default_ifname();
2025 ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
2026 if (ctrl_conn) {
2027 if (warning_displayed)
2028 printf("Connection established.\n");
2029 break;
2030 }
2031
2032 if (!interactive) {
2033 perror("Failed to connect to wpa_supplicant - "
2034 "wpa_ctrl_open");
2035 return -1;
2036 }
2037
2038 if (!warning_displayed) {
2039 printf("Could not connect to wpa_supplicant - "
2040 "re-trying\n");
2041 warning_displayed = 1;
2042 }
2043 os_sleep(1, 0);
2044 continue;
2045 }
2046
2047#ifndef _WIN32_WCE
2048 signal(SIGINT, wpa_cli_terminate);
2049 signal(SIGTERM, wpa_cli_terminate);
2050#endif /* _WIN32_WCE */
2051#ifndef CONFIG_NATIVE_WINDOWS
2052 signal(SIGALRM, wpa_cli_alarm);
2053#endif /* CONFIG_NATIVE_WINDOWS */
2054
2055 if (interactive || action_file) {
2056 if (wpa_ctrl_attach(ctrl_conn) == 0) {
2057 wpa_cli_attached = 1;
2058 } else {
2059 printf("Warning: Failed to attach to "
2060 "wpa_supplicant.\n");
2061 if (!interactive)
2062 return -1;
2063 }
2064 }
2065
2066 if (daemonize && os_daemonize(pid_file))
2067 return -1;
2068
2069 if (interactive)
2070 wpa_cli_interactive();
2071 else if (action_file)
2072 wpa_cli_action(ctrl_conn);
2073 else
2074 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
2075
2076 os_free(ctrl_ifname);
2077 wpa_cli_cleanup();
2078
2079 return ret;
2080}
2081
2082#else /* CONFIG_CTRL_IFACE */
2083int main(int argc, char *argv[])
2084{
2085 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
2086 return -1;
2087}
2088#endif /* CONFIG_CTRL_IFACE */