parent
7b293a42cd
commit
e22ec91101
2 changed files with 60 additions and 36 deletions
|
@ -21,8 +21,8 @@ namespace net {
|
|||
// types {{{
|
||||
|
||||
struct quality_range {
|
||||
int val = 0;
|
||||
int max = 0;
|
||||
int val{0};
|
||||
int max{0};
|
||||
|
||||
int percentage() const {
|
||||
if (max < 0)
|
||||
|
@ -34,15 +34,15 @@ namespace net {
|
|||
using bytes_t = unsigned int;
|
||||
|
||||
struct link_activity {
|
||||
bytes_t transmitted = 0;
|
||||
bytes_t received = 0;
|
||||
bytes_t transmitted{0};
|
||||
bytes_t received{0};
|
||||
chrono::system_clock::time_point time;
|
||||
};
|
||||
|
||||
struct link_status {
|
||||
string ip;
|
||||
link_activity previous;
|
||||
link_activity current;
|
||||
link_activity previous{};
|
||||
link_activity current{};
|
||||
};
|
||||
|
||||
// }}}
|
||||
|
@ -62,12 +62,14 @@ namespace net {
|
|||
string upspeed(int minwidth = 3) const;
|
||||
|
||||
protected:
|
||||
void check_tuntap();
|
||||
bool test_interface() const;
|
||||
string format_speedrate(float bytes_diff, int minwidth) const;
|
||||
|
||||
int m_socketfd = 0;
|
||||
link_status m_status;
|
||||
int m_socketfd{0};
|
||||
link_status m_status{};
|
||||
string m_interface;
|
||||
bool m_tuntap{false};
|
||||
};
|
||||
|
||||
// }}}
|
||||
|
@ -82,7 +84,7 @@ namespace net {
|
|||
string linkspeed() const;
|
||||
|
||||
private:
|
||||
int m_linkspeed = 0;
|
||||
int m_linkspeed{0};
|
||||
};
|
||||
|
||||
// }}}
|
||||
|
@ -106,8 +108,8 @@ namespace net {
|
|||
private:
|
||||
shared_ptr<wireless_info> m_info;
|
||||
string m_essid;
|
||||
quality_range m_signalstrength;
|
||||
quality_range m_linkquality;
|
||||
quality_range m_signalstrength{};
|
||||
quality_range m_linkquality{};
|
||||
};
|
||||
|
||||
// }}}
|
||||
|
|
|
@ -46,6 +46,7 @@ namespace net {
|
|||
throw network_error("Invalid network interface \"" + m_interface + "\"");
|
||||
if ((m_socketfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
throw network_error("Failed to open socket");
|
||||
check_tuntap();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,11 +72,11 @@ namespace net {
|
|||
m_status.current.time = chrono::system_clock::now();
|
||||
|
||||
for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_data == nullptr || ifa->ifa_addr == nullptr)
|
||||
if (ifa->ifa_addr == nullptr)
|
||||
continue;
|
||||
|
||||
if (m_interface.compare(0, m_interface.length(), ifa->ifa_name) != 0)
|
||||
if (!accumulate || ifa->ifa_addr->sa_family != AF_PACKET)
|
||||
if (!accumulate || (ifa->ifa_data == nullptr && ifa->ifa_addr->sa_family != AF_PACKET))
|
||||
continue;
|
||||
|
||||
switch (ifa->ifa_addr->sa_family) {
|
||||
|
@ -86,6 +87,8 @@ namespace net {
|
|||
break;
|
||||
|
||||
case AF_PACKET:
|
||||
if (ifa->ifa_data == nullptr)
|
||||
continue;
|
||||
struct rtnl_link_stats* link_state = reinterpret_cast<decltype(link_state)>(ifa->ifa_data);
|
||||
if (link_state == nullptr)
|
||||
continue;
|
||||
|
@ -136,6 +139,32 @@ namespace net {
|
|||
return format_speedrate(bytes_diff, minwidth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query driver info to check if the
|
||||
* interface is a TUN/TAP device
|
||||
*/
|
||||
void network::check_tuntap() {
|
||||
struct ethtool_drvinfo driver;
|
||||
struct ifreq request;
|
||||
|
||||
driver.cmd = ETHTOOL_GDRVINFO;
|
||||
|
||||
strncpy(request.ifr_name, m_interface.c_str(), IFNAMSIZ - 0);
|
||||
|
||||
request.ifr_data = reinterpret_cast<caddr_t>(&driver);
|
||||
|
||||
if (ioctl(m_socketfd, SIOCETHTOOL, &request) == -1)
|
||||
return;
|
||||
|
||||
// Check if it's a TUN/TAP device
|
||||
if (strncmp(driver.bus_info, "tun", 3) == 0)
|
||||
m_tuntap = true;
|
||||
else if (strncmp(driver.bus_info, "tap", 3) == 0)
|
||||
m_tuntap = true;
|
||||
else
|
||||
m_tuntap = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the network interface is in a valid state
|
||||
*/
|
||||
|
@ -171,20 +200,22 @@ namespace net {
|
|||
* Query device driver for information
|
||||
*/
|
||||
bool wired_network::query(bool accumulate) {
|
||||
if (!network::query(accumulate))
|
||||
if (m_tuntap)
|
||||
return true;
|
||||
else if (!network::query(accumulate))
|
||||
return false;
|
||||
|
||||
struct ethtool_cmd ethernet_data;
|
||||
ethernet_data.cmd = ETHTOOL_GSET;
|
||||
|
||||
struct ifreq request;
|
||||
struct ethtool_cmd data;
|
||||
|
||||
strncpy(request.ifr_name, m_interface.c_str(), IFNAMSIZ - 1);
|
||||
request.ifr_data = reinterpret_cast<caddr_t>(ðernet_data);
|
||||
data.cmd = ETHTOOL_GSET;
|
||||
request.ifr_data = reinterpret_cast<caddr_t>(&data);
|
||||
|
||||
if (ioctl(m_socketfd, SIOCETHTOOL, &request) == -1)
|
||||
return false;
|
||||
|
||||
m_linkspeed = ethernet_data.speed;
|
||||
m_linkspeed = data.speed;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -193,20 +224,20 @@ namespace net {
|
|||
* Check current connection state
|
||||
*/
|
||||
bool wired_network::connected() const {
|
||||
if (!network::test_interface())
|
||||
if (!m_tuntap && !network::test_interface())
|
||||
return false;
|
||||
|
||||
struct ethtool_value data;
|
||||
struct ifreq request;
|
||||
struct ethtool_value ethernet_data;
|
||||
|
||||
strncpy(request.ifr_name, m_interface.c_str(), IFNAMSIZ - 1);
|
||||
ethernet_data.cmd = ETHTOOL_GLINK;
|
||||
request.ifr_data = reinterpret_cast<caddr_t>(ðernet_data);
|
||||
data.cmd = ETHTOOL_GLINK;
|
||||
request.ifr_data = reinterpret_cast<caddr_t>(&data);
|
||||
|
||||
if (ioctl(m_socketfd, SIOCETHTOOL, &request) != -1)
|
||||
return ethernet_data.data != 0;
|
||||
if (ioctl(m_socketfd, SIOCETHTOOL, &request) == -1)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
return data.data != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -256,16 +287,7 @@ namespace net {
|
|||
bool wireless_network::connected() const {
|
||||
if (!network::test_interface())
|
||||
return false;
|
||||
|
||||
struct ifreq request;
|
||||
strncpy(request.ifr_name, m_interface.c_str(), IFNAMSIZ - 1);
|
||||
|
||||
if ((ioctl(m_socketfd, SIOCGIFFLAGS, &request)) == -1)
|
||||
return false;
|
||||
if (m_essid.empty())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return !m_essid.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue