forked from osmocom/wireshark
Add a new record type REC_TYPE_SYSTEMD_JOURNAL.
Systemd journal entries aren't file-type-specific; they're found in both systemd journal entry blocks in pcapng files and in systemd journal export files. Give it a record type, for use with both file types. This fixes #16955. It also means that you can open a systemd journal export file and save it as a pcapng file.
This commit is contained in:
parent
edd71daa90
commit
889e0d5cb6
|
@ -2078,6 +2078,11 @@ invalid_time:
|
|||
caplen = rec->rec_header.syscall_header.event_filelen;
|
||||
do_mutation = TRUE;
|
||||
break;
|
||||
|
||||
case REC_TYPE_SYSTEMD_JOURNAL:
|
||||
caplen = rec->rec_header.systemd_journal_header.record_len;
|
||||
do_mutation = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (change_offset > caplen) {
|
||||
|
|
|
@ -105,6 +105,7 @@ static int frame_tap = -1;
|
|||
|
||||
static dissector_handle_t docsis_handle;
|
||||
static dissector_handle_t sysdig_handle;
|
||||
static dissector_handle_t systemd_journal_handle;
|
||||
|
||||
/* Preferences */
|
||||
static gboolean show_file_off = FALSE;
|
||||
|
@ -379,6 +380,10 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
|
|||
pinfo->current_proto = "System Call";
|
||||
break;
|
||||
|
||||
case REC_TYPE_SYSTEMD_JOURNAL:
|
||||
pinfo->current_proto = "Systemd Journal";
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
|
@ -493,6 +498,19 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
|
|||
"System Call %u: %u byte%s",
|
||||
pinfo->num, frame_len, frame_plurality);
|
||||
break;
|
||||
|
||||
case REC_TYPE_SYSTEMD_JOURNAL:
|
||||
/*
|
||||
* XXX - we need to rethink what's handled by
|
||||
* packet-record.c, what's handled by packet-frame.c.
|
||||
* and what's handled by the syscall and systemd
|
||||
* journal dissectors (and maybe even the packet
|
||||
* dissector).
|
||||
*/
|
||||
ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, tvb_captured_length(tvb),
|
||||
"Systemd Journal Entry %u: %u byte%s",
|
||||
pinfo->num, frame_len, frame_plurality);
|
||||
break;
|
||||
}
|
||||
|
||||
fh_tree = proto_item_add_subtree(ti, ett_frame);
|
||||
|
@ -799,6 +817,14 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
|
|||
(void *)pinfo->pseudo_header);
|
||||
}
|
||||
break;
|
||||
|
||||
case REC_TYPE_SYSTEMD_JOURNAL:
|
||||
if (systemd_journal_handle) {
|
||||
call_dissector_with_data(systemd_journal_handle,
|
||||
tvb, pinfo, parent_tree,
|
||||
(void *)pinfo->pseudo_header);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
|
||||
|
@ -1274,6 +1300,7 @@ proto_reg_handoff_frame(void)
|
|||
{
|
||||
docsis_handle = find_dissector_add_dependency("docsis", proto_frame);
|
||||
sysdig_handle = find_dissector_add_dependency("sysdig", proto_frame);
|
||||
systemd_journal_handle = find_dissector_add_dependency("systemd_journal", proto_frame);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -161,6 +161,8 @@ static expert_field ei_unhandled_field_type = EI_INIT;
|
|||
static expert_field ei_nonbinary_field = EI_INIT;
|
||||
static expert_field ei_undecoded_field = EI_INIT;
|
||||
|
||||
static dissector_handle_t sje_handle = NULL;
|
||||
|
||||
#define MAX_DATA_SIZE 262144 // WTAP_MAX_PACKET_SIZE_STANDARD. Increase if needed.
|
||||
|
||||
/* Initialize the subtree pointers */
|
||||
|
@ -877,6 +879,9 @@ proto_register_systemd_journal(void)
|
|||
expert_systemd_journal = expert_register_protocol(proto_systemd_journal);
|
||||
expert_register_field_array(expert_systemd_journal, ei, array_length(ei));
|
||||
|
||||
sje_handle = register_dissector("systemd_journal", dissect_systemd_journal_line_entry,
|
||||
proto_systemd_journal);
|
||||
|
||||
init_jf_to_hf_map();
|
||||
}
|
||||
|
||||
|
@ -884,13 +889,6 @@ proto_register_systemd_journal(void)
|
|||
void
|
||||
proto_reg_handoff_systemd_journal(void)
|
||||
{
|
||||
static dissector_handle_t sje_handle = NULL;
|
||||
|
||||
if (!sje_handle) {
|
||||
sje_handle = create_dissector_handle(dissect_systemd_journal_line_entry,
|
||||
proto_systemd_journal);
|
||||
}
|
||||
|
||||
dissector_add_uint("wtap_fts_rec", WTAP_FILE_TYPE_SUBTYPE_SYSTEMD_JOURNAL, sje_handle);
|
||||
dissector_add_uint("pcapng.block_type", BLOCK_TYPE_SYSTEMD_JOURNAL, sje_handle);
|
||||
// It's possible to ship journal entries over HTTP/HTTPS using
|
||||
|
|
|
@ -192,6 +192,15 @@ frame_data_init(frame_data *fdata, guint32 num, const wtap_rec *rec,
|
|||
fdata->cum_bytes = cum_bytes + rec->rec_header.syscall_header.event_len;
|
||||
fdata->cap_len = rec->rec_header.syscall_header.event_filelen;
|
||||
break;
|
||||
|
||||
case REC_TYPE_SYSTEMD_JOURNAL:
|
||||
/*
|
||||
* XXX - is cum_bytes supposed to count non-packet bytes?
|
||||
*/
|
||||
fdata->pkt_len = rec->rec_header.systemd_journal_header.record_len;
|
||||
fdata->cum_bytes = cum_bytes + rec->rec_header.systemd_journal_header.record_len;
|
||||
fdata->cap_len = rec->rec_header.systemd_journal_header.record_len;
|
||||
break;
|
||||
}
|
||||
|
||||
/* To save some memory, we coerce it into 4 bits */
|
||||
|
|
|
@ -501,6 +501,10 @@ dissect_record(epan_dissect_t *edt, int file_type_subtype,
|
|||
record_type = "System Call";
|
||||
break;
|
||||
|
||||
case REC_TYPE_SYSTEMD_JOURNAL:
|
||||
record_type = "Systemd Journal Entry";
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* XXX - if we add record types that shouldn't be
|
||||
|
@ -544,6 +548,10 @@ dissect_record(epan_dissect_t *edt, int file_type_subtype,
|
|||
case REC_TYPE_SYSCALL:
|
||||
edt->pi.pseudo_header = NULL;
|
||||
break;
|
||||
|
||||
case REC_TYPE_SYSTEMD_JOURNAL:
|
||||
edt->pi.pseudo_header = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
edt->pi.fd = fd;
|
||||
|
|
|
@ -69,6 +69,7 @@ get_stats_for_preview(wtap *wth, ws_file_preview_stats *stats,
|
|||
case REC_TYPE_FT_SPECIFIC_EVENT:
|
||||
case REC_TYPE_FT_SPECIFIC_REPORT:
|
||||
case REC_TYPE_SYSCALL:
|
||||
case REC_TYPE_SYSTEMD_JOURNAL:
|
||||
data_records++;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2519,9 +2519,8 @@ pcapng_read_systemd_journal_export_block(wtap *wth, FILE_T fh, pcapng_block_head
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
wblock->rec->rec_type = REC_TYPE_FT_SPECIFIC_EVENT;
|
||||
wblock->rec->rec_header.ft_specific_header.record_type = BLOCK_TYPE_SYSTEMD_JOURNAL;
|
||||
wblock->rec->rec_header.ft_specific_header.record_len = entry_length;
|
||||
wblock->rec->rec_type = REC_TYPE_SYSTEMD_JOURNAL;
|
||||
wblock->rec->rec_header.systemd_journal_header.record_len = entry_length;
|
||||
wblock->rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
|
||||
wblock->rec->tsprec = WTAP_TSPREC_USEC;
|
||||
|
||||
|
@ -3863,23 +3862,23 @@ pcapng_write_systemd_journal_export_block(wtap_dumper *wdh, const wtap_rec *rec,
|
|||
guint32 pad_len;
|
||||
|
||||
/* Don't write anything we're not willing to read. */
|
||||
if (rec->rec_header.ft_specific_header.record_len > WTAP_MAX_PACKET_SIZE_STANDARD) {
|
||||
if (rec->rec_header.systemd_journal_header.record_len > WTAP_MAX_PACKET_SIZE_STANDARD) {
|
||||
*err = WTAP_ERR_PACKET_TOO_LARGE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (rec->rec_header.ft_specific_header.record_len % 4) {
|
||||
pad_len = 4 - (rec->rec_header.ft_specific_header.record_len % 4);
|
||||
if (rec->rec_header.systemd_journal_header.record_len % 4) {
|
||||
pad_len = 4 - (rec->rec_header.systemd_journal_header.record_len % 4);
|
||||
} else {
|
||||
pad_len = 0;
|
||||
}
|
||||
|
||||
/* write systemd journal export block header */
|
||||
bh.block_type = BLOCK_TYPE_SYSTEMD_JOURNAL;
|
||||
bh.block_total_length = (guint32)sizeof(bh) + rec->rec_header.ft_specific_header.record_len + pad_len + 4;
|
||||
bh.block_total_length = (guint32)sizeof(bh) + rec->rec_header.systemd_journal_header.record_len + pad_len + 4;
|
||||
|
||||
pcapng_debug("%s: writing %u bytes, %u padded", G_STRFUNC,
|
||||
rec->rec_header.ft_specific_header.record_len,
|
||||
rec->rec_header.systemd_journal_header.record_len,
|
||||
bh.block_total_length);
|
||||
|
||||
if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
|
||||
|
@ -3887,9 +3886,9 @@ pcapng_write_systemd_journal_export_block(wtap_dumper *wdh, const wtap_rec *rec,
|
|||
wdh->bytes_dumped += sizeof bh;
|
||||
|
||||
/* write entry data */
|
||||
if (!wtap_dump_file_write(wdh, pd, rec->rec_header.ft_specific_header.record_len, err))
|
||||
if (!wtap_dump_file_write(wdh, pd, rec->rec_header.systemd_journal_header.record_len, err))
|
||||
return FALSE;
|
||||
wdh->bytes_dumped += rec->rec_header.ft_specific_header.record_len;
|
||||
wdh->bytes_dumped += rec->rec_header.systemd_journal_header.record_len;
|
||||
|
||||
/* write padding (if any) */
|
||||
if (pad_len != 0) {
|
||||
|
@ -4824,12 +4823,6 @@ static gboolean pcapng_dump(wtap_dumper *wdh,
|
|||
|
||||
case REC_TYPE_FT_SPECIFIC_EVENT:
|
||||
case REC_TYPE_FT_SPECIFIC_REPORT:
|
||||
if (rec->rec_header.ft_specific_header.record_type == WTAP_FILE_TYPE_SUBTYPE_SYSTEMD_JOURNAL) {
|
||||
if (!pcapng_write_systemd_journal_export_block(wdh, rec, pd, err)) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#ifdef HAVE_PLUGINS
|
||||
/*
|
||||
* Do we have a handler for this block type?
|
||||
|
@ -4855,6 +4848,12 @@ static gboolean pcapng_dump(wtap_dumper *wdh,
|
|||
}
|
||||
break;
|
||||
|
||||
case REC_TYPE_SYSTEMD_JOURNAL:
|
||||
if (!pcapng_write_systemd_journal_export_block(wdh, rec, pd, err)) {
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* We don't support writing this record type. */
|
||||
*err = WTAP_ERR_UNWRITABLE_REC_TYPE;
|
||||
|
|
|
@ -225,10 +225,9 @@ systemd_journal_read_export_entry(FILE_T fh, wtap_rec *rec, Buffer *buf, int *er
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
rec->rec_type = REC_TYPE_FT_SPECIFIC_EVENT;
|
||||
rec->rec_type = REC_TYPE_SYSTEMD_JOURNAL;
|
||||
rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
|
||||
rec->rec_header.ft_specific_header.record_type = WTAP_FILE_TYPE_SUBTYPE_SYSTEMD_JOURNAL;
|
||||
rec->rec_header.ft_specific_header.record_len = (guint32) fld_end;
|
||||
rec->rec_header.systemd_journal_header.record_len = (guint32) fld_end;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -1296,6 +1296,7 @@ union wtap_pseudo_header {
|
|||
#define REC_TYPE_FT_SPECIFIC_EVENT 1 /**< file-type-specific event */
|
||||
#define REC_TYPE_FT_SPECIFIC_REPORT 2 /**< file-type-specific report */
|
||||
#define REC_TYPE_SYSCALL 3 /**< system call */
|
||||
#define REC_TYPE_SYSTEMD_JOURNAL 4 /**< systemd journal entry */
|
||||
|
||||
typedef struct {
|
||||
guint32 caplen; /* data length in the file */
|
||||
|
@ -1402,6 +1403,10 @@ typedef struct {
|
|||
/* ... Event ... */
|
||||
} wtap_syscall_header;
|
||||
|
||||
typedef struct {
|
||||
guint32 record_len; /* length of the record */
|
||||
} wtap_systemd_journal_header;
|
||||
|
||||
typedef struct {
|
||||
guint rec_type; /* what type of record is this? */
|
||||
guint32 presence_flags; /* what stuff do we have? */
|
||||
|
@ -1411,6 +1416,7 @@ typedef struct {
|
|||
wtap_packet_header packet_header;
|
||||
wtap_ft_specific_header ft_specific_header;
|
||||
wtap_syscall_header syscall_header;
|
||||
wtap_systemd_journal_header systemd_journal_header;
|
||||
} rec_header;
|
||||
/*
|
||||
* XXX - this should become a full set of options.
|
||||
|
|
Loading…
Reference in New Issue