2 * Routines for calculating statistics based on protocol.
4 * $Id: proto_hier_stats.c,v 1.2 2001/03/23 21:55:36 guy Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@zing.org>
8 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #include "proto_hier_stats.h"
39 find_stat_node(GNode *parent_node, header_field_info *needle_hfinfo)
43 ph_stats_node_t *stats;
45 needle_node = g_node_first_child(parent_node);
48 finfo = needle_node->data;
49 if (finfo && finfo->hfinfo && finfo->hfinfo->id == needle_hfinfo->id) {
52 needle_node = g_node_next_sibling(needle_node);
55 /* None found. Create one. */
56 stats = g_new(ph_stats_node_t, 1);
58 /* Intialize counters */
59 stats->hfinfo = needle_hfinfo;
60 stats->num_pkts_total = 0;
61 stats->num_pkts_last = 0;
62 stats->num_bytes_total = 0;
63 stats->num_bytes_last = 0;
65 needle_node = g_node_new(stats);
66 g_node_append(parent_node, needle_node);
72 process_node(proto_item *proto_node, GNode *parent_stat_node, ph_stats_t *ps, guint pkt_len)
75 ph_stats_node_t *stats;
76 proto_item *proto_sibling_node;
79 finfo = proto_node->data;
82 stat_node = find_stat_node(parent_stat_node, finfo->hfinfo);
84 /* Assert that the finfo is related to a protocol, not a field. */
85 g_assert(finfo->hfinfo->parent == -1);
87 stats = stat_node->data;
88 stats->num_pkts_total++;
89 stats->num_bytes_total += pkt_len;
91 proto_sibling_node = g_node_next_sibling(proto_node);
93 if (proto_sibling_node) {
94 process_node(proto_sibling_node, stat_node, ps, pkt_len);
97 stats->num_pkts_last++;
98 stats->num_bytes_last += pkt_len;
105 process_tree(proto_tree *protocol_tree, ph_stats_t* ps, guint pkt_len)
107 proto_item *proto_node;
109 proto_node = g_node_first_child(protocol_tree);
114 process_node(proto_node, ps->stats_tree, ps, pkt_len);
118 process_frame(frame_data *frame, ph_stats_t* ps)
121 union wtap_pseudo_header phdr;
122 proto_tree *protocol_tree;
123 guint8 pd[WTAP_MAX_PACKET_SIZE];
125 protocol_tree = proto_tree_create_root();
127 /* Load the frame from the capture file */
128 wtap_seek_read(cfile.wth, frame->file_off, &phdr,
131 /* Dissect the frame */
132 edt = epan_dissect_new(&phdr, pd, frame, protocol_tree);
134 /* Get stats from this protocol tree */
135 process_tree(protocol_tree, ps, frame->pkt_len);
137 /* Free our memory. */
138 epan_dissect_free(edt);
139 proto_tree_free(protocol_tree);
149 guint tot_packets, tot_bytes;
151 /* Initialize the data */
152 ps = g_new(ph_stats_t, 1);
155 ps->stats_tree = g_node_new(NULL);
162 /* Skip frames that are hidden due to the display filter */
163 if (!frame->flags.passed_dfilter) {
167 process_frame(frame, ps);
170 tot_bytes += frame->pkt_len;
175 ps->tot_packets = tot_packets;
176 ps->tot_bytes = tot_bytes;
182 stat_node_free(GNode *node, gpointer data)
184 ph_stats_node_t *stats = node->data;
193 ph_stats_free(ph_stats_t *ps)
196 if (ps->stats_tree) {
197 g_node_traverse(ps->stats_tree, G_IN_ORDER,
199 stat_node_free, NULL);
200 g_node_destroy(ps->stats_tree);