|
|
@ -1,8 +1,6 @@ |
|
|
|
extern "C" { |
|
|
|
#include <netlink/cli/utils.h> |
|
|
|
#include <netlink/cli/neigh.h> |
|
|
|
#include <netlink/cli/addr.h> |
|
|
|
#include <netlink/cli/link.h> |
|
|
|
#include <netlink/genl/ctrl.h> |
|
|
|
#include <netlink/genl/genl.h> |
|
|
|
#include <netlink/genl/family.h> |
|
|
|
#include <pthread.h> |
|
|
|
#include <linux/nl80211.h> |
|
|
@ -13,10 +11,7 @@ extern "C" { |
|
|
|
#include "utils.h" |
|
|
|
#include <iostream> |
|
|
|
#include <QStringList> |
|
|
|
|
|
|
|
#define BUFLEN 65535 |
|
|
|
#define MACBUFLEN 18 |
|
|
|
#define IPBUFLEN 64 |
|
|
|
#include <QRegularExpression> |
|
|
|
|
|
|
|
struct nl80211_channel_block { |
|
|
|
char *phyname; |
|
|
@ -91,7 +86,9 @@ int IEEE80211Freq[][2] = { |
|
|
|
Wireless::Wireless(QString interface) : |
|
|
|
QObject(0), |
|
|
|
m_interface(interface), |
|
|
|
m_channels() |
|
|
|
m_channels(), |
|
|
|
m_isValid(false), |
|
|
|
m_isNL80211(false) |
|
|
|
{ |
|
|
|
void *handle, *family = NULL; |
|
|
|
struct nl_cache *cache = NULL; |
|
|
@ -104,20 +101,16 @@ m_channels() |
|
|
|
|
|
|
|
cblock.phyname = nl80211_find_parent(interfaceStr); |
|
|
|
|
|
|
|
if(cblock.phyname != NULL) { |
|
|
|
if(strlen(cblock.phyname) == 0) { |
|
|
|
if(Utils::interfaceIndex(interfaceStr) <= 0) { |
|
|
|
fprintf(stderr, "Interface %s doesn't exist\n", interfaceStr); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
fprintf(stderr, "could not find a parent phy device " |
|
|
|
"for interface %s, it isn't nl80211?\n", interfaceStr); |
|
|
|
return; |
|
|
|
if(cblock.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); |
|
|
|
} |
|
|
|
}else{ |
|
|
|
fprintf(stderr, "Interface %s doesn't exist\n", interfaceStr); |
|
|
|
|
|
|
|
return; |
|
|
|
}else{ |
|
|
|
m_isNL80211 = true; |
|
|
|
} |
|
|
|
|
|
|
|
if(nl80211_connect(interfaceStr, &handle, &cache, &family) < 0) { |
|
|
@ -138,7 +131,7 @@ m_channels() |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
while (err) |
|
|
|
while(err) |
|
|
|
nl_recvmsgs((struct nl_sock *)handle, cb); |
|
|
|
|
|
|
|
nl80211_disconnect(handle, cache); |
|
|
@ -149,6 +142,15 @@ m_channels() |
|
|
|
|
|
|
|
free(cblock.channel_list); |
|
|
|
free(cblock.phyname); |
|
|
|
m_isValid = true; |
|
|
|
} |
|
|
|
|
|
|
|
bool Wireless::isValid() { |
|
|
|
return m_isValid; |
|
|
|
} |
|
|
|
|
|
|
|
bool Wireless::isNL80211() { |
|
|
|
return m_isNL80211; |
|
|
|
} |
|
|
|
|
|
|
|
const QString& Wireless::name() const { |
|
|
@ -156,31 +158,71 @@ const QString& Wireless::name() const { |
|
|
|
} |
|
|
|
|
|
|
|
int Wireless::ChanToFreq(int in_chan) { |
|
|
|
int x = 0; |
|
|
|
// 802.11 channels to frequencies
|
|
|
|
|
|
|
|
while (IEEE80211Freq[x][0] != 0) { |
|
|
|
if (IEEE80211Freq[x][0] == in_chan) { |
|
|
|
return IEEE80211Freq[x][1]; |
|
|
|
} |
|
|
|
x++; |
|
|
|
int x = 0; |
|
|
|
|
|
|
|
while(IEEE80211Freq[x][0] != 0) { |
|
|
|
if(IEEE80211Freq[x][0] == in_chan) { |
|
|
|
return IEEE80211Freq[x][1]; |
|
|
|
} |
|
|
|
|
|
|
|
++x; |
|
|
|
} |
|
|
|
|
|
|
|
return in_chan; |
|
|
|
} |
|
|
|
|
|
|
|
QString Wireless::ChanToFreq(QString in_chan, QString outputFormat) { |
|
|
|
QString freq; |
|
|
|
QRegularExpression re("[^\\d]"); |
|
|
|
in_chan = in_chan.replace(re, ""); |
|
|
|
|
|
|
|
if(outputFormat.isEmpty()) { |
|
|
|
bool ok = false; |
|
|
|
int chanInt = in_chan.toInt(&ok); |
|
|
|
|
|
|
|
if(ok) { |
|
|
|
freq = QString::number(ChanToFreq(chanInt)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return in_chan; |
|
|
|
return freq; |
|
|
|
} |
|
|
|
|
|
|
|
int Wireless::FreqToChan(int in_freq) { |
|
|
|
int x = 0; |
|
|
|
// 802.11 frequencies to channels
|
|
|
|
|
|
|
|
while (IEEE80211Freq[x][1] != 0) { |
|
|
|
if (IEEE80211Freq[x][1] == in_freq) { |
|
|
|
return IEEE80211Freq[x][0]; |
|
|
|
} |
|
|
|
x++; |
|
|
|
int x = 0; |
|
|
|
|
|
|
|
while(IEEE80211Freq[x][1] != 0) { |
|
|
|
if(IEEE80211Freq[x][1] == in_freq) { |
|
|
|
return IEEE80211Freq[x][0]; |
|
|
|
} |
|
|
|
|
|
|
|
++x; |
|
|
|
} |
|
|
|
|
|
|
|
return in_freq; |
|
|
|
} |
|
|
|
|
|
|
|
QString Wireless::FreqToChan(QString in_freq, QString outputFormat) { |
|
|
|
QString chan; |
|
|
|
QRegularExpression re("[^\\d]"); |
|
|
|
in_freq = in_freq.replace(re, ""); |
|
|
|
|
|
|
|
if(in_freq.length() < 4) { |
|
|
|
for(int i = in_freq.length() + 1; i <= 4; ++i) { |
|
|
|
in_freq.append("0"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if(outputFormat.isEmpty()) { |
|
|
|
bool ok = false; |
|
|
|
int freqInt = in_freq.toInt(&ok); |
|
|
|
|
|
|
|
if(ok) { |
|
|
|
chan = QString::number(FreqToChan(freqInt)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return in_freq; |
|
|
|
return chan; |
|
|
|
} |
|
|
|
|
|
|
|
int Wireless::nl80211_connect(const char * /*interface*/, void **handle, struct nl_cache **cache, void **family) { |
|
|
@ -245,7 +287,7 @@ int Wireless::nl80211_freqlist_cb(struct nl_msg *msg, void *arg) { |
|
|
|
} |
|
|
|
|
|
|
|
if (tb_msg[NL80211_ATTR_WIPHY_NAME]) { |
|
|
|
if (strcmp(nla_get_string(tb_msg[NL80211_ATTR_WIPHY_NAME]), |
|
|
|
if (strcmp(nla_get_string(tb_msg[NL80211_ATTR_WIPHY_NAME]), |
|
|
|
chanb->phyname) != 0) { |
|
|
|
return NL_SKIP; |
|
|
|
} |
|
|
@ -254,7 +296,7 @@ int Wireless::nl80211_freqlist_cb(struct nl_msg *msg, void *arg) { |
|
|
|
// Count the number of channels
|
|
|
|
for (nl_band = (struct nlattr *) nla_data(tb_msg[NL80211_ATTR_WIPHY_BANDS]), |
|
|
|
rem_band = nla_len(tb_msg[NL80211_ATTR_WIPHY_BANDS]); |
|
|
|
nla_ok(nl_band, rem_band); |
|
|
|
nla_ok(nl_band, rem_band); |
|
|
|
nl_band = (struct nlattr *) nla_next(nl_band, &rem_band)) { |
|
|
|
|
|
|
|
nla_parse(tb_band, NL80211_BAND_ATTR_MAX, (struct nlattr *) nla_data(nl_band), |
|
|
@ -262,10 +304,10 @@ int Wireless::nl80211_freqlist_cb(struct nl_msg *msg, void *arg) { |
|
|
|
|
|
|
|
for (nl_freq = (struct nlattr *) nla_data(tb_band[NL80211_BAND_ATTR_FREQS]), |
|
|
|
rem_freq = nla_len(tb_band[NL80211_BAND_ATTR_FREQS]); |
|
|
|
nla_ok(nl_freq, rem_freq); |
|
|
|
nla_ok(nl_freq, rem_freq); |
|
|
|
nl_freq = (struct nlattr *) nla_next(nl_freq, &rem_freq)) { |
|
|
|
|
|
|
|
nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, |
|
|
|
nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, |
|
|
|
(struct nlattr *) nla_data(nl_freq), |
|
|
|
nla_len(nl_freq), NULL); |
|
|
|
|
|
|
@ -286,7 +328,7 @@ int Wireless::nl80211_freqlist_cb(struct nl_msg *msg, void *arg) { |
|
|
|
// Assemble a return
|
|
|
|
for (nl_band = (struct nlattr *) nla_data(tb_msg[NL80211_ATTR_WIPHY_BANDS]), |
|
|
|
rem_band = nla_len(tb_msg[NL80211_ATTR_WIPHY_BANDS]); |
|
|
|
nla_ok(nl_band, rem_band); |
|
|
|
nla_ok(nl_band, rem_band); |
|
|
|
nl_band = (struct nlattr *) nla_next(nl_band, &rem_band)) { |
|
|
|
|
|
|
|
nla_parse(tb_band, NL80211_BAND_ATTR_MAX, (struct nlattr *) nla_data(nl_band), |
|
|
@ -294,10 +336,10 @@ int Wireless::nl80211_freqlist_cb(struct nl_msg *msg, void *arg) { |
|
|
|
|
|
|
|
for (nl_freq = (struct nlattr *) nla_data(tb_band[NL80211_BAND_ATTR_FREQS]), |
|
|
|
rem_freq = nla_len(tb_band[NL80211_BAND_ATTR_FREQS]); |
|
|
|
nla_ok(nl_freq, rem_freq); |
|
|
|
nla_ok(nl_freq, rem_freq); |
|
|
|
nl_freq = (struct nlattr *) nla_next(nl_freq, &rem_freq)) { |
|
|
|
|
|
|
|
nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, |
|
|
|
nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, |
|
|
|
(struct nlattr *) nla_data(nl_freq), |
|
|
|
nla_len(nl_freq), NULL); |
|
|
|
|
|
|
@ -316,8 +358,7 @@ int Wireless::nl80211_freqlist_cb(struct nl_msg *msg, void *arg) { |
|
|
|
return NL_SKIP; |
|
|
|
} |
|
|
|
|
|
|
|
int Wireless::nl80211_error_cb(struct sockaddr_nl * /*nla*/, struct nlmsgerr *err, |
|
|
|
void *arg) { |
|
|
|
int Wireless::nl80211_error_cb(struct sockaddr_nl * /*nla*/, struct nlmsgerr *err, void *arg) { |
|
|
|
int *ret = (int *) arg; |
|
|
|
*ret = err->error; |
|
|
|
return NL_STOP; |
|
|
@ -353,6 +394,6 @@ char* Wireless::nl80211_find_parent(const char *interface) { |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
const QMap<int, int>& Wireless::channels() const { |
|
|
|
const QMap<int, int>& Wireless::channelMap() const { |
|
|
|
return m_channels; |
|
|
|
} |
|
|
|