Initial Sysdig syscall (event) support.
Add a dissector for reading Sysdig event blocks. It only handles plain events but it's usable for reading trace files on hand here. Use a script to generate various parts of the dissector. As an experiment, update parts in-place instead of using a template. Ultimately there should probably be a top-level "Syscall" or "Event" dissector alongside the "Frame" dissector, which could then call this. You could then directly compare an executable's system calls alongside its network traffic. For now leverage the pcapng_block dissector and keep everything under "Frame". Next steps: - Items listed at the top of packet-sysdig-event.c. Change-Id: I17077e8d7f40d10a946d61189ebc077d81c4da37 Reviewed-on: https://code.wireshark.org/review/11103 Petri-Dish: Gerald Combs <gerald@wireshark.org> Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Gerald Combs <gerald@wireshark.org>
This commit is contained in:
parent
6a56224c18
commit
0d497e8125
|
@ -1321,6 +1321,7 @@ set(DISSECTOR_SRC
|
|||
dissectors/packet-sync.c
|
||||
dissectors/packet-synergy.c
|
||||
dissectors/packet-synphasor.c
|
||||
dissectors/packet-sysdig-event.c
|
||||
dissectors/packet-sysex.c
|
||||
dissectors/packet-syslog.c
|
||||
dissectors/packet-t30.c
|
||||
|
|
|
@ -187,6 +187,7 @@ ASN1_DISSECTOR_SRC = \
|
|||
packet-smrse.c \
|
||||
packet-spnego.c \
|
||||
packet-sv.c \
|
||||
packet-sysdig-event.c \
|
||||
packet-sysex.c \
|
||||
packet-t124.c \
|
||||
packet-t125.c \
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -137,6 +137,7 @@ EXTRA_DIST = \
|
|||
fuzz-test.sh \
|
||||
gen-bugnote \
|
||||
generate-bacnet-vendors.py \
|
||||
generate-sysdig-event.py \
|
||||
Get-HardenFlags.ps1 \
|
||||
git-compare-abis.sh \
|
||||
git-export-release.sh \
|
||||
|
|
|
@ -0,0 +1,345 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Wireshark - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@wireshark.org>
|
||||
# Copyright 1998 Gerald Combs
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
'''\
|
||||
Generate Sysdig event dissector sections from the sysdig sources.
|
||||
|
||||
Reads driver/event_table.c and driver/ppm_events_public.h and generates
|
||||
corresponding dissection code in packet-sysdig-event.c. Updates are
|
||||
performed in-place in the dissector code.
|
||||
|
||||
Requires an Internet connection. Assets are loaded from GitHub over HTTPS.
|
||||
'''
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import urllib2
|
||||
import sys
|
||||
|
||||
sysdig_repo_pfx = 'https://raw.githubusercontent.com/draios/sysdig/0.5.0/'
|
||||
|
||||
ppm_ev_pub = urllib2.urlopen(sysdig_repo_pfx + 'driver/ppm_events_public.h')
|
||||
ppm_ev_pub_lines = ppm_ev_pub.readlines()
|
||||
ppm_ev_pub.close()
|
||||
|
||||
ppme_re = re.compile('^\s+PPME_([A-Z0-9_]+_[EX])\s*=\s*([0-9]+)\s*,')
|
||||
|
||||
event_info_d = {}
|
||||
|
||||
def get_event_defines():
|
||||
event_d = {}
|
||||
for line in ppm_ev_pub_lines:
|
||||
m = ppme_re.match(line)
|
||||
if m:
|
||||
event_d[int(m.group(2))] = m.group(1)
|
||||
return event_d
|
||||
|
||||
ppm_ev_table = urllib2.urlopen(sysdig_repo_pfx + 'driver/event_table.c')
|
||||
ppm_ev_table_lines = ppm_ev_table.readlines()
|
||||
ppm_ev_table.close()
|
||||
|
||||
hf_d = {}
|
||||
|
||||
event_info_re = re.compile('^\s+/\*\s*PPME_.*\*\/\s*{\s*"([A-Za-z0-9_]+)"\s*,[^,]+,[^,]+,\s*([0-9]+)\s*[,{}]')
|
||||
event_param_re = re.compile('{\s*"([A-Za-z0-9_]+)"\s*,\s*PT_([A-Z0-9_]+)\s*,\s*PF_([A-Z0-9_]+)\s*[,}]')
|
||||
|
||||
def get_event_names():
|
||||
'''Return a contiguous list of event names. Names are lower case.'''
|
||||
event_name_l = []
|
||||
for line in ppm_ev_table_lines:
|
||||
ei = event_info_re.match(line)
|
||||
if ei:
|
||||
event_name_l.append(ei.group(1))
|
||||
return event_name_l
|
||||
|
||||
# PT_xxx to FT_xxx
|
||||
pt_to_ft = {
|
||||
'BYTEBUF': 'BYTES',
|
||||
'CHARBUF': 'STRING',
|
||||
'FD': 'INT64',
|
||||
'FSPATH': 'STRING',
|
||||
}
|
||||
|
||||
def get_event_params():
|
||||
'''Return a list of dictionaries containing event names and parameter info.'''
|
||||
event_param_l = []
|
||||
event_num = 0
|
||||
force_string_l = ['args', 'env']
|
||||
for line in ppm_ev_table_lines:
|
||||
ei = event_info_re.match(line)
|
||||
ep = event_param_re.findall(line)
|
||||
if ei and ep:
|
||||
src_param_count = int(ei.group(2))
|
||||
if len(ep) != src_param_count:
|
||||
err_msg = '{}: found {} parameters. Expected {}. Params: {}'.format(
|
||||
ei.group(1), len(ep), src_param_count, repr(ep))
|
||||
raise NameError(err_msg)
|
||||
for p in ep:
|
||||
if p[0] in force_string_l:
|
||||
param_type = 'STRING'
|
||||
elif p[1] in pt_to_ft:
|
||||
param_type = pt_to_ft[p[1]]
|
||||
elif p[0] == 'flags' and p[1].startswith('INT') and 'HEX' in p[2]:
|
||||
param_type = 'U' + p[1]
|
||||
elif 'INT' in p[1]:
|
||||
# Ints
|
||||
param_type = p[1]
|
||||
else:
|
||||
# Fall back to bytes
|
||||
param_type = 'BYTES'
|
||||
|
||||
if p[2] == 'NA':
|
||||
if 'INT' in param_type:
|
||||
param_format = 'DEC'
|
||||
else:
|
||||
param_format = 'NONE'
|
||||
elif param_type == 'BYTES':
|
||||
param_format = 'NONE'
|
||||
else:
|
||||
param_format = p[2]
|
||||
param_d = {
|
||||
'event_name': ei.group(1),
|
||||
'event_num': event_num,
|
||||
'param_name': p[0],
|
||||
'param_type': param_type,
|
||||
'param_format': param_format,
|
||||
}
|
||||
event_param_l.append(param_d)
|
||||
if ei:
|
||||
event_num += 1
|
||||
return event_param_l
|
||||
|
||||
def param_to_hf_name(param):
|
||||
return 'hf_param_{}_{}'.format(param['param_name'], param['param_type'].lower())
|
||||
|
||||
def param_to_value_string_name(param):
|
||||
return '{}_{}_vals'.format(param['param_name'], param['param_type'].lower())
|
||||
|
||||
def get_param_desc(param):
|
||||
# Try to coerce event names and parameters into human-friendly
|
||||
# strings.
|
||||
# XXX This could use some work.
|
||||
|
||||
# Specific descriptions. Event name + parameter name.
|
||||
param_descs = {
|
||||
'accept.queuepct': 'Accept queue per connection',
|
||||
'execve.args': 'Program arguments',
|
||||
'execve.comm': 'Command',
|
||||
'execve.cwd': 'Current working directory',
|
||||
}
|
||||
# General descriptions. Event name only.
|
||||
event_descs = {
|
||||
'ioctl': 'I/O control',
|
||||
}
|
||||
|
||||
event_name = param['event_name']
|
||||
param_id = '{}.{}'.format(event_name, param['param_name'])
|
||||
if param_id in param_descs:
|
||||
param_desc = param_descs[param_id]
|
||||
elif event_name in event_descs:
|
||||
param_desc = '{}: {}'.format(event_descs[event_name], param['param_name'])
|
||||
else:
|
||||
param_desc = param['param_name']
|
||||
return param_desc
|
||||
|
||||
def main():
|
||||
# Event list
|
||||
event_d = get_event_defines()
|
||||
event_nums = event_d.keys()
|
||||
event_nums.sort()
|
||||
|
||||
event_name_l = get_event_names()
|
||||
event_param_l = get_event_params()
|
||||
|
||||
hf_d = {}
|
||||
for param in event_param_l:
|
||||
hf_name = param_to_hf_name(param)
|
||||
hf_d[hf_name] = param
|
||||
|
||||
idx_id_to_name = { '': 'no' }
|
||||
parameter_index_l = []
|
||||
|
||||
for en in range (0, len(event_nums)):
|
||||
param_id = ''
|
||||
param_l = []
|
||||
event_var = event_d[en].lower()
|
||||
for param in event_param_l:
|
||||
if param['event_num'] == en:
|
||||
hf_name = param_to_hf_name(param)
|
||||
param_l.append(hf_name)
|
||||
param_id += ':' + param['param_name'] + '_' + param['param_type']
|
||||
|
||||
ei_str = ''
|
||||
if param_id not in idx_id_to_name:
|
||||
idx_id_to_name[param_id] = event_var
|
||||
ei_str = 'static const int *{}_indexes[] = {{ &{}, NULL }};'.format(
|
||||
event_var,
|
||||
', &'.join(param_l)
|
||||
)
|
||||
else:
|
||||
ei_str = '#define {}_indexes {}_indexes'.format(event_var, idx_id_to_name[param_id])
|
||||
|
||||
parameter_index_l.append(ei_str)
|
||||
|
||||
dissector_path = os.path.join(os.path.dirname(__file__),
|
||||
'..', 'epan', 'dissectors', 'packet-sysdig-event.c')
|
||||
dissector_f = open(dissector_path, 'r')
|
||||
dissector_lines = list(dissector_f)
|
||||
dissector_f = open(dissector_path, 'w+')
|
||||
|
||||
# Strip out old content
|
||||
strip_re_l = []
|
||||
strip_re_l.append(re.compile('^static\s+int\s+hf_param_.*;'))
|
||||
strip_re_l.append(re.compile('^#define\s+EVT_STR_[A-Z0-9_]+\s+"[A-Za-z0-9_]+"'))
|
||||
strip_re_l.append(re.compile('^#define\s+EVT_[A-Z0-9_]+\s+[0-9]+'))
|
||||
strip_re_l.append(re.compile('^\s*{\s*EVT_[A-Z0-9_]+\s*,\s*EVT_STR_[A-Z0-9_]+\s*}'))
|
||||
strip_re_l.append(re.compile('^static\s+const\s+int\s+\*\s*[a-z0-9_]+_[ex]_indexes\[\]\s*=\s*\{\s*&hf_param_.*NULL\s*\}\s*;'))
|
||||
strip_re_l.append(re.compile('^\s*#define\s+[a-z0-9_]+_[ex]_indexes\s+[a-z0-9_]+_indexes'))
|
||||
strip_re_l.append(re.compile('^\s*\{\s*EVT_[A-Z0-9_]+_[EX]\s*,\s*[a-z0-9_]+_[ex]_indexes\s*}\s*,'))
|
||||
strip_re_l.append(re.compile('^\s*{\s*&hf_param_.*},')) # Must all be on one line
|
||||
|
||||
for strip_re in strip_re_l:
|
||||
dissector_lines = [l for l in dissector_lines if not strip_re.search(l)]
|
||||
|
||||
# Find our value strings
|
||||
value_string_re = re.compile('static\s+const\s+value_string\s+([A-Za-z0-9_]+_vals)')
|
||||
value_string_l = []
|
||||
for line in dissector_lines:
|
||||
vs = value_string_re.match(line)
|
||||
if vs:
|
||||
value_string_l.append(vs.group(1))
|
||||
|
||||
# Add in new content after comments.
|
||||
|
||||
header_fields_c = 'Header fields'
|
||||
header_fields_re = re.compile('/\*\s+' + header_fields_c, flags = re.IGNORECASE)
|
||||
header_fields_l = []
|
||||
for hf_name in sorted(hf_d.keys()):
|
||||
header_fields_l.append('static int {} = -1;'.format(hf_name))
|
||||
|
||||
event_names_c = 'Event names'
|
||||
event_names_re = re.compile('/\*\s+' + event_names_c, flags = re.IGNORECASE)
|
||||
event_names_l = []
|
||||
event_str_l = list(set(event_name_l))
|
||||
event_str_l.sort()
|
||||
for evt_str in event_str_l:
|
||||
event_names_l.append('#define EVT_STR_{0:24s} "{1:s}"'.format(evt_str.upper(), evt_str))
|
||||
|
||||
event_definitions_c = 'Event definitions'
|
||||
event_definitions_re = re.compile('/\*\s+' + event_definitions_c, flags = re.IGNORECASE)
|
||||
event_definitions_l = []
|
||||
for evt in event_nums:
|
||||
event_definitions_l.append('#define EVT_{0:24s} {1:3d}'.format(event_d[evt], evt))
|
||||
|
||||
value_strings_c = 'Value strings'
|
||||
value_strings_re = re.compile('/\*\s+' + value_strings_c, flags = re.IGNORECASE)
|
||||
value_strings_l = []
|
||||
for evt in event_nums:
|
||||
evt_num = 'EVT_{},'.format(event_d[evt])
|
||||
evt_str = 'EVT_STR_' + event_name_l[evt].upper()
|
||||
value_strings_l.append(' {{ {0:<32s} {1:s} }},'.format(evt_num, evt_str))
|
||||
|
||||
parameter_index_c = 'Parameter indexes'
|
||||
parameter_index_re = re.compile('/\*\s+' + parameter_index_c, flags = re.IGNORECASE)
|
||||
# parameter_index_l defined above.
|
||||
|
||||
event_tree_c = 'Event tree'
|
||||
event_tree_re = re.compile('/\*\s+' + event_tree_c, flags = re.IGNORECASE)
|
||||
event_tree_l = []
|
||||
for evt in event_nums:
|
||||
evt_num = 'EVT_{}'.format(event_d[evt])
|
||||
evt_idx = '{}_indexes'.format(event_d[evt].lower())
|
||||
event_tree_l.append(' {{ {}, {} }},'.format(evt_num, evt_idx))
|
||||
|
||||
header_field_reg_c = 'Header field registration'
|
||||
header_field_reg_re = re.compile('/\*\s+' + header_field_reg_c, flags = re.IGNORECASE)
|
||||
header_field_reg_l = []
|
||||
for hf_name in sorted(hf_d.keys()):
|
||||
param = hf_d[hf_name]
|
||||
event_name = param['event_name']
|
||||
param_desc = get_param_desc(param)
|
||||
param_name = param['param_name']
|
||||
param_type = param['param_type']
|
||||
param_format = param['param_format']
|
||||
fieldconvert = 'NULL'
|
||||
vs_name = param_to_value_string_name(param)
|
||||
if vs_name in value_string_l and 'INT' in param_type:
|
||||
fieldconvert = 'VALS({})'.format(vs_name)
|
||||
header_field_reg_l.append(' {{ &{}, {{ "{}", "sysdig.param.{}.{}", FT_{}, BASE_{}, {}, 0, NULL, HFILL }} }},'.format(
|
||||
hf_name,
|
||||
param_desc,
|
||||
event_name,
|
||||
param_name,
|
||||
param_type,
|
||||
param_format,
|
||||
fieldconvert
|
||||
))
|
||||
|
||||
for line in dissector_lines:
|
||||
fill_comment = None
|
||||
fill_l = []
|
||||
|
||||
if header_fields_re.match(line):
|
||||
fill_comment = header_fields_c
|
||||
fill_l = header_fields_l
|
||||
elif event_names_re.match(line):
|
||||
fill_comment = event_names_c
|
||||
fill_l = event_names_l
|
||||
elif event_definitions_re.match(line):
|
||||
fill_comment = event_definitions_c
|
||||
fill_l = event_definitions_l
|
||||
elif value_strings_re.match(line):
|
||||
fill_comment = value_strings_c
|
||||
fill_l = value_strings_l
|
||||
elif parameter_index_re.match(line):
|
||||
fill_comment = parameter_index_c
|
||||
fill_l = parameter_index_l
|
||||
elif event_tree_re.match(line):
|
||||
fill_comment = event_tree_c
|
||||
fill_l = event_tree_l
|
||||
elif header_field_reg_re.match(line):
|
||||
fill_comment = header_field_reg_c
|
||||
fill_l = header_field_reg_l
|
||||
|
||||
if fill_comment is not None:
|
||||
# Write our comment followed by the content
|
||||
print('Generating {}, {:d} lines'.format(fill_comment, len(fill_l)))
|
||||
dissector_f.write('/* {}. Automatically generated by tools/{} */\n'.format(
|
||||
fill_comment,
|
||||
os.path.basename(__file__)
|
||||
))
|
||||
for line in fill_l:
|
||||
dissector_f.write('{}\n'.format(line))
|
||||
# Fill each section only once
|
||||
del fill_l[:]
|
||||
else:
|
||||
# Existing content
|
||||
dissector_f.write(line)
|
||||
|
||||
dissector_f.close()
|
||||
|
||||
#
|
||||
# On with the show
|
||||
#
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
118
wiretap/pcapng.c
118
wiretap/pcapng.c
|
@ -183,6 +183,11 @@ typedef struct pcapng_interface_statistics_block_s {
|
|||
*/
|
||||
#define MIN_ISB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_interface_statistics_block_t)))
|
||||
|
||||
/*
|
||||
* Minimum Sysdig size = minimum block size + packed size of sysdig_event_phdr.
|
||||
*/
|
||||
#define MIN_SYSDIG_EVENT_SIZE ((guint32)(MIN_BLOCK_SIZE)) + ((16 + 64 + 64 + 32 + 16) / 8)
|
||||
|
||||
/* pcapng: common option header file encoding for every option type */
|
||||
typedef struct pcapng_option_header_s {
|
||||
guint16 option_code;
|
||||
|
@ -196,7 +201,6 @@ struct option {
|
|||
guint16 value_length;
|
||||
};
|
||||
|
||||
|
||||
/* Option codes: 16-bit field */
|
||||
#define OPT_EOFOPT 0x0000
|
||||
#define OPT_COMMENT 0x0001
|
||||
|
@ -378,8 +382,9 @@ register_pcapng_block_type_handler(guint block_type, block_reader reader,
|
|||
#define BT_INDEX_PBS 2 /* all packet blocks */
|
||||
#define BT_INDEX_NRB 3
|
||||
#define BT_INDEX_ISB 4
|
||||
#define BT_INDEX_EVT 5
|
||||
|
||||
#define NUM_BT_INDICES 5
|
||||
#define NUM_BT_INDICES 6
|
||||
|
||||
static GHashTable *option_handlers[NUM_BT_INDICES];
|
||||
|
||||
|
@ -412,6 +417,11 @@ get_block_type_index(guint block_type, guint *bt_index)
|
|||
*bt_index = BT_INDEX_ISB;
|
||||
break;
|
||||
|
||||
case BLOCK_TYPE_SYSDIG_EVENT:
|
||||
/* case BLOCK_TYPE_SYSDIG_EVF: */
|
||||
*bt_index = BT_INDEX_EVT;
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* This is a block type we don't process; either we ignore it,
|
||||
|
@ -2155,6 +2165,96 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pcapng_read_sysdig_event_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn _U_, wtapng_block_t *wblock, int *err, gchar **err_info)
|
||||
{
|
||||
unsigned block_read;
|
||||
guint32 block_total_length;
|
||||
guint16 cpu_id;
|
||||
guint64 wire_ts;
|
||||
guint64 ts;
|
||||
guint64 thread_id;
|
||||
guint32 event_len;
|
||||
guint16 event_type;
|
||||
|
||||
if (bh->block_total_length < MIN_SYSDIG_EVENT_SIZE) {
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("%s: total block length %u is too small (< %u)", G_STRFUNC,
|
||||
bh->block_total_length, MIN_SYSDIG_EVENT_SIZE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* add padding bytes to "block total length" */
|
||||
/* (the "block total length" of some example files don't contain any padding bytes!) */
|
||||
if (bh->block_total_length % 4) {
|
||||
block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
|
||||
} else {
|
||||
block_total_length = bh->block_total_length;
|
||||
}
|
||||
|
||||
pcapng_debug("pcapng_read_sysdig_event_block: block_total_length %u",
|
||||
bh->block_total_length);
|
||||
|
||||
wblock->packet_header->rec_type = REC_TYPE_FT_SPECIFIC_EVENT;
|
||||
wblock->packet_header->pseudo_header.sysdig_event.record_type = BLOCK_TYPE_SYSDIG_EVENT;
|
||||
wblock->packet_header->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN /*|WTAP_HAS_INTERFACE_ID */;
|
||||
wblock->packet_header->pkt_tsprec = WTAP_TSPREC_NSEC;
|
||||
|
||||
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");
|
||||
return FALSE;
|
||||
}
|
||||
if (!wtap_read_bytes(fh, &wire_ts, sizeof wire_ts, err, err_info)) {
|
||||
pcapng_debug("pcapng_read_packet_block: failed to read sysdig event timestamp");
|
||||
return FALSE;
|
||||
}
|
||||
if (!wtap_read_bytes(fh, &thread_id, sizeof thread_id, err, err_info)) {
|
||||
pcapng_debug("pcapng_read_packet_block: failed to read sysdig event thread id");
|
||||
return FALSE;
|
||||
}
|
||||
if (!wtap_read_bytes(fh, &event_len, sizeof event_len, err, err_info)) {
|
||||
pcapng_debug("pcapng_read_packet_block: failed to read sysdig event length");
|
||||
return FALSE;
|
||||
}
|
||||
if (!wtap_read_bytes(fh, &event_type, sizeof event_type, err, err_info)) {
|
||||
pcapng_debug("pcapng_read_packet_block: failed to read sysdig event type");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
block_read -= MIN_SYSDIG_EVENT_SIZE;
|
||||
wblock->packet_header->pseudo_header.sysdig_event.byte_order = G_BYTE_ORDER;
|
||||
|
||||
if (pn->byte_swapped) {
|
||||
wblock->packet_header->pseudo_header.sysdig_event.byte_order =
|
||||
G_BYTE_ORDER == G_LITTLE_ENDIAN ? G_BIG_ENDIAN : G_LITTLE_ENDIAN;
|
||||
wblock->packet_header->pseudo_header.sysdig_event.cpu_id = GUINT16_SWAP_LE_BE(cpu_id);
|
||||
ts = GUINT64_SWAP_LE_BE(wire_ts);
|
||||
wblock->packet_header->pseudo_header.sysdig_event.thread_id = GUINT64_SWAP_LE_BE(thread_id);
|
||||
wblock->packet_header->pseudo_header.sysdig_event.event_len = GUINT32_SWAP_LE_BE(event_len);
|
||||
wblock->packet_header->pseudo_header.sysdig_event.event_type = GUINT16_SWAP_LE_BE(event_type);
|
||||
} else {
|
||||
wblock->packet_header->pseudo_header.sysdig_event.cpu_id = cpu_id;
|
||||
ts = wire_ts;
|
||||
wblock->packet_header->pseudo_header.sysdig_event.thread_id = thread_id;
|
||||
wblock->packet_header->pseudo_header.sysdig_event.event_len = event_len;
|
||||
wblock->packet_header->pseudo_header.sysdig_event.event_type = event_type;
|
||||
}
|
||||
|
||||
wblock->packet_header->ts.secs = (time_t) (ts / 1000000000);
|
||||
wblock->packet_header->ts.nsecs = (int) (ts % 1000000000);
|
||||
|
||||
wblock->packet_header->caplen = block_read;
|
||||
wblock->packet_header->len = wblock->packet_header->pseudo_header.sysdig_event.event_len;
|
||||
|
||||
/* "Sysdig Event Block" read event data */
|
||||
if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
|
||||
block_read, err, err_info))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pcapng_read_unknown_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn _U_, wtapng_block_t *wblock _U_, int *err, gchar **err_info)
|
||||
|
@ -2290,6 +2390,11 @@ pcapng_read_block(wtap *wth, FILE_T fh, pcapng_t *pn, wtapng_block_t *wblock, in
|
|||
if (!pcapng_read_interface_statistics_block(fh, &bh, pn, wblock, err, err_info))
|
||||
return PCAPNG_BLOCK_ERROR;
|
||||
break;
|
||||
case(BLOCK_TYPE_SYSDIG_EVENT):
|
||||
/* case(BLOCK_TYPE_SYSDIG_EVF): */
|
||||
if (!pcapng_read_sysdig_event_block(fh, &bh, pn, wblock, err, err_info))
|
||||
return PCAPNG_BLOCK_ERROR;
|
||||
break;
|
||||
default:
|
||||
pcapng_debug("pcapng_read_block: Unknown block_type: 0x%x (block ignored), block total length %d", bh.block_type, bh.block_total_length);
|
||||
if (!pcapng_read_unknown_block(fh, &bh, pn, wblock, err, err_info))
|
||||
|
@ -2523,6 +2628,8 @@ pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
|
|||
case(BLOCK_TYPE_PB):
|
||||
case(BLOCK_TYPE_SPB):
|
||||
case(BLOCK_TYPE_EPB):
|
||||
case(BLOCK_TYPE_SYSDIG_EVENT):
|
||||
case(BLOCK_TYPE_SYSDIG_EVF):
|
||||
/* packet block - we've found a packet */
|
||||
goto got_packet;
|
||||
|
||||
|
@ -2615,10 +2722,11 @@ pcapng_seek_read(wtap *wth, gint64 seek_off,
|
|||
}
|
||||
|
||||
/* block must be a "Packet Block", an "Enhanced Packet Block",
|
||||
or a "Simple Packet Block" */
|
||||
a "Simple Packet Block", or an event */
|
||||
if (wblock.type != BLOCK_TYPE_PB && wblock.type != BLOCK_TYPE_EPB &&
|
||||
wblock.type != BLOCK_TYPE_SPB) {
|
||||
pcapng_debug("pcapng_seek_read: block type %u not PB/EPB/SPB", wblock.type);
|
||||
wblock.type != BLOCK_TYPE_SPB &&
|
||||
wblock.type != BLOCK_TYPE_SYSDIG_EVENT && wblock.type != BLOCK_TYPE_SYSDIG_EVF) {
|
||||
pcapng_debug("pcapng_seek_read: block type %u not PB/EPB/SPB", wblock.type);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#define BLOCK_TYPE_NRB 0x00000004 /* Name Resolution Block */
|
||||
#define BLOCK_TYPE_ISB 0x00000005 /* Interface Statistics Block */
|
||||
#define BLOCK_TYPE_EPB 0x00000006 /* Enhanced Packet Block */
|
||||
#define BLOCK_TYPE_SYSDIG_EVENT 0x00000204 /* Sysdig Event Block */
|
||||
#define BLOCK_TYPE_SYSDIG_EVF 0x00000208 /* Sysdig Event Block with flags */
|
||||
#define BLOCK_TYPE_SHB 0x0A0D0D0A /* Section Header Block */
|
||||
/* TODO: the following are not yet well defined in the draft spec:
|
||||
* Compression Block
|
||||
|
|
|
@ -1119,6 +1119,20 @@ struct logcat_phdr {
|
|||
gint version;
|
||||
};
|
||||
|
||||
/* Packet "pseudo-header" information for Sysdig events. */
|
||||
|
||||
struct sysdig_event_phdr {
|
||||
guint record_type; /* XXX match ft_specific_record_phdr so that we chain off of packet-pcapng_block for now. */
|
||||
int byte_order;
|
||||
guint16 cpu_id;
|
||||
/* guint32 sentinel; */
|
||||
guint64 timestamp; /* ns since epoch */
|
||||
guint64 thread_id;
|
||||
guint32 event_len; /* XXX dup of wtap_pkthdr.len */
|
||||
guint16 event_type;
|
||||
/* ... Event ... */
|
||||
};
|
||||
|
||||
/* Pseudo-header for file-type-specific records */
|
||||
struct ft_specific_record_phdr {
|
||||
guint record_type; /* the type of record this is */
|
||||
|
@ -1150,6 +1164,7 @@ union wtap_pseudo_header {
|
|||
struct nokia_phdr nokia;
|
||||
struct llcp_phdr llcp;
|
||||
struct logcat_phdr logcat;
|
||||
struct sysdig_event_phdr sysdig_event;
|
||||
struct ft_specific_record_phdr ftsrec;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue