aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2018-09-10 16:49:36 -0700
committerGerald Combs <gerald@wireshark.org>2018-09-26 21:31:13 +0000
commit123bcb0362a21ee1b498328e0be7fcad2a14f133 (patch)
tree761846e3f76363fa57f57edd158d04cbc42fd06d
parent56086e20b0c7de7eddb8db7901ad760a9139900b (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.c6
-rw-r--r--epan/dissectors/packet-frame.c2
-rw-r--r--epan/dissectors/packet-systemd-journal.c4
-rw-r--r--epan/frame_data.c5
-rw-r--r--wiretap/file_access.c14
-rw-r--r--wiretap/pcapng.c206
-rw-r--r--wiretap/pcapng_module.h23
-rw-r--r--wiretap/systemd_journal.c29
-rw-r--r--wiretap/wtap.c11
-rw-r--r--wiretap/wtap.h3
10 files changed, 263 insertions, 40 deletions
diff --git a/editcap.c b/editcap.c
index 7dbb52a47a..99985a636d 100644
--- a/editcap.c
+++ b/editcap.c
@@ -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 {