falco/userspace/engine/falco_engine.cpp
Mark Stemm f547dc97ab Move falco engine to its own library.
Move the c++ and lua code implementing falco engine/falco common to its
own directory userspace/engine. It's compiled as a static library
libfalco_engine.a, and has its own CMakeLists.txt so it can be included
by other projects.

The engine's CMakeLists.txt has a add_subdirectory for the falco rules
directory, so including the engine also builds the rules.

The variables you need to set to use the engine's CMakeLists.txt are:

- CMAKE_INSTALL_PREFIX: the root directory below which everything is
  installed.
- FALCO_ETC_DIR: where to install the rules file.
- FALCO_SHARE_DIR: where to install lua code, relative to the
- install/package root.
- LUAJIT_INCLUDE: where to find header files for lua.
- FALCO_SINSP_LIBRARY: the library containing sinsp code. It will be
- considered a dependency of the engine.
- LPEG_LIB/LYAML_LIB/LIBYAML_LIB: locations for third-party libraries.
- FALCO_COMPONENT: if set, will be included as a part of any install()
  commands.

Instead of specifying /usr/share/falco in config_falco_*.h.in, use
CMAKE_INSTALL_PREFIX and FALCO_SHARE_DIR.

The lua code for the engine has also moved, so the two lua source
directories (userspace/engine/lua and userspace/falco/lua) need to be
available separately via falco_common, so make it an argument to
falco_common::init.

As a part of making it easy to include in another project, also clean up
LPEG build/defs. Modify build-lpeg to add a PREFIX argument to allow for
object files/libraries being in an alternate location, and when building
lpeg, put object files in a build/ subdirectory.
2016-10-24 15:56:45 -07:00

146 lines
2.9 KiB
C++

#include <string>
#include <fstream>
#include "falco_engine.h"
#include "config_falco_engine.h"
extern "C" {
#include "lpeg.h"
#include "lyaml.h"
}
#include "utils.h"
string lua_on_event = "on_event";
string lua_print_stats = "print_stats";
using namespace std;
falco_engine::falco_engine()
: m_rules(NULL)
{
luaopen_lpeg(m_ls);
luaopen_yaml(m_ls);
falco_common::init(m_lua_main_filename.c_str(), FALCO_ENGINE_SOURCE_LUA_DIR);
falco_rules::init(m_ls);
}
falco_engine::~falco_engine()
{
if (m_rules)
{
delete m_rules;
}
}
void falco_engine::load_rules(const string &rules_content, bool verbose, bool all_events)
{
// The engine must have been given an inspector by now.
if(! m_inspector)
{
throw falco_exception("No inspector provided");
}
if(!m_rules)
{
m_rules = new falco_rules(m_inspector, this, m_ls);
}
m_rules->load_rules(rules_content, verbose, all_events);
}
void falco_engine::load_rules_file(const string &rules_filename, bool verbose, bool all_events)
{
ifstream is;
is.open(rules_filename);
if (!is.is_open())
{
throw falco_exception("Could not open rules filename " +
rules_filename + " " +
"for reading");
}
string rules_content((istreambuf_iterator<char>(is)),
istreambuf_iterator<char>());
load_rules(rules_content, verbose, all_events);
}
void falco_engine::enable_rule(string &pattern, bool enabled)
{
m_evttype_filter.enable(pattern, enabled);
}
falco_engine::rule_result *falco_engine::process_event(sinsp_evt *ev)
{
if(!m_evttype_filter.run(ev))
{
return NULL;
}
struct rule_result *res = new rule_result();
lua_getglobal(m_ls, lua_on_event.c_str());
if(lua_isfunction(m_ls, -1))
{
lua_pushlightuserdata(m_ls, ev);
lua_pushnumber(m_ls, ev->get_check_id());
if(lua_pcall(m_ls, 2, 3, 0) != 0)
{
const char* lerr = lua_tostring(m_ls, -1);
string err = "Error invoking function output: " + string(lerr);
throw falco_exception(err);
}
res->evt = ev;
const char *p = lua_tostring(m_ls, -3);
res->rule = p;
res->priority = lua_tostring(m_ls, -2);
res->format = lua_tostring(m_ls, -1);
}
else
{
throw falco_exception("No function " + lua_on_event + " found in lua compiler module");
}
return res;
}
void falco_engine::describe_rule(string *rule)
{
return m_rules->describe_rule(rule);
}
// Print statistics on the the rules that triggered
void falco_engine::print_stats()
{
lua_getglobal(m_ls, lua_print_stats.c_str());
if(lua_isfunction(m_ls, -1))
{
if(lua_pcall(m_ls, 0, 0, 0) != 0)
{
const char* lerr = lua_tostring(m_ls, -1);
string err = "Error invoking function print_stats: " + string(lerr);
throw falco_exception(err);
}
}
else
{
throw falco_exception("No function " + lua_print_stats + " found in lua rule loader module");
}
}
void falco_engine::add_evttype_filter(string &rule,
list<uint32_t> &evttypes,
sinsp_filter* filter)
{
m_evttype_filter.add(rule, evttypes, filter);
}