Commit 52a66714 authored by Peter Wu's avatar Peter Wu Committed by AndersBroman

wiretap: add read/write support for Decryption Secrets Block (DSB)

Support reading and writing pcapng files with DSBs. A DSB may occur
multiple times but should appear before packets that need those
decryption secrets (so it cannot be moved to the end like NRB). The TLS
dissector will be updated in the future to make use of these secrets.
pcapng spec update: https://github.com/pcapng/pcapng/pull/54

As DSBs may be interleaved with packets, do not even try to read it in
pcapng_open (as is done for IDBs). Instead process them during the
sequential read, appending them to the 'wtap::dsbs' array.

Writing is more complicated, secrets may initially not be available when
'wtap_dumper' is created. As they may become available in 'wtap::dsbs'
as more packets are read, allow 'wtap_dumper::dsbs_growing' to reference
this array. This saves every user from checking/dumping DSBs.

If the wtap user needs to insert extra DSBs (while preserving existing
DSBs), they can set the 'wtap_dumper::dsbs_initial' field.

The test file was creating using a patched editcap (future patch) and
combined using mergecap (which required a change to preserve the DSBs).

Change-Id: I74e4ee3171bd852a89ea0f6fbae9e0f65ed6eda9
Ping-Bug: 15252
Reviewed-on: https://code.wireshark.org/review/30692Reviewed-by: Peter Wu's avatarPeter Wu <peter@lekensteyn.nl>
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: AndersBroman's avatarAnders Broman <a.broman58@gmail.com>
parent ad21e312
Pipeline #37203387 passed with stage
in 58 minutes and 33 seconds
......@@ -20,6 +20,7 @@
#include <epan/show_exception.h>
#include <epan/addr_resolv.h>
#include <epan/wmem/wmem.h>
#include <wiretap/secrets-types.h>
#include <epan/dissectors/packet-pcap_pktdata.h>
......@@ -121,6 +122,10 @@ static int hf_pcapng_record_ipv6 = -1;
static int hf_pcapng_record_name = -1;
static int hf_pcapng_record_padding = -1;
static int hf_pcapng_dsb_secrets_type = -1;
static int hf_pcapng_dsb_secrets_length = -1;
static int hf_pcapng_dsb_secrets_data = -1;
static int hf_pcapng_darwin_process_id = -1;
static int hf_pcapng_option_code_darwin_process_info = -1;
static int hf_pcapng_option_darwin_process_name = -1;
......@@ -531,6 +536,11 @@ static const value_string flags_reception_type_vals[] = {
{ 0, NULL }
};
static const value_string dsb_secrets_types_vals[] = {
{ SECRETS_TYPE_TLS, "TLS Key Log" },
{ 0, NULL }
};
void proto_register_pcapng(void);
void proto_reg_handoff_pcapng(void);
......@@ -1570,6 +1580,30 @@ static gint dissect_block(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - 4 - 8 - 4 - 4 - captured_length - ((captured_length % 4)?(4 - (captured_length % 4)):0));
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, encoding, NULL);
break;
case BLOCK_DSB:
{
guint32 secrets_length;
proto_tree_add_item(block_data_tree, hf_pcapng_dsb_secrets_type, tvb, offset, 4, encoding);
offset += 4;
proto_tree_add_item_ret_uint(block_data_tree, hf_pcapng_dsb_secrets_length, tvb, offset, 4, encoding, &secrets_length);
offset += 4;
proto_tree_add_item(block_data_tree, hf_pcapng_dsb_secrets_data, tvb, offset, secrets_length, encoding);
offset += secrets_length;
guint32 padlen = (4 - (secrets_length & 3)) & 3;
if (padlen) {
proto_tree_add_item(block_data_tree, hf_pcapng_record_padding, tvb, offset, padlen, ENC_NA);
offset += padlen;
}
if (block_data_length > 4 + 4 + secrets_length + padlen) {
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - 4 - 4 - secrets_length - padlen);
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, encoding, NULL);
}
}
break;
case BLOCK_DARWIN_PROCESS:
proto_item_append_text(block_item, " %u", info->darwin_process_event_number);
......@@ -1584,7 +1618,6 @@ static gint dissect_block(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
break;
case BLOCK_IRIG_TIMESTAMP:
case BLOCK_ARINC_429:
case BLOCK_DSB:
default:
offset += block_data_length;
}
......@@ -2138,6 +2171,21 @@ proto_register_pcapng(void)
FT_STRINGZ, STR_ASCII, NULL, 0x00,
NULL, HFILL }
},
{ &hf_pcapng_dsb_secrets_type,
{ "Secrets Type", "pcapng.dsb.secrets_type",
FT_UINT32, BASE_HEX, VALS(dsb_secrets_types_vals), 0x00,
NULL, HFILL }
},
{ &hf_pcapng_dsb_secrets_length,
{ "Secrets Type", "pcapng.dsb.secrets_length",
FT_UINT32, BASE_DEC, NULL, 0x00,
NULL, HFILL }
},
{ &hf_pcapng_dsb_secrets_data,
{ "Secrets Data", "pcapng.dsb.secrets_data",
FT_BYTES, BASE_NONE, NULL, 0x00,
NULL, HFILL }
},
{ &hf_pcapng_darwin_process_id,
{ "Darwin Process ID", "pcapng.darwin.process_id",
FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
......
# first
CLIENT_RANDOM f67a28b386b31c620d76c0026fdd9888edbe6bf0f5b715b2caca158f84ae9d66 cc38e78182b9dfd74ef3103d79bbc99cfc9b4dad209ed209062b5481e63353128da7571b13cfd4d3a5ae7d0520fb346d
CLIENT_RANDOM 1e0d63b41d7c7bb639559cfc9f06ffd5c65fe4a9df31abc5af833b0d834436f4 c7f5dda54fb417181cb26e52112afaf9e1756addd77d3c479d96a609c0d3c9bb9929c8475cafb4dbad8f72e868a43e02
......@@ -110,6 +110,53 @@ class case_fileformat_pcapng(subprocesstest.SubprocessTestCase):
)
self.assertTrue(self.diffOutput(capture_proc.stdout_str, fileformats_baseline_str, 'tshark', baseline_file))
@fixtures.fixture
def check_pcapng_dsb_fields(request, cmd_tshark):
'''Factory that checks whether the DSB within the capture file matches.'''
self = request.instance
def check_dsb_fields_real(outfile, fields):
proc = self.runProcess((cmd_tshark,
'-r', outfile,
'-Xread_format:MIME Files Format',
'-Tfields',
'-e', 'pcapng.dsb.secrets_type',
'-e', 'pcapng.dsb.secrets_length',
'-e', 'pcapng.dsb.secrets_data',
'-Y', 'pcapng.dsb.secrets_data'
))
# Convert "t1,t2 l1,l2 v1,2" -> [(t1, l1, v1), (t2, l2, v2)]
output = proc.stdout_str.strip()
actual = list(zip(*[x.split(",") for x in output.split('\t')]))
def format_field(field):
t, l, v = field
v_hex = ''.join('%02x' % c for c in v)
return ('0x%08x' % t, str(l), v_hex)
fields = [format_field(field) for field in fields]
self.assertEqual(fields, actual)
return check_dsb_fields_real
@fixtures.mark_usefixtures('base_env')
@fixtures.uses_fixtures
class case_fileformat_pcapng_dsb(subprocesstest.SubprocessTestCase):
def test_pcapng_dsb_1(self, cmd_tshark, dirs, capture_file, check_pcapng_dsb_fields):
'''Check that DSBs are preserved while rewriting files.'''
dsb_keys1 = os.path.join(dirs.key_dir, 'tls12-dsb-1.keys')
dsb_keys2 = os.path.join(dirs.key_dir, 'tls12-dsb-2.keys')
outfile = self.filename_from_id('tls12-dsb-same.pcapng')
self.runProcess((cmd_tshark,
'-r', capture_file('tls12-dsb.pcapng'),
'-w', outfile,
))
with open(dsb_keys1, 'r') as f:
dsb1_contents = f.read().encode('utf8')
with open(dsb_keys2, 'r') as f:
dsb2_contents = f.read().encode('utf8')
check_pcapng_dsb_fields(outfile, (
(0x544c534b, len(dsb1_contents), dsb1_contents),
(0x544c534b, len(dsb2_contents), dsb2_contents),
))
@fixtures.mark_usefixtures('test_env')
@fixtures.uses_fixtures
......
......@@ -14,6 +14,7 @@ set(WIRETAP_PUBLIC_HEADERS
merge.h
pcap-encap.h
pcapng_module.h
secrets-types.h
wtap.h
wtap_opttypes.h
)
......
......@@ -2347,6 +2347,9 @@ wtap_dump_init_dumper(int file_type_subtype, wtap_compression_type compression_t
descr_mand->interface_statistics = NULL;
g_array_append_val(wdh->interface_data, descr);
}
/* Set Decryption Secrets Blocks */
wdh->dsbs_initial = params->dsbs_initial;
wdh->dsbs_growing = params->dsbs_growing;
return wdh;
}
......@@ -2653,6 +2656,7 @@ wtap_dump_close(wtap_dumper *wdh, int *err)
}
g_free(wdh->priv);
wtap_block_array_free(wdh->interface_data);
wtap_block_array_free(wdh->dsbs_initial);
g_free(wdh);
return ret;
}
......
......@@ -25,6 +25,7 @@
#include "merge.h"
#include "wtap_opttypes.h"
#include "pcapng.h"
#include "wtap-int.h"
#include <wsutil/filesystem.h>
#include "wsutil/os_version_info.h"
......@@ -832,6 +833,7 @@ merge_process_packets(wtap_dumper *pdh, const int file_type,
merge_in_file_t *in_files, const guint in_file_count,
const gboolean do_append, guint snaplen,
merge_progress_callback_t* cb,
GArray *dsb_combined,
int *err, gchar **err_info, guint *err_fileno,
guint32 *err_framenum)
{
......@@ -911,6 +913,18 @@ merge_process_packets(wtap_dumper *pdh, const int file_type,
}
}
}
/*
* If any DSBs were read before this record, be sure to pass those now
* such that wtap_dump can pick it up.
*/
if (dsb_combined && in_file->wth->dsbs) {
GArray *in_dsb = in_file->wth->dsbs;
for (guint i = in_file->dsbs_seen; i < in_dsb->len; i++) {
wtap_block_t wblock = g_array_index(in_dsb, wtap_block_t, i);
g_array_append_val(dsb_combined, wblock);
in_file->dsbs_seen++;
}
}
if (!wtap_dump(pdh, rec, wtap_get_buf_ptr(in_file->wth), err, err_info)) {
status = MERGE_ERR_CANT_WRITE_OUTFILE;
......@@ -921,8 +935,6 @@ merge_process_packets(wtap_dumper *pdh, const int file_type,
if (cb)
cb->callback_func(MERGE_EVENT_DONE, count, in_files, in_file_count, cb->data);
merge_close_in_files(in_file_count, in_files);
if (status == MERGE_OK || status == MERGE_USER_ABORTED) {
if (!wtap_dump_close(pdh, err))
status = MERGE_ERR_CANT_CLOSE_OUTFILE;
......@@ -937,6 +949,12 @@ merge_process_packets(wtap_dumper *pdh, const int file_type,
(void)wtap_dump_close(pdh, &close_err);
}
/* Close the input files after the output file in case the latter still
* holds references to blocks in the input file (such as the DSB). Even if
* those DSBs are only written when wtap_dump is called and nothing bad will
* happen now, let's keep all pointers in pdh valid for correctness sake. */
merge_close_in_files(in_file_count, in_files);
if (status == MERGE_OK || in_file == NULL) {
*err_fileno = 0;
*err_framenum = 0;
......@@ -964,6 +982,7 @@ merge_files_common(const gchar* out_filename, /* normal output mode */
wtap_dumper *pdh;
GArray *shb_hdrs = NULL;
wtapng_iface_descriptions_t *idb_inf = NULL;
GArray *dsb_combined = NULL;
g_assert(in_file_count > 0);
g_assert(in_filenames != NULL);
......@@ -1017,6 +1036,8 @@ merge_files_common(const gchar* out_filename, /* normal output mode */
/* XXX other blocks like NRB are now discarded. */
params.shb_hdrs = shb_hdrs;
params.idb_inf = idb_inf;
dsb_combined = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
params.dsbs_growing = dsb_combined;
}
if (out_filename) {
pdh = wtap_dump_open(out_filename, file_type, WTAP_UNCOMPRESSED, &params, err);
......@@ -1031,6 +1052,9 @@ merge_files_common(const gchar* out_filename, /* normal output mode */
g_free(in_files);
wtap_block_array_free(shb_hdrs);
wtap_free_idb_info(idb_inf);
if (dsb_combined) {
g_array_free(dsb_combined, TRUE);
}
*err_framenum = 0;
return MERGE_ERR_CANT_OPEN_OUTFILE;
}
......@@ -1039,12 +1063,15 @@ merge_files_common(const gchar* out_filename, /* normal output mode */
cb->callback_func(MERGE_EVENT_READY_TO_MERGE, 0, in_files, in_file_count, cb->data);
status = merge_process_packets(pdh, file_type, in_files, in_file_count,
do_append, snaplen, cb, err, err_info,
do_append, snaplen, cb, dsb_combined, err, err_info,
err_fileno, err_framenum);
g_free(in_files);
wtap_block_array_free(shb_hdrs);
wtap_free_idb_info(idb_inf);
if (dsb_combined) {
g_array_free(dsb_combined, TRUE);
}
return status;
}
......
......@@ -34,6 +34,7 @@ typedef struct merge_in_file_s {
guint32 packet_num; /* current packet number */
gint64 size; /* file size */
GArray *idb_index_map; /* used for mapping the old phdr interface_id values to new during merge */
guint dsbs_seen; /* number of elements processed so far from wth->dsbs */
} merge_in_file_t;
/** Return values from merge_files(). */
......
......@@ -29,6 +29,7 @@
#include "pcap-encap.h"
#include "pcapng.h"
#include "pcapng_module.h"
#include "secrets-types.h"
#if 0
#define pcapng_debug(...) g_warning(__VA_ARGS__)
......@@ -260,6 +261,7 @@ register_pcapng_block_type_handler(guint block_type, block_reader reader,
case BLOCK_TYPE_NRB:
case BLOCK_TYPE_ISB:
case BLOCK_TYPE_EPB:
case BLOCK_TYPE_DSB:
case BLOCK_TYPE_SYSDIG_EVENT:
case BLOCK_TYPE_SYSTEMD_JOURNAL:
/*
......@@ -352,8 +354,9 @@ register_pcapng_block_type_handler(guint block_type, block_reader reader,
#define BT_INDEX_NRB 3
#define BT_INDEX_ISB 4
#define BT_INDEX_EVT 5
#define BT_INDEX_DSB 6
#define NUM_BT_INDICES 6
#define NUM_BT_INDICES 7
typedef struct {
option_handler_fn hfunc;
......@@ -395,6 +398,10 @@ get_block_type_index(guint block_type, guint *bt_index)
*bt_index = BT_INDEX_EVT;
break;
case BLOCK_TYPE_DSB:
*bt_index = BT_INDEX_DSB;
break;
default:
/*
* This is a block type we don't process; either we ignore it,
......@@ -1057,6 +1064,56 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
return TRUE;
}
static gboolean
pcapng_read_decryption_secrets_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn,
wtapng_block_t *wblock, int *err, gchar **err_info)
{
guint to_read;
pcapng_decryption_secrets_block_t dsb;
wtapng_dsb_mandatory_t *dsb_mand;
/* read block content */
if (!wtap_read_bytes(fh, &dsb, sizeof(dsb), err, err_info)) {
pcapng_debug("%s: failed to read DSB", G_STRFUNC);
return FALSE;
}
/* mandatory values */
wblock->block = wtap_block_create(WTAP_BLOCK_DSB);
dsb_mand = (wtapng_dsb_mandatory_t *)wtap_block_get_mandatory_data(wblock->block);
if (pn->byte_swapped) {
dsb_mand->secrets_type = GUINT32_SWAP_LE_BE(dsb.secrets_type);
dsb_mand->secrets_len = GUINT32_SWAP_LE_BE(dsb.secrets_len);
} else {
dsb_mand->secrets_type = dsb.secrets_type;
dsb_mand->secrets_len = dsb.secrets_len;
}
/* Sanity check: assume the secrets are not larger than 1 GiB */
if (dsb_mand->secrets_len > 1024 * 1024 * 1024) {
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("%s: secrets block is too large: %u", G_STRFUNC, dsb_mand->secrets_len);
return FALSE;
}
dsb_mand->secrets_data = (char *)g_malloc0(dsb_mand->secrets_len);
if (!wtap_read_bytes(fh, dsb_mand->secrets_data, dsb_mand->secrets_len, err, err_info)) {
pcapng_debug("%s: failed to read DSB", G_STRFUNC);
return FALSE;
}
/* Skip past padding and discard options (not supported yet). */
to_read = bh->block_total_length - MIN_DSB_SIZE - dsb_mand->secrets_len;
if (!wtap_read_bytes(fh, NULL, to_read, err, err_info)) {
pcapng_debug("%s: failed to read DSB options", G_STRFUNC);
return FALSE;
}
/*
* We don't return these to the caller in pcapng_read().
*/
wblock->internal = TRUE;
return TRUE;
}
static gboolean
pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info, gboolean enhanced)
......@@ -2519,6 +2576,10 @@ pcapng_read_block(wtap *wth, FILE_T fh, pcapng_t *pn, wtapng_block_t *wblock, in
if (!pcapng_read_interface_statistics_block(fh, &bh, pn, wblock, err, err_info))
return PCAPNG_BLOCK_ERROR;
break;
case(BLOCK_TYPE_DSB):
if (!pcapng_read_decryption_secrets_block(fh, &bh, pn, wblock, err, err_info))
return PCAPNG_BLOCK_ERROR;
break;
case(BLOCK_TYPE_SYSDIG_EVENT):
/* case(BLOCK_TYPE_SYSDIG_EVF): */
if (!pcapng_read_sysdig_event_block(fh, &bh, pn, wblock, err, err_info))
......@@ -2581,6 +2642,14 @@ pcapng_process_idb(wtap *wth, pcapng_t *pcapng, wtapng_block_t *wblock)
g_array_append_val(pcapng->interfaces, iface_info);
}
/* Process a DSB that we have just read. */
static void
pcapng_process_dsb(wtap *wth, wtapng_block_t *wblock)
{
/* Store DSB such that it can be saved by the dumper. */
g_array_append_val(wth->dsbs, wblock->block);
}
/* classic wtap: open capture file */
wtap_open_return_val
pcapng_open(wtap *wth, int *err, gchar **err_info)
......@@ -2660,6 +2729,10 @@ pcapng_open(wtap *wth, int *err, gchar **err_info)
wth->subtype_close = pcapng_close;
wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAPNG;
/* Always initialize the list of Decryption Secret Blocks such that a
* wtap_dumper can refer to it right after opening the capture file. */
wth->dsbs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
/* Loop over all IDB:s that appear before any packets */
while (1) {
/* peek at next block */
......@@ -2759,6 +2832,13 @@ pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
wtap_block_free(wblock.block);
break;
case(BLOCK_TYPE_DSB):
/* Decryption secrets. */
pcapng_debug("pcapng_read: block type BLOCK_TYPE_DSB");
pcapng_process_dsb(wth, &wblock);
/* Do not free wblock.block, it is consumed by pcapng_process_dsb */
break;
case(BLOCK_TYPE_NRB):
/* More name resolution entries */
pcapng_debug("pcapng_read: block type BLOCK_TYPE_NRB");
......@@ -3437,6 +3517,49 @@ pcapng_write_systemd_journal_export_block(wtap_dumper *wdh, const wtap_rec *rec,
}
static gboolean
pcapng_write_decryption_secrets_block(wtap_dumper *wdh, wtap_block_t sdata, int *err)
{
pcapng_block_header_t bh;
pcapng_decryption_secrets_block_t dsb;
wtapng_dsb_mandatory_t *mand_data = (wtapng_dsb_mandatory_t *)wtap_block_get_mandatory_data(sdata);
guint pad_len = (4 - (mand_data->secrets_len & 3)) & 3;
/* write block header */
bh.block_type = BLOCK_TYPE_DSB;
bh.block_total_length = MIN_DSB_SIZE + mand_data->secrets_len + pad_len;
pcapng_debug("%s: Total len %u", G_STRFUNC, bh.block_total_length);
if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
return FALSE;
wdh->bytes_dumped += sizeof bh;
/* write block fixed content */
dsb.secrets_type = mand_data->secrets_type;
dsb.secrets_len = mand_data->secrets_len;
if (!wtap_dump_file_write(wdh, &dsb, sizeof dsb, err))
return FALSE;
wdh->bytes_dumped += sizeof dsb;
if (!wtap_dump_file_write(wdh, mand_data->secrets_data, mand_data->secrets_len, err))
return FALSE;
wdh->bytes_dumped += mand_data->secrets_len;
if (pad_len) {
const guint32 zero_pad = 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;
wdh->bytes_dumped += sizeof bh.block_total_length;
return TRUE;
}
/*
* libpcap's maximum pcapng block size is currently 16MB.
*
......@@ -4258,6 +4381,20 @@ static gboolean pcapng_dump(wtap_dumper *wdh,
block_handler *handler;
#endif
/* Write (optional) Decryption Secrets Blocks that were collected while
* reading packet blocks. */
if (wdh->dsbs_growing) {
for (guint i = wdh->dsbs_growing_written; i < wdh->dsbs_growing->len; i++) {
pcapng_debug("%s: writing DSB %u", G_STRFUNC, i);
wtap_block_t dsb = g_array_index(wdh->dsbs_growing, wtap_block_t, i);
if (!pcapng_write_decryption_secrets_block(wdh, dsb, err)) {
return FALSE;
}
++wdh->dsbs_growing_written;
}
}
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),
......@@ -4395,6 +4532,16 @@ pcapng_dump_open(wtap_dumper *wdh, int *err)
}
/* Write (optional) fixed Decryption Secrets Blocks. */
if (wdh->dsbs_initial) {
for (i = 0; i < wdh->dsbs_initial->len; i++) {
wtap_block_t dsb = g_array_index(wdh->dsbs_initial, wtap_block_t, i);
if (!pcapng_write_decryption_secrets_block(wdh, dsb, err)) {
return FALSE;
}
}
}
return TRUE;
}
......
......@@ -53,6 +53,14 @@ typedef struct pcapng_interface_statistics_block_s {
/* ... Options ... */
} pcapng_interface_statistics_block_t;
/* pcapng: Decryption Secrets Block file encoding */
typedef struct pcapng_decryption_secrets_block_s {
guint32 secrets_type; /* Secrets Type, see secrets-types.h */
guint32 secrets_len; /* Size of variable-length secrets data. */
/* x bytes Secrets Data. */
/* ... Options ... */
} pcapng_decryption_secrets_block_t;
struct pcapng_option_header {
guint16 type;
guint16 value_length;
......@@ -62,6 +70,7 @@ struct pcapng_option_header {
* Minimum IDB size = minimum block size + size of fixed length portion of IDB.
*/
#define MIN_IDB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_interface_description_block_t)))
#define MIN_DSB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_decryption_secrets_block_t)))
wtap_open_return_val pcapng_open(wtap *wth, int *err, gchar **err_info);
gboolean pcapng_dump_open(wtap_dumper *wdh, int *err);
......
......@@ -25,6 +25,7 @@
#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_DSB 0x0000000A /* Decryption Secrets Block */
#define BLOCK_TYPE_SYSDIG_EVENT 0x00000204 /* Sysdig Event Block */
#define BLOCK_TYPE_SYSDIG_EVF 0x00000208 /* Sysdig Event Block with flags */
......
/* secrets-types.h
* Identifiers used by Decryption Secrets Blocks (DSB).
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef __SECRETS_TYPES_H__
#define __SECRETS_TYPES_H__
/*
* Type describing the format of the opaque secrets value in a pcapng DSB.
*/
#define SECRETS_TYPE_TLS 0x544c534b /* TLS Key Log */
#endif /* __SECRETS_TYPES_H__ */
......@@ -42,6 +42,7 @@ struct wtap {
GArray *shb_hdrs;
GArray *interface_data; /**< An array holding the interface data from pcapng IDB:s or equivalent(?)*/
GArray *nrb_hdrs; /**< holds the Name Res Block's comment/custom_opts, or NULL */
GArray *dsbs; /**< An array of DSBs (of type wtap_block_t), or NULL if not supported. */
void *priv; /* this one holds per-file state and is free'd automatically by wtap_close() */
void *wslua_data; /* this one holds wslua state info and is not free'd */
......@@ -102,6 +103,14 @@ struct wtap_dumper {
GArray *shb_hdrs;
GArray *nrb_hdrs; /**< name resolution comment/custom_opt, or NULL */
GArray *interface_data; /**< An array holding the interface data from pcapng IDB:s or equivalent(?) NULL if not present.*/
GArray *dsbs_initial; /**< An array of initial DSBs (of type wtap_block_t) */
/*
* Additional blocks that might grow as data is being collected.
* Subtypes should write these blocks before writing new packet blocks.
*/
const GArray *dsbs_growing; /**< A reference to an array of DSBs (of type wtap_block_t) */
guint dsbs_growing_written; /**< Number of already processed DSBs in dsbs_growing. */
};
WS_DLL_PUBLIC gboolean wtap_dump_file_write(wtap_dumper *wdh, const void *buf,
......@@ -319,14 +328,14 @@ wtap_full_file_seek_read(wtap *wth, gint64 seek_off, wtap_rec *rec, Buffer *buf,
#endif /* __WTAP_INT_H__ */
/*
* Editor modelines
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local Variables:
* c-basic-offset: 8
* Local variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: t
* indent-tabs-mode: nil
* End: