Some work on multi file dissection
[jelmer/wireshark.git] / tshark.c
index a852b8355cd98a6849df228aac5ebad23e2669ee..a9cff874852407d73f11c09d64ca162bfa8dc19e 100644 (file)
--- a/tshark.c
+++ b/tshark.c
 #include <epan/timestamp.h>
 #include <epan/packet.h>
 #include "file.h"
-#include "disabled_protos.h"
+#include "frame_tvbuff.h"
+#include <epan/disabled_protos.h>
 #include <epan/prefs.h>
 #include <epan/column.h>
-#include "print.h"
+#include <epan/print.h>
 #include <epan/addr_resolv.h>
 #include "ui/util.h"
 #include "clopts_common.h"
@@ -320,7 +321,7 @@ print_usage(gboolean print_ver)
   fprintf(output, "     aggregator=,|/s|<char> select comma, space, printable character as\n");
   fprintf(output, "                           aggregator\n");
   fprintf(output, "     quote=d|s|n           select double, single, no quotes for values\n");
-  fprintf(output, "  -t ad|a|r|d|dd|e         output format of time stamps (def: r: rel. to first)\n");
+  fprintf(output, "  -t a|ad|d|dd|e|r|u|ud    output format of time stamps (def: r: rel. to first)\n");
   fprintf(output, "  -u s|hms                 output format of seconds (def: s: seconds)\n");
   fprintf(output, "  -l                       flush standard output after each packet\n");
   fprintf(output, "  -q                       be more quiet on stdout (e.g. when using statistics)\n");
@@ -1245,7 +1246,7 @@ main(int argc, char *argv[])
 #endif
     case 'D':        /* Print a list of capture devices and exit */
 #ifdef HAVE_LIBPCAP
-      if_list = capture_interface_list(&err, &err_str);
+      if_list = capture_interface_list(&err, &err_str,NULL);
       if (if_list == NULL) {
         switch (err) {
         case CANT_GET_INTERFACE_LIST:
@@ -1405,8 +1406,9 @@ main(int argc, char *argv[])
       else {
         cmdarg_err("Invalid time stamp type \"%s\"",
                    optarg);
-        cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
-        cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
+        cmdarg_err_cont("It must be \"a\" for absolute, \"ad\" for absolute with date, \"d\" for delta,");
+        cmdarg_err_cont("\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative, \"u\" for UTC, ");
+        cmdarg_err_cont("or \"ud\" for UTC with date.");
         return 1;
       }
       break;
@@ -1959,7 +1961,7 @@ main(int argc, char *argv[])
           if_capabilities_t *caps;
 
           interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
-          caps = capture_get_if_capabilities(interface_opts.name, interface_opts.monitor_mode, &err_str);
+          caps = capture_get_if_capabilities(interface_opts.name, interface_opts.monitor_mode, &err_str, NULL);
           if (caps == NULL) {
             cmdarg_err("%s", err_str);
             g_free(err_str);
@@ -2194,10 +2196,9 @@ capture(void)
   relinquish_special_privs_perm();
   print_current_user();
 
-  /* Cleanup all data structures used for dissection. */
-  cleanup_dissection();
-  /* Initialize all data structures used for dissection. */
-  init_dissection();
+  /* Create new dissection section. */
+  epan_free(cfile.epan);
+  cfile.epan = epan_new();
 
 #ifdef _WIN32
   /* Catch a CTRL+C event and, if we get it, clean up and exit. */
@@ -2274,7 +2275,7 @@ capture(void)
   fflush(stderr);
   g_string_free(str, TRUE);
 
-  ret = sync_pipe_start(&global_capture_opts, &global_capture_session);
+  ret = sync_pipe_start(&global_capture_opts, &global_capture_session, NULL);
 
   if (!ret)
     return FALSE;
@@ -2341,13 +2342,6 @@ capture(void)
   return TRUE;
 }
 
-
-/* XXX - move the call to main_window_update() out of capture_sync.c */
-/* dummy for capture_sync.c to make linker happy */
-void main_window_update(void)
-{
-}
-
 /* capture child detected an error */
 void
 capture_input_error_message(capture_session *cap_session _U_, char *error_msg, char *secondary_error_msg)
@@ -2692,7 +2686,7 @@ process_packet_first_pass(capture_file *cf,
 
     /* We're not going to display the protocol tree on this pass,
        so it's not going to be "visible". */
-    epan_dissect_init(&edt, create_proto_tree, FALSE);
+    epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
 
     /* If we're running a read filter, prime the epan_dissect_t with that
        filter. */
@@ -2702,7 +2696,7 @@ process_packet_first_pass(capture_file *cf,
     frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
                                   &first_ts, prev_dis, prev_cap);
 
-    epan_dissect_run(&edt, whdr, pd, &fdlocal, NULL);
+    epan_dissect_run(&edt, whdr, frame_tvbuff_new(&fdlocal, pd), &fdlocal, NULL);
 
     /* Run the read filter if we have one. */
     if (cf->rfcode)
@@ -2726,11 +2720,6 @@ process_packet_first_pass(capture_file *cf,
     /* if we don't add it to the frame_data_sequence, clean it up right now
      * to avoid leaks */
     frame_data_destroy(&fdlocal);
-    /* TODO, bug #8160 */
-    /*
-    prev_cap_frame = fdlocal;
-    prev_cap = &prev_cap_frame;
-     */
   }
 
   if (do_dissection)
@@ -2741,7 +2730,7 @@ process_packet_first_pass(capture_file *cf,
 
 static gboolean
 process_packet_second_pass(capture_file *cf, frame_data *fdata,
-               struct wtap_pkthdr *phdr, const guchar *pd,
+               struct wtap_pkthdr *phdr, Buffer *buf,
                gboolean filtering_tap_listeners, guint tap_flags)
 {
   gboolean        create_proto_tree;
@@ -2773,7 +2762,7 @@ process_packet_second_pass(capture_file *cf, frame_data *fdata,
        printing packet details, which is true if we're printing stuff
        ("print_packet_info" is true) and we're in verbose mode
        ("packet_details" is true). */
-    epan_dissect_init(&edt, create_proto_tree, print_packet_info && print_details);
+    epan_dissect_init(&edt, cf->epan, create_proto_tree, print_packet_info && print_details);
 
     /* If we're running a display filter, prime the epan_dissect_t with that
        filter. */
@@ -2793,7 +2782,10 @@ process_packet_second_pass(capture_file *cf, frame_data *fdata,
     else
       cinfo = NULL;
 
-    epan_dissect_run_with_taps(&edt, phdr, pd, fdata, cinfo);
+    frame_data_set_before_dissect(fdata, &cf->elapsed_time,
+                                  &first_ts, prev_dis, prev_cap);
+
+    epan_dissect_run_with_taps(&edt, phdr, frame_tvbuff_new_buffer(fdata, buf), fdata, cinfo);
 
     /* Run the read/display filter if we have one. */
     if (cf->dfcode)
@@ -2801,6 +2793,7 @@ process_packet_second_pass(capture_file *cf, frame_data *fdata,
   }
 
   if (passed) {
+    frame_data_set_after_dissect(fdata, &cum_bytes);
     /* Process this packet. */
     if (print_packet_info) {
       /* We're printing packet information; print the information for
@@ -2838,7 +2831,9 @@ process_packet_second_pass(capture_file *cf, frame_data *fdata,
         exit(2);
       }
     }
+    prev_dis = fdata;
   }
+  prev_cap = fdata;
 
   if (do_dissection) {
     epan_dissect_cleanup(&edt);
@@ -2863,11 +2858,12 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
   wtapng_section_t            *shb_hdr;
   wtapng_iface_descriptions_t *idb_inf;
   char         appname[100];
+  Buffer       buf;
 
   shb_hdr = wtap_file_get_shb_info(cf->wth);
   idb_inf = wtap_file_get_idb_info(cf->wth);
 #ifdef PCAP_NG_DEFAULT
-  if (idb_inf->number_of_interfaces > 0) {
+  if (idb_inf->number_of_interfaces > 1) {
     linktype = WTAP_ENCAP_PER_PACKET;
   } else {
     linktype = wtap_file_encap(cf->wth);
@@ -2891,8 +2887,12 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
         shb_hdr->shb_user_appl = appname;
     }
 
-    pdh = wtap_dump_open_ng(save_file, out_file_type, linktype, snapshot_length,
-        FALSE /* compressed */, shb_hdr, idb_inf, &err);
+    if (linktype != WTAP_ENCAP_PER_PACKET && out_file_type == WTAP_FILE_PCAP)
+        pdh = wtap_dump_open(save_file, out_file_type, linktype,
+            snapshot_length, FALSE /* compressed */, &err);
+    else
+        pdh = wtap_dump_open_ng(save_file, out_file_type, linktype,
+            snapshot_length, FALSE /* compressed */, shb_hdr, idb_inf, &err);
 
     g_free(idb_inf);
     idb_inf = NULL;
@@ -2983,18 +2983,20 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
 
     max_packet_count = old_max_packet_count;
 
+    prev_dis = NULL;
+    prev_cap = NULL;
+    buffer_init(&buf, 1500);
     for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
       fdata = frame_data_sequence_find(cf->frames, framenum);
       if (wtap_seek_read(cf->wth, fdata->file_off, &cf->phdr,
-          cf->pd, fdata->cap_len, &err, &err_info)) {
-        if (process_packet_second_pass(cf, fdata,
-                           &cf->phdr, cf->pd,
-                           filtering_tap_listeners, tap_flags)) {
+          &buf, fdata->cap_len, &err, &err_info)) {
+        if (process_packet_second_pass(cf, fdata, &cf->phdr, &buf,
+                                       filtering_tap_listeners, tap_flags)) {
           /* Either there's no read filtering or this packet passed the
              filter, so, if we're writing to a capture file, write
              this packet out. */
           if (pdh != NULL) {
-            if (!wtap_dump(pdh, &cf->phdr, cf->pd, &err)) {
+            if (!wtap_dump(pdh, &cf->phdr, buffer_start_ptr(&cf->buf), &err)) {
               /* Error writing to a capture file */
               switch (err) {
 
@@ -3033,6 +3035,7 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
         }
       }
     }
+    buffer_free(&buf);
   }
   else {
     framenum = 0;
@@ -3218,7 +3221,7 @@ process_packet(capture_file *cf, gint64 offset, struct wtap_pkthdr *whdr,
        printing packet details, which is true if we're printing stuff
        ("print_packet_info" is true) and we're in verbose mode
        ("packet_details" is true). */
-    epan_dissect_init(&edt, create_proto_tree, print_packet_info && print_details);
+    epan_dissect_init(&edt, cf->epan, create_proto_tree, print_packet_info && print_details);
 
     /* If we're running a filter, prime the epan_dissect_t with that
        filter. */
@@ -3244,7 +3247,7 @@ process_packet(capture_file *cf, gint64 offset, struct wtap_pkthdr *whdr,
     frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
                                   &first_ts, prev_dis, prev_cap);
 
-    epan_dissect_run_with_taps(&edt, whdr, pd, &fdata, cinfo);
+    epan_dissect_run_with_taps(&edt, whdr, frame_tvbuff_new(&fdata, pd), &fdata, cinfo);
 
     /* Run the filters if we have them. */
     if (cf->rfcode)
@@ -3315,7 +3318,7 @@ write_preamble(capture_file *cf)
   switch (output_action) {
 
   case WRITE_TEXT:
-    return print_preamble(print_stream, cf ? cf->filename : NULL);
+    return print_preamble(print_stream, cf ? cf->filename : NULL, wireshark_svnversion);
 
   case WRITE_XML:
     if (print_details)
@@ -3702,10 +3705,9 @@ cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
 
   /* The open succeeded.  Fill in the information for this file. */
 
-  /* Cleanup all data structures used for dissection. */
-  cleanup_dissection();
-  /* Initialize all data structures used for dissection. */
-  init_dissection();
+  /* Create new epan session for dissection. */
+  epan_free(cf->epan);
+  cf->epan = epan_new();
 
   cf->wth = wth;
   cf->f_datalen = 0; /* not used, but set it anyway */