From d9a75112a9d05650d05fa1f0566b59409ad66b24 Mon Sep 17 00:00:00 2001 From: Jason Dellaluce Date: Fri, 24 Nov 2023 10:31:54 +0000 Subject: [PATCH] refactor(userspace/libsinsp)!: drop support to protodecoders Signed-off-by: Jason Dellaluce --- userspace/chisel/chisel_utils.cpp | 1 - userspace/libsinsp/CMakeLists.txt | 2 +- userspace/libsinsp/fdinfo.cpp | 68 ---- userspace/libsinsp/fdinfo.h | 58 +-- userspace/libsinsp/parsers.cpp | 117 +------ userspace/libsinsp/parsers.h | 25 +- userspace/libsinsp/protodecoder.cpp | 330 ------------------ userspace/libsinsp/protodecoder.h | 143 -------- userspace/libsinsp/sinsp.cpp | 36 -- userspace/libsinsp/sinsp.h | 24 +- .../libsinsp/sinsp_filtercheck_event.cpp | 24 +- .../libsinsp/sinsp_filtercheck_syslog.cpp | 32 +- userspace/libsinsp/sinsp_filtercheck_syslog.h | 6 +- userspace/libsinsp/sinsp_pd_callback_type.h | 31 -- userspace/libsinsp/sinsp_syslog.cpp | 132 +++++++ userspace/libsinsp/sinsp_syslog.h | 85 +++++ userspace/libsinsp/threadinfo.cpp | 12 - userspace/libsinsp/utils.cpp | 2 - 18 files changed, 257 insertions(+), 871 deletions(-) delete mode 100644 userspace/libsinsp/protodecoder.cpp delete mode 100644 userspace/libsinsp/protodecoder.h delete mode 100644 userspace/libsinsp/sinsp_pd_callback_type.h create mode 100644 userspace/libsinsp/sinsp_syslog.cpp create mode 100644 userspace/libsinsp/sinsp_syslog.h diff --git a/userspace/chisel/chisel_utils.cpp b/userspace/chisel/chisel_utils.cpp index 83b46cbcbf..66ed84d711 100644 --- a/userspace/chisel/chisel_utils.cpp +++ b/userspace/chisel/chisel_utils.cpp @@ -50,7 +50,6 @@ limitations under the License. #include "utils.h" #include "chisel.h" #include "chisel_utils.h" -#include "protodecoder.h" #ifndef PATH_MAX #define PATH_MAX 4096 diff --git a/userspace/libsinsp/CMakeLists.txt b/userspace/libsinsp/CMakeLists.txt index d8979d975b..ba95fea021 100644 --- a/userspace/libsinsp/CMakeLists.txt +++ b/userspace/libsinsp/CMakeLists.txt @@ -118,7 +118,7 @@ set(SINSP_SOURCES plugin_table_api.cpp plugin_filtercheck.cpp prefix_search.cpp - protodecoder.cpp + sinsp_syslog.cpp threadinfo.cpp tuples.cpp sinsp.cpp diff --git a/userspace/libsinsp/fdinfo.cpp b/userspace/libsinsp/fdinfo.cpp index d9f60b718f..090f28e8f6 100644 --- a/userspace/libsinsp/fdinfo.cpp +++ b/userspace/libsinsp/fdinfo.cpp @@ -31,7 +31,6 @@ template<> sinsp_fdinfo_t::sinsp_fdinfo() { m_type = SCAP_FD_UNINITIALIZED; m_flags = FLAGS_NONE; - m_callbacks = NULL; m_usrstate = NULL; m_name = ""; m_name_raw = ""; @@ -47,8 +46,6 @@ template<> void sinsp_fdinfo_t::reset() { m_type = SCAP_FD_UNINITIALIZED; m_flags = FLAGS_NONE; - delete(m_callbacks); - m_callbacks = NULL; m_usrstate = NULL; m_name = ""; m_name_raw = ""; @@ -271,71 +268,6 @@ template<> scap_l4_proto sinsp_fdinfo_t::get_l4proto() } } -template<> void sinsp_fdinfo_t::register_event_callback(sinsp_pd_callback_type etype, sinsp_protodecoder* dec) -{ - if(this->m_callbacks == NULL) - { - m_callbacks = new fd_callbacks_info(); - } - - switch(etype) - { - case CT_READ: - m_callbacks->m_read_callbacks.push_back(dec); - break; - case CT_WRITE: - m_callbacks->m_write_callbacks.push_back(dec); - break; - default: - ASSERT(false); - break; - } - - return; -} - -template<> void sinsp_fdinfo_t::unregister_event_callback(sinsp_pd_callback_type etype, sinsp_protodecoder* dec) -{ - std::vector::iterator it; - - if(m_callbacks == NULL) - { - ASSERT(false); - return; - } - - switch(etype) - { - case CT_READ: - for(it = m_callbacks->m_read_callbacks.begin(); it != m_callbacks->m_read_callbacks.end(); ++it) - { - if(*it == dec) - { - m_callbacks->m_read_callbacks.erase(it); - return; - } - } - - break; - case CT_WRITE: - for(it = m_callbacks->m_write_callbacks.begin(); it != m_callbacks->m_write_callbacks.end(); ++it) - { - if(*it == dec) - { - m_callbacks->m_write_callbacks.erase(it); - return; - } - } - - break; - default: - ASSERT(false); - break; - } - - return; -} - /////////////////////////////////////////////////////////////////////////////// // sinsp_fdtable implementation /////////////////////////////////////////////////////////////////////////////// diff --git a/userspace/libsinsp/fdinfo.h b/userspace/libsinsp/fdinfo.h index 3ce0bf1491..bf07652cef 100644 --- a/userspace/libsinsp/fdinfo.h +++ b/userspace/libsinsp/fdinfo.h @@ -17,7 +17,9 @@ limitations under the License. */ #pragma once -#include "sinsp_pd_callback_type.h" + +#include "tuples.h" + #include #include @@ -27,8 +29,6 @@ limitations under the License. #define CANCELED_FD_NUMBER std::numeric_limits::max() #endif -class sinsp_protodecoder; - // fd type characters #define CHAR_FD_FILE 'f' #define CHAR_FD_IPV4_SOCK '4' @@ -66,13 +66,6 @@ typedef union _sinsp_sockinfo unix_tuple m_unixinfo; ///< The tuple if this a unix socket. }sinsp_sockinfo; -class fd_callbacks_info -{ -public: - std::vector m_write_callbacks; - std::vector m_read_callbacks; -}; - /*! \brief File Descriptor information class. This class contains the full state for a FD, and a bunch of functions to @@ -94,11 +87,6 @@ class SINSP_PUBLIC sinsp_fdinfo ~sinsp_fdinfo() { - if(m_callbacks != NULL) - { - delete m_callbacks; - } - if(m_usrstate != NULL) { delete m_usrstate; @@ -130,27 +118,12 @@ class SINSP_PUBLIC sinsp_fdinfo if(free_state) { - if(m_callbacks != NULL) - { - delete m_callbacks; - } - if(m_usrstate != NULL) { delete m_usrstate; } } - if(other.m_callbacks != NULL) - { - m_callbacks = new fd_callbacks_info(); - *m_callbacks = *other.m_callbacks; - } - else - { - m_callbacks = NULL; - } - if(other.m_usrstate != NULL) { m_usrstate = new T(*other.m_usrstate); @@ -180,6 +153,14 @@ class SINSP_PUBLIC sinsp_fdinfo */ std::string tostring_clean(); + /*! + \brief Return true if this is a log device. + */ + inline bool is_syslog() const + { + return m_name.find("/dev/log") != std::string::npos; + } + /*! \brief Returns true if this is a unix socket. */ @@ -306,16 +287,6 @@ class SINSP_PUBLIC sinsp_fdinfo */ scap_l4_proto get_l4proto(); - /*! - \brief Used by protocol decoders to register callbacks related to this FD. - */ - void register_event_callback(sinsp_pd_callback_type etype, sinsp_protodecoder* dec); - - /*! - \brief Used by protocol decoders to unregister callbacks related to this FD. - */ - void unregister_event_callback(sinsp_pd_callback_type etype, sinsp_protodecoder* dec); - /*! \brief Return true if this FD is a socket server */ @@ -373,11 +344,6 @@ class SINSP_PUBLIC sinsp_fdinfo std::string m_name_raw; // Human readable rendering of this FD. See m_name, only used if fd is a file path. Path is kept "raw" with limited sanitization and without absolute path derivation. std::string m_oldname; // The name of this fd at the beginning of event parsing. Used to detect name changes that result from parsing an event. - inline bool has_decoder_callbacks() - { - return (m_callbacks != NULL); - } - /*! \brief FD flags. */ @@ -518,8 +484,6 @@ class SINSP_PUBLIC sinsp_fdinfo uint32_t m_mount_id; uint64_t m_ino; int64_t m_pid; // only if fd is a pidfd - - fd_callbacks_info* m_callbacks; }; /*@}*/ diff --git a/userspace/libsinsp/parsers.cpp b/userspace/libsinsp/parsers.cpp index 1f91087a05..1dd80e85e5 100644 --- a/userspace/libsinsp/parsers.cpp +++ b/userspace/libsinsp/parsers.cpp @@ -37,7 +37,6 @@ limitations under the License. #include "sinsp_errno.h" #include "filter.h" #include "filterchecks.h" -#include "protodecoder.h" #include "strl.h" #include "plugin_manager.h" #include "sinsp_observer.h" @@ -51,9 +50,6 @@ bool should_drop(sinsp_evt *evt); #include "container_engine/docker/async_source.h" #endif -extern sinsp_protodecoder_list g_decoderlist; -extern sinsp_evttables g_infotables; - sinsp_parser::sinsp_parser(sinsp *inspector) : m_inspector(inspector), m_tmp_evt(m_inspector), @@ -64,18 +60,12 @@ sinsp_parser::sinsp_parser(sinsp *inspector) : sinsp_parser::~sinsp_parser() { - for(uint32_t j = 0; j < m_protodecoders.size(); j++) - { - delete m_protodecoders[j]; - } - while(!m_tmp_events_buffer.empty()) { auto ptr = m_tmp_events_buffer.top(); free(ptr); m_tmp_events_buffer.pop(); } - m_protodecoders.clear(); } void sinsp_parser::set_track_connection_status(bool enabled) @@ -505,6 +495,8 @@ void sinsp_parser::event_cleanup(sinsp_evt *evt) // bool sinsp_parser::reset(sinsp_evt *evt) { + m_syslog_decoder.reset(); + uint16_t etype = evt->get_type(); // // Before anything can happen, the event needs to be @@ -947,48 +939,6 @@ bool sinsp_parser::retrieve_enter_event(sinsp_evt *enter_evt, sinsp_evt *exit_ev return true; } -sinsp_protodecoder* sinsp_parser::add_protodecoder(std::string decoder_name) -{ - // - // Make sure this decoder is not present yet - // - std::vector::iterator it; - for(it = m_protodecoders.begin(); it != m_protodecoders.end(); ++it) - { - if((*it)->get_name() == decoder_name) - { - return (*it); - } - } - - sinsp_protodecoder* nd = g_decoderlist.new_protodecoder_from_name(decoder_name, - m_inspector); - - nd->init(); - - m_protodecoders.push_back(nd); - - return nd; -} - -void sinsp_parser::register_event_callback(sinsp_pd_callback_type etype, sinsp_protodecoder* dec) -{ - switch(etype) - { - case CT_OPEN: - m_open_callbacks.push_back(dec); - break; - case CT_CONNECT: - m_connect_callbacks.push_back(dec); - break; - default: - ASSERT(false); - break; - } - - return; -} - /////////////////////////////////////////////////////////////////////////////// // PARSERS /////////////////////////////////////////////////////////////////////////////// @@ -2852,14 +2802,6 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) // evt->m_fdinfo = evt->m_tinfo->add_fd(fd, &fdi); - // - // Call the protocol decoder callbacks associated to this event - // - std::vector::iterator it; - for(it = m_open_callbacks.begin(); it != m_open_callbacks.end(); ++it) - { - (*it)->on_event(evt, CT_OPEN); - } } if(m_inspector->get_observer() && !(flags & PPM_O_DIRECTORY)) @@ -3475,15 +3417,6 @@ void sinsp_parser::parse_connect_exit(sinsp_evt *evt) fill_client_socket_info(evt, packed_data, force_overwrite_stale_data); - // - // Call the protocol decoder callbacks associated to this event - // - std::vector::iterator it; - for(it = m_connect_callbacks.begin(); it != m_connect_callbacks.end(); ++it) - { - (*it)->on_event(evt, CT_CONNECT); - } - // // If there's a listener callback, invoke it // @@ -4071,16 +4004,6 @@ bool sinsp_parser::update_fd(sinsp_evt *evt, sinsp_evt_param *parinfo) evt->m_fdinfo->set_unix_info(packed_data); evt->m_fdinfo->m_name = ((char*)packed_data) + 17; - // - // Call the protocol decoder callbacks to notify the decoders that this FD - // changed. - // - std::vector::iterator it; - for(it = m_connect_callbacks.begin(); it != m_connect_callbacks.end(); ++it) - { - (*it)->on_event(evt, CT_TUPLE_CHANGE); - } - return true; } @@ -4109,16 +4032,6 @@ bool sinsp_parser::update_fd(sinsp_evt *evt, sinsp_evt_param *parinfo) // m_inspector->m_network_interfaces.update_fd(evt->m_fdinfo); - // - // Call the protocol decoder callbacks to notify the decoders that this FD - // changed. - // - std::vector::iterator it; - for(it = m_connect_callbacks.begin(); it != m_connect_callbacks.end(); ++it) - { - (*it)->on_event(evt, CT_TUPLE_CHANGE); - } - return true; } @@ -4274,19 +4187,6 @@ void sinsp_parser::parse_rw_exit(sinsp_evt *evt) data, (uint32_t)retval, datalen); } - // - // Call the protocol decoder callbacks associated to this event - // - if(evt->m_fdinfo->m_callbacks) - { - std::vector* cbacks = &(evt->m_fdinfo->m_callbacks->m_read_callbacks); - - for(auto it = cbacks->begin(); it != cbacks->end(); ++it) - { - (*it)->on_read(evt, data, datalen); - } - } - // // Check if recvmsg contains ancillary data. If so, we check for SCM_RIGHTS, // which is used to pass FDs between processes, and update the sinsp state @@ -4394,17 +4294,10 @@ void sinsp_parser::parse_rw_exit(sinsp_evt *evt) data, (uint32_t)retval, datalen); } - // - // Call the protocol decoder callbacks associated to this event - // - if(evt->m_fdinfo->m_callbacks) + // perform syslog decoding if applicable + if (evt->m_fdinfo->is_syslog()) { - std::vector* cbacks = &(evt->m_fdinfo->m_callbacks->m_write_callbacks); - - for(auto it = cbacks->begin(); it != cbacks->end(); ++it) - { - (*it)->on_write(evt, data, datalen); - } + m_syslog_decoder.parse_data(data, datalen); } } } else if (m_track_connection_status) { diff --git a/userspace/libsinsp/parsers.h b/userspace/libsinsp/parsers.h index d80f208680..ea233bfcf5 100644 --- a/userspace/libsinsp/parsers.h +++ b/userspace/libsinsp/parsers.h @@ -21,6 +21,7 @@ limitations under the License. //////////////////////////////////////////////////////////////////////////// #pragma once #include "sinsp.h" +#include "sinsp_syslog.h" class sinsp_parser { @@ -46,21 +47,14 @@ class sinsp_parser // static void parse_dirfd(sinsp_evt *evt, const char* name, int64_t dirfd, OUT std::string* sdir); - // - // Protocol decoder infrastructure methods - // - sinsp_protodecoder* add_protodecoder(std::string decoder_name); - void register_event_callback(sinsp_pd_callback_type etype, sinsp_protodecoder* dec); - - // - // Protocol decoders callback lists - // - std::vector m_open_callbacks; - std::vector m_connect_callbacks; - void set_track_connection_status(bool enabled); bool get_track_connection_status() { return m_track_connection_status; } + inline sinsp_syslog_decoder& get_syslog_decoder() + { + return m_syslog_decoder; + } + private: // // Helpers @@ -155,15 +149,10 @@ class sinsp_parser bool m_track_connection_status = false; - // - // The protocol decoders allocated by this parser - // - std::vector m_protodecoders; - std::stack m_tmp_events_buffer; // caches the index of the "syscall" event source size_t m_syscall_event_source_idx; - friend class sinsp_protodecoder; + sinsp_syslog_decoder m_syslog_decoder; }; diff --git a/userspace/libsinsp/protodecoder.cpp b/userspace/libsinsp/protodecoder.cpp deleted file mode 100644 index f54303d9ad..0000000000 --- a/userspace/libsinsp/protodecoder.cpp +++ /dev/null @@ -1,330 +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. - -*/ - -#include -#ifndef _WIN32 -#include -#endif -#include "sinsp.h" -#include "sinsp_int.h" -#include "protodecoder.h" - -extern sinsp_protodecoder_list g_decoderlist; - -/////////////////////////////////////////////////////////////////////////////// -// sinsp_protodecoder implementation -/////////////////////////////////////////////////////////////////////////////// -sinsp_protodecoder::sinsp_protodecoder() -{ -} - -void sinsp_protodecoder::set_inspector(sinsp* inspector) -{ - m_inspector = inspector; -} - -void sinsp_protodecoder::on_read(sinsp_evt* evt, char *data, uint32_t len) -{ - ASSERT(false); -} - -void sinsp_protodecoder::on_write(sinsp_evt* evt, char *data, uint32_t len) -{ - ASSERT(false); -} - -void sinsp_protodecoder::on_reset(sinsp_evt* evt) -{ - ASSERT(false); -} - -void sinsp_protodecoder::register_event_callback(sinsp_pd_callback_type etype) -{ - ASSERT(m_inspector != NULL); - - m_inspector->m_parser->register_event_callback(etype, this); -} - -void sinsp_protodecoder::register_read_callback(sinsp_fdinfo_t* fdinfo) -{ - ASSERT(m_inspector != NULL); - - fdinfo->register_event_callback(CT_READ, this); -} - -void sinsp_protodecoder::register_write_callback(sinsp_fdinfo_t* fdinfo) -{ - ASSERT(m_inspector != NULL); - - fdinfo->register_event_callback(CT_WRITE, this); -} - -void sinsp_protodecoder::unregister_read_callback(sinsp_fdinfo_t* fdinfo) -{ - ASSERT(m_inspector != NULL); - - fdinfo->unregister_event_callback(CT_READ, this); -} - -void sinsp_protodecoder::unregister_write_callback(sinsp_fdinfo_t* fdinfo) -{ - ASSERT(m_inspector != NULL); - - fdinfo->unregister_event_callback(CT_WRITE, this); -} - -/////////////////////////////////////////////////////////////////////////////// -// sinsp_protodecoder_list implementation -/////////////////////////////////////////////////////////////////////////////// -sinsp_protodecoder_list::sinsp_protodecoder_list() -{ - ////////////////////////////////////////////////////////////////////////////// - // ADD NEW DECODER CLASSES HERE - ////////////////////////////////////////////////////////////////////////////// - add_protodecoder(new sinsp_decoder_syslog()); -} - -sinsp_protodecoder_list::~sinsp_protodecoder_list() -{ - uint32_t j; - - for(j = 0; j < m_decoders_list.size(); j++) - { - delete m_decoders_list[j]; - } -} - -void sinsp_protodecoder_list::add_protodecoder(sinsp_protodecoder* protodecoder) -{ - m_decoders_list.push_back(protodecoder); -} - -sinsp_protodecoder* sinsp_protodecoder_list::new_protodecoder_from_name(const std::string& name, - sinsp* inspector) -{ - uint32_t j; - - for(j = 0; j < m_decoders_list.size(); j++) - { - m_decoders_list[j]->m_inspector = inspector; - - if(m_decoders_list[j]->m_name == name) - { - sinsp_protodecoder* newchk = m_decoders_list[j]->allocate_new(); - newchk->set_inspector(inspector); - return newchk; - } - } - - throw sinsp_exception("unknown protocol decoder " + name); -} - -/////////////////////////////////////////////////////////////////////////////// -// sinsp_decoder_syslog implementation -/////////////////////////////////////////////////////////////////////////////// -const char* syslog_severity_strings[] = -{ - "emerg", "alert", "crit", "err", "warn", "notice", "info", "debug" -}; - -const char* 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" -}; - -sinsp_decoder_syslog::sinsp_decoder_syslog() -{ - m_name = "syslog"; - m_priority = -1; -} - -sinsp_protodecoder* sinsp_decoder_syslog::allocate_new() -{ - return (sinsp_protodecoder*) new sinsp_decoder_syslog(); -} - -void sinsp_decoder_syslog::init() -{ - register_event_callback(CT_OPEN); - register_event_callback(CT_CONNECT); -} - -void sinsp_decoder_syslog::on_fd_from_proc(sinsp_fdinfo_t* fdinfo) -{ - if(fdinfo == NULL) - { - ASSERT(false); - return ; - } - - if(fdinfo->m_name.find("/dev/log") != std::string::npos) - { - register_write_callback(fdinfo); - } -} - -void sinsp_decoder_syslog::on_event(sinsp_evt* evt, sinsp_pd_callback_type etype) -{ - if(etype == CT_OPEN || - etype == CT_CONNECT) - { - sinsp_fdinfo_t* fdinfo = evt->get_fd_info(); - if(fdinfo == NULL) - { - return ; - } - - if(fdinfo->m_name.find("/dev/log") != std::string::npos) - { - register_write_callback(fdinfo); - } - } - else if(etype == CT_TUPLE_CHANGE) - { - sinsp_fdinfo_t* fdinfo = evt->get_fd_info(); - if(fdinfo == NULL) - { - return ; - } - - if(fdinfo->m_name.find("/dev/log") != std::string::npos) - { - register_write_callback(fdinfo); - } - else - { - if(fdinfo->has_decoder_callbacks()) - { - unregister_write_callback(fdinfo); - } - } - } - else - { - ASSERT(false); - } -} - -#define PRI_BUF_SIZE 16 - -void sinsp_decoder_syslog::on_write(sinsp_evt* evt, char *data, uint32_t len) -{ - char pri[PRI_BUF_SIZE]; - char* tc = data + 1; - 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); -} - -void sinsp_decoder_syslog::on_reset(sinsp_evt* evt) -{ - m_priority = -1; -} - -bool sinsp_decoder_syslog::is_data_valid() -{ - return (m_priority != -1); -} - -const char* sinsp_decoder_syslog::get_severity_str() -{ - if(m_severity >= sizeof(syslog_severity_strings) / sizeof(syslog_severity_strings[0])) - { - return ""; - } - else - { - return syslog_severity_strings[m_severity]; - } -} - -const char* sinsp_decoder_syslog::get_facility_str() -{ - if(m_facility >= sizeof(syslog_facility_strings) / sizeof(syslog_facility_strings[0])) - { - return ""; - } - else - { - return syslog_facility_strings[m_facility]; - } -} - -void sinsp_decoder_syslog::decode_message(char *data, uint32_t len, char* pristr, uint32_t pristrlen) -{ - if(len < pristrlen + 2 || pristrlen == 0) - { - m_priority = -1; - return; - } - - bool res = sinsp_numparser::tryparsed32_fast(pristr, pristrlen, &m_priority); - - if(!res) - { - m_priority = -1; - return; - } - - m_severity = m_priority & 0x07; - m_facility = m_priority >> 3; - - m_msg.assign(data + pristrlen + 2, len - pristrlen - 2); - - m_inspector->protodecoder_register_reset(this); -} - -bool sinsp_decoder_syslog::get_info_line(char** res) -{ - m_infostr = std::string("syslog sev=") + get_severity_str() + " msg=" + m_msg; - - *res = (char*)m_infostr.c_str(); - return (m_priority != -1); -} diff --git a/userspace/libsinsp/protodecoder.h b/userspace/libsinsp/protodecoder.h deleted file mode 100644 index 17b4b83b78..0000000000 --- a/userspace/libsinsp/protodecoder.h +++ /dev/null @@ -1,143 +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. - -*/ - -#pragma once - -/////////////////////////////////////////////////////////////////////////////// -// The protocol decoder interface -/////////////////////////////////////////////////////////////////////////////// -class sinsp_protodecoder -{ -public: - sinsp_protodecoder(); - - virtual ~sinsp_protodecoder() - { - } - - // - // Allocate a new decoder of the same type. - // Every protodecoder plugin must implement this. - // - virtual sinsp_protodecoder* allocate_new() = 0; - - // - // Allocate a new decoder of the same type. - // Every protodecoder plugin must implement this. - // - virtual void init() = 0; - - // - // Return the protocol decoder name - // - const std::string& get_name() - { - return m_name; - } - - // - // Called by the engine for each of the FDs that are added from proc - // (or from the file) at the beginning of a capture. - // - virtual void on_fd_from_proc(sinsp_fdinfo_t* fdinfo) = 0; - - // - // Called by the engine after an event has been received and parsed. - // - virtual void on_event(sinsp_evt* evt, sinsp_pd_callback_type etype) = 0; - - // - // These are not part of on_event for performance reasons - // - virtual void on_read(sinsp_evt* evt, char *data, uint32_t len); - virtual void on_write(sinsp_evt* evt, char *data, uint32_t len); - virtual void on_reset(sinsp_evt* evt); - - // - // Used by the engine to retrieve the info line for the last event. - // Must return true if the line is valid. - // - virtual bool get_info_line(char** res) = 0; - -protected: - // - // Interface for the plugins - // - void register_event_callback(sinsp_pd_callback_type etype); - void register_read_callback(sinsp_fdinfo_t* fdinfo); - void register_write_callback(sinsp_fdinfo_t* fdinfo); - - void unregister_read_callback(sinsp_fdinfo_t* fdinfo); - void unregister_write_callback(sinsp_fdinfo_t* fdinfo); - - std::string m_name; - sinsp* m_inspector; - -private: - void set_inspector(sinsp* inspector); - -friend class sinsp_protodecoder_list; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Global class that stores the list of protocol decoders and offers -// functions to work with it. -/////////////////////////////////////////////////////////////////////////////// -class sinsp_protodecoder_list -{ -public: - sinsp_protodecoder_list(); - ~sinsp_protodecoder_list(); - void add_protodecoder(sinsp_protodecoder* protodecoder); - sinsp_protodecoder* new_protodecoder_from_name(const std::string& name, sinsp* inspector); - -private: - std::vector m_decoders_list; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Decoder classes -// NOTE: these should be moved to a separate file but, since we have only one -// for the moment, we keep it here -/////////////////////////////////////////////////////////////////////////////// -class sinsp_decoder_syslog : public sinsp_protodecoder -{ -public: - sinsp_decoder_syslog(); - sinsp_protodecoder* allocate_new(); - void init(); - void on_fd_from_proc(sinsp_fdinfo_t* fdinfo); - void on_event(sinsp_evt* evt, sinsp_pd_callback_type etype); - void on_write(sinsp_evt* evt, char *data, uint32_t len); - void on_reset(sinsp_evt* evt); - bool get_info_line(char** res); - - bool is_data_valid(); - - const char* get_severity_str(); - const char* get_facility_str(); - - int32_t m_priority; - uint32_t m_facility; - uint32_t m_severity; - std::string m_msg; - -private: - void decode_message(char *data, uint32_t len, char* pristr, uint32_t pristrlen); - std::string m_infostr; -}; diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index fb2fedae34..57ac0cfba6 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -36,7 +36,6 @@ limitations under the License. #include "filter.h" #include "filterchecks.h" #include "cyclewriter.h" -#include "protodecoder.h" #include "dns_manager.h" #include "plugin.h" #include "plugin_manager.h" @@ -212,11 +211,6 @@ sinsp::~sinsp() #endif } -void sinsp::add_protodecoders() -{ - m_parser->add_protodecoder("syslog"); -} - bool sinsp::is_initialstate_event(scap_evt* pevent) { return pevent->type == PPME_CONTAINER_E || @@ -297,12 +291,6 @@ void sinsp::init() ASSERT(false); } - // - // Attach the protocol decoders - // -#ifndef HAS_ANALYZER - add_protodecoders(); -#endif // // Allocate the cycle writer // @@ -1340,20 +1328,6 @@ int32_t sinsp::next(OUT sinsp_evt **puevt) { evt = &m_evt; - // - // Reset previous event's decoders if required - // - if(m_decoders_reset_list.size() != 0) - { - std::vector::iterator it; - for(it = m_decoders_reset_list.begin(); it != m_decoders_reset_list.end(); ++it) - { - (*it)->on_reset(evt); - } - - m_decoders_reset_list.clear(); - } - // fetch the next event res = fetch_next_event(evt); @@ -2138,16 +2112,6 @@ void sinsp::set_max_evt_output_len(uint32_t len) m_max_evt_output_len = len; } -sinsp_protodecoder* sinsp::require_protodecoder(std::string decoder_name) -{ - return m_parser->add_protodecoder(decoder_name); -} - -void sinsp::protodecoder_register_reset(sinsp_protodecoder* dec) -{ - m_decoders_reset_list.push_back(dec); -} - sinsp_parser* sinsp::get_parser() { return m_parser; diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index f602301978..12971392cd 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -90,7 +90,6 @@ limitations under the License. #include "threadinfo.h" #include "ifinfo.h" #include "eventformatter.h" -#include "sinsp_pd_callback_type.h" #include "include/sinsp_external_processor.h" #include "plugin.h" @@ -103,7 +102,6 @@ class sinsp_parser; class sinsp_analyzer; class sinsp_filter; class cycle_writer; -class sinsp_protodecoder; class sinsp_plugin; class sinsp_plugin_manager; class sinsp_observer; @@ -804,20 +802,6 @@ class SINSP_PUBLIC sinsp : public capture_stats_source return m_print_container_data; } - /*! - \brief Lets a filter plugin request a protocol decoder. - - \param the name of the required decoder - */ - sinsp_protodecoder* require_protodecoder(std::string decoder_name); - - /*! - \brief Lets a filter plugin request a protocol decoder. - - \param the name of the required decoder - */ - void protodecoder_register_reset(sinsp_protodecoder* dec); - /*! \brief If this is an offline capture, return the name of the file that is being read, otherwise return an empty string. @@ -1023,7 +1007,6 @@ VISIBILITY_PRIVATE bool is_initialstate_event(scap_evt* pevent); void import_ifaddr_list(); void import_user_list(); - void add_protodecoders(); void remove_thread(int64_t tid); int32_t fetch_next_event(sinsp_evt*& evt); @@ -1182,11 +1165,6 @@ VISIBILITY_PRIVATE // bool m_isdropping; - // - // Protocol decoding state - // - std::vector m_decoders_reset_list; - // // meta event management for other sources like k8s, mesos. // @@ -1349,7 +1327,7 @@ VISIBILITY_PRIVATE friend class sinsp_dumper; friend class sinsp_chisel; friend class sinsp_filter_check_event; - friend class sinsp_protodecoder; + friend class sinsp_filter_check_syslog; friend class lua_cbacks; friend class sinsp_filter_check_container; friend class sinsp_worker; diff --git a/userspace/libsinsp/sinsp_filtercheck_event.cpp b/userspace/libsinsp/sinsp_filtercheck_event.cpp index b12213a21d..d24ff5a29c 100644 --- a/userspace/libsinsp/sinsp_filtercheck_event.cpp +++ b/userspace/libsinsp/sinsp_filtercheck_event.cpp @@ -23,7 +23,6 @@ limitations under the License. #include "sinsp_int.h" #include "plugin.h" #include "plugin_manager.h" -#include "protodecoder.h" #include "value_parser.h" using namespace std; @@ -1120,20 +1119,10 @@ uint8_t* sinsp_filter_check_event::extract(sinsp_evt *evt, OUT uint32_t* len, bo break; case TYPE_INFO: { - sinsp_fdinfo_t* fdinfo = evt->m_fdinfo; - - if(fdinfo != NULL && fdinfo->m_callbacks != NULL) + if(m_inspector->m_parser->get_syslog_decoder().is_data_valid()) { - char* il; - vector* cbacks = &(fdinfo->m_callbacks->m_write_callbacks); - - for(auto it = cbacks->begin(); it != cbacks->end(); ++it) - { - if((*it)->get_info_line(&il)) - { - RETURN_EXTRACT_CSTR(il); - } - } + // syslog is actually the only info line we support up until now + RETURN_EXTRACT_STRING(m_inspector->m_parser->get_syslog_decoder().get_info_line()); } } // @@ -1426,12 +1415,9 @@ uint8_t* sinsp_filter_check_event::extract(sinsp_evt *evt, OUT uint32_t* len, bo { sinsp_fdinfo_t* fdinfo = evt->m_fdinfo; - if(fdinfo != NULL) + if(fdinfo != NULL && fdinfo->is_syslog()) { - if(fdinfo->m_name.find("/dev/log") != string::npos) - { - m_u32val = 1; - } + m_u32val = 1; } } diff --git a/userspace/libsinsp/sinsp_filtercheck_syslog.cpp b/userspace/libsinsp/sinsp_filtercheck_syslog.cpp index 5ff2ea69f4..cad51d0fb1 100644 --- a/userspace/libsinsp/sinsp_filtercheck_syslog.cpp +++ b/userspace/libsinsp/sinsp_filtercheck_syslog.cpp @@ -19,7 +19,6 @@ limitations under the License. #include "sinsp_filtercheck_syslog.h" #include "sinsp.h" #include "sinsp_int.h" -#include "protodecoder.h" using namespace std; @@ -56,7 +55,6 @@ sinsp_filter_check_syslog::sinsp_filter_check_syslog() m_info.m_desc = "Content of Syslog messages."; m_info.m_fields = sinsp_filter_check_syslog_fields; m_info.m_nfields = sizeof(sinsp_filter_check_syslog_fields) / sizeof(sinsp_filter_check_syslog_fields[0]); - m_decoder = NULL; } sinsp_filter_check* sinsp_filter_check_syslog::allocate_new() @@ -64,23 +62,11 @@ sinsp_filter_check* sinsp_filter_check_syslog::allocate_new() return (sinsp_filter_check*) new sinsp_filter_check_syslog(); } -int32_t sinsp_filter_check_syslog::parse_field_name(const char* str, bool alloc_state, bool needed_for_filtering) -{ - int32_t res = sinsp_filter_check::parse_field_name(str, alloc_state, needed_for_filtering); - if(res != -1) - { - m_decoder = (sinsp_decoder_syslog*)m_inspector->require_protodecoder("syslog"); - } - - return res; -} - uint8_t* sinsp_filter_check_syslog::extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { *len = 0; - const char *str; - ASSERT(m_decoder != NULL); - if(!m_decoder->is_data_valid()) + auto& decoder = m_inspector->m_parser->get_syslog_decoder(); + if (!decoder.is_data_valid()) { return NULL; } @@ -88,17 +74,17 @@ uint8_t* sinsp_filter_check_syslog::extract(sinsp_evt *evt, OUT uint32_t* len, b switch(m_field_id) { case TYPE_FACILITY: - RETURN_EXTRACT_VAR(m_decoder->m_facility); + m_storageu32 = decoder.get_facility(); + RETURN_EXTRACT_VAR(m_storageu32); case TYPE_FACILITY_STR: - str = m_decoder->get_facility_str(); - RETURN_EXTRACT_CSTR(str); + RETURN_EXTRACT_STRING(decoder.get_facility_str()); case TYPE_SEVERITY: - RETURN_EXTRACT_VAR(m_decoder->m_severity); + m_storageu32 = decoder.get_severity(); + RETURN_EXTRACT_VAR(m_storageu32); case TYPE_SEVERITY_STR: - str = m_decoder->get_severity_str(); - RETURN_EXTRACT_CSTR(str); + RETURN_EXTRACT_STRING(decoder.get_severity_str()); case TYPE_MESSAGE: - RETURN_EXTRACT_STRING(m_decoder->m_msg); + RETURN_EXTRACT_STRING(decoder.get_msg()); default: ASSERT(false); return NULL; diff --git a/userspace/libsinsp/sinsp_filtercheck_syslog.h b/userspace/libsinsp/sinsp_filtercheck_syslog.h index b86d9d8609..3ca7981c84 100644 --- a/userspace/libsinsp/sinsp_filtercheck_syslog.h +++ b/userspace/libsinsp/sinsp_filtercheck_syslog.h @@ -20,8 +20,6 @@ limitations under the License. #include "sinsp_filtercheck.h" -class sinsp_decoder_syslog; - class sinsp_filter_check_syslog : public sinsp_filter_check { public: @@ -36,10 +34,8 @@ class sinsp_filter_check_syslog : public sinsp_filter_check sinsp_filter_check_syslog(); sinsp_filter_check* allocate_new(); - int32_t parse_field_name(const char* str, bool alloc_state, bool needed_for_filtering); uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true); - sinsp_decoder_syslog* m_decoder; - uint32_t m_gid; + uint32_t m_storageu32; std::string m_name; }; diff --git a/userspace/libsinsp/sinsp_pd_callback_type.h b/userspace/libsinsp/sinsp_pd_callback_type.h deleted file mode 100644 index c207013cba..0000000000 --- a/userspace/libsinsp/sinsp_pd_callback_type.h +++ /dev/null @@ -1,31 +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. - -*/ - -#pragma once - -// -// Protocol decoder callback type -// -typedef enum sinsp_pd_callback_type -{ - CT_OPEN, - CT_CONNECT, - CT_READ, - CT_WRITE, - CT_TUPLE_CHANGE, -}sinsp_pd_callback_type; diff --git a/userspace/libsinsp/sinsp_syslog.cpp b/userspace/libsinsp/sinsp_syslog.cpp new file mode 100644 index 0000000000..7143ea8af0 --- /dev/null +++ b/userspace/libsinsp/sinsp_syslog.cpp @@ -0,0 +1,132 @@ +// 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. + +*/ + +#include "sinsp_syslog.h" +#include "utils.h" + +#define PRI_BUF_SIZE 16 + +static std::string s_syslog_severity_strings[] = +{ + "emerg", "alert", "crit", "err", "warn", "notice", "info", "debug" +}; + +static 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(char *data, uint32_t len) +{ + char pri[PRI_BUF_SIZE]; + char* tc = data + 1; + 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); +} + +const 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]; + } +} + +const 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(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); +} + +const std::string& sinsp_syslog_decoder::get_info_line() +{ + if (!is_data_valid()) + { + m_infostr = ""; + } + else + { + m_infostr = std::string("syslog sev=") + get_severity_str() + " msg=" + m_msg; + } + return m_infostr; +} diff --git a/userspace/libsinsp/sinsp_syslog.h b/userspace/libsinsp/sinsp_syslog.h new file mode 100644 index 0000000000..4e9a665c84 --- /dev/null +++ b/userspace/libsinsp/sinsp_syslog.h @@ -0,0 +1,85 @@ +// 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. + +*/ + +#pragma once + +#include "sinsp_exception.h" + +#include +#include +#include + +class sinsp_syslog_decoder +{ +public: + sinsp_syslog_decoder() = default; + ~sinsp_syslog_decoder() = default; + sinsp_syslog_decoder(sinsp_syslog_decoder&&) = default; + sinsp_syslog_decoder& operator = (sinsp_syslog_decoder&&) = default; + sinsp_syslog_decoder(const sinsp_syslog_decoder& s) = default; + sinsp_syslog_decoder& operator = (const sinsp_syslog_decoder& s) = default; + + void parse_data(char *data, uint32_t len); + + const std::string& get_info_line(); + + const std::string& get_severity_str() const; + + 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; + } + +private: + void decode_message(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; +}; diff --git a/userspace/libsinsp/threadinfo.cpp b/userspace/libsinsp/threadinfo.cpp index 34065b687e..dec8e4b78d 100644 --- a/userspace/libsinsp/threadinfo.cpp +++ b/userspace/libsinsp/threadinfo.cpp @@ -26,7 +26,6 @@ limitations under the License. #include "strl.h" #include "sinsp.h" #include "sinsp_int.h" -#include "protodecoder.h" #include "scap-int.h" constexpr static const char* s_thread_table_name = "threads"; @@ -381,17 +380,6 @@ void sinsp_threadinfo::add_fd_from_scap(scap_fdinfo *fdi, OUT sinsp_fdinfo_t *re break; } - // - // Call the protocol decoder callbacks associated to notify them about this FD - // - ASSERT(m_inspector != NULL); - std::vector::iterator it; - - for(it = m_inspector->m_parser->m_open_callbacks.begin(); - it != m_inspector->m_parser->m_open_callbacks.end(); ++it) - { - (*it)->on_fd_from_proc(newfdi); - } // // Add the FD to the table diff --git a/userspace/libsinsp/utils.cpp b/userspace/libsinsp/utils.cpp index 8055e29602..28f04584b0 100644 --- a/userspace/libsinsp/utils.cpp +++ b/userspace/libsinsp/utils.cpp @@ -49,7 +49,6 @@ limitations under the License. #include "filter.h" #include "filter_check_list.h" #include "filterchecks.h" -#include "protodecoder.h" #include "strl.h" #if !defined(_WIN32) && !defined(MINIMAL_BUILD) && !defined(__EMSCRIPTEN__) #include "curl/curl.h" @@ -69,7 +68,6 @@ limitations under the License. sinsp_evttables g_infotables; sinsp_logger g_logger; sinsp_initializer g_initializer; -sinsp_protodecoder_list g_decoderlist; // // loading time initializations