Get rid of a Clist and move the functon to display floats with two decimals to gui_utils.
[metze/wireshark/wip.git] / proto_hier_stats.c
index 8974e52ac1ca59275887c73ef4d6398a3f0d7be8..40651fc6aeea556cd753110aac39d7c4a773c263 100644 (file)
@@ -3,8 +3,8 @@
  *
  * $Id$
  *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
  * This program is free software; you can redistribute it and/or
@@ -34,6 +34,7 @@
 #include <wtap.h>
 
 #include <stdio.h>
+#include <string.h>
 #include <glib.h>
 
 /* Update the progress bar this many times when scanning the packet list. */
 #define STAT_NODE_STATS(n)   ((ph_stats_node_t*)(n)->data)
 #define STAT_NODE_HFINFO(n)  (STAT_NODE_STATS(n)->hfinfo)
 
-static double
-secs_usecs(guint32 s, guint32 us)
-{
-  return (us / 1000000.0) + (double)s;
-}
 
 static GNode*
 find_stat_node(GNode *parent_stat_node, header_field_info *needle_hfinfo)
@@ -92,21 +88,33 @@ process_node(proto_node *ptree_node, GNode *parent_stat_node, ph_stats_t *ps, gu
        finfo = PITEM_FINFO(ptree_node);
        g_assert(finfo);
 
-       stat_node = find_stat_node(parent_stat_node, finfo->hfinfo);
-
-       /* Assert that the finfo is related to a protocol, not a field. */
-       g_assert(finfo->hfinfo->parent == -1);
-
-       stats = STAT_NODE_STATS(stat_node);
-       stats->num_pkts_total++;
-       stats->num_bytes_total += pkt_len;
+       /* If the field info isn't related to a protocol but to a field,
+        * don't count them, as they don't belong to any protocol.
+        * (happens e.g. for toplevel tree item of desegmentation "[Reassembled TCP Segments]") */
+       if (finfo->hfinfo->parent != -1) {
+               /* Skip this element, use parent status node */
+               stat_node = parent_stat_node;
+               stats = STAT_NODE_STATS(stat_node);
+       } else {
+               stat_node = find_stat_node(parent_stat_node, finfo->hfinfo);
+
+               stats = STAT_NODE_STATS(stat_node);
+               stats->num_pkts_total++;
+               stats->num_bytes_total += pkt_len;
+       }
 
        proto_sibling_node = ptree_node->next;
 
        if (proto_sibling_node) {
+               /* If the name does not exist for this proto_sibling_node, then it is
+                * not a normal protocol in the top-level tree.  It was instead
+                * added as a normal tree such as IPv6's Hop-by-hop Option Header and
+                * should be skipped when creating the protocol hierarchy display. */
+               if(strlen(proto_sibling_node->finfo->hfinfo->name) == 0 && ptree_node->next)
+                       proto_sibling_node = proto_sibling_node->next;
+
                process_node(proto_sibling_node, stat_node, ps, pkt_len);
-       }
-       else {
+       } else {
                stats->num_pkts_last++;
                stats->num_bytes_last += pkt_len;
        }
@@ -145,7 +153,7 @@ process_frame(frame_data *frame, column_info *cinfo, ph_stats_t* ps)
                return FALSE;   /* failure */
        }
 
-       /* Dissect the frame */
+       /* Dissect the frame   tree  not visible */
        edt = epan_dissect_new(TRUE, FALSE);
        epan_dissect_run(edt, &phdr, pd, frame, cinfo);
 
@@ -153,7 +161,7 @@ process_frame(frame_data *frame, column_info *cinfo, ph_stats_t* ps)
        process_tree(edt->tree, ps, frame->pkt_len);
 
        /* Update times */
-       cur_time = secs_usecs(frame->abs_secs, frame->abs_usecs);
+       cur_time = nstime_to_sec(&frame->abs_ts);
        if (cur_time < ps->first_time) {
          ps->first_time = cur_time;
        }
@@ -176,7 +184,7 @@ ph_stats_new(void)
        progdlg_t       *progbar = NULL;
        gboolean        stop_flag;
        int             count;
-       float           prog_val;
+       float           progbar_val;
        GTimeVal        start_time;
        gchar           status_str[100];
        int             progbar_nextstep;
@@ -197,6 +205,8 @@ ph_stats_new(void)
        progbar_quantum = cfile.count/N_PROGBAR_UPDATES;
        /* Count of packets at which we've looked. */
        count = 0;
+       /* Progress so far. */
+       progbar_val = 0.0;
 
        stop_flag = FALSE;
        g_get_current_time(&start_time);
@@ -205,6 +215,17 @@ ph_stats_new(void)
        tot_bytes = 0;
 
        for (frame = cfile.plist; frame != NULL; frame = frame->next) {
+               /* Create the progress bar if necessary.
+                  We check on every iteration of the loop, so that
+                  it takes no longer than the standard time to create
+                  it (otherwise, for a large file, we might take
+                  considerably longer than that standard time in order
+                  to get to the next progress bar step). */
+               if (progbar == NULL)
+                       progbar = delayed_create_progress_dlg(
+                           "Computing", "protocol hierarchy statistics", 
+                           TRUE, &stop_flag, &start_time, progbar_val);
+
                /* Update the progress bar, but do it only N_PROGBAR_UPDATES
                   times; when we update it, we have to run the GTK+ main
                   loop to get it to repaint what's pending, and doing so
@@ -217,18 +238,12 @@ ph_stats_new(void)
                         */
                        g_assert(cfile.count > 0);
 
-                       prog_val = (gfloat) count / cfile.count;
-
-                       if (progbar == NULL)
-                               /* Create the progress bar if necessary */
-                               progbar = delayed_create_progress_dlg(
-                                   "Computing", "protocol hierarchy statistics", 
-                                   &stop_flag, &start_time, prog_val);
+                       progbar_val = (gfloat) count / cfile.count;
 
                        if (progbar != NULL) {
                                g_snprintf(status_str, sizeof(status_str),
                                        "%4u of %u frames", count, cfile.count);
-                               update_progress_dlg(progbar, prog_val, status_str);
+                               update_progress_dlg(progbar, progbar_val, status_str);
                        }
 
                        progbar_nextstep += progbar_quantum;
@@ -248,13 +263,13 @@ ph_stats_new(void)
                if (frame->flags.passed_dfilter) {
 
                        if (tot_packets == 0) {
-                               double cur_time = secs_usecs(frame->abs_secs,
-                                                            frame->abs_usecs);
+                               double cur_time = nstime_to_sec(&frame->abs_ts);
                                ps->first_time = cur_time;
                                ps->last_time = cur_time;
                        }
-
-                       if (!process_frame(frame, &cfile.cinfo, ps)) {
+                       
+                       /* we don't care about colinfo */
+                       if (!process_frame(frame, NULL, ps)) {
                                /*
                                 * Give up, and set "stop_flag" so we
                                 * just abort rather than popping up