1 1.1 christos /* 2 1.1 christos * hostapd - command line interface for hostapd daemon 3 1.12 christos * Copyright (c) 2004-2022, Jouni Malinen <j (at) w1.fi> 4 1.1 christos * 5 1.5 christos * This software may be distributed under the terms of the BSD license. 6 1.5 christos * See README for more details. 7 1.1 christos */ 8 1.1 christos 9 1.1 christos #include "includes.h" 10 1.1 christos #include <dirent.h> 11 1.1 christos 12 1.1 christos #include "common/wpa_ctrl.h" 13 1.9 christos #include "common/ieee802_11_defs.h" 14 1.4 christos #include "utils/common.h" 15 1.4 christos #include "utils/eloop.h" 16 1.4 christos #include "utils/edit.h" 17 1.1 christos #include "common/version.h" 18 1.9 christos #include "common/cli.h" 19 1.1 christos 20 1.9 christos #ifndef CONFIG_NO_CTRL_IFACE 21 1.1 christos 22 1.9 christos static const char *const hostapd_cli_version = 23 1.1 christos "hostapd_cli v" VERSION_STR "\n" 24 1.12 christos "Copyright (c) 2004-2024, Jouni Malinen <j (at) w1.fi> and contributors"; 25 1.1 christos 26 1.1 christos static struct wpa_ctrl *ctrl_conn; 27 1.1 christos static int hostapd_cli_quit = 0; 28 1.1 christos static int hostapd_cli_attached = 0; 29 1.6 christos 30 1.6 christos #ifndef CONFIG_CTRL_IFACE_DIR 31 1.6 christos #define CONFIG_CTRL_IFACE_DIR "/var/run/hostapd" 32 1.6 christos #endif /* CONFIG_CTRL_IFACE_DIR */ 33 1.6 christos static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR; 34 1.9 christos static const char *client_socket_dir = NULL; 35 1.6 christos 36 1.1 christos static char *ctrl_ifname = NULL; 37 1.1 christos static const char *pid_file = NULL; 38 1.1 christos static const char *action_file = NULL; 39 1.1 christos static int ping_interval = 5; 40 1.4 christos static int interactive = 0; 41 1.9 christos static int event_handler_registered = 0; 42 1.9 christos 43 1.9 christos static DEFINE_DL_LIST(stations); /* struct cli_txt_entry */ 44 1.9 christos 45 1.9 christos static void print_help(FILE *stream, const char *cmd); 46 1.9 christos static char ** list_cmd_list(void); 47 1.9 christos static void hostapd_cli_receive(int sock, void *eloop_ctx, void *sock_ctx); 48 1.10 christos static void update_stations(struct wpa_ctrl *ctrl); 49 1.10 christos static void cli_event(const char *str); 50 1.1 christos 51 1.1 christos 52 1.1 christos static void usage(void) 53 1.1 christos { 54 1.1 christos fprintf(stderr, "%s\n", hostapd_cli_version); 55 1.1 christos fprintf(stderr, 56 1.1 christos "\n" 57 1.12 christos "usage: hostapd_cli [-p<path>] [-i<ifname>] [-hvBr] " 58 1.1 christos "[-a<path>] \\\n" 59 1.9 christos " [-P<pid file>] [-G<ping interval>] [command..]\n" 60 1.1 christos "\n" 61 1.1 christos "Options:\n" 62 1.1 christos " -h help (show this usage text)\n" 63 1.1 christos " -v shown version information\n" 64 1.1 christos " -p<path> path to find control sockets (default: " 65 1.1 christos "/var/run/hostapd)\n" 66 1.9 christos " -s<dir_path> dir path to open client sockets (default: " 67 1.9 christos CONFIG_CTRL_IFACE_DIR ")\n" 68 1.1 christos " -a<file> run in daemon mode executing the action file " 69 1.1 christos "based on events\n" 70 1.1 christos " from hostapd\n" 71 1.12 christos " -r try to reconnect when client socket is " 72 1.12 christos "disconnected.\n" 73 1.12 christos " This is useful only when used with -a.\n" 74 1.1 christos " -B run a daemon in the background\n" 75 1.1 christos " -i<ifname> Interface to listen on (default: first " 76 1.1 christos "interface found in the\n" 77 1.9 christos " socket path)\n\n"); 78 1.9 christos print_help(stderr, NULL); 79 1.9 christos } 80 1.9 christos 81 1.9 christos 82 1.9 christos static void register_event_handler(struct wpa_ctrl *ctrl) 83 1.9 christos { 84 1.9 christos if (!ctrl_conn) 85 1.9 christos return; 86 1.9 christos if (interactive) { 87 1.9 christos event_handler_registered = 88 1.9 christos !eloop_register_read_sock(wpa_ctrl_get_fd(ctrl), 89 1.9 christos hostapd_cli_receive, 90 1.9 christos NULL, NULL); 91 1.9 christos } 92 1.9 christos } 93 1.9 christos 94 1.9 christos 95 1.9 christos static void unregister_event_handler(struct wpa_ctrl *ctrl) 96 1.9 christos { 97 1.9 christos if (!ctrl_conn) 98 1.9 christos return; 99 1.9 christos if (interactive && event_handler_registered) { 100 1.9 christos eloop_unregister_read_sock(wpa_ctrl_get_fd(ctrl)); 101 1.9 christos event_handler_registered = 0; 102 1.9 christos } 103 1.1 christos } 104 1.1 christos 105 1.1 christos 106 1.1 christos static struct wpa_ctrl * hostapd_cli_open_connection(const char *ifname) 107 1.1 christos { 108 1.9 christos #ifndef CONFIG_CTRL_IFACE_UDP 109 1.1 christos char *cfile; 110 1.1 christos int flen; 111 1.9 christos #endif /* !CONFIG_CTRL_IFACE_UDP */ 112 1.1 christos 113 1.1 christos if (ifname == NULL) 114 1.1 christos return NULL; 115 1.1 christos 116 1.9 christos #ifdef CONFIG_CTRL_IFACE_UDP 117 1.9 christos ctrl_conn = wpa_ctrl_open(ifname); 118 1.9 christos return ctrl_conn; 119 1.9 christos #else /* CONFIG_CTRL_IFACE_UDP */ 120 1.1 christos flen = strlen(ctrl_iface_dir) + strlen(ifname) + 2; 121 1.1 christos cfile = malloc(flen); 122 1.1 christos if (cfile == NULL) 123 1.1 christos return NULL; 124 1.1 christos snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname); 125 1.1 christos 126 1.9 christos if (client_socket_dir && client_socket_dir[0] && 127 1.9 christos access(client_socket_dir, F_OK) < 0) { 128 1.9 christos perror(client_socket_dir); 129 1.9 christos free(cfile); 130 1.9 christos return NULL; 131 1.9 christos } 132 1.9 christos 133 1.9 christos ctrl_conn = wpa_ctrl_open2(cfile, client_socket_dir); 134 1.1 christos free(cfile); 135 1.1 christos return ctrl_conn; 136 1.9 christos #endif /* CONFIG_CTRL_IFACE_UDP */ 137 1.1 christos } 138 1.1 christos 139 1.1 christos 140 1.1 christos static void hostapd_cli_close_connection(void) 141 1.1 christos { 142 1.1 christos if (ctrl_conn == NULL) 143 1.1 christos return; 144 1.1 christos 145 1.9 christos unregister_event_handler(ctrl_conn); 146 1.1 christos if (hostapd_cli_attached) { 147 1.1 christos wpa_ctrl_detach(ctrl_conn); 148 1.1 christos hostapd_cli_attached = 0; 149 1.1 christos } 150 1.1 christos wpa_ctrl_close(ctrl_conn); 151 1.1 christos ctrl_conn = NULL; 152 1.1 christos } 153 1.1 christos 154 1.1 christos 155 1.10 christos static int hostapd_cli_reconnect(const char *ifname) 156 1.10 christos { 157 1.10 christos char *next_ctrl_ifname; 158 1.10 christos 159 1.10 christos hostapd_cli_close_connection(); 160 1.10 christos 161 1.10 christos if (!ifname) 162 1.10 christos return -1; 163 1.10 christos 164 1.10 christos next_ctrl_ifname = os_strdup(ifname); 165 1.10 christos os_free(ctrl_ifname); 166 1.10 christos ctrl_ifname = next_ctrl_ifname; 167 1.10 christos if (!ctrl_ifname) 168 1.10 christos return -1; 169 1.10 christos 170 1.10 christos ctrl_conn = hostapd_cli_open_connection(ctrl_ifname); 171 1.10 christos if (!ctrl_conn) 172 1.10 christos return -1; 173 1.10 christos if (!interactive && !action_file) 174 1.10 christos return 0; 175 1.10 christos if (wpa_ctrl_attach(ctrl_conn) == 0) { 176 1.10 christos hostapd_cli_attached = 1; 177 1.10 christos register_event_handler(ctrl_conn); 178 1.10 christos update_stations(ctrl_conn); 179 1.10 christos } else { 180 1.10 christos printf("Warning: Failed to attach to hostapd.\n"); 181 1.10 christos } 182 1.10 christos return 0; 183 1.10 christos } 184 1.10 christos 185 1.10 christos 186 1.1 christos static void hostapd_cli_msg_cb(char *msg, size_t len) 187 1.1 christos { 188 1.10 christos cli_event(msg); 189 1.1 christos printf("%s\n", msg); 190 1.1 christos } 191 1.1 christos 192 1.1 christos 193 1.10 christos static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd, int print) 194 1.1 christos { 195 1.1 christos char buf[4096]; 196 1.1 christos size_t len; 197 1.1 christos int ret; 198 1.1 christos 199 1.1 christos if (ctrl_conn == NULL) { 200 1.1 christos printf("Not connected to hostapd - command dropped.\n"); 201 1.1 christos return -1; 202 1.1 christos } 203 1.1 christos len = sizeof(buf) - 1; 204 1.1 christos ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, 205 1.1 christos hostapd_cli_msg_cb); 206 1.1 christos if (ret == -2) { 207 1.1 christos printf("'%s' command timed out.\n", cmd); 208 1.1 christos return -2; 209 1.1 christos } else if (ret < 0) { 210 1.1 christos printf("'%s' command failed.\n", cmd); 211 1.1 christos return -1; 212 1.1 christos } 213 1.1 christos if (print) { 214 1.1 christos buf[len] = '\0'; 215 1.1 christos printf("%s", buf); 216 1.1 christos } 217 1.1 christos return 0; 218 1.1 christos } 219 1.1 christos 220 1.1 christos 221 1.10 christos static inline int wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd) 222 1.1 christos { 223 1.1 christos return _wpa_ctrl_command(ctrl, cmd, 1); 224 1.1 christos } 225 1.1 christos 226 1.1 christos 227 1.9 christos static int hostapd_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, 228 1.9 christos int min_args, int argc, char *argv[]) 229 1.9 christos { 230 1.9 christos char buf[4096]; 231 1.9 christos 232 1.9 christos if (argc < min_args) { 233 1.9 christos printf("Invalid %s command - at least %d argument%s required.\n", 234 1.9 christos cmd, min_args, min_args > 1 ? "s are" : " is"); 235 1.9 christos return -1; 236 1.9 christos } 237 1.9 christos if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0) 238 1.9 christos return -1; 239 1.9 christos return wpa_ctrl_command(ctrl, buf); 240 1.9 christos } 241 1.9 christos 242 1.9 christos 243 1.1 christos static int hostapd_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[]) 244 1.1 christos { 245 1.1 christos return wpa_ctrl_command(ctrl, "PING"); 246 1.1 christos } 247 1.1 christos 248 1.1 christos 249 1.4 christos static int hostapd_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[]) 250 1.4 christos { 251 1.4 christos return wpa_ctrl_command(ctrl, "RELOG"); 252 1.4 christos } 253 1.4 christos 254 1.4 christos 255 1.12 christos static int hostapd_cli_cmd_close_log(struct wpa_ctrl *ctrl, int argc, 256 1.12 christos char *argv[]) 257 1.12 christos { 258 1.12 christos return wpa_ctrl_command(ctrl, "CLOSE_LOG"); 259 1.12 christos } 260 1.12 christos 261 1.12 christos 262 1.6 christos static int hostapd_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[]) 263 1.6 christos { 264 1.6 christos if (argc > 0 && os_strcmp(argv[0], "driver") == 0) 265 1.6 christos return wpa_ctrl_command(ctrl, "STATUS-DRIVER"); 266 1.6 christos return wpa_ctrl_command(ctrl, "STATUS"); 267 1.6 christos } 268 1.6 christos 269 1.6 christos 270 1.1 christos static int hostapd_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[]) 271 1.1 christos { 272 1.6 christos if (argc > 0) { 273 1.6 christos char buf[100]; 274 1.6 christos os_snprintf(buf, sizeof(buf), "MIB %s", argv[0]); 275 1.6 christos return wpa_ctrl_command(ctrl, buf); 276 1.6 christos } 277 1.1 christos return wpa_ctrl_command(ctrl, "MIB"); 278 1.1 christos } 279 1.1 christos 280 1.1 christos 281 1.1 christos static int hostapd_cli_exec(const char *program, const char *arg1, 282 1.1 christos const char *arg2) 283 1.1 christos { 284 1.6 christos char *arg; 285 1.1 christos size_t len; 286 1.1 christos int res; 287 1.1 christos 288 1.6 christos len = os_strlen(arg1) + os_strlen(arg2) + 2; 289 1.6 christos arg = os_malloc(len); 290 1.6 christos if (arg == NULL) 291 1.6 christos return -1; 292 1.6 christos os_snprintf(arg, len, "%s %s", arg1, arg2); 293 1.6 christos res = os_exec(program, arg, 1); 294 1.6 christos os_free(arg); 295 1.1 christos 296 1.6 christos return res; 297 1.1 christos } 298 1.1 christos 299 1.1 christos 300 1.1 christos static void hostapd_cli_action_process(char *msg, size_t len) 301 1.1 christos { 302 1.1 christos const char *pos; 303 1.1 christos 304 1.1 christos pos = msg; 305 1.1 christos if (*pos == '<') { 306 1.1 christos pos = os_strchr(pos, '>'); 307 1.1 christos if (pos) 308 1.1 christos pos++; 309 1.1 christos else 310 1.1 christos pos = msg; 311 1.1 christos } 312 1.1 christos 313 1.1 christos hostapd_cli_exec(action_file, ctrl_ifname, pos); 314 1.1 christos } 315 1.1 christos 316 1.1 christos 317 1.12 christos static void hostapd_cli_action_cb(char *msg, size_t len) 318 1.12 christos { 319 1.12 christos hostapd_cli_action_process(msg, len); 320 1.12 christos } 321 1.12 christos 322 1.12 christos 323 1.1 christos static int hostapd_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) 324 1.1 christos { 325 1.1 christos char buf[64]; 326 1.6 christos if (argc < 1) { 327 1.6 christos printf("Invalid 'sta' command - at least one argument, STA " 328 1.1 christos "address, is required.\n"); 329 1.1 christos return -1; 330 1.1 christos } 331 1.6 christos if (argc > 1) 332 1.6 christos snprintf(buf, sizeof(buf), "STA %s %s", argv[0], argv[1]); 333 1.6 christos else 334 1.6 christos snprintf(buf, sizeof(buf), "STA %s", argv[0]); 335 1.1 christos return wpa_ctrl_command(ctrl, buf); 336 1.1 christos } 337 1.1 christos 338 1.1 christos 339 1.10 christos static char ** hostapd_complete_stations(const char *str, int pos) 340 1.10 christos { 341 1.10 christos int arg = get_cmd_arg_num(str, pos); 342 1.10 christos char **res = NULL; 343 1.10 christos 344 1.10 christos switch (arg) { 345 1.10 christos case 1: 346 1.10 christos res = cli_txt_list_array(&stations); 347 1.10 christos break; 348 1.10 christos } 349 1.10 christos 350 1.10 christos return res; 351 1.10 christos } 352 1.10 christos 353 1.10 christos 354 1.1 christos static int hostapd_cli_cmd_new_sta(struct wpa_ctrl *ctrl, int argc, 355 1.1 christos char *argv[]) 356 1.1 christos { 357 1.1 christos char buf[64]; 358 1.1 christos if (argc != 1) { 359 1.1 christos printf("Invalid 'new_sta' command - exactly one argument, STA " 360 1.1 christos "address, is required.\n"); 361 1.1 christos return -1; 362 1.1 christos } 363 1.1 christos snprintf(buf, sizeof(buf), "NEW_STA %s", argv[0]); 364 1.1 christos return wpa_ctrl_command(ctrl, buf); 365 1.1 christos } 366 1.1 christos 367 1.1 christos 368 1.1 christos static int hostapd_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc, 369 1.1 christos char *argv[]) 370 1.1 christos { 371 1.1 christos char buf[64]; 372 1.1 christos if (argc < 1) { 373 1.1 christos printf("Invalid 'deauthenticate' command - exactly one " 374 1.1 christos "argument, STA address, is required.\n"); 375 1.1 christos return -1; 376 1.1 christos } 377 1.1 christos if (argc > 1) 378 1.1 christos os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s %s", 379 1.1 christos argv[0], argv[1]); 380 1.1 christos else 381 1.1 christos os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s", argv[0]); 382 1.1 christos return wpa_ctrl_command(ctrl, buf); 383 1.1 christos } 384 1.1 christos 385 1.1 christos 386 1.1 christos static int hostapd_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc, 387 1.1 christos char *argv[]) 388 1.1 christos { 389 1.1 christos char buf[64]; 390 1.1 christos if (argc < 1) { 391 1.1 christos printf("Invalid 'disassociate' command - exactly one " 392 1.1 christos "argument, STA address, is required.\n"); 393 1.1 christos return -1; 394 1.1 christos } 395 1.1 christos if (argc > 1) 396 1.1 christos os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s %s", 397 1.1 christos argv[0], argv[1]); 398 1.1 christos else 399 1.1 christos os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s", argv[0]); 400 1.1 christos return wpa_ctrl_command(ctrl, buf); 401 1.1 christos } 402 1.1 christos 403 1.1 christos 404 1.9 christos #ifdef CONFIG_TAXONOMY 405 1.9 christos static int hostapd_cli_cmd_signature(struct wpa_ctrl *ctrl, int argc, 406 1.9 christos char *argv[]) 407 1.9 christos { 408 1.9 christos char buf[64]; 409 1.9 christos 410 1.9 christos if (argc != 1) { 411 1.9 christos printf("Invalid 'signature' command - exactly one argument, STA address, is required.\n"); 412 1.9 christos return -1; 413 1.9 christos } 414 1.9 christos os_snprintf(buf, sizeof(buf), "SIGNATURE %s", argv[0]); 415 1.9 christos return wpa_ctrl_command(ctrl, buf); 416 1.9 christos } 417 1.9 christos #endif /* CONFIG_TAXONOMY */ 418 1.9 christos 419 1.9 christos 420 1.1 christos static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc, 421 1.1 christos char *argv[]) 422 1.1 christos { 423 1.1 christos char buf[64]; 424 1.1 christos if (argc != 1) { 425 1.1 christos printf("Invalid 'sa_query' command - exactly one argument, " 426 1.1 christos "STA address, is required.\n"); 427 1.1 christos return -1; 428 1.1 christos } 429 1.1 christos snprintf(buf, sizeof(buf), "SA_QUERY %s", argv[0]); 430 1.1 christos return wpa_ctrl_command(ctrl, buf); 431 1.1 christos } 432 1.1 christos 433 1.1 christos 434 1.1 christos #ifdef CONFIG_WPS 435 1.1 christos static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, 436 1.1 christos char *argv[]) 437 1.1 christos { 438 1.4 christos char buf[256]; 439 1.1 christos if (argc < 2) { 440 1.1 christos printf("Invalid 'wps_pin' command - at least two arguments, " 441 1.1 christos "UUID and PIN, are required.\n"); 442 1.1 christos return -1; 443 1.1 christos } 444 1.4 christos if (argc > 3) 445 1.4 christos snprintf(buf, sizeof(buf), "WPS_PIN %s %s %s %s", 446 1.4 christos argv[0], argv[1], argv[2], argv[3]); 447 1.4 christos else if (argc > 2) 448 1.1 christos snprintf(buf, sizeof(buf), "WPS_PIN %s %s %s", 449 1.1 christos argv[0], argv[1], argv[2]); 450 1.1 christos else 451 1.1 christos snprintf(buf, sizeof(buf), "WPS_PIN %s %s", argv[0], argv[1]); 452 1.1 christos return wpa_ctrl_command(ctrl, buf); 453 1.1 christos } 454 1.1 christos 455 1.1 christos 456 1.4 christos static int hostapd_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc, 457 1.4 christos char *argv[]) 458 1.4 christos { 459 1.4 christos char cmd[256]; 460 1.4 christos int res; 461 1.4 christos 462 1.4 christos if (argc != 1 && argc != 2) { 463 1.4 christos printf("Invalid WPS_CHECK_PIN command: needs one argument:\n" 464 1.4 christos "- PIN to be verified\n"); 465 1.4 christos return -1; 466 1.4 christos } 467 1.4 christos 468 1.4 christos if (argc == 2) 469 1.4 christos res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s", 470 1.4 christos argv[0], argv[1]); 471 1.4 christos else 472 1.4 christos res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s", 473 1.4 christos argv[0]); 474 1.7 christos if (os_snprintf_error(sizeof(cmd), res)) { 475 1.4 christos printf("Too long WPS_CHECK_PIN command.\n"); 476 1.4 christos return -1; 477 1.4 christos } 478 1.4 christos return wpa_ctrl_command(ctrl, cmd); 479 1.4 christos } 480 1.4 christos 481 1.4 christos 482 1.1 christos static int hostapd_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, 483 1.1 christos char *argv[]) 484 1.1 christos { 485 1.1 christos return wpa_ctrl_command(ctrl, "WPS_PBC"); 486 1.1 christos } 487 1.1 christos 488 1.1 christos 489 1.5 christos static int hostapd_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc, 490 1.5 christos char *argv[]) 491 1.5 christos { 492 1.5 christos return wpa_ctrl_command(ctrl, "WPS_CANCEL"); 493 1.5 christos } 494 1.5 christos 495 1.5 christos 496 1.5 christos #ifdef CONFIG_WPS_NFC 497 1.5 christos static int hostapd_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc, 498 1.5 christos char *argv[]) 499 1.5 christos { 500 1.5 christos int ret; 501 1.5 christos char *buf; 502 1.5 christos size_t buflen; 503 1.5 christos 504 1.5 christos if (argc != 1) { 505 1.5 christos printf("Invalid 'wps_nfc_tag_read' command - one argument " 506 1.5 christos "is required.\n"); 507 1.5 christos return -1; 508 1.5 christos } 509 1.5 christos 510 1.5 christos buflen = 18 + os_strlen(argv[0]); 511 1.5 christos buf = os_malloc(buflen); 512 1.5 christos if (buf == NULL) 513 1.5 christos return -1; 514 1.5 christos os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]); 515 1.5 christos 516 1.5 christos ret = wpa_ctrl_command(ctrl, buf); 517 1.5 christos os_free(buf); 518 1.5 christos 519 1.5 christos return ret; 520 1.5 christos } 521 1.5 christos 522 1.5 christos 523 1.5 christos static int hostapd_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, 524 1.5 christos int argc, char *argv[]) 525 1.5 christos { 526 1.5 christos char cmd[64]; 527 1.5 christos int res; 528 1.5 christos 529 1.5 christos if (argc != 1) { 530 1.5 christos printf("Invalid 'wps_nfc_config_token' command - one argument " 531 1.5 christos "is required.\n"); 532 1.5 christos return -1; 533 1.5 christos } 534 1.5 christos 535 1.5 christos res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC_CONFIG_TOKEN %s", 536 1.5 christos argv[0]); 537 1.7 christos if (os_snprintf_error(sizeof(cmd), res)) { 538 1.5 christos printf("Too long WPS_NFC_CONFIG_TOKEN command.\n"); 539 1.5 christos return -1; 540 1.5 christos } 541 1.5 christos return wpa_ctrl_command(ctrl, cmd); 542 1.5 christos } 543 1.5 christos 544 1.5 christos 545 1.5 christos static int hostapd_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, 546 1.5 christos int argc, char *argv[]) 547 1.1 christos { 548 1.5 christos char cmd[64]; 549 1.1 christos int res; 550 1.1 christos 551 1.5 christos if (argc != 1) { 552 1.5 christos printf("Invalid 'wps_nfc_token' command - one argument is " 553 1.5 christos "required.\n"); 554 1.1 christos return -1; 555 1.1 christos } 556 1.1 christos 557 1.5 christos res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC_TOKEN %s", argv[0]); 558 1.7 christos if (os_snprintf_error(sizeof(cmd), res)) { 559 1.5 christos printf("Too long WPS_NFC_TOKEN command.\n"); 560 1.1 christos return -1; 561 1.1 christos } 562 1.1 christos return wpa_ctrl_command(ctrl, cmd); 563 1.1 christos } 564 1.6 christos 565 1.6 christos 566 1.6 christos static int hostapd_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, 567 1.6 christos int argc, char *argv[]) 568 1.6 christos { 569 1.6 christos char cmd[64]; 570 1.6 christos int res; 571 1.6 christos 572 1.6 christos if (argc != 2) { 573 1.6 christos printf("Invalid 'nfc_get_handover_sel' command - two arguments " 574 1.6 christos "are required.\n"); 575 1.6 christos return -1; 576 1.6 christos } 577 1.6 christos 578 1.6 christos res = os_snprintf(cmd, sizeof(cmd), "NFC_GET_HANDOVER_SEL %s %s", 579 1.6 christos argv[0], argv[1]); 580 1.7 christos if (os_snprintf_error(sizeof(cmd), res)) { 581 1.6 christos printf("Too long NFC_GET_HANDOVER_SEL command.\n"); 582 1.6 christos return -1; 583 1.6 christos } 584 1.6 christos return wpa_ctrl_command(ctrl, cmd); 585 1.6 christos } 586 1.6 christos 587 1.5 christos #endif /* CONFIG_WPS_NFC */ 588 1.3 christos 589 1.3 christos 590 1.3 christos static int hostapd_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc, 591 1.3 christos char *argv[]) 592 1.3 christos { 593 1.3 christos char buf[64]; 594 1.3 christos if (argc < 1) { 595 1.3 christos printf("Invalid 'wps_ap_pin' command - at least one argument " 596 1.3 christos "is required.\n"); 597 1.3 christos return -1; 598 1.3 christos } 599 1.3 christos if (argc > 2) 600 1.3 christos snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s %s", 601 1.3 christos argv[0], argv[1], argv[2]); 602 1.3 christos else if (argc > 1) 603 1.3 christos snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s", 604 1.3 christos argv[0], argv[1]); 605 1.3 christos else 606 1.3 christos snprintf(buf, sizeof(buf), "WPS_AP_PIN %s", argv[0]); 607 1.3 christos return wpa_ctrl_command(ctrl, buf); 608 1.3 christos } 609 1.4 christos 610 1.4 christos 611 1.6 christos static int hostapd_cli_cmd_wps_get_status(struct wpa_ctrl *ctrl, int argc, 612 1.6 christos char *argv[]) 613 1.6 christos { 614 1.6 christos return wpa_ctrl_command(ctrl, "WPS_GET_STATUS"); 615 1.6 christos } 616 1.6 christos 617 1.6 christos 618 1.4 christos static int hostapd_cli_cmd_wps_config(struct wpa_ctrl *ctrl, int argc, 619 1.4 christos char *argv[]) 620 1.4 christos { 621 1.4 christos char buf[256]; 622 1.9 christos char ssid_hex[2 * SSID_MAX_LEN + 1]; 623 1.4 christos char key_hex[2 * 64 + 1]; 624 1.4 christos int i; 625 1.4 christos 626 1.4 christos if (argc < 1) { 627 1.4 christos printf("Invalid 'wps_config' command - at least two arguments " 628 1.4 christos "are required.\n"); 629 1.4 christos return -1; 630 1.4 christos } 631 1.4 christos 632 1.4 christos ssid_hex[0] = '\0'; 633 1.9 christos for (i = 0; i < SSID_MAX_LEN; i++) { 634 1.4 christos if (argv[0][i] == '\0') 635 1.4 christos break; 636 1.4 christos os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[0][i]); 637 1.4 christos } 638 1.4 christos 639 1.4 christos key_hex[0] = '\0'; 640 1.4 christos if (argc > 3) { 641 1.4 christos for (i = 0; i < 64; i++) { 642 1.4 christos if (argv[3][i] == '\0') 643 1.4 christos break; 644 1.4 christos os_snprintf(&key_hex[i * 2], 3, "%02x", 645 1.4 christos argv[3][i]); 646 1.4 christos } 647 1.4 christos } 648 1.4 christos 649 1.4 christos if (argc > 3) 650 1.4 christos snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s %s %s", 651 1.4 christos ssid_hex, argv[1], argv[2], key_hex); 652 1.4 christos else if (argc > 2) 653 1.4 christos snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s %s", 654 1.4 christos ssid_hex, argv[1], argv[2]); 655 1.4 christos else 656 1.4 christos snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s", 657 1.4 christos ssid_hex, argv[1]); 658 1.4 christos return wpa_ctrl_command(ctrl, buf); 659 1.4 christos } 660 1.1 christos #endif /* CONFIG_WPS */ 661 1.1 christos 662 1.1 christos 663 1.5 christos static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc, 664 1.5 christos char *argv[]) 665 1.5 christos { 666 1.5 christos char buf[300]; 667 1.5 christos int res; 668 1.5 christos 669 1.5 christos if (argc < 2) { 670 1.5 christos printf("Invalid 'disassoc_imminent' command - two arguments " 671 1.5 christos "(STA addr and Disassociation Timer) are needed\n"); 672 1.5 christos return -1; 673 1.5 christos } 674 1.5 christos 675 1.5 christos res = os_snprintf(buf, sizeof(buf), "DISASSOC_IMMINENT %s %s", 676 1.5 christos argv[0], argv[1]); 677 1.7 christos if (os_snprintf_error(sizeof(buf), res)) 678 1.5 christos return -1; 679 1.5 christos return wpa_ctrl_command(ctrl, buf); 680 1.5 christos } 681 1.5 christos 682 1.5 christos 683 1.4 christos static int hostapd_cli_cmd_ess_disassoc(struct wpa_ctrl *ctrl, int argc, 684 1.4 christos char *argv[]) 685 1.4 christos { 686 1.4 christos char buf[300]; 687 1.4 christos int res; 688 1.4 christos 689 1.6 christos if (argc < 3) { 690 1.6 christos printf("Invalid 'ess_disassoc' command - three arguments (STA " 691 1.6 christos "addr, disassoc timer, and URL) are needed\n"); 692 1.4 christos return -1; 693 1.4 christos } 694 1.4 christos 695 1.6 christos res = os_snprintf(buf, sizeof(buf), "ESS_DISASSOC %s %s %s", 696 1.6 christos argv[0], argv[1], argv[2]); 697 1.7 christos if (os_snprintf_error(sizeof(buf), res)) 698 1.4 christos return -1; 699 1.4 christos return wpa_ctrl_command(ctrl, buf); 700 1.4 christos } 701 1.4 christos 702 1.4 christos 703 1.7 christos static int hostapd_cli_cmd_bss_tm_req(struct wpa_ctrl *ctrl, int argc, 704 1.7 christos char *argv[]) 705 1.7 christos { 706 1.7 christos char buf[2000], *tmp; 707 1.7 christos int res, i, total; 708 1.7 christos 709 1.7 christos if (argc < 1) { 710 1.7 christos printf("Invalid 'bss_tm_req' command - at least one argument (STA addr) is needed\n"); 711 1.7 christos return -1; 712 1.7 christos } 713 1.7 christos 714 1.7 christos res = os_snprintf(buf, sizeof(buf), "BSS_TM_REQ %s", argv[0]); 715 1.7 christos if (os_snprintf_error(sizeof(buf), res)) 716 1.7 christos return -1; 717 1.7 christos 718 1.7 christos total = res; 719 1.7 christos for (i = 1; i < argc; i++) { 720 1.7 christos tmp = &buf[total]; 721 1.7 christos res = os_snprintf(tmp, sizeof(buf) - total, " %s", argv[i]); 722 1.7 christos if (os_snprintf_error(sizeof(buf) - total, res)) 723 1.7 christos return -1; 724 1.7 christos total += res; 725 1.7 christos } 726 1.7 christos return wpa_ctrl_command(ctrl, buf); 727 1.7 christos } 728 1.7 christos 729 1.7 christos 730 1.4 christos static int hostapd_cli_cmd_get_config(struct wpa_ctrl *ctrl, int argc, 731 1.4 christos char *argv[]) 732 1.4 christos { 733 1.4 christos return wpa_ctrl_command(ctrl, "GET_CONFIG"); 734 1.4 christos } 735 1.4 christos 736 1.4 christos 737 1.10 christos static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, const char *cmd, 738 1.10 christos char *addr, size_t addr_len, int print) 739 1.1 christos { 740 1.1 christos char buf[4096], *pos; 741 1.1 christos size_t len; 742 1.1 christos int ret; 743 1.1 christos 744 1.1 christos if (ctrl_conn == NULL) { 745 1.1 christos printf("Not connected to hostapd - command dropped.\n"); 746 1.1 christos return -1; 747 1.1 christos } 748 1.1 christos len = sizeof(buf) - 1; 749 1.1 christos ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, 750 1.1 christos hostapd_cli_msg_cb); 751 1.1 christos if (ret == -2) { 752 1.1 christos printf("'%s' command timed out.\n", cmd); 753 1.1 christos return -2; 754 1.1 christos } else if (ret < 0) { 755 1.1 christos printf("'%s' command failed.\n", cmd); 756 1.1 christos return -1; 757 1.1 christos } 758 1.1 christos 759 1.1 christos buf[len] = '\0'; 760 1.1 christos if (memcmp(buf, "FAIL", 4) == 0) 761 1.1 christos return -1; 762 1.10 christos if (print) 763 1.10 christos printf("%s", buf); 764 1.1 christos 765 1.1 christos pos = buf; 766 1.1 christos while (*pos != '\0' && *pos != '\n') 767 1.1 christos pos++; 768 1.1 christos *pos = '\0'; 769 1.1 christos os_strlcpy(addr, buf, addr_len); 770 1.1 christos return 0; 771 1.1 christos } 772 1.1 christos 773 1.1 christos 774 1.1 christos static int hostapd_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, 775 1.1 christos char *argv[]) 776 1.1 christos { 777 1.1 christos char addr[32], cmd[64]; 778 1.1 christos 779 1.10 christos if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 1)) 780 1.1 christos return 0; 781 1.1 christos do { 782 1.1 christos snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); 783 1.10 christos } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 1) == 0); 784 1.1 christos 785 1.1 christos return -1; 786 1.1 christos } 787 1.1 christos 788 1.1 christos 789 1.10 christos static int hostapd_cli_cmd_list_sta(struct wpa_ctrl *ctrl, int argc, 790 1.10 christos char *argv[]) 791 1.10 christos { 792 1.10 christos char addr[32], cmd[64]; 793 1.10 christos 794 1.10 christos if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 0)) 795 1.10 christos return 0; 796 1.10 christos do { 797 1.10 christos if (os_strcmp(addr, "") != 0) 798 1.10 christos printf("%s\n", addr); 799 1.10 christos os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); 800 1.10 christos } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 0) == 0); 801 1.10 christos 802 1.10 christos return 0; 803 1.10 christos } 804 1.10 christos 805 1.10 christos 806 1.1 christos static int hostapd_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[]) 807 1.1 christos { 808 1.9 christos print_help(stdout, argc > 0 ? argv[0] : NULL); 809 1.1 christos return 0; 810 1.1 christos } 811 1.1 christos 812 1.1 christos 813 1.9 christos static char ** hostapd_cli_complete_help(const char *str, int pos) 814 1.9 christos { 815 1.9 christos int arg = get_cmd_arg_num(str, pos); 816 1.9 christos char **res = NULL; 817 1.9 christos 818 1.9 christos switch (arg) { 819 1.9 christos case 1: 820 1.9 christos res = list_cmd_list(); 821 1.9 christos break; 822 1.9 christos } 823 1.9 christos 824 1.9 christos return res; 825 1.9 christos } 826 1.9 christos 827 1.9 christos 828 1.1 christos static int hostapd_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, 829 1.1 christos char *argv[]) 830 1.1 christos { 831 1.9 christos printf("%s\n\n%s\n", hostapd_cli_version, cli_full_license); 832 1.1 christos return 0; 833 1.1 christos } 834 1.1 christos 835 1.1 christos 836 1.6 christos static int hostapd_cli_cmd_set_qos_map_set(struct wpa_ctrl *ctrl, 837 1.6 christos int argc, char *argv[]) 838 1.6 christos { 839 1.6 christos char buf[200]; 840 1.6 christos int res; 841 1.6 christos 842 1.6 christos if (argc != 1) { 843 1.6 christos printf("Invalid 'set_qos_map_set' command - " 844 1.6 christos "one argument (comma delimited QoS map set) " 845 1.6 christos "is needed\n"); 846 1.6 christos return -1; 847 1.6 christos } 848 1.6 christos 849 1.6 christos res = os_snprintf(buf, sizeof(buf), "SET_QOS_MAP_SET %s", argv[0]); 850 1.7 christos if (os_snprintf_error(sizeof(buf), res)) 851 1.6 christos return -1; 852 1.6 christos return wpa_ctrl_command(ctrl, buf); 853 1.6 christos } 854 1.6 christos 855 1.6 christos 856 1.6 christos static int hostapd_cli_cmd_send_qos_map_conf(struct wpa_ctrl *ctrl, 857 1.6 christos int argc, char *argv[]) 858 1.6 christos { 859 1.6 christos char buf[50]; 860 1.6 christos int res; 861 1.6 christos 862 1.6 christos if (argc != 1) { 863 1.6 christos printf("Invalid 'send_qos_map_conf' command - " 864 1.6 christos "one argument (STA addr) is needed\n"); 865 1.6 christos return -1; 866 1.6 christos } 867 1.6 christos 868 1.6 christos res = os_snprintf(buf, sizeof(buf), "SEND_QOS_MAP_CONF %s", argv[0]); 869 1.7 christos if (os_snprintf_error(sizeof(buf), res)) 870 1.6 christos return -1; 871 1.6 christos return wpa_ctrl_command(ctrl, buf); 872 1.6 christos } 873 1.6 christos 874 1.6 christos 875 1.6 christos static int hostapd_cli_cmd_hs20_wnm_notif(struct wpa_ctrl *ctrl, int argc, 876 1.6 christos char *argv[]) 877 1.6 christos { 878 1.6 christos char buf[300]; 879 1.6 christos int res; 880 1.6 christos 881 1.6 christos if (argc < 2) { 882 1.6 christos printf("Invalid 'hs20_wnm_notif' command - two arguments (STA " 883 1.6 christos "addr and URL) are needed\n"); 884 1.6 christos return -1; 885 1.6 christos } 886 1.6 christos 887 1.6 christos res = os_snprintf(buf, sizeof(buf), "HS20_WNM_NOTIF %s %s", 888 1.6 christos argv[0], argv[1]); 889 1.7 christos if (os_snprintf_error(sizeof(buf), res)) 890 1.6 christos return -1; 891 1.6 christos return wpa_ctrl_command(ctrl, buf); 892 1.6 christos } 893 1.6 christos 894 1.6 christos 895 1.6 christos static int hostapd_cli_cmd_hs20_deauth_req(struct wpa_ctrl *ctrl, int argc, 896 1.6 christos char *argv[]) 897 1.6 christos { 898 1.6 christos char buf[300]; 899 1.6 christos int res; 900 1.6 christos 901 1.6 christos if (argc < 3) { 902 1.6 christos printf("Invalid 'hs20_deauth_req' command - at least three arguments (STA addr, Code, Re-auth Delay) are needed\n"); 903 1.6 christos return -1; 904 1.6 christos } 905 1.6 christos 906 1.6 christos if (argc > 3) 907 1.6 christos res = os_snprintf(buf, sizeof(buf), 908 1.6 christos "HS20_DEAUTH_REQ %s %s %s %s", 909 1.6 christos argv[0], argv[1], argv[2], argv[3]); 910 1.6 christos else 911 1.6 christos res = os_snprintf(buf, sizeof(buf), 912 1.6 christos "HS20_DEAUTH_REQ %s %s %s", 913 1.6 christos argv[0], argv[1], argv[2]); 914 1.7 christos if (os_snprintf_error(sizeof(buf), res)) 915 1.6 christos return -1; 916 1.6 christos return wpa_ctrl_command(ctrl, buf); 917 1.6 christos } 918 1.6 christos 919 1.6 christos 920 1.1 christos static int hostapd_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[]) 921 1.1 christos { 922 1.1 christos hostapd_cli_quit = 1; 923 1.4 christos if (interactive) 924 1.4 christos eloop_terminate(); 925 1.1 christos return 0; 926 1.1 christos } 927 1.1 christos 928 1.1 christos 929 1.1 christos static int hostapd_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) 930 1.1 christos { 931 1.1 christos char cmd[256]; 932 1.1 christos if (argc != 1) { 933 1.1 christos printf("Invalid LEVEL command: needs one argument (debug " 934 1.1 christos "level)\n"); 935 1.1 christos return 0; 936 1.1 christos } 937 1.1 christos snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]); 938 1.1 christos return wpa_ctrl_command(ctrl, cmd); 939 1.1 christos } 940 1.1 christos 941 1.1 christos 942 1.10 christos static void update_stations(struct wpa_ctrl *ctrl) 943 1.10 christos { 944 1.10 christos char addr[32], cmd[64]; 945 1.10 christos 946 1.10 christos if (!ctrl || !interactive) 947 1.10 christos return; 948 1.10 christos 949 1.10 christos cli_txt_list_flush(&stations); 950 1.10 christos 951 1.10 christos if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 0)) 952 1.10 christos return; 953 1.10 christos do { 954 1.10 christos if (os_strcmp(addr, "") != 0) 955 1.10 christos cli_txt_list_add(&stations, addr); 956 1.10 christos os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); 957 1.10 christos } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 0) == 0); 958 1.10 christos } 959 1.10 christos 960 1.10 christos 961 1.9 christos static void hostapd_cli_get_interfaces(struct wpa_ctrl *ctrl, 962 1.9 christos struct dl_list *interfaces) 963 1.9 christos { 964 1.9 christos struct dirent *dent; 965 1.9 christos DIR *dir; 966 1.9 christos 967 1.9 christos if (!ctrl || !interfaces) 968 1.9 christos return; 969 1.9 christos dir = opendir(ctrl_iface_dir); 970 1.9 christos if (dir == NULL) 971 1.9 christos return; 972 1.9 christos 973 1.9 christos while ((dent = readdir(dir))) { 974 1.9 christos if (strcmp(dent->d_name, ".") == 0 || 975 1.9 christos strcmp(dent->d_name, "..") == 0) 976 1.9 christos continue; 977 1.9 christos cli_txt_list_add(interfaces, dent->d_name); 978 1.9 christos } 979 1.9 christos closedir(dir); 980 1.9 christos } 981 1.9 christos 982 1.9 christos 983 1.1 christos static void hostapd_cli_list_interfaces(struct wpa_ctrl *ctrl) 984 1.1 christos { 985 1.1 christos struct dirent *dent; 986 1.1 christos DIR *dir; 987 1.1 christos 988 1.1 christos dir = opendir(ctrl_iface_dir); 989 1.1 christos if (dir == NULL) { 990 1.1 christos printf("Control interface directory '%s' could not be " 991 1.12 christos "opened.\n", ctrl_iface_dir); 992 1.1 christos return; 993 1.1 christos } 994 1.1 christos 995 1.1 christos printf("Available interfaces:\n"); 996 1.1 christos while ((dent = readdir(dir))) { 997 1.1 christos if (strcmp(dent->d_name, ".") == 0 || 998 1.1 christos strcmp(dent->d_name, "..") == 0) 999 1.1 christos continue; 1000 1.1 christos printf("%s\n", dent->d_name); 1001 1.1 christos } 1002 1.1 christos closedir(dir); 1003 1.1 christos } 1004 1.1 christos 1005 1.1 christos 1006 1.1 christos static int hostapd_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, 1007 1.1 christos char *argv[]) 1008 1.1 christos { 1009 1.1 christos if (argc < 1) { 1010 1.1 christos hostapd_cli_list_interfaces(ctrl); 1011 1.1 christos return 0; 1012 1.1 christos } 1013 1.10 christos if (hostapd_cli_reconnect(argv[0]) != 0) { 1014 1.1 christos printf("Could not connect to interface '%s' - re-trying\n", 1015 1.1 christos ctrl_ifname); 1016 1.1 christos } 1017 1.1 christos return 0; 1018 1.1 christos } 1019 1.1 christos 1020 1.1 christos 1021 1.9 christos static char ** hostapd_complete_interface(const char *str, int pos) 1022 1.9 christos { 1023 1.9 christos int arg = get_cmd_arg_num(str, pos); 1024 1.9 christos char **res = NULL; 1025 1.9 christos DEFINE_DL_LIST(interfaces); 1026 1.9 christos 1027 1.9 christos switch (arg) { 1028 1.9 christos case 1: 1029 1.9 christos hostapd_cli_get_interfaces(ctrl_conn, &interfaces); 1030 1.9 christos res = cli_txt_list_array(&interfaces); 1031 1.9 christos cli_txt_list_flush(&interfaces); 1032 1.9 christos break; 1033 1.9 christos } 1034 1.9 christos 1035 1.9 christos return res; 1036 1.9 christos } 1037 1.9 christos 1038 1.9 christos 1039 1.4 christos static int hostapd_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1040 1.4 christos { 1041 1.10 christos char cmd[2048]; 1042 1.4 christos int res; 1043 1.4 christos 1044 1.4 christos if (argc != 2) { 1045 1.4 christos printf("Invalid SET command: needs two arguments (variable " 1046 1.4 christos "name and value)\n"); 1047 1.4 christos return -1; 1048 1.4 christos } 1049 1.4 christos 1050 1.4 christos res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]); 1051 1.7 christos if (os_snprintf_error(sizeof(cmd), res)) { 1052 1.4 christos printf("Too long SET command.\n"); 1053 1.4 christos return -1; 1054 1.4 christos } 1055 1.4 christos return wpa_ctrl_command(ctrl, cmd); 1056 1.4 christos } 1057 1.4 christos 1058 1.4 christos 1059 1.10 christos static char ** hostapd_complete_set(const char *str, int pos) 1060 1.10 christos { 1061 1.10 christos int arg = get_cmd_arg_num(str, pos); 1062 1.10 christos const char *fields[] = { 1063 1.10 christos #ifdef CONFIG_WPS_TESTING 1064 1.12 christos "wps_version_number", "wps_testing_stub_cred", 1065 1.10 christos "wps_corrupt_pkhash", 1066 1.10 christos #endif /* CONFIG_WPS_TESTING */ 1067 1.10 christos #ifdef CONFIG_INTERWORKING 1068 1.10 christos "gas_frag_limit", 1069 1.10 christos #endif /* CONFIG_INTERWORKING */ 1070 1.10 christos #ifdef CONFIG_TESTING_OPTIONS 1071 1.10 christos "ext_mgmt_frame_handling", "ext_eapol_frame_io", 1072 1.10 christos #endif /* CONFIG_TESTING_OPTIONS */ 1073 1.10 christos #ifdef CONFIG_MBO 1074 1.10 christos "mbo_assoc_disallow", 1075 1.10 christos #endif /* CONFIG_MBO */ 1076 1.10 christos "deny_mac_file", "accept_mac_file", 1077 1.10 christos }; 1078 1.10 christos int i, num_fields = ARRAY_SIZE(fields); 1079 1.10 christos 1080 1.10 christos if (arg == 1) { 1081 1.10 christos char **res; 1082 1.10 christos 1083 1.10 christos res = os_calloc(num_fields + 1, sizeof(char *)); 1084 1.10 christos if (!res) 1085 1.10 christos return NULL; 1086 1.10 christos for (i = 0; i < num_fields; i++) { 1087 1.10 christos res[i] = os_strdup(fields[i]); 1088 1.10 christos if (!res[i]) 1089 1.10 christos return res; 1090 1.10 christos } 1091 1.10 christos return res; 1092 1.10 christos } 1093 1.10 christos return NULL; 1094 1.10 christos } 1095 1.10 christos 1096 1.10 christos 1097 1.4 christos static int hostapd_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1098 1.4 christos { 1099 1.4 christos char cmd[256]; 1100 1.4 christos int res; 1101 1.4 christos 1102 1.4 christos if (argc != 1) { 1103 1.4 christos printf("Invalid GET command: needs one argument (variable " 1104 1.4 christos "name)\n"); 1105 1.4 christos return -1; 1106 1.4 christos } 1107 1.4 christos 1108 1.4 christos res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]); 1109 1.7 christos if (os_snprintf_error(sizeof(cmd), res)) { 1110 1.4 christos printf("Too long GET command.\n"); 1111 1.4 christos return -1; 1112 1.4 christos } 1113 1.4 christos return wpa_ctrl_command(ctrl, cmd); 1114 1.4 christos } 1115 1.4 christos 1116 1.4 christos 1117 1.10 christos static char ** hostapd_complete_get(const char *str, int pos) 1118 1.10 christos { 1119 1.10 christos int arg = get_cmd_arg_num(str, pos); 1120 1.10 christos const char *fields[] = { 1121 1.10 christos "version", "tls_library", 1122 1.10 christos }; 1123 1.10 christos int i, num_fields = ARRAY_SIZE(fields); 1124 1.10 christos 1125 1.10 christos if (arg == 1) { 1126 1.10 christos char **res; 1127 1.10 christos 1128 1.10 christos res = os_calloc(num_fields + 1, sizeof(char *)); 1129 1.10 christos if (!res) 1130 1.10 christos return NULL; 1131 1.10 christos for (i = 0; i < num_fields; i++) { 1132 1.10 christos res[i] = os_strdup(fields[i]); 1133 1.10 christos if (!res[i]) 1134 1.10 christos return res; 1135 1.10 christos } 1136 1.10 christos return res; 1137 1.10 christos } 1138 1.10 christos return NULL; 1139 1.10 christos } 1140 1.10 christos 1141 1.10 christos 1142 1.9 christos #ifdef CONFIG_FST 1143 1.9 christos static int hostapd_cli_cmd_fst(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1144 1.9 christos { 1145 1.9 christos char cmd[256]; 1146 1.9 christos int res; 1147 1.9 christos int i; 1148 1.9 christos int total; 1149 1.9 christos 1150 1.9 christos if (argc <= 0) { 1151 1.9 christos printf("FST command: parameters are required.\n"); 1152 1.9 christos return -1; 1153 1.9 christos } 1154 1.9 christos 1155 1.9 christos total = os_snprintf(cmd, sizeof(cmd), "FST-MANAGER"); 1156 1.9 christos 1157 1.9 christos for (i = 0; i < argc; i++) { 1158 1.9 christos res = os_snprintf(cmd + total, sizeof(cmd) - total, " %s", 1159 1.9 christos argv[i]); 1160 1.9 christos if (os_snprintf_error(sizeof(cmd) - total, res)) { 1161 1.9 christos printf("Too long fst command.\n"); 1162 1.9 christos return -1; 1163 1.9 christos } 1164 1.9 christos total += res; 1165 1.9 christos } 1166 1.9 christos return wpa_ctrl_command(ctrl, cmd); 1167 1.9 christos } 1168 1.9 christos #endif /* CONFIG_FST */ 1169 1.9 christos 1170 1.9 christos 1171 1.12 christos #ifdef CONFIG_IEEE80211AX 1172 1.12 christos static int hostapd_cli_cmd_color_change(struct wpa_ctrl *ctrl, 1173 1.12 christos int argc, char *argv[]) 1174 1.12 christos { 1175 1.12 christos return hostapd_cli_cmd(ctrl, "COLOR_CHANGE", 1, argc, argv); 1176 1.12 christos } 1177 1.12 christos #endif /* CONFIG_IEEE80211AX */ 1178 1.12 christos 1179 1.12 christos 1180 1.6 christos static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl, 1181 1.6 christos int argc, char *argv[]) 1182 1.6 christos { 1183 1.6 christos char cmd[256]; 1184 1.6 christos int res; 1185 1.6 christos int i; 1186 1.6 christos char *tmp; 1187 1.6 christos int total; 1188 1.6 christos 1189 1.6 christos if (argc < 2) { 1190 1.6 christos printf("Invalid chan_switch command: needs at least two " 1191 1.6 christos "arguments (count and freq)\n" 1192 1.6 christos "usage: <cs_count> <freq> [sec_channel_offset=] " 1193 1.6 christos "[center_freq1=] [center_freq2=] [bandwidth=] " 1194 1.12 christos "[blocktx] [ht|vht|he|eht]\n"); 1195 1.6 christos return -1; 1196 1.6 christos } 1197 1.6 christos 1198 1.6 christos res = os_snprintf(cmd, sizeof(cmd), "CHAN_SWITCH %s %s", 1199 1.6 christos argv[0], argv[1]); 1200 1.7 christos if (os_snprintf_error(sizeof(cmd), res)) { 1201 1.6 christos printf("Too long CHAN_SWITCH command.\n"); 1202 1.6 christos return -1; 1203 1.6 christos } 1204 1.6 christos 1205 1.6 christos total = res; 1206 1.6 christos for (i = 2; i < argc; i++) { 1207 1.6 christos tmp = cmd + total; 1208 1.6 christos res = os_snprintf(tmp, sizeof(cmd) - total, " %s", argv[i]); 1209 1.7 christos if (os_snprintf_error(sizeof(cmd) - total, res)) { 1210 1.6 christos printf("Too long CHAN_SWITCH command.\n"); 1211 1.6 christos return -1; 1212 1.6 christos } 1213 1.6 christos total += res; 1214 1.6 christos } 1215 1.6 christos return wpa_ctrl_command(ctrl, cmd); 1216 1.6 christos } 1217 1.6 christos 1218 1.6 christos 1219 1.12 christos static int hostapd_cli_cmd_notify_cw_change(struct wpa_ctrl *ctrl, 1220 1.12 christos int argc, char *argv[]) 1221 1.12 christos { 1222 1.12 christos return hostapd_cli_cmd(ctrl, "NOTIFY_CW_CHANGE", 1, argc, argv); 1223 1.12 christos } 1224 1.12 christos 1225 1.12 christos 1226 1.7 christos static int hostapd_cli_cmd_enable(struct wpa_ctrl *ctrl, int argc, 1227 1.12 christos char *argv[]) 1228 1.7 christos { 1229 1.7 christos return wpa_ctrl_command(ctrl, "ENABLE"); 1230 1.7 christos } 1231 1.7 christos 1232 1.7 christos 1233 1.7 christos static int hostapd_cli_cmd_reload(struct wpa_ctrl *ctrl, int argc, 1234 1.12 christos char *argv[]) 1235 1.12 christos { 1236 1.12 christos return wpa_ctrl_command(ctrl, "RELOAD"); 1237 1.12 christos } 1238 1.12 christos 1239 1.12 christos 1240 1.12 christos static int hostapd_cli_cmd_reload_bss(struct wpa_ctrl *ctrl, int argc, 1241 1.7 christos char *argv[]) 1242 1.7 christos { 1243 1.12 christos return wpa_ctrl_command(ctrl, "RELOAD_BSS"); 1244 1.12 christos } 1245 1.12 christos 1246 1.12 christos 1247 1.12 christos static int hostapd_cli_cmd_reload_config(struct wpa_ctrl *ctrl, int argc, 1248 1.12 christos char *argv[]) 1249 1.12 christos { 1250 1.12 christos return wpa_ctrl_command(ctrl, "RELOAD_CONFIG"); 1251 1.7 christos } 1252 1.7 christos 1253 1.7 christos 1254 1.7 christos static int hostapd_cli_cmd_disable(struct wpa_ctrl *ctrl, int argc, 1255 1.12 christos char *argv[]) 1256 1.12 christos { 1257 1.12 christos return wpa_ctrl_command(ctrl, "DISABLE"); 1258 1.12 christos } 1259 1.12 christos 1260 1.12 christos 1261 1.12 christos static int hostapd_cli_cmd_enable_mld(struct wpa_ctrl *ctrl, int argc, 1262 1.7 christos char *argv[]) 1263 1.7 christos { 1264 1.12 christos return wpa_ctrl_command(ctrl, "ENABLE_MLD"); 1265 1.12 christos } 1266 1.12 christos 1267 1.12 christos 1268 1.12 christos static int hostapd_cli_cmd_disable_mld(struct wpa_ctrl *ctrl, int argc, 1269 1.12 christos char *argv[]) 1270 1.12 christos { 1271 1.12 christos return wpa_ctrl_command(ctrl, "DISABLE_MLD"); 1272 1.7 christos } 1273 1.7 christos 1274 1.7 christos 1275 1.11 christos static int hostapd_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc, 1276 1.12 christos char *argv[]) 1277 1.11 christos { 1278 1.11 christos return wpa_ctrl_command(ctrl, "UPDATE_BEACON"); 1279 1.11 christos } 1280 1.11 christos 1281 1.11 christos 1282 1.12 christos static int hostapd_cli_cmd_stop_ap(struct wpa_ctrl *ctrl, int argc, 1283 1.12 christos char *argv[]) 1284 1.12 christos { 1285 1.12 christos return wpa_ctrl_command(ctrl, "STOP_AP"); 1286 1.12 christos } 1287 1.12 christos 1288 1.12 christos 1289 1.6 christos static int hostapd_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1290 1.6 christos { 1291 1.6 christos char cmd[256]; 1292 1.6 christos int res; 1293 1.6 christos 1294 1.12 christos if (argc < 2 || argc > 4) { 1295 1.6 christos printf("Invalid vendor command\n" 1296 1.12 christos "usage: <vendor id> <command id> [<hex formatted command argument>] [nested=<0|1>]\n"); 1297 1.6 christos return -1; 1298 1.6 christos } 1299 1.6 christos 1300 1.12 christos res = os_snprintf(cmd, sizeof(cmd), "VENDOR %s %s %s%s%s", argv[0], 1301 1.12 christos argv[1], argc >= 3 ? argv[2] : "", 1302 1.12 christos argc == 4 ? " " : "", argc == 4 ? argv[3] : ""); 1303 1.7 christos if (os_snprintf_error(sizeof(cmd), res)) { 1304 1.6 christos printf("Too long VENDOR command.\n"); 1305 1.6 christos return -1; 1306 1.6 christos } 1307 1.6 christos return wpa_ctrl_command(ctrl, cmd); 1308 1.6 christos } 1309 1.6 christos 1310 1.6 christos 1311 1.7 christos static int hostapd_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, 1312 1.7 christos char *argv[]) 1313 1.7 christos { 1314 1.7 christos return wpa_ctrl_command(ctrl, "ERP_FLUSH"); 1315 1.7 christos } 1316 1.7 christos 1317 1.7 christos 1318 1.9 christos static int hostapd_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, 1319 1.9 christos char *argv[]) 1320 1.9 christos { 1321 1.9 christos char cmd[256]; 1322 1.9 christos int res; 1323 1.9 christos 1324 1.9 christos res = os_snprintf(cmd, sizeof(cmd), "LOG_LEVEL%s%s%s%s", 1325 1.9 christos argc >= 1 ? " " : "", 1326 1.9 christos argc >= 1 ? argv[0] : "", 1327 1.9 christos argc == 2 ? " " : "", 1328 1.9 christos argc == 2 ? argv[1] : ""); 1329 1.9 christos if (os_snprintf_error(sizeof(cmd), res)) { 1330 1.9 christos printf("Too long option\n"); 1331 1.9 christos return -1; 1332 1.9 christos } 1333 1.9 christos return wpa_ctrl_command(ctrl, cmd); 1334 1.9 christos } 1335 1.9 christos 1336 1.9 christos 1337 1.9 christos static int hostapd_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1338 1.9 christos { 1339 1.9 christos if (argc == 0) 1340 1.9 christos return -1; 1341 1.9 christos return hostapd_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]); 1342 1.9 christos } 1343 1.9 christos 1344 1.9 christos 1345 1.9 christos static int hostapd_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1346 1.9 christos { 1347 1.9 christos return wpa_ctrl_command(ctrl, "PMKSA"); 1348 1.9 christos } 1349 1.9 christos 1350 1.9 christos 1351 1.9 christos static int hostapd_cli_cmd_pmksa_flush(struct wpa_ctrl *ctrl, int argc, 1352 1.9 christos char *argv[]) 1353 1.9 christos { 1354 1.9 christos return wpa_ctrl_command(ctrl, "PMKSA_FLUSH"); 1355 1.9 christos } 1356 1.9 christos 1357 1.9 christos 1358 1.9 christos static int hostapd_cli_cmd_set_neighbor(struct wpa_ctrl *ctrl, int argc, 1359 1.9 christos char *argv[]) 1360 1.9 christos { 1361 1.9 christos char cmd[2048]; 1362 1.9 christos int res; 1363 1.9 christos 1364 1.10 christos if (argc < 3 || argc > 6) { 1365 1.10 christos printf("Invalid set_neighbor command: needs 3-6 arguments\n"); 1366 1.9 christos return -1; 1367 1.9 christos } 1368 1.9 christos 1369 1.10 christos res = os_snprintf(cmd, sizeof(cmd), "SET_NEIGHBOR %s %s %s %s %s %s", 1370 1.9 christos argv[0], argv[1], argv[2], argc >= 4 ? argv[3] : "", 1371 1.10 christos argc >= 5 ? argv[4] : "", argc == 6 ? argv[5] : ""); 1372 1.9 christos if (os_snprintf_error(sizeof(cmd), res)) { 1373 1.9 christos printf("Too long SET_NEIGHBOR command.\n"); 1374 1.9 christos return -1; 1375 1.9 christos } 1376 1.9 christos return wpa_ctrl_command(ctrl, cmd); 1377 1.9 christos } 1378 1.9 christos 1379 1.9 christos 1380 1.12 christos static int hostapd_cli_cmd_show_neighbor(struct wpa_ctrl *ctrl, int argc, 1381 1.12 christos char *argv[]) 1382 1.12 christos { 1383 1.12 christos return wpa_ctrl_command(ctrl, "SHOW_NEIGHBOR"); 1384 1.12 christos } 1385 1.12 christos 1386 1.12 christos 1387 1.9 christos static int hostapd_cli_cmd_remove_neighbor(struct wpa_ctrl *ctrl, int argc, 1388 1.9 christos char *argv[]) 1389 1.9 christos { 1390 1.12 christos return hostapd_cli_cmd(ctrl, "REMOVE_NEIGHBOR", 1, argc, argv); 1391 1.9 christos } 1392 1.9 christos 1393 1.9 christos 1394 1.9 christos static int hostapd_cli_cmd_req_lci(struct wpa_ctrl *ctrl, int argc, 1395 1.9 christos char *argv[]) 1396 1.9 christos { 1397 1.9 christos char cmd[256]; 1398 1.9 christos int res; 1399 1.9 christos 1400 1.9 christos if (argc != 1) { 1401 1.9 christos printf("Invalid req_lci command - requires destination address\n"); 1402 1.9 christos return -1; 1403 1.9 christos } 1404 1.9 christos 1405 1.9 christos res = os_snprintf(cmd, sizeof(cmd), "REQ_LCI %s", argv[0]); 1406 1.9 christos if (os_snprintf_error(sizeof(cmd), res)) { 1407 1.9 christos printf("Too long REQ_LCI command.\n"); 1408 1.9 christos return -1; 1409 1.9 christos } 1410 1.9 christos return wpa_ctrl_command(ctrl, cmd); 1411 1.9 christos } 1412 1.9 christos 1413 1.9 christos 1414 1.9 christos static int hostapd_cli_cmd_req_range(struct wpa_ctrl *ctrl, int argc, 1415 1.9 christos char *argv[]) 1416 1.9 christos { 1417 1.9 christos if (argc < 4) { 1418 1.9 christos printf("Invalid req_range command: needs at least 4 arguments - dest address, randomization interval, min AP count, and 1 to 16 AP addresses\n"); 1419 1.9 christos return -1; 1420 1.9 christos } 1421 1.9 christos 1422 1.9 christos return hostapd_cli_cmd(ctrl, "REQ_RANGE", 4, argc, argv); 1423 1.9 christos } 1424 1.9 christos 1425 1.9 christos 1426 1.9 christos static int hostapd_cli_cmd_driver_flags(struct wpa_ctrl *ctrl, int argc, 1427 1.9 christos char *argv[]) 1428 1.9 christos { 1429 1.9 christos return wpa_ctrl_command(ctrl, "DRIVER_FLAGS"); 1430 1.9 christos } 1431 1.9 christos 1432 1.9 christos 1433 1.12 christos static int hostapd_cli_cmd_driver_flags2(struct wpa_ctrl *ctrl, int argc, 1434 1.12 christos char *argv[]) 1435 1.12 christos { 1436 1.12 christos return wpa_ctrl_command(ctrl, "DRIVER_FLAGS2"); 1437 1.12 christos } 1438 1.12 christos 1439 1.12 christos 1440 1.10 christos #ifdef CONFIG_DPP 1441 1.10 christos 1442 1.10 christos static int hostapd_cli_cmd_dpp_qr_code(struct wpa_ctrl *ctrl, int argc, 1443 1.10 christos char *argv[]) 1444 1.10 christos { 1445 1.10 christos return hostapd_cli_cmd(ctrl, "DPP_QR_CODE", 1, argc, argv); 1446 1.10 christos } 1447 1.10 christos 1448 1.10 christos 1449 1.10 christos static int hostapd_cli_cmd_dpp_bootstrap_gen(struct wpa_ctrl *ctrl, int argc, 1450 1.10 christos char *argv[]) 1451 1.10 christos { 1452 1.10 christos return hostapd_cli_cmd(ctrl, "DPP_BOOTSTRAP_GEN", 1, argc, argv); 1453 1.10 christos } 1454 1.10 christos 1455 1.10 christos 1456 1.10 christos static int hostapd_cli_cmd_dpp_bootstrap_remove(struct wpa_ctrl *ctrl, int argc, 1457 1.10 christos char *argv[]) 1458 1.10 christos { 1459 1.10 christos return hostapd_cli_cmd(ctrl, "DPP_BOOTSTRAP_REMOVE", 1, argc, argv); 1460 1.10 christos } 1461 1.10 christos 1462 1.10 christos 1463 1.10 christos static int hostapd_cli_cmd_dpp_bootstrap_get_uri(struct wpa_ctrl *ctrl, 1464 1.10 christos int argc, char *argv[]) 1465 1.10 christos { 1466 1.10 christos return hostapd_cli_cmd(ctrl, "DPP_BOOTSTRAP_GET_URI", 1, argc, argv); 1467 1.10 christos } 1468 1.10 christos 1469 1.10 christos 1470 1.10 christos static int hostapd_cli_cmd_dpp_bootstrap_info(struct wpa_ctrl *ctrl, int argc, 1471 1.10 christos char *argv[]) 1472 1.10 christos { 1473 1.10 christos return hostapd_cli_cmd(ctrl, "DPP_BOOTSTRAP_INFO", 1, argc, argv); 1474 1.10 christos } 1475 1.10 christos 1476 1.10 christos 1477 1.12 christos static int hostapd_cli_cmd_dpp_bootstrap_set(struct wpa_ctrl *ctrl, int argc, 1478 1.12 christos char *argv[]) 1479 1.12 christos { 1480 1.12 christos return hostapd_cli_cmd(ctrl, "DPP_BOOTSTRAP_SET", 1, argc, argv); 1481 1.12 christos } 1482 1.12 christos 1483 1.12 christos 1484 1.10 christos static int hostapd_cli_cmd_dpp_auth_init(struct wpa_ctrl *ctrl, int argc, 1485 1.10 christos char *argv[]) 1486 1.10 christos { 1487 1.10 christos return hostapd_cli_cmd(ctrl, "DPP_AUTH_INIT", 1, argc, argv); 1488 1.10 christos } 1489 1.10 christos 1490 1.10 christos 1491 1.10 christos static int hostapd_cli_cmd_dpp_listen(struct wpa_ctrl *ctrl, int argc, 1492 1.10 christos char *argv[]) 1493 1.10 christos { 1494 1.10 christos return hostapd_cli_cmd(ctrl, "DPP_LISTEN", 1, argc, argv); 1495 1.10 christos } 1496 1.10 christos 1497 1.10 christos 1498 1.10 christos static int hostapd_cli_cmd_dpp_stop_listen(struct wpa_ctrl *ctrl, int argc, 1499 1.10 christos char *argv[]) 1500 1.10 christos { 1501 1.10 christos return wpa_ctrl_command(ctrl, "DPP_STOP_LISTEN"); 1502 1.10 christos } 1503 1.10 christos 1504 1.10 christos 1505 1.10 christos static int hostapd_cli_cmd_dpp_configurator_add(struct wpa_ctrl *ctrl, int argc, 1506 1.10 christos char *argv[]) 1507 1.10 christos { 1508 1.10 christos return hostapd_cli_cmd(ctrl, "DPP_CONFIGURATOR_ADD", 0, argc, argv); 1509 1.10 christos } 1510 1.10 christos 1511 1.10 christos 1512 1.10 christos static int hostapd_cli_cmd_dpp_configurator_remove(struct wpa_ctrl *ctrl, 1513 1.10 christos int argc, char *argv[]) 1514 1.10 christos { 1515 1.10 christos return hostapd_cli_cmd(ctrl, "DPP_CONFIGURATOR_REMOVE", 1, argc, argv); 1516 1.10 christos } 1517 1.10 christos 1518 1.10 christos 1519 1.10 christos static int hostapd_cli_cmd_dpp_configurator_get_key(struct wpa_ctrl *ctrl, 1520 1.10 christos int argc, char *argv[]) 1521 1.10 christos { 1522 1.10 christos return hostapd_cli_cmd(ctrl, "DPP_CONFIGURATOR_GET_KEY", 1, argc, argv); 1523 1.10 christos } 1524 1.10 christos 1525 1.10 christos 1526 1.11 christos static int hostapd_cli_cmd_dpp_configurator_sign(struct wpa_ctrl *ctrl, 1527 1.11 christos int argc, char *argv[]) 1528 1.11 christos { 1529 1.11 christos return hostapd_cli_cmd(ctrl, "DPP_CONFIGURATOR_SIGN", 1, argc, argv); 1530 1.11 christos } 1531 1.11 christos 1532 1.11 christos 1533 1.10 christos static int hostapd_cli_cmd_dpp_pkex_add(struct wpa_ctrl *ctrl, int argc, 1534 1.10 christos char *argv[]) 1535 1.10 christos { 1536 1.10 christos return hostapd_cli_cmd(ctrl, "DPP_PKEX_ADD", 1, argc, argv); 1537 1.10 christos } 1538 1.10 christos 1539 1.10 christos 1540 1.10 christos static int hostapd_cli_cmd_dpp_pkex_remove(struct wpa_ctrl *ctrl, int argc, 1541 1.10 christos char *argv[]) 1542 1.10 christos { 1543 1.10 christos return hostapd_cli_cmd(ctrl, "DPP_PKEX_REMOVE", 1, argc, argv); 1544 1.10 christos } 1545 1.10 christos 1546 1.12 christos 1547 1.12 christos #ifdef CONFIG_DPP2 1548 1.12 christos 1549 1.12 christos static int hostapd_cli_cmd_dpp_controller_start(struct wpa_ctrl *ctrl, int argc, 1550 1.12 christos char *argv[]) 1551 1.12 christos { 1552 1.12 christos return hostapd_cli_cmd(ctrl, "DPP_CONTROLLER_START", 0, argc, argv); 1553 1.12 christos } 1554 1.12 christos 1555 1.12 christos 1556 1.12 christos static int hostapd_cli_cmd_dpp_controller_stop(struct wpa_ctrl *ctrl, int argc, 1557 1.12 christos char *argv[]) 1558 1.12 christos { 1559 1.12 christos return wpa_ctrl_command(ctrl, "DPP_CONTROLLER_STOP"); 1560 1.12 christos } 1561 1.12 christos 1562 1.12 christos 1563 1.12 christos static int hostapd_cli_cmd_dpp_chirp(struct wpa_ctrl *ctrl, int argc, 1564 1.12 christos char *argv[]) 1565 1.12 christos { 1566 1.12 christos return hostapd_cli_cmd(ctrl, "DPP_CHIRP", 1, argc, argv); 1567 1.12 christos } 1568 1.12 christos 1569 1.12 christos 1570 1.12 christos static int hostapd_cli_cmd_dpp_stop_chirp(struct wpa_ctrl *ctrl, int argc, 1571 1.12 christos char *argv[]) 1572 1.12 christos { 1573 1.12 christos return wpa_ctrl_command(ctrl, "DPP_STOP_CHIRP"); 1574 1.12 christos } 1575 1.12 christos 1576 1.12 christos #endif /* CONFIG_DPP2 */ 1577 1.12 christos 1578 1.12 christos 1579 1.12 christos #ifdef CONFIG_DPP3 1580 1.12 christos static int hostapd_cli_cmd_dpp_push_button(struct wpa_ctrl *ctrl, int argc, 1581 1.12 christos char *argv[]) 1582 1.12 christos { 1583 1.12 christos return hostapd_cli_cmd(ctrl, "DPP_PUSH_BUTTON", 0, argc, argv); 1584 1.12 christos } 1585 1.12 christos #endif /* CONFIG_DPP3 */ 1586 1.10 christos #endif /* CONFIG_DPP */ 1587 1.10 christos 1588 1.10 christos 1589 1.10 christos static int hostapd_cli_cmd_accept_macacl(struct wpa_ctrl *ctrl, int argc, 1590 1.10 christos char *argv[]) 1591 1.10 christos { 1592 1.10 christos return hostapd_cli_cmd(ctrl, "ACCEPT_ACL", 1, argc, argv); 1593 1.10 christos } 1594 1.10 christos 1595 1.10 christos 1596 1.10 christos static int hostapd_cli_cmd_deny_macacl(struct wpa_ctrl *ctrl, int argc, 1597 1.10 christos char *argv[]) 1598 1.10 christos { 1599 1.10 christos return hostapd_cli_cmd(ctrl, "DENY_ACL", 1, argc, argv); 1600 1.10 christos } 1601 1.10 christos 1602 1.10 christos 1603 1.10 christos static int hostapd_cli_cmd_poll_sta(struct wpa_ctrl *ctrl, int argc, 1604 1.10 christos char *argv[]) 1605 1.10 christos { 1606 1.10 christos return hostapd_cli_cmd(ctrl, "POLL_STA", 1, argc, argv); 1607 1.10 christos } 1608 1.10 christos 1609 1.10 christos 1610 1.11 christos static int hostapd_cli_cmd_req_beacon(struct wpa_ctrl *ctrl, int argc, 1611 1.11 christos char *argv[]) 1612 1.11 christos { 1613 1.11 christos return hostapd_cli_cmd(ctrl, "REQ_BEACON", 2, argc, argv); 1614 1.11 christos } 1615 1.11 christos 1616 1.11 christos 1617 1.12 christos static int hostapd_cli_cmd_req_link_measurement(struct wpa_ctrl *ctrl, int argc, 1618 1.12 christos char *argv[]) 1619 1.12 christos { 1620 1.12 christos return hostapd_cli_cmd(ctrl, "REQ_LINK_MEASUREMENT", 1, argc, argv); 1621 1.12 christos } 1622 1.12 christos 1623 1.12 christos 1624 1.11 christos static int hostapd_cli_cmd_reload_wpa_psk(struct wpa_ctrl *ctrl, int argc, 1625 1.11 christos char *argv[]) 1626 1.11 christos { 1627 1.11 christos return wpa_ctrl_command(ctrl, "RELOAD_WPA_PSK"); 1628 1.11 christos } 1629 1.11 christos 1630 1.11 christos 1631 1.12 christos #ifdef CONFIG_IEEE80211R_AP 1632 1.12 christos 1633 1.12 christos static int hostapd_cli_cmd_get_rxkhs(struct wpa_ctrl *ctrl, int argc, 1634 1.12 christos char *argv[]) 1635 1.12 christos { 1636 1.12 christos return wpa_ctrl_command(ctrl, "GET_RXKHS"); 1637 1.12 christos } 1638 1.12 christos 1639 1.12 christos 1640 1.12 christos static int hostapd_cli_cmd_reload_rxkhs(struct wpa_ctrl *ctrl, int argc, 1641 1.12 christos char *argv[]) 1642 1.12 christos { 1643 1.12 christos return wpa_ctrl_command(ctrl, "RELOAD_RXKHS"); 1644 1.12 christos } 1645 1.12 christos 1646 1.12 christos #endif /* CONFIG_IEEE80211R_AP */ 1647 1.12 christos 1648 1.12 christos 1649 1.12 christos #ifdef ANDROID 1650 1.12 christos static int hostapd_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1651 1.12 christos { 1652 1.12 christos return hostapd_cli_cmd(ctrl, "DRIVER", 1, argc, argv); 1653 1.12 christos } 1654 1.12 christos #endif /* ANDROID */ 1655 1.12 christos 1656 1.12 christos 1657 1.1 christos struct hostapd_cli_cmd { 1658 1.1 christos const char *cmd; 1659 1.1 christos int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]); 1660 1.9 christos char ** (*completion)(const char *str, int pos); 1661 1.9 christos const char *usage; 1662 1.1 christos }; 1663 1.1 christos 1664 1.9 christos static const struct hostapd_cli_cmd hostapd_cli_commands[] = { 1665 1.9 christos { "ping", hostapd_cli_cmd_ping, NULL, 1666 1.9 christos "= pings hostapd" }, 1667 1.9 christos { "mib", hostapd_cli_cmd_mib, NULL, 1668 1.9 christos "= get MIB variables (dot1x, dot11, radius)" }, 1669 1.10 christos { "relog", hostapd_cli_cmd_relog, NULL, 1670 1.10 christos "= reload/truncate debug log output file" }, 1671 1.12 christos { "close_log", hostapd_cli_cmd_close_log, NULL, 1672 1.12 christos "= disable debug log output file" }, 1673 1.10 christos { "status", hostapd_cli_cmd_status, NULL, 1674 1.10 christos "= show interface status info" }, 1675 1.10 christos { "sta", hostapd_cli_cmd_sta, hostapd_complete_stations, 1676 1.9 christos "<addr> = get MIB variables for one station" }, 1677 1.9 christos { "all_sta", hostapd_cli_cmd_all_sta, NULL, 1678 1.9 christos "= get MIB variables for all stations" }, 1679 1.10 christos { "list_sta", hostapd_cli_cmd_list_sta, NULL, 1680 1.10 christos "= list all stations" }, 1681 1.9 christos { "new_sta", hostapd_cli_cmd_new_sta, NULL, 1682 1.9 christos "<addr> = add a new station" }, 1683 1.9 christos { "deauthenticate", hostapd_cli_cmd_deauthenticate, 1684 1.10 christos hostapd_complete_stations, 1685 1.9 christos "<addr> = deauthenticate a station" }, 1686 1.9 christos { "disassociate", hostapd_cli_cmd_disassociate, 1687 1.10 christos hostapd_complete_stations, 1688 1.9 christos "<addr> = disassociate a station" }, 1689 1.9 christos #ifdef CONFIG_TAXONOMY 1690 1.10 christos { "signature", hostapd_cli_cmd_signature, hostapd_complete_stations, 1691 1.9 christos "<addr> = get taxonomy signature for a station" }, 1692 1.9 christos #endif /* CONFIG_TAXONOMY */ 1693 1.10 christos { "sa_query", hostapd_cli_cmd_sa_query, hostapd_complete_stations, 1694 1.9 christos "<addr> = send SA Query to a station" }, 1695 1.1 christos #ifdef CONFIG_WPS 1696 1.9 christos { "wps_pin", hostapd_cli_cmd_wps_pin, NULL, 1697 1.9 christos "<uuid> <pin> [timeout] [addr] = add WPS Enrollee PIN" }, 1698 1.9 christos { "wps_check_pin", hostapd_cli_cmd_wps_check_pin, NULL, 1699 1.9 christos "<PIN> = verify PIN checksum" }, 1700 1.9 christos { "wps_pbc", hostapd_cli_cmd_wps_pbc, NULL, 1701 1.9 christos "= indicate button pushed to initiate PBC" }, 1702 1.9 christos { "wps_cancel", hostapd_cli_cmd_wps_cancel, NULL, 1703 1.9 christos "= cancel the pending WPS operation" }, 1704 1.5 christos #ifdef CONFIG_WPS_NFC 1705 1.9 christos { "wps_nfc_tag_read", hostapd_cli_cmd_wps_nfc_tag_read, NULL, 1706 1.9 christos "<hexdump> = report read NFC tag with WPS data" }, 1707 1.9 christos { "wps_nfc_config_token", hostapd_cli_cmd_wps_nfc_config_token, NULL, 1708 1.9 christos "<WPS/NDEF> = build NFC configuration token" }, 1709 1.9 christos { "wps_nfc_token", hostapd_cli_cmd_wps_nfc_token, NULL, 1710 1.9 christos "<WPS/NDEF/enable/disable> = manager NFC password token" }, 1711 1.9 christos { "nfc_get_handover_sel", hostapd_cli_cmd_nfc_get_handover_sel, NULL, 1712 1.9 christos NULL }, 1713 1.5 christos #endif /* CONFIG_WPS_NFC */ 1714 1.9 christos { "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin, NULL, 1715 1.9 christos "<cmd> [params..] = enable/disable AP PIN" }, 1716 1.9 christos { "wps_config", hostapd_cli_cmd_wps_config, NULL, 1717 1.9 christos "<SSID> <auth> <encr> <key> = configure AP" }, 1718 1.9 christos { "wps_get_status", hostapd_cli_cmd_wps_get_status, NULL, 1719 1.9 christos "= show current WPS status" }, 1720 1.1 christos #endif /* CONFIG_WPS */ 1721 1.10 christos { "disassoc_imminent", hostapd_cli_cmd_disassoc_imminent, NULL, 1722 1.10 christos "= send Disassociation Imminent notification" }, 1723 1.10 christos { "ess_disassoc", hostapd_cli_cmd_ess_disassoc, NULL, 1724 1.10 christos "= send ESS Dissassociation Imminent notification" }, 1725 1.10 christos { "bss_tm_req", hostapd_cli_cmd_bss_tm_req, NULL, 1726 1.10 christos "= send BSS Transition Management Request" }, 1727 1.9 christos { "get_config", hostapd_cli_cmd_get_config, NULL, 1728 1.9 christos "= show current configuration" }, 1729 1.9 christos { "help", hostapd_cli_cmd_help, hostapd_cli_complete_help, 1730 1.9 christos "= show this usage help" }, 1731 1.9 christos { "interface", hostapd_cli_cmd_interface, hostapd_complete_interface, 1732 1.9 christos "[ifname] = show interfaces/select interface" }, 1733 1.9 christos #ifdef CONFIG_FST 1734 1.10 christos { "fst", hostapd_cli_cmd_fst, NULL, 1735 1.10 christos "<params...> = send FST-MANAGER control interface command" }, 1736 1.9 christos #endif /* CONFIG_FST */ 1737 1.10 christos { "raw", hostapd_cli_cmd_raw, NULL, 1738 1.10 christos "<params..> = send unprocessed command" }, 1739 1.9 christos { "level", hostapd_cli_cmd_level, NULL, 1740 1.9 christos "<debug level> = change debug level" }, 1741 1.9 christos { "license", hostapd_cli_cmd_license, NULL, 1742 1.9 christos "= show full hostapd_cli license" }, 1743 1.9 christos { "quit", hostapd_cli_cmd_quit, NULL, 1744 1.9 christos "= exit hostapd_cli" }, 1745 1.10 christos { "set", hostapd_cli_cmd_set, hostapd_complete_set, 1746 1.10 christos "<name> <value> = set runtime variables" }, 1747 1.10 christos { "get", hostapd_cli_cmd_get, hostapd_complete_get, 1748 1.10 christos "<name> = get runtime info" }, 1749 1.10 christos { "set_qos_map_set", hostapd_cli_cmd_set_qos_map_set, NULL, 1750 1.10 christos "<arg,arg,...> = set QoS Map set element" }, 1751 1.10 christos { "send_qos_map_conf", hostapd_cli_cmd_send_qos_map_conf, 1752 1.10 christos hostapd_complete_stations, 1753 1.10 christos "<addr> = send QoS Map Configure frame" }, 1754 1.10 christos { "chan_switch", hostapd_cli_cmd_chan_switch, NULL, 1755 1.10 christos "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]\n" 1756 1.10 christos " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]\n" 1757 1.10 christos " = initiate channel switch announcement" }, 1758 1.12 christos #ifdef CONFIG_IEEE80211AX 1759 1.12 christos { "color_change", hostapd_cli_cmd_color_change, NULL, 1760 1.12 christos "<color> = initiate BSS color change to set the specified color\n" 1761 1.12 christos "Value 0 will disable the color.\n"}, 1762 1.12 christos #endif /* CONFIG_IEEE80211AX */ 1763 1.12 christos { "notify_cw_change", hostapd_cli_cmd_notify_cw_change, NULL, 1764 1.12 christos "<channel_width> = 0 - 20 MHz, 1 - 40 MHz, 2 - 80 MHz, 3 - 160 MHz" }, 1765 1.10 christos { "hs20_wnm_notif", hostapd_cli_cmd_hs20_wnm_notif, NULL, 1766 1.10 christos "<addr> <url>\n" 1767 1.10 christos " = send WNM-Notification Subscription Remediation Request" }, 1768 1.10 christos { "hs20_deauth_req", hostapd_cli_cmd_hs20_deauth_req, NULL, 1769 1.10 christos "<addr> <code (0/1)> <Re-auth-Delay(sec)> [url]\n" 1770 1.10 christos " = send WNM-Notification imminent deauthentication indication" }, 1771 1.10 christos { "vendor", hostapd_cli_cmd_vendor, NULL, 1772 1.10 christos "<vendor id> <sub command id> [<hex formatted data>]\n" 1773 1.10 christos " = send vendor driver command" }, 1774 1.10 christos { "enable", hostapd_cli_cmd_enable, NULL, 1775 1.10 christos "= enable hostapd on current interface" }, 1776 1.10 christos { "reload", hostapd_cli_cmd_reload, NULL, 1777 1.10 christos "= reload configuration for current interface" }, 1778 1.12 christos { "reload_bss", hostapd_cli_cmd_reload_bss, NULL, 1779 1.12 christos "= reload configuration for current BSS" }, 1780 1.12 christos { "reload_config", hostapd_cli_cmd_reload_config, NULL, 1781 1.12 christos "= reload configuration for current interface" }, 1782 1.10 christos { "disable", hostapd_cli_cmd_disable, NULL, 1783 1.10 christos "= disable hostapd on current interface" }, 1784 1.12 christos { "enable_mld", hostapd_cli_cmd_enable_mld, NULL, 1785 1.12 christos "= enable AP MLD to which the interface is affiliated" }, 1786 1.12 christos { "disable_mld", hostapd_cli_cmd_disable_mld, NULL, 1787 1.12 christos "= disable AP MLD to which the interface is affiliated" }, 1788 1.11 christos { "update_beacon", hostapd_cli_cmd_update_beacon, NULL, 1789 1.11 christos "= update Beacon frame contents\n"}, 1790 1.12 christos { "stop_ap", hostapd_cli_cmd_stop_ap, NULL, 1791 1.12 christos "= stop AP\n"}, 1792 1.10 christos { "erp_flush", hostapd_cli_cmd_erp_flush, NULL, 1793 1.10 christos "= drop all ERP keys"}, 1794 1.10 christos { "log_level", hostapd_cli_cmd_log_level, NULL, 1795 1.10 christos "[level] = show/change log verbosity level" }, 1796 1.10 christos { "pmksa", hostapd_cli_cmd_pmksa, NULL, 1797 1.10 christos " = show PMKSA cache entries" }, 1798 1.10 christos { "pmksa_flush", hostapd_cli_cmd_pmksa_flush, NULL, 1799 1.10 christos " = flush PMKSA cache" }, 1800 1.10 christos { "set_neighbor", hostapd_cli_cmd_set_neighbor, NULL, 1801 1.10 christos "<addr> <ssid=> <nr=> [lci=] [civic=] [stat]\n" 1802 1.10 christos " = add AP to neighbor database" }, 1803 1.12 christos { "show_neighbor", hostapd_cli_cmd_show_neighbor, NULL, 1804 1.12 christos " = show neighbor database entries" }, 1805 1.10 christos { "remove_neighbor", hostapd_cli_cmd_remove_neighbor, NULL, 1806 1.12 christos "<addr> [ssid=<hex>] = remove AP from neighbor database" }, 1807 1.10 christos { "req_lci", hostapd_cli_cmd_req_lci, hostapd_complete_stations, 1808 1.10 christos "<addr> = send LCI request to a station"}, 1809 1.10 christos { "req_range", hostapd_cli_cmd_req_range, NULL, 1810 1.10 christos " = send FTM range request"}, 1811 1.10 christos { "driver_flags", hostapd_cli_cmd_driver_flags, NULL, 1812 1.10 christos " = show supported driver flags"}, 1813 1.12 christos { "driver_flags2", hostapd_cli_cmd_driver_flags2, NULL, 1814 1.12 christos " = show supported driver flags2"}, 1815 1.10 christos #ifdef CONFIG_DPP 1816 1.10 christos { "dpp_qr_code", hostapd_cli_cmd_dpp_qr_code, NULL, 1817 1.10 christos "report a scanned DPP URI from a QR Code" }, 1818 1.10 christos { "dpp_bootstrap_gen", hostapd_cli_cmd_dpp_bootstrap_gen, NULL, 1819 1.10 christos "type=<qrcode> [chan=..] [mac=..] [info=..] [curve=..] [key=..] = generate DPP bootstrap information" }, 1820 1.10 christos { "dpp_bootstrap_remove", hostapd_cli_cmd_dpp_bootstrap_remove, NULL, 1821 1.10 christos "*|<id> = remove DPP bootstrap information" }, 1822 1.10 christos { "dpp_bootstrap_get_uri", hostapd_cli_cmd_dpp_bootstrap_get_uri, NULL, 1823 1.10 christos "<id> = get DPP bootstrap URI" }, 1824 1.10 christos { "dpp_bootstrap_info", hostapd_cli_cmd_dpp_bootstrap_info, NULL, 1825 1.10 christos "<id> = show DPP bootstrap information" }, 1826 1.12 christos { "dpp_bootstrap_set", hostapd_cli_cmd_dpp_bootstrap_set, NULL, 1827 1.12 christos "<id> [conf=..] [ssid=<SSID>] [ssid_charset=#] [psk=<PSK>] [pass=<passphrase>] [configurator=<id>] [conn_status=#] [akm_use_selector=<0|1>] [group_id=..] [expiry=#] [csrattrs=..] = set DPP configurator parameters" }, 1828 1.10 christos { "dpp_auth_init", hostapd_cli_cmd_dpp_auth_init, NULL, 1829 1.10 christos "peer=<id> [own=<id>] = initiate DPP bootstrapping" }, 1830 1.10 christos { "dpp_listen", hostapd_cli_cmd_dpp_listen, NULL, 1831 1.10 christos "<freq in MHz> = start DPP listen" }, 1832 1.10 christos { "dpp_stop_listen", hostapd_cli_cmd_dpp_stop_listen, NULL, 1833 1.10 christos "= stop DPP listen" }, 1834 1.10 christos { "dpp_configurator_add", hostapd_cli_cmd_dpp_configurator_add, NULL, 1835 1.10 christos "[curve=..] [key=..] = add DPP configurator" }, 1836 1.10 christos { "dpp_configurator_remove", hostapd_cli_cmd_dpp_configurator_remove, 1837 1.10 christos NULL, 1838 1.10 christos "*|<id> = remove DPP configurator" }, 1839 1.10 christos { "dpp_configurator_get_key", hostapd_cli_cmd_dpp_configurator_get_key, 1840 1.10 christos NULL, 1841 1.10 christos "<id> = Get DPP configurator's private key" }, 1842 1.11 christos { "dpp_configurator_sign", hostapd_cli_cmd_dpp_configurator_sign, NULL, 1843 1.11 christos "conf=<role> configurator=<id> = generate self DPP configuration" }, 1844 1.10 christos { "dpp_pkex_add", hostapd_cli_cmd_dpp_pkex_add, NULL, 1845 1.10 christos "add PKEX code" }, 1846 1.10 christos { "dpp_pkex_remove", hostapd_cli_cmd_dpp_pkex_remove, NULL, 1847 1.10 christos "*|<id> = remove DPP pkex information" }, 1848 1.12 christos #ifdef CONFIG_DPP2 1849 1.12 christos { "dpp_controller_start", hostapd_cli_cmd_dpp_controller_start, NULL, 1850 1.12 christos "[tcp_port=<port>] [role=..] = start DPP controller" }, 1851 1.12 christos { "dpp_controller_stop", hostapd_cli_cmd_dpp_controller_stop, NULL, 1852 1.12 christos "= stop DPP controller" }, 1853 1.12 christos { "dpp_chirp", hostapd_cli_cmd_dpp_chirp, NULL, 1854 1.12 christos "own=<BI ID> iter=<count> = start DPP chirp" }, 1855 1.12 christos { "dpp_stop_chirp", hostapd_cli_cmd_dpp_stop_chirp, NULL, 1856 1.12 christos "= stop DPP chirp" }, 1857 1.12 christos #endif /* CONFIG_DPP2 */ 1858 1.12 christos #ifdef CONFIG_DPP3 1859 1.12 christos { "dpp_push_button", hostapd_cli_cmd_dpp_push_button, NULL, 1860 1.12 christos "= press DPP push button" }, 1861 1.12 christos #endif /* CONFIG_DPP3 */ 1862 1.10 christos #endif /* CONFIG_DPP */ 1863 1.10 christos { "accept_acl", hostapd_cli_cmd_accept_macacl, NULL, 1864 1.10 christos "=Add/Delete/Show/Clear accept MAC ACL" }, 1865 1.10 christos { "deny_acl", hostapd_cli_cmd_deny_macacl, NULL, 1866 1.10 christos "=Add/Delete/Show/Clear deny MAC ACL" }, 1867 1.10 christos { "poll_sta", hostapd_cli_cmd_poll_sta, hostapd_complete_stations, 1868 1.10 christos "<addr> = poll a STA to check connectivity with a QoS null frame" }, 1869 1.11 christos { "req_beacon", hostapd_cli_cmd_req_beacon, NULL, 1870 1.11 christos "<addr> [req_mode=] <measurement request hexdump> = send a Beacon report request to a station" }, 1871 1.12 christos { "req_link_measurement", hostapd_cli_cmd_req_link_measurement, NULL, 1872 1.12 christos "<addr> = send a link measurement report request to a station"}, 1873 1.11 christos { "reload_wpa_psk", hostapd_cli_cmd_reload_wpa_psk, NULL, 1874 1.11 christos "= reload wpa_psk_file only" }, 1875 1.12 christos #ifdef CONFIG_IEEE80211R_AP 1876 1.12 christos { "reload_rxkhs", hostapd_cli_cmd_reload_rxkhs, NULL, 1877 1.12 christos "= reload R0KHs and R1KHs" }, 1878 1.12 christos { "get_rxkhs", hostapd_cli_cmd_get_rxkhs, NULL, 1879 1.12 christos "= get R0KHs and R1KHs" }, 1880 1.12 christos #endif /* CONFIG_IEEE80211R_AP */ 1881 1.12 christos #ifdef ANDROID 1882 1.12 christos { "driver", hostapd_cli_cmd_driver, NULL, 1883 1.12 christos "<driver sub command> [<hex formatted data>] = send driver command data" }, 1884 1.12 christos #endif /* ANDROID */ 1885 1.9 christos { NULL, NULL, NULL, NULL } 1886 1.1 christos }; 1887 1.1 christos 1888 1.1 christos 1889 1.9 christos /* 1890 1.9 christos * Prints command usage, lines are padded with the specified string. 1891 1.9 christos */ 1892 1.9 christos static void print_cmd_help(FILE *stream, const struct hostapd_cli_cmd *cmd, 1893 1.9 christos const char *pad) 1894 1.9 christos { 1895 1.9 christos char c; 1896 1.9 christos size_t n; 1897 1.9 christos 1898 1.9 christos if (cmd->usage == NULL) 1899 1.9 christos return; 1900 1.9 christos fprintf(stream, "%s%s ", pad, cmd->cmd); 1901 1.9 christos for (n = 0; (c = cmd->usage[n]); n++) { 1902 1.9 christos fprintf(stream, "%c", c); 1903 1.9 christos if (c == '\n') 1904 1.9 christos fprintf(stream, "%s", pad); 1905 1.9 christos } 1906 1.9 christos fprintf(stream, "\n"); 1907 1.9 christos } 1908 1.9 christos 1909 1.9 christos 1910 1.9 christos static void print_help(FILE *stream, const char *cmd) 1911 1.9 christos { 1912 1.9 christos int n; 1913 1.9 christos 1914 1.9 christos fprintf(stream, "commands:\n"); 1915 1.9 christos for (n = 0; hostapd_cli_commands[n].cmd; n++) { 1916 1.9 christos if (cmd == NULL || str_starts(hostapd_cli_commands[n].cmd, cmd)) 1917 1.9 christos print_cmd_help(stream, &hostapd_cli_commands[n], " "); 1918 1.9 christos } 1919 1.9 christos } 1920 1.9 christos 1921 1.9 christos 1922 1.1 christos static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1923 1.1 christos { 1924 1.9 christos const struct hostapd_cli_cmd *cmd, *match = NULL; 1925 1.1 christos int count; 1926 1.1 christos 1927 1.1 christos count = 0; 1928 1.1 christos cmd = hostapd_cli_commands; 1929 1.1 christos while (cmd->cmd) { 1930 1.1 christos if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0) { 1931 1.1 christos match = cmd; 1932 1.4 christos if (os_strcasecmp(cmd->cmd, argv[0]) == 0) { 1933 1.4 christos /* we have an exact match */ 1934 1.4 christos count = 1; 1935 1.4 christos break; 1936 1.4 christos } 1937 1.1 christos count++; 1938 1.1 christos } 1939 1.1 christos cmd++; 1940 1.1 christos } 1941 1.1 christos 1942 1.1 christos if (count > 1) { 1943 1.1 christos printf("Ambiguous command '%s'; possible commands:", argv[0]); 1944 1.1 christos cmd = hostapd_cli_commands; 1945 1.1 christos while (cmd->cmd) { 1946 1.1 christos if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 1947 1.1 christos 0) { 1948 1.1 christos printf(" %s", cmd->cmd); 1949 1.1 christos } 1950 1.1 christos cmd++; 1951 1.1 christos } 1952 1.1 christos printf("\n"); 1953 1.1 christos } else if (count == 0) { 1954 1.1 christos printf("Unknown command '%s'\n", argv[0]); 1955 1.1 christos } else { 1956 1.1 christos match->handler(ctrl, argc - 1, &argv[1]); 1957 1.1 christos } 1958 1.1 christos } 1959 1.1 christos 1960 1.1 christos 1961 1.9 christos static void cli_event(const char *str) 1962 1.9 christos { 1963 1.9 christos const char *start, *s; 1964 1.9 christos 1965 1.9 christos start = os_strchr(str, '>'); 1966 1.9 christos if (start == NULL) 1967 1.9 christos return; 1968 1.9 christos 1969 1.9 christos start++; 1970 1.9 christos 1971 1.9 christos if (str_starts(start, AP_STA_CONNECTED)) { 1972 1.9 christos s = os_strchr(start, ' '); 1973 1.9 christos if (s == NULL) 1974 1.9 christos return; 1975 1.9 christos cli_txt_list_add(&stations, s + 1); 1976 1.9 christos return; 1977 1.9 christos } 1978 1.9 christos 1979 1.9 christos if (str_starts(start, AP_STA_DISCONNECTED)) { 1980 1.9 christos s = os_strchr(start, ' '); 1981 1.9 christos if (s == NULL) 1982 1.9 christos return; 1983 1.9 christos cli_txt_list_del_addr(&stations, s + 1); 1984 1.9 christos return; 1985 1.9 christos } 1986 1.9 christos } 1987 1.9 christos 1988 1.9 christos 1989 1.1 christos static void hostapd_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read, 1990 1.1 christos int action_monitor) 1991 1.1 christos { 1992 1.1 christos int first = 1; 1993 1.1 christos if (ctrl_conn == NULL) 1994 1.1 christos return; 1995 1.1 christos while (wpa_ctrl_pending(ctrl)) { 1996 1.10 christos char buf[4096]; 1997 1.1 christos size_t len = sizeof(buf) - 1; 1998 1.1 christos if (wpa_ctrl_recv(ctrl, buf, &len) == 0) { 1999 1.1 christos buf[len] = '\0'; 2000 1.1 christos if (action_monitor) 2001 1.1 christos hostapd_cli_action_process(buf, len); 2002 1.1 christos else { 2003 1.9 christos cli_event(buf); 2004 1.1 christos if (in_read && first) 2005 1.1 christos printf("\n"); 2006 1.1 christos first = 0; 2007 1.1 christos printf("%s\n", buf); 2008 1.1 christos } 2009 1.1 christos } else { 2010 1.1 christos printf("Could not read pending message.\n"); 2011 1.1 christos break; 2012 1.1 christos } 2013 1.1 christos } 2014 1.1 christos } 2015 1.1 christos 2016 1.1 christos 2017 1.9 christos static void hostapd_cli_receive(int sock, void *eloop_ctx, void *sock_ctx) 2018 1.1 christos { 2019 1.9 christos hostapd_cli_recv_pending(ctrl_conn, 0, 0); 2020 1.1 christos } 2021 1.1 christos 2022 1.1 christos 2023 1.4 christos static void hostapd_cli_ping(void *eloop_ctx, void *timeout_ctx) 2024 1.1 christos { 2025 1.1 christos if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) { 2026 1.1 christos printf("Connection to hostapd lost - trying to reconnect\n"); 2027 1.1 christos hostapd_cli_close_connection(); 2028 1.1 christos } 2029 1.10 christos if (!ctrl_conn && hostapd_cli_reconnect(ctrl_ifname) == 0) 2030 1.10 christos printf("Connection to hostapd re-established\n"); 2031 1.1 christos if (ctrl_conn) 2032 1.1 christos hostapd_cli_recv_pending(ctrl_conn, 1, 0); 2033 1.4 christos eloop_register_timeout(ping_interval, 0, hostapd_cli_ping, NULL, NULL); 2034 1.4 christos } 2035 1.4 christos 2036 1.4 christos 2037 1.4 christos static void hostapd_cli_eloop_terminate(int sig, void *signal_ctx) 2038 1.4 christos { 2039 1.4 christos eloop_terminate(); 2040 1.4 christos } 2041 1.4 christos 2042 1.4 christos 2043 1.4 christos static void hostapd_cli_edit_cmd_cb(void *ctx, char *cmd) 2044 1.4 christos { 2045 1.4 christos char *argv[max_args]; 2046 1.4 christos int argc; 2047 1.4 christos argc = tokenize_cmd(cmd, argv); 2048 1.4 christos if (argc) 2049 1.4 christos wpa_request(ctrl_conn, argc, argv); 2050 1.4 christos } 2051 1.4 christos 2052 1.4 christos 2053 1.4 christos static void hostapd_cli_edit_eof_cb(void *ctx) 2054 1.4 christos { 2055 1.4 christos eloop_terminate(); 2056 1.4 christos } 2057 1.4 christos 2058 1.4 christos 2059 1.9 christos static char ** list_cmd_list(void) 2060 1.9 christos { 2061 1.9 christos char **res; 2062 1.9 christos int i, count; 2063 1.9 christos 2064 1.9 christos count = ARRAY_SIZE(hostapd_cli_commands); 2065 1.9 christos res = os_calloc(count + 1, sizeof(char *)); 2066 1.9 christos if (res == NULL) 2067 1.9 christos return NULL; 2068 1.9 christos 2069 1.9 christos for (i = 0; hostapd_cli_commands[i].cmd; i++) { 2070 1.9 christos res[i] = os_strdup(hostapd_cli_commands[i].cmd); 2071 1.9 christos if (res[i] == NULL) 2072 1.9 christos break; 2073 1.9 christos } 2074 1.9 christos 2075 1.9 christos return res; 2076 1.9 christos } 2077 1.9 christos 2078 1.9 christos 2079 1.9 christos static char ** hostapd_cli_cmd_completion(const char *cmd, const char *str, 2080 1.9 christos int pos) 2081 1.9 christos { 2082 1.9 christos int i; 2083 1.9 christos 2084 1.9 christos for (i = 0; hostapd_cli_commands[i].cmd; i++) { 2085 1.9 christos if (os_strcasecmp(hostapd_cli_commands[i].cmd, cmd) != 0) 2086 1.9 christos continue; 2087 1.9 christos if (hostapd_cli_commands[i].completion) 2088 1.9 christos return hostapd_cli_commands[i].completion(str, pos); 2089 1.9 christos if (!hostapd_cli_commands[i].usage) 2090 1.9 christos return NULL; 2091 1.9 christos edit_clear_line(); 2092 1.9 christos printf("\r%s\n", hostapd_cli_commands[i].usage); 2093 1.9 christos edit_redraw(); 2094 1.9 christos break; 2095 1.9 christos } 2096 1.9 christos 2097 1.9 christos return NULL; 2098 1.9 christos } 2099 1.9 christos 2100 1.9 christos 2101 1.9 christos static char ** hostapd_cli_edit_completion_cb(void *ctx, const char *str, 2102 1.9 christos int pos) 2103 1.9 christos { 2104 1.9 christos char **res; 2105 1.9 christos const char *end; 2106 1.9 christos char *cmd; 2107 1.9 christos 2108 1.9 christos end = os_strchr(str, ' '); 2109 1.9 christos if (end == NULL || str + pos < end) 2110 1.9 christos return list_cmd_list(); 2111 1.9 christos 2112 1.9 christos cmd = os_malloc(pos + 1); 2113 1.9 christos if (cmd == NULL) 2114 1.9 christos return NULL; 2115 1.9 christos os_memcpy(cmd, str, pos); 2116 1.9 christos cmd[end - str] = '\0'; 2117 1.9 christos res = hostapd_cli_cmd_completion(cmd, str, pos); 2118 1.9 christos os_free(cmd); 2119 1.9 christos return res; 2120 1.9 christos } 2121 1.9 christos 2122 1.9 christos 2123 1.4 christos static void hostapd_cli_interactive(void) 2124 1.4 christos { 2125 1.10 christos char *hfile = NULL; 2126 1.10 christos char *home; 2127 1.10 christos 2128 1.4 christos printf("\nInteractive mode\n\n"); 2129 1.4 christos 2130 1.10 christos #ifdef CONFIG_HOSTAPD_CLI_HISTORY_DIR 2131 1.10 christos home = CONFIG_HOSTAPD_CLI_HISTORY_DIR; 2132 1.10 christos #else /* CONFIG_HOSTAPD_CLI_HISTORY_DIR */ 2133 1.10 christos home = getenv("HOME"); 2134 1.10 christos #endif /* CONFIG_HOSTAPD_CLI_HISTORY_DIR */ 2135 1.10 christos if (home) { 2136 1.10 christos const char *fname = ".hostapd_cli_history"; 2137 1.10 christos int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1; 2138 1.10 christos hfile = os_malloc(hfile_len); 2139 1.10 christos if (hfile) 2140 1.10 christos os_snprintf(hfile, hfile_len, "%s/%s", home, fname); 2141 1.10 christos } 2142 1.10 christos 2143 1.4 christos edit_init(hostapd_cli_edit_cmd_cb, hostapd_cli_edit_eof_cb, 2144 1.10 christos hostapd_cli_edit_completion_cb, NULL, hfile, NULL); 2145 1.4 christos eloop_register_timeout(ping_interval, 0, hostapd_cli_ping, NULL, NULL); 2146 1.4 christos 2147 1.4 christos eloop_run(); 2148 1.4 christos 2149 1.9 christos cli_txt_list_flush(&stations); 2150 1.10 christos edit_deinit(hfile, NULL); 2151 1.10 christos os_free(hfile); 2152 1.4 christos eloop_cancel_timeout(hostapd_cli_ping, NULL, NULL); 2153 1.4 christos } 2154 1.4 christos 2155 1.4 christos 2156 1.4 christos static void hostapd_cli_cleanup(void) 2157 1.4 christos { 2158 1.4 christos hostapd_cli_close_connection(); 2159 1.4 christos if (pid_file) 2160 1.4 christos os_daemonize_terminate(pid_file); 2161 1.4 christos 2162 1.4 christos os_program_deinit(); 2163 1.1 christos } 2164 1.1 christos 2165 1.1 christos 2166 1.12 christos static void hostapd_cli_action_ping(void *eloop_ctx, void *timeout_ctx) 2167 1.1 christos { 2168 1.12 christos struct wpa_ctrl *ctrl = eloop_ctx; 2169 1.1 christos char buf[256]; 2170 1.1 christos size_t len; 2171 1.1 christos 2172 1.12 christos /* verify that connection is still working */ 2173 1.12 christos len = sizeof(buf) - 1; 2174 1.12 christos if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len, 2175 1.12 christos hostapd_cli_action_cb) < 0 || 2176 1.12 christos len < 4 || os_memcmp(buf, "PONG", 4) != 0) { 2177 1.12 christos printf("hostapd did not reply to PING command - exiting\n"); 2178 1.12 christos eloop_terminate(); 2179 1.12 christos return; 2180 1.12 christos } 2181 1.12 christos eloop_register_timeout(ping_interval, 0, hostapd_cli_action_ping, 2182 1.12 christos ctrl, NULL); 2183 1.12 christos } 2184 1.12 christos 2185 1.12 christos 2186 1.12 christos static void hostapd_cli_action_receive(int sock, void *eloop_ctx, 2187 1.12 christos void *sock_ctx) 2188 1.12 christos { 2189 1.12 christos struct wpa_ctrl *ctrl = eloop_ctx; 2190 1.12 christos 2191 1.12 christos hostapd_cli_recv_pending(ctrl, 0, 1); 2192 1.12 christos } 2193 1.12 christos 2194 1.1 christos 2195 1.12 christos static void hostapd_cli_action(struct wpa_ctrl *ctrl) 2196 1.12 christos { 2197 1.12 christos int fd; 2198 1.1 christos 2199 1.12 christos fd = wpa_ctrl_get_fd(ctrl); 2200 1.12 christos eloop_register_timeout(ping_interval, 0, hostapd_cli_action_ping, 2201 1.12 christos ctrl, NULL); 2202 1.12 christos eloop_register_read_sock(fd, hostapd_cli_action_receive, ctrl, NULL); 2203 1.12 christos eloop_run(); 2204 1.12 christos eloop_cancel_timeout(hostapd_cli_action_ping, ctrl, NULL); 2205 1.12 christos eloop_unregister_read_sock(fd); 2206 1.1 christos } 2207 1.1 christos 2208 1.1 christos 2209 1.1 christos int main(int argc, char *argv[]) 2210 1.1 christos { 2211 1.1 christos int warning_displayed = 0; 2212 1.1 christos int c; 2213 1.1 christos int daemonize = 0; 2214 1.12 christos int reconnect = 0; 2215 1.1 christos 2216 1.1 christos if (os_program_init()) 2217 1.1 christos return -1; 2218 1.1 christos 2219 1.1 christos for (;;) { 2220 1.12 christos c = getopt(argc, argv, "a:BhG:i:p:P:rs:v"); 2221 1.1 christos if (c < 0) 2222 1.1 christos break; 2223 1.1 christos switch (c) { 2224 1.1 christos case 'a': 2225 1.1 christos action_file = optarg; 2226 1.1 christos break; 2227 1.1 christos case 'B': 2228 1.1 christos daemonize = 1; 2229 1.1 christos break; 2230 1.1 christos case 'G': 2231 1.1 christos ping_interval = atoi(optarg); 2232 1.1 christos break; 2233 1.1 christos case 'h': 2234 1.1 christos usage(); 2235 1.1 christos return 0; 2236 1.1 christos case 'v': 2237 1.1 christos printf("%s\n", hostapd_cli_version); 2238 1.1 christos return 0; 2239 1.1 christos case 'i': 2240 1.1 christos os_free(ctrl_ifname); 2241 1.1 christos ctrl_ifname = os_strdup(optarg); 2242 1.1 christos break; 2243 1.1 christos case 'p': 2244 1.1 christos ctrl_iface_dir = optarg; 2245 1.1 christos break; 2246 1.9 christos case 'P': 2247 1.9 christos pid_file = optarg; 2248 1.9 christos break; 2249 1.12 christos case 'r': 2250 1.12 christos reconnect = 1; 2251 1.12 christos break; 2252 1.9 christos case 's': 2253 1.9 christos client_socket_dir = optarg; 2254 1.9 christos break; 2255 1.1 christos default: 2256 1.1 christos usage(); 2257 1.1 christos return -1; 2258 1.1 christos } 2259 1.1 christos } 2260 1.1 christos 2261 1.1 christos interactive = (argc == optind) && (action_file == NULL); 2262 1.1 christos 2263 1.1 christos if (interactive) { 2264 1.9 christos printf("%s\n\n%s\n\n", hostapd_cli_version, cli_license); 2265 1.1 christos } 2266 1.1 christos 2267 1.4 christos if (eloop_init()) 2268 1.4 christos return -1; 2269 1.4 christos 2270 1.1 christos for (;;) { 2271 1.1 christos if (ctrl_ifname == NULL) { 2272 1.1 christos struct dirent *dent; 2273 1.1 christos DIR *dir = opendir(ctrl_iface_dir); 2274 1.1 christos if (dir) { 2275 1.1 christos while ((dent = readdir(dir))) { 2276 1.1 christos if (os_strcmp(dent->d_name, ".") == 0 2277 1.1 christos || 2278 1.1 christos os_strcmp(dent->d_name, "..") == 0) 2279 1.1 christos continue; 2280 1.1 christos printf("Selected interface '%s'\n", 2281 1.1 christos dent->d_name); 2282 1.1 christos ctrl_ifname = os_strdup(dent->d_name); 2283 1.1 christos break; 2284 1.1 christos } 2285 1.1 christos closedir(dir); 2286 1.1 christos } 2287 1.1 christos } 2288 1.10 christos hostapd_cli_reconnect(ctrl_ifname); 2289 1.1 christos if (ctrl_conn) { 2290 1.1 christos if (warning_displayed) 2291 1.1 christos printf("Connection established.\n"); 2292 1.1 christos break; 2293 1.1 christos } 2294 1.12 christos if (!interactive && !reconnect) { 2295 1.1 christos perror("Failed to connect to hostapd - " 2296 1.1 christos "wpa_ctrl_open"); 2297 1.1 christos return -1; 2298 1.1 christos } 2299 1.1 christos 2300 1.1 christos if (!warning_displayed) { 2301 1.1 christos printf("Could not connect to hostapd - re-trying\n"); 2302 1.1 christos warning_displayed = 1; 2303 1.1 christos } 2304 1.1 christos os_sleep(1, 0); 2305 1.1 christos continue; 2306 1.1 christos } 2307 1.1 christos 2308 1.12 christos eloop_register_signal_terminate(hostapd_cli_eloop_terminate, NULL); 2309 1.12 christos 2310 1.10 christos if (action_file && !hostapd_cli_attached) 2311 1.10 christos return -1; 2312 1.8 roy if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue()) 2313 1.1 christos return -1; 2314 1.12 christos if (reconnect && action_file && ctrl_ifname) { 2315 1.12 christos while (!hostapd_cli_quit) { 2316 1.12 christos if (ctrl_conn) 2317 1.12 christos hostapd_cli_action(ctrl_conn); 2318 1.12 christos os_sleep(1, 0); 2319 1.12 christos hostapd_cli_reconnect(ctrl_ifname); 2320 1.12 christos } 2321 1.12 christos } else if (interactive) 2322 1.1 christos hostapd_cli_interactive(); 2323 1.1 christos else if (action_file) 2324 1.1 christos hostapd_cli_action(ctrl_conn); 2325 1.1 christos else 2326 1.1 christos wpa_request(ctrl_conn, argc - optind, &argv[optind]); 2327 1.1 christos 2328 1.9 christos unregister_event_handler(ctrl_conn); 2329 1.1 christos os_free(ctrl_ifname); 2330 1.4 christos eloop_destroy(); 2331 1.1 christos hostapd_cli_cleanup(); 2332 1.1 christos return 0; 2333 1.1 christos } 2334 1.9 christos 2335 1.9 christos #else /* CONFIG_NO_CTRL_IFACE */ 2336 1.9 christos 2337 1.9 christos int main(int argc, char *argv[]) 2338 1.9 christos { 2339 1.9 christos return -1; 2340 1.9 christos } 2341 1.9 christos 2342 1.9 christos #endif /* CONFIG_NO_CTRL_IFACE */ 2343