Merge pull request #3959 from voiceroy/ip-address-display

Provide an option to show ipv4, ipv6 or both
This commit is contained in:
Alexis Rouillard
2025-03-28 09:25:44 +01:00
committed by GitHub
3 changed files with 62 additions and 14 deletions

View File

@ -16,6 +16,8 @@
#include "util/rfkill.hpp" #include "util/rfkill.hpp"
#endif #endif
enum ip_addr_pref : uint8_t { IPV4, IPV6, IPV4_6 };
namespace waybar::modules { namespace waybar::modules {
class Network : public ALabel { class Network : public ALabel {
@ -50,6 +52,7 @@ class Network : public ALabel {
std::optional<std::pair<unsigned long long, unsigned long long>> readBandwidthUsage(); std::optional<std::pair<unsigned long long, unsigned long long>> readBandwidthUsage();
int ifid_; int ifid_;
ip_addr_pref addr_pref_;
struct sockaddr_nl nladdr_ = {0}; struct sockaddr_nl nladdr_ = {0};
struct nl_sock* sock_ = nullptr; struct nl_sock* sock_ = nullptr;
struct nl_sock* ev_sock_ = nullptr; struct nl_sock* ev_sock_ = nullptr;
@ -73,9 +76,12 @@ class Network : public ALabel {
bool carrier_; bool carrier_;
std::string ifname_; std::string ifname_;
std::string ipaddr_; std::string ipaddr_;
std::string ipaddr6_;
std::string gwaddr_; std::string gwaddr_;
std::string netmask_; std::string netmask_;
std::string netmask6_;
int cidr_; int cidr_;
int cidr6_;
int32_t signal_strength_dbm_; int32_t signal_strength_dbm_;
uint8_t signal_strength_; uint8_t signal_strength_;
std::string signal_strength_app_; std::string signal_strength_app_;

View File

@ -24,7 +24,7 @@ Addressed by *network*
*family*: ++ *family*: ++
typeof: string ++ typeof: string ++
default: *ipv4* ++ default: *ipv4* ++
The address family that is used for the format replacement {ipaddr} and to determine if a network connection is present. The address family that is used for the format replacement {ipaddr} and to determine if a network connection is present. Set it to ipv4_6 to display both.
*format*: ++ *format*: ++
typeof: string ++ typeof: string ++
@ -155,9 +155,13 @@ Addressed by *network*
*{gwaddr}*: The default gateway for the interface *{gwaddr}*: The default gateway for the interface
*{netmask}*: The subnetmask corresponding to the IP. *{netmask}*: The subnetmask corresponding to the IP(V4).
*{cidr}*: The subnetmask corresponding to the IP in CIDR notation. *{netmask6}*: The subnetmask corresponding to the IP(V6).
*{cidr}*: The subnetmask corresponding to the IP(V4) in CIDR notation.
*{cidr6}*: The subnetmask corresponding to the IP(V6) in CIDR notation.
*{essid}*: Name (SSID) of the wireless network. *{essid}*: Name (SSID) of the wireless network.

View File

@ -80,6 +80,7 @@ waybar::modules::Network::readBandwidthUsage() {
waybar::modules::Network::Network(const std::string &id, const Json::Value &config) waybar::modules::Network::Network(const std::string &id, const Json::Value &config)
: ALabel(config, "network", id, DEFAULT_FORMAT, 60), : ALabel(config, "network", id, DEFAULT_FORMAT, 60),
ifid_(-1), ifid_(-1),
addr_pref_(IPV4),
efd_(-1), efd_(-1),
ev_fd_(-1), ev_fd_(-1),
want_route_dump_(false), want_route_dump_(false),
@ -88,6 +89,7 @@ waybar::modules::Network::Network(const std::string &id, const Json::Value &conf
dump_in_progress_(false), dump_in_progress_(false),
is_p2p_(false), is_p2p_(false),
cidr_(0), cidr_(0),
cidr6_(0),
signal_strength_dbm_(0), signal_strength_dbm_(0),
signal_strength_(0), signal_strength_(0),
#ifdef WANT_RFKILL #ifdef WANT_RFKILL
@ -101,6 +103,12 @@ waybar::modules::Network::Network(const std::string &id, const Json::Value &conf
// the module start with no text, but the event_box_ is shown. // the module start with no text, but the event_box_ is shown.
label_.set_markup("<s></s>"); label_.set_markup("<s></s>");
if (config_["family"] == "ipv6") {
addr_pref_ = IPV6;
} else if (config["family"] == "ipv4_6") {
addr_pref_ = IPV4_6;
}
auto bandwidth = readBandwidthUsage(); auto bandwidth = readBandwidthUsage();
if (bandwidth.has_value()) { if (bandwidth.has_value()) {
bandwidth_down_total_ = (*bandwidth).first; bandwidth_down_total_ = (*bandwidth).first;
@ -270,7 +278,7 @@ const std::string waybar::modules::Network::getNetworkState() const {
return "disconnected"; return "disconnected";
} }
if (!carrier_) return "disconnected"; if (!carrier_) return "disconnected";
if (ipaddr_.empty()) return "linked"; if (ipaddr_.empty() && ipaddr6_.empty()) return "linked";
if (essid_.empty()) return "ethernet"; if (essid_.empty()) return "ethernet";
return "wifi"; return "wifi";
} }
@ -316,12 +324,24 @@ auto waybar::modules::Network::update() -> void {
} }
getState(signal_strength_); getState(signal_strength_);
std::string final_ipaddr_;
if (addr_pref_ == ip_addr_pref::IPV4) {
final_ipaddr_ = ipaddr_;
} else if (addr_pref_ == ip_addr_pref::IPV6) {
final_ipaddr_ = ipaddr6_;
} else if (addr_pref_ == ip_addr_pref::IPV4_6) {
final_ipaddr_ = ipaddr_;
final_ipaddr_ += '\n';
final_ipaddr_ += ipaddr6_;
}
auto text = fmt::format( auto text = fmt::format(
fmt::runtime(format_), fmt::arg("essid", essid_), fmt::arg("bssid", bssid_), fmt::runtime(format_), fmt::arg("essid", essid_), fmt::arg("bssid", bssid_),
fmt::arg("signaldBm", signal_strength_dbm_), fmt::arg("signalStrength", signal_strength_), fmt::arg("signaldBm", signal_strength_dbm_), fmt::arg("signalStrength", signal_strength_),
fmt::arg("signalStrengthApp", signal_strength_app_), fmt::arg("ifname", ifname_), fmt::arg("signalStrengthApp", signal_strength_app_), fmt::arg("ifname", ifname_),
fmt::arg("netmask", netmask_), fmt::arg("ipaddr", ipaddr_), fmt::arg("gwaddr", gwaddr_), fmt::arg("netmask", netmask_), fmt::arg("netmask6", netmask6_),
fmt::arg("cidr", cidr_), fmt::arg("frequency", fmt::format("{:.1f}", frequency_)), fmt::arg("ipaddr", final_ipaddr_), fmt::arg("gwaddr", gwaddr_), fmt::arg("cidr", cidr_),
fmt::arg("cidr6", cidr6_), fmt::arg("frequency", fmt::format("{:.1f}", frequency_)),
fmt::arg("icon", getIcon(signal_strength_, state_)), fmt::arg("icon", getIcon(signal_strength_, state_)),
fmt::arg("bandwidthDownBits", pow_format(bandwidth_down * 8ull / interval_.count(), "b/s")), fmt::arg("bandwidthDownBits", pow_format(bandwidth_down * 8ull / interval_.count(), "b/s")),
fmt::arg("bandwidthUpBits", pow_format(bandwidth_up * 8ull / interval_.count(), "b/s")), fmt::arg("bandwidthUpBits", pow_format(bandwidth_up * 8ull / interval_.count(), "b/s")),
@ -352,8 +372,9 @@ auto waybar::modules::Network::update() -> void {
fmt::runtime(tooltip_format), fmt::arg("essid", essid_), fmt::arg("bssid", bssid_), fmt::runtime(tooltip_format), fmt::arg("essid", essid_), fmt::arg("bssid", bssid_),
fmt::arg("signaldBm", signal_strength_dbm_), fmt::arg("signalStrength", signal_strength_), fmt::arg("signaldBm", signal_strength_dbm_), fmt::arg("signalStrength", signal_strength_),
fmt::arg("signalStrengthApp", signal_strength_app_), fmt::arg("ifname", ifname_), fmt::arg("signalStrengthApp", signal_strength_app_), fmt::arg("ifname", ifname_),
fmt::arg("netmask", netmask_), fmt::arg("ipaddr", ipaddr_), fmt::arg("gwaddr", gwaddr_), fmt::arg("netmask", netmask_), fmt::arg("netmask6", netmask6_),
fmt::arg("cidr", cidr_), fmt::arg("frequency", fmt::format("{:.1f}", frequency_)), fmt::arg("ipaddr", final_ipaddr_), fmt::arg("gwaddr", gwaddr_), fmt::arg("cidr", cidr_),
fmt::arg("cidr6", cidr6_), fmt::arg("frequency", fmt::format("{:.1f}", frequency_)),
fmt::arg("icon", getIcon(signal_strength_, state_)), fmt::arg("icon", getIcon(signal_strength_, state_)),
fmt::arg("bandwidthDownBits", fmt::arg("bandwidthDownBits",
pow_format(bandwidth_down * 8ull / interval_.count(), "b/s")), pow_format(bandwidth_down * 8ull / interval_.count(), "b/s")),
@ -394,10 +415,13 @@ void waybar::modules::Network::clearIface() {
essid_.clear(); essid_.clear();
bssid_.clear(); bssid_.clear();
ipaddr_.clear(); ipaddr_.clear();
ipaddr6_.clear();
gwaddr_.clear(); gwaddr_.clear();
netmask_.clear(); netmask_.clear();
netmask6_.clear();
carrier_ = false; carrier_ = false;
cidr_ = 0; cidr_ = 0;
cidr6_ = 0;
signal_strength_dbm_ = 0; signal_strength_dbm_ = 0;
signal_strength_ = 0; signal_strength_ = 0;
signal_strength_app_.clear(); signal_strength_app_.clear();
@ -521,7 +545,6 @@ int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) {
if (ifa->ifa_scope >= RT_SCOPE_LINK) { if (ifa->ifa_scope >= RT_SCOPE_LINK) {
return NL_OK; return NL_OK;
} }
for (; RTA_OK(ifa_rta, attrlen); ifa_rta = RTA_NEXT(ifa_rta, attrlen)) { for (; RTA_OK(ifa_rta, attrlen); ifa_rta = RTA_NEXT(ifa_rta, attrlen)) {
switch (ifa_rta->rta_type) { switch (ifa_rta->rta_type) {
case IFA_ADDRESS: case IFA_ADDRESS:
@ -529,8 +552,20 @@ int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) {
case IFA_LOCAL: case IFA_LOCAL:
char ipaddr[INET6_ADDRSTRLEN]; char ipaddr[INET6_ADDRSTRLEN];
if (!is_del_event) { if (!is_del_event) {
net->ipaddr_ = inet_ntop(ifa->ifa_family, RTA_DATA(ifa_rta), ipaddr, sizeof(ipaddr)); if ((net->addr_pref_ == ip_addr_pref::IPV4 ||
net->cidr_ = ifa->ifa_prefixlen; net->addr_pref_ == ip_addr_pref::IPV4_6) &&
net->cidr_ == 0 && ifa->ifa_family == AF_INET) {
net->ipaddr_ =
inet_ntop(ifa->ifa_family, RTA_DATA(ifa_rta), ipaddr, sizeof(ipaddr));
net->cidr_ = ifa->ifa_prefixlen;
} else if ((net->addr_pref_ == ip_addr_pref::IPV6 ||
net->addr_pref_ == ip_addr_pref::IPV4_6) &&
net->cidr6_ == 0 && ifa->ifa_family == AF_INET6) {
net->ipaddr6_ =
inet_ntop(ifa->ifa_family, RTA_DATA(ifa_rta), ipaddr, sizeof(ipaddr));
net->cidr6_ = ifa->ifa_prefixlen;
}
switch (ifa->ifa_family) { switch (ifa->ifa_family) {
case AF_INET: { case AF_INET: {
struct in_addr netmask; struct in_addr netmask;
@ -538,21 +573,24 @@ int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) {
net->netmask_ = inet_ntop(ifa->ifa_family, &netmask, ipaddr, sizeof(ipaddr)); net->netmask_ = inet_ntop(ifa->ifa_family, &netmask, ipaddr, sizeof(ipaddr));
} }
case AF_INET6: { case AF_INET6: {
struct in6_addr netmask; struct in6_addr netmask6;
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
int v = (i + 1) * 8 - ifa->ifa_prefixlen; int v = (i + 1) * 8 - ifa->ifa_prefixlen;
if (v < 0) v = 0; if (v < 0) v = 0;
if (v > 8) v = 8; if (v > 8) v = 8;
netmask.s6_addr[i] = ~0 << v; netmask6.s6_addr[i] = ~0 << v;
} }
net->netmask_ = inet_ntop(ifa->ifa_family, &netmask, ipaddr, sizeof(ipaddr)); net->netmask6_ = inet_ntop(ifa->ifa_family, &netmask6, ipaddr, sizeof(ipaddr));
} }
} }
spdlog::debug("network: {}, new addr {}/{}", net->ifname_, net->ipaddr_, net->cidr_); spdlog::debug("network: {}, new addr {}/{}", net->ifname_, net->ipaddr_, net->cidr_);
} else { } else {
net->ipaddr_.clear(); net->ipaddr_.clear();
net->ipaddr6_.clear();
net->cidr_ = 0; net->cidr_ = 0;
net->cidr6_ = 0;
net->netmask_.clear(); net->netmask_.clear();
net->netmask6_.clear();
spdlog::debug("network: {} addr deleted {}/{}", net->ifname_, spdlog::debug("network: {} addr deleted {}/{}", net->ifname_,
inet_ntop(ifa->ifa_family, RTA_DATA(ifa_rta), ipaddr, sizeof(ipaddr)), inet_ntop(ifa->ifa_family, RTA_DATA(ifa_rta), ipaddr, sizeof(ipaddr)),
ifa->ifa_prefixlen); ifa->ifa_prefixlen);