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"
74 " wps_cancel cancel the pending WPS operation\n"
76 " wps_nfc_tag_read <hexdump> report read NFC tag with WPS data\n"
77 " wps_nfc_config_token <WPS/NDEF> build NFC configuration token\n"
78 " wps_nfc_token <WPS/NDEF/enable/disable> manager NFC password token\n"
79 #endif /* CONFIG_WPS_NFC */
80 " wps_ap_pin <cmd> [params..] enable/disable AP PIN\n"
81 " wps_config <SSID> <auth> <encr> <key> configure AP\n"
82 #endif /* CONFIG_WPS */
83 " get_config show current configuration\n"
84 " help show this usage help\n"
85 " interface [ifname] show interfaces/select interface\n"
86 " level <debug level> change debug level\n"
87 " license show full hostapd_cli license\n"
88 " quit exit hostapd_cli\n";
90 static struct wpa_ctrl
*ctrl_conn
;
91 static int hostapd_cli_quit
= 0;
92 static int hostapd_cli_attached
= 0;
93 static const char *ctrl_iface_dir
= "/var/run/hostapd";
94 static char *ctrl_ifname
= NULL
;
95 static const char *pid_file
= NULL
;
96 static const char *action_file
= NULL
;
97 static int ping_interval
= 5;
98 static int interactive
= 0;
101 static void usage(void)
103 fprintf(stderr
, "%s\n", hostapd_cli_version
);
106 "usage: hostapd_cli [-p<path>] [-i<ifname>] [-hvB] "
108 " [-G<ping interval>] [command..]\n"
111 " -h help (show this usage text)\n"
112 " -v shown version information\n"
113 " -p<path> path to find control sockets (default: "
114 "/var/run/hostapd)\n"
115 " -a<file> run in daemon mode executing the action file "
118 " -B run a daemon in the background\n"
119 " -i<ifname> Interface to listen on (default: first "
120 "interface found in the\n"
127 static struct wpa_ctrl
* hostapd_cli_open_connection(const char *ifname
)
135 flen
= strlen(ctrl_iface_dir
) + strlen(ifname
) + 2;
136 cfile
= malloc(flen
);
139 snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
, ifname
);
141 ctrl_conn
= wpa_ctrl_open(cfile
);
147 static void hostapd_cli_close_connection(void)
149 if (ctrl_conn
== NULL
)
152 if (hostapd_cli_attached
) {
153 wpa_ctrl_detach(ctrl_conn
);
154 hostapd_cli_attached
= 0;
156 wpa_ctrl_close(ctrl_conn
);
161 static void hostapd_cli_msg_cb(char *msg
, size_t len
)
167 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
173 if (ctrl_conn
== NULL
) {
174 printf("Not connected to hostapd - command dropped.\n");
177 len
= sizeof(buf
) - 1;
178 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
181 printf("'%s' command timed out.\n", cmd
);
183 } else if (ret
< 0) {
184 printf("'%s' command failed.\n", cmd
);
195 static inline int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
197 return _wpa_ctrl_command(ctrl
, cmd
, 1);
201 static int hostapd_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
203 return wpa_ctrl_command(ctrl
, "PING");
207 static int hostapd_cli_cmd_relog(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
209 return wpa_ctrl_command(ctrl
, "RELOG");
213 static int hostapd_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
215 return wpa_ctrl_command(ctrl
, "MIB");
219 static int hostapd_cli_exec(const char *program
, const char *arg1
,
227 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
228 cmd
= os_malloc(len
);
231 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
232 if (res
< 0 || (size_t) res
>= len
) {
240 #endif /* _WIN32_WCE */
247 static void hostapd_cli_action_process(char *msg
, size_t len
)
253 pos
= os_strchr(pos
, '>');
260 hostapd_cli_exec(action_file
, ctrl_ifname
, pos
);
264 static int hostapd_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
268 printf("Invalid 'sta' command - exactly one argument, STA "
269 "address, is required.\n");
272 snprintf(buf
, sizeof(buf
), "STA %s", argv
[0]);
273 return wpa_ctrl_command(ctrl
, buf
);
277 static int hostapd_cli_cmd_new_sta(struct wpa_ctrl
*ctrl
, int argc
,
282 printf("Invalid 'new_sta' command - exactly one argument, STA "
283 "address, is required.\n");
286 snprintf(buf
, sizeof(buf
), "NEW_STA %s", argv
[0]);
287 return wpa_ctrl_command(ctrl
, buf
);
291 static int hostapd_cli_cmd_deauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
296 printf("Invalid 'deauthenticate' command - exactly one "
297 "argument, STA address, is required.\n");
301 os_snprintf(buf
, sizeof(buf
), "DEAUTHENTICATE %s %s",
304 os_snprintf(buf
, sizeof(buf
), "DEAUTHENTICATE %s", argv
[0]);
305 return wpa_ctrl_command(ctrl
, buf
);
309 static int hostapd_cli_cmd_disassociate(struct wpa_ctrl
*ctrl
, int argc
,
314 printf("Invalid 'disassociate' command - exactly one "
315 "argument, STA address, is required.\n");
319 os_snprintf(buf
, sizeof(buf
), "DISASSOCIATE %s %s",
322 os_snprintf(buf
, sizeof(buf
), "DISASSOCIATE %s", argv
[0]);
323 return wpa_ctrl_command(ctrl
, buf
);
327 #ifdef CONFIG_IEEE80211W
328 static int hostapd_cli_cmd_sa_query(struct wpa_ctrl
*ctrl
, int argc
,
333 printf("Invalid 'sa_query' command - exactly one argument, "
334 "STA address, is required.\n");
337 snprintf(buf
, sizeof(buf
), "SA_QUERY %s", argv
[0]);
338 return wpa_ctrl_command(ctrl
, buf
);
340 #endif /* CONFIG_IEEE80211W */
344 static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
,
349 printf("Invalid 'wps_pin' command - at least two arguments, "
350 "UUID and PIN, are required.\n");
354 snprintf(buf
, sizeof(buf
), "WPS_PIN %s %s %s %s",
355 argv
[0], argv
[1], argv
[2], argv
[3]);
357 snprintf(buf
, sizeof(buf
), "WPS_PIN %s %s %s",
358 argv
[0], argv
[1], argv
[2]);
360 snprintf(buf
, sizeof(buf
), "WPS_PIN %s %s", argv
[0], argv
[1]);
361 return wpa_ctrl_command(ctrl
, buf
);
365 static int hostapd_cli_cmd_wps_check_pin(struct wpa_ctrl
*ctrl
, int argc
,
371 if (argc
!= 1 && argc
!= 2) {
372 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
373 "- PIN to be verified\n");
378 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s %s",
381 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s",
383 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
384 printf("Too long WPS_CHECK_PIN command.\n");
387 return wpa_ctrl_command(ctrl
, cmd
);
391 static int hostapd_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
,
394 return wpa_ctrl_command(ctrl
, "WPS_PBC");
398 static int hostapd_cli_cmd_wps_cancel(struct wpa_ctrl
*ctrl
, int argc
,
401 return wpa_ctrl_command(ctrl
, "WPS_CANCEL");
405 #ifdef CONFIG_WPS_NFC
406 static int hostapd_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl
*ctrl
, int argc
,
414 printf("Invalid 'wps_nfc_tag_read' command - one argument "
419 buflen
= 18 + os_strlen(argv
[0]);
420 buf
= os_malloc(buflen
);
423 os_snprintf(buf
, buflen
, "WPS_NFC_TAG_READ %s", argv
[0]);
425 ret
= wpa_ctrl_command(ctrl
, buf
);
432 static int hostapd_cli_cmd_wps_nfc_config_token(struct wpa_ctrl
*ctrl
,
433 int argc
, char *argv
[])
439 printf("Invalid 'wps_nfc_config_token' command - one argument "
444 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_NFC_CONFIG_TOKEN %s",
446 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
447 printf("Too long WPS_NFC_CONFIG_TOKEN command.\n");
450 return wpa_ctrl_command(ctrl
, cmd
);
454 static int hostapd_cli_cmd_wps_nfc_token(struct wpa_ctrl
*ctrl
,
455 int argc
, char *argv
[])
461 printf("Invalid 'wps_nfc_token' command - one argument is "
466 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_NFC_TOKEN %s", argv
[0]);
467 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
468 printf("Too long WPS_NFC_TOKEN command.\n");
471 return wpa_ctrl_command(ctrl
, cmd
);
473 #endif /* CONFIG_WPS_NFC */
476 static int hostapd_cli_cmd_wps_ap_pin(struct wpa_ctrl
*ctrl
, int argc
,
481 printf("Invalid 'wps_ap_pin' command - at least one argument "
486 snprintf(buf
, sizeof(buf
), "WPS_AP_PIN %s %s %s",
487 argv
[0], argv
[1], argv
[2]);
489 snprintf(buf
, sizeof(buf
), "WPS_AP_PIN %s %s",
492 snprintf(buf
, sizeof(buf
), "WPS_AP_PIN %s", argv
[0]);
493 return wpa_ctrl_command(ctrl
, buf
);
497 static int hostapd_cli_cmd_wps_config(struct wpa_ctrl
*ctrl
, int argc
,
501 char ssid_hex
[2 * 32 + 1];
502 char key_hex
[2 * 64 + 1];
506 printf("Invalid 'wps_config' command - at least two arguments "
512 for (i
= 0; i
< 32; i
++) {
513 if (argv
[0][i
] == '\0')
515 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[0][i
]);
520 for (i
= 0; i
< 64; i
++) {
521 if (argv
[3][i
] == '\0')
523 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
529 snprintf(buf
, sizeof(buf
), "WPS_CONFIG %s %s %s %s",
530 ssid_hex
, argv
[1], argv
[2], key_hex
);
532 snprintf(buf
, sizeof(buf
), "WPS_CONFIG %s %s %s",
533 ssid_hex
, argv
[1], argv
[2]);
535 snprintf(buf
, sizeof(buf
), "WPS_CONFIG %s %s",
537 return wpa_ctrl_command(ctrl
, buf
);
539 #endif /* CONFIG_WPS */
542 static int hostapd_cli_cmd_ess_disassoc(struct wpa_ctrl
*ctrl
, int argc
,
549 printf("Invalid 'ess_disassoc' command - two arguments (STA "
550 "addr and URL) are needed\n");
554 res
= os_snprintf(buf
, sizeof(buf
), "ESS_DISASSOC %s %s",
556 if (res
< 0 || res
>= (int) sizeof(buf
))
558 return wpa_ctrl_command(ctrl
, buf
);
562 static int hostapd_cli_cmd_get_config(struct wpa_ctrl
*ctrl
, int argc
,
565 return wpa_ctrl_command(ctrl
, "GET_CONFIG");
569 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
570 char *addr
, size_t addr_len
)
572 char buf
[4096], *pos
;
576 if (ctrl_conn
== NULL
) {
577 printf("Not connected to hostapd - command dropped.\n");
580 len
= sizeof(buf
) - 1;
581 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
584 printf("'%s' command timed out.\n", cmd
);
586 } else if (ret
< 0) {
587 printf("'%s' command failed.\n", cmd
);
592 if (memcmp(buf
, "FAIL", 4) == 0)
597 while (*pos
!= '\0' && *pos
!= '\n')
600 os_strlcpy(addr
, buf
, addr_len
);
605 static int hostapd_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
,
608 char addr
[32], cmd
[64];
610 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
613 snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
614 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
620 static int hostapd_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
622 printf("%s", commands_help
);
627 static int hostapd_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
,
630 printf("%s\n\n%s\n", hostapd_cli_version
, hostapd_cli_full_license
);
635 static int hostapd_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
637 hostapd_cli_quit
= 1;
644 static int hostapd_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
648 printf("Invalid LEVEL command: needs one argument (debug "
652 snprintf(cmd
, sizeof(cmd
), "LEVEL %s", argv
[0]);
653 return wpa_ctrl_command(ctrl
, cmd
);
657 static void hostapd_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
662 dir
= opendir(ctrl_iface_dir
);
664 printf("Control interface directory '%s' could not be "
665 "openned.\n", ctrl_iface_dir
);
669 printf("Available interfaces:\n");
670 while ((dent
= readdir(dir
))) {
671 if (strcmp(dent
->d_name
, ".") == 0 ||
672 strcmp(dent
->d_name
, "..") == 0)
674 printf("%s\n", dent
->d_name
);
680 static int hostapd_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
,
684 hostapd_cli_list_interfaces(ctrl
);
688 hostapd_cli_close_connection();
690 ctrl_ifname
= strdup(argv
[0]);
692 if (hostapd_cli_open_connection(ctrl_ifname
)) {
693 printf("Connected to interface '%s.\n", ctrl_ifname
);
694 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
695 hostapd_cli_attached
= 1;
697 printf("Warning: Failed to attach to "
701 printf("Could not connect to interface '%s' - re-trying\n",
708 static int hostapd_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
714 printf("Invalid SET command: needs two arguments (variable "
715 "name and value)\n");
719 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s", argv
[0], argv
[1]);
720 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
721 printf("Too long SET command.\n");
724 return wpa_ctrl_command(ctrl
, cmd
);
728 static int hostapd_cli_cmd_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
734 printf("Invalid GET command: needs one argument (variable "
739 res
= os_snprintf(cmd
, sizeof(cmd
), "GET %s", argv
[0]);
740 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
741 printf("Too long GET command.\n");
744 return wpa_ctrl_command(ctrl
, cmd
);
748 struct hostapd_cli_cmd
{
750 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
753 static struct hostapd_cli_cmd hostapd_cli_commands
[] = {
754 { "ping", hostapd_cli_cmd_ping
},
755 { "mib", hostapd_cli_cmd_mib
},
756 { "relog", hostapd_cli_cmd_relog
},
757 { "sta", hostapd_cli_cmd_sta
},
758 { "all_sta", hostapd_cli_cmd_all_sta
},
759 { "new_sta", hostapd_cli_cmd_new_sta
},
760 { "deauthenticate", hostapd_cli_cmd_deauthenticate
},
761 { "disassociate", hostapd_cli_cmd_disassociate
},
762 #ifdef CONFIG_IEEE80211W
763 { "sa_query", hostapd_cli_cmd_sa_query
},
764 #endif /* CONFIG_IEEE80211W */
766 { "wps_pin", hostapd_cli_cmd_wps_pin
},
767 { "wps_check_pin", hostapd_cli_cmd_wps_check_pin
},
768 { "wps_pbc", hostapd_cli_cmd_wps_pbc
},
769 { "wps_cancel", hostapd_cli_cmd_wps_cancel
},
770 #ifdef CONFIG_WPS_NFC
771 { "wps_nfc_tag_read", hostapd_cli_cmd_wps_nfc_tag_read
},
772 { "wps_nfc_config_token", hostapd_cli_cmd_wps_nfc_config_token
},
773 { "wps_nfc_token", hostapd_cli_cmd_wps_nfc_token
},
774 #endif /* CONFIG_WPS_NFC */
775 { "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin
},
776 { "wps_config", hostapd_cli_cmd_wps_config
},
777 #endif /* CONFIG_WPS */
778 { "ess_disassoc", hostapd_cli_cmd_ess_disassoc
},
779 { "get_config", hostapd_cli_cmd_get_config
},
780 { "help", hostapd_cli_cmd_help
},
781 { "interface", hostapd_cli_cmd_interface
},
782 { "level", hostapd_cli_cmd_level
},
783 { "license", hostapd_cli_cmd_license
},
784 { "quit", hostapd_cli_cmd_quit
},
785 { "set", hostapd_cli_cmd_set
},
786 { "get", hostapd_cli_cmd_get
},
791 static void wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
793 struct hostapd_cli_cmd
*cmd
, *match
= NULL
;
797 cmd
= hostapd_cli_commands
;
799 if (strncasecmp(cmd
->cmd
, argv
[0], strlen(argv
[0])) == 0) {
801 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
802 /* we have an exact match */
812 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
813 cmd
= hostapd_cli_commands
;
815 if (strncasecmp(cmd
->cmd
, argv
[0], strlen(argv
[0])) ==
817 printf(" %s", cmd
->cmd
);
822 } else if (count
== 0) {
823 printf("Unknown command '%s'\n", argv
[0]);
825 match
->handler(ctrl
, argc
- 1, &argv
[1]);
830 static void hostapd_cli_recv_pending(struct wpa_ctrl
*ctrl
, int in_read
,
834 if (ctrl_conn
== NULL
)
836 while (wpa_ctrl_pending(ctrl
)) {
838 size_t len
= sizeof(buf
) - 1;
839 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
842 hostapd_cli_action_process(buf
, len
);
844 if (in_read
&& first
)
850 printf("Could not read pending message.\n");
859 static int tokenize_cmd(char *cmd
, char *argv
[])
872 if (argc
== max_args
)
875 char *pos2
= os_strrchr(pos
, '"');
879 while (*pos
!= '\0' && *pos
!= ' ')
889 static void hostapd_cli_ping(void *eloop_ctx
, void *timeout_ctx
)
891 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
892 printf("Connection to hostapd lost - trying to reconnect\n");
893 hostapd_cli_close_connection();
896 ctrl_conn
= hostapd_cli_open_connection(ctrl_ifname
);
898 printf("Connection to hostapd re-established\n");
899 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
900 hostapd_cli_attached
= 1;
902 printf("Warning: Failed to attach to "
908 hostapd_cli_recv_pending(ctrl_conn
, 1, 0);
909 eloop_register_timeout(ping_interval
, 0, hostapd_cli_ping
, NULL
, NULL
);
913 static void hostapd_cli_eloop_terminate(int sig
, void *signal_ctx
)
919 static void hostapd_cli_edit_cmd_cb(void *ctx
, char *cmd
)
921 char *argv
[max_args
];
923 argc
= tokenize_cmd(cmd
, argv
);
925 wpa_request(ctrl_conn
, argc
, argv
);
929 static void hostapd_cli_edit_eof_cb(void *ctx
)
935 static void hostapd_cli_interactive(void)
937 printf("\nInteractive mode\n\n");
939 eloop_register_signal_terminate(hostapd_cli_eloop_terminate
, NULL
);
940 edit_init(hostapd_cli_edit_cmd_cb
, hostapd_cli_edit_eof_cb
,
941 NULL
, NULL
, NULL
, NULL
);
942 eloop_register_timeout(ping_interval
, 0, hostapd_cli_ping
, NULL
, NULL
);
946 edit_deinit(NULL
, NULL
);
947 eloop_cancel_timeout(hostapd_cli_ping
, NULL
, NULL
);
951 static void hostapd_cli_cleanup(void)
953 hostapd_cli_close_connection();
955 os_daemonize_terminate(pid_file
);
961 static void hostapd_cli_action(struct wpa_ctrl
*ctrl
)
969 fd
= wpa_ctrl_get_fd(ctrl
);
971 while (!hostapd_cli_quit
) {
974 tv
.tv_sec
= ping_interval
;
976 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
977 if (res
< 0 && errno
!= EINTR
) {
982 if (FD_ISSET(fd
, &rfds
))
983 hostapd_cli_recv_pending(ctrl
, 0, 1);
985 len
= sizeof(buf
) - 1;
986 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
987 hostapd_cli_action_process
) < 0 ||
988 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
989 printf("hostapd did not reply to PING "
990 "command - exiting\n");
998 int main(int argc
, char *argv
[])
1000 int warning_displayed
= 0;
1004 if (os_program_init())
1008 c
= getopt(argc
, argv
, "a:BhG:i:p:v");
1013 action_file
= optarg
;
1019 ping_interval
= atoi(optarg
);
1025 printf("%s\n", hostapd_cli_version
);
1028 os_free(ctrl_ifname
);
1029 ctrl_ifname
= os_strdup(optarg
);
1032 ctrl_iface_dir
= optarg
;
1040 interactive
= (argc
== optind
) && (action_file
== NULL
);
1043 printf("%s\n\n%s\n\n", hostapd_cli_version
,
1044 hostapd_cli_license
);
1051 if (ctrl_ifname
== NULL
) {
1052 struct dirent
*dent
;
1053 DIR *dir
= opendir(ctrl_iface_dir
);
1055 while ((dent
= readdir(dir
))) {
1056 if (os_strcmp(dent
->d_name
, ".") == 0
1058 os_strcmp(dent
->d_name
, "..") == 0)
1060 printf("Selected interface '%s'\n",
1062 ctrl_ifname
= os_strdup(dent
->d_name
);
1068 ctrl_conn
= hostapd_cli_open_connection(ctrl_ifname
);
1070 if (warning_displayed
)
1071 printf("Connection established.\n");
1076 perror("Failed to connect to hostapd - "
1081 if (!warning_displayed
) {
1082 printf("Could not connect to hostapd - re-trying\n");
1083 warning_displayed
= 1;
1089 if (interactive
|| action_file
) {
1090 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
1091 hostapd_cli_attached
= 1;
1093 printf("Warning: Failed to attach to hostapd.\n");
1099 if (daemonize
&& os_daemonize(pid_file
))
1103 hostapd_cli_interactive();
1104 else if (action_file
)
1105 hostapd_cli_action(ctrl_conn
);
1107 wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
1109 os_free(ctrl_ifname
);
1111 hostapd_cli_cleanup();