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

(cherry picked from commit fbe8d3a00f)
This commit is contained in:
Loris Degioanni 2021-04-05 22:16:09 -07:00 committed by Guy Harris
parent 1be17e2d30
commit e94d9f4549
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

@ -280,6 +280,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
@ -411,6 +412,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;
@ -622,8 +624,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);
@ -2347,6 +2349,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;
@ -2371,7 +2374,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");
@ -2393,6 +2400,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;
@ -2416,6 +2429,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);
@ -2740,6 +2754,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

@ -1399,6 +1399,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;