Add summary-vs-detail radio buttons to the print dialog box; detail
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Sun, 12 Sep 1999 06:11:51 +0000 (06:11 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Sun, 12 Sep 1999 06:11:51 +0000 (06:11 +0000)
prints the protocol tree, and summary prints the fields in the summary
clist, with a header line at the beginning of the printout.

Print only packets selected by the current packet filter.

Just have "ARP" and "RARP" in the "Protocol" field for ARP packets;
whether it's a request or a reply can be seen in the "Info" field.

Add to the "Frame" section of the protocol tree the time between the
current packet and the previous displayed packet, and the packet number.
Have FT_RELATIVE_TIME fields be a "struct timeval", and display them as
seconds and fractional seconds (we didn't have any fields of that type,
and that type of time fits the delta time above).

Add an FT_DOUBLE field type (although we don't yet have anything using
it).

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@666 f5534014-38df-0310-8fa8-9805f1628bb7

14 files changed:
column.c
column.h
file.c
file.h
gtk/keys.h
gtk/main.c
gtk/print_dlg.c
packet-arp.c
packet.c
packet.h
print.c
print.h
proto.c
proto.h

index a654ed5dbdf665bf65169545635bf93f47c8e4ae..b7ea2d6da68bdf3dd28b85d8b6bbd4cc91ac8863 100644 (file)
--- a/column.c
+++ b/column.c
@@ -1,7 +1,7 @@
 /* column.c
  * Routines for handling column preferences
  *
- * $Id: column.c,v 1.23 1999/09/10 07:09:35 guy Exp $
+ * $Id: column.c,v 1.24 1999/09/12 06:11:34 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -168,35 +168,27 @@ get_column_format_matches(gboolean *fmt_list, gint format) {
   }
 }
 
-/* Returns the longest possible width for a particular column type.
-
-   Except for the COL...SRC and COL...DST columns, these are used
-   only when a capture is being displayed while it's taking place;
-   they are arguably somewhat fragile, as changes to the code that
-   generates them don't cause these widths to change, but that's
-   probably not too big a problem, given that the sizes are
-   recomputed based on the actual data in the columns when the capture
-   is done, and given that the width for COL...SRC and COL...DST columns
-   is somewhat arbitrary in any case.  We should probably clean
-   that up eventually, though. */
-gint
-get_column_width(gint format, GdkFont *font) {
+/* Returns a string representing the longest possible value for a
+   particular column type. */
+static char *
+get_column_longest_string(gint format)
+{
   switch (format) {
     case COL_NUMBER:
-      return (gdk_string_width(font, "0") * 7);
+      return "0000000";
       break;
     case COL_CLS_TIME:
       if (timestamp_type == ABSOLUTE)
-        return (gdk_string_width(font, "00:00:00.000000"));
+        return "00:00:00.000000";
       else
-        return (gdk_string_width(font, "0000.000000"));
+        return "0000.000000";
       break;
     case COL_ABS_TIME:
-      return (gdk_string_width(font, "00:00:00.000000"));
+      return "00:00:00.000000";
       break;
     case COL_REL_TIME:
     case COL_DELTA_TIME:
-      return (gdk_string_width(font, "0000.000000"));
+      return "0000.000000";
       break;
     case COL_DEF_SRC:
     case COL_RES_SRC:
@@ -216,7 +208,7 @@ get_column_width(gint format, GdkFont *font) {
     case COL_DEF_NET_DST:
     case COL_RES_NET_DST:
     case COL_UNRES_NET_DST:
-      return (gdk_string_width(font, "00000000.000000000000")); /* IPX-style */
+      return "00000000.000000000000"; /* IPX-style */
       break;
     case COL_DEF_SRC_PORT:
     case COL_RES_SRC_PORT:
@@ -224,21 +216,46 @@ get_column_width(gint format, GdkFont *font) {
     case COL_DEF_DST_PORT:
     case COL_RES_DST_PORT:
     case COL_UNRES_DST_PORT:
-      return (gdk_string_width(font, "0") * 6);
+      return "000000";
       break;
     case COL_PROTOCOL:
-      return (gdk_string_width(font, "NBNS (UDP)"));
+      return "NBNS (UDP)";
       break;
     case COL_PACKET_LENGTH:
-      return (gdk_string_width(font, "0") * 6);
+      return "000000";
       break;
     default: /* COL_INFO */
-      return (gdk_string_width(font, "Source port: kerberos-master  "
-        "Destination port: kerberos-master"));
+      return "Source port: kerberos-master  Destination port: kerberos-master";
       break;
   }
 }
 
+/* Returns the longest possible width, using the specified font,
+   for a particular column type.
+
+   Except for the COL...SRC and COL...DST columns, these are used
+   only when a capture is being displayed while it's taking place;
+   they are arguably somewhat fragile, as changes to the code that
+   generates them don't cause these widths to change, but that's
+   probably not too big a problem, given that the sizes are
+   recomputed based on the actual data in the columns when the capture
+   is done, and given that the width for COL...SRC and COL...DST columns
+   is somewhat arbitrary in any case.  We should probably clean
+   that up eventually, though. */
+gint
+get_column_width(gint format, GdkFont *font)
+{
+  return (gdk_string_width(font, get_column_longest_string(format)));
+}
+
+/* Returns the longest possible width, in characters, for a particular
+   column type. */
+gint
+get_column_char_width(gint format)
+{
+  return strlen(get_column_longest_string(format));
+}
+
 enum col_resize_type
 get_column_resize_type(gint format) {
   switch (format) {
index 21ddbd56edfc4724ed2f9047f143df2bb5121f44..da467447805ced42683a3251845c7aad0d7e3dd8 100644 (file)
--- a/column.h
+++ b/column.h
@@ -1,7 +1,7 @@
 /* column.h
  * Definitions for column handling routines
  *
- * $Id: column.h,v 1.5 1999/09/10 06:53:23 guy Exp $
+ * $Id: column.h,v 1.6 1999/09/12 06:11:34 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -43,6 +43,7 @@ gchar               *get_column_title(gint);
 gchar               *col_format_to_pref_str(void);
 void                 get_column_format_matches(gboolean *, gint);
 gint                 get_column_width(gint format, GdkFont *font);
+gint                 get_column_char_width(gint format);
 GtkWidget           *column_prefs_show(void);
 void                 column_prefs_ok(GtkWidget *);
 void                 column_prefs_save(GtkWidget *);
diff --git a/file.c b/file.c
index 7acc0362c74d99bdfde1bd98ebede9e6643afadf..cd5b86d77dd05e418ec902317b1e6cbc17f7d728 100644 (file)
--- a/file.c
+++ b/file.c
@@ -1,7 +1,7 @@
 /* file.c
  * File I/O routines
  *
- * $Id: file.c,v 1.89 1999/09/11 12:33:56 deniel Exp $
+ * $Id: file.c,v 1.90 1999/09/12 06:11:34 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -450,6 +450,26 @@ col_add_cls_time(frame_data *fd)
   }
 }
 
+static void
+fill_in_columns(frame_data *fd)
+{
+  if (check_col(fd, COL_NUMBER))
+    col_add_fstr(fd, COL_NUMBER, "%u", fd->num);
+
+  /* Set any time stamp columns. */
+  if (check_col(fd, COL_CLS_TIME))
+    col_add_cls_time(fd);
+  if (check_col(fd, COL_ABS_TIME))
+    col_add_abs_time(fd, COL_ABS_TIME);
+  if (check_col(fd, COL_REL_TIME))
+    col_add_rel_time(fd, COL_REL_TIME);
+  if (check_col(fd, COL_DELTA_TIME))
+    col_add_delta_time(fd, COL_DELTA_TIME);
+
+  if (check_col(fd, COL_PACKET_LENGTH))
+    col_add_fstr(fd, COL_PACKET_LENGTH, "%d", fd->pkt_len);
+}
+
 static void
 add_packet_to_packet_list(frame_data *fdata, capture_file *cf, const u_char *buf)
 {
@@ -458,6 +478,8 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf, const u_char *buf
   gint                 color;
   proto_tree   *protocol_tree;
 
+  fdata->num = cf->count;
+
   /* 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. */
@@ -508,9 +530,6 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf, const u_char *buf
        color = -1;
   }
   if (fdata->passed_dfilter) {
-    if (check_col(fdata, COL_NUMBER))
-      col_add_fstr(fdata, COL_NUMBER, "%d", cf->count);
-
     /* If we don't have the time stamp of the previous displayed packet,
        it's because this is the first displayed packet.  Save the time
        stamp of this packet as the time stamp of the previous displayed
@@ -536,39 +555,25 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf, const u_char *buf
     prevsec = fdata->abs_secs;
     prevusec = fdata->abs_usecs;
 
-    /* Set any time stamp columns. */
-    if (check_col(fdata, COL_CLS_TIME))
-      col_add_cls_time(fdata);
-    if (check_col(fdata, COL_ABS_TIME))
-      col_add_abs_time(fdata, COL_ABS_TIME);
-    if (check_col(fdata, COL_REL_TIME))
-      col_add_rel_time(fdata, COL_REL_TIME);
-    if (check_col(fdata, COL_DELTA_TIME))
-      col_add_delta_time(fdata, COL_DELTA_TIME);
-
-    if (check_col(fdata, COL_PACKET_LENGTH))
-      col_add_fstr(fdata, COL_PACKET_LENGTH, "%d", fdata->pkt_len);
+    fill_in_columns(fdata);
 
     row = gtk_clist_append(GTK_CLIST(packet_list), fdata->cinfo->col_data);
     fdata->row = row;
 
-        if (cf->colors->color_filters && (color != -1)){
-                gtk_clist_set_background(GTK_CLIST(packet_list), row,
+    if (cf->colors->color_filters && (color != -1)){
+        gtk_clist_set_background(GTK_CLIST(packet_list), row,
                    &(color_filter(cf,color)->bg_color));
-                gtk_clist_set_foreground(GTK_CLIST(packet_list), row,
+        gtk_clist_set_foreground(GTK_CLIST(packet_list), row,
                    &(color_filter(cf,color)->fg_color));
-       } else {
-                gtk_clist_set_background(GTK_CLIST(packet_list), row,
-                   &WHITE);
-                gtk_clist_set_foreground(GTK_CLIST(packet_list), row,
-                   &BLACK);
-
-       }
+    } else {
+        gtk_clist_set_background(GTK_CLIST(packet_list), row, &WHITE);
+        gtk_clist_set_foreground(GTK_CLIST(packet_list), row, &BLACK);
+    }
 
     /* If this was the selected packet, remember the row it's in, so
        we can re-select it.  ("selected_packet" is 0-origin, as it's
-       a GList index; "count", however, is 1-origin.) */
-    if (cf->selected_packet == cf->count - 1)
+       a GList index; "num", however, is 1-origin.) */
+    if (cf->selected_packet == fdata->num - 1)
       cf->selected_row = row;
   } else
     fdata->row = -1;   /* not in the display */
@@ -728,12 +733,16 @@ filter_packets(capture_file *cf)
 }
 
 int
-print_packets(capture_file *cf, int to_file, const char *dest)
+print_packets(capture_file *cf, print_args_t *print_args)
 {
+  int         i;
   frame_data *fd;
   proto_tree *protocol_tree;
+  gint       *col_widths = NULL;
+  gint        data_width;
+  gboolean    print_separator;
 
-  cf->print_fh = open_print_dest(to_file, dest);
+  cf->print_fh = open_print_dest(print_args->to_file, print_args->dest);
   if (cf->print_fh == NULL)
     return FALSE;      /* attempt to open destination failed */
 
@@ -746,30 +755,88 @@ print_packets(capture_file *cf, int to_file, const char *dest)
   print_preamble(cf->print_fh);
 #endif
 
+  if (print_args->print_summary) {
+    /* We're printing packet summaries.
+
+       Find the widths for each of the columns - maximum of the
+       width of the title and the width of the data - and print
+       the column titles. */
+    col_widths = (gint *) g_malloc(sizeof(gint) * cf->cinfo.num_cols);
+    for (i = 0; i < cf->cinfo.num_cols; i++) {
+      /* Don't pad the last column. */
+      if (i == cf->cinfo.num_cols - 1)
+        col_widths[i] = 0;
+      else {
+        col_widths[i] = strlen(cf->cinfo.col_title[i]);
+        data_width = get_column_char_width(get_column_format(i));
+        if (data_width > col_widths[i])
+          col_widths[i] = data_width;
+      }
+
+      /* Right-justify the packet number column. */
+      if (cf->cinfo.col_fmt[i] == COL_NUMBER)
+        fprintf(cf->print_fh, "%*s", col_widths[i], cf->cinfo.col_title[i]);
+      else
+        fprintf(cf->print_fh, "%-*s", col_widths[i], cf->cinfo.col_title[i]);
+      if (i == cf->cinfo.num_cols - 1)
+        fputc('\n', cf->print_fh);
+      else
+        fputc(' ', cf->print_fh);
+    }
+  }
+
+  print_separator = FALSE;
   proto_tree_is_visible = TRUE;
 
-  /* Iterate through the list of packets, printing each of them.  */
-  cf->count = 0;
+  /* Iterate through the list of packets, printing the packets that
+     were selected by the current display filter.  */
   for (fd = cf->plist; fd != NULL; fd = fd->next) {
-    cf->count++;
+    if (fd->passed_dfilter) {
+      wtap_seek_read (cf->cd_t, cf->fh, fd->file_off, cf->pd, fd->cap_len);
+      if (print_args->print_summary) {
+        /* Fill in the column information, but don't bother creating
+           the logical protocol tree. */
+        fd->cinfo = &cf->cinfo;
+        for (i = 0; i < fd->cinfo->num_cols; i++) {
+          fd->cinfo->col_data[i][0] = '\0';
+        }
+        dissect_packet(cf->pd, fd, NULL);
+        fill_in_columns(fd);
+        for (i = 0; i < cf->cinfo.num_cols; i++) {
+          /* Right-justify the packet number column. */
+          if (cf->cinfo.col_fmt[i] == COL_NUMBER)
+            fprintf(cf->print_fh, "%*s", col_widths[i], cf->cinfo.col_data[i]);
+          else
+            fprintf(cf->print_fh, "%-*s", col_widths[i], cf->cinfo.col_data[i]);
+          if (i == cf->cinfo.num_cols - 1)
+            fputc('\n', cf->print_fh);
+          else
+            fputc(' ', cf->print_fh);
+        }
+      } else {
+        if (print_separator)
+          fputc('\n', cf->print_fh);
 
-    wtap_seek_read (cf-> cd_t, cf->fh, fd->file_off, cf->pd, fd->cap_len);
+        /* Create the logical protocol tree. */
+        protocol_tree = proto_tree_create_root();
+        dissect_packet(cf->pd, fd, protocol_tree);
 
-    /* create the logical protocol tree */
-    protocol_tree = proto_tree_create_root();
-    dissect_packet(cf->pd, fd, protocol_tree);
+        /* Print the information in that tree. */
+        proto_tree_print(FALSE, (GNode *)protocol_tree, cf->pd, fd, cf->print_fh);
 
-    /* Print the packet */
-    proto_tree_print(cf->count, (GNode *)protocol_tree, cf->pd, fd, cf->print_fh);
+        proto_tree_free(protocol_tree);
 
-    proto_tree_free(protocol_tree);
+        /* Print a blank line if we print anything after this. */
+        print_separator = TRUE;
+      }
+    }
   }
 
 #if 0
   print_finale(cf->print_fh);
 #endif
 
-  close_print_dest(to_file, cf->print_fh);
+  close_print_dest(print_args->to_file, cf->print_fh);
   cf->print_fh = NULL;
   return TRUE;
 }
diff --git a/file.h b/file.h
index 5be11cfe5e55b489c147c280c4076c15445fa046..cb12384344f0038923296b552ee828d0db028b7d 100644 (file)
--- a/file.h
+++ b/file.h
@@ -1,7 +1,7 @@
 /* file.h
  * Definitions for file structures and routines
  *
- * $Id: file.h,v 1.42 1999/08/28 01:51:57 guy Exp $
+ * $Id: file.h,v 1.43 1999/09/12 06:11:35 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -99,7 +99,15 @@ int  read_cap_file(capture_file *);
 int  tail_cap_file(char *, capture_file *);
 /* size_t read_frame_header(capture_file *); */
 
-int print_packets(capture_file *cf, int to_file, const char *dest);
+typedef struct {
+  gboolean     to_file;        /* TRUE if we're printing to a file */
+  char         *dest;          /* if printing to file, pathname;
+                                  if not, command string */
+  gboolean     print_summary;  /* TRUE if we should just print summary;
+                                  FALSE if we should print protocol tree. */
+} print_args_t;
+
+int print_packets(capture_file *cf, print_args_t *print_args);
 void filter_packets(capture_file *);
 void change_time_formats(capture_file *);
 void select_packet(capture_file *, int);
index c28599b48bdfc4651d6a401fb89c7e06c8db4e5e..514e602856355fbc6e56e791b28b768248c93531 100644 (file)
@@ -1,7 +1,7 @@
 /* keys.h
  * Key definitions for various objects
  *
- * $Id: keys.h,v 1.2 1999/09/09 04:25:49 guy Exp $
+ * $Id: keys.h,v 1.3 1999/09/12 06:11:50 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
 
 /* Keys for gtk_object_set_data */
 
-#define E_DFILTER_TE_KEY "display_filter_te"
-#define E_RFILTER_TE_KEY "read_filter_te"
-
-#define PRINT_CMD_LB_KEY  "printer_command_label"
-#define PRINT_CMD_TE_KEY  "printer_command_entry"
-#define PRINT_FILE_BT_KEY "printer_file_button"
-#define PRINT_FILE_TE_KEY "printer_file_entry"
-#define PRINT_DEST_RB_KEY "printer_destination_radio_button"
+#define E_DFILTER_TE_KEY     "display_filter_te"
+#define E_RFILTER_TE_KEY     "read_filter_te"
 
+#define PRINT_CMD_LB_KEY     "printer_command_label"
+#define PRINT_CMD_TE_KEY     "printer_command_entry"
+#define PRINT_FILE_BT_KEY    "printer_file_button"
+#define PRINT_FILE_TE_KEY    "printer_file_entry"
+#define PRINT_DEST_RB_KEY    "printer_destination_radio_button"
+#define PRINT_SUMMARY_RB_KEY "printer_summary_radio_button"
 
 #endif
index 5ee848eedaf08f84ba62cb8d3c4fb18fc694f856..07af23a40d58e60f32bad04b501ca0817fcec3a6 100644 (file)
@@ -1,6 +1,6 @@
 /* main.c
  *
- * $Id: main.c,v 1.3 1999/09/11 12:36:14 deniel Exp $
+ * $Id: main.c,v 1.4 1999/09/12 06:11:50 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -501,7 +501,6 @@ main(int argc, char *argv[])
   dfilter             *rfcode = NULL;
   gboolean             rfilter_parse_failed = FALSE;
   e_prefs             *prefs;
-  gchar              **col_title;
 
   ethereal_path = argv[0];
 
@@ -553,8 +552,9 @@ main(int argc, char *argv[])
   cf.cinfo.num_cols    = prefs->num_cols;
   cf.cinfo.col_fmt      = (gint *) g_malloc(sizeof(gint) * cf.cinfo.num_cols);
   cf.cinfo.fmt_matx    = (gboolean **) g_malloc(sizeof(gboolean *) * cf.cinfo.num_cols);
-  cf.cinfo.col_data    = (gchar **) g_malloc(sizeof(gchar *) * cf.cinfo.num_cols);
   cf.cinfo.col_width   = (gint *) g_malloc(sizeof(gint) * cf.cinfo.num_cols);
+  cf.cinfo.col_title    = (gchar **) g_malloc(sizeof(gchar *) * cf.cinfo.num_cols);
+  cf.cinfo.col_data    = (gchar **) g_malloc(sizeof(gchar *) * cf.cinfo.num_cols);
 
   /* Assemble the compile-time options */
   snprintf(comp_info_str, 256,
@@ -695,11 +695,9 @@ main(int argc, char *argv[])
 #endif
 
   /* Build the column format array */  
-  col_title = (gchar **) g_malloc(sizeof(gchar *) * cf.cinfo.num_cols);
-  
   for (i = 0; i < cf.cinfo.num_cols; i++) {
     cf.cinfo.col_fmt[i] = get_column_format(i);
-    col_title[i] = g_strdup(get_column_title(i));
+    cf.cinfo.col_title[i] = g_strdup(get_column_title(i));
     cf.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
       NUM_COL_FMTS);
     get_column_format_matches(cf.cinfo.fmt_matx[i], cf.cinfo.col_fmt[i]);
@@ -761,7 +759,7 @@ main(int argc, char *argv[])
   gtk_widget_show(l_pane);
 
   /* Packet list */
-  packet_list = gtk_clist_new_with_titles(cf.cinfo.num_cols, col_title);
+  packet_list = gtk_clist_new_with_titles(cf.cinfo.num_cols, cf.cinfo.col_title);
   gtk_clist_column_titles_passive(GTK_CLIST(packet_list));
   packet_sw = gtk_scrolled_window_new(NULL, NULL);
   gtk_widget_show(packet_sw);
index 468410a6a1e1827b41a85a24744a0680780479e7..302653d94b5a45b4ddf9431828ad9f42062ac077 100644 (file)
@@ -1,7 +1,7 @@
 /* print_dlg.c
  * Dialog boxes for printing
  *
- * $Id: print_dlg.c,v 1.3 1999/09/09 04:25:49 guy Exp $
+ * $Id: print_dlg.c,v 1.4 1999/09/12 06:11:51 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -77,6 +77,8 @@ file_print_cmd_cb(GtkWidget *widget, gpointer data)
   GtkWidget     *cmd_lb, *cmd_te;
   GtkWidget     *file_bt_hb, *file_bt, *file_te;
   GSList        *dest_grp;
+  GtkWidget     *summary_rb, *detail_rb;
+  GSList        *summary_grp;
   GtkWidget     *bbox, *ok_bt, *cancel_bt;
 
   /* XXX - don't pop up one if there's already one open; instead,
@@ -188,6 +190,17 @@ file_print_cmd_cb(GtkWidget *widget, gpointer data)
   gtk_signal_connect(GTK_OBJECT(file_bt), "clicked",
                GTK_SIGNAL_FUNC(print_file_cb), GTK_OBJECT(file_te));
 
+  /* "Print summary"/"Print detail" radio buttons */
+  summary_rb = gtk_radio_button_new_with_label(NULL, "Print summary");
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(summary_rb), FALSE);
+  summary_grp = gtk_radio_button_group(GTK_RADIO_BUTTON(summary_rb));
+  gtk_container_add(GTK_CONTAINER(main_vb), summary_rb);
+  gtk_widget_show(summary_rb);
+  detail_rb = gtk_radio_button_new_with_label(summary_grp, "Print detail");
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(detail_rb), TRUE);
+  gtk_container_add(GTK_CONTAINER(main_vb), detail_rb);
+  gtk_widget_show(detail_rb);
+
   /* Button row: OK and Cancel buttons */
   bbox = gtk_hbutton_box_new();
   gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
@@ -199,6 +212,7 @@ file_print_cmd_cb(GtkWidget *widget, gpointer data)
   gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_DEST_RB_KEY, dest_rb);
   gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_CMD_TE_KEY, cmd_te);
   gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_FILE_TE_KEY, file_te);
+  gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_SUMMARY_RB_KEY, summary_rb);
   gtk_signal_connect(GTK_OBJECT(ok_bt), "clicked",
     GTK_SIGNAL_FUNC(print_ok_cb), GTK_OBJECT(print_w));
   GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
@@ -284,38 +298,40 @@ static void
 print_ok_cb(GtkWidget *ok_bt, gpointer parent_w)
 {
   GtkWidget *button;
-  char *dest;
+  print_args_t print_args;
 
   button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(ok_bt),
                                               PRINT_DEST_RB_KEY);
-  if (GTK_TOGGLE_BUTTON (button)->active)
-    print_to_file = TRUE;
-  else
-    print_to_file = FALSE;
+  print_to_file = GTK_TOGGLE_BUTTON (button)->active;
+  print_args.to_file = print_to_file;
 
-  if (print_to_file)
-    dest = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(ok_bt),
+  if (print_args.to_file)
+    print_args.dest = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(ok_bt),
       PRINT_FILE_TE_KEY))));
   else
-    dest = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(ok_bt),
+    print_args.dest = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(ok_bt),
       PRINT_CMD_TE_KEY))));
 
+  button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(ok_bt),
+                                              PRINT_SUMMARY_RB_KEY);
+  print_args.print_summary = GTK_TOGGLE_BUTTON (button)->active;
+
   gtk_widget_destroy(GTK_WIDGET(parent_w));
 #if 0
   display_opt_window_active = FALSE;
 #endif
 
   /* Now print the packets */
-  if (!print_packets(&cf, print_to_file, dest)) {
-    if (print_to_file)
+  if (!print_packets(&cf, &print_args)) {
+    if (print_args.to_file)
       simple_dialog(ESD_TYPE_WARN, NULL,
-        file_write_error_message(errno), dest);
+        file_write_error_message(errno), print_args.dest);
     else
       simple_dialog(ESD_TYPE_WARN, NULL, "Couldn't run print command %s.",
-        prefs.pr_cmd);
+        print_args.dest);
   }
 
-  g_free(dest);
+  g_free(print_args.dest);
 }
 
 static void
@@ -365,7 +381,7 @@ file_print_packet_cmd_cb(GtkWidget *widget, gpointer data) {
   }
 
   print_preamble(fh);
-  proto_tree_print(-1, (GNode*) cf.protocol_tree, cf.pd, cf.fd, fh);
+  proto_tree_print(TRUE, (GNode*) cf.protocol_tree, cf.pd, cf.fd, fh);
   print_finale(fh);
   close_print_dest(prefs.pr_dest == PR_DEST_FILE, fh);
 }
index f510db9a8f6e092ccb354cfdbd48ca99c44b5a15..c77d901dc17d3df550e8ce19d7bb5544ee01c476 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-arp.c
  * Routines for ARP packet disassembly
  *
- * $Id: packet-arp.c,v 1.16 1999/07/30 05:42:25 guy Exp $
+ * $Id: packet-arp.c,v 1.17 1999/09/12 06:11:35 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -188,10 +188,19 @@ dissect_arp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
   tpa_str = arpproaddr_to_str((guint8 *) &pd[tpa_offset], ar_pln, ar_pro);
   
   if (check_col(fd, COL_PROTOCOL)) {
-    if ((op_str = match_strval(ar_op, op_vals)))
-      col_add_str(fd, COL_PROTOCOL, op_str);
-    else
+    switch (ar_op) {
+
+    case ARPOP_REQUEST:
+    case ARPOP_REPLY:
+    default:
       col_add_str(fd, COL_PROTOCOL, "ARP");
+      break;
+
+    case ARPOP_RREQUEST:
+    case ARPOP_RREPLY:
+      col_add_str(fd, COL_PROTOCOL, "RARP");
+      break;
+    }
   }
 
   if (check_col(fd, COL_INFO)) {
index 7bc1fde6a1e2e25084a707d2d17b9cb93f53662c..8960eef206ffd49413bdcdcc2b833a04a47d0452 100644 (file)
--- a/packet.c
+++ b/packet.c
@@ -1,7 +1,7 @@
 /* packet.c
  * Routines for packet disassembly
  *
- * $Id: packet.c,v 1.41 1999/09/11 04:50:35 gerald Exp $
+ * $Id: packet.c,v 1.42 1999/09/12 06:11:36 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -62,6 +62,8 @@ extern capture_file  cf;
 
 int proto_frame = -1;
 int hf_frame_arrival_time = -1;
+int hf_frame_time_delta = -1;
+int hf_frame_number = -1;
 int hf_frame_packet_len = -1;
 int hf_frame_capture_len = -1;
 
@@ -266,6 +268,25 @@ abs_time_to_str(struct timeval *abs_time)
         return cur;
 }
 
+gchar *
+rel_time_to_str(struct timeval *rel_time)
+{
+        static gchar *cur;
+        static char str[3][10+1+6+1];
+
+        if (cur == &str[0][0]) {
+                cur = &str[1][0];
+        } else if (cur == &str[1][0]) {
+                cur = &str[2][0];
+        } else {
+                cur = &str[0][0];
+        }
+
+       sprintf(cur, "%ld.%06ld", (long)rel_time->tv_sec,
+               (long)rel_time->tv_usec);
+
+        return cur;
+}
 
 /*
  * Given a pointer into a data buffer, and to the end of the buffer,
@@ -638,6 +659,15 @@ dissect_packet(const u_char *pd, frame_data *fd, proto_tree *tree)
          proto_tree_add_item(fh_tree, hf_frame_arrival_time,
                0, 0, &tv);
 
+         tv.tv_sec = fd->del_secs;
+         tv.tv_usec = fd->del_usecs;
+
+         proto_tree_add_item(fh_tree, hf_frame_time_delta,
+               0, 0, &tv);
+
+         proto_tree_add_item(fh_tree, hf_frame_number,
+               0, 0, fd->num);
+
          proto_tree_add_item_format(fh_tree, hf_frame_packet_len,
                0, 0, fd->pkt_len, "Packet Length: %d byte%s", fd->pkt_len,
                plurality(fd->pkt_len, "", "s"));
@@ -697,6 +727,12 @@ proto_register_frame(void)
                { &hf_frame_arrival_time,
                { "Arrival Time",               "frame.time", FT_ABSOLUTE_TIME, NULL }},
 
+               { &hf_frame_time_delta,
+               { "Time delta from previous packet",    "frame.time_delta", FT_RELATIVE_TIME, NULL }},
+
+               { &hf_frame_number,
+               { "Frame Number",               "frame.number", FT_UINT32, NULL }},
+
                { &hf_frame_packet_len,
                { "Total Frame Length",         "frame.pkt_len", FT_UINT32, NULL }},
 
index 6e08f338a0c3e4285374b3588ceb0b2308ac2e6b..8c5ede4782b0b028de87e9cc93286ed111d66c81 100644 (file)
--- a/packet.h
+++ b/packet.h
@@ -1,7 +1,7 @@
 /* packet.h
  * Definitions for packet disassembly structures and routines
  *
- * $Id: packet.h,v 1.96 1999/09/11 04:19:25 gerald Exp $
+ * $Id: packet.h,v 1.97 1999/09/12 06:11:36 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -81,6 +81,7 @@ typedef struct _column_info {
   gint      *col_fmt;   /* Format of column */
   gboolean **fmt_matx;  /* Specifies which formats apply to a column */
   gint      *col_width; /* Column widths to use during a "-S" capture */
+  gchar    **col_title; /* Column titles */
   gchar    **col_data;  /* Column data */
 } column_info;
 
@@ -99,6 +100,7 @@ typedef struct _packet_counts {
 
 typedef struct _frame_data {
   struct _frame_data *next; /* Next element in list */
+  guint32      num;       /* Frame number */
   guint32      pkt_len;   /* Packet length */
   guint32      cap_len;   /* Amount actually captured */
   guint32      rel_secs;  /* Relative seconds */
@@ -334,6 +336,7 @@ enum {
 gchar*     ether_to_str(const guint8 *);
 gchar*     ip_to_str(const guint8 *);
 gchar*    abs_time_to_str(struct timeval*);
+gchar*    rel_time_to_str(struct timeval*);
 gchar*     time_secs_to_str(guint32);
 gchar*     bytes_to_str(const guint8 *, int);
 const u_char *find_line_end(const u_char *data, const u_char *dataend,
diff --git a/print.c b/print.c
index 809cecf3be5cd868117f48522dc12f7b65d95781..c8b7ff1e518711112c9270eeae6a8f905dd4b802 100644 (file)
--- a/print.c
+++ b/print.c
@@ -1,7 +1,7 @@
 /* print.c
  * Routines for printing packet analysis trees.
  *
- * $Id: print.c,v 1.18 1999/09/09 02:42:25 gram Exp $
+ * $Id: print.c,v 1.19 1999/09/12 06:11:37 guy Exp $
  *
  * Gilbert Ramirez <gram@verdict.uthscsa.edu>
  *
@@ -92,7 +92,7 @@ void print_finale(FILE *fh)
                print_ps_finale(fh);
 }
 
-void proto_tree_print(int frame_num, GNode *protocol_tree,
+void proto_tree_print(gboolean print_one, GNode *protocol_tree,
     const u_char *pd, frame_data *fd, FILE *fh)
 {
        print_data data;
@@ -107,22 +107,12 @@ void proto_tree_print(int frame_num, GNode *protocol_tree,
           and I'll have to spend some time learning enough about
           PostScript to figure it out, so, for now, we only print
           multiple frames as text. */
-       if (prefs.pr_format == PR_FMT_TEXT || frame_num != -1) {
-               if (frame_num != -1)
-                       fprintf(fh, "Frame %d:\n\n", frame_num);
+       if (prefs.pr_format == PR_FMT_TEXT || !print_one) {
                g_node_children_foreach((GNode*) protocol_tree, G_TRAVERSE_ALL,
                        proto_tree_print_node_text, &data);
-               if (frame_num != -1)
-                       fprintf(fh, "\n");
        } else {
-               if (frame_num != -1) {
-                       fprintf(fh, "0 (Frame %d:) putline\n", frame_num);
-                       fprintf(fh, "0 () putline\n");
-               }
                g_node_children_foreach((GNode*) protocol_tree, G_TRAVERSE_ALL,
                        proto_tree_print_node_ps, &data);
-               if (frame_num != -1)
-                       fprintf(fh, "0 () putline\n");
        }
 }
 
diff --git a/print.h b/print.h
index e5f302d257915d64ca4112b8ef4f9da143fa9b89..70d019371bbcca473b205a4f07dcc7a1748dbb4b 100644 (file)
--- a/print.h
+++ b/print.h
@@ -1,7 +1,7 @@
 /* print.h
  * Definitions for printing packet analysis trees.
  *
- * $Id: print.h,v 1.10 1999/09/01 03:04:12 gram Exp $
+ * $Id: print.h,v 1.11 1999/09/12 06:11:37 guy Exp $
  *
  * Gilbert Ramirez <gram@verdict.uthscsa.edu>
  *
@@ -34,7 +34,7 @@ FILE *open_print_dest(int to_file, const char *dest);
 void close_print_dest(int to_file, FILE *fh);
 void print_preamble(FILE *fh);
 void print_finale(FILE *fh);
-void proto_tree_print(int frame_num, GNode *protocol_tree,
+void proto_tree_print(gboolean print_one, GNode *protocol_tree,
     const u_char *pd, frame_data *fd, FILE *fh);
 
 #endif /* print.h */
diff --git a/proto.c b/proto.c
index 4e5e9672525d16eac859d312a3462490275fc40e..d57fa0b8c417ca293dea6ac090f606a9c9aaa945 100644 (file)
--- a/proto.c
+++ b/proto.c
@@ -1,7 +1,7 @@
 /* proto.c
  * Routines for protocol tree
  *
- * $Id: proto.c,v 1.23 1999/09/11 22:36:30 gerald Exp $
+ * $Id: proto.c,v 1.24 1999/09/12 06:11:37 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -412,18 +412,22 @@ NOTES
                case FT_UINT32:
                case FT_VALS_UINT24:
                case FT_VALS_UINT32:
-               case FT_RELATIVE_TIME:
                case FT_IPv4:
                case FT_IPXNET:
                        fi->value.numeric = va_arg(ap, unsigned int);
                        break;
 
+               case FT_DOUBLE:
+                       fi->value.floating = va_arg(ap, double);
+                       break;
+
                case FT_ETHER:
                        memcpy(fi->value.ether, va_arg(ap, guint8*), 6);
                        break;
 
                case FT_ABSOLUTE_TIME:
-                       memcpy(&fi->value.abs_time, va_arg(ap, struct timeval*),
+               case FT_RELATIVE_TIME:
+                       memcpy(&fi->value.time, va_arg(ap, struct timeval*),
                                sizeof(struct timeval));
                        break;
 
@@ -556,10 +560,22 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
                                fi->value.numeric);
                        break;
 
+               case FT_DOUBLE:
+                       snprintf(label_str, ITEM_LABEL_LENGTH,
+                               "%s: %g", fi->hfinfo->name,
+                               fi->value.floating);
+                       break;
+
                case FT_ABSOLUTE_TIME:
                        snprintf(label_str, ITEM_LABEL_LENGTH,
                                "%s: %s", fi->hfinfo->name,
-                               abs_time_to_str(&fi->value.abs_time));
+                               abs_time_to_str(&fi->value.time));
+                       break;
+
+               case FT_RELATIVE_TIME:
+                       snprintf(label_str, ITEM_LABEL_LENGTH,
+                               "%s: %s seconds", fi->hfinfo->name,
+                               rel_time_to_str(&fi->value.time));
                        break;
 
                case FT_VALS_UINT8:
@@ -823,6 +839,9 @@ proto_registrar_dump(void)
                        case FT_UINT32:
                                enum_name = "FT_UINT32";
                                break;
+                       case FT_DOUBLE:
+                               enum_name = "FT_DOUBLE";
+                               break;
                        case FT_ABSOLUTE_TIME:
                                enum_name = "FT_ABSOLUTE_TIME";
                                break;
diff --git a/proto.h b/proto.h
index a7ade0ad7d9992510b2384f7609dd1f7c008a0e6..21ebc146b8941f35ce70610afd17b7978d9ac343 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -1,7 +1,7 @@
 /* proto.h
  * Definitions for protocol display
  *
- * $Id: proto.h,v 1.9 1999/08/29 04:06:43 gram Exp $
+ * $Id: proto.h,v 1.10 1999/09/12 06:11:38 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -56,6 +56,7 @@ enum ftenum {
        FT_UINT8,
        FT_UINT16,
        FT_UINT32,
+       FT_DOUBLE,
        FT_ABSOLUTE_TIME,
        FT_RELATIVE_TIME,
        FT_STRING,
@@ -105,7 +106,8 @@ typedef struct field_info {
        union {
                gboolean        boolean;
                guint32         numeric;
-               struct timeval  abs_time; /* the whole struct, not a pointer */
+               struct timeval  time; /* the whole struct, not a pointer */
+               gdouble         floating;
                gchar           *string;
                guint8          ether[6];
        }                               value;