From f4673a985881616b7dd5183041647902238b075b Mon Sep 17 00:00:00 2001 From: Leonardo Di Giovanna Date: Thu, 26 Sep 2024 14:28:20 +0200 Subject: [PATCH] feat(stats): add host_netinfo networking information stats family Introduce host_netinfo stats family to hold information regarding host networking. At the moment, it only provides ipv4 and ipv6 addresses list for each interface available on the host. The naming schema for the introduced stats is falco.host_netinfo.interfaces..protocols..addresses. Signed-off-by: Leonardo Di Giovanna --- userspace/falco/stats_writer.cpp | 71 ++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/userspace/falco/stats_writer.cpp b/userspace/falco/stats_writer.cpp index fac1b76843c..0db265a4bc2 100644 --- a/userspace/falco/stats_writer.cpp +++ b/userspace/falco/stats_writer.cpp @@ -309,6 +309,75 @@ stats_writer::collector::collector(const std::shared_ptr& writer) { } +std::string merge_strings(const std::vector& v, const std::string& delim) { + if(v.empty()) + { + return ""; + } + std::stringstream ss; + std::copy(v.cbegin(), v.cend(), std::ostream_iterator(ss, delim.c_str())); + const std::string s_str = ss.str(); + return s_str.substr(0, s_str.size() - delim.size()); +} + +void add_netinfo_metrics_output_fields( + nlohmann::json& output_fields, + const std::shared_ptr& inspector) +{ + const auto ipv4_ifinfo = inspector->get_ifaddr_list().get_ipv4_list(); + const auto ipv6_ifinfo = inspector->get_ifaddr_list().get_ipv6_list(); + + // For each interface name, collect the corresponding list of IPv4/IPv6 addresses + std::map> ifnames_to_ipv4_addresses; + std::map> ifnames_to_ipv6_addresses; + + for (const auto& ifinfo : *ipv4_ifinfo) + { + if(ifinfo.m_name == "lo") + { + return; + } + + auto it = ifnames_to_ipv4_addresses.find(ifinfo.m_name); + auto address = ifinfo.addr_to_string(); + if (it == ifnames_to_ipv4_addresses.end()) + { + ifnames_to_ipv4_addresses.emplace(ifinfo.m_name, std::vector{address}); + return; + } + it->second.emplace_back(address); + } + + for (const auto& ifinfo : *ipv6_ifinfo) + { + if(ifinfo.m_name == "lo") + { + return; + } + + auto it = ifnames_to_ipv6_addresses.find(ifinfo.m_name); + auto address = ifinfo.addr_to_string(); + if (it == ifnames_to_ipv6_addresses.end()) + { + ifnames_to_ipv6_addresses.emplace(ifinfo.m_name, std::vector{address}); + return; + } + it->second.emplace_back(address); + } + + for (const auto& item : ifnames_to_ipv4_addresses) { + auto metric_name = "falco.host_netinfo.interfaces." + item.first + ".protocols.ipv4.addresses"; + auto addresses = merge_strings(item.second, ","); + output_fields.emplace(metric_name, addresses); + } + + for (const auto& item : ifnames_to_ipv6_addresses) { + auto metric_name = "falco.host_netinfo.interfaces." + item.first + ".protocols.ipv6.addresses"; + auto addresses = merge_strings(item.second, ","); + output_fields.emplace(metric_name, addresses); + } +} + void stats_writer::collector::get_metrics_output_fields_wrapper( nlohmann::json& output_fields, const std::shared_ptr& inspector, @@ -358,6 +427,8 @@ void stats_writer::collector::get_metrics_output_fields_wrapper( output_fields[metric_name_file_sha256] = item.second; } + add_netinfo_metrics_output_fields(output_fields, inspector); + #endif output_fields["evt.source"] = src; for (size_t i = 0; i < sizeof(all_driver_engines) / sizeof(const char*); i++)