2 * hostapd - command line interface for hostapd daemon
3 * Copyright (c) 2004-2012, 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 */
78 " wps_nfc_tag_read <hexdump> report read NFC tag with WPS data\n"
79 " wps_nfc_config_token <WPS/NDEF> build NFC configuration token\n"
80 " wps_nfc_token <WPS/NDEF/enable/disable> manager NFC password token\n"
81 #endif /* CONFIG_WPS_NFC */
82 " wps_ap_pin <cmd> [params..] enable/disable AP PIN\n"
83 " wps_config <SSID> <auth> <encr> <key> configure AP\n"
84 #endif /* CONFIG_WPS */
85 " get_config show current configuration\n"
86 " help show this usage help\n"
87 " interface [ifname] show interfaces/select interface\n"
88 " level <debug level> change debug level\n"
89 " license show full hostapd_cli license\n"
90 " quit exit hostapd_cli\n";
92 static struct wpa_ctrl *ctrl_conn;
93 static int hostapd_cli_quit = 0;
94 static int hostapd_cli_attached = 0;
95 static const char *ctrl_iface_dir = "/var/run/hostapd";
96 static char *ctrl_ifname = NULL;
97 static const char *pid_file = NULL;
98 static const char *action_file = NULL;
99 static int ping_interval = 5;
100 static int interactive = 0;
103 static void usage(void)
105 fprintf(stderr, "%s\n", hostapd_cli_version);
108 "usage: hostapd_cli [-p<path>] [-i<ifname>] [-hvB] "
110 " [-G<ping interval>] [command..]\n"
113 " -h help (show this usage text)\n"
114 " -v shown version information\n"
115 " -p<path> path to find control sockets (default: "
116 "/var/run/hostapd)\n"
117 " -a<file> run in daemon mode executing the action file "
120 " -B run a daemon in the background\n"
121 " -i<ifname> Interface to listen on (default: first "
122 "interface found in the\n"
129 static struct wpa_ctrl * hostapd_cli_open_connection(const char *ifname)
137 flen = strlen(ctrl_iface_dir) + strlen(ifname) + 2;
138 cfile = malloc(flen);
141 snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
143 ctrl_conn = wpa_ctrl_open(cfile);
149 static void hostapd_cli_close_connection(void)
151 if (ctrl_conn == NULL)
154 if (hostapd_cli_attached) {
155 wpa_ctrl_detach(ctrl_conn);
156 hostapd_cli_attached = 0;
158 wpa_ctrl_close(ctrl_conn);
163 static void hostapd_cli_msg_cb(char *msg, size_t len)
169 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
175 if (ctrl_conn == NULL) {
176 printf("Not connected to hostapd - command dropped.\n");
179 len = sizeof(buf) - 1;
180 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
183 printf("'%s' command timed out.\n", cmd);
185 } else if (ret < 0) {
186 printf("'%s' command failed.\n", cmd);
197 static inline int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
199 return _wpa_ctrl_command(ctrl, cmd, 1);
203 static int hostapd_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
205 return wpa_ctrl_command(ctrl, "PING");
209 static int hostapd_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
211 return wpa_ctrl_command(ctrl, "RELOG");
215 static int hostapd_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
217 return wpa_ctrl_command(ctrl, "MIB");
221 static int hostapd_cli_exec(const char *program, const char *arg1,
229 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
230 cmd = os_malloc(len);
233 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
234 if (res < 0 || (size_t) res >= len) {
242 #endif /* _WIN32_WCE */
249 static void hostapd_cli_action_process(char *msg, size_t len)
255 pos = os_strchr(pos, '>');
262 hostapd_cli_exec(action_file, ctrl_ifname, pos);
266 static int hostapd_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
270 printf("Invalid 'sta' command - exactly one argument, STA "
271 "address, is required.\n");
274 snprintf(buf, sizeof(buf), "STA %s", argv[0]);
275 return wpa_ctrl_command(ctrl, buf);
279 static int hostapd_cli_cmd_new_sta(struct wpa_ctrl *ctrl, int argc,
284 printf("Invalid 'new_sta' command - exactly one argument, STA "
285 "address, is required.\n");
288 snprintf(buf, sizeof(buf), "NEW_STA %s", argv[0]);
289 return wpa_ctrl_command(ctrl, buf);
293 static int hostapd_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
298 printf("Invalid 'deauthenticate' command - exactly one "
299 "argument, STA address, is required.\n");
303 os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s %s",
306 os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s", argv[0]);
307 return wpa_ctrl_command(ctrl, buf);
311 static int hostapd_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
316 printf("Invalid 'disassociate' command - exactly one "
317 "argument, STA address, is required.\n");
321 os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s %s",
324 os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s", argv[0]);
325 return wpa_ctrl_command(ctrl, buf);
329 #ifdef CONFIG_IEEE80211W
330 static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc,
335 printf("Invalid 'sa_query' command - exactly one argument, "
336 "STA address, is required.\n");
339 snprintf(buf, sizeof(buf), "SA_QUERY %s", argv[0]);
340 return wpa_ctrl_command(ctrl, buf);
342 #endif /* CONFIG_IEEE80211W */
346 static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc,
351 printf("Invalid 'wps_pin' command - at least two arguments, "
352 "UUID and PIN, are required.\n");
356 snprintf(buf, sizeof(buf), "WPS_PIN %s %s %s %s",
357 argv[0], argv[1], argv[2], argv[3]);
359 snprintf(buf, sizeof(buf), "WPS_PIN %s %s %s",
360 argv[0], argv[1], argv[2]);
362 snprintf(buf, sizeof(buf), "WPS_PIN %s %s", argv[0], argv[1]);
363 return wpa_ctrl_command(ctrl, buf);
367 static int hostapd_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
373 if (argc != 1 && argc != 2) {
374 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
375 "- PIN to be verified\n");
380 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
383 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
385 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
386 printf("Too long WPS_CHECK_PIN command.\n");
389 return wpa_ctrl_command(ctrl, cmd);
393 static int hostapd_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc,
396 return wpa_ctrl_command(ctrl, "WPS_PBC");
400 static int hostapd_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
403 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
407 #ifdef CONFIG_WPS_OOB
408 static int hostapd_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc,
414 if (argc != 3 && argc != 4) {
415 printf("Invalid WPS_OOB command: need three or four "
417 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
418 "- PATH: path of OOB device like '/mnt'\n"
419 "- METHOD: OOB method 'pin-e' or 'pin-r', "
421 "- DEV_NAME: (only for NFC) device name like "
427 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
428 argv[0], argv[1], argv[2]);
430 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
431 argv[0], argv[1], argv[2], argv[3]);
432 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
433 printf("Too long WPS_OOB command.\n");
436 return wpa_ctrl_command(ctrl, cmd);
438 #endif /* CONFIG_WPS_OOB */
441 #ifdef CONFIG_WPS_NFC
442 static int hostapd_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
450 printf("Invalid 'wps_nfc_tag_read' command - one argument "
455 buflen = 18 + os_strlen(argv[0]);
456 buf = os_malloc(buflen);
459 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
461 ret = wpa_ctrl_command(ctrl, buf);
468 static int hostapd_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl,
469 int argc, char *argv[])
475 printf("Invalid 'wps_nfc_config_token' command - one argument "
480 res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC_CONFIG_TOKEN %s",
482 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
483 printf("Too long WPS_NFC_CONFIG_TOKEN command.\n");
486 return wpa_ctrl_command(ctrl, cmd);
490 static int hostapd_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl,
491 int argc, char *argv[])
497 printf("Invalid 'wps_nfc_token' command - one argument is "
502 res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC_TOKEN %s", argv[0]);
503 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
504 printf("Too long WPS_NFC_TOKEN command.\n");
507 return wpa_ctrl_command(ctrl, cmd);
509 #endif /* CONFIG_WPS_NFC */
512 static int hostapd_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
517 printf("Invalid 'wps_ap_pin' command - at least one argument "
522 snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s %s",
523 argv[0], argv[1], argv[2]);
525 snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s",
528 snprintf(buf, sizeof(buf), "WPS_AP_PIN %s", argv[0]);
529 return wpa_ctrl_command(ctrl, buf);
533 static int hostapd_cli_cmd_wps_config(struct wpa_ctrl *ctrl, int argc,
537 char ssid_hex[2 * 32 + 1];
538 char key_hex[2 * 64 + 1];
542 printf("Invalid 'wps_config' command - at least two arguments "
548 for (i = 0; i < 32; i++) {
549 if (argv[0][i] == '\0')
551 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[0][i]);
556 for (i = 0; i < 64; i++) {
557 if (argv[3][i] == '\0')
559 os_snprintf(&key_hex[i * 2], 3, "%02x",
565 snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s %s %s",
566 ssid_hex, argv[1], argv[2], key_hex);
568 snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s %s",
569 ssid_hex, argv[1], argv[2]);
571 snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s",
573 return wpa_ctrl_command(ctrl, buf);
575 #endif /* CONFIG_WPS */
578 static int hostapd_cli_cmd_ess_disassoc(struct wpa_ctrl *ctrl, int argc,
585 printf("Invalid 'ess_disassoc' command - two arguments (STA "
586 "addr and URL) are needed\n");
590 res = os_snprintf(buf, sizeof(buf), "ESS_DISASSOC %s %s",
592 if (res < 0 || res >= (int) sizeof(buf))
594 return wpa_ctrl_command(ctrl, buf);
598 static int hostapd_cli_cmd_get_config(struct wpa_ctrl *ctrl, int argc,
601 return wpa_ctrl_command(ctrl, "GET_CONFIG");
605 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
606 char *addr, size_t addr_len)
608 char buf[4096], *pos;
612 if (ctrl_conn == NULL) {
613 printf("Not connected to hostapd - command dropped.\n");
616 len = sizeof(buf) - 1;
617 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
620 printf("'%s' command timed out.\n", cmd);
622 } else if (ret < 0) {
623 printf("'%s' command failed.\n", cmd);
628 if (memcmp(buf, "FAIL", 4) == 0)
633 while (*pos != '\0' && *pos != '\n')
636 os_strlcpy(addr, buf, addr_len);
641 static int hostapd_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc,
644 char addr[32], cmd[64];
646 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
649 snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
650 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
656 static int hostapd_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
658 printf("%s", commands_help);
663 static int hostapd_cli_cmd_license(struct wpa_ctrl *ctrl, int argc,
666 printf("%s\n\n%s\n", hostapd_cli_version, hostapd_cli_full_license);
671 static int hostapd_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
673 hostapd_cli_quit = 1;
680 static int hostapd_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
684 printf("Invalid LEVEL command: needs one argument (debug "
688 snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
689 return wpa_ctrl_command(ctrl, cmd);
693 static void hostapd_cli_list_interfaces(struct wpa_ctrl *ctrl)
698 dir = opendir(ctrl_iface_dir);
700 printf("Control interface directory '%s' could not be "
701 "openned.\n", ctrl_iface_dir);
705 printf("Available interfaces:\n");
706 while ((dent = readdir(dir))) {
707 if (strcmp(dent->d_name, ".") == 0 ||
708 strcmp(dent->d_name, "..") == 0)
710 printf("%s\n", dent->d_name);
716 static int hostapd_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc,
720 hostapd_cli_list_interfaces(ctrl);
724 hostapd_cli_close_connection();
726 ctrl_ifname = strdup(argv[0]);
728 if (hostapd_cli_open_connection(ctrl_ifname)) {
729 printf("Connected to interface '%s.\n", ctrl_ifname);
730 if (wpa_ctrl_attach(ctrl_conn) == 0) {
731 hostapd_cli_attached = 1;
733 printf("Warning: Failed to attach to "
737 printf("Could not connect to interface '%s' - re-trying\n",
744 static int hostapd_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
750 printf("Invalid SET command: needs two arguments (variable "
751 "name and value)\n");
755 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
756 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
757 printf("Too long SET command.\n");
760 return wpa_ctrl_command(ctrl, cmd);
764 static int hostapd_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
770 printf("Invalid GET command: needs one argument (variable "
775 res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
776 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
777 printf("Too long GET command.\n");
780 return wpa_ctrl_command(ctrl, cmd);
784 struct hostapd_cli_cmd {
786 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
789 static struct hostapd_cli_cmd hostapd_cli_commands[] = {
790 { "ping", hostapd_cli_cmd_ping },
791 { "mib", hostapd_cli_cmd_mib },
792 { "relog", hostapd_cli_cmd_relog },
793 { "sta", hostapd_cli_cmd_sta },
794 { "all_sta", hostapd_cli_cmd_all_sta },
795 { "new_sta", hostapd_cli_cmd_new_sta },
796 { "deauthenticate", hostapd_cli_cmd_deauthenticate },
797 { "disassociate", hostapd_cli_cmd_disassociate },
798 #ifdef CONFIG_IEEE80211W
799 { "sa_query", hostapd_cli_cmd_sa_query },
800 #endif /* CONFIG_IEEE80211W */
802 { "wps_pin", hostapd_cli_cmd_wps_pin },
803 { "wps_check_pin", hostapd_cli_cmd_wps_check_pin },
804 { "wps_pbc", hostapd_cli_cmd_wps_pbc },
805 { "wps_cancel", hostapd_cli_cmd_wps_cancel },
806 #ifdef CONFIG_WPS_OOB
807 { "wps_oob", hostapd_cli_cmd_wps_oob },
808 #endif /* CONFIG_WPS_OOB */
809 #ifdef CONFIG_WPS_NFC
810 { "wps_nfc_tag_read", hostapd_cli_cmd_wps_nfc_tag_read },
811 { "wps_nfc_config_token", hostapd_cli_cmd_wps_nfc_config_token },
812 { "wps_nfc_token", hostapd_cli_cmd_wps_nfc_token },
813 #endif /* CONFIG_WPS_NFC */
814 { "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin },
815 { "wps_config", hostapd_cli_cmd_wps_config },
816 #endif /* CONFIG_WPS */
817 { "ess_disassoc", hostapd_cli_cmd_ess_disassoc },
818 { "get_config", hostapd_cli_cmd_get_config },
819 { "help", hostapd_cli_cmd_help },
820 { "interface", hostapd_cli_cmd_interface },
821 { "level", hostapd_cli_cmd_level },
822 { "license", hostapd_cli_cmd_license },
823 { "quit", hostapd_cli_cmd_quit },
824 { "set", hostapd_cli_cmd_set },
825 { "get", hostapd_cli_cmd_get },
830 static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
832 struct hostapd_cli_cmd *cmd, *match = NULL;
836 cmd = hostapd_cli_commands;
838 if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0) {
840 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
841 /* we have an exact match */
851 printf("Ambiguous command '%s'; possible commands:", argv[0]);
852 cmd = hostapd_cli_commands;
854 if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) ==
856 printf(" %s", cmd->cmd);
861 } else if (count == 0) {
862 printf("Unknown command '%s'\n", argv[0]);
864 match->handler(ctrl, argc - 1, &argv[1]);
869 static void hostapd_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
873 if (ctrl_conn == NULL)
875 while (wpa_ctrl_pending(ctrl)) {
877 size_t len = sizeof(buf) - 1;
878 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
881 hostapd_cli_action_process(buf, len);
883 if (in_read && first)
889 printf("Could not read pending message.\n");
898 static int tokenize_cmd(char *cmd, char *argv[])
911 if (argc == max_args)
914 char *pos2 = os_strrchr(pos, '"');
918 while (*pos != '\0' && *pos != ' ')
928 static void hostapd_cli_ping(void *eloop_ctx, void *timeout_ctx)
930 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
931 printf("Connection to hostapd lost - trying to reconnect\n");
932 hostapd_cli_close_connection();
935 ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
937 printf("Connection to hostapd re-established\n");
938 if (wpa_ctrl_attach(ctrl_conn) == 0) {
939 hostapd_cli_attached = 1;
941 printf("Warning: Failed to attach to "
947 hostapd_cli_recv_pending(ctrl_conn, 1, 0);
948 eloop_register_timeout(ping_interval, 0, hostapd_cli_ping, NULL, NULL);
952 static void hostapd_cli_eloop_terminate(int sig, void *signal_ctx)
958 static void hostapd_cli_edit_cmd_cb(void *ctx, char *cmd)
960 char *argv[max_args];
962 argc = tokenize_cmd(cmd, argv);
964 wpa_request(ctrl_conn, argc, argv);
968 static void hostapd_cli_edit_eof_cb(void *ctx)
974 static void hostapd_cli_interactive(void)
976 printf("\nInteractive mode\n\n");
978 eloop_register_signal_terminate(hostapd_cli_eloop_terminate, NULL);
979 edit_init(hostapd_cli_edit_cmd_cb, hostapd_cli_edit_eof_cb,
981 eloop_register_timeout(ping_interval, 0, hostapd_cli_ping, NULL, NULL);
985 edit_deinit(NULL, NULL);
986 eloop_cancel_timeout(hostapd_cli_ping, NULL, NULL);
990 static void hostapd_cli_cleanup(void)
992 hostapd_cli_close_connection();
994 os_daemonize_terminate(pid_file);
1000 static void hostapd_cli_action(struct wpa_ctrl *ctrl)
1008 fd = wpa_ctrl_get_fd(ctrl);
1010 while (!hostapd_cli_quit) {
1013 tv.tv_sec = ping_interval;
1015 res = select(fd + 1, &rfds, NULL, NULL, &tv);
1016 if (res < 0 && errno != EINTR) {
1021 if (FD_ISSET(fd, &rfds))
1022 hostapd_cli_recv_pending(ctrl, 0, 1);
1024 len = sizeof(buf) - 1;
1025 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
1026 hostapd_cli_action_process) < 0 ||
1027 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
1028 printf("hostapd did not reply to PING "
1029 "command - exiting\n");
1037 int main(int argc, char *argv[])
1039 int warning_displayed = 0;
1043 if (os_program_init())
1047 c = getopt(argc, argv, "a:BhG:i:p:v");
1052 action_file = optarg;
1058 ping_interval = atoi(optarg);
1064 printf("%s\n", hostapd_cli_version);
1067 os_free(ctrl_ifname);
1068 ctrl_ifname = os_strdup(optarg);
1071 ctrl_iface_dir = optarg;
1079 interactive = (argc == optind) && (action_file == NULL);
1082 printf("%s\n\n%s\n\n", hostapd_cli_version,
1083 hostapd_cli_license);
1090 if (ctrl_ifname == NULL) {
1091 struct dirent *dent;
1092 DIR *dir = opendir(ctrl_iface_dir);
1094 while ((dent = readdir(dir))) {
1095 if (os_strcmp(dent->d_name, ".") == 0
1097 os_strcmp(dent->d_name, "..") == 0)
1099 printf("Selected interface '%s'\n",
1101 ctrl_ifname = os_strdup(dent->d_name);
1107 ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
1109 if (warning_displayed)
1110 printf("Connection established.\n");
1115 perror("Failed to connect to hostapd - "
1120 if (!warning_displayed) {
1121 printf("Could not connect to hostapd - re-trying\n");
1122 warning_displayed = 1;
1128 if (interactive || action_file) {
1129 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1130 hostapd_cli_attached = 1;
1132 printf("Warning: Failed to attach to hostapd.\n");
1138 if (daemonize && os_daemonize(pid_file))
1142 hostapd_cli_interactive();
1143 else if (action_file)
1144 hostapd_cli_action(ctrl_conn);
1146 wpa_request(ctrl_conn, argc - optind, &argv[optind]);
1148 os_free(ctrl_ifname);
1150 hostapd_cli_cleanup();