2 * hostapd - command line interface for hostapd daemon
3 * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
18 #include "common/wpa_ctrl.h"
20 #include "common/version.h"
23 static const char *hostapd_cli_version =
24 "hostapd_cli v" VERSION_STR "\n"
25 "Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> and contributors";
28 static 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"
32 "Alternatively, this software may be distributed under the terms of the\n"
33 "BSD license. See README and COPYING for more details.\n";
35 static 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"
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"
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"
49 "Alternatively, this software may be distributed under the terms of the\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"
56 "1. Redistributions of source code must retain the above copyright\n"
57 " notice, this list of conditions and the following disclaimer.\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"
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"
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"
80 static const char *commands_help =
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"
86 " deauthenticate <addr> deauthenticate a station\n"
87 " disassociate <addr> disassociate a station\n"
88 #ifdef CONFIG_IEEE80211W
89 " sa_query <addr> send SA Query to a station\n"
90 #endif /* CONFIG_IEEE80211W */
92 " wps_pin <uuid> <pin> [timeout] [addr] add WPS Enrollee PIN\n"
93 " wps_check_pin <PIN> verify PIN checksum\n"
94 " wps_pbc indicate button pushed to initiate PBC\n"
96 " wps_oob <type> <path> <method> use WPS with out-of-band (UFD)\n"
97 #endif /* CONFIG_WPS_OOB */
98 " wps_ap_pin <cmd> [params..] enable/disable AP PIN\n"
99 " wps_config <SSID> <auth> <encr> <key> configure AP\n"
100 #endif /* CONFIG_WPS */
101 " get_config show current configuration\n"
102 " help show this usage help\n"
103 " interface [ifname] show interfaces/select interface\n"
104 " level <debug level> change debug level\n"
105 " license show full hostapd_cli license\n"
106 " quit exit hostapd_cli\n";
108 static struct wpa_ctrl *ctrl_conn;
109 static int hostapd_cli_quit = 0;
110 static int hostapd_cli_attached = 0;
111 static const char *ctrl_iface_dir = "/var/run/hostapd";
112 static char *ctrl_ifname = NULL;
113 static const char *pid_file = NULL;
114 static const char *action_file = NULL;
115 static int ping_interval = 5;
118 static void usage(void)
120 fprintf(stderr, "%s\n", hostapd_cli_version);
123 "usage: hostapd_cli [-p<path>] [-i<ifname>] [-hvB] "
125 " [-G<ping interval>] [command..]\n"
128 " -h help (show this usage text)\n"
129 " -v shown version information\n"
130 " -p<path> path to find control sockets (default: "
131 "/var/run/hostapd)\n"
132 " -a<file> run in daemon mode executing the action file "
135 " -B run a daemon in the background\n"
136 " -i<ifname> Interface to listen on (default: first "
137 "interface found in the\n"
144 static struct wpa_ctrl * hostapd_cli_open_connection(const char *ifname)
152 flen = strlen(ctrl_iface_dir) + strlen(ifname) + 2;
153 cfile = malloc(flen);
156 snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
158 ctrl_conn = wpa_ctrl_open(cfile);
164 static void hostapd_cli_close_connection(void)
166 if (ctrl_conn == NULL)
169 if (hostapd_cli_attached) {
170 wpa_ctrl_detach(ctrl_conn);
171 hostapd_cli_attached = 0;
173 wpa_ctrl_close(ctrl_conn);
178 static void hostapd_cli_msg_cb(char *msg, size_t len)
184 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
190 if (ctrl_conn == NULL) {
191 printf("Not connected to hostapd - command dropped.\n");
194 len = sizeof(buf) - 1;
195 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
198 printf("'%s' command timed out.\n", cmd);
200 } else if (ret < 0) {
201 printf("'%s' command failed.\n", cmd);
212 static inline int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
214 return _wpa_ctrl_command(ctrl, cmd, 1);
218 static int hostapd_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
220 return wpa_ctrl_command(ctrl, "PING");
224 static int hostapd_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
226 return wpa_ctrl_command(ctrl, "MIB");
230 static int hostapd_cli_exec(const char *program, const char *arg1,
238 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
239 cmd = os_malloc(len);
242 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
243 if (res < 0 || (size_t) res >= len) {
251 #endif /* _WIN32_WCE */
258 static void hostapd_cli_action_process(char *msg, size_t len)
264 pos = os_strchr(pos, '>');
271 hostapd_cli_exec(action_file, ctrl_ifname, pos);
275 static int hostapd_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
279 printf("Invalid 'sta' command - exactly one argument, STA "
280 "address, is required.\n");
283 snprintf(buf, sizeof(buf), "STA %s", argv[0]);
284 return wpa_ctrl_command(ctrl, buf);
288 static int hostapd_cli_cmd_new_sta(struct wpa_ctrl *ctrl, int argc,
293 printf("Invalid 'new_sta' command - exactly one argument, STA "
294 "address, is required.\n");
297 snprintf(buf, sizeof(buf), "NEW_STA %s", argv[0]);
298 return wpa_ctrl_command(ctrl, buf);
302 static int hostapd_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
307 printf("Invalid 'deauthenticate' command - exactly one "
308 "argument, STA address, is required.\n");
312 os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s %s",
315 os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s", argv[0]);
316 return wpa_ctrl_command(ctrl, buf);
320 static int hostapd_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
325 printf("Invalid 'disassociate' command - exactly one "
326 "argument, STA address, is required.\n");
330 os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s %s",
333 os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s", argv[0]);
334 return wpa_ctrl_command(ctrl, buf);
338 #ifdef CONFIG_IEEE80211W
339 static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc,
344 printf("Invalid 'sa_query' command - exactly one argument, "
345 "STA address, is required.\n");
348 snprintf(buf, sizeof(buf), "SA_QUERY %s", argv[0]);
349 return wpa_ctrl_command(ctrl, buf);
351 #endif /* CONFIG_IEEE80211W */
355 static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc,
360 printf("Invalid 'wps_pin' command - at least two arguments, "
361 "UUID and PIN, are required.\n");
365 snprintf(buf, sizeof(buf), "WPS_PIN %s %s %s %s",
366 argv[0], argv[1], argv[2], argv[3]);
368 snprintf(buf, sizeof(buf), "WPS_PIN %s %s %s",
369 argv[0], argv[1], argv[2]);
371 snprintf(buf, sizeof(buf), "WPS_PIN %s %s", argv[0], argv[1]);
372 return wpa_ctrl_command(ctrl, buf);
376 static int hostapd_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
382 if (argc != 1 && argc != 2) {
383 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
384 "- PIN to be verified\n");
389 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
392 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
394 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
395 printf("Too long WPS_CHECK_PIN command.\n");
398 return wpa_ctrl_command(ctrl, cmd);
402 static int hostapd_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc,
405 return wpa_ctrl_command(ctrl, "WPS_PBC");
409 #ifdef CONFIG_WPS_OOB
410 static int hostapd_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc,
416 if (argc != 3 && argc != 4) {
417 printf("Invalid WPS_OOB command: need three or four "
419 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
420 "- PATH: path of OOB device like '/mnt'\n"
421 "- METHOD: OOB method 'pin-e' or 'pin-r', "
423 "- DEV_NAME: (only for NFC) device name like "
429 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
430 argv[0], argv[1], argv[2]);
432 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
433 argv[0], argv[1], argv[2], argv[3]);
434 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
435 printf("Too long WPS_OOB command.\n");
438 return wpa_ctrl_command(ctrl, cmd);
440 #endif /* CONFIG_WPS_OOB */
443 static int hostapd_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
448 printf("Invalid 'wps_ap_pin' command - at least one argument "
453 snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s %s",
454 argv[0], argv[1], argv[2]);
456 snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s",
459 snprintf(buf, sizeof(buf), "WPS_AP_PIN %s", argv[0]);
460 return wpa_ctrl_command(ctrl, buf);
464 static int hostapd_cli_cmd_wps_config(struct wpa_ctrl *ctrl, int argc,
468 char ssid_hex[2 * 32 + 1];
469 char key_hex[2 * 64 + 1];
473 printf("Invalid 'wps_config' command - at least two arguments "
479 for (i = 0; i < 32; i++) {
480 if (argv[0][i] == '\0')
482 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[0][i]);
487 for (i = 0; i < 64; i++) {
488 if (argv[3][i] == '\0')
490 os_snprintf(&key_hex[i * 2], 3, "%02x",
496 snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s %s %s",
497 ssid_hex, argv[1], argv[2], key_hex);
499 snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s %s",
500 ssid_hex, argv[1], argv[2]);
502 snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s",
504 return wpa_ctrl_command(ctrl, buf);
506 #endif /* CONFIG_WPS */
509 static int hostapd_cli_cmd_get_config(struct wpa_ctrl *ctrl, int argc,
512 return wpa_ctrl_command(ctrl, "GET_CONFIG");
516 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
517 char *addr, size_t addr_len)
519 char buf[4096], *pos;
523 if (ctrl_conn == NULL) {
524 printf("Not connected to hostapd - command dropped.\n");
527 len = sizeof(buf) - 1;
528 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
531 printf("'%s' command timed out.\n", cmd);
533 } else if (ret < 0) {
534 printf("'%s' command failed.\n", cmd);
539 if (memcmp(buf, "FAIL", 4) == 0)
544 while (*pos != '\0' && *pos != '\n')
547 os_strlcpy(addr, buf, addr_len);
552 static int hostapd_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc,
555 char addr[32], cmd[64];
557 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
560 snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
561 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
567 static int hostapd_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
569 printf("%s", commands_help);
574 static int hostapd_cli_cmd_license(struct wpa_ctrl *ctrl, int argc,
577 printf("%s\n\n%s\n", hostapd_cli_version, hostapd_cli_full_license);
582 static int hostapd_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
584 hostapd_cli_quit = 1;
589 static int hostapd_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
593 printf("Invalid LEVEL command: needs one argument (debug "
597 snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
598 return wpa_ctrl_command(ctrl, cmd);
602 static void hostapd_cli_list_interfaces(struct wpa_ctrl *ctrl)
607 dir = opendir(ctrl_iface_dir);
609 printf("Control interface directory '%s' could not be "
610 "openned.\n", ctrl_iface_dir);
614 printf("Available interfaces:\n");
615 while ((dent = readdir(dir))) {
616 if (strcmp(dent->d_name, ".") == 0 ||
617 strcmp(dent->d_name, "..") == 0)
619 printf("%s\n", dent->d_name);
625 static int hostapd_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc,
629 hostapd_cli_list_interfaces(ctrl);
633 hostapd_cli_close_connection();
635 ctrl_ifname = strdup(argv[0]);
637 if (hostapd_cli_open_connection(ctrl_ifname)) {
638 printf("Connected to interface '%s.\n", ctrl_ifname);
639 if (wpa_ctrl_attach(ctrl_conn) == 0) {
640 hostapd_cli_attached = 1;
642 printf("Warning: Failed to attach to "
646 printf("Could not connect to interface '%s' - re-trying\n",
653 static int hostapd_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
659 printf("Invalid SET command: needs two arguments (variable "
660 "name and value)\n");
664 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
665 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
666 printf("Too long SET command.\n");
669 return wpa_ctrl_command(ctrl, cmd);
673 struct hostapd_cli_cmd {
675 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
678 static struct hostapd_cli_cmd hostapd_cli_commands[] = {
679 { "ping", hostapd_cli_cmd_ping },
680 { "mib", hostapd_cli_cmd_mib },
681 { "sta", hostapd_cli_cmd_sta },
682 { "all_sta", hostapd_cli_cmd_all_sta },
683 { "new_sta", hostapd_cli_cmd_new_sta },
684 { "deauthenticate", hostapd_cli_cmd_deauthenticate },
685 { "disassociate", hostapd_cli_cmd_disassociate },
686 #ifdef CONFIG_IEEE80211W
687 { "sa_query", hostapd_cli_cmd_sa_query },
688 #endif /* CONFIG_IEEE80211W */
690 { "wps_pin", hostapd_cli_cmd_wps_pin },
691 { "wps_check_pin", hostapd_cli_cmd_wps_check_pin },
692 { "wps_pbc", hostapd_cli_cmd_wps_pbc },
693 #ifdef CONFIG_WPS_OOB
694 { "wps_oob", hostapd_cli_cmd_wps_oob },
695 #endif /* CONFIG_WPS_OOB */
696 { "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin },
697 { "wps_config", hostapd_cli_cmd_wps_config },
698 #endif /* CONFIG_WPS */
699 { "get_config", hostapd_cli_cmd_get_config },
700 { "help", hostapd_cli_cmd_help },
701 { "interface", hostapd_cli_cmd_interface },
702 { "level", hostapd_cli_cmd_level },
703 { "license", hostapd_cli_cmd_license },
704 { "quit", hostapd_cli_cmd_quit },
705 { "set", hostapd_cli_cmd_set },
710 static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
712 struct hostapd_cli_cmd *cmd, *match = NULL;
716 cmd = hostapd_cli_commands;
718 if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0) {
726 printf("Ambiguous command '%s'; possible commands:", argv[0]);
727 cmd = hostapd_cli_commands;
729 if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) ==
731 printf(" %s", cmd->cmd);
736 } else if (count == 0) {
737 printf("Unknown command '%s'\n", argv[0]);
739 match->handler(ctrl, argc - 1, &argv[1]);
744 static void hostapd_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
748 if (ctrl_conn == NULL)
750 while (wpa_ctrl_pending(ctrl)) {
752 size_t len = sizeof(buf) - 1;
753 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
756 hostapd_cli_action_process(buf, len);
758 if (in_read && first)
764 printf("Could not read pending message.\n");
771 static void hostapd_cli_interactive(void)
773 const int max_args = 10;
774 char cmd[256], *res, *argv[max_args], *pos;
777 printf("\nInteractive mode\n\n");
780 hostapd_cli_recv_pending(ctrl_conn, 0, 0);
782 alarm(ping_interval);
783 res = fgets(cmd, sizeof(cmd), stdin);
788 while (*pos != '\0') {
804 if (argc == max_args)
806 while (*pos != '\0' && *pos != ' ')
812 wpa_request(ctrl_conn, argc, argv);
813 } while (!hostapd_cli_quit);
817 static void hostapd_cli_cleanup(void)
819 hostapd_cli_close_connection();
821 os_daemonize_terminate(pid_file);
827 static void hostapd_cli_terminate(int sig)
829 hostapd_cli_cleanup();
834 static void hostapd_cli_alarm(int sig)
836 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
837 printf("Connection to hostapd lost - trying to reconnect\n");
838 hostapd_cli_close_connection();
841 ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
843 printf("Connection to hostapd re-established\n");
844 if (wpa_ctrl_attach(ctrl_conn) == 0) {
845 hostapd_cli_attached = 1;
847 printf("Warning: Failed to attach to "
853 hostapd_cli_recv_pending(ctrl_conn, 1, 0);
854 alarm(ping_interval);
858 static void hostapd_cli_action(struct wpa_ctrl *ctrl)
866 fd = wpa_ctrl_get_fd(ctrl);
868 while (!hostapd_cli_quit) {
871 tv.tv_sec = ping_interval;
873 res = select(fd + 1, &rfds, NULL, NULL, &tv);
874 if (res < 0 && errno != EINTR) {
879 if (FD_ISSET(fd, &rfds))
880 hostapd_cli_recv_pending(ctrl, 0, 1);
882 len = sizeof(buf) - 1;
883 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
884 hostapd_cli_action_process) < 0 ||
885 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
886 printf("hostapd did not reply to PING "
887 "command - exiting\n");
895 int main(int argc, char *argv[])
898 int warning_displayed = 0;
902 if (os_program_init())
906 c = getopt(argc, argv, "a:BhG:i:p:v");
911 action_file = optarg;
917 ping_interval = atoi(optarg);
923 printf("%s\n", hostapd_cli_version);
926 os_free(ctrl_ifname);
927 ctrl_ifname = os_strdup(optarg);
930 ctrl_iface_dir = optarg;
938 interactive = (argc == optind) && (action_file == NULL);
941 printf("%s\n\n%s\n\n", hostapd_cli_version,
942 hostapd_cli_license);
946 if (ctrl_ifname == NULL) {
948 DIR *dir = opendir(ctrl_iface_dir);
950 while ((dent = readdir(dir))) {
951 if (os_strcmp(dent->d_name, ".") == 0
953 os_strcmp(dent->d_name, "..") == 0)
955 printf("Selected interface '%s'\n",
957 ctrl_ifname = os_strdup(dent->d_name);
963 ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
965 if (warning_displayed)
966 printf("Connection established.\n");
971 perror("Failed to connect to hostapd - "
976 if (!warning_displayed) {
977 printf("Could not connect to hostapd - re-trying\n");
978 warning_displayed = 1;
984 signal(SIGINT, hostapd_cli_terminate);
985 signal(SIGTERM, hostapd_cli_terminate);
986 signal(SIGALRM, hostapd_cli_alarm);
988 if (interactive || action_file) {
989 if (wpa_ctrl_attach(ctrl_conn) == 0) {
990 hostapd_cli_attached = 1;
992 printf("Warning: Failed to attach to hostapd.\n");
998 if (daemonize && os_daemonize(pid_file))
1002 hostapd_cli_interactive();
1003 else if (action_file)
1004 hostapd_cli_action(ctrl_conn);
1006 wpa_request(ctrl_conn, argc - optind, &argv[optind]);
1008 os_free(ctrl_ifname);
1009 hostapd_cli_cleanup();