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_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
226 return wpa_ctrl_command(ctrl, "RELOG");
230 static int hostapd_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
232 return wpa_ctrl_command(ctrl, "MIB");
236 static int hostapd_cli_exec(const char *program, const char *arg1,
244 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
245 cmd = os_malloc(len);
248 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
249 if (res < 0 || (size_t) res >= len) {
257 #endif /* _WIN32_WCE */
264 static void hostapd_cli_action_process(char *msg, size_t len)
270 pos = os_strchr(pos, '>');
277 hostapd_cli_exec(action_file, ctrl_ifname, pos);
281 static int hostapd_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
285 printf("Invalid 'sta' command - exactly one argument, STA "
286 "address, is required.\n");
289 snprintf(buf, sizeof(buf), "STA %s", argv[0]);
290 return wpa_ctrl_command(ctrl, buf);
294 static int hostapd_cli_cmd_new_sta(struct wpa_ctrl *ctrl, int argc,
299 printf("Invalid 'new_sta' command - exactly one argument, STA "
300 "address, is required.\n");
303 snprintf(buf, sizeof(buf), "NEW_STA %s", argv[0]);
304 return wpa_ctrl_command(ctrl, buf);
308 static int hostapd_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
313 printf("Invalid 'deauthenticate' command - exactly one "
314 "argument, STA address, is required.\n");
318 os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s %s",
321 os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s", argv[0]);
322 return wpa_ctrl_command(ctrl, buf);
326 static int hostapd_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
331 printf("Invalid 'disassociate' command - exactly one "
332 "argument, STA address, is required.\n");
336 os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s %s",
339 os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s", argv[0]);
340 return wpa_ctrl_command(ctrl, buf);
344 #ifdef CONFIG_IEEE80211W
345 static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc,
350 printf("Invalid 'sa_query' command - exactly one argument, "
351 "STA address, is required.\n");
354 snprintf(buf, sizeof(buf), "SA_QUERY %s", argv[0]);
355 return wpa_ctrl_command(ctrl, buf);
357 #endif /* CONFIG_IEEE80211W */
361 static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc,
366 printf("Invalid 'wps_pin' command - at least two arguments, "
367 "UUID and PIN, are required.\n");
371 snprintf(buf, sizeof(buf), "WPS_PIN %s %s %s %s",
372 argv[0], argv[1], argv[2], argv[3]);
374 snprintf(buf, sizeof(buf), "WPS_PIN %s %s %s",
375 argv[0], argv[1], argv[2]);
377 snprintf(buf, sizeof(buf), "WPS_PIN %s %s", argv[0], argv[1]);
378 return wpa_ctrl_command(ctrl, buf);
382 static int hostapd_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
388 if (argc != 1 && argc != 2) {
389 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
390 "- PIN to be verified\n");
395 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
398 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
400 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
401 printf("Too long WPS_CHECK_PIN command.\n");
404 return wpa_ctrl_command(ctrl, cmd);
408 static int hostapd_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc,
411 return wpa_ctrl_command(ctrl, "WPS_PBC");
415 #ifdef CONFIG_WPS_OOB
416 static int hostapd_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc,
422 if (argc != 3 && argc != 4) {
423 printf("Invalid WPS_OOB command: need three or four "
425 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
426 "- PATH: path of OOB device like '/mnt'\n"
427 "- METHOD: OOB method 'pin-e' or 'pin-r', "
429 "- DEV_NAME: (only for NFC) device name like "
435 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
436 argv[0], argv[1], argv[2]);
438 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
439 argv[0], argv[1], argv[2], argv[3]);
440 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
441 printf("Too long WPS_OOB command.\n");
444 return wpa_ctrl_command(ctrl, cmd);
446 #endif /* CONFIG_WPS_OOB */
449 static int hostapd_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
454 printf("Invalid 'wps_ap_pin' command - at least one argument "
459 snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s %s",
460 argv[0], argv[1], argv[2]);
462 snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s",
465 snprintf(buf, sizeof(buf), "WPS_AP_PIN %s", argv[0]);
466 return wpa_ctrl_command(ctrl, buf);
470 static int hostapd_cli_cmd_wps_config(struct wpa_ctrl *ctrl, int argc,
474 char ssid_hex[2 * 32 + 1];
475 char key_hex[2 * 64 + 1];
479 printf("Invalid 'wps_config' command - at least two arguments "
485 for (i = 0; i < 32; i++) {
486 if (argv[0][i] == '\0')
488 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[0][i]);
493 for (i = 0; i < 64; i++) {
494 if (argv[3][i] == '\0')
496 os_snprintf(&key_hex[i * 2], 3, "%02x",
502 snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s %s %s",
503 ssid_hex, argv[1], argv[2], key_hex);
505 snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s %s",
506 ssid_hex, argv[1], argv[2]);
508 snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s",
510 return wpa_ctrl_command(ctrl, buf);
512 #endif /* CONFIG_WPS */
515 static int hostapd_cli_cmd_get_config(struct wpa_ctrl *ctrl, int argc,
518 return wpa_ctrl_command(ctrl, "GET_CONFIG");
522 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
523 char *addr, size_t addr_len)
525 char buf[4096], *pos;
529 if (ctrl_conn == NULL) {
530 printf("Not connected to hostapd - command dropped.\n");
533 len = sizeof(buf) - 1;
534 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
537 printf("'%s' command timed out.\n", cmd);
539 } else if (ret < 0) {
540 printf("'%s' command failed.\n", cmd);
545 if (memcmp(buf, "FAIL", 4) == 0)
550 while (*pos != '\0' && *pos != '\n')
553 os_strlcpy(addr, buf, addr_len);
558 static int hostapd_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc,
561 char addr[32], cmd[64];
563 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
566 snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
567 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
573 static int hostapd_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
575 printf("%s", commands_help);
580 static int hostapd_cli_cmd_license(struct wpa_ctrl *ctrl, int argc,
583 printf("%s\n\n%s\n", hostapd_cli_version, hostapd_cli_full_license);
588 static int hostapd_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
590 hostapd_cli_quit = 1;
595 static int hostapd_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
599 printf("Invalid LEVEL command: needs one argument (debug "
603 snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
604 return wpa_ctrl_command(ctrl, cmd);
608 static void hostapd_cli_list_interfaces(struct wpa_ctrl *ctrl)
613 dir = opendir(ctrl_iface_dir);
615 printf("Control interface directory '%s' could not be "
616 "openned.\n", ctrl_iface_dir);
620 printf("Available interfaces:\n");
621 while ((dent = readdir(dir))) {
622 if (strcmp(dent->d_name, ".") == 0 ||
623 strcmp(dent->d_name, "..") == 0)
625 printf("%s\n", dent->d_name);
631 static int hostapd_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc,
635 hostapd_cli_list_interfaces(ctrl);
639 hostapd_cli_close_connection();
641 ctrl_ifname = strdup(argv[0]);
643 if (hostapd_cli_open_connection(ctrl_ifname)) {
644 printf("Connected to interface '%s.\n", ctrl_ifname);
645 if (wpa_ctrl_attach(ctrl_conn) == 0) {
646 hostapd_cli_attached = 1;
648 printf("Warning: Failed to attach to "
652 printf("Could not connect to interface '%s' - re-trying\n",
659 static int hostapd_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
665 printf("Invalid SET command: needs two arguments (variable "
666 "name and value)\n");
670 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
671 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
672 printf("Too long SET command.\n");
675 return wpa_ctrl_command(ctrl, cmd);
679 static int hostapd_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
685 printf("Invalid GET command: needs one argument (variable "
690 res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
691 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
692 printf("Too long GET command.\n");
695 return wpa_ctrl_command(ctrl, cmd);
699 struct hostapd_cli_cmd {
701 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
704 static struct hostapd_cli_cmd hostapd_cli_commands[] = {
705 { "ping", hostapd_cli_cmd_ping },
706 { "mib", hostapd_cli_cmd_mib },
707 { "relog", hostapd_cli_cmd_relog },
708 { "sta", hostapd_cli_cmd_sta },
709 { "all_sta", hostapd_cli_cmd_all_sta },
710 { "new_sta", hostapd_cli_cmd_new_sta },
711 { "deauthenticate", hostapd_cli_cmd_deauthenticate },
712 { "disassociate", hostapd_cli_cmd_disassociate },
713 #ifdef CONFIG_IEEE80211W
714 { "sa_query", hostapd_cli_cmd_sa_query },
715 #endif /* CONFIG_IEEE80211W */
717 { "wps_pin", hostapd_cli_cmd_wps_pin },
718 { "wps_check_pin", hostapd_cli_cmd_wps_check_pin },
719 { "wps_pbc", hostapd_cli_cmd_wps_pbc },
720 #ifdef CONFIG_WPS_OOB
721 { "wps_oob", hostapd_cli_cmd_wps_oob },
722 #endif /* CONFIG_WPS_OOB */
723 { "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin },
724 { "wps_config", hostapd_cli_cmd_wps_config },
725 #endif /* CONFIG_WPS */
726 { "get_config", hostapd_cli_cmd_get_config },
727 { "help", hostapd_cli_cmd_help },
728 { "interface", hostapd_cli_cmd_interface },
729 { "level", hostapd_cli_cmd_level },
730 { "license", hostapd_cli_cmd_license },
731 { "quit", hostapd_cli_cmd_quit },
732 { "set", hostapd_cli_cmd_set },
733 { "get", hostapd_cli_cmd_get },
738 static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
740 struct hostapd_cli_cmd *cmd, *match = NULL;
744 cmd = hostapd_cli_commands;
746 if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0) {
748 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
749 /* we have an exact match */
759 printf("Ambiguous command '%s'; possible commands:", argv[0]);
760 cmd = hostapd_cli_commands;
762 if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) ==
764 printf(" %s", cmd->cmd);
769 } else if (count == 0) {
770 printf("Unknown command '%s'\n", argv[0]);
772 match->handler(ctrl, argc - 1, &argv[1]);
777 static void hostapd_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
781 if (ctrl_conn == NULL)
783 while (wpa_ctrl_pending(ctrl)) {
785 size_t len = sizeof(buf) - 1;
786 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
789 hostapd_cli_action_process(buf, len);
791 if (in_read && first)
797 printf("Could not read pending message.\n");
804 static void hostapd_cli_interactive(void)
806 const int max_args = 10;
807 char cmd[256], *res, *argv[max_args], *pos;
810 printf("\nInteractive mode\n\n");
813 hostapd_cli_recv_pending(ctrl_conn, 0, 0);
815 alarm(ping_interval);
816 res = fgets(cmd, sizeof(cmd), stdin);
821 while (*pos != '\0') {
837 if (argc == max_args)
839 while (*pos != '\0' && *pos != ' ')
845 wpa_request(ctrl_conn, argc, argv);
846 } while (!hostapd_cli_quit);
850 static void hostapd_cli_cleanup(void)
852 hostapd_cli_close_connection();
854 os_daemonize_terminate(pid_file);
860 static void hostapd_cli_terminate(int sig)
862 hostapd_cli_cleanup();
867 static void hostapd_cli_alarm(int sig)
869 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
870 printf("Connection to hostapd lost - trying to reconnect\n");
871 hostapd_cli_close_connection();
874 ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
876 printf("Connection to hostapd re-established\n");
877 if (wpa_ctrl_attach(ctrl_conn) == 0) {
878 hostapd_cli_attached = 1;
880 printf("Warning: Failed to attach to "
886 hostapd_cli_recv_pending(ctrl_conn, 1, 0);
887 alarm(ping_interval);
891 static void hostapd_cli_action(struct wpa_ctrl *ctrl)
899 fd = wpa_ctrl_get_fd(ctrl);
901 while (!hostapd_cli_quit) {
904 tv.tv_sec = ping_interval;
906 res = select(fd + 1, &rfds, NULL, NULL, &tv);
907 if (res < 0 && errno != EINTR) {
912 if (FD_ISSET(fd, &rfds))
913 hostapd_cli_recv_pending(ctrl, 0, 1);
915 len = sizeof(buf) - 1;
916 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
917 hostapd_cli_action_process) < 0 ||
918 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
919 printf("hostapd did not reply to PING "
920 "command - exiting\n");
928 int main(int argc, char *argv[])
931 int warning_displayed = 0;
935 if (os_program_init())
939 c = getopt(argc, argv, "a:BhG:i:p:v");
944 action_file = optarg;
950 ping_interval = atoi(optarg);
956 printf("%s\n", hostapd_cli_version);
959 os_free(ctrl_ifname);
960 ctrl_ifname = os_strdup(optarg);
963 ctrl_iface_dir = optarg;
971 interactive = (argc == optind) && (action_file == NULL);
974 printf("%s\n\n%s\n\n", hostapd_cli_version,
975 hostapd_cli_license);
979 if (ctrl_ifname == NULL) {
981 DIR *dir = opendir(ctrl_iface_dir);
983 while ((dent = readdir(dir))) {
984 if (os_strcmp(dent->d_name, ".") == 0
986 os_strcmp(dent->d_name, "..") == 0)
988 printf("Selected interface '%s'\n",
990 ctrl_ifname = os_strdup(dent->d_name);
996 ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
998 if (warning_displayed)
999 printf("Connection established.\n");
1004 perror("Failed to connect to hostapd - "
1009 if (!warning_displayed) {
1010 printf("Could not connect to hostapd - re-trying\n");
1011 warning_displayed = 1;
1017 signal(SIGINT, hostapd_cli_terminate);
1018 signal(SIGTERM, hostapd_cli_terminate);
1019 signal(SIGALRM, hostapd_cli_alarm);
1021 if (interactive || action_file) {
1022 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1023 hostapd_cli_attached = 1;
1025 printf("Warning: Failed to attach to hostapd.\n");
1031 if (daemonize && os_daemonize(pid_file))
1035 hostapd_cli_interactive();
1036 else if (action_file)
1037 hostapd_cli_action(ctrl_conn);
1039 wpa_request(ctrl_conn, argc - optind, &argv[optind]);
1041 os_free(ctrl_ifname);
1042 hostapd_cli_cleanup();