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>
This commit is contained in:
parent
56086e20b0
commit
123bcb0362
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -1621,6 +1621,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;
|
||||
}
|
||||
|
||||
|
|
206
wiretap/pcapng.c
206
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
|
||||
|
@ -2228,6 +2241,106 @@ pcapng_read_sysdig_event_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *p
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
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,
|
||||
#
|
||||
|
@ -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;
|
||||
|
@ -4239,6 +4424,19 @@ int pcapng_dump_can_write_encap(int wtap_encap)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue