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);