📄 wpa_cli.c
字号:
}static void wpa_cli_action_process(const char *msg){ const char *pos; char *copy = NULL, *id, *pos2; pos = msg; if (*pos == '<') { /* skip priority */ pos = os_strchr(pos, '>'); if (pos) pos++; else pos = msg; } if (str_match(pos, WPA_EVENT_CONNECTED)) { int new_id = -1; os_unsetenv("WPA_ID"); os_unsetenv("WPA_ID_STR"); os_unsetenv("WPA_CTRL_DIR"); pos = os_strstr(pos, "[id="); if (pos) copy = os_strdup(pos + 4); if (copy) { pos2 = id = copy; while (*pos2 && *pos2 != ' ') pos2++; *pos2++ = '\0'; new_id = atoi(id); os_setenv("WPA_ID", id, 1); while (*pos2 && *pos2 != '=') pos2++; if (*pos2 == '=') pos2++; id = pos2; while (*pos2 && *pos2 != ']') pos2++; *pos2 = '\0'; os_setenv("WPA_ID_STR", id, 1); os_free(copy); } os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1); if (!wpa_cli_connected || new_id != wpa_cli_last_id) { wpa_cli_connected = 1; wpa_cli_last_id = new_id; wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED"); } } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) { if (wpa_cli_connected) { wpa_cli_connected = 0; wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED"); } } else if (str_match(pos, WPA_EVENT_TERMINATING)) { printf("wpa_supplicant is terminating - stop monitoring\n"); wpa_cli_quit = 1; }}#ifndef CONFIG_ANSI_C_EXTRAstatic void wpa_cli_action_cb(char *msg, size_t len){ wpa_cli_action_process(msg);}#endif /* CONFIG_ANSI_C_EXTRA */static void wpa_cli_reconnect(void){ wpa_cli_close_connection(); ctrl_conn = wpa_cli_open_connection(ctrl_ifname); if (ctrl_conn) { printf("Connection to wpa_supplicant re-established\n"); if (wpa_ctrl_attach(ctrl_conn) == 0) { wpa_cli_attached = 1; } else { printf("Warning: Failed to attach to " "wpa_supplicant.\n"); } }}static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read, int action_monitor){ int first = 1; if (ctrl_conn == NULL) { wpa_cli_reconnect(); return; } while (wpa_ctrl_pending(ctrl) > 0) { char buf[256]; size_t len = sizeof(buf) - 1; if (wpa_ctrl_recv(ctrl, buf, &len) == 0) { buf[len] = '\0'; if (action_monitor) wpa_cli_action_process(buf); else { if (in_read && first) printf("\n"); first = 0; printf("%s\n", buf); } } else { printf("Could not read pending message.\n"); break; } } if (wpa_ctrl_pending(ctrl) < 0) { printf("Connection to wpa_supplicant lost - trying to " "reconnect\n"); wpa_cli_reconnect(); }}#ifdef CONFIG_READLINEstatic char * wpa_cli_cmd_gen(const char *text, int state){ static int i, len; const char *cmd; if (state == 0) { i = 0; len = os_strlen(text); } while ((cmd = wpa_cli_commands[i].cmd)) { i++; if (os_strncasecmp(cmd, text, len) == 0) return os_strdup(cmd); } return NULL;}static char * wpa_cli_dummy_gen(const char *text, int state){ return NULL;}static char ** wpa_cli_completion(const char *text, int start, int end){ return rl_completion_matches(text, start == 0 ? wpa_cli_cmd_gen : wpa_cli_dummy_gen);}#endif /* CONFIG_READLINE */static void wpa_cli_interactive(void){#define max_args 10 char cmdbuf[256], *cmd, *argv[max_args], *pos; int argc;#ifdef CONFIG_READLINE char *home, *hfile = NULL;#endif /* CONFIG_READLINE */ printf("\nInteractive mode\n\n");#ifdef CONFIG_READLINE rl_attempted_completion_function = wpa_cli_completion; home = getenv("HOME"); if (home) { const char *fname = ".wpa_cli_history"; int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1; hfile = os_malloc(hfile_len); if (hfile) { os_snprintf(hfile, hfile_len, "%s/%s", home, fname); hfile[hfile_len - 1] = '\0'; read_history(hfile); stifle_history(100); } }#endif /* CONFIG_READLINE */ do { wpa_cli_recv_pending(ctrl_conn, 0, 0);#ifndef CONFIG_NATIVE_WINDOWS alarm(1);#endif /* CONFIG_NATIVE_WINDOWS */#ifdef CONFIG_READLINE cmd = readline("> "); if (cmd && *cmd) { HIST_ENTRY *h; while (next_history()) ; h = previous_history(); if (h == NULL || os_strcmp(cmd, h->line) != 0) add_history(cmd); next_history(); }#else /* CONFIG_READLINE */ printf("> "); cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);#endif /* CONFIG_READLINE */#ifndef CONFIG_NATIVE_WINDOWS alarm(0);#endif /* CONFIG_NATIVE_WINDOWS */ if (cmd == NULL) break; wpa_cli_recv_pending(ctrl_conn, 0, 0); pos = cmd; while (*pos != '\0') { if (*pos == '\n') { *pos = '\0'; break; } pos++; } argc = 0; pos = cmd; for (;;) { while (*pos == ' ') pos++; if (*pos == '\0') break; argv[argc] = pos; argc++; if (argc == max_args) break; if (*pos == '"') { char *pos2 = os_strrchr(pos, '"'); if (pos2) pos = pos2 + 1; } while (*pos != '\0' && *pos != ' ') pos++; if (*pos == ' ') *pos++ = '\0'; } if (argc) wpa_request(ctrl_conn, argc, argv); if (cmd != cmdbuf) os_free(cmd); } while (!wpa_cli_quit);#ifdef CONFIG_READLINE if (hfile) { /* Save command history, excluding lines that may contain * passwords. */ HIST_ENTRY *h; history_set_pos(0); h = next_history(); while (h) { char *p = h->line; while (*p == ' ' || *p == '\t') p++; if (os_strncasecmp(p, "pa", 2) == 0 || os_strncasecmp(p, "o", 1) == 0 || os_strncasecmp(p, "n", 1)) { h = remove_history(where_history()); if (h) { os_free(h->line); os_free(h->data); os_free(h); } h = current_history(); } else { h = next_history(); } } write_history(hfile); os_free(hfile); }#endif /* CONFIG_READLINE */}static void wpa_cli_action(struct wpa_ctrl *ctrl){#ifdef CONFIG_ANSI_C_EXTRA /* TODO: ANSI C version(?) */ printf("Action processing not supported in ANSI C build.\n");#else /* CONFIG_ANSI_C_EXTRA */ fd_set rfds; int fd, res; struct timeval tv; char buf[256]; /* note: large enough to fit in unsolicited messages */ size_t len; fd = wpa_ctrl_get_fd(ctrl); while (!wpa_cli_quit) { FD_ZERO(&rfds); FD_SET(fd, &rfds); tv.tv_sec = 2; tv.tv_usec = 0; res = select(fd + 1, &rfds, NULL, NULL, &tv); if (res < 0 && errno != EINTR) { perror("select"); break; } if (FD_ISSET(fd, &rfds)) wpa_cli_recv_pending(ctrl, 0, 1); else { /* verify that connection is still working */ len = sizeof(buf) - 1; if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len, wpa_cli_action_cb) < 0 || len < 4 || os_memcmp(buf, "PONG", 4) != 0) { printf("wpa_supplicant did not reply to PING " "command - exiting\n"); break; } } }#endif /* CONFIG_ANSI_C_EXTRA */}static void wpa_cli_cleanup(void){ wpa_cli_close_connection(); if (pid_file) os_daemonize_terminate(pid_file); os_program_deinit();}static void wpa_cli_terminate(int sig){ wpa_cli_cleanup(); exit(0);}#ifndef CONFIG_NATIVE_WINDOWSstatic void wpa_cli_alarm(int sig){ if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) { printf("Connection to wpa_supplicant lost - trying to " "reconnect\n"); wpa_cli_close_connection(); } if (!ctrl_conn) wpa_cli_reconnect(); if (ctrl_conn) wpa_cli_recv_pending(ctrl_conn, 1, 0); alarm(1);}#endif /* CONFIG_NATIVE_WINDOWS */static char * wpa_cli_get_default_ifname(void){ char *ifname = NULL;#ifdef CONFIG_CTRL_IFACE_UNIX struct dirent *dent; DIR *dir = opendir(ctrl_iface_dir); if (!dir) return NULL; while ((dent = readdir(dir))) {#ifdef _DIRENT_HAVE_D_TYPE /* * Skip the file if it is not a socket. Also accept * DT_UNKNOWN (0) in case the C library or underlying * file system does not support d_type. */ if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN) continue;#endif /* _DIRENT_HAVE_D_TYPE */ if (os_strcmp(dent->d_name, ".") == 0 || os_strcmp(dent->d_name, "..") == 0) continue; printf("Selected interface '%s'\n", dent->d_name); ifname = os_strdup(dent->d_name); break; } closedir(dir);#endif /* CONFIG_CTRL_IFACE_UNIX */#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE char buf[2048], *pos; size_t len; struct wpa_ctrl *ctrl; int ret; ctrl = wpa_ctrl_open(NULL); if (ctrl == NULL) return NULL; len = sizeof(buf) - 1; ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL); if (ret >= 0) { buf[len] = '\0'; pos = os_strchr(buf, '\n'); if (pos) *pos = '\0'; ifname = os_strdup(buf); } wpa_ctrl_close(ctrl);#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ return ifname;}int main(int argc, char *argv[]){ int interactive; int warning_displayed = 0; int c; int daemonize = 0; int ret = 0; const char *global = NULL; if (os_program_init()) return -1; for (;;) { c = getopt(argc, argv, "a:Bg:hi:p:P:v"); if (c < 0) break; switch (c) { case 'a': action_file = optarg; break; case 'B': daemonize = 1; break; case 'g': global = optarg; break; case 'h': usage(); return 0; case 'v': printf("%s\n", wpa_cli_version); return 0; case 'i': os_free(ctrl_ifname); ctrl_ifname = os_strdup(optarg); break; case 'p': ctrl_iface_dir = optarg; break; case 'P': pid_file = optarg; break; default: usage(); return -1; } } interactive = (argc == optind) && (action_file == NULL); if (interactive) printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license); if (global) {#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE ctrl_conn = wpa_ctrl_open(NULL);#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */ ctrl_conn = wpa_ctrl_open(global);#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ if (ctrl_conn == NULL) { perror("Failed to connect to wpa_supplicant - " "wpa_ctrl_open"); return -1; } } for (; !global;) { if (ctrl_ifname == NULL) ctrl_ifname = wpa_cli_get_default_ifname(); ctrl_conn = wpa_cli_open_connection(ctrl_ifname); if (ctrl_conn) { if (warning_displayed) printf("Connection established.\n"); break; } if (!interactive) { perror("Failed to connect to wpa_supplicant - " "wpa_ctrl_open"); return -1; } if (!warning_displayed) { printf("Could not connect to wpa_supplicant - " "re-trying\n"); warning_displayed = 1; } os_sleep(1, 0); continue; }#ifndef _WIN32_WCE signal(SIGINT, wpa_cli_terminate); signal(SIGTERM, wpa_cli_terminate);#endif /* _WIN32_WCE */#ifndef CONFIG_NATIVE_WINDOWS signal(SIGALRM, wpa_cli_alarm);#endif /* CONFIG_NATIVE_WINDOWS */ if (interactive || action_file) { if (wpa_ctrl_attach(ctrl_conn) == 0) { wpa_cli_attached = 1; } else { printf("Warning: Failed to attach to " "wpa_supplicant.\n"); if (!interactive) return -1; } } if (daemonize && os_daemonize(pid_file)) return -1; if (interactive) wpa_cli_interactive(); else if (action_file) wpa_cli_action(ctrl_conn); else ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]); os_free(ctrl_ifname); wpa_cli_cleanup(); return ret;}#else /* CONFIG_CTRL_IFACE */int main(int argc, char *argv[]){ printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n"); return -1;}#endif /* CONFIG_CTRL_IFACE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -