diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4f68487045..5089c38295 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -110,13 +110,13 @@ jobs: name: build-sysdig-${{ matrix.os }}-${{ matrix.arch }} strategy: matrix: - os: [windows-latest, macos-13, macos-14] + os: [windows-latest, macos-15-intel, macos-14] include: - os: windows-latest artifact_name: win artifact_ext: exe arch: x86_64 - - os: macos-13 + - os: macos-15-intel artifact_name: osx artifact_ext: dmg arch: x86_64 diff --git a/.github/workflows/release-draft.yaml b/.github/workflows/release-draft.yaml index b3a8b79aa0..37a539a0e0 100644 --- a/.github/workflows/release-draft.yaml +++ b/.github/workflows/release-draft.yaml @@ -105,13 +105,13 @@ jobs: name: build-release-others strategy: matrix: - os: [windows-latest, macos-13, macos-14] + os: [windows-latest, macos-15-intel, macos-14] include: - os: windows-latest artifact_name: win artifact_ext: exe arch: x86_64 - - os: macos-13 + - os: macos-15-intel artifact_name: osx artifact_ext: dmg arch: x86_64 diff --git a/cmake/modules/container_plugin.cmake b/cmake/modules/container_plugin.cmake index fda848ef30..790f7f4bbb 100644 --- a/cmake/modules/container_plugin.cmake +++ b/cmake/modules/container_plugin.cmake @@ -17,7 +17,7 @@ include(ExternalProject) string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} PLUGINS_SYSTEM_NAME) -set(CONTAINER_VERSION "0.5.0") +set(CONTAINER_VERSION "0.6.0") if(UNIX AND NOT APPLE) @@ -25,9 +25,9 @@ if(UNIX AND NOT APPLE) "${CMAKE_BINARY_DIR}/container_plugin-prefix/src/container_plugin/libcontainer.so" ) if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64") - set(CONTAINER_HASH "717020a51d2c0a58a777fef724be53cb802d687815e336f17d9cb0bbdb79fcb1") + set(CONTAINER_HASH "f9c322dc2aa4cbda492a5e6258532f771e960db45509a53bc1a528a01f4b6168") else() # arm64 - set(CONTAINER_HASH "2de25ef29eaadd719507441dbf1610bf094e9c41e9aa8cdb5f6a70c4ec8bba75") + set(CONTAINER_HASH "f2015a5c758b5eb79869ec1593352adf5c955990e58e08047b4c1344c6b07676") endif() if(NOT TARGET container_plugin) @@ -75,7 +75,7 @@ else() ExternalProject_Add( container_plugin URL "https://github.com/falcosecurity/plugins/archive/refs/tags/plugins/container/v${CONTAINER_VERSION}.tar.gz" - URL_HASH "SHA256=b3e3fc3f26bf405c3332a8d75377fbbdd298066d46c21813a4a2bbb0f352f7fb" + URL_HASH "SHA256=308354b7a92c8d4fb0240e22a62cf0ac35c4b5b2ecf73863365d60d4d0a1d58f" SOURCE_SUBDIR plugins/container BUILD_IN_SOURCE 1 BUILD_BYPRODUCTS "${CONTAINER_LIBRARY}" diff --git a/cmake/modules/zlib.cmake b/cmake/modules/zlib.cmake deleted file mode 100644 index 13f92db51e..0000000000 --- a/cmake/modules/zlib.cmake +++ /dev/null @@ -1,106 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# -# Copyright (C) 2023 The Falco Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the -# specific language governing permissions and limitations under the License. -# - -option(USE_BUNDLED_ZLIB "Enable building of the bundled zlib" ${USE_BUNDLED_DEPS}) - -if(ZLIB_INCLUDE) - # we already have zlib -elseif(NOT USE_BUNDLED_ZLIB) - find_path(ZLIB_INCLUDE zlib.h PATH_SUFFIXES zlib) - find_library(ZLIB_LIB NAMES z) - if(ZLIB_INCLUDE AND ZLIB_LIB) - message(STATUS "Found zlib: include: ${ZLIB_INCLUDE}, lib: ${ZLIB_LIB}") - else() - message(FATAL_ERROR "Couldn't find system zlib") - endif() -else() - set(ZLIB_SRC "${PROJECT_BINARY_DIR}/zlib-prefix/src/zlib") - set(ZLIB_INCLUDE "${ZLIB_SRC}") - set(ZLIB_HEADERS "") - list(APPEND ZLIB_HEADERS - "${ZLIB_INCLUDE}/crc32.h" - "${ZLIB_INCLUDE}/deflate.h" - "${ZLIB_INCLUDE}/gzguts.h" - "${ZLIB_INCLUDE}/inffast.h" - "${ZLIB_INCLUDE}/inffixed.h" - "${ZLIB_INCLUDE}/inflate.h" - "${ZLIB_INCLUDE}/inftrees.h" - "${ZLIB_INCLUDE}/trees.h" - "${ZLIB_INCLUDE}/zconf.h" - "${ZLIB_INCLUDE}/zlib.h" - "${ZLIB_INCLUDE}/zutil.h" - ) - if(NOT TARGET zlib) - set(ZLIB_CFLAGS ) - if (ENABLE_PIC) - set(ZLIB_CFLAGS -fPIC) - endif() - - message(STATUS "Using bundled zlib in '${ZLIB_SRC}'") - if(NOT WIN32) - if(BUILD_SHARED_LIBS) - set(ZLIB_LIB_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(ZLIB_CONFIGURE_FLAGS ) - else() - set(ZLIB_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(ZLIB_CONFIGURE_FLAGS "--static") - endif() - set(ZLIB_LIB "${ZLIB_SRC}/libz${ZLIB_LIB_SUFFIX}") - ExternalProject_Add(zlib - PREFIX "${PROJECT_BINARY_DIR}/zlib-prefix" - URL "https://github.com/madler/zlib/archive/v1.2.13.tar.gz" - URL_HASH "SHA256=1525952a0a567581792613a9723333d7f8cc20b87a81f920fb8bc7e3f2251428" - CONFIGURE_COMMAND CFLAGS=${ZLIB_CFLAGS} ./configure --prefix=${ZLIB_SRC} ${ZLIB_CONFIGURE_FLAGS} - BUILD_COMMAND make - BUILD_IN_SOURCE 1 - BUILD_BYPRODUCTS ${ZLIB_LIB} - INSTALL_COMMAND "") - install(FILES "${ZLIB_LIB}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/${LIBS_PACKAGE_NAME}" - COMPONENT "libs-deps") - install(FILES ${ZLIB_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${LIBS_PACKAGE_NAME}/zlib" - COMPONENT "libs-deps") - else() - if(BUILD_SHARED_LIBS) - set(ZLIB_LIB_SUFFIX "${CMAKE_SHARED_LIBRARY_SUFFIX}") - set(ZLIB_LIB "${ZLIB_SRC}/lib/zlib${ZLIB_LIB_SUFFIX}") - else() - set(ZLIB_LIB_SUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}") - set(ZLIB_LIB "${ZLIB_SRC}/lib/zlibstatic${ZLIB_LIB_SUFFIX}") - endif() - ExternalProject_Add(zlib - PREFIX "${PROJECT_BINARY_DIR}/zlib-prefix" - URL "https://github.com/madler/zlib/archive/v1.2.13.tar.gz" - URL_HASH "SHA256=1525952a0a567581792613a9723333d7f8cc20b87a81f920fb8bc7e3f2251428" - BUILD_IN_SOURCE 1 - BUILD_BYPRODUCTS ${ZLIB_LIB} - CMAKE_ARGS - -DCMAKE_POLICY_DEFAULT_CMP0091:STRING=NEW - -DCMAKE_MSVC_RUNTIME_LIBRARY=${CMAKE_MSVC_RUNTIME_LIBRARY} - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -DCMAKE_POSITION_INDEPENDENT_CODE=${ENABLE_PIC} - -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} - -DCMAKE_INSTALL_PREFIX=${ZLIB_SRC}) - install(FILES "${ZLIB_LIB}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/${LIBS_PACKAGE_NAME}" - COMPONENT "libs-deps") - install(FILES ${ZLIB_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${LIBS_PACKAGE_NAME}/zlib" - COMPONENT "libs-deps") - endif() - endif() -endif() - -if(NOT TARGET zlib) - add_custom_target(zlib) -endif() - -include_directories(${ZLIB_INCLUDE}) diff --git a/userspace/chisel/chisel.cpp b/userspace/chisel/chisel.cpp index 96521632d5..8b25fe203b 100644 --- a/userspace/chisel/chisel.cpp +++ b/userspace/chisel/chisel.cpp @@ -251,7 +251,7 @@ void chiselinfo::set_callback_precise_interval(uint64_t interval) /////////////////////////////////////////////////////////////////////////////// // chisel implementation /////////////////////////////////////////////////////////////////////////////// -sinsp_chisel::sinsp_chisel(sinsp* inspector, std::string filename, bool is_file) +sinsp_chisel::sinsp_chisel(sinsp* inspector, std::string filename, std::shared_ptr filter_list, bool is_file) { m_inspector = inspector; m_ls = NULL; @@ -261,6 +261,7 @@ sinsp_chisel::sinsp_chisel(sinsp* inspector, std::string filename, bool is_file) m_lua_last_interval_sample_time = 0; m_lua_last_interval_ts = 0; m_udp_socket = 0; + m_filter_check_list = std::move(filter_list); load(filename, is_file); } diff --git a/userspace/chisel/chisel.h b/userspace/chisel/chisel.h index 9d7dac5370..23f30057f6 100644 --- a/userspace/chisel/chisel.h +++ b/userspace/chisel/chisel.h @@ -135,7 +135,7 @@ class chiselinfo class sinsp_chisel { public: - sinsp_chisel(sinsp* inspector, std::string filename, bool is_file = true); + sinsp_chisel(sinsp* inspector, std::string filename, std::shared_ptr filter_list, bool is_file = true); ~sinsp_chisel(); static void add_lua_package_path(lua_State* ls, const std::string& path); diff --git a/userspace/chisel/chisel_api.cpp b/userspace/chisel/chisel_api.cpp index 94a91b69f1..ee55a8f154 100644 --- a/userspace/chisel/chisel_api.cpp +++ b/userspace/chisel/chisel_api.cpp @@ -1152,7 +1152,7 @@ int lua_cbacks::get_container_table(lua_State *ls) // Go through the list // if(ctable != nullptr) { - auto fld_id = ctable->get_field("container_id"); + auto fld_id = ctable->get_field("id"); auto fld_name = ctable->get_field("name"); auto fld_image = ctable->get_field("image"); auto fld_type = ctable->get_field("type"); @@ -1178,6 +1178,9 @@ int lua_cbacks::get_container_table(lua_State *ls) lua_pushliteral(ls, "type"); switch (type) { + case container_type::CT_HOST: + lua_pushstring(ls, ""); + break; case container_type::CT_DOCKER: lua_pushstring(ls, "docker"); break; diff --git a/userspace/sinspui/cursescomponents.cpp b/userspace/sinspui/cursescomponents.cpp index a681e7eeba..a3631be74f 100644 --- a/userspace/sinspui/cursescomponents.cpp +++ b/userspace/sinspui/cursescomponents.cpp @@ -129,7 +129,12 @@ const char* spy_text_renderer::process_event_spy(sinsp_evt* evt, int64_t* len) // // Get and validate the length // - const sinsp_evt_param* parinfo = evt->get_param(0); + const sinsp_evt_param* parinfo; + try { + parinfo = evt->get_param(0); + } catch (...) { + return NULL; + } ASSERT(parinfo->m_len == sizeof(int64_t)); *len = *(int64_t*)parinfo->m_val; if(*len <= 0) diff --git a/userspace/sysdig/CMakeLists.txt b/userspace/sysdig/CMakeLists.txt index cd2e08f4c5..4acbb0300c 100644 --- a/userspace/sysdig/CMakeLists.txt +++ b/userspace/sysdig/CMakeLists.txt @@ -45,12 +45,16 @@ else() endif() list(APPEND SOURCE_FILES + filterchecks/sinsp_filtercheck_syslog.cpp + utils/sinsp_syslog.cpp utils/sinsp_opener.cpp utils/plugin_utils.cpp utils/supported_events.cpp utils/supported_fields.cpp) list(APPEND SOURCE_FILES_CSYSDIG + filterchecks/sinsp_filtercheck_syslog.cpp + utils/sinsp_syslog.cpp utils/sinsp_opener.cpp utils/plugin_utils.cpp utils/supported_events.cpp diff --git a/userspace/sysdig/csysdig.cpp b/userspace/sysdig/csysdig.cpp index 5a8007d4f7..89be2aa506 100644 --- a/userspace/sysdig/csysdig.cpp +++ b/userspace/sysdig/csysdig.cpp @@ -44,6 +44,7 @@ limitations under the License. #include "utils/plugin_utils.h" #include "utils/sinsp_opener.h" #include "utils/supported_fields.h" +#include "filterchecks/sinsp_filtercheck_syslog.h" #ifdef _WIN32 #include "win32/getopt.h" @@ -258,7 +259,8 @@ static void print_views(chisel_view_manager* view_manager) captureinfo do_inspect(sinsp* inspector, uint64_t cnt, sinsp_cursesui* ui, - const chisel_table::output_type& output_type) + const chisel_table::output_type& output_type, + std::shared_ptr syslog_decoder) { captureinfo retval; int32_t res; @@ -279,7 +281,9 @@ captureinfo do_inspect(sinsp* inspector, break; } + syslog_decoder->reset(); res = inspector->next(&ev); + syslog_decoder->parse(ev); if(res == SCAP_TIMEOUT || res == SCAP_FILTERED_EVENT) { @@ -352,6 +356,7 @@ sysdig_init_res csysdig_init(int argc, char **argv) int32_t json_last_row = 0; int32_t sorting_col = -1; bool list_views = false; + std::shared_ptr syslog_decoder = std::make_shared(); #ifndef _WIN32 chisel_table::output_type output_type = chisel_table::OT_CURSES; @@ -643,6 +648,7 @@ sysdig_init_res csysdig_init(int argc, char **argv) // TODO(therealbobo): add plugins filterchecks filter_list = std::make_shared(); + filter_list->add_filter_check(std::make_unique(syslog_decoder)); plugins.init_loaded_plugins(inspector, filter_list.get()); for (auto plugin : inspector->m_plugin_manager->plugins()) @@ -895,10 +901,7 @@ sysdig_init_res csysdig_init(int argc, char **argv) // // Start the capture loop // - cinfo = do_inspect(inspector, - cnt, - &ui, - output_type); + cinfo = do_inspect(inspector, cnt, &ui, output_type, syslog_decoder); if(output_type == chisel_table::OT_JSON) { diff --git a/userspace/sysdig/filterchecks/sinsp_filtercheck_syslog.cpp b/userspace/sysdig/filterchecks/sinsp_filtercheck_syslog.cpp new file mode 100644 index 0000000000..66e708fb35 --- /dev/null +++ b/userspace/sysdig/filterchecks/sinsp_filtercheck_syslog.cpp @@ -0,0 +1,96 @@ +#include "sinsp_filtercheck_syslog.h" +#include +#include + +using namespace std; + +#define RETURN_EXTRACT_VAR(x) \ + do { \ + *len = sizeof((x)); \ + return (uint8_t*)&(x); \ + } while(0) + +#define RETURN_EXTRACT_STRING(x) \ + do { \ + *len = (x).size(); \ + return (uint8_t*)(x).c_str(); \ + } while(0) + +#define RETURN_EXTRACT_CSTR(x) \ + do { \ + if((x)) { \ + *len = strlen((char*)((x))); \ + } \ + return (uint8_t*)((x)); \ + } while(0) + +static const filtercheck_field_info sinsp_filter_check_syslog_fields[] = { + {PT_CHARBUF, EPF_NONE, PF_NA, "syslog.facility.str", "Facility", "facility as a string."}, + {PT_UINT32, + EPF_NONE, + PF_DEC, + "syslog.facility", + "Numeric Facility", + "facility as a number (0-23)."}, + {PT_CHARBUF, + EPF_NONE, + PF_NA, + "syslog.severity.str", + "Severity", + "severity as a string. Can have one of these values: emerg, alert, crit, err, warn, " + "notice, info, debug"}, + {PT_UINT32, + EPF_NONE, + PF_DEC, + "syslog.severity", + "Numeric Severity", + "severity as a number (0-7)."}, + {PT_CHARBUF, EPF_NONE, PF_NA, "syslog.message", "Message", "message sent to syslog."}, +}; + +sinsp_filter_check_syslog::sinsp_filter_check_syslog(std::shared_ptr syslog_decoder) { + static const filter_check_info s_field_infos = { + "syslog", + "", + "Content of Syslog messages.", + sizeof(sinsp_filter_check_syslog_fields) / sizeof(sinsp_filter_check_syslog_fields[0]), + sinsp_filter_check_syslog_fields, + filter_check_info::FL_NONE, + }; + m_info = &s_field_infos; + m_syslog_decoder = syslog_decoder; +} + +std::unique_ptr sinsp_filter_check_syslog::allocate_new() { + return std::make_unique(m_syslog_decoder); +} + +uint8_t* sinsp_filter_check_syslog::extract_single(sinsp_evt* evt, + uint32_t* len, + bool sanitize_strings) { + *len = 0; + if(!m_syslog_decoder->is_data_valid()) { + return NULL; + } + + switch(m_field_id) { + case TYPE_FACILITY: + m_storageu32 = m_syslog_decoder->get_facility(); + RETURN_EXTRACT_VAR(m_storageu32); + case TYPE_FACILITY_STR: + mstrstorage = m_syslog_decoder->get_facility_str(); + RETURN_EXTRACT_STRING(mstrstorage); + case TYPE_SEVERITY: + m_storageu32 = m_syslog_decoder->get_severity(); + RETURN_EXTRACT_VAR(m_storageu32); + case TYPE_SEVERITY_STR: + mstrstorage = m_syslog_decoder->get_severity_str(); + RETURN_EXTRACT_STRING(mstrstorage); + case TYPE_MESSAGE: + mstrstorage = m_syslog_decoder->get_msg(); + RETURN_EXTRACT_STRING(mstrstorage); + default: + ASSERT(false); + return NULL; + } +} diff --git a/userspace/sysdig/filterchecks/sinsp_filtercheck_syslog.h b/userspace/sysdig/filterchecks/sinsp_filtercheck_syslog.h new file mode 100644 index 0000000000..007c979d9a --- /dev/null +++ b/userspace/sysdig/filterchecks/sinsp_filtercheck_syslog.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include "../utils/sinsp_syslog.h" + +class sinsp_filter_check_syslog : public sinsp_filter_check { +public: + enum check_type { + TYPE_FACILITY_STR = 0, + TYPE_FACILITY, + TYPE_SEVERITY_STR, + TYPE_SEVERITY, + TYPE_MESSAGE, + }; + + sinsp_filter_check_syslog(std::shared_ptr syslog_decoder); + virtual ~sinsp_filter_check_syslog() = default; + + std::unique_ptr allocate_new() override; + +protected: + uint8_t* extract_single(sinsp_evt*, uint32_t* len, bool sanitize_strings = true) override; + +private: + uint32_t m_storageu32; + std::string mstrstorage; + std::shared_ptr m_syslog_decoder; +}; diff --git a/userspace/sysdig/sysdig.cpp b/userspace/sysdig/sysdig.cpp index d9faec5cc5..1ba3d31ec6 100644 --- a/userspace/sysdig/sysdig.cpp +++ b/userspace/sysdig/sysdig.cpp @@ -48,6 +48,8 @@ limitations under the License. #include #endif +#include "filterchecks/sinsp_filtercheck_syslog.h" + #include "utils/sinsp_opener.h" #include "utils/plugin_utils.h" #include "utils/supported_events.h" @@ -696,19 +698,15 @@ std::vector split_nextrun_args(std::string na) // // Event processing loop // -captureinfo do_inspect(sinsp* inspector, - sinsp_cycledumper* dumper, - uint64_t cnt, - uint64_t duration_to_tot_ns, - bool quiet, - bool json, - bool do_flush, - bool reset_colors, - bool print_progress, - std::unique_ptr display_filter, - std::vector &summary_table, - sinsp_evt_formatter* syscall_evt_formatter, - sinsp_evt_formatter* plugin_evt_formatter) +captureinfo do_inspect(sinsp *inspector, sinsp_cycledumper *dumper, + uint64_t cnt, uint64_t duration_to_tot_ns, bool quiet, + bool json, bool do_flush, bool reset_colors, + bool print_progress, + std::unique_ptr display_filter, + std::vector &summary_table, + sinsp_evt_formatter *syscall_evt_formatter, + sinsp_evt_formatter *plugin_evt_formatter, + std::shared_ptr syslog_decoder) { captureinfo retval; int32_t res; @@ -745,7 +743,10 @@ captureinfo do_inspect(sinsp* inspector, handle_end_of_file(inspector, print_progress, reset_colors, formatter); break; } + syslog_decoder->reset(); res = inspector->next(&ev); + syslog_decoder->parse(ev); + if(dumper && ev && res != SCAP_EOF) { dumper->dump(ev); @@ -825,9 +826,9 @@ captureinfo do_inspect(sinsp* inspector, #ifdef HAS_CHISELS if(!g_chisels.empty()) { - for(std::vector::iterator it = g_chisels.begin(); it != g_chisels.end(); ++it) + for(const auto& chisel : g_chisels) { - if((*it)->run(ev) == false) + if(chisel->run(ev) == false) { continue; } @@ -1008,6 +1009,7 @@ sysdig_init_res sysdig_init(int argc, char **argv) std::shared_ptr filter_factory; color_term_out color_flag = COLOR; bool user_defined_format = false; + std::shared_ptr syslog_decoder = std::make_shared(); // These variables are for the cycle_writer engine int duration_seconds = 0; @@ -1085,6 +1087,7 @@ sysdig_init_res sysdig_init(int argc, char **argv) inspector->set_hostname_and_port_resolution_mode(false); filter_list.reset(new sinsp_filter_check_list()); + filter_list->add_filter_check(std::make_unique(syslog_decoder)); filter_factory.reset(new sinsp_filter_factory(inspector.get(), *filter_list.get())); #ifdef HAS_CHISELS @@ -1148,6 +1151,7 @@ sysdig_init_res sysdig_init(int argc, char **argv) // TODO(therealbobo): add plugins filterchecks auto filter_list = std::make_shared(); + filter_list->add_filter_check(std::make_unique(syslog_decoder)); for (auto plugin : inspector->m_plugin_manager->plugins()) { @@ -1158,7 +1162,7 @@ sysdig_init_res sysdig_init(int argc, char **argv) } } auto tmp_filter_factory = std::make_shared(inspector.get(), *filter_list.get()); - sinsp_chisel* ch = new sinsp_chisel(inspector.get(), chisel); + sinsp_chisel* ch = new sinsp_chisel(inspector.get(), chisel, filter_list); parse_chisel_args(ch, tmp_filter_factory, optind, argc, argv, &n_filterargs); g_chisels.push_back(ch); } @@ -1701,6 +1705,7 @@ sysdig_init_res sysdig_init(int argc, char **argv) for (auto &ch : g_chisels) { auto filter_list = std::make_shared(); + filter_list->add_filter_check(std::make_unique(syslog_decoder)); for (auto plugin : inspector->m_plugin_manager->plugins()) { @@ -1905,19 +1910,14 @@ sysdig_init_res sysdig_init(int argc, char **argv) // from messing up the output and possibly the shell line after program termination. disable_tty_echo(); #endif - cinfo = do_inspect(inspector.get(), - dumper.get(), - cnt, - uint64_t(duration_to_tot*ONE_SECOND_IN_NS), - quiet, - jflag, - unbuf_flag, - reset_colors, - opener.options.print_progress, - std::move(display_filter), - summary_table, - &syscall_evt_formatter, - &plugin_evt_formatter); + cinfo = do_inspect( + inspector.get(), dumper.get(), cnt, + uint64_t(duration_to_tot * ONE_SECOND_IN_NS), quiet, + jflag, unbuf_flag, reset_colors, + opener.options.print_progress, + std::move(display_filter), summary_table, + &syscall_evt_formatter, &plugin_evt_formatter, + syslog_decoder); duration = ((double)clock()) / CLOCKS_PER_SEC - duration; diff --git a/userspace/sysdig/utils/sinsp_syslog.cpp b/userspace/sysdig/utils/sinsp_syslog.cpp new file mode 100644 index 0000000000..7d36a2ee36 --- /dev/null +++ b/userspace/sysdig/utils/sinsp_syslog.cpp @@ -0,0 +1,109 @@ +#include "sinsp_syslog.h" +#include + +#define PRI_BUF_SIZE 16 + +static const std::string s_syslog_severity_strings[] = + {"emerg", "alert", "crit", "err", "warn", "notice", "info", "debug"}; + +static const std::string s_syslog_facility_strings[] = { + "kern", "user", "mail", "daemon", "auth", "syslog", "lpr", "news", + "uucp", "clock", "authpriv", "ftp", "ntp", "logaudit", "logalert", "cron", + "local0", "local1", "local2", "local3", "local4", "local5", "local6", "local7"}; + +void sinsp_syslog_decoder::parse_data(const char* data, uint32_t len) { + char pri[PRI_BUF_SIZE]; + const char* tc = data + 1; + const char* te = data + len; + uint32_t j = 0; + + while(tc < te && *tc != '>' && *tc != '\0' && j < PRI_BUF_SIZE - 1) { + pri[j++] = *tc; + tc++; + } + + pri[j] = 0; + + decode_message(data, len, pri, j); +} + +std::string sinsp_syslog_decoder::get_severity_str() const { + if(!is_data_valid() || + m_severity >= sizeof(s_syslog_severity_strings) / sizeof(s_syslog_severity_strings[0])) { + return ""; + } else { + return s_syslog_severity_strings[m_severity]; + } +} + +std::string sinsp_syslog_decoder::get_facility_str() const { + if(!is_data_valid() || + m_facility >= sizeof(s_syslog_facility_strings) / sizeof(s_syslog_facility_strings[0])) { + return ""; + } else { + return s_syslog_facility_strings[m_facility]; + } +} + +void sinsp_syslog_decoder::decode_message(const char* data, + uint32_t len, + char* pristr, + uint32_t pristrlen) { + if(len < pristrlen + 2 || pristrlen == 0) { + m_priority = s_invalid_priority; + return; + } + + bool res = sinsp_numparser::tryparsed32_fast(pristr, pristrlen, &m_priority); + + if(!res) { + m_priority = s_invalid_priority; + return; + } + + m_severity = m_priority & 0x07; + m_facility = m_priority >> 3; + + m_msg.assign(data + pristrlen + 2, len - pristrlen - 2); +} + +std::string sinsp_syslog_decoder::get_info_line() const { + if(!is_data_valid()) { + return ""; + } + + return "syslog sev=" + get_severity_str() + " msg=" + m_msg; +} + +void sinsp_syslog_decoder::parse(sinsp_evt* evt) { + if(!evt || !evt->get_fd_info()) { + return; + } + + // Check if this is a syslog fd + if(!evt->get_fd_info()->is_syslog()) { + return; + } + + // Extract the data buffer based on event type + uint16_t etype = evt->get_type(); + const sinsp_evt_param* parinfo = nullptr; + + // Determine which parameter contains the data based on event type + if(etype == PPME_SOCKET_SENDMMSG_X) { + parinfo = evt->get_param(2); + } else if(etype == PPME_SYSCALL_READV_X || etype == PPME_SYSCALL_PREADV_X || + etype == PPME_SOCKET_RECVMSG_X) { + parinfo = evt->get_param(2); + } else if(etype == PPME_SOCKET_RECVMMSG_X) { + parinfo = evt->get_param(3); + } else { + parinfo = evt->get_param(1); + } + + if(parinfo) { + const char* data = parinfo->m_val; + uint32_t datalen = parinfo->m_len; + parse_data(data, datalen); + } +} diff --git a/userspace/sysdig/utils/sinsp_syslog.h b/userspace/sysdig/utils/sinsp_syslog.h new file mode 100644 index 0000000000..0e829fd52e --- /dev/null +++ b/userspace/sysdig/utils/sinsp_syslog.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include + +#include +#include +#include + +class sinsp_syslog_decoder { +public: + void parse_data(const char* data, uint32_t len); + + std::string get_info_line() const; + std::string get_severity_str() const; + std::string get_facility_str() const; + + inline void reset() { m_priority = s_invalid_priority; } + + bool is_data_valid() const { return m_priority != s_invalid_priority; } + + inline int32_t get_priority() const { return m_priority; } + + inline uint32_t get_facility() const { return m_facility; } + + inline uint32_t get_severity() const { return m_severity; } + + inline const std::string& get_msg() const { return m_msg; } + + void parse(sinsp_evt* evt); + +private: + void decode_message(const char* data, uint32_t len, char* pristr, uint32_t pristrlen); + + int32_t m_priority{s_invalid_priority}; + uint32_t m_facility{0}; + uint32_t m_severity{0}; + std::string m_msg; + std::string m_infostr; + + static constexpr const int32_t s_invalid_priority = -1; +};