forked from osmocom/wireshark
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:
parent
4f3f507eee
commit
2141f0f03b
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue