Update to V9.0.0 (2009-12)
[obnox/wireshark/wip.git] / rawshark.c
index cad73de744364640adf59b24c82a1de398e77d81..9b99b3a92b40686469b4a024a9f1e9f2c61caadb 100644 (file)
 #include "strerror.h"
 #endif
 
-#ifdef NEED_GETOPT_H
-#include "getopt.h"
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#else
+#include "wsgetopt.h"
 #endif
 
 #include <glib.h>
  */
 static const gchar decode_as_arg_template[] = "<layer_type>==<selector>,<decode_as_protocol>";
 
+static guint32 cum_bytes;
 static nstime_t first_ts;
 static nstime_t prev_dis_ts;
 static nstime_t prev_cap_ts;
-static GString *comp_info_str, *runtime_info_str;
 
 /*
  * The way the packet decode is to be written.
@@ -134,8 +136,8 @@ typedef enum {
        WRITE_XML       /* PDML or PSML */
        /* Add CSV and the like here */
 } output_action_e;
+
 static gboolean line_buffered;
-static guint32 cum_bytes = 0;
 static print_format_e print_format = PR_FMT_TEXT;
 
 /*
@@ -409,12 +411,25 @@ set_link_type(const char *lt_arg) {
   return FALSE;
 }
 
+static void
+show_version(GString *comp_info_str, GString *runtime_info_str)
+{
+  printf("Rawshark " VERSION "%s\n"
+         "\n"
+         "%s"
+         "\n"
+         "%s"
+         "\n"
+         "%s",
+         wireshark_svnversion, get_copyright_info(), comp_info_str->str,
+         runtime_info_str->str);
+}
+
 int
 main(int argc, char *argv[])
 {
   char                *init_progfile_dir_error;
   int                  opt, i;
-  extern char         *optarg;
   gboolean             arg_error = FALSE;
 
 #ifdef _WIN32
@@ -566,15 +581,7 @@ main(int argc, char *argv[])
   load_wpcap();
 #endif
 
-  init_cap_file(&cfile);
-
-  /* Assemble the compile-time version information string */
-  comp_info_str = g_string_new("Compiled ");
-  get_compiled_version_info(comp_info_str, get_epan_compiled_version_info);
-
-  /* Assemble the run-time version information string */
-  runtime_info_str = g_string_new("Running ");
-  get_runtime_version_info(runtime_info_str, NULL);
+  cap_file_init(&cfile);
 
   /* Print format defaults to this. */
   print_format = PR_FMT_TEXT;
@@ -688,18 +695,22 @@ main(int argc, char *argv[])
         }
         break;
       case 'v':        /* Show version and exit */
-        printf("Rawshark " VERSION "%s\n"
-               "\n"
-               "%s"
-               "\n"
-               "%s"
-               "\n"
-               "%s",
-               wireshark_svnversion, get_copyright_info(), comp_info_str->str,
-               runtime_info_str->str);
+      {
+        GString             *comp_info_str;
+        GString             *runtime_info_str;
+        /* Assemble the compile-time version information string */
+        comp_info_str = g_string_new("Compiled ");
+        get_compiled_version_info(comp_info_str, get_epan_compiled_version_info);
+
+        /* Assemble the run-time version information string */
+        runtime_info_str = g_string_new("Running ");
+        get_runtime_version_info(runtime_info_str, NULL);
+        show_version(comp_info_str, runtime_info_str);
+        g_string_free(comp_info_str, TRUE);
+        g_string_free(runtime_info_str, TRUE);
         exit(0);
         break;
-
+      }
       default:
       case '?':        /* Bad flag - print usage message */
         print_usage(TRUE);
@@ -766,35 +777,7 @@ main(int argc, char *argv[])
   }
 
   /* Build the column format array */
-  col_setup(&cfile.cinfo, prefs->num_cols);
-  for (i = 0; i < cfile.cinfo.num_cols; i++) {
-    cfile.cinfo.col_fmt[i] = get_column_format(i);
-    cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
-    cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
-      NUM_COL_FMTS);
-    get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
-    cfile.cinfo.col_data[i] = NULL;
-    if (cfile.cinfo.col_fmt[i] == COL_INFO)
-      cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
-    else
-      cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
-    cfile.cinfo.col_fence[i] = 0;
-    cfile.cinfo.col_expr.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
-    cfile.cinfo.col_expr.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
-  }
-
-  for (i = 0; i < cfile.cinfo.num_cols; i++) {
-      int j;
-
-      for (j = 0; j < NUM_COL_FMTS; j++) {
-         if (!cfile.cinfo.fmt_matx[i][j])
-             continue;
-
-         if (cfile.cinfo.col_first[j] == -1)
-             cfile.cinfo.col_first[j] = i;
-         cfile.cinfo.col_last[j] = i;
-      }
-  }
+  build_column_format_array(&cfile.cinfo, prefs->num_cols, TRUE);
 
   if (n_rfilters != 0) {
     for (i = 0; i < n_rfilters; i++) {
@@ -920,7 +903,6 @@ raw_pipe_read(struct wtap_pkthdr *phdr, guchar * pd, int *err, gchar **err_info,
     ptr += bytes_read;
   }
 
-  bytes_read = 0;
   phdr->ts.secs = hdr.ts_sec;
   phdr->ts.nsecs = hdr.ts_usec * 1000;
   phdr->caplen = bytes_needed = hdr.incl_len;
@@ -1006,87 +988,13 @@ load_cap_file(capture_file *cf)
   return err;
 }
 
-static void
-fill_in_fdata(frame_data *fdata, capture_file *cf,
-              const struct wtap_pkthdr *phdr, gint64 offset)
-{
-  fdata->next = NULL;
-  fdata->prev = NULL;
-  fdata->pfd = NULL;
-  fdata->num = cf->count;
-  fdata->pkt_len = phdr->len;
-  cum_bytes += phdr->len;
-  fdata->cum_bytes  = cum_bytes;
-  fdata->cap_len = phdr->caplen;
-  fdata->file_off = offset;
-  fdata->lnk_t = phdr->pkt_encap;
-  fdata->abs_ts.secs = phdr->ts.secs;
-  fdata->abs_ts.nsecs = phdr->ts.nsecs;
-  fdata->flags.passed_dfilter = 0;
-  fdata->flags.encoding = CHAR_ASCII;
-  fdata->flags.visited = 0;
-  fdata->flags.marked = 0;
-  fdata->flags.ref_time = 0;
-  fdata->color_filter = NULL;
-
-  /* If we don't have the time stamp of the first packet in the
-     capture, it's because this is the first packet.  Save the time
-     stamp of this packet as the time stamp of the first packet. */
-  if (nstime_is_unset(&first_ts)) {
-    first_ts = fdata->abs_ts;
-  }
-
-  /* If we don't have the time stamp of the previous captured packet,
-     it's because this is the first packet.  Save the time
-     stamp of this packet as the time stamp of the previous captured
-     packet. */
-  if (nstime_is_unset(&prev_cap_ts)) {
-    prev_cap_ts = fdata->abs_ts;
-  }
-
-  /* Get the time elapsed between the first packet and this packet. */
-  nstime_delta(&fdata->rel_ts, &fdata->abs_ts, &first_ts);
-
-  /* If it's greater than the current elapsed time, set the elapsed time
-     to it (we check for "greater than" so as not to be confused by
-     time moving backwards). */
-  if ((gint32)cf->elapsed_time.secs < fdata->rel_ts.secs
-       || ((gint32)cf->elapsed_time.secs == fdata->rel_ts.secs && (gint32)cf->elapsed_time.nsecs < fdata->rel_ts.nsecs)) {
-    cf->elapsed_time = fdata->rel_ts;
-  }
-
-  /* If we don't have the time stamp of the previous displayed packet,
-     it's because this is the first packet that's being displayed.  Save the time
-     stamp of this packet as the time stamp of the previous displayed
-     packet. */
-  if (nstime_is_unset(&prev_dis_ts))
-    prev_dis_ts = fdata->abs_ts;
-
-  /* Get the time elapsed between the previous displayed packet and
-     this packet. */
-  nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
-
-  /* Get the time elapsed between the previous captured packet and
-     this packet. */
-  nstime_delta(&fdata->del_cap_ts, &fdata->abs_ts, &prev_cap_ts);
-  prev_cap_ts = fdata->abs_ts;
-}
-
-/* Free up all data attached to a "frame_data" structure. */
-static void
-clear_fdata(frame_data *fdata)
-{
-  if (fdata->pfd)
-    g_slist_free(fdata->pfd);
-}
-
 static gboolean
 process_packet(capture_file *cf, gint64 offset, const struct wtap_pkthdr *whdr,
                const guchar *pd)
 {
   frame_data fdata;
   gboolean create_proto_tree;
-  epan_dissect_t *edt;
+  epan_dissect_t edt;
   gboolean passed;
   union wtap_pseudo_header pseudo_header;
   int i;
@@ -1113,7 +1021,7 @@ process_packet(capture_file *cf, gint64 offset, const struct wtap_pkthdr *whdr,
   /* If we're going to print packet information, or we're going to
      run a read filter, or we're going to process taps, set up to
      do a dissection and do so. */
-  fill_in_fdata(&fdata, cf, whdr, offset);
+  frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes);
 
   passed = TRUE;
   create_proto_tree = TRUE;
@@ -1121,31 +1029,36 @@ process_packet(capture_file *cf, gint64 offset, const struct wtap_pkthdr *whdr,
   /* The protocol tree will be "visible", i.e., printed, only if we're
      printing packet details, which is true if we're in verbose mode ("verbose"
      is true). */
-  edt = epan_dissect_new(create_proto_tree, FALSE);
+  epan_dissect_init(&edt, create_proto_tree, FALSE);
 
   /* If we're running a read filter, prime the epan_dissect_t with that
      filter. */
   if (n_rfilters > 0) {
     for(i = 0; i < n_rfcodes; i++) {
-      epan_dissect_prime_dfilter(edt, rfcodes[i]);
+      epan_dissect_prime_dfilter(&edt, rfcodes[i]);
     }
   }
 
-  tap_queue_init(edt);
+  tap_queue_init(&edt);
+
+  printf("%lu", (unsigned long int) cf->count);
 
-  printf("%lu", (unsigned long int)cf->count);
+  frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
+                                &first_ts, &prev_dis_ts, &prev_cap_ts);
 
   /* We only need the columns if we're printing packet info but we're
      *not* verbose; in verbose mode, we print the protocol tree, not
      the protocol summary. */
-  epan_dissect_run(edt, &pseudo_header, pd, &fdata, &cf->cinfo);
+  epan_dissect_run(&edt, &pseudo_header, pd, &fdata, &cf->cinfo);
 
-  tap_push_tapped_queue(edt);
+  tap_push_tapped_queue(&edt);
+
+  frame_data_set_after_dissect(&fdata, &cum_bytes, &prev_dis_ts);
 
   for(i = 0; i < n_rfilters; i++) {
     /* Run the read filter if we have one. */
     if (rfcodes[i])
-      passed = dfilter_apply_edt(rfcodes[i], edt);
+      passed = dfilter_apply_edt(rfcodes[i], &edt);
     else
       passed = TRUE;
 
@@ -1183,8 +1096,8 @@ process_packet(capture_file *cf, gint64 offset, const struct wtap_pkthdr *whdr,
     exit(2);
   }
 
-  epan_dissect_free(edt);
-  clear_fdata(&fdata);
+  epan_dissect_cleanup(&edt);
+  frame_data_cleanup(&fdata);
 
   return passed;
 }
@@ -1276,7 +1189,19 @@ char* ftenum_to_string(header_field_info *hfi)
        };
 }
 
-char* base_display_e_to_string(base_display_e bd)
+static char* absolute_time_display_e_to_string(absolute_time_display_e atd)
+{
+       switch(atd) {
+       case ABSOLUTE_TIME_LOCAL:
+                       return "ABSOLUTE_TIME_LOCAL";
+       case ABSOLUTE_TIME_UTC:
+                       return "ABSOLUTE_TIME_UTC";
+       default:
+                       return "n.a.";
+       }
+}
+
+static char* base_display_e_to_string(base_display_e bd)
 {
        switch(bd) {
        case BASE_NONE:
@@ -1460,10 +1385,23 @@ protocolinfo_init(char *field)
                exit(1);
        }
 
-       printf("%u %s %s - ",
-               g_cmd_line_index,
-               ftenum_to_string(hfi),
-               base_display_e_to_string(hfi->display));
+       switch (hfi->type) {
+
+       case FT_ABSOLUTE_TIME:
+               printf("%u %s %s - ",
+                       g_cmd_line_index,
+                       ftenum_to_string(hfi),
+                       absolute_time_display_e_to_string(hfi->display));
+               break;
+               break;
+
+       default:
+               printf("%u %s %s - ",
+                       g_cmd_line_index,
+                       ftenum_to_string(hfi),
+                       base_display_e_to_string(hfi->display));
+               break;
+       }
 
        rs=g_malloc(sizeof(pci_t));
        rs->hf_index=hfi->id;
@@ -1599,6 +1537,8 @@ raw_cf_open(capture_file *cf, const char *fname)
 
   /* 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();