diff options
author | Gerald Combs <gerald@wireshark.org> | 2018-09-10 16:49:36 -0700 |
---|---|---|
committer | Gerald Combs <gerald@wireshark.org> | 2018-09-26 21:31:13 +0000 |
commit | 123bcb0362a21ee1b498328e0be7fcad2a14f133 (patch) | |
tree | 761846e3f76363fa57f57edd158d04cbc42fd06d | |
parent | 56086e20b0c7de7eddb8db7901ad760a9139900b (diff) |
Make systemd journal entries events.
Treat systemd journal entries filetype-specific events instead of
packets.
Add support for reading and writing systemd journal entries to pcapng.
Note that pcapng IDBs should be optional.
Add support for REC_TYPE_FT_SPECIFIC_EVENT where needed.
Change-Id: Ided999b1732108f480c6c75323a0769a9d9ef09f
Reviewed-on: https://code.wireshark.org/review/29611
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Gerald Combs <gerald@wireshark.org>
-rw-r--r-- | editcap.c | 6 | ||||
-rw-r--r-- | epan/dissectors/packet-frame.c | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-systemd-journal.c | 4 | ||||
-rw-r--r-- | epan/frame_data.c | 5 | ||||
-rw-r--r-- | wiretap/file_access.c | 14 | ||||
-rw-r--r-- | wiretap/pcapng.c | 206 | ||||
-rw-r--r-- | wiretap/pcapng_module.h | 23 | ||||
-rw-r--r-- | wiretap/systemd_journal.c | 29 | ||||
-rw-r--r-- | wiretap/wtap.c | 11 | ||||
-rw-r--r-- | wiretap/wtap.h | 3 |
10 files changed, 263 insertions, 40 deletions
@@ -1781,6 +1781,12 @@ main(int argc, char *argv[]) do_mutation = TRUE; break; + case REC_TYPE_FT_SPECIFIC_EVENT: + case REC_TYPE_FT_SPECIFIC_REPORT: + caplen = rec->rec_header.ft_specific_header.record_len; + do_mutation = TRUE; + break; + case REC_TYPE_SYSCALL: caplen = rec->rec_header.syscall_header.event_filelen; do_mutation = TRUE; diff --git a/epan/dissectors/packet-frame.c b/epan/dissectors/packet-frame.c index 55e0cd90ab..7dac6b8120 100644 --- a/epan/dissectors/packet-frame.c +++ b/epan/dissectors/packet-frame.c @@ -598,7 +598,7 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* if (!dissector_try_uint(wtap_fts_rec_dissector_table, file_type_subtype, tvb, pinfo, parent_tree)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN"); - col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %d", + col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP FT ST = %d", file_type_subtype); call_data_dissector(tvb, pinfo, parent_tree); } diff --git a/epan/dissectors/packet-systemd-journal.c b/epan/dissectors/packet-systemd-journal.c index 96ac543c9f..dff789d011 100644 --- a/epan/dissectors/packet-systemd-journal.c +++ b/epan/dissectors/packet-systemd-journal.c @@ -826,6 +826,7 @@ proto_register_systemd_journal(void) init_jf_to_hf_map(); } +#define BLOCK_TYPE_SYSTEMD_JOURNAL 0x0000009 void proto_reg_handoff_systemd_journal(void) { @@ -836,7 +837,8 @@ proto_reg_handoff_systemd_journal(void) proto_systemd_journal); } - dissector_add_uint("wtap_encap", WTAP_ENCAP_SYSTEMD_JOURNAL, sje_handle); + 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 // systemd-journal-remote. Dissecting them on the wire isn't very // useful since it's easy to end up with a packet containing a diff --git a/epan/frame_data.c b/epan/frame_data.c index 4d95c07c8c..4cbb60f802 100644 --- a/epan/frame_data.c +++ b/epan/frame_data.c @@ -179,8 +179,9 @@ frame_data_init(frame_data *fdata, guint32 num, const wtap_rec *rec, /* * XXX */ - fdata->pkt_len = 0; - fdata->cap_len = 0; + fdata->pkt_len = rec->rec_header.ft_specific_header.record_len; + fdata->cum_bytes = cum_bytes + rec->rec_header.ft_specific_header.record_len; + fdata->cap_len = rec->rec_header.ft_specific_header.record_len; break; case REC_TYPE_SYSCALL: diff --git a/wiretap/file_access.c b/wiretap/file_access.c index 9b2f1011c0..39e404d6a6 100644 --- a/wiretap/file_access.c +++ b/wiretap/file_access.c @@ -1622,6 +1622,16 @@ static const struct file_type_subtype_info dump_open_table_base[] = { /* WTAP_FILE_TYPE_SUBTYPE_RFC7468 */ { "RFC 7468 files", "rfc7468", NULL, NULL, FALSE, FALSE, 0, + NULL, NULL, NULL }, + + /* WTAP_FILE_TYPE_SUBTYPE_RUBY_MARSHAL */ + { "Ruby marshal files", "ruby_marshal", NULL, NULL, + FALSE, FALSE, 0, + NULL, NULL, NULL }, + + /* WTAP_FILE_TYPE_SUBTYPE_SYSTEMD_JOURNAL */ + { "systemd journal export", "systemd journal", NULL, NULL, + FALSE, FALSE, 0, NULL, NULL, NULL } }; @@ -2250,7 +2260,6 @@ wtap_dump_init_dumper(int file_type_subtype, int encap, int snaplen, gboolean co /* Note: this memory is owned by wtap_dumper and will become * invalid after wtap_dump_close. */ - wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); for (itf_count = 0; itf_count < idb_inf->interface_data->len; itf_count++) { file_int_data = g_array_index(idb_inf->interface_data, wtap_block_t, itf_count); file_int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(file_int_data); @@ -2263,6 +2272,7 @@ wtap_dump_init_dumper(int file_type_subtype, int encap, int snaplen, gboolean co g_array_append_val(wdh->interface_data, descr); } } else { + // XXX IDBs should be optional. descr = wtap_block_create(WTAP_BLOCK_IF_DESCR); descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(descr); descr_mand->wtap_encap = encap; @@ -2289,7 +2299,6 @@ wtap_dump_init_dumper(int file_type_subtype, int encap, int snaplen, gboolean co descr_mand->snap_len = snaplen; descr_mand->num_stat_entries = 0; /* Number of ISB:s */ descr_mand->interface_statistics = NULL; - wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); g_array_append_val(wdh->interface_data, descr); } return wdh; @@ -2542,6 +2551,7 @@ wtap_dump_alloc_wdh(int file_type_subtype, int encap, int snaplen, gboolean comp wdh->encap = encap; wdh->compressed = compressed; wdh->wslua_data = NULL; + wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); return wdh; } diff --git a/wiretap/pcapng.c b/wiretap/pcapng.c index fa84530e68..90c56147f3 100644 --- a/wiretap/pcapng.c +++ b/wiretap/pcapng.c @@ -45,6 +45,9 @@ pcapng_seek_read(wtap *wth, gint64 seek_off, static void pcapng_close(wtap *wth); +static gboolean +pcapng_encap_is_ft_specific(int encap); + /* * Minimum block size = size of block header + size of block trailer. */ @@ -126,6 +129,15 @@ typedef struct pcapng_name_resolution_block_s { #define SYSDIG_EVENT_HEADER_SIZE ((16 + 64 + 64 + 32 + 16)/8) /* CPU ID + TS + TID + Event len + Event type */ #define MIN_SYSDIG_EVENT_SIZE ((guint32)(MIN_BLOCK_SIZE + SYSDIG_EVENT_HEADER_SIZE)) +/* + * We require __CURSOR + __REALTIME_TIMESTAMP + __MONOTONIC_TIMESTAMP in + * systemd journal export entries, which is 200 bytes or so (203 on a test + * system here). + */ +#define SDJ__REALTIME_TIMESTAMP "__REALTIME_TIMESTAMP=" +#define MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE 200 +#define MIN_SYSTEMD_JOURNAL_EXPORT_BLOCK_SIZE ((guint32)(MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE + MIN_BLOCK_SIZE)) + /* pcapng: common option header file encoding for every option type */ typedef struct pcapng_option_header_s { guint16 option_code; @@ -249,6 +261,7 @@ register_pcapng_block_type_handler(guint block_type, block_reader reader, case BLOCK_TYPE_ISB: case BLOCK_TYPE_EPB: case BLOCK_TYPE_SYSDIG_EVENT: + case BLOCK_TYPE_SYSTEMD_JOURNAL: /* * Yes; we already handle it, and don't allow a replacement to * be registeted (if there's a bug in our code, or there's @@ -2229,6 +2242,106 @@ pcapng_read_sysdig_event_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *p } static gboolean +pcapng_read_systemd_journal_export_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn _U_, wtapng_block_t *wblock, int *err, gchar **err_info) +{ + guint32 entry_length; + guint32 block_total_length; + guint64 rt_ts; + + if (bh->block_total_length < MIN_SYSTEMD_JOURNAL_EXPORT_BLOCK_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_SYSTEMD_JOURNAL_EXPORT_BLOCK_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("%s: block_total_length %u", G_STRFUNC, bh->block_total_length); + + entry_length = block_total_length - MIN_BLOCK_SIZE; + + /* Includes padding bytes. */ + if (!wtap_read_packet_bytes(fh, wblock->frame_buffer, + entry_length, err, err_info)) { + return FALSE; + } + + /* We don't have memmem available everywhere, so we get to use strstr. */ + ws_buffer_append(wblock->frame_buffer, (guint8 * ) "", 1); + + gchar *buf_ptr = (gchar *) ws_buffer_start_ptr(wblock->frame_buffer); + while (entry_length > 0 && buf_ptr[entry_length] == '\0') { + entry_length--; + } + + if (entry_length < MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE) { + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup_printf("%s: entry length %u is too small (< %u)", G_STRFUNC, + bh->block_total_length, MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE); + return FALSE; + } + + pcapng_debug("%s: entry_length %u", G_STRFUNC, entry_length); + + size_t rt_ts_len = sizeof(SDJ__REALTIME_TIMESTAMP); + char *ts_pos = strstr(buf_ptr, SDJ__REALTIME_TIMESTAMP); + + if (!ts_pos) { + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup_printf("%s: no timestamp", G_STRFUNC); + return FALSE; + } + + if (ts_pos+rt_ts_len >= (char *) buf_ptr+entry_length) { + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup_printf("%s: timestamp past end of buffer", G_STRFUNC); + return FALSE; + } + + errno = 0; + rt_ts = strtoul(ts_pos+rt_ts_len, NULL, 10); + if (errno) { + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup_printf("%s: invalid timestamp", G_STRFUNC); + 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->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; + wblock->rec->tsprec = WTAP_TSPREC_USEC; + + wblock->rec->rec_header.syscall_header.byte_order = G_BYTE_ORDER; + + wblock->rec->ts.secs = (time_t) (rt_ts / 1000000000); + wblock->rec->ts.nsecs = (int) (rt_ts % 1000000000); + + /* + * We return these to the caller in pcapng_read(). + */ + wblock->internal = FALSE; + + if (wth->file_encap == WTAP_ENCAP_UNKNOWN) { + /* + * Nothing (most notably an IDB) has set a file encap at this point. + * Do so here. + * XXX Should we set WTAP_ENCAP_SYSTEMD_JOURNAL if appropriate? + */ + wth->file_encap = WTAP_ENCAP_PER_PACKET; + } + + return TRUE; +} + +static gboolean pcapng_read_unknown_block(FILE_T fh, pcapng_block_header_t *bh, # #ifdef HAVE_PLUGINS @@ -2412,6 +2525,10 @@ pcapng_read_block(wtap *wth, FILE_T fh, pcapng_t *pn, wtapng_block_t *wblock, in if (!pcapng_read_sysdig_event_block(fh, &bh, pn, wblock, err, err_info)) return PCAPNG_BLOCK_ERROR; break; + case(BLOCK_TYPE_SYSTEMD_JOURNAL): + if (!pcapng_read_systemd_journal_export_block(wth, 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)) @@ -3268,6 +3385,59 @@ pcapng_write_sysdig_event_block(wtap_dumper *wdh, const wtap_rec *rec, } +static gboolean +pcapng_write_systemd_journal_export_block(wtap_dumper *wdh, const wtap_rec *rec, + const guint8 *pd, int *err) +{ + pcapng_block_header_t bh; + const guint32 zero_pad = 0; + 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) { + *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); + } 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; + + pcapng_debug("%s: writing %u bytes, %u padded", G_STRFUNC, + rec->rec_header.ft_specific_header.record_len, + bh.block_total_length); + + if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err)) + return FALSE; + wdh->bytes_dumped += sizeof bh; + + /* write entry data */ + if (!wtap_dump_file_write(wdh, pd, rec->rec_header.ft_specific_header.record_len, err)) + return FALSE; + wdh->bytes_dumped += rec->rec_header.ft_specific_header.record_len; + + /* write padding (if any) */ + if (pad_len != 0) { + if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err)) + return FALSE; + wdh->bytes_dumped += pad_len; + } + + /* write block footer */ + if (!wtap_dump_file_write(wdh, &bh.block_total_length, + sizeof bh.block_total_length, err)) + return FALSE; + + return TRUE; + +} + /* * libpcap's maximum pcapng block size is currently 16MB. * @@ -4021,8 +4191,10 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_block_t int_data, int *err) link_type = wtap_wtap_encap_to_pcap_encap(mand_data->wtap_encap); if (link_type == -1) { - *err = WTAP_ERR_UNWRITABLE_ENCAP; - return FALSE; + if (!pcapng_encap_is_ft_specific(mand_data->wtap_encap)) { + *err = WTAP_ERR_UNWRITABLE_ENCAP; + return FALSE; + } } /* Compute block size */ @@ -4087,9 +4259,10 @@ static gboolean pcapng_dump(wtap_dumper *wdh, block_handler *handler; #endif - pcapng_debug("pcapng_dump: encap = %d (%s)", + pcapng_debug("%s: encap = %d (%s) rec type = %u", G_STRFUNC, rec->rec_header.packet_header.pkt_encap, - wtap_encap_string(rec->rec_header.packet_header.pkt_encap)); + wtap_encap_string(rec->rec_header.packet_header.pkt_encap), + rec->rec_type); switch (rec->rec_type) { @@ -4106,6 +4279,12 @@ 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? @@ -4187,6 +4366,7 @@ pcapng_dump_open(wtap_dumper *wdh, int *err) wdh->subtype_write = pcapng_dump; wdh->subtype_finish = pcapng_dump_finish; + // XXX IDBs should be optional. if (wdh->interface_data->len == 0) { pcapng_debug("There are no interfaces. Can't handle that..."); *err = WTAP_ERR_INTERNAL; @@ -4232,6 +4412,11 @@ int pcapng_dump_can_write_encap(int wtap_encap) if (wtap_encap == WTAP_ENCAP_PER_PACKET) return 0; + /* Is it a filetype-specific encapsulation that we support? */ + if (pcapng_encap_is_ft_specific(wtap_encap)) { + return 0; + } + /* Make sure we can figure out this DLT type */ if (wtap_wtap_encap_to_pcap_encap(wtap_encap) == -1) return WTAP_ERR_UNWRITABLE_ENCAP; @@ -4240,6 +4425,19 @@ int pcapng_dump_can_write_encap(int wtap_encap) } /* + * Returns TRUE if the specified encapsulation type is filetype-specific + * and one that we support. + */ +gboolean pcapng_encap_is_ft_specific(int encap) +{ + switch (encap) { + case WTAP_ENCAP_SYSTEMD_JOURNAL: + return TRUE; + } + return FALSE; +} + +/* * Editor modelines - https://www.wireshark.org/tools/modelines.html * * Local variables: diff --git a/wiretap/pcapng_module.h b/wiretap/pcapng_module.h index cf914ceeab..01abd39f49 100644 --- a/wiretap/pcapng_module.h +++ b/wiretap/pcapng_module.h @@ -15,17 +15,18 @@ * * XXX - Dear Sysdig People: please add your blocks to the spec! */ -#define BLOCK_TYPE_SHB 0x0A0D0D0A /* Section Header Block */ -#define BLOCK_TYPE_IDB 0x00000001 /* Interface Description Block */ -#define BLOCK_TYPE_PB 0x00000002 /* Packet Block (obsolete) */ -#define BLOCK_TYPE_SPB 0x00000003 /* Simple Packet Block */ -#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_IRIG_TS 0x00000007 /* IRIG Timestamp Block */ -#define BLOCK_TYPE_ARINC_429 0x00000008 /* ARINC 429 in AFDX Encapsulation Information 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 */ +#define BLOCK_TYPE_IDB 0x00000001 /* Interface Description Block */ +#define BLOCK_TYPE_PB 0x00000002 /* Packet Block (obsolete) */ +#define BLOCK_TYPE_SPB 0x00000003 /* Simple Packet Block */ +#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_IRIG_TS 0x00000007 /* IRIG Timestamp Block */ +#define BLOCK_TYPE_ARINC_429 0x00000008 /* ARINC 429 in AFDX Encapsulation Information Block */ +#define BLOCK_TYPE_SYSTEMD_JOURNAL 0x00000009 /* systemd journal entry */ +#define BLOCK_TYPE_SYSDIG_EVENT 0x00000204 /* Sysdig Event Block */ +#define BLOCK_TYPE_SYSDIG_EVF 0x00000208 /* Sysdig Event Block with flags */ /* TODO: the following are not yet well defined in the draft spec, * and do not yet have block type values assigned to them: diff --git a/wiretap/systemd_journal.c b/wiretap/systemd_journal.c index 886cac3e42..cda48b01c8 100644 --- a/wiretap/systemd_journal.c +++ b/wiretap/systemd_journal.c @@ -12,6 +12,7 @@ #include <string.h> #include <stdlib.h> #include "wtap-int.h" +#include "pcapng_module.h" #include "file_wrappers.h" #include "systemd_journal.h" @@ -91,6 +92,7 @@ wtap_open_return_val systemd_journal_open(wtap *wth, int *err _U_, gchar **err_i return WTAP_OPEN_NOT_MINE; } + wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_SYSTEMD_JOURNAL; wth->subtype_read = systemd_journal_read; wth->subtype_seek_read = systemd_journal_seek_read; wth->file_encap = WTAP_ENCAP_SYSTEMD_JOURNAL; @@ -137,7 +139,7 @@ static gboolean systemd_journal_read_export_entry(FILE_T fh, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info) { size_t fld_end = 0; - gchar *entry_buff = (gchar*) g_malloc(MAX_EXPORT_ENTRY_LENGTH); + gchar *buf_ptr; gchar *entry_line = NULL; gboolean got_cursor = FALSE; gboolean got_rt_ts = FALSE; @@ -146,8 +148,11 @@ systemd_journal_read_export_entry(FILE_T fh, wtap_rec *rec, Buffer *buf, int *er int line_num; size_t rt_ts_len = strlen(FLD__REALTIME_TIMESTAMP); + ws_buffer_assure_space(buf, MAX_EXPORT_ENTRY_LENGTH); + buf_ptr = (gchar *) ws_buffer_start_ptr(buf); + for (line_num = 0; line_num < MAX_EXPORT_ENTRY_LINES; line_num++) { - entry_line = file_gets(entry_buff + fld_end, MAX_EXPORT_ENTRY_LENGTH - (int) fld_end, fh); + entry_line = file_gets(buf_ptr + fld_end, MAX_EXPORT_ENTRY_LENGTH - (int) fld_end, fh); if (!entry_line) { break; } @@ -179,7 +184,7 @@ systemd_journal_read_export_entry(FILE_T fh, wtap_rec *rec, Buffer *buf, int *er if (!wtap_read_bytes(fh, &le_data_len, 8, err, err_info)) { return FALSE; } - memcpy(entry_buff + fld_end, &le_data_len, 8); + memcpy(buf_ptr + fld_end, &le_data_len, 8); fld_end += 8; data_len = pletoh64(&le_data_len); if (data_len < 1 || data_len - 1 >= MAX_EXPORT_ENTRY_LENGTH - fld_end) { @@ -188,7 +193,7 @@ systemd_journal_read_export_entry(FILE_T fh, wtap_rec *rec, Buffer *buf, int *er return FALSE; } // Data + trailing \n - if (!wtap_read_bytes(fh, entry_buff + fld_end, (unsigned) data_len + 1, err, err_info)) { + if (!wtap_read_bytes(fh, buf_ptr + fld_end, (unsigned) data_len + 1, err, err_info)) { return FALSE; } fld_end += (size_t) data_len + 1; @@ -199,25 +204,17 @@ systemd_journal_read_export_entry(FILE_T fh, wtap_rec *rec, Buffer *buf, int *er } if (!got_cursor || !got_rt_ts || !got_mt_ts) { - g_free(entry_buff); return FALSE; } if (!got_double_newline && !file_eof(fh)) { - g_free(entry_buff); return FALSE; } - rec->rec_type = REC_TYPE_PACKET; - rec->presence_flags = WTAP_HAS_TS; - rec->rec_header.packet_header.caplen = (guint32) fld_end; - rec->rec_header.packet_header.len = rec->rec_header.packet_header.caplen; - - ws_buffer_assure_space(buf, rec->rec_header.packet_header.caplen + 1); - guint8 *pd = ws_buffer_start_ptr(buf); - entry_buff[fld_end+1] = '\0'; - memcpy(pd, entry_buff, rec->rec_header.packet_header.caplen + 1); - g_free(entry_buff); + rec->rec_type = REC_TYPE_FT_SPECIFIC_EVENT; + 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; return TRUE; } diff --git a/wiretap/wtap.c b/wiretap/wtap.c index 259d3bf3f1..bac88d8be2 100644 --- a/wiretap/wtap.c +++ b/wiretap/wtap.c @@ -930,6 +930,9 @@ static struct encap_type_info encap_table_base[] = { /* WTAP_ENCAP_RFC7468 */ { "RFC 7468 file", "rfc7468" }, + + /* WTAP_ENCAP_SYSTEMD_JOURNAL */ + { "systemd journal", "sdjournal" } }; WS_DLL_LOCAL @@ -1363,8 +1366,12 @@ wtap_read_packet_bytes(FILE_T fh, Buffer *buf, guint length, int *err, gchar **err_info) { ws_buffer_assure_space(buf, length); - return wtap_read_bytes(fh, ws_buffer_start_ptr(buf), length, err, - err_info); + if (wtap_read_bytes(fh, ws_buffer_start_ptr(buf), length, err, + err_info)) { + ws_buffer_increase_length(buf, length); + return TRUE; + } + return FALSE; } /* diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 7851852a57..2146a42124 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -283,7 +283,7 @@ extern "C" { #define WTAP_ENCAP_DPAUXMON 200 #define WTAP_ENCAP_RUBY_MARSHAL 201 #define WTAP_ENCAP_RFC7468 202 -#define WTAP_ENCAP_SYSTEMD_JOURNAL 203 +#define WTAP_ENCAP_SYSTEMD_JOURNAL 203 /* Event, not a packet */ /* After adding new item here, please also add new item to encap_table_base array */ @@ -1268,6 +1268,7 @@ typedef struct { typedef struct { guint record_type; /* the type of record this is - file type-specific value */ + guint32 record_len; /* length of the record */ } wtap_ft_specific_header; typedef struct { |