Browse Source

add getInterfaceType() Wireless function to show current AP/Client/etc. modes, also show current mode in TUI

master
Brad Parker 11 years ago
parent
commit
8b6a4b4c05
  1. 2
      iptest/iptest.cpp
  2. 30
      tui/menu.cpp
  3. 182
      wireless.cpp
  4. 8
      wireless.h

2
iptest/iptest.cpp

@ -127,6 +127,8 @@ int main(int argc, char *argv[]) {
std::cout << std::endl;
std::cout << "wifi interface type: " << qPrintable(wi.getInterfaceType()) << std::endl;
QTimer::singleShot(0, qApp, SLOT(quit()));
int ret = app.exec();

30
tui/menu.cpp

@ -316,19 +316,37 @@ void Menu::wifiInterfaceSelect(WINDOW *window, QString interface) {
box(window, 0, 0);
red(window);
QString title = QString("Wireless info for: ") + interface;
QByteArray array = title.toLatin1();
const char *data = array.constData();
QString title = "Wireless info for:";
QByteArray titleArr = title.toLatin1();
const char *titleData = titleArr.constData();
mvwaddstr(window, 1, 2, data);
mvwaddstr(window, 3, 2, "Bands: Channels:");
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<Wireless::BandInfo> bands = wir.bandMap();
int count = 1;
int y = 5;
int y = 7;
int y2 = y;
foreach(Wireless::BandInfo band, bands) {

182
wireless.cpp

@ -81,7 +81,13 @@ int IEEE80211Freq[][2] = {
struct nl_callback {
char *phyname;
void *bands;
void *extra;
};
struct nl_interfaceCallback {
char *ifname;
nl80211_iftype *iftype;
QString *iftypeString;
};
/*!
@ -95,10 +101,38 @@ struct nl_callback {
Wireless::Wireless(QString interface) :
QObject(0),
m_interface(interface),
m_interfaceType(),
m_bands(),
m_isValid(false),
m_isNL80211(false)
m_isNL80211(false),
m_iftype(NL80211_IFTYPE_UNSPECIFIED)
{
if(parseBands() && parseInterface()) {
m_isValid = true;
}
}
Wireless::~Wireless() {
std::cerr << "del wireless" << std::endl;
m_bands.clear();
}
QStringList Wireless::interfaceList() {
QStringList interfaces = Interface::list();
foreach(QString interface, interfaces) {
Wireless wir(interface);
if(!wir.isValid()) {
interfaces.removeAll(interface);
}
}
return interfaces;
}
bool Wireless::parseBands() {
void *handle = NULL;
struct genl_family *family = NULL;
struct nl_cache *cache = NULL;
@ -117,18 +151,23 @@ m_isNL80211(false)
fprintf(stderr, "could not find a parent phy device for interface %s, it isn't nl80211?\n", interfaceStr);
}
return;
nlmsg_free(msg);
nl_cb_put(cb);
return false;
}else{
m_isNL80211 = true;
}
if(nl80211_connect(interfaceStr, &handle, &cache, &family) < 0) {
std::cerr << "could not connect to nl80211" << std::endl;
return;
nlmsg_free(msg);
nl_cb_put(cb);
return false;
}
struct nl_callback callback = { .phyname = phyname, .bands = &m_bands };
struct nl_callback callback = { .phyname = phyname, .extra = &m_bands };
// freqlist
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, nl80211_freqlist_cb, &callback);
nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl80211_finish_cb, &err);
nl_cb_err(cb, NL_CB_CUSTOM, nl80211_error_cb, &err);
@ -139,35 +178,80 @@ m_isNL80211(false)
fprintf(stderr, "%s: Failed to write nl80211 message\n",
__FUNCTION__);
nl80211_disconnect(handle, cache, family);
return;
nlmsg_free(msg);
nl_cb_put(cb);
return false;
}
while(err)
nl_recvmsgs((struct nl_sock *)handle, cb);
nl80211_disconnect(handle, cache, family);
nlmsg_free(msg);
nl_cb_put(cb);
m_isValid = true;
return true;
}
Wireless::~Wireless() {
std::cerr << "del wireless" << std::endl;
bool Wireless::parseInterface() {
void *handle = NULL;
struct genl_family *family = NULL;
struct nl_cache *cache = NULL;
struct nl_msg *msgInterface = nlmsg_alloc();
struct nl_cb *cbInterface = nl_cb_alloc(NL_CB_DEFAULT);
QByteArray interfaceArray = m_interface.toLatin1();
const char *interfaceStr = interfaceArray.constData();
char *interfaceData = interfaceArray.data();
int err = 1;
m_bands.clear();
}
char *phyname = nl80211_find_parent(interfaceStr);
QStringList Wireless::interfaceList() {
QStringList interfaces = Interface::list();
if(phyname == NULL) {
if(!(Utils::interfaceIndex(interfaceStr))) {
fprintf(stderr, "Interface %s doesn't exist\n", interfaceStr);
}else{
fprintf(stderr, "could not find a parent phy device for interface %s, it isn't nl80211?\n", interfaceStr);
}
foreach(QString interface, interfaces) {
Wireless wir(interface);
nlmsg_free(msgInterface);
nl_cb_put(cbInterface);
return false;
}else{
m_isNL80211 = true;
}
if(!wir.isValid()) {
interfaces.removeAll(interface);
}
if(nl80211_connect(interfaceStr, &handle, &cache, &family) < 0) {
std::cerr << "could not connect to nl80211" << std::endl;
nlmsg_free(msgInterface);
nl_cb_put(cbInterface);
return false;
}
return interfaces;
struct nl_interfaceCallback callback = { .ifname = interfaceData, .iftype = &m_iftype, .iftypeString = &m_interfaceType};
nl_cb_set(cbInterface, NL_CB_VALID, NL_CB_CUSTOM, nl80211_interface_cb, &callback);
nl_cb_set(cbInterface, NL_CB_FINISH, NL_CB_CUSTOM, nl80211_finish_cb, &err);
nl_cb_err(cbInterface, NL_CB_CUSTOM, nl80211_error_cb, &err);
genlmsg_put(msgInterface, 0, 0, genl_family_get_id((struct genl_family *)family), 0, NLM_F_DUMP, NL80211_CMD_GET_INTERFACE, 0);
if(nl_send_auto_complete((struct nl_sock *)handle, msgInterface) < 0) {
fprintf(stderr, "%s: Failed to write nl80211 message\n",
__FUNCTION__);
nl80211_disconnect(handle, cache, family);
nlmsg_free(msgInterface);
nl_cb_put(cbInterface);
return false;
}
while(err)
nl_recvmsgs((struct nl_sock *)handle, cbInterface);
nl80211_disconnect(handle, cache, family);
nlmsg_free(msgInterface);
nl_cb_put(cbInterface);
return true;
}
/*!
@ -424,12 +508,62 @@ void Wireless::nl80211_disconnect(void *handle, struct nl_cache *cache, struct g
nl_socket_free((struct nl_sock *)handle);
}
nl80211_iftype Wireless::getInterfaceTypeRaw() {
return m_iftype;
}
const QString& Wireless::getInterfaceType() const {
return m_interfaceType;
}
int Wireless::nl80211_interface_cb(struct nl_msg *msg, void *arg) {
struct nlattr *tb_msg[NL80211_ATTR_MAX + 1] = {NULL};
struct genlmsghdr *gnlh = (struct genlmsghdr *) nlmsg_data(nlmsg_hdr(msg));
//struct nlattr *tb_interface[NL80211_IFTYPE_MAX + 1];
//struct nlattr *nl_interface = NULL;
//int rem_interface = 0;
struct nl_interfaceCallback *callback = (struct nl_interfaceCallback*)arg;
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
if (!tb_msg[NL80211_ATTR_IFTYPE]) {
return NL_SKIP;
}
if (tb_msg[NL80211_ATTR_IFNAME]) {
if (strcmp(nla_get_string(tb_msg[NL80211_ATTR_IFNAME]),
callback->ifname) != 0) {
return NL_SKIP;
}
}
*(callback->iftype) = static_cast<nl80211_iftype>(nla_get_u32(tb_msg[NL80211_ATTR_IFTYPE]));
switch(*(callback->iftype)) {
case NL80211_IFTYPE_UNSPECIFIED: { *(callback->iftypeString) = "Unspecified"; break; }
case NL80211_IFTYPE_ADHOC: { *(callback->iftypeString) = "Ad-hoc"; break; }
case NL80211_IFTYPE_STATION: { *(callback->iftypeString) = "Client"; break; }
case NL80211_IFTYPE_AP: { *(callback->iftypeString) = "AP"; break; }
case NL80211_IFTYPE_AP_VLAN: { *(callback->iftypeString) = "AP-VLAN"; break; }
case NL80211_IFTYPE_WDS: { *(callback->iftypeString) = "WDS"; break; }
case NL80211_IFTYPE_MONITOR: { *(callback->iftypeString) = "Monitor"; break; }
case NL80211_IFTYPE_MESH_POINT: { *(callback->iftypeString) = "Mesh Point"; break; }
case NL80211_IFTYPE_P2P_CLIENT: { *(callback->iftypeString) = "P2P Client"; break; }
case NL80211_IFTYPE_P2P_GO: { *(callback->iftypeString) = "P2P Go"; break; }
case NL80211_IFTYPE_P2P_DEVICE: { *(callback->iftypeString) = "P2P Device"; break; }
default: { *(callback->iftypeString) = "Unspecified"; break; }
}
return NL_SKIP;
}
int Wireless::nl80211_freqlist_cb(struct nl_msg *msg, void *arg) {
struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
struct nlattr *tb_msg[NL80211_ATTR_MAX + 1] = {NULL};
struct genlmsghdr *gnlh = (struct genlmsghdr *) nlmsg_data(nlmsg_hdr(msg));
struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
struct nlattr *nl_band, *nl_freq;
struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1] = {NULL};
struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1] = {NULL};
struct nlattr *nl_band, *nl_freq = NULL;
int rem_band, rem_freq = 0;
struct nl_callback *callback = (struct nl_callback*)arg;
@ -456,7 +590,7 @@ int Wireless::nl80211_freqlist_cb(struct nl_msg *msg, void *arg) {
nla_parse(tb_band, NL80211_BAND_ATTR_MAX, (struct nlattr *) nla_data(nl_band),
nla_len(nl_band), NULL);
QList<BandInfo> *bands = static_cast<QList<BandInfo>*>(callback->bands);
QList<BandInfo> *bands = static_cast<QList<BandInfo>*>(callback->extra);
BandInfo band;
if(tb_band[NL80211_BAND_ATTR_HT_CAPA]) {

8
wireless.h

@ -4,6 +4,7 @@
#include <QObject>
#include <QMap>
#include "libip_global.h"
#include <linux/nl80211.h>
class LIBIP_EXPORT Wireless : public QObject {
Q_OBJECT
@ -89,13 +90,20 @@ public:
bool isNL80211() const;
bool channelSupported(int channel) const;
bool frequencySupported(int frequency) const;
nl80211_iftype getInterfaceTypeRaw();
const QString& getInterfaceType() const;
private:
QString m_interface;
QString m_interfaceType;
QList<BandInfo> m_bands;
bool m_isValid;
bool m_isNL80211;
nl80211_iftype m_iftype;
bool parseBands();
bool parseInterface();
static int nl80211_interface_cb(struct nl_msg *msg, void *arg);
static int nl80211_freqlist_cb(struct nl_msg *msg, void *arg);
static int nl80211_error_cb(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg);
static int nl80211_finish_cb(struct nl_msg *msg, void *arg);

Loading…
Cancel
Save