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