diff --git a/userspace/engine/CMakeLists.txt b/userspace/engine/CMakeLists.txt index d6b2b1cf..7ee9a1b9 100644 --- a/userspace/engine/CMakeLists.txt +++ b/userspace/engine/CMakeLists.txt @@ -18,6 +18,7 @@ set(FALCO_ENGINE_SOURCE_FILES json_evt.cpp evttype_index_ruleset.cpp formats.cpp + filter_details_resolver.cpp filter_macro_resolver.cpp filter_warning_resolver.cpp stats_manager.cpp diff --git a/userspace/engine/filter_details_resolver.cpp b/userspace/engine/filter_details_resolver.cpp new file mode 100644 index 00000000..3246ea28 --- /dev/null +++ b/userspace/engine/filter_details_resolver.cpp @@ -0,0 +1,91 @@ +/* +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 "filter_details_resolver.h" + +using namespace libsinsp::filter; + +void filter_details_resolver::run(ast::expr* filter, filter_details& details) +{ + visitor v(details); + filter->accept(&v); +} + +void filter_details_resolver::visitor::visit(ast::and_expr* e) +{ + for(size_t i = 0; i < e->children.size(); i++) + { + e->children[i]->accept(this); + } +} + +void filter_details_resolver::visitor::visit(ast::or_expr* e) +{ + for(size_t i = 0; i < e->children.size(); i++) + { + e->children[i]->accept(this); + } +} + +void filter_details_resolver::visitor::visit(ast::not_expr* e) +{ + e->child->accept(this); +} + +void filter_details_resolver::visitor::visit(ast::list_expr* e) +{ + +} + +void filter_details_resolver::visitor::visit(ast::binary_check_expr* e) +{ + m_details.fields.insert(e->field); + m_details.operators.insert(e->op); + + auto list = dynamic_cast(e->value.get()); + if(list == nullptr) + { + return; + } + + for(const auto& item : list->values) + { + if(m_details.known_lists.find(item) != m_details.known_lists.end()) + { + m_details.lists.insert(item); + } + } +} + +void filter_details_resolver::visitor::visit(ast::unary_check_expr* e) +{ + m_details.fields.insert(e->field); + m_details.operators.insert(e->op); +} + +void filter_details_resolver::visitor::visit(ast::value_expr* e) +{ + auto it = m_details.known_macros.find(e->value); + if(it == m_details.known_macros.end()) + { + return; + } + + m_details.macros.insert(it->first); + + // Recursively visit the macro AST as well + it->second->accept(this); +} \ No newline at end of file diff --git a/userspace/engine/filter_details_resolver.h b/userspace/engine/filter_details_resolver.h new file mode 100644 index 00000000..7dcdeb42 --- /dev/null +++ b/userspace/engine/filter_details_resolver.h @@ -0,0 +1,72 @@ +/* +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 +#include +#include +#include + +struct filter_details +{ + // input macros and lists + std::unordered_map> known_macros; + std::unordered_set known_lists; + + // output details + std::unordered_set fields; + std::unordered_set macros; + std::unordered_set operators; + std::unordered_set lists; +}; + +/*! + \brief Helper class for getting details about rules' filters. +*/ +class filter_details_resolver +{ +public: + /*! + \brief Visits a filter AST and stores details about macros, lists, + fields and operators used. + \param filter The filter AST to be processed. + \param details Helper structure used to state known macros and + lists on input, and to store all the retrieved details as output. + */ + void run(libsinsp::filter::ast::expr* filter, + filter_details& details); + +private: + struct visitor : public libsinsp::filter::ast::expr_visitor + { + visitor(filter_details& details) : m_details(details) {} + visitor(visitor&&) = default; + visitor& operator = (visitor&&) = default; + visitor(const visitor&) = delete; + visitor& operator = (const visitor&) = delete; + + void visit(libsinsp::filter::ast::and_expr* e) override; + void visit(libsinsp::filter::ast::or_expr* e) override; + void visit(libsinsp::filter::ast::not_expr* e) override; + void visit(libsinsp::filter::ast::value_expr* e) override; + void visit(libsinsp::filter::ast::list_expr* e) override; + void visit(libsinsp::filter::ast::unary_check_expr* e) override; + void visit(libsinsp::filter::ast::binary_check_expr* e) override; + + filter_details& m_details; + }; +};