2 * hostapd - command line interface for hostapd daemon
3 * Copyright (c) 2004-2011, 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"
19 #include "utils/common.h"
20 #include "utils/eloop.h"
21 #include "utils/edit.h"
22 #include "common/version.h"
25 static const char *hostapd_cli_version =
26 "hostapd_cli v" VERSION_STR "\n"
27 "Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> and contributors";
30 static const char *hostapd_cli_license =
31 "This software may be distributed under the terms of the BSD license.\n"
32 "See README for more details.\n";
34 static const char *hostapd_cli_full_license =
35 "This software may be distributed under the terms of the BSD license.\n"
37 "Redistribution and use in source and binary forms, with or without\n"
38 "modification, are permitted provided that the following conditions are\n"
41 "1. Redistributions of source code must retain the above copyright\n"
42 " notice, this list of conditions and the following disclaimer.\n"
44 "2. Redistributions in binary form must reproduce the above copyright\n"
45 " notice, this list of conditions and the following disclaimer in the\n"
46 " documentation and/or other materials provided with the distribution.\n"
48 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
49 " names of its contributors may be used to endorse or promote products\n"
50 " derived from this software without specific prior written permission.\n"
52 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
53 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
54 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
55 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
56 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
57 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
58 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
59 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
60 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
61 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
62 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
65 static const char *commands_help =
67 " mib get MIB variables (dot1x, dot11, radius)\n"
68 " sta <addr> get MIB variables for one station\n"
69 " all_sta get MIB variables for all stations\n"
70 " new_sta <addr> add a new station\n"
71 " deauthenticate <addr> deauthenticate a station\n"
72 " disassociate <addr> disassociate a station\n"
73 #ifdef CONFIG_IEEE80211W
74 " sa_query <addr> send SA Query to a station\n"
75 #endif /* CONFIG_IEEE80211W */
77 " wps_pin <uuid> <pin> [timeout] [addr] add WPS Enrollee PIN\n"
78 " wps_check_pin <PIN> verify PIN checksum\n"
79 " wps_pbc indicate button pushed to initiate PBC\n"
81 " wps_oob <type> <path> <method> use WPS with out-of-band (UFD)\n"
82 #endif /* CONFIG_WPS_OOB */
83 " wps_ap_pin <cmd> [params..] enable/disable AP PIN\n"
84 " wps_config <SSID> <auth> <encr> <key> configure AP\n"
85 #endif /* CONFIG_WPS */
86 " get_config show current configuration\n"
87 " help show this usage help\n"
88 " interface [ifname] show interfaces/select interface\n"
89 " level <debug level> change debug level\n"
90 " license show full hostapd_cli license\n"
91 " quit exit hostapd_cli\n";
93 static struct wpa_ctrl *ctrl_conn;
94 static int hostapd_cli_quit = 0;
95 static int hostapd_cli_attached = 0;
96 static const char *ctrl_iface_dir = "/var/run/hostapd";
97 static char *ctrl_ifname = NULL;
98 static const char *pid_file = NULL;
99 static const char *action_file = NULL;
100 static int ping_interval = 5;
101 static int interactive = 0;
104 static void usage(void)
106 fprintf(stderr, "%s\n", hostapd_cli_version);
109 "usage: hostapd_cli [-p<path>] [-i<ifname>] [-hvB] "
111 " [-G<ping interval>] [command..]\n"
114 " -h help (show this usage text)\n"
115 " -v shown version information\n"
116 " -p<path> path to find control sockets (default: "
117 "/var/run/hostapd)\n"
118 " -a<file> run in daemon mode executing the action file "
121 " -B run a daemon in the background\n"
122 " -i<ifname> Interface to listen on (default: first "
123 "interface found in the\n"
130 static struct wpa_ctrl * hostapd_cli_open_connection(const char *ifname)
138 flen = strlen(ctrl_iface_dir) + strlen(ifname) + 2;
139 cfile = malloc(flen);
142 snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
144 ctrl_conn = wpa_ctrl_open(cfile);
150 static void hostapd_cli_close_connection(void)
152 if (ctrl_conn == NULL)
155 if (hostapd_cli_attached) {
156 wpa_ctrl_detach(ctrl_conn);
157 hostapd_cli_attached = 0;
159 wpa_ctrl_close(ctrl_conn);
164 static void hostapd_cli_msg_cb(char *msg, size_t len)
170 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
176 if (ctrl_conn == NULL) {
177 printf("Not connected to hostapd - command dropped.\n");
180 len = sizeof(buf) - 1;
181 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
184 printf("'%s' command timed out.\n", cmd);
186 } else if (ret < 0) {
187 printf("'%s' command failed.\n", cmd);
198 static inline int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
200 return _wpa_ctrl_command(ctrl, cmd, 1);
204 static int hostapd_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
206 return wpa_ctrl_command(ctrl, "PING");
210 static int hostapd_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
212 return wpa_ctrl_command(ctrl, "RELOG");
216 static int hostapd_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
218 return wpa_ctrl_command(ctrl, "MIB");
222 static int hostapd_cli_exec(const char *program, const char *arg1,
230 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
231 cmd = os_malloc(len);
234 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
235 if (res < 0 || (size_t) res >= len) {
243 #endif /* _WIN32_WCE */
250 static void hostapd_cli_action_process(char *msg, size_t len)
256 pos = os_strchr(pos, '>');
263 hostapd_cli_exec(action_file, ctrl_ifname, pos);
267 static int hostapd_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
271 printf("Invalid 'sta' command - exactly one argument, STA "
272 "address, is required.\n");
275 snprintf(buf, sizeof(buf), "STA %s", argv[0]);
276 return wpa_ctrl_command(ctrl, buf);
280 static int hostapd_cli_cmd_new_sta(struct wpa_ctrl *ctrl, int argc,
285 printf("Invalid 'new_sta' command - exactly one argument, STA "
286 "address, is required.\n");
289 snprintf(buf, sizeof(buf), "NEW_STA %s", argv[0]);
290 return wpa_ctrl_command(ctrl, buf);
294 static int hostapd_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
299 printf("Invalid 'deauthenticate' command - exactly one "
300 "argument, STA address, is required.\n");
304 os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s %s",
307 os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s", argv[0]);
308 return wpa_ctrl_command(ctrl, buf);
312 static int hostapd_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
317 printf("Invalid 'disassociate' command - exactly one "
318 "argument, STA address, is required.\n");
322 os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s %s",
325 os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s", argv[0]);
326 return wpa_ctrl_command(ctrl, buf);
330 #ifdef CONFIG_IEEE80211W
331 static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc,
336 printf("Invalid 'sa_query' command - exactly one argument, "
337 "STA address, is required.\n");
340 snprintf(buf, sizeof(buf), "SA_QUERY %s", argv[0]);
341 return wpa_ctrl_command(ctrl, buf);
343 #endif /* CONFIG_IEEE80211W */
347 static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc,
352 printf("Invalid 'wps_pin' command - at least two arguments, "
353 "UUID and PIN, are required.\n");
357 snprintf(buf, sizeof(buf), "WPS_PIN %s %s %s %s",
358 argv[0], argv[1], argv[2], argv[3]);
360 snprintf(buf, sizeof(buf), "WPS_PIN %s %s %s",
361 argv[0], argv[1], argv[2]);
363 snprintf(buf, sizeof(buf), "WPS_PIN %s %s", argv[0], argv[1]);
364 return wpa_ctrl_command(ctrl, buf);
368 static int hostapd_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
374 if (argc != 1 && argc != 2) {
375 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
376 "- PIN to be verified\n");
381 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
384 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
386 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
387 printf("Too long WPS_CHECK_PIN command.\n");
390 return wpa_ctrl_command(ctrl, cmd);
394 static int hostapd_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc,
397 return wpa_ctrl_command(ctrl, "WPS_PBC");
401 #ifdef CONFIG_WPS_OOB
402 static int hostapd_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc,
408 if (argc != 3 && argc != 4) {
409 printf("Invalid WPS_OOB command: need three or four "
411 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
412 "- PATH: path of OOB device like '/mnt'\n"
413 "- METHOD: OOB method 'pin-e' or 'pin-r', "
415 "- DEV_NAME: (only for NFC) device name like "
421 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
422 argv[0], argv[1], argv[2]);
424 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
425 argv[0], argv[1], argv[2], argv[3]);
426 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
427 printf("Too long WPS_OOB command.\n");
430 return wpa_ctrl_command(ctrl, cmd);
432 #endif /* CONFIG_WPS_OOB */
435 static int hostapd_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
440 printf("Invalid 'wps_ap_pin' command - at least one argument "
445 snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s %s",
446 argv[0], argv[1], argv[2]);
448 snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s",
451 snprintf(buf, sizeof(buf), "WPS_AP_PIN %s", argv[0]);
452 return wpa_ctrl_command(ctrl, buf);
456 static int hostapd_cli_cmd_wps_config(struct wpa_ctrl *ctrl, int argc,
460 char ssid_hex[2 * 32 + 1];
461 char key_hex[2 * 64 + 1];
465 printf("Invalid 'wps_config' command - at least two arguments "
471 for (i = 0; i < 32; i++) {
472 if (argv[0][i] == '\0')
474 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[0][i]);
479 for (i = 0; i < 64; i++) {
480 if (argv[3][i] == '\0')
482 os_snprintf(&key_hex[i * 2], 3, "%02x",
488 snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s %s %s",
489 ssid_hex, argv[1], argv[2], key_hex);
491 snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s %s",
492 ssid_hex, argv[1], argv[2]);
494 snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s",
496 return wpa_ctrl_command(ctrl, buf);
498 #endif /* CONFIG_WPS */
501 static int hostapd_cli_cmd_ess_disassoc(struct wpa_ctrl *ctrl, int argc,
508 printf("Invalid 'ess_disassoc' command - two arguments (STA "
509 "addr and URL) are needed\n");
513 res = os_snprintf(buf, sizeof(buf), "ESS_DISASSOC %s %s",
515 if (res < 0 || res >= (int) sizeof(buf))
517 return wpa_ctrl_command(ctrl, buf);
521 static int hostapd_cli_cmd_get_config(struct wpa_ctrl *ctrl, int argc,
524 return wpa_ctrl_command(ctrl, "GET_CONFIG");
528 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
529 char *addr, size_t addr_len)
531 char buf[4096], *pos;
535 if (ctrl_conn == NULL) {
536 printf("Not connected to hostapd - command dropped.\n");
539 len = sizeof(buf) - 1;
540 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
543 printf("'%s' command timed out.\n", cmd);
545 } else if (ret < 0) {
546 printf("'%s' command failed.\n", cmd);
551 if (memcmp(buf, "FAIL", 4) == 0)
556 while (*pos != '\0' && *pos != '\n')
559 os_strlcpy(addr, buf, addr_len);
564 static int hostapd_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc,
567 char addr[32], cmd[64];
569 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
572 snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
573 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
579 static int hostapd_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
581 printf("%s", commands_help);
586 static int hostapd_cli_cmd_license(struct wpa_ctrl *ctrl, int argc,
589 printf("%s\n\n%s\n", hostapd_cli_version, hostapd_cli_full_license);
594 static int hostapd_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
596 hostapd_cli_quit = 1;
603 static int hostapd_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
607 printf("Invalid LEVEL command: needs one argument (debug "
611 snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
612 return wpa_ctrl_command(ctrl, cmd);
616 static void hostapd_cli_list_interfaces(struct wpa_ctrl *ctrl)
621 dir = opendir(ctrl_iface_dir);
623 printf("Control interface directory '%s' could not be "
624 "openned.\n", ctrl_iface_dir);
628 printf("Available interfaces:\n");
629 while ((dent = readdir(dir))) {
630 if (strcmp(dent->d_name, ".") == 0 ||
631 strcmp(dent->d_name, "..") == 0)
633 printf("%s\n", dent->d_name);
639 static int hostapd_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc,
643 hostapd_cli_list_interfaces(ctrl);
647 hostapd_cli_close_connection();
649 ctrl_ifname = strdup(argv[0]);
651 if (hostapd_cli_open_connection(ctrl_ifname)) {
652 printf("Connected to interface '%s.\n", ctrl_ifname);
653 if (wpa_ctrl_attach(ctrl_conn) == 0) {
654 hostapd_cli_attached = 1;
656 printf("Warning: Failed to attach to "
660 printf("Could not connect to interface '%s' - re-trying\n",
667 static int hostapd_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
673 printf("Invalid SET command: needs two arguments (variable "
674 "name and value)\n");
678 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
679 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
680 printf("Too long SET command.\n");
683 return wpa_ctrl_command(ctrl, cmd);
687 static int hostapd_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
693 printf("Invalid GET command: needs one argument (variable "
698 res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
699 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
700 printf("Too long GET command.\n");
703 return wpa_ctrl_command(ctrl, cmd);
707 struct hostapd_cli_cmd {
709 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
712 static struct hostapd_cli_cmd hostapd_cli_commands[] = {
713 { "ping", hostapd_cli_cmd_ping },
714 { "mib", hostapd_cli_cmd_mib },
715 { "relog", hostapd_cli_cmd_relog },
716 { "sta", hostapd_cli_cmd_sta },
717 { "all_sta", hostapd_cli_cmd_all_sta },
718 { "new_sta", hostapd_cli_cmd_new_sta },
719 { "deauthenticate", hostapd_cli_cmd_deauthenticate },
720 { "disassociate", hostapd_cli_cmd_disassociate },
721 #ifdef CONFIG_IEEE80211W
722 { "sa_query", hostapd_cli_cmd_sa_query },
723 #endif /* CONFIG_IEEE80211W */
725 { "wps_pin", hostapd_cli_cmd_wps_pin },
726 { "wps_check_pin", hostapd_cli_cmd_wps_check_pin },
727 { "wps_pbc", hostapd_cli_cmd_wps_pbc },
728 #ifdef CONFIG_WPS_OOB
729 { "wps_oob", hostapd_cli_cmd_wps_oob },
730 #endif /* CONFIG_WPS_OOB */
731 { "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin },
732 { "wps_config", hostapd_cli_cmd_wps_config },
733 #endif /* CONFIG_WPS */
734 { "ess_disassoc", hostapd_cli_cmd_ess_disassoc },
735 { "get_config", hostapd_cli_cmd_get_config },
736 { "help", hostapd_cli_cmd_help },
737 { "interface", hostapd_cli_cmd_interface },
738 { "level", hostapd_cli_cmd_level },
739 { "license", hostapd_cli_cmd_license },
740 { "quit", hostapd_cli_cmd_quit },
741 { "set", hostapd_cli_cmd_set },
742 { "get", hostapd_cli_cmd_get },
747 static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
749 struct hostapd_cli_cmd *cmd, *match = NULL;
753 cmd = hostapd_cli_commands;
755 if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0) {
757 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
758 /* we have an exact match */
768 printf("Ambiguous command '%s'; possible commands:", argv[0]);
769 cmd = hostapd_cli_commands;
771 if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) ==
773 printf(" %s", cmd->cmd);
778 } else if (count == 0) {
779 printf("Unknown command '%s'\n", argv[0]);
781 match->handler(ctrl, argc - 1, &argv[1]);
786 static void hostapd_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
790 if (ctrl_conn == NULL)
792 while (wpa_ctrl_pending(ctrl)) {
794 size_t len = sizeof(buf) - 1;
795 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
798 hostapd_cli_action_process(buf, len);
800 if (in_read && first)
806 printf("Could not read pending message.\n");
815 static int tokenize_cmd(char *cmd, char *argv[])
828 if (argc == max_args)
831 char *pos2 = os_strrchr(pos, '"');
835 while (*pos != '\0' && *pos != ' ')
845 static void hostapd_cli_ping(void *eloop_ctx, void *timeout_ctx)
847 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
848 printf("Connection to hostapd lost - trying to reconnect\n");
849 hostapd_cli_close_connection();
852 ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
854 printf("Connection to hostapd re-established\n");
855 if (wpa_ctrl_attach(ctrl_conn) == 0) {
856 hostapd_cli_attached = 1;
858 printf("Warning: Failed to attach to "
864 hostapd_cli_recv_pending(ctrl_conn, 1, 0);
865 eloop_register_timeout(ping_interval, 0, hostapd_cli_ping, NULL, NULL);
869 static void hostapd_cli_eloop_terminate(int sig, void *signal_ctx)
875 static void hostapd_cli_edit_cmd_cb(void *ctx, char *cmd)
877 char *argv[max_args];
879 argc = tokenize_cmd(cmd, argv);
881 wpa_request(ctrl_conn, argc, argv);
885 static void hostapd_cli_edit_eof_cb(void *ctx)
891 static void hostapd_cli_interactive(void)
893 printf("\nInteractive mode\n\n");
895 eloop_register_signal_terminate(hostapd_cli_eloop_terminate, NULL);
896 edit_init(hostapd_cli_edit_cmd_cb, hostapd_cli_edit_eof_cb,
898 eloop_register_timeout(ping_interval, 0, hostapd_cli_ping, NULL, NULL);
902 edit_deinit(NULL, NULL);
903 eloop_cancel_timeout(hostapd_cli_ping, NULL, NULL);
907 static void hostapd_cli_cleanup(void)
909 hostapd_cli_close_connection();
911 os_daemonize_terminate(pid_file);
917 static void hostapd_cli_action(struct wpa_ctrl *ctrl)
925 fd = wpa_ctrl_get_fd(ctrl);
927 while (!hostapd_cli_quit) {
930 tv.tv_sec = ping_interval;
932 res = select(fd + 1, &rfds, NULL, NULL, &tv);
933 if (res < 0 && errno != EINTR) {
938 if (FD_ISSET(fd, &rfds))
939 hostapd_cli_recv_pending(ctrl, 0, 1);
941 len = sizeof(buf) - 1;
942 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
943 hostapd_cli_action_process) < 0 ||
944 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
945 printf("hostapd did not reply to PING "
946 "command - exiting\n");
954 int main(int argc, char *argv[])
956 int warning_displayed = 0;
960 if (os_program_init())
964 c = getopt(argc, argv, "a:BhG:i:p:v");
969 action_file = optarg;
975 ping_interval = atoi(optarg);
981 printf("%s\n", hostapd_cli_version);
984 os_free(ctrl_ifname);
985 ctrl_ifname = os_strdup(optarg);
988 ctrl_iface_dir = optarg;
996 interactive = (argc == optind) && (action_file == NULL);
999 printf("%s\n\n%s\n\n", hostapd_cli_version,
1000 hostapd_cli_license);
1007 if (ctrl_ifname == NULL) {
1008 struct dirent *dent;
1009 DIR *dir = opendir(ctrl_iface_dir);
1011 while ((dent = readdir(dir))) {
1012 if (os_strcmp(dent->d_name, ".") == 0
1014 os_strcmp(dent->d_name, "..") == 0)
1016 printf("Selected interface '%s'\n",
1018 ctrl_ifname = os_strdup(dent->d_name);
1024 ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
1026 if (warning_displayed)
1027 printf("Connection established.\n");
1032 perror("Failed to connect to hostapd - "
1037 if (!warning_displayed) {
1038 printf("Could not connect to hostapd - re-trying\n");
1039 warning_displayed = 1;
1045 if (interactive || action_file) {
1046 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1047 hostapd_cli_attached = 1;
1049 printf("Warning: Failed to attach to hostapd.\n");
1055 if (daemonize && os_daemonize(pid_file))
1059 hostapd_cli_interactive();
1060 else if (action_file)
1061 hostapd_cli_action(ctrl_conn);
1063 wpa_request(ctrl_conn, argc - optind, &argv[optind]);
1065 os_free(ctrl_ifname);
1067 hostapd_cli_cleanup();