/* wpatalk_recv_pending -- process pending packets from authentication * daemon, and return > 0 if there are more packets (less than zero * if error). * If block is set to 1, will sleep waiting for up to one packet. */ static int wpatalk_recv_pending(int block) { struct pollfd fds[1]; int nfds; int more = 0; int timeout_msec = 0; /* negative for infinity */ char buf[512]; /* note: large enough to fit in unsolicited messages */ size_t len; int nloops; for (nloops = 0; ; nloops++) { if (ctrl_conn == NULL) { return -1; } fds[0].fd = wpa_ctrl_get_fd(ctrl_conn); fds[0].events = POLLIN; fds[0].revents = 0; nfds = 1; if (nloops > 0) timeout_msec = 1000; else timeout_msec = 0; nfds = poll(fds, nfds, timeout_msec); if (nfds < 0) { if (errno == EINTR) continue; #if 1 wpatalk_error("Connection to daemon lost"); #else wpatalk_fatal("Died on poll() error %d", errno); #endif return -1; } more = (nfds > 0); if (more == 0) { if (block == 0) { return 0; /* nothing pending */ } else { /* blocking mode */ /* verify that connection is still working */ size_t len = sizeof(buf) - 1; if (wpa_ctrl_request(ctrl_conn, "PING", 4, buf, &len, wpatalk_action_cb) < 0 || len < 4 || os_memcmp(buf, "PONG", 4) != 0) { wpatalk_error("daemon did not reply to PING"); return -1; } /* and try again */ continue; } } len = sizeof(buf) - 1; if (wpa_ctrl_recv(ctrl_conn, buf, &len) == 0) { buf[len] = '\0'; wpatalk_info("GOT: %s", buf); wpatalk_action_process(buf); } else { wpatalk_error("Could not read pending message."); } break; } return more; }
int wifi_ctrl_recv(char *reply, size_t *reply_len) { int res; int ctrlfd = wpa_ctrl_get_fd(monitor_conn); struct pollfd rfds[2]; memset(rfds, 0, 2 * sizeof(struct pollfd)); rfds[0].fd = ctrlfd; rfds[0].events |= POLLIN; rfds[1].fd = exit_sockets[1]; rfds[1].events |= POLLIN; do { res = TEMP_FAILURE_RETRY(poll(rfds, 2, 30000)); if (res < 0) { ALOGE("Error poll = %d", res); return res; } else if (res == 0) { /* timed out, check if supplicant is active * or not .. */ res = wifi_supplicant_connection_active(); if (res < 0) return -2; } } while (res == 0); if (rfds[0].revents & POLLIN) { return wpa_ctrl_recv(monitor_conn, reply, reply_len); } /* it is not rfds[0], then it must be rfts[1] (i.e. the exit socket) * or we timed out. In either case, this call has failed .. */ return -2; }
int wifi_ctrl_recv(int index, char *reply, size_t *reply_len) { int res; int ctrlfd = wpa_ctrl_get_fd(monitor_conn[index]); struct pollfd rfds[2]; memset(rfds, 0, 2 * sizeof(struct pollfd)); rfds[0].fd = ctrlfd; rfds[0].events |= POLLIN; rfds[1].fd = exit_sockets[index][1]; rfds[1].events |= POLLIN; res = TEMP_FAILURE_RETRY(poll(rfds, 2, -1)); if (res < 0) { ALOGE("Error poll = %d", res); return res; } if (rfds[0].revents & POLLIN) { return wpa_ctrl_recv(monitor_conn[index], reply, reply_len); } else if (rfds[1].revents & POLLIN) { /* Close only the p2p sockets on receive side * see wifi_close_supplicant_connection() */ if (index == SECONDARY) { ALOGD("close sockets %d", index); wifi_close_sockets(index); } } return -2; }
static void hostapd_cli_action(struct wpa_ctrl *ctrl) { fd_set rfds; int fd, res; struct timeval tv; char buf[256]; size_t len; fd = wpa_ctrl_get_fd(ctrl); while (!hostapd_cli_quit) { FD_ZERO(&rfds); FD_SET(fd, &rfds); tv.tv_sec = ping_interval; 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)) hostapd_cli_recv_pending(ctrl, 0, 1); else { len = sizeof(buf) - 1; if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len, hostapd_cli_action_process) < 0 || len < 4 || os_memcmp(buf, "PONG", 4) != 0) { printf("hostapd did not reply to PING " "command - exiting\n"); break; } } } }
int wifi_ctrl_recv(char *reply, size_t *reply_len) { int res; int ctrlfd = wpa_ctrl_get_fd(monitor_conn); struct pollfd rfds[2]; memset(rfds, 0, 2 * sizeof(struct pollfd)); rfds[0].fd = ctrlfd; rfds[0].events |= POLLIN; rfds[1].fd = exit_sockets[1]; rfds[1].events |= POLLIN; res = TEMP_FAILURE_RETRY(poll(rfds, 2, -1)); if (res < 0) { ALOGE("Error poll = %d", res); return res; } if (rfds[0].revents & POLLIN) { return wpa_ctrl_recv(monitor_conn, reply, reply_len); } /* it is not rfds[0], then it must be rfts[1] (i.e. the exit socket) * or we timed out. In either case, this call has failed .. */ return -2; }
static void unregister_event_handler(struct wpa_ctrl *ctrl) { if (!ctrl_conn) return; if (interactive && event_handler_registered) { eloop_unregister_read_sock(wpa_ctrl_get_fd(ctrl)); event_handler_registered = 0; } }
int get_wpa_cli_event2(struct wpa_ctrl *mon, const char *event, const char *event2, char *buf, size_t buf_size) { int fd, ret; fd_set rfd; char *pos; struct timeval tv; time_t start, now; printf("Waiting for wpa_cli event %s\n", event); fd = wpa_ctrl_get_fd(mon); if (fd < 0) return -1; time(&start); while (1) { size_t len; FD_ZERO(&rfd); FD_SET(fd, &rfd); tv.tv_sec = default_timeout; tv.tv_usec = 0; ret = select(fd + 1, &rfd, NULL, NULL, &tv); if (ret == 0) { printf("Timeout on waiting for event %s\n", event); return -1; } if (ret < 0) { printf("select: %s\n", strerror(errno)); return -1; } len = buf_size; if (wpa_ctrl_recv(mon, buf, &len) < 0) { printf("Failure while waiting for event %s\n", event); return -1; } if (len == buf_size) len--; buf[len] = '\0'; pos = strchr(buf, '>'); if (pos && (strncmp(pos + 1, event, strlen(event)) == 0 || (event2 && strncmp(pos + 1, event2, strlen(event2)) == 0))) return 0; /* Event found */ time(&now); if ((int) (now - start) > default_timeout) { printf("Timeout on waiting for event %s\n", event); return -1; } } }
static void register_event_handler(struct wpa_ctrl *ctrl) { if (!ctrl_conn) return; if (interactive) { event_handler_registered = !eloop_register_read_sock(wpa_ctrl_get_fd(ctrl), hostapd_cli_receive, NULL, NULL); } }
int main(int argc, char *argv[]) { if (argc != 2) errx(EXIT_FAILURE, "%s <path to supplicant control pipe>", argv[0]); ctrl = wpa_ctrl_open(argv[1]); if (!ctrl) err(EXIT_FAILURE, "Couldn't open '%s'", argv[1]); if (wpa_ctrl_attach(ctrl) < 0) err(EXIT_FAILURE, "wpa_ctrl_attach"); int wpa_fd = wpa_ctrl_get_fd(ctrl); for (;;) { struct pollfd fdset[2]; fdset[0].fd = STDIN_FILENO; fdset[0].events = POLLIN; fdset[0].revents = 0; fdset[1].fd = wpa_fd; fdset[1].events = POLLIN; fdset[1].revents = 0; debug("waiting on poll\n"); int rc = poll(fdset, 2, -1); if (rc < 0) { // Retry if EINTR if (errno == EINTR) continue; err(EXIT_FAILURE, "poll"); } debug("poll: revents[0]=%08x, revents[1]=%08x\n", fdset[0].revents, fdset[1].revents); if (fdset[0].revents & (POLLIN | POLLHUP)) process_erl(); if (fdset[1].revents & POLLIN) process_wpa(); } return 0; }
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 */ }
int wifi_ctrl_recv(int index, char *reply, size_t *reply_len) { int res; int ctrlfd = wpa_ctrl_get_fd(monitor_conn[index]); struct pollfd rfds[2]; memset(rfds, 0, 2 * sizeof(struct pollfd)); rfds[0].fd = ctrlfd; rfds[0].events |= POLLIN; rfds[1].fd = exit_sockets[index][1]; rfds[1].events |= POLLIN; res = TEMP_FAILURE_RETRY(poll(rfds, 2, -1)); if (res < 0) { ALOGE("Error poll = %d", res); return res; } if (rfds[0].revents & POLLIN) { return wpa_ctrl_recv(monitor_conn[index], reply, reply_len); } else { return -2; } return 0; }
int wifi_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len) { int res; int ctrlfd = wpa_ctrl_get_fd(ctrl); struct pollfd rfds[2]; memset(rfds, 0, 2 * sizeof(struct pollfd)); rfds[0].fd = ctrlfd; rfds[0].events |= POLLIN; rfds[1].fd = exit_sockets[1]; rfds[1].events |= POLLIN; res = poll(rfds, 2, -1); if (res < 0) { LOGE("Error poll = %d", res); return res; } if (rfds[0].revents & POLLIN) { return wpa_ctrl_recv(ctrl, reply, reply_len); } else { LOGD("Received on exit socket, terminate"); return -1; } return 0; }
int ctrl_recv(P_SUPPLICANT_INFO_T prTarInfo, char *reply, size_t *reply_len) { int res; int ctrlfd = wpa_ctrl_get_fd(prTarInfo->prMonitorConn); struct pollfd rfds[2]; memset(rfds, 0, 2 * sizeof(struct pollfd)); rfds[0].fd = ctrlfd; rfds[0].events |= POLLIN; rfds[1].fd = prTarInfo->aucExitSockets[1]; rfds[1].events |= POLLIN; res = poll(rfds, 2, -1); if (res < 0) { LOGE("[%s] Error poll = %d", prTarInfo->acIfName, res); return res; } if (rfds[0].revents & POLLIN) { return prTarInfo->rSuppCtrl.ctrl_recv(prTarInfo->prMonitorConn, reply, reply_len); } else { LOGD("[%s] Received on exit socket, terminate", prTarInfo->acIfName); return -1; } return 0; }
void interactive_from_stdin(void) { for (;;) { const int timeout_msec = 1000; /* negative for infinity */ struct pollfd fds[2]; int nfds; fds[0].fd = wpa_ctrl_get_fd(ctrl_conn); fds[0].events = POLLIN; fds[0].revents = 0; fds[1].fd = 0; /* STDIN */ fds[1].events = POLLIN; fds[1].revents = 0; nfds = 2; nfds = poll(fds, nfds, timeout_msec); if (nfds < 0) { if (errno == EINTR) continue; wpatalk_fatal("Died on poll() error %d", errno); continue; } if (nfds == 0) { /* timeout */ char buf[512]; /* note: large enough to fit in unsolicited messages */ /* verify that connection is still working */ size_t len = sizeof(buf) - 1; if (wpa_ctrl_request(ctrl_conn, "PING", 4, buf, &len, wpatalk_action_cb) < 0 || len < 4 || os_memcmp(buf, "PONG", 4) != 0) { wpatalk_error("daemon did not reply to PING command"); goto reconnect; } continue; } if ((fds[0].revents & POLLIN) != 0) { for (;;) { int status = wpatalk_recv_pending(0/*block*/); if (status > 0) continue; /* more */ if (status < 0) { wpatalk_warning("Closing connection due to error."); goto reconnect; } break; } } if ((fds[1].revents & POLLIN) != 0) { char buf[512]; /* only one read() per ready to avoid blocking */ read_stdin(); /* the one read() may result in 0, 1 or more input lines */ while (extract_stdin_line(buf, sizeof(buf)) == 0) { command_from_file(buf); } } continue; reconnect: wpatalk_reconnect(); continue; } }
int WpaGui::openCtrlConnection(const char *ifname) { char *cfile; int flen; char buf[2048], *pos, *pos2; size_t len; if (ifname) { if (ifname != ctrl_iface) { free(ctrl_iface); ctrl_iface = strdup(ifname); } } else { #ifdef CONFIG_CTRL_IFACE_UDP free(ctrl_iface); ctrl_iface = strdup("udp"); #endif /* CONFIG_CTRL_IFACE_UDP */ #ifdef CONFIG_CTRL_IFACE_UNIX struct dirent *dent; DIR *dir = opendir(ctrl_iface_dir); free(ctrl_iface); ctrl_iface = NULL; if (dir) { 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 (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) continue; printf("Selected interface '%s'\n", dent->d_name); ctrl_iface = strdup(dent->d_name); break; } closedir(dir); } #endif /* CONFIG_CTRL_IFACE_UNIX */ #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE struct wpa_ctrl *ctrl; int ret; free(ctrl_iface); ctrl_iface = NULL; ctrl = wpa_ctrl_open(NULL); if (ctrl) { len = sizeof(buf) - 1; ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL); if (ret >= 0) { buf[len] = '\0'; pos = strchr(buf, '\n'); if (pos) *pos = '\0'; ctrl_iface = strdup(buf); } wpa_ctrl_close(ctrl); } #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ } if (ctrl_iface == NULL) return -1; #ifdef CONFIG_CTRL_IFACE_UNIX flen = strlen(ctrl_iface_dir) + strlen(ctrl_iface) + 2; cfile = (char *) malloc(flen); if (cfile == NULL) return -1; snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ctrl_iface); #else /* CONFIG_CTRL_IFACE_UNIX */ flen = strlen(ctrl_iface) + 1; cfile = (char *) malloc(flen); if (cfile == NULL) return -1; snprintf(cfile, flen, "%s", ctrl_iface); #endif /* CONFIG_CTRL_IFACE_UNIX */ if (ctrl_conn) { wpa_ctrl_close(ctrl_conn); ctrl_conn = NULL; } if (monitor_conn) { delete msgNotifier; msgNotifier = NULL; wpa_ctrl_detach(monitor_conn); wpa_ctrl_close(monitor_conn); monitor_conn = NULL; } printf("Trying to connect to '%s'\n", cfile); ctrl_conn = wpa_ctrl_open(cfile); if (ctrl_conn == NULL) { free(cfile); return -1; } monitor_conn = wpa_ctrl_open(cfile); free(cfile); if (monitor_conn == NULL) { wpa_ctrl_close(ctrl_conn); return -1; } if (wpa_ctrl_attach(monitor_conn)) { printf("Failed to attach to wpa_supplicant\n"); wpa_ctrl_close(monitor_conn); monitor_conn = NULL; wpa_ctrl_close(ctrl_conn); ctrl_conn = NULL; return -1; } #if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP) msgNotifier = new QSocketNotifier(wpa_ctrl_get_fd(monitor_conn), QSocketNotifier::Read, this); connect(msgNotifier, SIGNAL(activated(int)), SLOT(receiveMsgs())); #endif adapterSelect->clear(); adapterSelect->insertItem(ctrl_iface); adapterSelect->setCurrentItem(0); len = sizeof(buf) - 1; if (wpa_ctrl_request(ctrl_conn, "INTERFACES", 10, buf, &len, NULL) >= 0) { buf[len] = '\0'; pos = buf; while (*pos) { pos2 = strchr(pos, '\n'); if (pos2) *pos2 = '\0'; if (strcmp(pos, ctrl_iface) != 0) adapterSelect->insertItem(pos); if (pos2) pos = pos2 + 1; else break; } } return 0; }
int WpaGui::openCtrlConnection(const char *ifname) { char *cfile; int flen; char buf[2048], *pos, *pos2; size_t len; if (ifname) { if (ifname != ctrl_iface) { free(ctrl_iface); ctrl_iface = strdup(ifname); } } else { #ifdef CONFIG_CTRL_IFACE_UDP free(ctrl_iface); ctrl_iface = strdup("udp"); #endif /* CONFIG_CTRL_IFACE_UDP */ #ifdef CONFIG_CTRL_IFACE_UNIX struct dirent *dent; DIR *dir = opendir(ctrl_iface_dir); free(ctrl_iface); ctrl_iface = NULL; if (dir) { 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 (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) continue; printf("Selected interface '%s'\n", dent->d_name); ctrl_iface = strdup(dent->d_name); break; } closedir(dir); } #endif /* CONFIG_CTRL_IFACE_UNIX */ #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE struct wpa_ctrl *ctrl; int ret; free(ctrl_iface); ctrl_iface = NULL; ctrl = wpa_ctrl_open(NULL); if (ctrl) { len = sizeof(buf) - 1; ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL); if (ret >= 0) { connectedToService = true; buf[len] = '\0'; pos = strchr(buf, '\n'); if (pos) *pos = '\0'; ctrl_iface = strdup(buf); } wpa_ctrl_close(ctrl); } #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ } if (ctrl_iface == NULL) { #ifdef CONFIG_NATIVE_WINDOWS static bool first = true; if (first && !serviceRunning()) { first = false; if (QMessageBox::warning( this, qAppName(), tr("wpa_supplicant service is not " "running.\n" "Do you want to start it?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) startService(); } #endif /* CONFIG_NATIVE_WINDOWS */ return -1; } #ifdef CONFIG_CTRL_IFACE_UNIX flen = strlen(ctrl_iface_dir) + strlen(ctrl_iface) + 2; cfile = (char *) malloc(flen); if (cfile == NULL) return -1; snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ctrl_iface); #else /* CONFIG_CTRL_IFACE_UNIX */ flen = strlen(ctrl_iface) + 1; cfile = (char *) malloc(flen); if (cfile == NULL) return -1; snprintf(cfile, flen, "%s", ctrl_iface); #endif /* CONFIG_CTRL_IFACE_UNIX */ if (ctrl_conn) { wpa_ctrl_close(ctrl_conn); ctrl_conn = NULL; } if (monitor_conn) { delete msgNotifier; msgNotifier = NULL; wpa_ctrl_detach(monitor_conn); wpa_ctrl_close(monitor_conn); monitor_conn = NULL; } printf("Trying to connect to '%s'\n", cfile); ctrl_conn = wpa_ctrl_open(cfile); if (ctrl_conn == NULL) { free(cfile); return -1; } monitor_conn = wpa_ctrl_open(cfile); free(cfile); if (monitor_conn == NULL) { wpa_ctrl_close(ctrl_conn); return -1; } if (wpa_ctrl_attach(monitor_conn)) { printf("Failed to attach to wpa_supplicant\n"); wpa_ctrl_close(monitor_conn); monitor_conn = NULL; wpa_ctrl_close(ctrl_conn); ctrl_conn = NULL; return -1; } #if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP) msgNotifier = new QSocketNotifier(wpa_ctrl_get_fd(monitor_conn), QSocketNotifier::Read, this); connect(msgNotifier, SIGNAL(activated(int)), SLOT(receiveMsgs())); #endif adapterSelect->clear(); adapterSelect->addItem(ctrl_iface); adapterSelect->setCurrentIndex(0); len = sizeof(buf) - 1; if (wpa_ctrl_request(ctrl_conn, "INTERFACES", 10, buf, &len, NULL) >= 0) { buf[len] = '\0'; pos = buf; while (*pos) { pos2 = strchr(pos, '\n'); if (pos2) *pos2 = '\0'; if (strcmp(pos, ctrl_iface) != 0) adapterSelect->addItem(pos); if (pos2) pos = pos2 + 1; else break; } } len = sizeof(buf) - 1; if (wpa_ctrl_request(ctrl_conn, "GET_CAPABILITY eap", 18, buf, &len, NULL) >= 0) { buf[len] = '\0'; QString res(buf); QStringList types = res.split(QChar(' ')); bool wps = types.contains("WSC"); actionWPS->setEnabled(wps); wpsTab->setEnabled(wps); wpaguiTab->setTabEnabled(wpaguiTab->indexOf(wpsTab), wps); } return 0; }