📄 wpagui.cpp
字号:
/* * wpa_gui - WpaGui class * Copyright (c) 2005-2008, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#ifdef __MINGW32__/* Need to get getopt() */#include <unistd.h>#endif#include <QMessageBox>#include <QCloseEvent>#include "wpagui.h"#include "dirent.h"#include "wpa_ctrl.h"#include "userdatarequest.h"#include "networkconfig.h"WpaGui::WpaGui(QWidget *parent, const char *, Qt::WFlags) : QMainWindow(parent){ setupUi(this); (void) statusBar(); connect(fileEventHistoryAction, SIGNAL(triggered()), this, SLOT(eventHistory())); connect(fileSaveConfigAction, SIGNAL(triggered()), this, SLOT(saveConfig())); connect(fileExitAction, SIGNAL(triggered()), this, SLOT(close())); connect(networkAddAction, SIGNAL(triggered()), this, SLOT(addNetwork())); connect(networkEditAction, SIGNAL(triggered()), this, SLOT(editSelectedNetwork())); connect(networkRemoveAction, SIGNAL(triggered()), this, SLOT(removeSelectedNetwork())); connect(networkEnableAllAction, SIGNAL(triggered()), this, SLOT(enableAllNetworks())); connect(networkDisableAllAction, SIGNAL(triggered()), this, SLOT(disableAllNetworks())); connect(networkRemoveAllAction, SIGNAL(triggered()), this, SLOT(removeAllNetworks())); connect(helpIndexAction, SIGNAL(triggered()), this, SLOT(helpIndex())); connect(helpContentsAction, SIGNAL(triggered()), this, SLOT(helpContents())); connect(helpAboutAction, SIGNAL(triggered()), this, SLOT(helpAbout())); connect(disconnectButton, SIGNAL(clicked()), this, SLOT(disconnect())); connect(scanButton, SIGNAL(clicked()), this, SLOT(scan())); connect(connectButton, SIGNAL(clicked()), this, SLOT(connectB())); connect(adapterSelect, SIGNAL(activated(const QString&)), this, SLOT(selectAdapter(const QString&))); connect(networkSelect, SIGNAL(activated(const QString&)), this, SLOT(selectNetwork(const QString&))); connect(addNetworkButton, SIGNAL(clicked()), this, SLOT(addNetwork())); connect(editNetworkButton, SIGNAL(clicked()), this, SLOT(editListedNetwork())); connect(removeNetworkButton, SIGNAL(clicked()), this, SLOT(removeListedNetwork())); connect(networkList, SIGNAL(itemSelectionChanged()), this, SLOT(updateNetworkDisabledStatus())); connect(enableRadioButton, SIGNAL(toggled(bool)), this, SLOT(enableListedNetwork(bool))); connect(disableRadioButton, SIGNAL(toggled(bool)), this, SLOT(disableListedNetwork(bool))); connect(scanNetworkButton, SIGNAL(clicked()), this, SLOT(scan())); connect(networkList, SIGNAL(itemDoubleClicked(QListWidgetItem *)), this, SLOT(editListedNetwork())); eh = NULL; scanres = NULL; udr = NULL; ctrl_iface = NULL; ctrl_conn = NULL; monitor_conn = NULL; msgNotifier = NULL; ctrl_iface_dir = strdup("/var/run/wpa_supplicant"); parse_argv(); textStatus->setText("connecting to wpa_supplicant"); timer = new QTimer(this); connect(timer, SIGNAL(timeout()), SLOT(ping())); timer->setSingleShot(FALSE); timer->start(1000); if (openCtrlConnection(ctrl_iface) < 0) { printf("Failed to open control connection to " "wpa_supplicant.\n"); } updateStatus(); networkMayHaveChanged = true; updateNetworks();}WpaGui::~WpaGui(){ delete msgNotifier; if (monitor_conn) { wpa_ctrl_detach(monitor_conn); wpa_ctrl_close(monitor_conn); monitor_conn = NULL; } if (ctrl_conn) { wpa_ctrl_close(ctrl_conn); ctrl_conn = NULL; } if (eh) { eh->close(); delete eh; eh = NULL; } if (scanres) { scanres->close(); delete scanres; scanres = NULL; } if (udr) { udr->close(); delete udr; udr = NULL; } free(ctrl_iface); ctrl_iface = NULL; free(ctrl_iface_dir); ctrl_iface_dir = NULL;}void WpaGui::languageChange(){ retranslateUi(this);}void WpaGui::parse_argv(){ int c; for (;;) { c = getopt(qApp->argc(), qApp->argv(), "i:p:"); if (c < 0) break; switch (c) { case 'i': free(ctrl_iface); ctrl_iface = strdup(optarg); break; case 'p': free(ctrl_iface_dir); ctrl_iface_dir = strdup(optarg); break; } }}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->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; } } return 0;}static void wpa_gui_msg_cb(char *msg, size_t){ /* This should not happen anymore since two control connections are * used. */ printf("missed message: %s\n", msg);}int WpaGui::ctrlRequest(const char *cmd, char *buf, size_t *buflen){ int ret; if (ctrl_conn == NULL) return -3; ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen, wpa_gui_msg_cb); if (ret == -2) printf("'%s' command timed out.\n", cmd); else if (ret < 0) printf("'%s' command failed.\n", cmd); return ret;}void WpaGui::updateStatus(){ char buf[2048], *start, *end, *pos; size_t len; pingsToStatusUpdate = 10; len = sizeof(buf) - 1; if (ctrl_conn == NULL || ctrlRequest("STATUS", buf, &len) < 0) { textStatus->setText("Could not get status from " "wpa_supplicant"); textAuthentication->clear(); textEncryption->clear(); textSsid->clear(); textBssid->clear(); textIpAddress->clear(); return; } buf[len] = '\0'; bool auth_updated = false, ssid_updated = false; bool bssid_updated = false, ipaddr_updated = false; bool status_updated = false; char *pairwise_cipher = NULL, *group_cipher = NULL; start = buf; while (*start) { bool last = false; end = strchr(start, '\n'); if (end == NULL) { last = true; end = start; while (end[0] && end[1]) end++; } *end = '\0'; pos = strchr(start, '='); if (pos) { *pos++ = '\0'; if (strcmp(start, "bssid") == 0) { bssid_updated = true; textBssid->setText(pos); } else if (strcmp(start, "ssid") == 0) { ssid_updated = true; textSsid->setText(pos); } else if (strcmp(start, "ip_address") == 0) { ipaddr_updated = true; textIpAddress->setText(pos); } else if (strcmp(start, "wpa_state") == 0) { status_updated = true; textStatus->setText(pos); } else if (strcmp(start, "key_mgmt") == 0) { auth_updated = true; textAuthentication->setText(pos); /* TODO: could add EAP status to this */ } else if (strcmp(start, "pairwise_cipher") == 0) { pairwise_cipher = pos; } else if (strcmp(start, "group_cipher") == 0) { group_cipher = pos; } } if (last) break; start = end + 1; } if (pairwise_cipher || group_cipher) { QString encr; if (pairwise_cipher && group_cipher && strcmp(pairwise_cipher, group_cipher) != 0) { encr.append(pairwise_cipher); encr.append(" + "); encr.append(group_cipher); } else if (pairwise_cipher) { encr.append(pairwise_cipher); } else { encr.append(group_cipher); encr.append(" [group key only]"); } textEncryption->setText(encr); } else textEncryption->clear(); if (!status_updated) textStatus->clear(); if (!auth_updated) textAuthentication->clear(); if (!ssid_updated) textSsid->clear(); if (!bssid_updated) textBssid->clear(); if (!ipaddr_updated) textIpAddress->clear();}void WpaGui::updateNetworks(){ char buf[2048], *start, *end, *id, *ssid, *bssid, *flags; size_t len; int first_active = -1; int was_selected = -1; bool current = false; if (!networkMayHaveChanged) return; if (networkList->currentRow() >= 0) was_selected = networkList->currentRow(); networkSelect->clear(); networkList->clear(); if (ctrl_conn == NULL) return; len = sizeof(buf) - 1; if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0) return; buf[len] = '\0'; start = strchr(buf, '\n'); if (start == NULL) return; start++; while (*start) { bool last = false; end = strchr(start, '\n'); if (end == NULL) { last = true; end = start; while (end[0] && end[1]) end++; } *end = '\0'; id = start; ssid = strchr(id, '\t'); if (ssid == NULL) break; *ssid++ = '\0'; bssid = strchr(ssid, '\t'); if (bssid == NULL) break; *bssid++ = '\0'; flags = strchr(bssid, '\t'); if (flags == NULL) break; *flags++ = '\0'; QString network(id); network.append(": "); network.append(ssid); networkSelect->addItem(network); networkList->addItem(network); if (strstr(flags, "[CURRENT]")) { networkSelect->setCurrentIndex(networkSelect->count() - 1); current = true; } else if (first_active < 0 && strstr(flags, "[DISABLED]") == NULL) first_active = networkSelect->count() - 1; if (last) break; start = end + 1; } if (networkSelect->count() > 1) networkSelect->addItem("Select any network"); if (!current && first_active >= 0) networkSelect->setCurrentIndex(first_active); if (was_selected >= 0 && networkList->count() > 0) { if (was_selected < networkList->count()) networkList->setCurrentRow(was_selected); else networkList->setCurrentRow(networkList->count() - 1); } else networkList->setCurrentRow(networkSelect->currentIndex()); networkMayHaveChanged = false;}void WpaGui::helpIndex(){ printf("helpIndex\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -