]> git.ipfire.org Git - thirdparty/hostap.git/blame - hostapd/hostapd_cli.c
Remove src/common from default header file path
[thirdparty/hostap.git] / hostapd / hostapd_cli.c
CommitLineData
6fc6879b
JM
1/*
2 * hostapd - command line interface for hostapd 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#include <dirent.h>
17
90973fb2 18#include "common/wpa_ctrl.h"
6fc6879b 19#include "common.h"
90973fb2 20#include "common/version.h"
6fc6879b
JM
21
22
23static const char *hostapd_cli_version =
24"hostapd_cli v" VERSION_STR "\n"
6f78f2fb 25"Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> and contributors";
6fc6879b
JM
26
27
28static const char *hostapd_cli_license =
29"This program is free software. You can distribute it and/or modify it\n"
30"under the terms of the GNU General Public License version 2.\n"
31"\n"
32"Alternatively, this software may be distributed under the terms of the\n"
33"BSD license. See README and COPYING for more details.\n";
34
35static const char *hostapd_cli_full_license =
36"This program is free software; you can redistribute it and/or modify\n"
37"it under the terms of the GNU General Public License version 2 as\n"
38"published by the Free Software Foundation.\n"
39"\n"
40"This program is distributed in the hope that it will be useful,\n"
41"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
42"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
43"GNU General Public License for more details.\n"
44"\n"
45"You should have received a copy of the GNU General Public License\n"
46"along with this program; if not, write to the Free Software\n"
47"Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
48"\n"
49"Alternatively, this software may be distributed under the terms of the\n"
50"BSD license.\n"
51"\n"
52"Redistribution and use in source and binary forms, with or without\n"
53"modification, are permitted provided that the following conditions are\n"
54"met:\n"
55"\n"
56"1. Redistributions of source code must retain the above copyright\n"
57" notice, this list of conditions and the following disclaimer.\n"
58"\n"
59"2. Redistributions in binary form must reproduce the above copyright\n"
60" notice, this list of conditions and the following disclaimer in the\n"
61" documentation and/or other materials provided with the distribution.\n"
62"\n"
63"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
64" names of its contributors may be used to endorse or promote products\n"
65" derived from this software without specific prior written permission.\n"
66"\n"
67"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
68"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
69"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
70"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
71"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
72"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
73"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
74"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
75"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
76"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
77"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
78"\n";
79
80static const char *commands_help =
81"Commands:\n"
82" mib get MIB variables (dot1x, dot11, radius)\n"
83" sta <addr> get MIB variables for one station\n"
84" all_sta get MIB variables for all stations\n"
85" new_sta <addr> add a new station\n"
88b4b424
JM
86#ifdef CONFIG_IEEE80211W
87" sa_query <addr> send SA Query to a station\n"
88#endif /* CONFIG_IEEE80211W */
ad08c363 89#ifdef CONFIG_WPS
077a781f 90" wps_pin <uuid> <pin> [timeout] add WPS Enrollee PIN (Device Password)\n"
ad08c363 91" wps_pbc indicate button pushed to initiate PBC\n"
116f7bb0 92#ifdef CONFIG_WPS_OOB
46bdb83a 93" wps_oob <type> <path> <method> use WPS with out-of-band (UFD)\n"
116f7bb0 94#endif /* CONFIG_WPS_OOB */
ad08c363 95#endif /* CONFIG_WPS */
6fc6879b
JM
96" help show this usage help\n"
97" interface [ifname] show interfaces/select interface\n"
98" level <debug level> change debug level\n"
99" license show full hostapd_cli license\n"
100" quit exit hostapd_cli\n";
101
102static struct wpa_ctrl *ctrl_conn;
103static int hostapd_cli_quit = 0;
104static int hostapd_cli_attached = 0;
105static const char *ctrl_iface_dir = "/var/run/hostapd";
106static char *ctrl_ifname = NULL;
1cc84c1c 107static int ping_interval = 5;
6fc6879b
JM
108
109
110static void usage(void)
111{
112 fprintf(stderr, "%s\n", hostapd_cli_version);
113 fprintf(stderr,
114 "\n"
115 "usage: hostapd_cli [-p<path>] [-i<ifname>] [-hv] "
1cc84c1c
JM
116 "[-G<ping interval>] \\\n"
117 " [command..]\n"
6fc6879b
JM
118 "\n"
119 "Options:\n"
120 " -h help (show this usage text)\n"
121 " -v shown version information\n"
122 " -p<path> path to find control sockets (default: "
123 "/var/run/hostapd)\n"
124 " -i<ifname> Interface to listen on (default: first "
125 "interface found in the\n"
126 " socket path)\n\n"
127 "%s",
128 commands_help);
129}
130
131
132static struct wpa_ctrl * hostapd_cli_open_connection(const char *ifname)
133{
134 char *cfile;
135 int flen;
136
137 if (ifname == NULL)
138 return NULL;
139
140 flen = strlen(ctrl_iface_dir) + strlen(ifname) + 2;
141 cfile = malloc(flen);
142 if (cfile == NULL)
143 return NULL;
144 snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
145
146 ctrl_conn = wpa_ctrl_open(cfile);
147 free(cfile);
148 return ctrl_conn;
149}
150
151
152static void hostapd_cli_close_connection(void)
153{
154 if (ctrl_conn == NULL)
155 return;
156
157 if (hostapd_cli_attached) {
158 wpa_ctrl_detach(ctrl_conn);
159 hostapd_cli_attached = 0;
160 }
161 wpa_ctrl_close(ctrl_conn);
162 ctrl_conn = NULL;
163}
164
165
166static void hostapd_cli_msg_cb(char *msg, size_t len)
167{
168 printf("%s\n", msg);
169}
170
171
172static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
173{
174 char buf[4096];
175 size_t len;
176 int ret;
177
178 if (ctrl_conn == NULL) {
179 printf("Not connected to hostapd - command dropped.\n");
180 return -1;
181 }
182 len = sizeof(buf) - 1;
183 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
184 hostapd_cli_msg_cb);
185 if (ret == -2) {
186 printf("'%s' command timed out.\n", cmd);
187 return -2;
188 } else if (ret < 0) {
189 printf("'%s' command failed.\n", cmd);
190 return -1;
191 }
192 if (print) {
193 buf[len] = '\0';
194 printf("%s", buf);
195 }
196 return 0;
197}
198
199
200static inline int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
201{
202 return _wpa_ctrl_command(ctrl, cmd, 1);
203}
204
205
206static int hostapd_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
207{
208 return wpa_ctrl_command(ctrl, "PING");
209}
210
211
212static int hostapd_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
213{
214 return wpa_ctrl_command(ctrl, "MIB");
215}
216
217
218static int hostapd_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
219{
220 char buf[64];
221 if (argc != 1) {
222 printf("Invalid 'sta' command - exactly one argument, STA "
223 "address, is required.\n");
224 return -1;
225 }
226 snprintf(buf, sizeof(buf), "STA %s", argv[0]);
227 return wpa_ctrl_command(ctrl, buf);
228}
229
230
231static int hostapd_cli_cmd_new_sta(struct wpa_ctrl *ctrl, int argc,
232 char *argv[])
233{
234 char buf[64];
235 if (argc != 1) {
236 printf("Invalid 'new_sta' command - exactly one argument, STA "
237 "address, is required.\n");
238 return -1;
239 }
240 snprintf(buf, sizeof(buf), "NEW_STA %s", argv[0]);
241 return wpa_ctrl_command(ctrl, buf);
242}
243
244
88b4b424
JM
245#ifdef CONFIG_IEEE80211W
246static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc,
247 char *argv[])
248{
249 char buf[64];
250 if (argc != 1) {
251 printf("Invalid 'sa_query' command - exactly one argument, "
252 "STA address, is required.\n");
253 return -1;
254 }
255 snprintf(buf, sizeof(buf), "SA_QUERY %s", argv[0]);
256 return wpa_ctrl_command(ctrl, buf);
257}
258#endif /* CONFIG_IEEE80211W */
259
260
ad08c363
JM
261#ifdef CONFIG_WPS
262static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc,
263 char *argv[])
264{
265 char buf[64];
077a781f
JM
266 if (argc < 2) {
267 printf("Invalid 'wps_pin' command - at least two arguments, "
ad08c363
JM
268 "UUID and PIN, are required.\n");
269 return -1;
270 }
077a781f
JM
271 if (argc > 2)
272 snprintf(buf, sizeof(buf), "WPS_PIN %s %s %s",
273 argv[0], argv[1], argv[2]);
274 else
275 snprintf(buf, sizeof(buf), "WPS_PIN %s %s", argv[0], argv[1]);
ad08c363
JM
276 return wpa_ctrl_command(ctrl, buf);
277}
278
279
280static int hostapd_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc,
281 char *argv[])
282{
283 return wpa_ctrl_command(ctrl, "WPS_PBC");
284}
46bdb83a
MH
285
286
116f7bb0 287#ifdef CONFIG_WPS_OOB
46bdb83a
MH
288static int hostapd_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc,
289 char *argv[])
290{
291 char cmd[256];
292 int res;
293
e1ee6b60
MH
294 if (argc != 3 && argc != 4) {
295 printf("Invalid WPS_OOB command: need three or four "
296 "arguments:\n"
297 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
298 "- PATH: path of OOB device like '/mnt'\n"
299 "- METHOD: OOB method 'pin-e' or 'pin-r', "
300 "'cred'\n"
301 "- DEV_NAME: (only for NFC) device name like "
302 "'pn531'\n");
46bdb83a
MH
303 return -1;
304 }
305
e1ee6b60
MH
306 if (argc == 3)
307 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
308 argv[0], argv[1], argv[2]);
309 else
310 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
311 argv[0], argv[1], argv[2], argv[3]);
46bdb83a
MH
312 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
313 printf("Too long WPS_OOB command.\n");
314 return -1;
315 }
316 return wpa_ctrl_command(ctrl, cmd);
317}
116f7bb0 318#endif /* CONFIG_WPS_OOB */
ad08c363
JM
319#endif /* CONFIG_WPS */
320
321
6fc6879b
JM
322static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
323 char *addr, size_t addr_len)
324{
325 char buf[4096], *pos;
326 size_t len;
327 int ret;
328
329 if (ctrl_conn == NULL) {
330 printf("Not connected to hostapd - command dropped.\n");
331 return -1;
332 }
333 len = sizeof(buf) - 1;
334 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
335 hostapd_cli_msg_cb);
336 if (ret == -2) {
337 printf("'%s' command timed out.\n", cmd);
338 return -2;
339 } else if (ret < 0) {
340 printf("'%s' command failed.\n", cmd);
341 return -1;
342 }
343
344 buf[len] = '\0';
345 if (memcmp(buf, "FAIL", 4) == 0)
346 return -1;
347 printf("%s", buf);
348
349 pos = buf;
350 while (*pos != '\0' && *pos != '\n')
351 pos++;
352 *pos = '\0';
353 os_strlcpy(addr, buf, addr_len);
354 return 0;
355}
356
357
358static int hostapd_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc,
359 char *argv[])
360{
361 char addr[32], cmd[64];
362
363 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
364 return 0;
365 do {
366 snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
367 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
368
369 return -1;
370}
371
372
373static int hostapd_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
374{
375 printf("%s", commands_help);
376 return 0;
377}
378
379
380static int hostapd_cli_cmd_license(struct wpa_ctrl *ctrl, int argc,
381 char *argv[])
382{
383 printf("%s\n\n%s\n", hostapd_cli_version, hostapd_cli_full_license);
384 return 0;
385}
386
387
388static int hostapd_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
389{
390 hostapd_cli_quit = 1;
391 return 0;
392}
393
394
395static int hostapd_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
396{
397 char cmd[256];
398 if (argc != 1) {
399 printf("Invalid LEVEL command: needs one argument (debug "
400 "level)\n");
401 return 0;
402 }
403 snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
404 return wpa_ctrl_command(ctrl, cmd);
405}
406
407
408static void hostapd_cli_list_interfaces(struct wpa_ctrl *ctrl)
409{
410 struct dirent *dent;
411 DIR *dir;
412
413 dir = opendir(ctrl_iface_dir);
414 if (dir == NULL) {
415 printf("Control interface directory '%s' could not be "
416 "openned.\n", ctrl_iface_dir);
417 return;
418 }
419
420 printf("Available interfaces:\n");
421 while ((dent = readdir(dir))) {
422 if (strcmp(dent->d_name, ".") == 0 ||
423 strcmp(dent->d_name, "..") == 0)
424 continue;
425 printf("%s\n", dent->d_name);
426 }
427 closedir(dir);
428}
429
430
431static int hostapd_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc,
432 char *argv[])
433{
434 if (argc < 1) {
435 hostapd_cli_list_interfaces(ctrl);
436 return 0;
437 }
438
439 hostapd_cli_close_connection();
440 free(ctrl_ifname);
441 ctrl_ifname = strdup(argv[0]);
442
443 if (hostapd_cli_open_connection(ctrl_ifname)) {
444 printf("Connected to interface '%s.\n", ctrl_ifname);
445 if (wpa_ctrl_attach(ctrl_conn) == 0) {
446 hostapd_cli_attached = 1;
447 } else {
448 printf("Warning: Failed to attach to "
449 "hostapd.\n");
450 }
451 } else {
452 printf("Could not connect to interface '%s' - re-trying\n",
453 ctrl_ifname);
454 }
455 return 0;
456}
457
458
459struct hostapd_cli_cmd {
460 const char *cmd;
461 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
462};
463
464static struct hostapd_cli_cmd hostapd_cli_commands[] = {
465 { "ping", hostapd_cli_cmd_ping },
466 { "mib", hostapd_cli_cmd_mib },
467 { "sta", hostapd_cli_cmd_sta },
468 { "all_sta", hostapd_cli_cmd_all_sta },
469 { "new_sta", hostapd_cli_cmd_new_sta },
88b4b424
JM
470#ifdef CONFIG_IEEE80211W
471 { "sa_query", hostapd_cli_cmd_sa_query },
472#endif /* CONFIG_IEEE80211W */
ad08c363
JM
473#ifdef CONFIG_WPS
474 { "wps_pin", hostapd_cli_cmd_wps_pin },
475 { "wps_pbc", hostapd_cli_cmd_wps_pbc },
116f7bb0 476#ifdef CONFIG_WPS_OOB
46bdb83a 477 { "wps_oob", hostapd_cli_cmd_wps_oob },
116f7bb0 478#endif /* CONFIG_WPS_OOB */
ad08c363 479#endif /* CONFIG_WPS */
6fc6879b
JM
480 { "help", hostapd_cli_cmd_help },
481 { "interface", hostapd_cli_cmd_interface },
482 { "level", hostapd_cli_cmd_level },
483 { "license", hostapd_cli_cmd_license },
484 { "quit", hostapd_cli_cmd_quit },
485 { NULL, NULL }
486};
487
488
489static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
490{
491 struct hostapd_cli_cmd *cmd, *match = NULL;
492 int count;
493
494 count = 0;
495 cmd = hostapd_cli_commands;
496 while (cmd->cmd) {
497 if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0) {
498 match = cmd;
499 count++;
500 }
501 cmd++;
502 }
503
504 if (count > 1) {
505 printf("Ambiguous command '%s'; possible commands:", argv[0]);
506 cmd = hostapd_cli_commands;
507 while (cmd->cmd) {
508 if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) ==
509 0) {
510 printf(" %s", cmd->cmd);
511 }
512 cmd++;
513 }
514 printf("\n");
515 } else if (count == 0) {
516 printf("Unknown command '%s'\n", argv[0]);
517 } else {
518 match->handler(ctrl, argc - 1, &argv[1]);
519 }
520}
521
522
523static void hostapd_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read)
524{
525 int first = 1;
526 if (ctrl_conn == NULL)
527 return;
528 while (wpa_ctrl_pending(ctrl)) {
529 char buf[256];
530 size_t len = sizeof(buf) - 1;
531 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
532 buf[len] = '\0';
533 if (in_read && first)
534 printf("\n");
535 first = 0;
536 printf("%s\n", buf);
537 } else {
538 printf("Could not read pending message.\n");
539 break;
540 }
541 }
542}
543
544
545static void hostapd_cli_interactive(void)
546{
547 const int max_args = 10;
548 char cmd[256], *res, *argv[max_args], *pos;
549 int argc;
550
551 printf("\nInteractive mode\n\n");
552
553 do {
554 hostapd_cli_recv_pending(ctrl_conn, 0);
555 printf("> ");
1cc84c1c 556 alarm(ping_interval);
6fc6879b
JM
557 res = fgets(cmd, sizeof(cmd), stdin);
558 alarm(0);
559 if (res == NULL)
560 break;
561 pos = cmd;
562 while (*pos != '\0') {
563 if (*pos == '\n') {
564 *pos = '\0';
565 break;
566 }
567 pos++;
568 }
569 argc = 0;
570 pos = cmd;
571 for (;;) {
572 while (*pos == ' ')
573 pos++;
574 if (*pos == '\0')
575 break;
576 argv[argc] = pos;
577 argc++;
578 if (argc == max_args)
579 break;
580 while (*pos != '\0' && *pos != ' ')
581 pos++;
582 if (*pos == ' ')
583 *pos++ = '\0';
584 }
585 if (argc)
586 wpa_request(ctrl_conn, argc, argv);
587 } while (!hostapd_cli_quit);
588}
589
590
591static void hostapd_cli_terminate(int sig)
592{
593 hostapd_cli_close_connection();
594 exit(0);
595}
596
597
598static void hostapd_cli_alarm(int sig)
599{
600 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
601 printf("Connection to hostapd lost - trying to reconnect\n");
602 hostapd_cli_close_connection();
603 }
604 if (!ctrl_conn) {
605 ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
606 if (ctrl_conn) {
607 printf("Connection to hostapd re-established\n");
608 if (wpa_ctrl_attach(ctrl_conn) == 0) {
609 hostapd_cli_attached = 1;
610 } else {
611 printf("Warning: Failed to attach to "
612 "hostapd.\n");
613 }
614 }
615 }
616 if (ctrl_conn)
617 hostapd_cli_recv_pending(ctrl_conn, 1);
1cc84c1c 618 alarm(ping_interval);
6fc6879b
JM
619}
620
621
622int main(int argc, char *argv[])
623{
624 int interactive;
625 int warning_displayed = 0;
626 int c;
627
628 for (;;) {
1cc84c1c 629 c = getopt(argc, argv, "hG:i:p:v");
6fc6879b
JM
630 if (c < 0)
631 break;
632 switch (c) {
1cc84c1c
JM
633 case 'G':
634 ping_interval = atoi(optarg);
635 break;
6fc6879b
JM
636 case 'h':
637 usage();
638 return 0;
639 case 'v':
640 printf("%s\n", hostapd_cli_version);
641 return 0;
642 case 'i':
643 free(ctrl_ifname);
644 ctrl_ifname = strdup(optarg);
645 break;
646 case 'p':
647 ctrl_iface_dir = optarg;
648 break;
649 default:
650 usage();
651 return -1;
652 }
653 }
654
655 interactive = argc == optind;
656
657 if (interactive) {
658 printf("%s\n\n%s\n\n", hostapd_cli_version,
659 hostapd_cli_license);
660 }
661
662 for (;;) {
663 if (ctrl_ifname == NULL) {
664 struct dirent *dent;
665 DIR *dir = opendir(ctrl_iface_dir);
666 if (dir) {
667 while ((dent = readdir(dir))) {
668 if (strcmp(dent->d_name, ".") == 0 ||
669 strcmp(dent->d_name, "..") == 0)
670 continue;
671 printf("Selected interface '%s'\n",
672 dent->d_name);
673 ctrl_ifname = strdup(dent->d_name);
674 break;
675 }
676 closedir(dir);
677 }
678 }
679 ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
680 if (ctrl_conn) {
681 if (warning_displayed)
682 printf("Connection established.\n");
683 break;
684 }
685
686 if (!interactive) {
687 perror("Failed to connect to hostapd - "
688 "wpa_ctrl_open");
689 return -1;
690 }
691
692 if (!warning_displayed) {
693 printf("Could not connect to hostapd - re-trying\n");
694 warning_displayed = 1;
695 }
696 sleep(1);
697 continue;
698 }
699
700 signal(SIGINT, hostapd_cli_terminate);
701 signal(SIGTERM, hostapd_cli_terminate);
702 signal(SIGALRM, hostapd_cli_alarm);
703
704 if (interactive) {
705 if (wpa_ctrl_attach(ctrl_conn) == 0) {
706 hostapd_cli_attached = 1;
707 } else {
708 printf("Warning: Failed to attach to hostapd.\n");
709 }
710 hostapd_cli_interactive();
711 } else
712 wpa_request(ctrl_conn, argc - optind, &argv[optind]);
713
714 free(ctrl_ifname);
715 hostapd_cli_close_connection();
716 return 0;
717}