diff --git a/editcap.c b/editcap.c index 51d556f5f8..b646167089 100644 --- a/editcap.c +++ b/editcap.c @@ -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; diff --git a/tshark.c b/tshark.c index bb457c6785..1238a6ab54 100644 --- a/tshark.c +++ b/tshark.c @@ -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 -w ", + * 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)); diff --git a/wiretap/file_access.c b/wiretap/file_access.c index 5edae08169..54adc1e5d3 100644 --- a/wiretap/file_access.c +++ b/wiretap/file_access.c @@ -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) { diff --git a/wiretap/merge.c b/wiretap/merge.c index c567288247..121b80751f 100644 --- a/wiretap/merge.c +++ b/wiretap/merge.c @@ -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); } diff --git a/wiretap/merge.h b/wiretap/merge.h index 699258209c..b069f3ff0a 100644 --- a/wiretap/merge.h +++ b/wiretap/merge.h @@ -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; diff --git a/wiretap/pcapng.c b/wiretap/pcapng.c index f37212c0b1..98bc2375aa 100644 --- a/wiretap/pcapng.c +++ b/wiretap/pcapng.c @@ -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++) { diff --git a/wiretap/wtap-int.h b/wiretap/wtap-int.h index 2b1ad434a9..1ea8915cd7 100644 --- a/wiretap/wtap-int.h +++ b/wiretap/wtap-int.h @@ -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. */ }; diff --git a/wiretap/wtap.c b/wiretap/wtap.c index 8e63e81f5f..fca574265d 100644 --- a/wiretap/wtap.c +++ b/wiretap/wtap.c @@ -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); } } diff --git a/wiretap/wtap.h b/wiretap/wtap.h index eb4ef728af..d2e911e60b 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -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 diff --git a/wiretap/wtap_opttypes.h b/wiretap/wtap_opttypes.h index f9553f23b9..6104b18e6c 100644 --- a/wiretap/wtap_opttypes.h +++ b/wiretap/wtap_opttypes.h @@ -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;