aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-frame.c46
-rw-r--r--epan/frame_data.c10
-rw-r--r--epan/packet.c8
-rw-r--r--wiretap/pcapng.c168
-rw-r--r--wiretap/pcapng_module.h2
-rw-r--r--wiretap/wtap.h8
-rw-r--r--wiretap/wtap_opttypes.h1
7 files changed, 242 insertions, 1 deletions
diff --git a/epan/dissectors/packet-frame.c b/epan/dissectors/packet-frame.c
index cdbe5617bc..020c32a410 100644
--- a/epan/dissectors/packet-frame.c
+++ b/epan/dissectors/packet-frame.c
@@ -30,6 +30,7 @@
#include <wsutil/wsgcrypt.h>
#include <wsutil/str_util.h>
#include <epan/proto_data.h>
+#include <epan/addr_resolv.h>
#include <wmem/wmem.h>
#include "packet-frame.h"
@@ -90,6 +91,8 @@ static int hf_frame_pack_start_frame_delimiter_error = -1;
static int hf_frame_pack_preamble_error = -1;
static int hf_frame_pack_symbol_error = -1;
static int hf_frame_wtap_encap = -1;
+static int hf_frame_cb_pen = -1;
+static int hf_frame_cb_copy_allowed = -1;
static int hf_comments_text = -1;
static gint ett_frame = -1;
@@ -385,6 +388,10 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
pinfo->current_proto = "Systemd Journal";
break;
+ case REC_TYPE_CUSTOM_BLOCK:
+ pinfo->current_proto = "PCAPNG Custom Block";
+ break;
+
default:
DISSECTOR_ASSERT_NOT_REACHED();
break;
@@ -512,6 +519,20 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
"Systemd Journal Entry %u: %u byte%s",
pinfo->num, frame_len, frame_plurality);
break;
+
+ case REC_TYPE_CUSTOM_BLOCK:
+ ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, tvb_captured_length(tvb),
+ "PCAPNG Custom Block %u: %u byte%s",
+ pinfo->num, frame_len, frame_plurality);
+ if (generate_bits_field) {
+ proto_item_append_text(ti, " (%u bits)", frame_len * 8);
+ }
+ proto_item_append_text(ti, " of custom data and options, PEN %s (%u)",
+ enterprises_lookup(pinfo->rec->rec_header.custom_block_header.pen, "Unknown"),
+ pinfo->rec->rec_header.custom_block_header.pen);
+ proto_item_append_text(ti, ", copying%s allowed",
+ pinfo->rec->rec_header.custom_block_header.copy_allowed ? "" : " not");
+ break;
}
fh_tree = proto_item_add_subtree(ti, ett_frame);
@@ -830,6 +851,21 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
(void *)pinfo->pseudo_header);
}
break;
+
+ case REC_TYPE_CUSTOM_BLOCK:
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PCAPNG");
+ proto_tree_add_uint_format_value(fh_tree, hf_frame_cb_pen, tvb, 0, 0,
+ pinfo->rec->rec_header.custom_block_header.pen,
+ "%s (%u)",
+ enterprises_lookup(pinfo->rec->rec_header.custom_block_header.pen, "Unknown"),
+ pinfo->rec->rec_header.custom_block_header.pen);
+ proto_tree_add_boolean(fh_tree, hf_frame_cb_copy_allowed, tvb, 0, 0, pinfo->rec->rec_header.custom_block_header.copy_allowed);
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Custom Block: PEN = %s (%d), will%s be copied",
+ enterprises_lookup(pinfo->rec->rec_header.custom_block_header.pen, "Unknown"),
+ pinfo->rec->rec_header.custom_block_header.pen,
+ pinfo->rec->rec_header.custom_block_header.copy_allowed ? "" : " not");
+ call_data_dissector(tvb, pinfo, parent_tree);
+ break;
}
#ifdef _MSC_VER
} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
@@ -1216,6 +1252,16 @@ proto_register_frame(void)
{ "Drop Count", "frame.drop_count",
FT_UINT64, BASE_DEC, NULL, 0x0,
"Number of frames lost between this frame and the preceding one on the same interface", HFILL }},
+
+ { &hf_frame_cb_pen,
+ { "Private Enterprise Number", "frame.cb_pen",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "IANA assigned private enterprise number (PEN)", HFILL }},
+
+ { &hf_frame_cb_copy_allowed,
+ { "Copying", "frame.cb_copy",
+ FT_BOOLEAN, BASE_DEC, TFS(&tfs_allowed_not_allowed), 0x0,
+ "Whether the custom block will be written or not", HFILL }},
};
static hf_register_info hf_encap =
diff --git a/epan/frame_data.c b/epan/frame_data.c
index 1900b6ac59..43dc081b74 100644
--- a/epan/frame_data.c
+++ b/epan/frame_data.c
@@ -201,6 +201,16 @@ frame_data_init(frame_data *fdata, guint32 num, const wtap_rec *rec,
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;
+
+ case REC_TYPE_CUSTOM_BLOCK:
+ /*
+ * XXX - is cum_bytes supposed to count non-packet bytes?
+ */
+ fdata->pkt_len = rec->rec_header.custom_block_header.length;
+ fdata->cum_bytes = cum_bytes + rec->rec_header.custom_block_header.length;
+ fdata->cap_len = rec->rec_header.custom_block_header.length;
+ break;
+
}
/* To save some memory, we coerce it into 4 bits */
diff --git a/epan/packet.c b/epan/packet.c
index 0171d5c3a1..5315a28c15 100644
--- a/epan/packet.c
+++ b/epan/packet.c
@@ -504,6 +504,10 @@ dissect_record(epan_dissect_t *edt, int file_type_subtype,
record_type = "Systemd Journal Entry";
break;
+ case REC_TYPE_CUSTOM_BLOCK:
+ record_type = "PCAPNG Custom Block";
+ break;
+
default:
/*
* XXX - if we add record types that shouldn't be
@@ -551,6 +555,10 @@ dissect_record(epan_dissect_t *edt, int file_type_subtype,
case REC_TYPE_SYSTEMD_JOURNAL:
edt->pi.pseudo_header = NULL;
break;
+
+ case REC_TYPE_CUSTOM_BLOCK:
+ edt->pi.pseudo_header = NULL;
+ break;
}
edt->pi.fd = fd;
diff --git a/wiretap/pcapng.c b/wiretap/pcapng.c
index 6e9d5bd675..923ad242fe 100644
--- a/wiretap/pcapng.c
+++ b/wiretap/pcapng.c
@@ -121,6 +121,18 @@ typedef struct pcapng_name_resolution_block_s {
*/
#define MIN_NRB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_name_resolution_block_t)))
+/* pcapng: custom block file encoding */
+typedef struct pcapng_custom_block_s {
+ guint32 pen;
+ /* Custom data and options */
+} pcapng_custom_block_t;
+
+/*
+ * Minimum CB size = minimum block size + size of fixed length portion of CB.
+ */
+
+#define MIN_CB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_custom_block_t)))
+
/*
* Minimum ISB size = minimum block size + size of fixed length portion of ISB.
*/
@@ -281,6 +293,8 @@ register_pcapng_block_type_handler(guint block_type, block_reader reader,
case BLOCK_TYPE_ISB:
case BLOCK_TYPE_EPB:
case BLOCK_TYPE_DSB:
+ case BLOCK_TYPE_CB_COPY:
+ case BLOCK_TYPE_CB_NO_COPY:
case BLOCK_TYPE_SYSDIG_EVENT:
case BLOCK_TYPE_SYSDIG_EVENT_V2:
case BLOCK_TYPE_SYSTEMD_JOURNAL:
@@ -2365,6 +2379,77 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh,
}
static gboolean
+pcapng_handle_generic_custom_block(FILE_T fh, pcapng_block_header_t *bh,
+ guint32 pen, wtapng_block_t *wblock,
+ int *err, gchar **err_info)
+{
+ guint to_read;
+
+ ws_debug("unknown pen %u", pen);
+ if (bh->block_total_length % 4) {
+ to_read = bh->block_total_length + 4 - (bh->block_total_length % 4);
+ } else {
+ to_read = bh->block_total_length;
+ }
+ to_read -= MIN_CB_SIZE;
+ wblock->rec->rec_type = REC_TYPE_CUSTOM_BLOCK;
+ wblock->rec->presence_flags = 0;
+ wblock->rec->rec_header.custom_block_header.length = bh->block_total_length - MIN_CB_SIZE;
+ wblock->rec->rec_header.custom_block_header.pen = pen;
+ wblock->rec->rec_header.custom_block_header.copy_allowed = (bh->block_type == BLOCK_TYPE_CB_COPY);
+ if (!wtap_read_packet_bytes(fh, wblock->frame_buffer, to_read, err, err_info)) {
+ return FALSE;
+ }
+ /*
+ * We return these to the caller in pcapng_read().
+ */
+ wblock->internal = FALSE;
+ return TRUE;
+}
+static gboolean
+pcapng_read_custom_block(FILE_T fh, pcapng_block_header_t *bh,
+ const section_info_t *section_info,
+ wtapng_block_t *wblock,
+ int *err, gchar **err_info)
+{
+ pcapng_custom_block_t cb;
+ guint32 pen;
+
+ /* Is this block long enough to be an CB? */
+ if (bh->block_total_length < MIN_CB_SIZE) {
+ /*
+ * No.
+ */
+ *err = WTAP_ERR_BAD_FILE;
+ *err_info = g_strdup_printf("pcapng_read_custom_block: total block length %u is too small (< %u)",
+ bh->block_total_length, MIN_CB_SIZE);
+ return FALSE;
+ }
+
+ /* Custom block read fixed part */
+ if (!wtap_read_bytes(fh, &cb, sizeof cb, err, err_info)) {
+ ws_debug("failed to read pen");
+ return FALSE;
+ }
+ if (section_info->byte_swapped) {
+ pen = GUINT32_SWAP_LE_BE(cb.pen);
+ } else {
+ pen = cb.pen;
+ }
+ ws_debug("pen %u, custom data and option length %u", pen, bh->block_total_length - MIN_CB_SIZE);
+
+ switch (pen) {
+ default:
+ if (!pcapng_handle_generic_custom_block(fh, bh, pen, wblock, err, err_info)) {
+ return FALSE;
+ }
+ break;
+ }
+
+ return TRUE;
+}
+
+static gboolean
pcapng_read_sysdig_event_block(FILE_T fh, pcapng_block_header_t *bh,
const section_info_t *section_info,
wtapng_block_t *wblock,
@@ -2794,6 +2879,11 @@ pcapng_read_block(wtap *wth, FILE_T fh, pcapng_t *pn,
if (!pcapng_read_decryption_secrets_block(fh, &bh, section_info, wblock, err, err_info))
return FALSE;
break;
+ case(BLOCK_TYPE_CB_COPY):
+ case(BLOCK_TYPE_CB_NO_COPY):
+ if (!pcapng_read_custom_block(fh, &bh, section_info, wblock, err, err_info))
+ return FALSE;
+ break;
case(BLOCK_TYPE_SYSDIG_EVENT):
case(BLOCK_TYPE_SYSDIG_EVENT_V2):
/* case(BLOCK_TYPE_SYSDIG_EVF): */
@@ -3113,7 +3203,7 @@ pcapng_read(wtap *wth, wtap_rec *rec, Buffer *buf, int *err,
* Read the next block.
*/
if (!pcapng_read_block(wth, wth->fh, pcapng, current_section,
- &new_section, &wblock, err, err_info)) {
+ &new_section, &wblock, err, err_info)) {
ws_debug("data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset);
ws_debug("couldn't read packet block");
wtap_block_free(wblock.block);
@@ -4087,6 +4177,73 @@ pcapng_write_systemd_journal_export_block(wtap_dumper *wdh, const wtap_rec *rec,
}
static gboolean
+pcapng_write_custom_block(wtap_dumper *wdh, const wtap_rec *rec,
+ const guint8 *pd, int *err)
+{
+ pcapng_block_header_t bh;
+ pcapng_custom_block_t cb;
+ const guint32 zero_pad = 0;
+ guint32 pad_len;
+
+ /* Don't write anything we are not supposed to. */
+ if (!rec->rec_header.custom_block_header.copy_allowed) {
+ return TRUE;
+ }
+
+ /* Don't write anything we're not willing to read. */
+ if (rec->rec_header.custom_block_header.length > WTAP_MAX_PACKET_SIZE_STANDARD) {
+ *err = WTAP_ERR_PACKET_TOO_LARGE;
+ return FALSE;
+ }
+
+ if (rec->rec_header.custom_block_header.length % 4) {
+ pad_len = 4 - (rec->rec_header.custom_block_header.length % 4);
+ } else {
+ pad_len = 0;
+ }
+
+ /* write block header */
+ bh.block_type = BLOCK_TYPE_CB_COPY;
+ bh.block_total_length = (guint32)sizeof(bh) + (guint32)sizeof(cb) + rec->rec_header.custom_block_header.length + pad_len + 4;
+ ws_debug("writing %u bytes, %u padded",
+ rec->rec_header.custom_block_header.length,
+ bh.block_total_length);
+ if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err)) {
+ return FALSE;
+ }
+ wdh->bytes_dumped += sizeof bh;
+
+ /* write custom block header */
+ cb.pen = rec->rec_header.custom_block_header.pen;
+ if (!wtap_dump_file_write(wdh, &cb, sizeof cb, err)) {
+ return FALSE;
+ }
+ wdh->bytes_dumped += sizeof cb;
+
+ /* write custom data */
+ if (!wtap_dump_file_write(wdh, pd, rec->rec_header.custom_block_header.length, err)) {
+ return FALSE;
+ }
+ wdh->bytes_dumped += rec->rec_header.custom_block_header.length;
+
+ /* 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;
+}
+
+static gboolean
pcapng_write_decryption_secrets_block(wtap_dumper *wdh, wtap_block_t sdata, int *err)
{
pcapng_block_header_t bh;
@@ -5041,6 +5198,12 @@ static gboolean pcapng_dump(wtap_dumper *wdh,
}
break;
+ case REC_TYPE_CUSTOM_BLOCK:
+ if (!pcapng_write_custom_block(wdh, rec, pd, err)) {
+ return FALSE;
+ }
+ break;
+
default:
/* We don't support writing this record type. */
*err = WTAP_ERR_UNWRITABLE_REC_TYPE;
@@ -5281,6 +5444,9 @@ static const struct supported_block_type pcapng_blocks_supported[] = {
/* Multiple systemd journal records. */
{ WTAP_BLOCK_SYSTEMD_JOURNAL, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(systemd_journal_block_options_supported) },
+
+ /* Multiple custom blocks. */
+ { WTAP_BLOCK_CUSTOM_BLOCK, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED },
};
static const struct file_type_subtype_info pcapng_info = {
diff --git a/wiretap/pcapng_module.h b/wiretap/pcapng_module.h
index 745a6985e3..8f3eeee2d9 100644
--- a/wiretap/pcapng_module.h
+++ b/wiretap/pcapng_module.h
@@ -30,6 +30,8 @@
#define BLOCK_TYPE_SYSDIG_EVF 0x00000208 /* Sysdig Event Block with flags */
#define BLOCK_TYPE_SYSDIG_EVENT_V2 0x00000216 /* Sysdig Event Block version 2 */
#define BLOCK_TYPE_SYSDIG_EVF_V2 0x00000217 /* Sysdig Event Block with flags version 2 */
+#define BLOCK_TYPE_CB_COPY 0x00000BAD /* Custom Block which can be copied */
+#define BLOCK_TYPE_CB_NO_COPY 0x40000BAD /* Custom Block which should not be copied */
/* 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/wtap.h b/wiretap/wtap.h
index e79aa5ff84..70a4a219b0 100644
--- a/wiretap/wtap.h
+++ b/wiretap/wtap.h
@@ -1212,6 +1212,7 @@ union wtap_pseudo_header {
#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 */
+#define REC_TYPE_CUSTOM_BLOCK 5 /**< pcapng custom block */
typedef struct {
guint32 caplen; /* data length in the file */
@@ -1324,6 +1325,12 @@ typedef struct {
} wtap_systemd_journal_header;
typedef struct {
+ guint32 length; /* length of the record */
+ guint32 pen; /* private enterprise number */
+ gboolean copy_allowed; /* CB can be written */
+} wtap_custom_block_header;
+
+typedef struct {
guint rec_type; /* what type of record is this? */
guint32 presence_flags; /* what stuff do we have? */
nstime_t ts; /* time stamp */
@@ -1333,6 +1340,7 @@ typedef struct {
wtap_ft_specific_header ft_specific_header;
wtap_syscall_header syscall_header;
wtap_systemd_journal_header systemd_journal_header;
+ wtap_custom_block_header custom_block_header;
} rec_header;
/*
* XXX - this should become a full set of options.
diff --git a/wiretap/wtap_opttypes.h b/wiretap/wtap_opttypes.h
index dfba1510f1..01e8fb495b 100644
--- a/wiretap/wtap_opttypes.h
+++ b/wiretap/wtap_opttypes.h
@@ -168,6 +168,7 @@ typedef enum {
WTAP_BLOCK_FT_SPECIFIC_REPORT,
WTAP_BLOCK_FT_SPECIFIC_EVENT,
WTAP_BLOCK_SYSTEMD_JOURNAL,
+ WTAP_BLOCK_CUSTOM_BLOCK,
MAX_WTAP_BLOCK_TYPE_VALUE
} wtap_block_type_t;