sysdig: support the most recent version of sysdig

Update the pcap-ng reader and sysdig event dissector to support the second version of the sysdig event block, which was introduced after Wireshark's original implementation
This commit is contained in:
Loris Degioanni 2021-04-05 22:16:09 -07:00 committed by Guy Harris
parent b258f90ce5
commit fbe8d3a00f
4 changed files with 42 additions and 16 deletions

View File

@ -50,6 +50,7 @@ static int proto_sysdig_event = -1;
static int hf_se_cpu_id = -1;
static int hf_se_thread_id = -1;
static int hf_se_event_length = -1;
static int hf_se_nparams = -1;
static int hf_se_event_type = -1;
static int hf_se_param_lens = -1;
@ -2084,37 +2085,35 @@ static inline const gchar *format_param_str(tvbuff_t *tvb, int offset, int len)
/* Code to actually dissect the packets */
static int
dissect_header_lens(tvbuff_t *tvb, int offset, proto_tree *tree, int encoding, int * const *hf_indexes)
dissect_header_lens(tvbuff_t *tvb, wtap_syscall_header* syscall_header, int offset, proto_tree *tree, int encoding)
{
int param_count;
guint32 param_count;
proto_item *ti;
proto_tree *len_tree;
for (param_count = 0; hf_indexes[param_count]; param_count++);
ti = proto_tree_add_item(tree, hf_se_param_lens, tvb, offset, param_count * 2, ENC_NA);
ti = proto_tree_add_item(tree, hf_se_param_lens, tvb, offset, syscall_header->nparams * 2, ENC_NA);
len_tree = proto_item_add_subtree(ti, ett_sysdig_parm_lens);
for (param_count = 0; hf_indexes[param_count]; param_count++) {
for (param_count = 0; param_count < syscall_header->nparams; param_count++) {
proto_tree_add_item(len_tree, hf_se_param_len, tvb, offset + (param_count * 2), 2, encoding);
}
proto_item_set_len(ti, param_count * 2);
return param_count * 2;
proto_item_set_len(ti, syscall_header->nparams * 2);
return syscall_header->nparams * 2;
}
/* Dissect events */
static int
dissect_event_params(tvbuff_t *tvb, int offset, proto_tree *tree, int encoding, int * const *hf_indexes)
dissect_event_params(tvbuff_t *tvb, wtap_syscall_header* syscall_header, int offset, proto_tree *tree, int encoding, int * const *hf_indexes)
{
int len_offset = offset;
int param_offset;
int cur_param;
guint32 cur_param;
param_offset = offset + dissect_header_lens(tvb, offset, tree, encoding, hf_indexes);
param_offset = offset + dissect_header_lens(tvb, syscall_header, offset, tree, encoding);
for (cur_param = 0; hf_indexes[cur_param]; cur_param++) {
for (cur_param = 0; cur_param < syscall_header->nparams; cur_param++) {
int param_len = tvb_get_guint16(tvb, len_offset, encoding);
const int hf_index = *hf_indexes[cur_param];
if (proto_registrar_get_ftype(hf_index) == FT_STRING) {
@ -2201,13 +2200,16 @@ dissect_sysdig_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_tree_add_uint(se_tree, hf_se_cpu_id, tvb, 0, 0, pinfo->rec->rec_header.syscall_header.cpu_id);
proto_tree_add_uint64(se_tree, hf_se_thread_id, tvb, 0, 0, pinfo->rec->rec_header.syscall_header.thread_id);
proto_tree_add_uint(se_tree, hf_se_event_length, tvb, 0, 0, pinfo->rec->rec_header.syscall_header.event_len);
if (pinfo->rec->rec_header.syscall_header.nparams != 0) {
proto_tree_add_uint(se_tree, hf_se_nparams, tvb, 0, 0, pinfo->rec->rec_header.syscall_header.nparams);
}
ti = proto_tree_add_uint(se_tree, hf_se_event_type, tvb, 0, 0, event_type);
syscall_tree = proto_item_add_subtree(ti, ett_sysdig_syscall);
for (cur_tree_info = event_tree_info; cur_tree_info->hf_indexes; cur_tree_info++) {
if (cur_tree_info->event_type == event_type) {
dissect_event_params(tvb, 0, syscall_tree, encoding, cur_tree_info->hf_indexes);
dissect_event_params(tvb, &pinfo->rec->rec_header.syscall_header, 0, syscall_tree, encoding, cur_tree_info->hf_indexes);
break;
}
}
@ -2239,6 +2241,10 @@ proto_register_sysdig_event(void)
{ "Event length", "sysdig.event_len",
FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
},
{ &hf_se_nparams,
{ "Number of parameters", "sysdig.nparams",
FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
},
{ &hf_se_event_type,
{ "Event type", "sysdig.event_type",
FT_UINT16, BASE_DEC, VALS(event_type_vals), 0, NULL, HFILL }
@ -2445,6 +2451,7 @@ proto_register_sysdig_event(void)
}
#define BLOCK_TYPE_SYSDIG_EVENT 0x00000204
#define BLOCK_TYPE_SYSDIG_EVENT_V2 0x00000216
void
proto_reg_handoff_sysdig_event(void)
{
@ -2457,6 +2464,7 @@ proto_reg_handoff_sysdig_event(void)
sysdig_event_handle = create_dissector_handle(dissect_sysdig_event,
proto_sysdig_event);
dissector_add_uint("pcapng.block_type", BLOCK_TYPE_SYSDIG_EVENT, sysdig_event_handle);
dissector_add_uint("pcapng.block_type", BLOCK_TYPE_SYSDIG_EVENT_V2, sysdig_event_handle);
}
/*

View File

@ -281,6 +281,7 @@ register_pcapng_block_type_handler(guint block_type, block_reader reader,
case BLOCK_TYPE_EPB:
case BLOCK_TYPE_DSB:
case BLOCK_TYPE_SYSDIG_EVENT:
case BLOCK_TYPE_SYSDIG_EVENT_V2:
case BLOCK_TYPE_SYSTEMD_JOURNAL:
/*
* Yes; we already handle it, and don't allow a replacement to
@ -438,6 +439,7 @@ get_block_type_index(guint block_type, guint *bt_index)
break;
case BLOCK_TYPE_SYSDIG_EVENT:
case BLOCK_TYPE_SYSDIG_EVENT_V2:
/* case BLOCK_TYPE_SYSDIG_EVF: */
*bt_index = BT_INDEX_EVT;
break;
@ -766,8 +768,8 @@ pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh,
return PCAPNG_BLOCK_ERROR;
}
/* we currently only understand SHB V1.0 */
if (version_major != 1 || version_minor > 0) {
/* we currently only understand SHB V1.0 SHB V1.2*/
if (version_major != 1 || version_minor == 1 || version_minor > 2) {
*err = WTAP_ERR_UNSUPPORTED;
*err_info = g_strdup_printf("pcapng_read_section_header_block: unknown SHB version %u.%u",
version_major, version_minor);
@ -2353,6 +2355,7 @@ pcapng_read_sysdig_event_block(FILE_T fh, pcapng_block_header_t *bh,
guint64 thread_id;
guint32 event_len;
guint16 event_type;
guint32 nparams;
if (bh->block_total_length < MIN_SYSDIG_EVENT_SIZE) {
*err = WTAP_ERR_BAD_FILE;
@ -2377,7 +2380,11 @@ pcapng_read_sysdig_event_block(FILE_T fh, pcapng_block_header_t *bh,
wblock->rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN /*|WTAP_HAS_INTERFACE_ID */;
wblock->rec->tsprec = WTAP_TSPREC_NSEC;
block_read = block_total_length;
if (bh->block_type == BLOCK_TYPE_SYSDIG_EVENT_V2) {
block_read = block_total_length - 4;
} else {
block_read = block_total_length;
}
if (!wtap_read_bytes(fh, &cpu_id, sizeof cpu_id, err, err_info)) {
pcapng_debug("pcapng_read_packet_block: failed to read sysdig event cpu id");
@ -2399,6 +2406,12 @@ pcapng_read_sysdig_event_block(FILE_T fh, pcapng_block_header_t *bh,
pcapng_debug("pcapng_read_packet_block: failed to read sysdig event type");
return FALSE;
}
if (bh->block_type == BLOCK_TYPE_SYSDIG_EVENT_V2) {
if (!wtap_read_bytes(fh, &nparams, sizeof nparams, err, err_info)) {
pcapng_debug("pcapng_read_packet_block: failed to read sysdig event type");
return FALSE;
}
}
block_read -= MIN_SYSDIG_EVENT_SIZE;
wblock->rec->rec_header.syscall_header.byte_order = G_BYTE_ORDER;
@ -2422,6 +2435,7 @@ pcapng_read_sysdig_event_block(FILE_T fh, pcapng_block_header_t *bh,
wblock->rec->rec_header.syscall_header.thread_id = thread_id;
wblock->rec->rec_header.syscall_header.event_len = event_len;
wblock->rec->rec_header.syscall_header.event_type = event_type;
wblock->rec->rec_header.syscall_header.nparams = nparams;
}
wblock->rec->ts.secs = (time_t) (ts / 1000000000);
@ -2756,6 +2770,7 @@ pcapng_read_block(wtap *wth, FILE_T fh, pcapng_t *pn,
return FALSE;
break;
case(BLOCK_TYPE_SYSDIG_EVENT):
case(BLOCK_TYPE_SYSDIG_EVENT_V2):
/* case(BLOCK_TYPE_SYSDIG_EVF): */
if (!pcapng_read_sysdig_event_block(fh, &bh, section_info, wblock, err, err_info))
return FALSE;

View File

@ -28,6 +28,8 @@
#define BLOCK_TYPE_DSB 0x0000000A /* Decryption Secrets Block */
#define BLOCK_TYPE_SYSDIG_EVENT 0x00000204 /* Sysdig Event Block */
#define BLOCK_TYPE_SYSDIG_EVF 0x00000208 /* Sysdig Event Block with flags */
#define BLOCK_TYPE_SYSDIG_EVENT_V2 0x00000216 /* Sysdig Event Block version 2 */
#define BLOCK_TYPE_SYSDIG_EVF_V2 0x00000217 /* Sysdig Event Block with flags version 2 */
/* TODO: the following are not yet well defined in the draft spec,
* and do not yet have block type values assigned to them:

View File

@ -1314,6 +1314,7 @@ typedef struct {
guint32 event_len; /* length of the event */
guint32 event_filelen; /* event data length in the file */
guint16 event_type;
guint32 nparams; /* number of parameters of the event */
guint16 cpu_id;
/* ... Event ... */
} wtap_syscall_header;