feat(net): interface discovery (#2025)
This commit is contained in:
parent
eb302f96ff
commit
f7c2d83ef2
@ -67,6 +67,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
([`#2108`](https://github.com/polybar/polybar/issues/2108))
|
([`#2108`](https://github.com/polybar/polybar/issues/2108))
|
||||||
- `internal/xworkspaces`: Make the urgent hint persistent
|
- `internal/xworkspaces`: Make the urgent hint persistent
|
||||||
([`#1081`](https://github.com/polybar/polybar/issues/1081))
|
([`#1081`](https://github.com/polybar/polybar/issues/1081))
|
||||||
|
- `internal/network`: `interface-type` may be used in place of `interface` to
|
||||||
|
automatically select a network interface
|
||||||
|
([`#2025`](https://github.com/polybar/polybar/pull/2025))
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Slight changes to the value ranges the different ramp levels are responsible
|
- Slight changes to the value ranges the different ramp levels are responsible
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <chrono>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include "settings.hpp"
|
|
||||||
#include "errors.hpp"
|
|
||||||
#include "components/logger.hpp"
|
#include "components/logger.hpp"
|
||||||
|
#include "errors.hpp"
|
||||||
|
#include "settings.hpp"
|
||||||
#include "utils/math.hpp"
|
#include "utils/math.hpp"
|
||||||
|
|
||||||
#if WITH_LIBNL
|
#if WITH_LIBNL
|
||||||
@ -38,6 +38,8 @@ namespace net {
|
|||||||
DEFINE_ERROR(network_error);
|
DEFINE_ERROR(network_error);
|
||||||
|
|
||||||
bool is_wireless_interface(const string& ifname);
|
bool is_wireless_interface(const string& ifname);
|
||||||
|
std::string find_wireless_interface();
|
||||||
|
std::string find_wired_interface();
|
||||||
|
|
||||||
// types {{{
|
// types {{{
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "adapters/net.hpp"
|
#include "adapters/net.hpp"
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <linux/ethtool.h>
|
#include <linux/ethtool.h>
|
||||||
#include <linux/if_link.h>
|
#include <linux/if_link.h>
|
||||||
#include <linux/sockios.h>
|
#include <linux/sockios.h>
|
||||||
@ -9,6 +10,9 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
@ -21,14 +25,65 @@
|
|||||||
POLYBAR_NS
|
POLYBAR_NS
|
||||||
|
|
||||||
namespace net {
|
namespace net {
|
||||||
|
enum class NetType {
|
||||||
|
WIRELESS,
|
||||||
|
ETHERNET,
|
||||||
|
OTHER,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const string NO_IP = string("N/A");
|
||||||
|
static const string NET_PATH = "/sys/class/net/";
|
||||||
|
static const string VIRTUAL_PATH = "/sys/devices/virtual/";
|
||||||
|
|
||||||
|
static bool is_virtual(const std::string& ifname) {
|
||||||
|
char* target = realpath((NET_PATH + ifname).c_str(), nullptr);
|
||||||
|
const std::string real_path{target};
|
||||||
|
free(target);
|
||||||
|
return real_path.rfind(VIRTUAL_PATH, 0) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetType iface_type(const std::string& ifname) {
|
||||||
|
if (file_util::exists(NET_PATH + ifname + "/wireless")) {
|
||||||
|
return NetType::WIRELESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_virtual(ifname)) {
|
||||||
|
return NetType::OTHER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NetType::ETHERNET;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if interface with given name is a wireless device
|
* Test if interface with given name is a wireless device
|
||||||
*/
|
*/
|
||||||
bool is_wireless_interface(const string& ifname) {
|
bool is_wireless_interface(const string& ifname) {
|
||||||
return file_util::exists("/sys/class/net/" + ifname + "/wireless");
|
return iface_type(ifname) == NetType::WIRELESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const string NO_IP = string("N/A");
|
std::string find_interface(NetType type) {
|
||||||
|
struct ifaddrs* ifaddrs;
|
||||||
|
getifaddrs(&ifaddrs);
|
||||||
|
for (struct ifaddrs* i = ifaddrs; i != nullptr; i = i->ifa_next) {
|
||||||
|
const std::string name{i->ifa_name};
|
||||||
|
const NetType iftype = iface_type(name);
|
||||||
|
if (iftype != type) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
freeifaddrs(ifaddrs);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
freeifaddrs(ifaddrs);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string find_wireless_interface() {
|
||||||
|
return find_interface(NetType::WIRELESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string find_wired_interface() {
|
||||||
|
return find_interface(NetType::ETHERNET);
|
||||||
|
}
|
||||||
|
|
||||||
// class : network {{{
|
// class : network {{{
|
||||||
|
|
||||||
@ -215,7 +270,7 @@ namespace net {
|
|||||||
* Test if the network interface is in a valid state
|
* Test if the network interface is in a valid state
|
||||||
*/
|
*/
|
||||||
bool network::test_interface() const {
|
bool network::test_interface() const {
|
||||||
auto operstate = file_util::contents("/sys/class/net/" + m_interface + "/operstate");
|
auto operstate = file_util::contents(NET_PATH + m_interface + "/operstate");
|
||||||
bool up = operstate.compare(0, 2, "up") == 0;
|
bool up = operstate.compare(0, 2, "up") == 0;
|
||||||
return m_unknown_up ? (up || operstate.compare(0, 7, "unknown") == 0) : up;
|
return m_unknown_up ? (up || operstate.compare(0, 7, "unknown") == 0) : up;
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,8 @@
|
|||||||
#include "drawtypes/animation.hpp"
|
#include "drawtypes/animation.hpp"
|
||||||
#include "drawtypes/label.hpp"
|
#include "drawtypes/label.hpp"
|
||||||
#include "drawtypes/ramp.hpp"
|
#include "drawtypes/ramp.hpp"
|
||||||
#include "utils/factory.hpp"
|
|
||||||
|
|
||||||
#include "modules/meta/base.inl"
|
#include "modules/meta/base.inl"
|
||||||
|
#include "utils/factory.hpp"
|
||||||
|
|
||||||
POLYBAR_NS
|
POLYBAR_NS
|
||||||
|
|
||||||
@ -16,6 +15,32 @@ namespace modules {
|
|||||||
: timer_module<network_module>(bar, move(name_)) {
|
: timer_module<network_module>(bar, move(name_)) {
|
||||||
// Load configuration values
|
// Load configuration values
|
||||||
m_interface = m_conf.get(name(), "interface", m_interface);
|
m_interface = m_conf.get(name(), "interface", m_interface);
|
||||||
|
|
||||||
|
if (m_interface.empty()) {
|
||||||
|
std::string type = m_conf.get(name(), "interface-type");
|
||||||
|
if (type == "wired") {
|
||||||
|
m_interface = net::find_wired_interface();
|
||||||
|
if (!m_interface.empty()) {
|
||||||
|
m_log.notice("%s: Discovered wired interface %s", name(), m_interface);
|
||||||
|
}
|
||||||
|
} else if (type == "wireless") {
|
||||||
|
m_interface = net::find_wireless_interface();
|
||||||
|
if (!m_interface.empty()) {
|
||||||
|
m_log.notice("%s: Discovered wireless interface %s", name(), m_interface);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw module_error("Invalid interface type '" + type + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_interface.empty()) {
|
||||||
|
throw module_error("No interface found for type '" + type + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_interface.empty()) {
|
||||||
|
throw module_error("missing 'interface' or 'interface-type'");
|
||||||
|
}
|
||||||
|
|
||||||
m_ping_nth_update = m_conf.get(name(), "ping-interval", m_ping_nth_update);
|
m_ping_nth_update = m_conf.get(name(), "ping-interval", m_ping_nth_update);
|
||||||
m_udspeed_minwidth = m_conf.get(name(), "udspeed-minwidth", m_udspeed_minwidth);
|
m_udspeed_minwidth = m_conf.get(name(), "udspeed-minwidth", m_udspeed_minwidth);
|
||||||
m_accumulate = m_conf.get(name(), "accumulate-stats", m_accumulate);
|
m_accumulate = m_conf.get(name(), "accumulate-stats", m_accumulate);
|
||||||
@ -189,6 +214,6 @@ namespace modules {
|
|||||||
|
|
||||||
m_log.trace("%s: Reached end of network subthread", name());
|
m_log.trace("%s: Reached end of network subthread", name());
|
||||||
}
|
}
|
||||||
}
|
} // namespace modules
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
Loading…
Reference in New Issue
Block a user