wiretap: Preserve NRBs with editcap, mergecap, and tshark

Use a pointer to the growing array of NRBs from the source
file, as with DSBs, so as to handle reading NRBs in the middle
of a file in one-pass mode.

Write NRBs when reading a file with editcap, or in tshark when
not dissecting packets and writing our own NRB. Continue not
to write the NRB if we're supplying our own list of address info
instead.

If we have already read the entire source file in (such as in
two-pass tshark), move all the NRBs to the beginning of the file
before packets, as done with DSBs.

When merging files with mergecap, write both sets of NRBs. (There
is no attempt to merge the NRBs by looking for common entries.)

Check for name resolution data in the middle of dumping a file,
not just at the end, and check for DSBs at the end of a file,
after all the packets. This means that Wireshark no longer writes
the NRB at the very end of the file after all the packets (which
is worse for future one-pass reads), and DSBs after all packets
are preserved.

Ping #15502
This commit is contained in:
John Thacker 2023-01-26 00:42:10 -05:00
parent 3ff9f075c6
commit 67a01bdf26
10 changed files with 249 additions and 93 deletions

View File

@ -1851,7 +1851,9 @@ main(int argc, char *argv[])
* XXX - what about non-packet records in the file after this?
* We can *probably* ignore IDBs after this point, as they
* presumably indicate that we weren't capturing on that
* interface at this point, but what about, for example, NRBs?
* interface at this point, but what about, for example, ISBs?
* (NRBs and DSBs are now written when wtap_dump_close() calls
* pcapng_dump_finish().)
*/
if (max_packet_number <= read_count)
break;

View File

@ -3826,6 +3826,26 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type,
if (save_file != NULL) {
if (second_pass_status != PASS_WRITE_ERROR) {
if (pdh && out_file_name_res) {
/* XXX: This doesn't work as expected. First, it should be
* moved to between the first and second passes (if doing
* two-pass mode), so that the new NRB appears before packets,
* which is better for subsequent one-pass mode. It never works
* well in one-pass mode.
*
* Second, it only writes hosts that we've done lookups for,
* which means unless packet details are printed (or there's
* a display filter that matches something that will do a host
* lookup, e.g. -Y "ip") it doesn't actually have anything
* in the list to save. Notably, that includes the case of
* "tshark [-2] -H hosts.txt -r <infile> -w <outfile>",
* which a user would certainly expect to dissect packets,
* lookup hostnames, and add them to an NRB for later use.
* A workaround is if "-V > /dev/null" is added, but who
* expects that?
*
* A third issue is that name resolution blocks aren't
* written for live captures.
*/
if (!wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list())) {
cmdarg_err("The file format \"%s\" doesn't support name resolution information.",
wtap_file_type_subtype_name(out_file_type));

View File

@ -2272,7 +2272,7 @@ wtap_dump_init_dumper(int file_type_subtype, wtap_compression_type compression_t
/* Set Section Header Block data */
wdh->shb_hdrs = params->shb_hdrs;
/* Set Name Resolution Block data */
wdh->nrb_hdrs = params->nrb_hdrs;
wdh->nrbs_growing = params->nrbs_growing;
/* Set Interface Description Block data */
if (interfaces && interfaces->len) {
if (!params->dont_copy_idbs) { /* XXX */
@ -2704,6 +2704,18 @@ wtap_dump_set_addrinfo_list(wtap_dumper *wdh, addrinfo_lists_t *addrinfo_lists)
return TRUE;
}
void
wtap_dump_discard_name_resolution(wtap_dumper *wdh)
{
/* As below for DSBs. */
if (wdh->nrbs_growing) {
/*
* Pretend we've written all of them.
*/
wdh->nrbs_growing_written = wdh->nrbs_growing->len;
}
}
void
wtap_dump_discard_decryption_secrets(wtap_dumper *wdh)
{

View File

@ -910,7 +910,7 @@ merge_process_packets(wtap_dumper *pdh, const int file_type,
const idb_merge_mode mode, guint snaplen,
merge_progress_callback_t* cb,
wtapng_iface_descriptions_t *idb_inf,
GArray *dsb_combined,
GArray *nrb_combined, GArray *dsb_combined,
int *err, gchar **err_info, guint *err_fileno,
guint32 *err_framenum)
{
@ -1010,6 +1010,14 @@ 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 (nrb_combined && in_file->wth->nrbs) {
GArray *in_nrb = in_file->wth->nrbs;
for (guint i = in_file->nrbs_seen; i < in_nrb->len; i++) {
wtap_block_t wblock = g_array_index(in_nrb, wtap_block_t, i);
g_array_append_val(nrb_combined, wblock);
in_file->nrbs_seen++;
}
}
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++) {
@ -1031,6 +1039,33 @@ merge_process_packets(wtap_dumper *pdh, const int file_type,
cb->callback_func(MERGE_EVENT_DONE, count, in_files, in_file_count, cb->data);
if (status == MERGE_OK || status == MERGE_USER_ABORTED) {
/* Check for any NRBs or DSBs read after the last packet records. */
if (nrb_combined) {
for (guint j = 0; j < in_file_count; j++) {
in_file = &in_files[j];
GArray *in_nrb = in_file->wth->nrbs;
if (in_nrb) {
for (guint i = in_file->nrbs_seen; i < in_nrb->len; i++) {
wtap_block_t wblock = g_array_index(in_nrb, wtap_block_t, i);
g_array_append_val(nrb_combined, wblock);
in_file->nrbs_seen++;
}
}
}
}
if (dsb_combined) {
for (guint j = 0; j < in_file_count; j++) {
in_file = &in_files[j];
GArray *in_dsb = in_file->wth->dsbs;
if (in_dsb) {
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_close(pdh, NULL, err, err_info))
status = MERGE_ERR_CANT_CLOSE_OUTFILE;
} else {
@ -1080,6 +1115,7 @@ merge_files_common(const gchar* out_filename, /* filename in normal output mode,
wtap_dumper *pdh;
GArray *shb_hdrs = NULL;
wtapng_iface_descriptions_t *idb_inf = NULL;
GArray *nrb_combined = NULL;
GArray *dsb_combined = NULL;
ws_assert(in_file_count > 0);
@ -1146,9 +1182,17 @@ merge_files_common(const gchar* out_filename, /* filename in normal output mode,
idb_inf = generate_merged_idbs(in_files, in_file_count, &mode);
ws_debug("IDB merge operation complete, got %u IDBs", idb_inf ? idb_inf->interface_data->len : 0);
/* XXX other blocks like NRB are now discarded. */
/* XXX other blocks like ISB are now discarded. */
params.shb_hdrs = shb_hdrs;
params.idb_inf = idb_inf;
}
if (wtap_file_type_subtype_supports_block(file_type,
WTAP_BLOCK_NAME_RESOLUTION) != BLOCK_NOT_SUPPORTED) {
nrb_combined = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
params.nrbs_growing = nrb_combined;
}
if (wtap_file_type_subtype_supports_block(file_type,
WTAP_BLOCK_DECRYPTION_SECRETS) != BLOCK_NOT_SUPPORTED) {
dsb_combined = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
params.dsbs_growing = dsb_combined;
}
@ -1168,6 +1212,9 @@ merge_files_common(const gchar* out_filename, /* filename in normal output mode,
g_free(in_files);
wtap_block_array_free(shb_hdrs);
wtap_free_idb_info(idb_inf);
if (nrb_combined) {
g_array_free(nrb_combined, TRUE);
}
if (dsb_combined) {
g_array_free(dsb_combined, TRUE);
}
@ -1180,13 +1227,16 @@ merge_files_common(const gchar* out_filename, /* filename in normal output mode,
status = merge_process_packets(pdh, file_type, in_files, in_file_count,
do_append, mode, snaplen, cb,
idb_inf, dsb_combined,
idb_inf, nrb_combined, 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 (nrb_combined) {
g_array_free(nrb_combined, TRUE);
}
if (dsb_combined) {
g_array_free(dsb_combined, TRUE);
}

View File

@ -36,6 +36,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 nrbs_seen; /* number of elements processed so far from wth->nrbs */
guint dsbs_seen; /* number of elements processed so far from wth->dsbs */
} merge_in_file_t;

View File

@ -3431,14 +3431,11 @@ pcapng_process_nrb(wtap *wth, wtapng_block_t *wblock)
{
wtapng_process_nrb(wth, wblock->block);
if (wth->nrb_hdrs == NULL) {
wth->nrb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
if (wth->nrbs == NULL) {
wth->nrbs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
}
/* Store NRB such that it can be saved by the dumper.
* XXX: NRBs are not saved yet by the dumper, only the resolved
* and used lookups passed into via wtap_dump_set_addrinfo_list()
*/
g_array_append_val(wth->nrb_hdrs, wblock->block);
/* Store NRB such that it can be saved by the dumper. */
g_array_append_val(wth->nrbs, wblock->block);
}
/* Process a DSB that we have just read. */
@ -3704,9 +3701,11 @@ pcapng_open(wtap *wth, int *err, gchar **err_info)
wth->subtype_close = pcapng_close;
wth->file_type_subtype = pcapng_file_type_subtype;
/* Always initialize the list of Decryption Secret Blocks such that a
* wtap_dumper can refer to it right after opening the capture file. */
/* Always initialize the lists of Decryption Secret Blocks and
* Name Resolution Blocks such that a wtap_dumper can refer to
* them right after opening the capture file. */
wth->dsbs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
wth->nrbs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
/* Most other capture types (such as pcap) support a single link-layer
* type, indicated in the header, and don't support WTAP_ENCAP_PER_PACKET.
@ -5558,26 +5557,24 @@ put_nrb_option(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_ty
}
static void
put_nrb_options(wtap_dumper *wdh, guint8 *opt_ptr)
put_nrb_options(wtap_dumper *wdh _U_, wtap_block_t nrb, guint8 *opt_ptr)
{
if (wdh->nrb_hdrs && wdh->nrb_hdrs->len > 0) {
wtap_block_t nrb_hdr = g_array_index(wdh->nrb_hdrs, wtap_block_t, 0);
struct pcapng_option option_hdr;
struct pcapng_option option_hdr;
wtap_block_foreach_option(nrb_hdr, put_nrb_option, &opt_ptr);
wtap_block_foreach_option(nrb, put_nrb_option, &opt_ptr);
/* Put end of options */
option_hdr.type = OPT_EOFOPT;
option_hdr.value_length = 0;
memcpy(opt_ptr, &option_hdr, 4);
}
/* Put end of options */
option_hdr.type = OPT_EOFOPT;
option_hdr.value_length = 0;
memcpy(opt_ptr, &option_hdr, 4);
}
static gboolean
pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
pcapng_write_name_resolution_block(wtap_dumper *wdh, wtap_block_t sdata, int *err)
{
pcapng_block_header_t bh;
pcapng_name_resolution_block_t nrb;
wtapng_nrb_mandatory_t *mand_data = (wtapng_nrb_mandatory_t *)wtap_block_get_mandatory_data(sdata);
guint32 options_size;
size_t max_rec_data_size;
guint8 *block_data;
@ -5589,7 +5586,7 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
hashipv6_t *ipv6_hash_list_entry;
int i;
if (wtap_addrinfo_list_empty(wdh->addrinfo_lists)) {
if (!mand_data) {
/*
* No name/address pairs to write.
* XXX - what if we have options?
@ -5598,13 +5595,7 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
}
/* Calculate the space needed for options. */
options_size = 0;
if (wdh->nrb_hdrs && wdh->nrb_hdrs->len > 0) {
wtap_block_t nrb_hdr = g_array_index(wdh->nrb_hdrs, wtap_block_t, 0);
/* Compute size of all the options */
options_size = compute_options_size(nrb_hdr, compute_nrb_option_size);
}
options_size = compute_options_size(sdata, compute_nrb_option_size);
/*
* Make sure we can fit at least one maximum-sized record, plus
@ -5647,9 +5638,9 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
/*
* Write out the IPv4 resolved addresses, if any.
*/
if (wdh->addrinfo_lists->ipv4_addr_list){
if (mand_data->ipv4_addr_list){
i = 0;
ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(mand_data->ipv4_addr_list, i);
while(ipv4_hash_list_entry != NULL){
nrb.record_type = NRES_IP4RECORD;
@ -5660,7 +5651,7 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
* discard it.
*/
i++;
ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(mand_data->ipv4_addr_list, i);
continue;
}
namelen = (guint16)(hostnamelen + 1);
@ -5682,10 +5673,8 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
/*
* Put the options into the block.
*
* XXX - this puts the same options in all NRBs.
*/
put_nrb_options(wdh, block_data + block_off);
put_nrb_options(wdh, sdata, block_data + block_off);
block_off += options_size;
bh.block_total_length += options_size;
@ -5722,15 +5711,13 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
ws_debug("added IPv4 record for %s", ipv4_hash_list_entry->name);
i++;
ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(mand_data->ipv4_addr_list, i);
}
g_list_free(wdh->addrinfo_lists->ipv4_addr_list);
wdh->addrinfo_lists->ipv4_addr_list = NULL;
}
if (wdh->addrinfo_lists->ipv6_addr_list){
if (mand_data->ipv6_addr_list){
i = 0;
ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(mand_data->ipv6_addr_list, i);
while(ipv6_hash_list_entry != NULL){
nrb.record_type = NRES_IP6RECORD;
@ -5741,7 +5728,7 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
* discard it.
*/
i++;
ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(mand_data->ipv6_addr_list, i);
continue;
}
namelen = (guint16)(hostnamelen + 1);
@ -5763,10 +5750,8 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
/*
* Put the options into the block.
*
* XXX - this puts the same options in all NRBs.
*/
put_nrb_options(wdh, block_data + block_off);
put_nrb_options(wdh, sdata, block_data + block_off);
block_off += options_size;
bh.block_total_length += options_size;
@ -5803,10 +5788,8 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
ws_debug("added IPv6 record for %s", ipv6_hash_list_entry->name);
i++;
ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(mand_data->ipv6_addr_list, i);
}
g_list_free(wdh->addrinfo_lists->ipv6_addr_list);
wdh->addrinfo_lists->ipv6_addr_list = NULL;
}
/* Append the end-of-records record */
@ -5817,7 +5800,7 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
/*
* Put the options into the block.
*/
put_nrb_options(wdh, block_data + block_off);
put_nrb_options(wdh, sdata, block_data + block_off);
block_off += options_size;
bh.block_total_length += options_size;
@ -6077,13 +6060,8 @@ static gboolean pcapng_add_idb(wtap_dumper *wdh, wtap_block_t idb,
return pcapng_write_if_descr_block(wdh, idb_copy, err);
}
static gboolean pcapng_dump(wtap_dumper *wdh,
const wtap_rec *rec,
const guint8 *pd, int *err, gchar **err_info)
static gboolean pcapng_write_internal_blocks(wtap_dumper *wdh, int *err)
{
#ifdef HAVE_PLUGINS
block_handler *handler;
#endif
/* Write (optional) Decryption Secrets Blocks that were collected while
* reading packet blocks. */
@ -6098,6 +6076,80 @@ static gboolean pcapng_dump(wtap_dumper *wdh,
}
}
/* Write any hostname resolution info from wtap_dump_set_addrinfo_list() */
if (!wtap_addrinfo_list_empty(wdh->addrinfo_lists)) {
/*
* XXX: get_addrinfo_list() returns a list of all known and used
* resolved addresses, regardless of origin: existing NRBs, externally
* resolved, DNS packet data, a hosts file, and manual host resolution
* through the GUI. It does not include the source for each.
*
* If it did, we could instead create multiple NRBs, one for each
* server (as the options can only be included once per block.)
* Instead, we copy the options from the first already existing NRB
* (if there is one), since some of the name resolutions may be
* from that block.
*/
wtap_block_t nrb;
if (wdh->nrbs_growing && wdh->nrbs_growing->len) {
nrb = wtap_block_make_copy(g_array_index(wdh->nrbs_growing, wtap_block_t, 0));
} else {
nrb = wtap_block_create(WTAP_BLOCK_NAME_RESOLUTION);
}
wtapng_nrb_mandatory_t *mand_data = (wtapng_nrb_mandatory_t *)wtap_block_get_mandatory_data(nrb);
mand_data->ipv4_addr_list = wdh->addrinfo_lists->ipv4_addr_list;
mand_data->ipv6_addr_list = wdh->addrinfo_lists->ipv6_addr_list;
if (!pcapng_write_name_resolution_block(wdh, nrb, err)) {
return FALSE;
}
mand_data->ipv4_addr_list = NULL;
mand_data->ipv6_addr_list = NULL;
wtap_block_unref(nrb);
g_list_free(wdh->addrinfo_lists->ipv4_addr_list);
wdh->addrinfo_lists->ipv4_addr_list = NULL;
g_list_free(wdh->addrinfo_lists->ipv6_addr_list);
wdh->addrinfo_lists->ipv6_addr_list = NULL;
/* Since the addrinfo lists include information from existing NRBs,
* avoid writing them to avoid duplication.
*
* XXX: Perhaps we don't want to include information from the NRBs
* in get_addrinfo_list at all, so that we could write existing
* NRBs as-is.
*
* This is still not well oriented for one-pass programs, where we
* don't have addrinfo_lists until we've already written the
* NRBs. We should not write both in such a situation. See bug 15502.
*/
wtap_dump_discard_name_resolution(wdh);
}
/* Write (optional) Name Resolution Blocks that were collected while
* reading packet blocks. */
if (wdh->nrbs_growing) {
for (guint i = wdh->nrbs_growing_written; i < wdh->nrbs_growing->len; i++) {
wtap_block_t nrb = g_array_index(wdh->nrbs_growing, wtap_block_t, i);
if (!pcapng_write_name_resolution_block(wdh, nrb, err)) {
return FALSE;
}
++wdh->nrbs_growing_written;
}
}
return TRUE;
}
static gboolean pcapng_dump(wtap_dumper *wdh,
const wtap_rec *rec,
const guint8 *pd, int *err, gchar **err_info)
{
#ifdef HAVE_PLUGINS
block_handler *handler;
#endif
if (!pcapng_write_internal_blocks(wdh, err)) {
return FALSE;
}
ws_debug("encap = %d (%s) rec type = %u",
rec->rec_header.packet_header.pkt_encap,
@ -6182,8 +6234,10 @@ static gboolean pcapng_dump_finish(wtap_dumper *wdh, int *err,
{
guint i, j;
/* Flush any hostname resolution info we may have */
pcapng_write_name_resolution_block(wdh, err);
/* Flush any hostname resolution or decryption secrets info we may have */
if (!pcapng_write_internal_blocks(wdh, err)) {
return FALSE;
}
for (i = 0; i < wdh->interface_data->len; i++) {

View File

@ -42,7 +42,7 @@ struct wtap {
GArray *shb_hdrs;
GArray *interface_data; /**< An array holding the interface data from pcapng IDB:s or equivalent(?)*/
guint next_interface_data; /**< Next interface data that wtap_get_next_interface_description() will show */
GArray *nrb_hdrs; /**< holds the Name Res Block's comment/custom_opts, or NULL */
GArray *nrbs; /**< holds the Name Res Blocks, or NULL */
GArray *dsbs; /**< An array of DSBs (of type wtap_block_t), or NULL if not supported. */
char *pathname; /**< File pathname; might just be "-" */
@ -109,7 +109,6 @@ struct wtap_dumper {
addrinfo_lists_t *addrinfo_lists; /**< Struct containing lists of resolved addresses */
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) */
@ -117,7 +116,9 @@ struct wtap_dumper {
* Additional blocks that might grow as data is being collected.
* Subtypes should write these blocks before writing new packet blocks.
*/
const GArray *nrbs_growing; /**< A reference to an array of NRBs (of type wtap_block_t) */
const GArray *dsbs_growing; /**< A reference to an array of DSBs (of type wtap_block_t) */
guint nrbs_growing_written; /**< Number of already processed NRBs in nrbs_growing. */
guint dsbs_growing_written; /**< Number of already processed DSBs in dsbs_growing. */
};

View File

@ -440,31 +440,31 @@ wtap_get_debug_if_descr(const wtap_block_t if_descr,
wtap_block_t
wtap_file_get_nrb(wtap *wth)
{
if ((wth == NULL) || (wth->nrb_hdrs == NULL) || (wth->nrb_hdrs->len == 0))
if ((wth == NULL) || (wth->nrbs == NULL) || (wth->nrbs->len == 0))
return NULL;
return g_array_index(wth->nrb_hdrs, wtap_block_t, 0);
return g_array_index(wth->nrbs, wtap_block_t, 0);
}
GArray*
wtap_file_get_nrb_for_new_file(wtap *wth)
{
guint nrb_count;
wtap_block_t nrb_hdr_src, nrb_hdr_dest;
GArray* nrb_hdrs;
wtap_block_t nrb_src, nrb_dest;
GArray* nrbs;
if ((wth == NULL || wth->nrb_hdrs == NULL) || (wth->nrb_hdrs->len == 0))
if ((wth == NULL || wth->nrbs == NULL) || (wth->nrbs->len == 0))
return NULL;
nrb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
nrbs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
for (nrb_count = 0; nrb_count < wth->nrb_hdrs->len; nrb_count++) {
nrb_hdr_src = g_array_index(wth->nrb_hdrs, wtap_block_t, nrb_count);
nrb_hdr_dest = wtap_block_make_copy(nrb_hdr_src);
g_array_append_val(nrb_hdrs, nrb_hdr_dest);
for (nrb_count = 0; nrb_count < wth->nrbs->len; nrb_count++) {
nrb_src = g_array_index(wth->nrbs, wtap_block_t, nrb_count);
nrb_dest = wtap_block_make_copy(nrb_src);
g_array_append_val(nrbs, nrb_dest);
}
return nrb_hdrs;
return nrbs;
}
void
@ -479,10 +479,10 @@ wtap_dump_params_init(wtap_dump_params *params, wtap *wth)
params->tsprec = wtap_file_tsprec(wth);
params->shb_hdrs = wtap_file_get_shb_for_new_file(wth);
params->idb_inf = wtap_file_get_idb_info(wth);
params->nrb_hdrs = wtap_file_get_nrb_for_new_file(wth);
/* Assume that the input handle remains open until the dumper is closed.
* Refer to the DSBs from the input file, wtap_dump will then copy DSBs
* as they become available. */
params->nrbs_growing = wth->nrbs;
params->dsbs_growing = wth->dsbs;
params->dont_copy_idbs = FALSE;
}
@ -503,14 +503,20 @@ wtap_dump_params_init_no_idbs(wtap_dump_params *params, wtap *wth)
params->tsprec = wtap_file_tsprec(wth);
params->shb_hdrs = wtap_file_get_shb_for_new_file(wth);
params->idb_inf = wtap_file_get_idb_info(wth);
params->nrb_hdrs = wtap_file_get_nrb_for_new_file(wth);
/* Assume that the input handle remains open until the dumper is closed.
* Refer to the DSBs from the input file, wtap_dump will then copy DSBs
* as they become available. */
params->nrbs_growing = wth->nrbs;
params->dsbs_growing = wth->dsbs;
params->dont_copy_idbs = TRUE;
}
void
wtap_dump_params_discard_name_resolution(wtap_dump_params *params)
{
params->nrbs_growing = NULL;
}
void
wtap_dump_params_discard_decryption_secrets(wtap_dump_params *params)
{
@ -523,7 +529,6 @@ wtap_dump_params_cleanup(wtap_dump_params *params)
{
wtap_block_array_free(params->shb_hdrs);
/* params->idb_inf is currently expected to be freed by the caller. */
wtap_block_array_free(params->nrb_hdrs);
memset(params, 0, sizeof(*params));
}
@ -1477,7 +1482,7 @@ wtap_close(wtap *wth)
}
wtap_block_array_free(wth->shb_hdrs);
wtap_block_array_free(wth->nrb_hdrs);
wtap_block_array_free(wth->nrbs);
wtap_block_array_free(wth->interface_data);
wtap_block_array_free(wth->dsbs);
@ -1522,18 +1527,16 @@ void wtap_set_cb_new_ipv4(wtap *wth, wtap_new_ipv4_callback_t add_new_ipv4) {
wth->add_new_ipv4 = add_new_ipv4;
/* Are there any existing NRBs? (XXX: Unlike with DSBs, the
* GArray of nrb_hdrs is not initialized until the first one
* is encountered. */
if (!wth->nrb_hdrs)
/* Are there any existing NRBs? */
if (!wth->nrbs)
return;
/*
* Send all NRBs that were read so far to the new callback. file.c
* relies on this to support redissection (during redissection, the
* previous name resolutions are lost and has to be resupplied).
*/
for (guint i = 0; i < wth->nrb_hdrs->len; i++) {
wtap_block_t nrb = g_array_index(wth->nrb_hdrs, wtap_block_t, i);
for (guint i = 0; i < wth->nrbs->len; i++) {
wtap_block_t nrb = g_array_index(wth->nrbs, wtap_block_t, i);
wtapng_process_nrb_ipv4(wth, nrb);
}
}
@ -1544,18 +1547,16 @@ void wtap_set_cb_new_ipv6(wtap *wth, wtap_new_ipv6_callback_t add_new_ipv6) {
wth->add_new_ipv6 = add_new_ipv6;
/* Are there any existing NRBs? (XXX: Unlike with DSBs, the
* GArray of nrb_hdrs is not initialized until the first one
* is encountered. */
if (!wth->nrb_hdrs)
/* Are there any existing NRBs? */
if (!wth->nrbs)
return;
/*
* Send all NRBs that were read so far to the new callback. file.c
* relies on this to support redissection (during redissection, the
* previous name resolutions are lost and has to be resupplied).
*/
for (guint i = 0; i < wth->nrb_hdrs->len; i++) {
wtap_block_t nrb = g_array_index(wth->nrb_hdrs, wtap_block_t, i);
for (guint i = 0; i < wth->nrbs->len; i++) {
wtap_block_t nrb = g_array_index(wth->nrbs, wtap_block_t, i);
wtapng_process_nrb_ipv6(wth, nrb);
}
}

View File

@ -1448,11 +1448,12 @@ typedef struct addrinfo_lists {
* from wtap_dump_*, but its pointer fields must remain valid until
* wtap_dump_close is called.
*
* @note The shb_hdr, idb_inf, and nrb_hdr arguments will be used until
* @note The shb_hdr and idb_inf arguments will be used until
* wtap_dump_close() is called, but will not be free'd by the dumper. If
* you created them, you must free them yourself after wtap_dump_close().
* dsbs_initial will be freed by wtap_dump_close(),
* dsbs_growing typically refers to another wth->dsbs.
* nrbs_growing typically refers to another wth->nrbs.
*
* @see wtap_dump_params_init, wtap_dump_params_cleanup.
*/
@ -1462,7 +1463,9 @@ typedef struct wtap_dump_params {
int tsprec; /**< Per-file time stamp precision */
GArray *shb_hdrs; /**< The section header block(s) information, or NULL. */
wtapng_iface_descriptions_t *idb_inf; /**< The interface description information, or NULL. */
GArray *nrb_hdrs; /**< The name resolution blocks(s) comment/custom_opts information, or NULL. */
const GArray *nrbs_growing; /**< NRBs that will be written while writing packets, or NULL.
This array may grow since the dumper was opened and will subsequently
be written before newer packets are written in wtap_dump. */
GArray *dsbs_initial; /**< The initial Decryption Secrets Block(s) to be written, or NULL. */
const GArray *dsbs_growing; /**< DSBs that will be written while writing packets, or NULL.
This array may grow since the dumper was opened and will subsequently
@ -2033,6 +2036,16 @@ void wtap_dump_params_init(wtap_dump_params *params, wtap *wth);
WS_DLL_PUBLIC
void wtap_dump_params_init_no_idbs(wtap_dump_params *params, wtap *wth);
/**
* Remove any name resolution information from the per-file information;
* used if we're stripping name resolution as we write the file.
*
* @param params The parameters for wtap_dump_* from which to remove the
* name resolution..
*/
WS_DLL_PUBLIC
void wtap_dump_params_discard_name_resolution(wtap_dump_params *params);
/**
* Remove any decryption secret information from the per-file information;
* used if we're stripping decryption secrets as we write the file.
@ -2154,11 +2167,13 @@ gboolean wtap_addrinfo_list_empty(addrinfo_lists_t *addrinfo_lists);
WS_DLL_PUBLIC
gboolean wtap_dump_set_addrinfo_list(wtap_dumper *wdh, addrinfo_lists_t *addrinfo_lists);
WS_DLL_PUBLIC
void wtap_dump_discard_name_resolution(wtap_dumper *wdh);
WS_DLL_PUBLIC
void wtap_dump_discard_decryption_secrets(wtap_dumper *wdh);
/**
* Closes open file handles and frees memory associated with wdh. Note that
* shb_hdr, idb_inf and nrb_hdr are not freed by this routine.
* shb_hdr and idb_inf are not freed by this routine.
*
* @param wdh handle for the file we're closing.
* @param[out] needs_reload if not null, points to a gboolean that will

View File

@ -230,7 +230,7 @@ typedef struct wtapng_if_descr_mandatory_s {
/**
* Holds the required data from a WTAP_BLOCK_NAME_RESOLUTION.
*/
typedef struct wtapnf_nrb_mandatory_s {
typedef struct wtapng_nrb_mandatory_s {
GList *ipv4_addr_list;
GList *ipv6_addr_list;
} wtapng_nrb_mandatory_t;