TODO SMB2 NegotiateContext....
[metze/wireshark/wip.git] / tshark.c
index fec5266d633c0dedaf1044978607ee892779aebb..260d9cda8a8b2b82a9cd58b6a10f5cbde7e74aff 100644 (file)
--- a/tshark.c
+++ b/tshark.c
 #include <epan/exceptions.h>
 #include <epan/epan.h>
 
-#include <wsutil/clopts_common.h>
-#include <wsutil/cmdarg_err.h>
-#include <wsutil/crash_info.h>
+#include <ui/clopts_common.h>
+#include <ui/cmdarg_err.h>
 #include <wsutil/filesystem.h>
 #include <wsutil/file_util.h>
 #include <wsutil/privileges.h>
 #include <wsutil/report_message.h>
+#include <cli_main.h>
 #include <version_info.h>
 #include <wiretap/wtap_opttypes.h>
 #include <wiretap/pcapng.h>
@@ -86,7 +86,6 @@
 #include "epan/oids.h"
 #endif
 #include "epan/maxmind_db.h"
-#include "epan/register.h"
 #include <epan/epan_dissect.h>
 #include <epan/tap.h>
 #include <epan/stat_tap_ui.h>
@@ -95,6 +94,7 @@
 #include <epan/rtd_table.h>
 #include <epan/ex-opt.h>
 #include <epan/exported_pdu.h>
+#include <epan/secrets.h>
 
 #include "capture_opts.h"
 
 #include "caputils/capture_ifinfo.h"
 #ifdef _WIN32
 #include "caputils/capture-wpcap.h"
-#include <wsutil/os_version_info.h>
-#include <wsutil/unicode-utils.h>
 #endif /* _WIN32 */
 #include <capchild/capture_session.h>
 #include <capchild/capture_sync.h>
 
 #include <wsutil/str_util.h>
 #include <wsutil/utf8_entities.h>
+#include <wsutil/json_dumper.h>
 
 #include "extcap.h"
 
  */
 #define LONGOPT_COLOR (65536+1000)
 #define LONGOPT_NO_DUPLICATE_KEYS (65536+1001)
-#ifdef HAVE_JSONGLIB
 #define LONGOPT_ELASTIC_MAPPING_FILTER (65536+1002)
-#endif
 
 #if 0
 #define tshark_debug(...) g_warning(__VA_ARGS__)
@@ -197,6 +194,8 @@ static pf_flags protocolfilter_flags = PF_NONE;
 static gboolean no_duplicate_keys = FALSE;
 static proto_node_children_grouper_func node_children_grouper = proto_node_group_children_by_unique;
 
+static json_dumper jdumper;
+
 /* The line separator used between packets, changeable via the -S option */
 static const char *separator = "";
 
@@ -266,7 +265,7 @@ string_compare(gconstpointer a, gconstpointer b)
 }
 
 static void
-string_elem_print(gpointer data, gpointer not_used _U_)
+string_elem_print(gpointer data)
 {
   fprintf(stderr, "    %s - %s\n",
           ((struct string_elem *)data)->sstr,
@@ -289,8 +288,7 @@ list_capture_types(void) {
       list = g_slist_insert_sorted(list, &captypes[i], string_compare);
     }
   }
-  g_slist_foreach(list, string_elem_print, NULL);
-  g_slist_free(list);
+  g_slist_free_full(list, string_elem_print);
   g_free(captypes);
 }
 
@@ -311,8 +309,7 @@ list_read_capture_types(void) {
     captypes[i].lstr = (open_routines[i].type == OPEN_INFO_MAGIC) ? magic : heuristic;
     list = g_slist_insert_sorted(list, &captypes[i], string_compare);
   }
-  g_slist_foreach(list, string_elem_print, NULL);
-  g_slist_free(list);
+  g_slist_free_full(list, string_elem_print);
   g_free(captypes);
 }
 
@@ -374,7 +371,7 @@ print_usage(FILE *output)
   fprintf(output, "  -Y <display filter>      packet displaY filter in Wireshark display filter\n");
   fprintf(output, "                           syntax\n");
   fprintf(output, "  -n                       disable all name resolutions (def: all enabled)\n");
-  fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mnNtCd\"\n");
+  fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mnNtdv\"\n");
   fprintf(output, "  -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
   fprintf(output, "                           \"Decode As\", see the man page for details\n");
   fprintf(output, "                           Example: tcp.port==8888,http\n");
@@ -391,10 +388,18 @@ print_usage(FILE *output)
 
   /*fprintf(output, "\n");*/
   fprintf(output, "Output:\n");
+#ifdef PCAP_NG_DEFAULT
+  fprintf(output, "  -w <outfile|->           write packets to a pcapng-format file named \"outfile\"\n");
+#else
   fprintf(output, "  -w <outfile|->           write packets to a pcap-format file named \"outfile\"\n");
+#endif
   fprintf(output, "                           (or to the standard output for \"-\")\n");
   fprintf(output, "  -C <config profile>      start with specified configuration profile\n");
+#ifdef PCAP_NG_DEFAULT
   fprintf(output, "  -F <output file type>    set the output file type, default is pcapng\n");
+#else
+  fprintf(output, "  -F <output file type>    set the output file type, default is pcap\n");
+#endif
   fprintf(output, "                           an empty \"-F\" option will list the file types\n");
   fprintf(output, "  -V                       add output of packet tree        (Packet Details)\n");
   fprintf(output, "  -O <protocols>           Only show packet details of these protocols, comma\n");
@@ -443,10 +448,8 @@ print_usage(FILE *output)
   fprintf(output, "  --no-duplicate-keys      If -T json is specified, merge duplicate keys in an object\n");
   fprintf(output, "                           into a single key with as value a json array containing all\n");
   fprintf(output, "                           values\n");
-#ifdef HAVE_JSONGLIB
   fprintf(output, "  --elastic-mapping-filter <protocols> If -G elastic-mapping is specified, put only the\n");
   fprintf(output, "                           specified protocols within the mapping file\n");
-#endif
 
   fprintf(output, "\n");
   fprintf(output, "Miscellaneous:\n");
@@ -474,7 +477,7 @@ glossary_option_help(void)
 
   output = stdout;
 
-  fprintf(output, "TShark (Wireshark) %s\n", get_ws_vcs_version_info());
+  fprintf(output, "%s\n", get_appname_and_version());
 
   fprintf(output, "\n");
   fprintf(output, "Usage: tshark -G [report]\n");
@@ -483,9 +486,7 @@ glossary_option_help(void)
   fprintf(output, "  -G column-formats        dump column format codes and exit\n");
   fprintf(output, "  -G decodes               dump \"layer type\"/\"decode as\" associations and exit\n");
   fprintf(output, "  -G dissector-tables      dump dissector table names, types, and properties\n");
-#ifdef HAVE_JSONGLIB
   fprintf(output, "  -G elastic-mapping       dump ElasticSearch mapping file\n");
-#endif
   fprintf(output, "  -G fieldcount            dump count of header fields and exit\n");
   fprintf(output, "  -G fields                dump fields glossary and exit\n");
   fprintf(output, "  -G ftypes                dump field type basic and descriptive names\n");
@@ -674,8 +675,6 @@ must_do_dissection(dfilter_t *rfcode, dfilter_t *dfcode,
 int
 main(int argc, char *argv[])
 {
-  GString             *comp_info_str;
-  GString             *runtime_info_str;
   char                *init_progfile_dir_error;
   int                  opt;
   static const struct option long_options[] = {
@@ -687,9 +686,7 @@ main(int argc, char *argv[])
     {"export-objects", required_argument, NULL, LONGOPT_EXPORT_OBJECTS},
     {"color", no_argument, NULL, LONGOPT_COLOR},
     {"no-duplicate-keys", no_argument, NULL, LONGOPT_NO_DUPLICATE_KEYS},
-#ifdef HAVE_JSONGLIB
     {"elastic-mapping-filter", required_argument, NULL, LONGOPT_ELASTIC_MAPPING_FILTER},
-#endif
     {0, 0, 0, 0 }
   };
   gboolean             arg_error = FALSE;
@@ -709,6 +706,7 @@ main(int argc, char *argv[])
   gchar               *err_str;
 #else
   gboolean             capture_option_specified = FALSE;
+  volatile int         max_packet_count = 0;
 #endif
   gboolean             quiet = FALSE;
 #ifdef PCAP_NG_DEFAULT
@@ -731,11 +729,9 @@ main(int argc, char *argv[])
   int                  log_flags;
   gchar               *output_only = NULL;
   gchar               *volatile pdu_export_arg = NULL;
-  const char          *volatile exp_pdu_filename = NULL;
+  char                *volatile exp_pdu_filename = NULL;
   exp_pdu_t            exp_pdu_tap_data;
-#ifdef HAVE_JSONGLIB
   const gchar*         elastic_mapping_filter = NULL;
-#endif
 
 /*
  * The leading + ensures that getopt_long() does not permute the argv[]
@@ -768,7 +764,6 @@ main(int argc, char *argv[])
   cmdarg_err_init(failure_warning_message, failure_message_cont);
 
 #ifdef _WIN32
-  arg_list_utf_16to8(argc, argv);
   create_app_running_mutex();
 #endif /* _WIN32 */
 
@@ -785,7 +780,7 @@ main(int argc, char *argv[])
    * Attempt to get the pathname of the directory containing the
    * executable file.
    */
-  init_progfile_dir_error = init_progfile_dir(argv[0], main);
+  init_progfile_dir_error = init_progfile_dir(argv[0]);
   if (init_progfile_dir_error != NULL) {
     fprintf(stderr,
             "tshark: Can't get pathname of directory containing the tshark program: %s.\n"
@@ -802,31 +797,13 @@ main(int argc, char *argv[])
 #ifdef HAVE_LIBPCAP
   /* Load wpcap if possible. Do this before collecting the run-time version information */
   load_wpcap();
-
-  /* Warn the user if npf.sys isn't loaded. */
-  if (!npf_sys_is_running() && get_windows_major_version() >= 6) {
-    fprintf(stderr, "The NPF driver isn't running.  You may have trouble "
-      "capturing or\nlisting interfaces.\n");
-  }
 #endif /* HAVE_LIBPCAP */
 #endif /* _WIN32 */
 
-  /* Get the compile-time version information string */
-  comp_info_str = get_compiled_version_info(get_tshark_compiled_version_info,
-                                            epan_get_compiled_version_info);
-
-  /* Get the run-time version information string */
-  runtime_info_str = get_runtime_version_info(get_tshark_runtime_version_info);
-
-  /* Add it to the information to be reported on a crash. */
-  ws_add_crash_info("TShark (Wireshark) %s\n"
-         "\n"
-         "%s"
-         "\n"
-         "%s",
-      get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
-  g_string_free(comp_info_str, TRUE);
-  g_string_free(runtime_info_str, TRUE);
+  /* Initialize the version information. */
+  ws_init_version_info("TShark (Wireshark)", get_tshark_compiled_version_info,
+                       epan_get_compiled_version_info,
+                       get_tshark_runtime_version_info);
 
   /* Fail sometimes. Useful for testing fuzz scripts. */
   /* if (g_random_int_range(0, 100) < 5) abort(); */
@@ -877,11 +854,9 @@ main(int argc, char *argv[])
     case 'X':
       ex_opt_add(optarg);
       break;
-#ifdef HAVE_JSONGLIB
     case LONGOPT_ELASTIC_MAPPING_FILTER:
       elastic_mapping_filter = optarg;
       break;
-#endif
     default:
       break;
     }
@@ -933,8 +908,7 @@ main(int argc, char *argv[])
      "-G" flag, as the "-G" flag dumps information registered by the
      dissectors, and we must do it before we read the preferences, in
      case any dissectors register preferences. */
-  if (!epan_init(register_all_protocols, register_all_protocol_handoffs, NULL,
-                 NULL)) {
+  if (!epan_init(NULL, NULL, TRUE)) {
     exit_status = INIT_FAILED;
     goto clean_exit;
   }
@@ -985,10 +959,8 @@ main(int argc, char *argv[])
         write_prefs(NULL);
       else if (strcmp(argv[2], "dissector-tables") == 0)
         dissector_dump_dissector_tables();
-#ifdef HAVE_JSONGLIB
       else if (strcmp(argv[2], "elastic-mapping") == 0)
         proto_registrar_dump_elastic(elastic_mapping_filter);
-#endif
       else if (strcmp(argv[2], "fieldcount") == 0) {
         /* return value for the test suite */
         exit_status = proto_registrar_dump_fieldcount();
@@ -1122,7 +1094,9 @@ main(int argc, char *argv[])
          * Output file name, if we're reading a file and writing to another
          * file.
          */
-        output_file_name = optarg;
+        output_file_name = g_strdup(optarg);
+      } else if (opt == 'c') {
+        max_packet_count = get_positive_int(optarg, "packet count");
       } else {
         capture_option_specified = TRUE;
         arg_error = TRUE;
@@ -1205,10 +1179,7 @@ main(int argc, char *argv[])
       break;
 
     case 'h':        /* Print help and exit */
-      printf("TShark (Wireshark) %s\n"
-             "Dump and analyze network traffic.\n"
-             "See https://www.wireshark.org for more information.\n",
-             get_ws_vcs_version_info());
+      show_help_header("Dump and analyze network traffic.");
       print_usage(stdout);
       exit_status = EXIT_SUCCESS;
       goto clean_exit;
@@ -1387,12 +1358,7 @@ main(int argc, char *argv[])
         break;
     }
     case 'v':         /* Show version and exit */
-      comp_info_str = get_compiled_version_info(get_tshark_compiled_version_info,
-                                                epan_get_compiled_version_info);
-      runtime_info_str = get_runtime_version_info(get_tshark_runtime_version_info);
-      show_version("TShark (Wireshark)", comp_info_str, runtime_info_str);
-      g_string_free(comp_info_str, TRUE);
-      g_string_free(runtime_info_str, TRUE);
+      show_version();
       /* We don't really have to cleanup here, but it's a convenient way to test
        * start-up and shut-down of the epan library without any UI-specific
        * cruft getting in the way. Makes the results of running
@@ -1565,29 +1531,31 @@ main(int argc, char *argv[])
 
 #ifdef HAVE_LIBPCAP
   if (!global_capture_opts.saving_to_file) {
+#else
+  if (!output_file_name) {
+#endif
     /* We're not saving the capture to a file; if "-q" wasn't specified,
        we should print packet information */
     if (!quiet)
       print_packet_info = TRUE;
   } else {
+#ifdef HAVE_LIBPCAP
+    const char *save_file = global_capture_opts.save_file;
+#else
+    const char *save_file = output_file_name;
+#endif
     /* We're saving to a file; if we're writing to the standard output.
        and we'll also be writing dissected packets to the standard
        output, reject the request.  At best, we could redirect that
        to the standard error; we *can't* write both to the standard
        output and have either of them be useful. */
-    if (strcmp(global_capture_opts.save_file, "-") == 0 && print_packet_info) {
+    if (strcmp(save_file, "-") == 0 && print_packet_info) {
       cmdarg_err("You can't write both raw packet data and dissected packets"
           " to the standard output.");
       exit_status = INVALID_OPTION;
       goto clean_exit;
     }
   }
-#else
-  /* We're not saving the capture to a file; if "-q" wasn't specified,
-     we should print packet information */
-  if (!quiet)
-    print_packet_info = TRUE;
-#endif
 
 #ifndef HAVE_LIBPCAP
   if (capture_option_specified)
@@ -2000,20 +1968,25 @@ main(int argc, char *argv[])
           goto clean_exit;
       }
 
-      exp_fd = ws_open(exp_pdu_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
-      if (exp_fd == -1) {
+      if (strcmp(exp_pdu_filename, "-") == 0) {
+        /* Write to the standard output. */
+        exp_fd = 1;
+      } else {
+        exp_fd = ws_open(exp_pdu_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
+        if (exp_fd == -1) {
           cmdarg_err("%s: %s", exp_pdu_filename, file_open_error_message(errno, TRUE));
           exit_status = INVALID_FILE;
           goto clean_exit;
+        }
       }
 
       /* Activate the export PDU tap */
       comment = g_strdup_printf("Dump of PDUs from %s", cf_name);
       err = exp_pdu_open(&exp_pdu_tap_data, exp_fd, comment);
+      g_free(comment);
       if (err != 0) {
           cfile_dump_open_failure_message("TShark", exp_pdu_filename, err,
                                           WTAP_FILE_TYPE_SUBTYPE_PCAPNG);
-          g_free(comment);
           exit_status = INVALID_EXPORT;
           goto clean_exit;
       }
@@ -2054,7 +2027,7 @@ main(int argc, char *argv[])
           global_capture_opts.has_autostop_packets ? global_capture_opts.autostop_packets : 0,
           global_capture_opts.has_autostop_filesize ? global_capture_opts.autostop_filesize : 0);
 #else
-      success = process_cap_file(&cfile, output_file_name, out_file_type, out_file_name_res, 0, 0);
+      success = process_cap_file(&cfile, output_file_name, out_file_type, out_file_name_res, max_packet_count, 0);
 #endif
     }
     CATCH(OutOfMemoryError) {
@@ -2082,6 +2055,7 @@ main(int argc, char *argv[])
             exit_status = 2;
         }
         g_free(pdu_export_arg);
+        g_free(exp_pdu_filename);
     }
   } else {
     tshark_debug("tshark: no capture file specified");
@@ -2089,6 +2063,14 @@ main(int argc, char *argv[])
        or get a list of link-layer types for a live capture device;
        do we have support for live captures? */
 #ifdef HAVE_LIBPCAP
+#ifdef _WIN32
+    /* Warn the user if npf.sys isn't loaded. */
+    if (!npf_sys_is_running()) {
+      fprintf(stderr, "The NPF driver isn't running.  You may have trouble "
+          "capturing or\nlisting interfaces.\n");
+    }
+#endif /* _WIN32 */
+
     /* if no interface was specified, pick a default */
     exit_status = capture_opts_default_iface_if_necessary(&global_capture_opts,
         ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
@@ -2223,14 +2205,14 @@ main(int argc, char *argv[])
 #endif
   }
 
-  g_free(cf_name);
-
   if (cfile.provider.frames != NULL) {
     free_frame_data_sequence(cfile.provider.frames);
     cfile.provider.frames = NULL;
   }
 
   draw_tap_listeners(TRUE);
+  /* Memory cleanup */
+  reset_tap_listeners();
   funnel_dump_all_text_windows();
   epan_free(cfile.epan);
   epan_cleanup();
@@ -2240,9 +2222,12 @@ main(int argc, char *argv[])
   output_fields = NULL;
 
 clean_exit:
+  g_free(cf_name);
   destroy_print_stream(print_stream);
 #ifdef HAVE_LIBPCAP
   capture_opts_cleanup(&global_capture_opts);
+#else
+  g_free(output_file_name);
 #endif
   col_cleanup(&cfile.cinfo);
   free_filter_lists();
@@ -2398,7 +2383,7 @@ tshark_epan_new(capture_file *cf)
 static gboolean
 capture(void)
 {
-  gboolean          ret;
+  volatile gboolean ret = TRUE;
   guint             i;
   GString          *str;
 #ifdef USE_TSHARK_SELECT
@@ -2468,6 +2453,13 @@ capture(void)
   if (!ret)
     return FALSE;
 
+  /*
+   * Force synchronous resolution of IP addresses; we're doing only
+   * one pass, so we can't do it in the background and fix up past
+   * dissections.
+   */
+  set_resolution_synchrony(TRUE);
+
   /* the actual capture loop
    *
    * XXX - glib doesn't seem to provide any event based loop handling.
@@ -2503,13 +2495,15 @@ capture(void)
       if (ret == -1)
       {
         fprintf(stderr, "%s: %s\n", "select()", g_strerror(errno));
-        return TRUE;
+        ret = TRUE;
+        loop_running = FALSE;
       } else if (ret == 1) {
 #endif
         /* Call the real handler */
         if (!pipe_input.input_cb(pipe_input.source, pipe_input.user_data)) {
           g_log(NULL, G_LOG_LEVEL_DEBUG, "input pipe closed");
-          return FALSE;
+          ret = FALSE;
+          loop_running = FALSE;
         }
 #ifdef USE_TSHARK_SELECT
       }
@@ -2524,10 +2518,10 @@ capture(void)
             "\n"
             "More information and workarounds can be found at\n"
             "https://wiki.wireshark.org/KnownBugs/OutOfMemory\n");
-    exit(1);
+    abort();
   }
   ENDTRY;
-  return TRUE;
+  return ret;
 }
 
 /* capture child detected an error */
@@ -2579,7 +2573,7 @@ gboolean
 capture_input_new_file(capture_session *cap_session, gchar *new_file)
 {
   capture_options *capture_opts = cap_session->capture_opts;
-  capture_file *cf = (capture_file *) cap_session->cf;
+  capture_file *cf = cap_session->cf;
   gboolean is_tempfile;
   int      err;
 
@@ -2618,9 +2612,9 @@ capture_input_new_file(capture_session *cap_session, gchar *new_file)
   /* if we are in real-time mode, open the new file now */
   if (do_dissection) {
     /* this is probably unecessary, but better safe than sorry */
-    ((capture_file *)cap_session->cf)->open_type = WTAP_TYPE_AUTO;
+    cap_session->cf->open_type = WTAP_TYPE_AUTO;
     /* Attempt to open the capture file and set up to read from it. */
-    switch(cf_open((capture_file *)cap_session->cf, capture_opts->save_file, WTAP_TYPE_AUTO, is_tempfile, &err)) {
+    switch(cf_open(cap_session->cf, capture_opts->save_file, WTAP_TYPE_AUTO, is_tempfile, &err)) {
     case CF_OK:
       break;
     case CF_ERROR:
@@ -2646,7 +2640,7 @@ capture_input_new_packets(capture_session *cap_session, int to_read)
   int           err;
   gchar        *err_info;
   gint64        data_offset;
-  capture_file *cf = (capture_file *)cap_session->cf;
+  capture_file *cf = cap_session->cf;
   gboolean      filtering_tap_listeners;
   guint         tap_flags;
 
@@ -2786,7 +2780,7 @@ report_counts_siginfo(int signum _U_)
 
 /* capture child detected any packet drops? */
 void
-capture_input_drops(capture_session *cap_session _U_, guint32 dropped)
+capture_input_drops(capture_session *cap_session _U_, guint32 dropped, char* interface_name)
 {
   if (print_packet_counts) {
     /* We're printing packet counts to stderr.
@@ -2797,7 +2791,11 @@ capture_input_drops(capture_session *cap_session _U_, guint32 dropped)
   if (dropped != 0) {
     /* We're printing packet counts to stderr.
        Send a newline so that we move to the line after the packet count. */
-    fprintf(stderr, "%u packet%s dropped\n", dropped, plurality(dropped, "", "s"));
+    if (interface_name != NULL) {
+      fprintf(stderr, "%u packet%s dropped from %s\n", dropped, plurality(dropped, "", "s"), interface_name);
+    } else {
+      fprintf(stderr, "%u packet%s dropped\n", dropped, plurality(dropped, "", "s"));
+    }
   }
 }
 
@@ -2809,7 +2807,7 @@ capture_input_drops(capture_session *cap_session _U_, guint32 dropped)
 void
 capture_input_closed(capture_session *cap_session, gchar *msg)
 {
-  capture_file *cf = (capture_file *) cap_session->cf;
+  capture_file *cf = cap_session->cf;
 
   if (msg != NULL)
     fprintf(stderr, "tshark: %s\n", msg);
@@ -2907,11 +2905,6 @@ process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
      from the dissection or running taps on the packet; if we're doing
      any of that, we'll do it in the second pass.) */
   if (edt) {
-    if (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
-        gbl_resolv_flags.transport_name)
-      /* Grab any resolved addresses */
-      host_name_lookup_process();
-
     /* If we're running a read filter, prime the epan_dissect_t with that
        filter. */
     if (cf->rfcode)
@@ -2988,11 +2981,6 @@ process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
      passes over the packets; that's the pass where we print
      packet information or run taps.) */
   if (edt) {
-    if (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
-        gbl_resolv_flags.transport_name)
-      /* Grab any resolved addresses */
-      host_name_lookup_process();
-
     /* If we're running a display filter, prime the epan_dissect_t with that
        filter. */
     if (cf->dfcode)
@@ -3020,7 +3008,7 @@ process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
 
     if (dissect_color) {
       color_filters_prime_edt(edt);
-      fdata->flags.need_colorize = 1;
+      fdata->need_colorize = 1;
     }
 
     epan_dissect_run_with_taps(edt, cf->cd_t, rec,
@@ -3058,7 +3046,7 @@ process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
   if (edt) {
     epan_dissect_reset(edt);
   }
-  return passed || fdata->flags.dependent_of_displayed;
+  return passed || fdata->dependent_of_displayed;
 }
 
 static gboolean
@@ -3066,8 +3054,6 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type,
     gboolean out_file_name_res, int max_packet_count, gint64 max_byte_count)
 {
   gboolean     success = TRUE;
-  gint         linktype;
-  int          snapshot_length;
   wtap_dumper *pdh;
   guint32      framenum;
   int          err = 0, err_pass1 = 0;
@@ -3075,70 +3061,36 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type,
   gint64       data_offset;
   gboolean     filtering_tap_listeners;
   guint        tap_flags;
-  GArray                      *shb_hdrs = NULL;
-  wtapng_iface_descriptions_t *idb_inf = NULL;
-  GArray                      *nrb_hdrs = NULL;
+  wtap_dump_params params = WTAP_DUMP_PARAMS_INIT;
   wtap_rec     rec;
   Buffer       buf;
   epan_dissect_t *edt = NULL;
-  char                        *shb_user_appl;
+  char        *shb_user_appl;
 
   wtap_rec_init(&rec);
 
-  idb_inf = wtap_file_get_idb_info(cf->provider.wth);
-#ifdef PCAP_NG_DEFAULT
-  if (idb_inf->interface_data->len > 1) {
-    linktype = WTAP_ENCAP_PER_PACKET;
-  } else {
-    linktype = wtap_file_encap(cf->provider.wth);
-  }
-#else
-  linktype = wtap_file_encap(cf->provider.wth);
-#endif
   if (save_file != NULL) {
     /* Set up to write to the capture file. */
-    snapshot_length = wtap_snapshot_length(cf->provider.wth);
-    if (snapshot_length == 0) {
-      /* Snapshot length of input file not known. */
-      snapshot_length = WTAP_MAX_PACKET_SIZE_STANDARD;
-    }
-    tshark_debug("tshark: snapshot_length = %d", snapshot_length);
-
-    shb_hdrs = wtap_file_get_shb_for_new_file(cf->provider.wth);
-    nrb_hdrs = wtap_file_get_nrb_for_new_file(cf->provider.wth);
+    wtap_dump_params_init(&params, cf->provider.wth);
 
     /* If we don't have an application name add Tshark */
-    if (wtap_block_get_string_option_value(g_array_index(shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, &shb_user_appl) != WTAP_OPTTYPE_SUCCESS) {
+    if (wtap_block_get_string_option_value(g_array_index(params.shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, &shb_user_appl) != WTAP_OPTTYPE_SUCCESS) {
         /* this is free'd by wtap_block_free() later */
-        wtap_block_add_string_option_format(g_array_index(shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, "TShark (Wireshark) %s", get_ws_vcs_version_info());
+        wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, "%s", get_appname_and_version());
     }
 
-    if (linktype != WTAP_ENCAP_PER_PACKET &&
-        out_file_type == WTAP_FILE_TYPE_SUBTYPE_PCAP) {
-        tshark_debug("tshark: writing PCAP format to %s", save_file);
-        if (strcmp(save_file, "-") == 0) {
-          /* Write to the standard output. */
-          pdh = wtap_dump_open_stdout(out_file_type, linktype,
-              snapshot_length, FALSE /* compressed */, &err);
-        } else {
-          pdh = wtap_dump_open(save_file, out_file_type, linktype,
-              snapshot_length, FALSE /* compressed */, &err);
-        }
-    }
-    else {
-        tshark_debug("tshark: writing format type %d, to %s", out_file_type, save_file);
-        if (strcmp(save_file, "-") == 0) {
-          /* Write to the standard output. */
-          pdh = wtap_dump_open_stdout_ng(out_file_type, linktype,
-              snapshot_length, FALSE /* compressed */, shb_hdrs, idb_inf, nrb_hdrs, &err);
-        } else {
-          pdh = wtap_dump_open_ng(save_file, out_file_type, linktype,
-              snapshot_length, FALSE /* compressed */, shb_hdrs, idb_inf, nrb_hdrs, &err);
-        }
+    tshark_debug("tshark: writing format type %d, to %s", out_file_type, save_file);
+    if (strcmp(save_file, "-") == 0) {
+      /* Write to the standard output. */
+      pdh = wtap_dump_open_stdout(out_file_type, WTAP_UNCOMPRESSED, &params,
+                                  &err);
+    } else {
+      pdh = wtap_dump_open(save_file, out_file_type, WTAP_UNCOMPRESSED, &params,
+                           &err);
     }
 
-    g_free(idb_inf);
-    idb_inf = NULL;
+    g_free(params.idb_inf);
+    params.idb_inf = NULL;
 
     if (pdh == NULL) {
       /* We couldn't set up to write to the capture file. */
@@ -3155,8 +3107,6 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type,
         goto out;
       }
     }
-    g_free(idb_inf);
-    idb_inf = NULL;
     pdh = NULL;
   }
 
@@ -3277,6 +3227,12 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type,
       edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
     }
 
+    /*
+     * Force synchronous resolution of IP addresses; in this pass, we
+     * can't do it in the background and fix up past dissections.
+     */
+    set_resolution_synchrony(TRUE);
+
     for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
       fdata = frame_data_sequence_find(cf->provider.frames, framenum);
       if (wtap_seek_read(cf->provider.wth, fdata->file_off, &rec, &buf, &err,
@@ -3300,8 +3256,7 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type,
                                           err, err_info, framenum,
                                           out_file_type);
               wtap_dump_close(pdh, &err);
-              wtap_block_array_free(shb_hdrs);
-              wtap_block_array_free(nrb_hdrs);
+              wtap_dump_params_cleanup(&params);
               exit(2);
             }
           }
@@ -3359,6 +3314,13 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type,
       edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
     }
 
+    /*
+     * Force synchronous resolution of IP addresses; we're doing only
+     * one pass, so we can't do it in the background and fix up past
+     * dissections.
+     */
+    set_resolution_synchrony(TRUE);
+
     while (wtap_read(cf->provider.wth, &err, &err_info, &data_offset)) {
       framenum++;
 
@@ -3379,8 +3341,7 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type,
             cfile_write_failure_message("TShark", cf->filename, save_file,
                                         err, err_info, framenum, out_file_type);
             wtap_dump_close(pdh, &err);
-            wtap_block_array_free(shb_hdrs);
-            wtap_block_array_free(nrb_hdrs);
+            wtap_dump_params_cleanup(&params);
             exit(2);
           }
         }
@@ -3469,8 +3430,7 @@ out:
   wtap_close(cf->provider.wth);
   cf->provider.wth = NULL;
 
-  wtap_block_array_free(shb_hdrs);
-  wtap_block_array_free(nrb_hdrs);
+  wtap_dump_params_cleanup(&params);
 
   return success;
 }
@@ -3500,11 +3460,6 @@ process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, gint64 offset,
      over the packets, so, if we'll be printing packet information
      or running taps, we'll be doing it here.) */
   if (edt) {
-    if (print_packet_info && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
-        gbl_resolv_flags.transport_name))
-      /* Grab any resolved addresses */
-      host_name_lookup_process();
-
     /* If we're running a filter, prime the epan_dissect_t with that
        filter. */
     if (cf->dfcode)
@@ -3537,7 +3492,7 @@ process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, gint64 offset,
 
     if (dissect_color) {
       color_filters_prime_edt(edt);
-      fdata.flags.need_colorize = 1;
+      fdata.need_colorize = 1;
     }
 
     epan_dissect_run_with_taps(edt, cf->cd_t, rec,
@@ -3607,11 +3562,11 @@ write_preamble(capture_file *cf)
 
   case WRITE_JSON:
   case WRITE_JSON_RAW:
-    write_json_preamble(stdout);
+    jdumper = write_json_preamble(stdout);
     return !ferror(stdout);
 
   case WRITE_EK:
-    return !ferror(stdout);
+    return TRUE;
 
   default:
     g_assert_not_reached();
@@ -3964,7 +3919,7 @@ print_packet(capture_file *cf, epan_dissect_t *edt)
     if (print_details) {
       write_json_proto_tree(output_fields, print_dissections_expanded,
                             print_hex, protocolfilter, protocolfilter_flags,
-                            edt, &cf->cinfo, node_children_grouper, stdout);
+                            edt, &cf->cinfo, node_children_grouper, &jdumper);
       return !ferror(stdout);
     }
     break;
@@ -3975,7 +3930,7 @@ print_packet(capture_file *cf, epan_dissect_t *edt)
     if (print_details) {
       write_json_proto_tree(output_fields, print_dissections_none, TRUE,
                             protocolfilter, protocolfilter_flags,
-                            edt, &cf->cinfo, node_children_grouper, stdout);
+                            edt, &cf->cinfo, node_children_grouper, &jdumper);
       return !ferror(stdout);
     }
     break;
@@ -4020,11 +3975,11 @@ write_finale(void)
 
   case WRITE_JSON:
   case WRITE_JSON_RAW:
-    write_json_finale(stdout);
+    write_json_finale(&jdumper);
     return !ferror(stdout);
 
   case WRITE_EK:
-    return !ferror(stdout);
+    return TRUE;
 
   default:
     g_assert_not_reached();
@@ -4050,10 +4005,6 @@ cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_temp
 
   /* The open succeeded.  Fill in the information for this file. */
 
-  /* Create new epan session for dissection. */
-  epan_free(cf->epan);
-  cf->epan = tshark_epan_new(cf);
-
   cf->provider.wth = wth;
   cf->f_datalen = 0; /* not used, but set it anyway */
 
@@ -4079,10 +4030,13 @@ cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_temp
   cf->provider.prev_dis = NULL;
   cf->provider.prev_cap = NULL;
 
-  cf->state = FILE_READ_IN_PROGRESS;
+  /* Create new epan session for dissection. */
+  epan_free(cf->epan);
+  cf->epan = tshark_epan_new(cf);
 
   wtap_set_cb_new_ipv4(cf->provider.wth, add_ipv4_name);
   wtap_set_cb_new_ipv6(cf->provider.wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
+  wtap_set_cb_new_secrets(cf->provider.wth, secrets_wtap_callback);
 
   return CF_OK;