From d1d307d5005a7acce47693a8179e5390fa9bc1c7 Mon Sep 17 00:00:00 2001 From: sqwishy Date: Sun, 10 Jun 2018 13:51:43 -0700 Subject: [PATCH] feat(net): Add local_ip6 token (#1239) It's queried the same way ipv4 addresses are queried, but here it displays globally routable addresses. If there are multiple such addresses, it picks one (same as with ipv4). It's possible that an address discovered this way is not in fact globally reachable but still marked as global. --- include/adapters/net.hpp | 5 +++++ src/adapters/net.cpp | 37 +++++++++++++++++++++++++++++++++++-- src/modules/network.cpp | 1 + 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/include/adapters/net.hpp b/include/adapters/net.hpp index 248a8851..97e11469 100644 --- a/include/adapters/net.hpp +++ b/include/adapters/net.hpp @@ -14,6 +14,7 @@ #include "common.hpp" #include "settings.hpp" #include "errors.hpp" +#include "components/logger.hpp" #include "utils/math.hpp" POLYBAR_NS @@ -49,6 +50,7 @@ namespace net { struct link_status { string ip; + string ip6; link_activity previous{}; link_activity current{}; }; @@ -66,6 +68,7 @@ namespace net { virtual bool ping() const; string ip() const; + string ip6() const; string downspeed(int minwidth = 3) const; string upspeed(int minwidth = 3) const; void set_unknown_up(bool unknown = true); @@ -74,7 +77,9 @@ namespace net { void check_tuntap(); bool test_interface() const; string format_speedrate(float bytes_diff, int minwidth) const; + void query_ip6(); + const logger& m_log; unique_ptr m_socketfd; link_status m_status{}; string m_interface; diff --git a/src/adapters/net.cpp b/src/adapters/net.cpp index 5d122005..c4ce414d 100644 --- a/src/adapters/net.cpp +++ b/src/adapters/net.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -36,12 +37,14 @@ namespace net { return file_util::exists("/sys/class/net/" + ifname + "/wireless"); } + static const string NO_IP6 = string("N/A"); + // class : network {{{ /** * Construct network interface */ - network::network(string interface) : m_interface(move(interface)) { + network::network(string interface) : m_log(logger::make()), m_interface(move(interface)) { if (if_nametoindex(m_interface.c_str()) == 0) { throw network_error("Invalid network interface \"" + m_interface + "\""); } @@ -67,6 +70,7 @@ namespace net { m_status.current.transmitted = 0; m_status.current.received = 0; m_status.current.time = std::chrono::system_clock::now(); + m_status.ip6 = NO_IP6; for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) { if (ifa->ifa_addr == nullptr) { @@ -79,6 +83,8 @@ namespace net { } } + struct sockaddr_in6* sa6; + switch (ifa->ifa_addr->sa_family) { case AF_INET: char ip_buffer[NI_MAXHOST]; @@ -86,6 +92,26 @@ namespace net { m_status.ip = string{ip_buffer}; break; + case AF_INET6: + char ip6_buffer[INET_ADDRSTRLEN]; + sa6 = reinterpret_cast(ifa->ifa_addr); + if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) { + continue; + } + if (IN6_IS_ADDR_SITELOCAL(&sa6->sin6_addr)) { + continue; + } + if ((((unsigned char*)sa6->sin6_addr.s6_addr)[0] & 0xFE) == 0xFC) { + /* Skip Unique Local Addresses (fc00::/7) */ + continue; + } + if (inet_ntop(AF_INET6, &sa6->sin6_addr, ip6_buffer, NI_MAXHOST) == 0) { + m_log.warn("inet_ntop() " + string(strerror(errno))); + continue; + } + m_status.ip6 = string{ip6_buffer}; + break; + case AF_PACKET: if (ifa->ifa_data == nullptr) { continue; @@ -119,12 +145,19 @@ namespace net { } /** - * Get interface ip address + * Get interface ipv4 address */ string network::ip() const { return m_status.ip; } + /** + * Get interface ipv6 address + */ + string network::ip6() const { + return m_status.ip6; + } + /** * Get download speed rate */ diff --git a/src/modules/network.cpp b/src/modules/network.cpp index bec6269a..23e98d69 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -117,6 +117,7 @@ namespace modules { label->reset_tokens(); label->replace_token("%ifname%", m_interface); label->replace_token("%local_ip%", network->ip()); + label->replace_token("%local_ip6%", network->ip6()); label->replace_token("%upspeed%", upspeed); label->replace_token("%downspeed%", downspeed);