Falco Bridge: Update to match the current libsinsp API.

The extract_fields struct and calling convention changed, so update to
match. Extract all of our fields at once, which noticeably speeds up
dissection here.
This commit is contained in:
Gerald Combs 2022-03-15 18:09:37 -07:00 committed by A Wireshark GitLab Utility
parent 4f3f507eee
commit 2141f0f03b
3 changed files with 85 additions and 71 deletions

View File

@ -37,6 +37,7 @@
#include <wsutil/file_util.h>
#include <wsutil/filesystem.h>
#include <wsutil/report_message.h>
#include "sinsp-span.h"
#include "conversation-macros.h"
@ -249,9 +250,12 @@ import_plugin(char* fname)
sinsp_span = create_sinsp_span();
if (create_sinsp_source(sinsp_span, fname, &(bi->ssi)) == FALSE) {
char *err_str = create_sinsp_source(sinsp_span, fname, &(bi->ssi));
if (err_str) {
nbridges--;
THROW_FORMATTED(DissectorError, "unable to load sinsp plugin %s.", fname);
report_failure("Unable to load sinsp plugin %s: %s.", fname, err_str);
g_free(err_str);
return;
}
configure_plugin(bi, "");
@ -417,33 +421,38 @@ dissect_sinsp_span(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* da
guint8* payload = (guint8*)tvb_get_ptr(tvb, 0, plen);
sinsp_field_extract_t *sinsp_fields = (sinsp_field_extract_t*) wmem_alloc(pinfo->pool, sizeof(sinsp_field_extract_t) * bi->visible_fields);
for (uint32_t fld_idx = 0; fld_idx < bi->visible_fields; fld_idx++) {
header_field_info* hfinfo = &(bi->hf[fld_idx].hfinfo);
sinsp_field_extract_t sfe;
sinsp_field_extract_t *sfe = &sinsp_fields[fld_idx];
sfe.field_id = bi->field_ids[fld_idx];
sfe.field_name = hfinfo->abbrev;
sfe.type = hfinfo->type == FT_STRINGZ ? SFT_STRINGZ : SFT_UINT64;
sfe->field_id = bi->field_ids[fld_idx];
sfe->field_name = hfinfo->abbrev;
sfe->type = hfinfo->type == FT_STRINGZ ? SFT_STRINGZ : SFT_UINT64;
}
bool rc = extract_sisnp_source_field(bi->ssi, pinfo->num, payload, plen, pinfo->pool, &sfe);
if (!rc) {
REPORT_DISSECTOR_BUG("Falco plugin %s extract error", get_sinsp_source_name(bi->ssi));
}
if (!sfe.is_present) {
// If we have a failure, try to dissect what we can first, then bail out with an error.
bool rc = extract_sisnp_source_fields(bi->ssi, pinfo->num, payload, plen, pinfo->pool, sinsp_fields, bi->visible_fields);
for (uint32_t fld_idx = 0; fld_idx < bi->visible_fields; fld_idx++) {
sinsp_field_extract_t *sfe = &sinsp_fields[fld_idx];
header_field_info* hfinfo = &(bi->hf[fld_idx].hfinfo);
if (!sfe->is_present) {
continue;
}
if (sfe.type == SFT_STRINGZ && hfinfo->type == FT_STRINGZ) {
proto_item *pi = proto_tree_add_string(fb_tree, bi->hf_ids[fld_idx], tvb, 0, plen, sfe.res_str);
if (sfe->type == SFT_STRINGZ && hfinfo->type == FT_STRINGZ) {
proto_item *pi = proto_tree_add_string(fb_tree, bi->hf_ids[fld_idx], tvb, 0, plen, sfe->res_str);
if (bi->field_flags[fld_idx] & BFF_INFO) {
col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "%s", sfe.res_str);
col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "%s", sfe->res_str);
// Mark it hidden, otherwise we end up with a bunch of empty "Info" tree items.
proto_item_set_hidden(pi);
}
if ((bi->field_flags[fld_idx] & BFF_CONVERSATION) != 0) {
char* cvalptr = conv_flt_vals[conv_vals_cnt];
snprintf(cvalptr, MAX_CONV_FILTER_STR_LEN, "%s", sfe.res_str);
snprintf(cvalptr, MAX_CONV_FILTER_STR_LEN, "%s", sfe->res_str);
p_add_proto_data(pinfo->pool,
pinfo,
proto_falco_bridge,
@ -454,15 +463,19 @@ dissect_sinsp_span(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* da
conv_vals_cnt++;
}
}
else if (sfe.type == SFT_UINT64 && hfinfo->type == FT_UINT64) {
proto_tree_add_uint64(fb_tree, bi->hf_ids[fld_idx], tvb, 0, plen, sfe.res_u64);
else if (sfe->type == SFT_UINT64 && hfinfo->type == FT_UINT64) {
proto_tree_add_uint64(fb_tree, bi->hf_ids[fld_idx], tvb, 0, plen, sfe->res_u64);
}
else {
REPORT_DISSECTOR_BUG("field %s has an unrecognized or mismatched type %u != %u",
hfinfo->abbrev, sfe.type, hfinfo->type);
REPORT_DISSECTOR_BUG("Field %s has an unrecognized or mismatched type %u != %u",
hfinfo->abbrev, sfe->type, hfinfo->type);
}
}
if (!rc) {
REPORT_DISSECTOR_BUG("Falco plugin %s extract error", get_sinsp_source_name(bi->ssi));
}
return plen;
}

View File

@ -20,8 +20,6 @@
// epan/address.h and driver/ppm_events_public.h both define PT_NONE, so
// handle libsinsp calls here.
#include <wsutil/wmem/wmem.h>
typedef struct hf_register_info hf_register_info;
typedef struct ss_plugin_info ss_plugin_info;
@ -54,25 +52,32 @@ void destroy_sinsp_span(sinsp_span_t *sinsp_span) {
/*
* Populate a source_plugin_info struct with the symbols coming from a library loaded via libsinsp
*/
bool
char *
create_sinsp_source(sinsp_span_t *sinsp_span, const char* libname, sinsp_source_info_t **ssi_ptr)
{
sinsp_source_info_t *ssi = new(sinsp_source_info_t);
ssi->source = NULL;
sinsp_plugin *sp = sinsp_source_plugin::register_plugin(&sinsp_span->inspector, libname, "{}").get();
if (sp->type() == TYPE_SOURCE_PLUGIN) {
ssi->source = dynamic_cast<sinsp_source_plugin *>(sp);
char *err_str = NULL;
sinsp_source_info_t *ssi = new sinsp_source_info_t();
try {
sinsp_plugin *sp = sinsp_source_plugin::register_plugin(&sinsp_span->inspector, libname, "{}").get();
if (sp->type() == TYPE_SOURCE_PLUGIN) {
ssi->source = dynamic_cast<sinsp_source_plugin *>(sp);
} else {
err_str = g_strdup_printf("%s has unsupported plugin type %d", libname, sp->type());
}
} catch (const sinsp_exception& e) {
err_str = g_strdup_printf("Caught sinsp exception %s", e.what());
}
if (!ssi->source) {
if (err_str) {
delete ssi;
return false;
return err_str;
}
ssi->name = strdup(ssi->source->name().c_str());
ssi->description = strdup(ssi->source->description().c_str());
ssi->last_error = NULL;
*ssi_ptr = ssi;
return true;
return NULL;
}
uint32_t get_sinsp_source_id(sinsp_source_info_t *ssi)
@ -80,21 +85,6 @@ uint32_t get_sinsp_source_id(sinsp_source_info_t *ssi)
return ssi->source->id();
}
uint32_t get_sinsp_source_required_api_version_major(sinsp_source_info_t *ssi)
{
return ssi->source->required_api_version().m_version_major;
}
uint32_t get_sinsp_source_required_api_version_minor(sinsp_source_info_t *ssi)
{
return ssi->source->required_api_version().m_version_minor;
}
uint32_t get_sinsp_source_required_api_version_patch(sinsp_source_info_t *ssi)
{
return ssi->source->required_api_version().m_version_patch;
}
bool init_sinsp_source(sinsp_source_info_t *ssi, const char *config)
{
return ssi->source->init(config);
@ -173,29 +163,42 @@ bool get_sinsp_source_field_info(sinsp_source_info_t *ssi, unsigned field_num, s
return true;
}
bool extract_sisnp_source_field(sinsp_source_info_t *ssi, uint32_t evt_num, uint8_t *evt_data, uint32_t evt_datalen, wmem_allocator_t *pool, sinsp_field_extract_t *sfe)
// The code below, falcosecurity/libs, and falcosecurity/plugins need to be in alignment.
// The Makefile in /plugins defines FALCOSECURITY_LIBS_REVISION and uses that version of
// plugin_info.h. We need to build against a compatible revision of /libs.
bool extract_sisnp_source_fields(sinsp_source_info_t *ssi, uint32_t evt_num, uint8_t *evt_data, uint32_t evt_datalen, wmem_allocator_t *pool, sinsp_field_extract_t *sinsp_fields, uint32_t sinsp_field_len)
{
ss_plugin_event evt = { evt_num, evt_data, evt_datalen, (uint64_t) -1 };
sinsp_plugin::ext_field field;
std::vector<ss_plugin_extract_field> fields;
fields.resize(sinsp_field_len);
// We must supply field_id, field, arg, and type.
field.field_id = sfe->field_id;
field.field = sfe->field_name;
// field.arg = NULL;
field.ftype = sfe->type == SFT_STRINGZ ? PT_CHARBUF : PT_UINT64;
if (!ssi->source->extract_field(evt, field)) {
return false;
}
sfe->is_present = field.field_present;
if (field.field_present) {
if (field.ftype == PT_CHARBUF) {
sfe->res_str = wmem_strdup(pool, field.res_str.c_str());
} else if (field.ftype == PT_UINT64) {
sfe->res_u64 = field.res_u64;
for (size_t i = 0; i < sinsp_field_len; i++) {
fields.at(i).field_id = sinsp_fields[i].field_id;
fields.at(i).field = sinsp_fields[i].field_name;
if (sinsp_fields[i].type == SFT_STRINGZ) {
fields.at(i).ftype = FTYPE_STRING;
} else {
return false;
fields.at(i).ftype = FTYPE_UINT64;
}
}
return true;
bool status = true;
if (!ssi->source->extract_fields(evt, sinsp_field_len, fields.data())) {
status = false;
}
for (size_t i = 0; i < sinsp_field_len; i++) {
sinsp_fields[i].is_present = fields.at(i).res_len > 0;
if (sinsp_fields[i].is_present) {
if (fields.at(i).ftype == PT_CHARBUF) {
sinsp_fields[i].res_str = wmem_strdup(pool, *fields.at(i).res.str);
} else if (fields.at(i).ftype == PT_UINT64) {
sinsp_fields[i].res_u64 = *fields.at(i).res.u64;
} else {
status = false;
}
}
}
return status;
}

View File

@ -15,6 +15,8 @@
#include <stdint.h>
#include <wsutil/wmem/wmem.h>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
@ -58,23 +60,19 @@ typedef struct sinsp_field_extract_t {
sinsp_span_t *create_sinsp_span(void);
void destroy_sinsp_span(sinsp_span_t *sinsp_span);
bool create_sinsp_source(sinsp_span_t *sinsp_span, const char* libname, sinsp_source_info_t **ssi_ptr);
char *create_sinsp_source(sinsp_span_t *sinsp_span, const char* libname, sinsp_source_info_t **ssi_ptr);
// Extractor plugin routines.
// These roughly match common_plugin_info
uint32_t get_sinsp_source_id(sinsp_source_info_t *ssi);
uint32_t get_sinsp_source_required_api_version_major(sinsp_source_info_t *ssi);
uint32_t get_sinsp_source_required_api_version_minor(sinsp_source_info_t *ssi);
uint32_t get_sinsp_source_required_api_version_patch(sinsp_source_info_t *ssi);
bool init_sinsp_source(sinsp_source_info_t *ssi, const char *config);
uint32_t get_sinsp_source_type(sinsp_source_info_t *ssi);
const char *get_sinsp_source_last_error(sinsp_source_info_t *ssi);
//uint32_t get_sinsp_extractor_id(sinsp_span_t *sinsp_span, void *plugin_id);
const char *get_sinsp_source_name(sinsp_source_info_t *ssi);
const char* get_sinsp_source_description(sinsp_source_info_t *ssi);
uint32_t get_sinsp_source_nfields(sinsp_source_info_t *ssi);
bool get_sinsp_source_field_info(sinsp_source_info_t *ssi, unsigned field_num, sinsp_field_info_t *field);
bool extract_sisnp_source_field(sinsp_source_info_t *ssi, uint32_t evt_num, uint8_t *evt_data, uint32_t evt_datalen, wmem_allocator_t *pool, sinsp_field_extract_t *sfe);
bool extract_sisnp_source_fields(sinsp_source_info_t *ssi, uint32_t evt_num, uint8_t *evt_data, uint32_t evt_datalen, wmem_allocator_t *pool, sinsp_field_extract_t *sinsp_fields, uint32_t sinsp_field_len);
#ifdef __cplusplus