2 * hostapd - command line interface for hostapd daemon
3 * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
12 #include "common/wpa_ctrl.h"
13 #include "utils/common.h"
14 #include "utils/eloop.h"
15 #include "utils/edit.h"
16 #include "common/version.h"
19 static const char *hostapd_cli_version =
20 "hostapd_cli v" VERSION_STR "\n"
21 "Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> and contributors";
24 static const char *hostapd_cli_license =
25 "This software may be distributed under the terms of the BSD license.\n"
26 "See README for more details.\n";
28 static const char *hostapd_cli_full_license =
29 "This software may be distributed under the terms of the BSD license.\n"
31 "Redistribution and use in source and binary forms, with or without\n"
32 "modification, are permitted provided that the following conditions are\n"
35 "1. Redistributions of source code must retain the above copyright\n"
36 " notice, this list of conditions and the following disclaimer.\n"
38 "2. Redistributions in binary form must reproduce the above copyright\n"
39 " notice, this list of conditions and the following disclaimer in the\n"
40 " documentation and/or other materials provided with the distribution.\n"
42 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
43 " names of its contributors may be used to endorse or promote products\n"
44 " derived from this software without specific prior written permission.\n"
46 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
47 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
48 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
49 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
50 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
51 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
52 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
53 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
54 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
55 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
56 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
59 static const char *commands_help =
61 " mib get MIB variables (dot1x, dot11, radius)\n"
62 " sta <addr> get MIB variables for one station\n"
63 " all_sta get MIB variables for all stations\n"
64 " new_sta <addr> add a new station\n"
65 " deauthenticate <addr> deauthenticate a station\n"
66 " disassociate <addr> disassociate a station\n"
67 #ifdef CONFIG_IEEE80211W
68 " sa_query <addr> send SA Query to a station\n"
69 #endif /* CONFIG_IEEE80211W */
71 " wps_pin <uuid> <pin> [timeout] [addr] add WPS Enrollee PIN\n"
72 " wps_check_pin <PIN> verify PIN checksum\n"
73 " wps_pbc indicate button pushed to initiate PBC\n"
75 " wps_oob <type> <path> <method> use WPS with out-of-band (UFD)\n"
76 #endif /* CONFIG_WPS_OOB */
77 " wps_ap_pin <cmd> [params..] enable/disable AP PIN\n"
78 " wps_config <SSID> <auth> <encr> <key> configure AP\n"
79 #endif /* CONFIG_WPS */
80 " get_config show current configuration\n"
81 " help show this usage help\n"
82 " interface [ifname] show interfaces/select interface\n"
83 " level <debug level> change debug level\n"
84 " license show full hostapd_cli license\n"
85 " quit exit hostapd_cli\n";
87 static struct wpa_ctrl *ctrl_conn;
88 static int hostapd_cli_quit = 0;
89 static int hostapd_cli_attached = 0;
90 static const char *ctrl_iface_dir = "/var/run/hostapd";
91 static char *ctrl_ifname = NULL;
92 static const char *pid_file = NULL;
93 static const char *action_file = NULL;
94 static int ping_interval = 5;
95 static int interactive = 0;
98 static void usage(void)
100 fprintf(stderr, "%s\n", hostapd_cli_version);
103 "usage: hostapd_cli [-p<path>] [-i<ifname>] [-hvB] "
105 " [-G<ping interval>] [command..]\n"
108 " -h help (show this usage text)\n"
109 " -v shown version information\n"
110 " -p<path> path to find control sockets (default: "
111 "/var/run/hostapd)\n"
112 " -a<file> run in daemon mode executing the action file "
115 " -B run a daemon in the background\n"
116 " -i<ifname> Interface to listen on (default: first "
117 "interface found in the\n"
124 static struct wpa_ctrl * hostapd_cli_open_connection(const char *ifname)
132 flen = strlen(ctrl_iface_dir) + strlen(ifname) + 2;
133 cfile = malloc(flen);
136 snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
138 ctrl_conn = wpa_ctrl_open(cfile);
144 static void hostapd_cli_close_connection(void)
146 if (ctrl_conn == NULL)
149 if (hostapd_cli_attached) {
150 wpa_ctrl_detach(ctrl_conn);
151 hostapd_cli_attached = 0;
153 wpa_ctrl_close(ctrl_conn);
158 static void hostapd_cli_msg_cb(char *msg, size_t len)
164 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
170 if (ctrl_conn == NULL) {
171 printf("Not connected to hostapd - command dropped.\n");
174 len = sizeof(buf) - 1;
175 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
178 printf("'%s' command timed out.\n", cmd);
180 } else if (ret < 0) {
181 printf("'%s' command failed.\n", cmd);
192 static inline int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
194 return _wpa_ctrl_command(ctrl, cmd, 1);
198 static int hostapd_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
200 return wpa_ctrl_command(ctrl, "PING");
204 static int hostapd_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
206 return wpa_ctrl_command(ctrl, "RELOG");
210 static int hostapd_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
212 return wpa_ctrl_command(ctrl, "MIB");
216 static int hostapd_cli_exec(const char *program, const char *arg1,
224 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
225 cmd = os_malloc(len);
228 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
229 if (res < 0 || (size_t) res >= len) {
237 #endif /* _WIN32_WCE */
244 static void hostapd_cli_action_process(char *msg, size_t len)
250 pos = os_strchr(pos, '>');
257 hostapd_cli_exec(action_file, ctrl_ifname, pos);
261 static int hostapd_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
265 printf("Invalid 'sta' command - exactly one argument, STA "
266 "address, is required.\n");
269 snprintf(buf, sizeof(buf), "STA %s", argv[0]);
270 return wpa_ctrl_command(ctrl, buf);
274 static int hostapd_cli_cmd_new_sta(struct wpa_ctrl *ctrl, int argc,
279 printf("Invalid 'new_sta' command - exactly one argument, STA "
280 "address, is required.\n");
283 snprintf(buf, sizeof(buf), "NEW_STA %s", argv[0]);
284 return wpa_ctrl_command(ctrl, buf);
288 static int hostapd_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
293 printf("Invalid 'deauthenticate' command - exactly one "
294 "argument, STA address, is required.\n");
298 os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s %s",
301 os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s", argv[0]);
302 return wpa_ctrl_command(ctrl, buf);
306 static int hostapd_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
311 printf("Invalid 'disassociate' command - exactly one "
312 "argument, STA address, is required.\n");
316 os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s %s",
319 os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s", argv[0]);
320 return wpa_ctrl_command(ctrl, buf);
324 #ifdef CONFIG_IEEE80211W
325 static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc,
330 printf("Invalid 'sa_query' command - exactly one argument, "
331 "STA address, is required.\n");
334 snprintf(buf, sizeof(buf), "SA_QUERY %s", argv[0]);
335 return wpa_ctrl_command(ctrl, buf);
337 #endif /* CONFIG_IEEE80211W */
341 static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc,
346 printf("Invalid 'wps_pin' command - at least two arguments, "
347 "UUID and PIN, are required.\n");
351 snprintf(buf, sizeof(buf), "WPS_PIN %s %s %s %s",
352 argv[0], argv[1], argv[2], argv[3]);
354 snprintf(buf, sizeof(buf), "WPS_PIN %s %s %s",
355 argv[0], argv[1], argv[2]);
357 snprintf(buf, sizeof(buf), "WPS_PIN %s %s", argv[0], argv[1]);
358 return wpa_ctrl_command(ctrl, buf);
362 static int hostapd_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
368 if (argc != 1 && argc != 2) {
369 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
370 "- PIN to be verified\n");
375 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
378 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
380 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
381 printf("Too long WPS_CHECK_PIN command.\n");
384 return wpa_ctrl_command(ctrl, cmd);
388 static int hostapd_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc,
391 return wpa_ctrl_command(ctrl, "WPS_PBC");
395 static int hostapd_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
398 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
402 #ifdef CONFIG_WPS_OOB
403 static int hostapd_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc,
409 if (argc != 3 && argc != 4) {
410 printf("Invalid WPS_OOB command: need three or four "
412 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
413 "- PATH: path of OOB device like '/mnt'\n"
414 "- METHOD: OOB method 'pin-e' or 'pin-r', "
416 "- DEV_NAME: (only for NFC) device name like "
422 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
423 argv[0], argv[1], argv[2]);
425 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
426 argv[0], argv[1], argv[2], argv[3]);
427 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
428 printf("Too long WPS_OOB command.\n");
431 return wpa_ctrl_command(ctrl, cmd);
433 #endif /* CONFIG_WPS_OOB */
436 static int hostapd_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
441 printf("Invalid 'wps_ap_pin' command - at least one argument "
446 snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s %s",
447 argv[0], argv[1], argv[2]);
449 snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s",
452 snprintf(buf, sizeof(buf), "WPS_AP_PIN %s", argv[0]);
453 return wpa_ctrl_command(ctrl, buf);
457 static int hostapd_cli_cmd_wps_config(struct wpa_ctrl *ctrl, int argc,
461 char ssid_hex[2 * 32 + 1];
462 char key_hex[2 * 64 + 1];
466 printf("Invalid 'wps_config' command - at least two arguments "
472 for (i = 0; i < 32; i++) {
473 if (argv[0][i] == '\0')
475 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[0][i]);
480 for (i = 0; i < 64; i++) {
481 if (argv[3][i] == '\0')
483 os_snprintf(&key_hex[i * 2], 3, "%02x",
489 snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s %s %s",
490 ssid_hex, argv[1], argv[2], key_hex);
492 snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s %s",
493 ssid_hex, argv[1], argv[2]);
495 snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s",
497 return wpa_ctrl_command(ctrl, buf);
499 #endif /* CONFIG_WPS */
502 static int hostapd_cli_cmd_ess_disassoc(struct wpa_ctrl *ctrl, int argc,
509 printf("Invalid 'ess_disassoc' command - two arguments (STA "
510 "addr and URL) are needed\n");
514 res = os_snprintf(buf, sizeof(buf), "ESS_DISASSOC %s %s",
516 if (res < 0 || res >= (int) sizeof(buf))
518 return wpa_ctrl_command(ctrl, buf);
522 static int hostapd_cli_cmd_get_config(struct wpa_ctrl *ctrl, int argc,
525 return wpa_ctrl_command(ctrl, "GET_CONFIG");
529 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
530 char *addr, size_t addr_len)
532 char buf[4096], *pos;
536 if (ctrl_conn == NULL) {
537 printf("Not connected to hostapd - command dropped.\n");
540 len = sizeof(buf) - 1;
541 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
544 printf("'%s' command timed out.\n", cmd);
546 } else if (ret < 0) {
547 printf("'%s' command failed.\n", cmd);
552 if (memcmp(buf, "FAIL", 4) == 0)
557 while (*pos != '\0' && *pos != '\n')
560 os_strlcpy(addr, buf, addr_len);
565 static int hostapd_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc,
568 char addr[32], cmd[64];
570 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
573 snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
574 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
580 static int hostapd_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
582 printf("%s", commands_help);
587 static int hostapd_cli_cmd_license(struct wpa_ctrl *ctrl, int argc,
590 printf("%s\n\n%s\n", hostapd_cli_version, hostapd_cli_full_license);
595 static int hostapd_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
597 hostapd_cli_quit = 1;
604 static int hostapd_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
608 printf("Invalid LEVEL command: needs one argument (debug "
612 snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
613 return wpa_ctrl_command(ctrl, cmd);
617 static void hostapd_cli_list_interfaces(struct wpa_ctrl *ctrl)
622 dir = opendir(ctrl_iface_dir);
624 printf("Control interface directory '%s' could not be "
625 "openned.\n", ctrl_iface_dir);
629 printf("Available interfaces:\n");
630 while ((dent = readdir(dir))) {
631 if (strcmp(dent->d_name, ".") == 0 ||
632 strcmp(dent->d_name, "..") == 0)
634 printf("%s\n", dent->d_name);
640 static int hostapd_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc,
644 hostapd_cli_list_interfaces(ctrl);
648 hostapd_cli_close_connection();
650 ctrl_ifname = strdup(argv[0]);
652 if (hostapd_cli_open_connection(ctrl_ifname)) {
653 printf("Connected to interface '%s.\n", ctrl_ifname);
654 if (wpa_ctrl_attach(ctrl_conn) == 0) {
655 hostapd_cli_attached = 1;
657 printf("Warning: Failed to attach to "
661 printf("Could not connect to interface '%s' - re-trying\n",
668 static int hostapd_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
674 printf("Invalid SET command: needs two arguments (variable "
675 "name and value)\n");
679 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
680 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
681 printf("Too long SET command.\n");
684 return wpa_ctrl_command(ctrl, cmd);
688 static int hostapd_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
694 printf("Invalid GET command: needs one argument (variable "
699 res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
700 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
701 printf("Too long GET command.\n");
704 return wpa_ctrl_command(ctrl, cmd);
708 struct hostapd_cli_cmd {
710 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
713 static struct hostapd_cli_cmd hostapd_cli_commands[] = {
714 { "ping", hostapd_cli_cmd_ping },
715 { "mib", hostapd_cli_cmd_mib },
716 { "relog", hostapd_cli_cmd_relog },
717 { "sta", hostapd_cli_cmd_sta },
718 { "all_sta", hostapd_cli_cmd_all_sta },
719 { "new_sta", hostapd_cli_cmd_new_sta },
720 { "deauthenticate", hostapd_cli_cmd_deauthenticate },
721 { "disassociate", hostapd_cli_cmd_disassociate },
722 #ifdef CONFIG_IEEE80211W
723 { "sa_query", hostapd_cli_cmd_sa_query },
724 #endif /* CONFIG_IEEE80211W */
726 { "wps_pin", hostapd_cli_cmd_wps_pin },
727 { "wps_check_pin", hostapd_cli_cmd_wps_check_pin },
728 { "wps_pbc", hostapd_cli_cmd_wps_pbc },
729 { "wps_cancel", hostapd_cli_cmd_wps_cancel },
730 #ifdef CONFIG_WPS_OOB
731 { "wps_oob", hostapd_cli_cmd_wps_oob },
732 #endif /* CONFIG_WPS_OOB */
733 { "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin },
734 { "wps_config", hostapd_cli_cmd_wps_config },
735 #endif /* CONFIG_WPS */
736 { "ess_disassoc", hostapd_cli_cmd_ess_disassoc },
737 { "get_config", hostapd_cli_cmd_get_config },
738 { "help", hostapd_cli_cmd_help },
739 { "interface", hostapd_cli_cmd_interface },
740 { "level", hostapd_cli_cmd_level },
741 { "license", hostapd_cli_cmd_license },
742 { "quit", hostapd_cli_cmd_quit },
743 { "set", hostapd_cli_cmd_set },
744 { "get", hostapd_cli_cmd_get },
749 static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
751 struct hostapd_cli_cmd *cmd, *match = NULL;
755 cmd = hostapd_cli_commands;
757 if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0) {
759 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
760 /* we have an exact match */
770 printf("Ambiguous command '%s'; possible commands:", argv[0]);
771 cmd = hostapd_cli_commands;
773 if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) ==
775 printf(" %s", cmd->cmd);
780 } else if (count == 0) {
781 printf("Unknown command '%s'\n", argv[0]);
783 match->handler(ctrl, argc - 1, &argv[1]);
788 static void hostapd_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
792 if (ctrl_conn == NULL)
794 while (wpa_ctrl_pending(ctrl)) {
796 size_t len = sizeof(buf) - 1;
797 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
800 hostapd_cli_action_process(buf, len);
802 if (in_read && first)
808 printf("Could not read pending message.\n");
817 static int tokenize_cmd(char *cmd, char *argv[])
830 if (argc == max_args)
833 char *pos2 = os_strrchr(pos, '"');
837 while (*pos != '\0' && *pos != ' ')
847 static void hostapd_cli_ping(void *eloop_ctx, void *timeout_ctx)
849 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
850 printf("Connection to hostapd lost - trying to reconnect\n");
851 hostapd_cli_close_connection();
854 ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
856 printf("Connection to hostapd re-established\n");
857 if (wpa_ctrl_attach(ctrl_conn) == 0) {
858 hostapd_cli_attached = 1;
860 printf("Warning: Failed to attach to "
866 hostapd_cli_recv_pending(ctrl_conn, 1, 0);
867 eloop_register_timeout(ping_interval, 0, hostapd_cli_ping, NULL, NULL);
871 static void hostapd_cli_eloop_terminate(int sig, void *signal_ctx)
877 static void hostapd_cli_edit_cmd_cb(void *ctx, char *cmd)
879 char *argv[max_args];
881 argc = tokenize_cmd(cmd, argv);
883 wpa_request(ctrl_conn, argc, argv);
887 static void hostapd_cli_edit_eof_cb(void *ctx)
893 static void hostapd_cli_interactive(void)
895 printf("\nInteractive mode\n\n");
897 eloop_register_signal_terminate(hostapd_cli_eloop_terminate, NULL);
898 edit_init(hostapd_cli_edit_cmd_cb, hostapd_cli_edit_eof_cb,
900 eloop_register_timeout(ping_interval, 0, hostapd_cli_ping, NULL, NULL);
904 edit_deinit(NULL, NULL);
905 eloop_cancel_timeout(hostapd_cli_ping, NULL, NULL);
909 static void hostapd_cli_cleanup(void)
911 hostapd_cli_close_connection();
913 os_daemonize_terminate(pid_file);
919 static void hostapd_cli_action(struct wpa_ctrl *ctrl)
927 fd = wpa_ctrl_get_fd(ctrl);
929 while (!hostapd_cli_quit) {
932 tv.tv_sec = ping_interval;
934 res = select(fd + 1, &rfds, NULL, NULL, &tv);
935 if (res < 0 && errno != EINTR) {
940 if (FD_ISSET(fd, &rfds))
941 hostapd_cli_recv_pending(ctrl, 0, 1);
943 len = sizeof(buf) - 1;
944 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
945 hostapd_cli_action_process) < 0 ||
946 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
947 printf("hostapd did not reply to PING "
948 "command - exiting\n");
956 int main(int argc, char *argv[])
958 int warning_displayed = 0;
962 if (os_program_init())
966 c = getopt(argc, argv, "a:BhG:i:p:v");
971 action_file = optarg;
977 ping_interval = atoi(optarg);
983 printf("%s\n", hostapd_cli_version);
986 os_free(ctrl_ifname);
987 ctrl_ifname = os_strdup(optarg);
990 ctrl_iface_dir = optarg;
998 interactive = (argc == optind) && (action_file == NULL);
1001 printf("%s\n\n%s\n\n", hostapd_cli_version,
1002 hostapd_cli_license);
1009 if (ctrl_ifname == NULL) {
1010 struct dirent *dent;
1011 DIR *dir = opendir(ctrl_iface_dir);
1013 while ((dent = readdir(dir))) {
1014 if (os_strcmp(dent->d_name, ".") == 0
1016 os_strcmp(dent->d_name, "..") == 0)
1018 printf("Selected interface '%s'\n",
1020 ctrl_ifname = os_strdup(dent->d_name);
1026 ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
1028 if (warning_displayed)
1029 printf("Connection established.\n");
1034 perror("Failed to connect to hostapd - "
1039 if (!warning_displayed) {
1040 printf("Could not connect to hostapd - re-trying\n");
1041 warning_displayed = 1;
1047 if (interactive || action_file) {
1048 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1049 hostapd_cli_attached = 1;
1051 printf("Warning: Failed to attach to hostapd.\n");
1057 if (daemonize && os_daemonize(pid_file))
1061 hostapd_cli_interactive();
1062 else if (action_file)
1063 hostapd_cli_action(ctrl_conn);
1065 wpa_request(ctrl_conn, argc - optind, &argv[optind]);
1067 os_free(ctrl_ifname);
1069 hostapd_cli_cleanup();