210 lines
5.7 KiB
C++
210 lines
5.7 KiB
C++
/* sinsp-span.cpp
|
|
*
|
|
* By Gerald Combs
|
|
* Copyright (C) 2022 Sysdig, Inc.
|
|
*
|
|
* Wireshark - Network traffic analyzer
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
* Copyright 1998 Gerald Combs
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#include <glib.h>
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning(push)
|
|
#pragma warning(disable:4100)
|
|
#pragma warning(disable:4267)
|
|
#endif
|
|
|
|
// epan/address.h and driver/ppm_events_public.h both define PT_NONE, so
|
|
// handle libsinsp calls here.
|
|
|
|
typedef struct hf_register_info hf_register_info;
|
|
|
|
typedef struct ss_plugin_info ss_plugin_info;
|
|
|
|
#include "sinsp-span.h"
|
|
|
|
#include <sinsp.h>
|
|
|
|
typedef struct sinsp_source_info_t {
|
|
sinsp_plugin *source;
|
|
const char *name;
|
|
const char *description;
|
|
char *last_error;
|
|
const char *fields;
|
|
} sinsp_source_info_t;
|
|
|
|
typedef struct sinsp_span_t {
|
|
sinsp inspector;
|
|
} sinsp_span_t;
|
|
|
|
sinsp_span_t *create_sinsp_span()
|
|
{
|
|
return new(sinsp_span_t);
|
|
}
|
|
|
|
void destroy_sinsp_span(sinsp_span_t *sinsp_span) {
|
|
delete(sinsp_span);
|
|
}
|
|
|
|
/*
|
|
* Populate a source_plugin_info struct with the symbols coming from a library loaded via libsinsp
|
|
*/
|
|
char *
|
|
create_sinsp_source(sinsp_span_t *sinsp_span, const char* libname, sinsp_source_info_t **ssi_ptr)
|
|
{
|
|
char *err_str = NULL;
|
|
sinsp_source_info_t *ssi = new sinsp_source_info_t();
|
|
|
|
try {
|
|
sinsp_plugin *sp = sinsp_span->inspector.register_plugin(libname).get();
|
|
if (sp->caps() & CAP_EXTRACTION) {
|
|
ssi->source = dynamic_cast<sinsp_plugin *>(sp);
|
|
} else {
|
|
err_str = g_strdup_printf("%s has unsupported plugin capabilities 0x%02x", libname, sp->caps());
|
|
}
|
|
} catch (const sinsp_exception& e) {
|
|
err_str = g_strdup_printf("Caught sinsp exception %s", e.what());
|
|
}
|
|
|
|
std::string init_err;
|
|
if (!ssi->source->init("{}", init_err)) {
|
|
err_str = g_strdup_printf("Unable to initialize %s: %s", libname, init_err.c_str());
|
|
}
|
|
|
|
if (err_str) {
|
|
delete ssi;
|
|
return err_str;
|
|
}
|
|
|
|
ssi->name = strdup(ssi->source->name().c_str());
|
|
ssi->description = strdup(ssi->source->description().c_str());
|
|
*ssi_ptr = ssi;
|
|
return NULL;
|
|
}
|
|
|
|
uint32_t get_sinsp_source_id(sinsp_source_info_t *ssi)
|
|
{
|
|
return ssi->source->id();
|
|
}
|
|
|
|
const char *get_sinsp_source_last_error(sinsp_source_info_t *ssi)
|
|
{
|
|
if (ssi->last_error) {
|
|
free(ssi->last_error);
|
|
}
|
|
ssi->last_error = strdup(ssi->source->get_last_error().c_str());
|
|
return ssi->last_error;
|
|
}
|
|
|
|
const char *get_sinsp_source_name(sinsp_source_info_t *ssi)
|
|
{
|
|
return ssi->name;
|
|
}
|
|
|
|
const char *get_sinsp_source_description(sinsp_source_info_t *ssi)
|
|
{
|
|
return ssi->description;
|
|
}
|
|
|
|
size_t get_sinsp_source_nfields(sinsp_source_info_t *ssi)
|
|
{
|
|
return ssi->source->fields().size();
|
|
}
|
|
|
|
bool get_sinsp_source_field_info(sinsp_source_info_t *ssi, size_t field_num, sinsp_field_info_t *field)
|
|
{
|
|
if (field_num >= ssi->source->fields().size()) {
|
|
return false;
|
|
}
|
|
|
|
const filtercheck_field_info *ffi = &ssi->source->fields()[field_num];
|
|
|
|
switch (ffi->m_type) {
|
|
case PT_CHARBUF:
|
|
field->type = SFT_STRINGZ;
|
|
break;
|
|
case PT_UINT64:
|
|
field->type = SFT_UINT64;
|
|
break;
|
|
default:
|
|
field->type = SFT_UNKNOWN;
|
|
}
|
|
|
|
switch (ffi->m_print_format) {
|
|
case PF_DEC:
|
|
field->display_format = SFDF_DECIMAL;
|
|
break;
|
|
case PF_HEX:
|
|
field->display_format = SFDF_HEXADECIMAL;
|
|
break;
|
|
case PF_OCT:
|
|
field->display_format = SFDF_OCTAL;
|
|
break;
|
|
default:
|
|
field->display_format = SFDF_UNKNOWN;
|
|
}
|
|
|
|
g_strlcpy(field->abbrev, ffi->m_name, sizeof(ffi->m_name));
|
|
g_strlcpy(field->display, ffi->m_display, sizeof(ffi->m_display));
|
|
g_strlcpy(field->description, ffi->m_description, sizeof(ffi->m_description));
|
|
|
|
field->is_hidden = ffi->m_flags & EPF_TABLE_ONLY;
|
|
field->is_info = ffi->m_flags & EPF_INFO;
|
|
field->is_conversation = ffi->m_flags & EPF_CONVERSATION;
|
|
|
|
return true;
|
|
}
|
|
|
|
// 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 };
|
|
std::vector<ss_plugin_extract_field> fields;
|
|
|
|
fields.resize(sinsp_field_len);
|
|
// We must supply field_id, field, arg, and type.
|
|
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 {
|
|
fields.at(i).ftype = FTYPE_UINT64;
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning(pop)
|
|
#endif
|