#include #include #include #include #include "menu.h" Menu::Menu(WINDOW *window, QObject *parent) : QObject(parent), m_window(window) { } Menu::~Menu() { emit finished(); } void Menu::start() { mainmenu(m_window); } void Menu::red(WINDOW *window) { wattron(window, COLOR_PAIR(1)); } void Menu::cyan(WINDOW *window) { wattron(window, COLOR_PAIR(5)); } void Menu::green(WINDOW *window) { wattron(window, COLOR_PAIR(2)); } void Menu::magenta(WINDOW *window) { wattron(window, COLOR_PAIR(6)); } void Menu::quit(WINDOW *window) { delwin(window); endwin(); qApp->quit(); } void Menu::msgbox(const char *text) { //WINDOW *msgbox = newwin(LINES / 2, COLS / 2, LINES / 4, COLS / 4); WINDOW *msgbox = newwin(8, COLS / 2, LINES / 4, COLS / 4); wbkgd(msgbox, COLOR_PAIR(8)); box(msgbox, 0, 0); mvwaddstr(msgbox, 1, 2, text); move(3, 5); wrefresh(msgbox); WINDOW *ok = derwin(msgbox, 3, 6, msgbox->_maxy / 2 + 1, msgbox->_maxx / 2); box(ok, 0, 0); wattron(ok, COLOR_PAIR(5)); mvwaddstr(ok, 1, 2, "OK"); touchwin(msgbox); wrefresh(ok); check_return: char c = getch(); if(c != '\r') { goto check_return; } delwin(ok); delwin(msgbox); } void Menu::mainmenu(WINDOW *window) { wclear(window); cyan(window); box(window, 0, 0); red(window); mvwaddstr(window, 1, 2, "System Configuration:"); green(window); mvwaddstr(window, 3, 2, "1. Interfaces"); mvwaddstr(window, 4, 2, "2. ARP"); mvwaddstr(window, 5, 2, "3. Wireless"); cyan(window); mvwaddstr(window, 7, 2, "q. Quit"); magenta(window); mvwaddstr(window, 9, 2, "Enter selection: "); wrefresh(window); char c = getch(); if(c < '0' || c > '3') { if(c != 27 && c != 'q') { // allow escape in addition to 0 for quit mainmenu(window); } }else{ if(c == '1') { interfaceMenu(window); }else if(c == '2') { arpMenu(window); }else if(c == '3') { wifiInterfaceMenu(window); } } quit(window); } void Menu::arpMenu(WINDOW *window) { wclear(window); cyan(window); box(window, 0, 0); red(window); mvwaddstr(window, 1, 2, "ARP Table:"); green(window); QHash arpList = Neighbor::list(QString()); int y = 3; int width = 0; int widthMAC = 0; int widthIP = 0; QString format = "%-"; foreach(QString arp, arpList.keys()) { QString mac = arpList.value(arp); widthMAC = qMax(widthMAC, mac.length()); widthIP = qMax(widthIP, arp.length()); } width = widthMAC + widthIP; format += QString::number(widthIP) + "s at %" + QString::number(widthMAC) + "s"; QByteArray formatArr = format.toLatin1(); const char *formatStr = formatArr.constData(); char *str = (char*)malloc(width + 5); foreach(QString arp, arpList.keys()) { //arp = QString::number(count) + ". " + arp; memset(str, 0, width + 5); QByteArray arpArray = arp.toLatin1(); QString arpMac = arpList.value(arp); QByteArray arpMacArray = arpMac.toLatin1(); const char *arpStr = arpArray.constData(); const char *arpMacStr = arpMacArray.constData(); snprintf(str, width + 5, formatStr, arpStr, arpMacStr); /*memcpy(str, arpStr, strlen(arpStr)); memcpy(str + strlen(arpStr), " at ", 4); memcpy(str + strlen(arpStr) + 4, arpMacStr, strlen(arpMacStr));*/ mvwaddstr(window, y, 2, str); ++y; } free(str); cyan(window); mvwaddstr(window, y + 1, 2, "0. Back to main menu"); wrefresh(window); arpChar: char c = getch(); if(c != '0' && c != 27 && c != 'q') { goto arpChar; }else{ if(c != 'q') { mainmenu(window); } } } void Menu::wifiInterfaceMenu(WINDOW *window) { wclear(window); cyan(window); box(window, 0, 0); red(window); mvwaddstr(window, 1, 2, "Wireless Interfaces:"); green(window); QStringList interfaceList = Wireless::interfaceList(); int count = 1; int y = 3; int lastInterface = 0; QHash interfaceHash; foreach(QString interface, interfaceList) { QString orig = interface; interface = QString::number(count) + ". " + interface; QByteArray interfaceArray = interface.toLatin1(); const char *interfaceStr = interfaceArray.constData(); mvwaddstr(window, y, 2, interfaceStr); lastInterface = count + '0'; interfaceHash.insert(lastInterface, orig); ++y; ++count; } cyan(window); mvwaddstr(window, y + 1, 2, "0. Back to main menu"); magenta(window); mvwaddstr(window, y + 3, 2, "q. Quit"); mvwaddstr(window, y + 5, 2, "Enter selection: "); wrefresh(window); char c = getch(); if(c < '0' || c > lastInterface) { if(c != 'q') { if(c == 27) { mainmenu(window); }else{ wifiInterfaceMenu(window); } } }else{ if(c == '0') { mainmenu(window); }else{ if(c > '0' && c <= lastInterface) { wifiInterfaceSelect(window, interfaceHash.value(c)); } } } } void Menu::interfaceMenu(WINDOW *window) { wclear(window); cyan(window); box(window, 0, 0); red(window); mvwaddstr(window, 1, 2, "Interfaces:"); green(window); QStringList interfaceList = Interface::list(); int count = 1; int y = 3; int lastInterface = 0; QHash interfaceHash; foreach(QString interface, interfaceList) { QString orig = interface; interface = QString::number(count) + ". " + interface; QByteArray interfaceArray = interface.toLatin1(); const char *interfaceStr = interfaceArray.constData(); Interface interfaceObj(orig); if(interfaceObj.hasCarrier()) { green(window); }else if(interfaceObj.hasAdminLink()) { cyan(window); }else{ red(window); } mvwaddstr(window, y, 2, interfaceStr); lastInterface = count + '0'; interfaceHash.insert(lastInterface, orig); ++y; ++count; } cyan(window); mvwaddstr(window, y + 1, 2, "0. Back to main menu"); magenta(window); mvwaddstr(window, y + 3, 2, "q. Quit"); mvwaddstr(window, y + 5, 2, "Enter selection: "); wrefresh(window); char c = getch(); if(c < '0' || c > lastInterface) { if(c != 'q') { if(c == 27) { mainmenu(window); }else{ interfaceMenu(window); } } }else{ if(c == '0') { mainmenu(window); }else{ if(c > '0' && c <= lastInterface) { interfaceSelect(window, interfaceHash.value(c)); } } } } void Menu::wifiInterfaceSelect(WINDOW *window, QString interface) { Wireless wir(interface); Interface obj(""); QStringList ipList; wclear(window); cyan(window); box(window, 0, 0); red(window); QString title = "Wireless info for:"; QByteArray titleArr = title.toLatin1(); const char *titleData = titleArr.constData(); QByteArray interfaceArr = interface.toLatin1(); const char *interfaceData = interfaceArr.constData(); QString typeStr = wir.getInterfaceType(); QByteArray typeArr = typeStr.toLatin1(); const char *typeData = typeArr.constData(); mvwaddstr(window, 1, 2, titleData); green(window); mvwaddstr(window, 1, 2 + title.length() + 1, interfaceData); red(window); mvwaddstr(window, 3, 2, "Mode: "); green(window); mvwaddstr(window, 3, 8, typeData); red(window); mvwaddstr(window, 5, 2, "Bands: Channels:"); green(window); QList bands = wir.bandMap(); int count = 1; int y = 7; int y2 = y; foreach(Wireless::BandInfo band, bands) { QString bandStr; switch(band.band) { case Wireless::BAND_2GHZ: { bandStr = "2.4GHz"; break; } case Wireless::BAND_5GHZ: { bandStr = "5GHz"; break; } default: { bandStr = "Other"; break; } } QByteArray arr = bandStr.toLatin1(); const char *data = arr.constData(); mvwaddstr(window, y, 2, data); foreach(Wireless::ChannelInfo chan, band.channels) { QString chanStr = QString::number(chan.chan); chanStr += " "; if(chan.chan < 100) { chanStr.chop(QString::number(chan.chan).length()); } chanStr += QStringLiteral("- ") + QString::number((double)chan.freq / 1000.0) + " GHz ("; if(chan.disabled) { chanStr += "disabled"; }else{ chanStr += QString::number((double)chan.max_txpower / 100.0, 'f', 1) + " dBm"; if(chan.radar) { chanStr += ", DFS required"; }else{ if(chan.passive) { chanStr += ", RX-only"; } } } chanStr += ")"; QByteArray chanArr = chanStr.toLatin1(); const char *chanData = chanArr.constData(); mvwaddstr(window, y2, 11, chanData); ++y2; } ++y; ++count; } red(window); mvwaddstr(window, y2 + 1, 2, "Standards:"); green(window); y2 += 3; foreach(Wireless::BandInfo band, bands) { if((band.protocols & Wireless::PROTOCOL_80211_A) == Wireless::PROTOCOL_80211_A) { mvwaddstr(window, y2, 2, "802.11a"); ++y2; } if((band.protocols & Wireless::PROTOCOL_80211_B) == Wireless::PROTOCOL_80211_B) { mvwaddstr(window, y2, 2, "802.11b"); ++y2; } if((band.protocols & Wireless::PROTOCOL_80211_G) == Wireless::PROTOCOL_80211_G) { mvwaddstr(window, y2, 2, "802.11g"); ++y2; } if((band.protocols & Wireless::PROTOCOL_80211_N) == Wireless::PROTOCOL_80211_N) { QString nStr = "802.11n ("; if((band.width & Wireless::WIDTH_20MHZ) == Wireless::WIDTH_20MHZ) { nStr += "150mbps"; } if((band.width & Wireless::WIDTH_40MHZ) == Wireless::WIDTH_40MHZ) { nStr += " and 300mbps"; } nStr += ")"; QByteArray nArr = nStr.toLatin1(); const char *nData = nArr.constData(); mvwaddstr(window, y2, 2, nData); ++y2; } } red(window); if(count == 1) { mvwaddstr(window, y2, 2, "No supported bands found."); ++y2; } cyan(window); mvwaddstr(window, y2 + 1, 2, "0. Back to wireless interfaces"); magenta(window); mvwaddstr(window, y2 + 3, 2, "a. Add IP address"); mvwaddstr(window, y2 + 4, 2, "d. Delete IP address"); mvwaddstr(window, y2 + 5, 2, "q. Quit"); mvwaddstr(window, y2 + 7, 2, "Enter selection: "); wrefresh(window); char c = getch(); if(c < '0' || c > (count + '0' - 1)) { if(c == 27) { wifiInterfaceMenu(window); }else if(c == 'q') { // no-op, just quit }else if(c == 'a') { wdeleteln(window); mvwaddstr(window, y + 7, 2, "Enter IP address to add: "); wrefresh(window); char ipToAdd[19] = {0}; echo(); wgetnstr(window, ipToAdd, sizeof(ipToAdd) / sizeof(char) - 1); noecho(); QString ip = ipToAdd; if(!ip.contains(QRegularExpression("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([5-9]|[1-2][0-9]|3[0-2])$"))) { msgbox("Invalid IP address. Please try again."); interfaceSelect(window, interface); return; } wdeleteln(window); QString confirm = "Are you sure you want to add "; confirm += ip; confirm += " [y/n]? "; QByteArray arr = confirm.toLatin1(); const char *confirmStr = arr.constData(); mvwaddstr(window, y + 7, 2, confirmStr); wrefresh(window); c = getch(); if(c == 'y') { if(obj.addAddress(ip)) { msgbox("Could not add IP address. Not enough permissions?"); }else{ msgbox("IP address added successfully."); } interfaceSelect(window, interface); }else{ interfaceSelect(window, interface); } }else if(c == 'd') { wdeleteln(window); mvwaddstr(window, y + 7, 2, "Enter number of IP address to delete: "); wrefresh(window); char ipToDelete = getch(); if(ipToDelete < '1' || ipToDelete > '9') { interfaceSelect(window, interface); return; } if(!(ipList.count() >= ipToDelete - '0')) { interfaceSelect(window, interface); return; } wdeleteln(window); QString confirm = "Are you sure you want to delete "; confirm += ipList[ipToDelete - '0' - 1]; confirm += " [y/n]? "; QByteArray arr = confirm.toLatin1(); const char *confirmStr = arr.constData(); mvwaddstr(window, y + 7, 2, confirmStr); wrefresh(window); c = getch(); if(c == 'y') { if(obj.deleteAddress(ipList[ipToDelete - '0' - 1])) { msgbox("Could not delete IP address. Not enough permissions?"); }else{ msgbox("IP address deleted successfully."); } interfaceSelect(window, interface); }else{ interfaceSelect(window, interface); } }else{ wifiInterfaceSelect(window, interface); } }else{ if(c == '0') { wifiInterfaceMenu(window); }else{ wifiInterfaceSelect(window, interface); } } } void Menu::interfaceSelect(WINDOW *window, QString interface) { wclear(window); cyan(window); box(window, 0, 0); red(window); QString title = QString("IP Addresses on: ") + interface; QByteArray array = title.toLatin1(); const char *data = array.constData(); mvwaddstr(window, 1, 2, data); green(window); Interface obj(interface); QStringList ipList = obj.addresses(); int count = 1; int y = 3; foreach(QString ip, ipList) { ip = QString::number(count) + ". " + ip; QByteArray ipArray = ip.toLatin1(); const char *ipStr = ipArray.constData(); mvwaddstr(window, y, 2, ipStr); ++y; ++count; } if(count == 1) { mvwaddstr(window, y, 2, "No IP addresses found."); ++y; } cyan(window); mvwaddstr(window, y + 1, 2, "0. Back to interfaces"); magenta(window); mvwaddstr(window, y + 3, 2, "a. Add IP address"); mvwaddstr(window, y + 4, 2, "d. Delete IP address"); mvwaddstr(window, y + 5, 2, "+. Set link up"); mvwaddstr(window, y + 6, 2, "-. Set link down"); mvwaddstr(window, y + 7, 2, "q. Quit"); mvwaddstr(window, y + 9, 2, "Enter selection: "); wrefresh(window); char c = getch(); if(c < '0' || c > (count + '0' - 1)) { if(c == 27) { interfaceMenu(window); }else if(c == 'q') { // no-op, just quit }else if(c == 'a') { wdeleteln(window); mvwaddstr(window, y + 9, 2, "Enter IP address to add: "); wrefresh(window); char ipToAdd[19] = {0}; echo(); wgetnstr(window, ipToAdd, sizeof(ipToAdd) / sizeof(char) - 1); noecho(); QString ip = ipToAdd; if(!ip.contains(QRegularExpression("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([5-9]|[1-2][0-9]|3[0-2])$"))) { msgbox("Invalid IP address. Please try again."); interfaceSelect(window, interface); return; } wdeleteln(window); QString confirm = "Are you sure you want to add "; confirm += ip; confirm += " [y/n]? "; QByteArray arr = confirm.toLatin1(); const char *confirmStr = arr.constData(); mvwaddstr(window, y + 9, 2, confirmStr); wrefresh(window); c = getch(); if(c == 'y') { if(obj.addAddress(ip)) { msgbox("Could not add IP address. Not enough permissions?"); }else{ msgbox("IP address added successfully."); } interfaceSelect(window, interface); }else{ interfaceSelect(window, interface); } }else if(c == 'd') { wdeleteln(window); mvwaddstr(window, y + 9, 2, "Enter number of IP address to delete: "); wrefresh(window); char ipToDelete = getch(); if(ipToDelete < '1' || ipToDelete > '9') { interfaceSelect(window, interface); return; } if(!(ipList.count() >= ipToDelete - '0')) { interfaceSelect(window, interface); return; } wdeleteln(window); QString confirm = "Are you sure you want to delete "; confirm += ipList[ipToDelete - '0' - 1]; confirm += " [y/n]? "; QByteArray arr = confirm.toLatin1(); const char *confirmStr = arr.constData(); mvwaddstr(window, y + 9, 2, confirmStr); wrefresh(window); c = getch(); if(c == 'y') { if(obj.deleteAddress(ipList[ipToDelete - '0' - 1])) { msgbox("Could not delete IP address. Not enough permissions?"); }else{ msgbox("IP address deleted successfully."); } interfaceSelect(window, interface); }else{ interfaceSelect(window, interface); } }else if(c == '+') { QString error; if(obj.setLinkUp() != 0) { QString err = "Could not change link state."; QByteArray arr = err.toLatin1(); const char *errorString = arr.constData(); msgbox(errorString); }else{ msgbox("Link state set to UP."); } interfaceSelect(window, interface); }else if(c == '-') { QString error; if(obj.setLinkDown() != 0) { QString err = "Could not change link state."; QByteArray arr = err.toLatin1(); const char *errorString = arr.constData(); msgbox(errorString); }else{ msgbox("Link state set to DOWN."); } interfaceSelect(window, interface); }else{ interfaceSelect(window, interface); } }else{ if(c == '0') { interfaceMenu(window); }else{ interfaceSelect(window, interface); } } }