forked from osmocom/wireshark
hierarchy stats: Only increment the total packet count once per frame
The same hierarchy of protocols can appear multiple times in a frame, for example if there are multiple PDUs for a protocol that begin in that frame. Keep track of the last frame where we incremented our stat node and use that to only increment it once per frame. Add a "total number of PDUs with this hierarchy" statistic and display it as a new final column in the GUI. Update the User Guide. In the purpose of doing this, get rid of temporary variables and increment the ph_stats_t members directly, since we pass that into our functions already, and thus have access to the current packet count. Fix #17553. Fix #18034. Fix #12565.
This commit is contained in:
parent
4c7865c81b
commit
7a3c2252f5
Binary file not shown.
Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 85 KiB |
|
@ -144,7 +144,7 @@ Percent Packets::
|
||||||
The percentage of protocol packets relative to all packets in the capture.
|
The percentage of protocol packets relative to all packets in the capture.
|
||||||
|
|
||||||
Packets::
|
Packets::
|
||||||
The total number of packets of this protocol.
|
The total number of packets that contain this protocol.
|
||||||
|
|
||||||
Percent Bytes::
|
Percent Bytes::
|
||||||
The percentage of protocol bytes relative to the total bytes in the capture.
|
The percentage of protocol bytes relative to the total bytes in the capture.
|
||||||
|
@ -164,19 +164,23 @@ The absolute number of bytes of this protocol where it was the highest protocol
|
||||||
End Bits/s::
|
End Bits/s::
|
||||||
The bandwidth of this protocol relative to the capture time where was the highest protocol in the stack (last dissected).
|
The bandwidth of this protocol relative to the capture time where was the highest protocol in the stack (last dissected).
|
||||||
|
|
||||||
Packets usually contain multiple protocols. As a result, more than one protocol will
|
PDUs::
|
||||||
be counted for each packet. Example: In the screenshot IP has 99.9% and TCP
|
The total number of PDUs of this protocol.
|
||||||
98.5% (which is together much more than 100%).
|
|
||||||
|
Packets usually contain multiple protocols. As a result, more than one protocol
|
||||||
|
will be counted for each packet. Example: In the screenshot 100% of packets
|
||||||
|
are IP and 99.3% are TCP (which is together much more than 100%).
|
||||||
|
|
||||||
Protocol layers can consist of packets that won’t contain any higher layer
|
Protocol layers can consist of packets that won’t contain any higher layer
|
||||||
protocol, so the sum of all higher layer packets may not sum up to the protocols
|
protocol, so the sum of all higher layer packets may not sum to the protocol's
|
||||||
packet count. Example: In the screenshot TCP has 98.5% but the sum of the
|
packet count. This can be caused by segments and fragments reassembled in other
|
||||||
subprotocols (TLS, HTTP, etc.) is much less. This can be caused by continuation
|
frames, TCP protocol overhead, and other undissected data. Example: In the
|
||||||
frames, TCP protocol overhead, and other undissected data.
|
screenshot 99.3% of the packets are TCP but the sum of the subprotocols
|
||||||
|
(TLS, HTTP, Git, etc.) is much less.
|
||||||
|
|
||||||
A single packet can contain the same protocol more than once. In this case, the
|
A single packet can contain the same protocol more than once. In this case, the
|
||||||
protocol is counted more than once. For example, ICMP replies and many tunneling
|
entry in the `PDUs` column will be greater than that of `Packets`. Example:
|
||||||
protocols will carry more than one IP header.
|
In the screenshot there are many more TLS and Git PDUs than there are packets.
|
||||||
|
|
||||||
[#ChStatConversations]
|
[#ChStatConversations]
|
||||||
|
|
||||||
|
|
|
@ -68,9 +68,11 @@ find_stat_node(GNode *parent_stat_node, header_field_info *needle_hfinfo)
|
||||||
/* Intialize counters */
|
/* Intialize counters */
|
||||||
stats->hfinfo = needle_hfinfo;
|
stats->hfinfo = needle_hfinfo;
|
||||||
stats->num_pkts_total = 0;
|
stats->num_pkts_total = 0;
|
||||||
|
stats->num_pdus_total = 0;
|
||||||
stats->num_pkts_last = 0;
|
stats->num_pkts_last = 0;
|
||||||
stats->num_bytes_total = 0;
|
stats->num_bytes_total = 0;
|
||||||
stats->num_bytes_last = 0;
|
stats->num_bytes_last = 0;
|
||||||
|
stats->last_pkt = 0;
|
||||||
|
|
||||||
needle_stat_node = g_node_new(stats);
|
needle_stat_node = g_node_new(stats);
|
||||||
g_node_append(parent_stat_node, needle_stat_node);
|
g_node_append(parent_stat_node, needle_stat_node);
|
||||||
|
@ -102,7 +104,17 @@ process_node(proto_node *ptree_node, GNode *parent_stat_node, ph_stats_t *ps)
|
||||||
stat_node = find_stat_node(parent_stat_node, finfo->hfinfo);
|
stat_node = find_stat_node(parent_stat_node, finfo->hfinfo);
|
||||||
|
|
||||||
stats = STAT_NODE_STATS(stat_node);
|
stats = STAT_NODE_STATS(stat_node);
|
||||||
stats->num_pkts_total++;
|
/* Only increment the total packet count once per packet for a given
|
||||||
|
* node, since there could be multiple PDUs in a frame.
|
||||||
|
* (All the other statistics should be incremented every time,
|
||||||
|
* including the count for how often a protocol was the last
|
||||||
|
* protocol in a packet.)
|
||||||
|
*/
|
||||||
|
if (stats->last_pkt != ps->tot_packets) {
|
||||||
|
stats->num_pkts_total++;
|
||||||
|
stats->last_pkt = ps->tot_packets;
|
||||||
|
}
|
||||||
|
stats->num_pdus_total++;
|
||||||
stats->num_bytes_total += finfo->length;
|
stats->num_bytes_total += finfo->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +202,6 @@ ph_stats_new(capture_file *cf)
|
||||||
ph_stats_t *ps;
|
ph_stats_t *ps;
|
||||||
guint32 framenum;
|
guint32 framenum;
|
||||||
frame_data *frame;
|
frame_data *frame;
|
||||||
guint tot_packets, tot_bytes;
|
|
||||||
progdlg_t *progbar = NULL;
|
progdlg_t *progbar = NULL;
|
||||||
gboolean stop_flag;
|
gboolean stop_flag;
|
||||||
int count;
|
int count;
|
||||||
|
@ -225,9 +236,6 @@ ph_stats_new(capture_file *cf)
|
||||||
|
|
||||||
stop_flag = FALSE;
|
stop_flag = FALSE;
|
||||||
|
|
||||||
tot_packets = 0;
|
|
||||||
tot_bytes = 0;
|
|
||||||
|
|
||||||
wtap_rec_init(&rec);
|
wtap_rec_init(&rec);
|
||||||
ws_buffer_init(&buf, 1514);
|
ws_buffer_init(&buf, 1514);
|
||||||
|
|
||||||
|
@ -283,13 +291,20 @@ ph_stats_new(capture_file *cf)
|
||||||
if (frame->passed_dfilter) {
|
if (frame->passed_dfilter) {
|
||||||
|
|
||||||
if (frame->has_ts) {
|
if (frame->has_ts) {
|
||||||
if (tot_packets == 0) {
|
if (ps->tot_packets == 0) {
|
||||||
double cur_time = nstime_to_sec(&frame->abs_ts);
|
double cur_time = nstime_to_sec(&frame->abs_ts);
|
||||||
ps->first_time = cur_time;
|
ps->first_time = cur_time;
|
||||||
ps->last_time = cur_time;
|
ps->last_time = cur_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We throw away the statistics if we quit in the middle,
|
||||||
|
* so increment this first so that the count starts at 1
|
||||||
|
* when processing records, since we initialize the stat
|
||||||
|
* nodes' last_pkt to 0.
|
||||||
|
*/
|
||||||
|
ps->tot_packets++;
|
||||||
|
|
||||||
/* we don't care about colinfo */
|
/* we don't care about colinfo */
|
||||||
if (!process_record(cf, frame, NULL, &rec, &buf, ps)) {
|
if (!process_record(cf, frame, NULL, &rec, &buf, ps)) {
|
||||||
/*
|
/*
|
||||||
|
@ -301,8 +316,7 @@ ph_stats_new(capture_file *cf)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tot_packets++;
|
ps->tot_bytes += frame->pkt_len;
|
||||||
tot_bytes += frame->pkt_len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
|
@ -326,9 +340,6 @@ ph_stats_new(capture_file *cf)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ps->tot_packets = tot_packets;
|
|
||||||
ps->tot_bytes = tot_bytes;
|
|
||||||
|
|
||||||
return ps;
|
return ps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,11 @@ extern "C" {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
header_field_info *hfinfo;
|
header_field_info *hfinfo;
|
||||||
guint num_pkts_total;
|
guint num_pkts_total;
|
||||||
|
guint num_pdus_total;
|
||||||
guint num_pkts_last;
|
guint num_pkts_last;
|
||||||
guint num_bytes_total;
|
guint num_bytes_total;
|
||||||
guint num_bytes_last;
|
guint num_bytes_last;
|
||||||
|
guint last_pkt;
|
||||||
} ph_stats_node_t;
|
} ph_stats_node_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ const int bandwidth_col_ = 5;
|
||||||
const int end_packets_col_ = 6;
|
const int end_packets_col_ = 6;
|
||||||
const int end_bytes_col_ = 7;
|
const int end_bytes_col_ = 7;
|
||||||
const int end_bandwidth_col_ = 8;
|
const int end_bandwidth_col_ = 8;
|
||||||
|
const int pdus_col_ = 9;
|
||||||
|
|
||||||
class ProtocolHierarchyTreeWidgetItem : public QTreeWidgetItem
|
class ProtocolHierarchyTreeWidgetItem : public QTreeWidgetItem
|
||||||
{
|
{
|
||||||
|
@ -53,6 +54,7 @@ public:
|
||||||
ProtocolHierarchyTreeWidgetItem(QTreeWidgetItem *parent, ph_stats_node_t& ph_stats_node) :
|
ProtocolHierarchyTreeWidgetItem(QTreeWidgetItem *parent, ph_stats_node_t& ph_stats_node) :
|
||||||
QTreeWidgetItem(parent),
|
QTreeWidgetItem(parent),
|
||||||
total_packets_(ph_stats_node.num_pkts_total),
|
total_packets_(ph_stats_node.num_pkts_total),
|
||||||
|
total_pdus_(ph_stats_node.num_pdus_total),
|
||||||
last_packets_(ph_stats_node.num_pkts_last),
|
last_packets_(ph_stats_node.num_pkts_last),
|
||||||
total_bytes_(ph_stats_node.num_bytes_total),
|
total_bytes_(ph_stats_node.num_bytes_total),
|
||||||
last_bytes_(ph_stats_node.num_bytes_last),
|
last_bytes_(ph_stats_node.num_bytes_last),
|
||||||
|
@ -87,6 +89,7 @@ public:
|
||||||
setText(end_packets_col_, QString::number(last_packets_));
|
setText(end_packets_col_, QString::number(last_packets_));
|
||||||
setText(end_bytes_col_, QString::number(last_bytes_));
|
setText(end_bytes_col_, QString::number(last_bytes_));
|
||||||
setText(end_bandwidth_col_, seconds > 0.0 ? bits_s_to_qstring(end_bits_s_) : UTF8_EM_DASH);
|
setText(end_bandwidth_col_, seconds > 0.0 ? bits_s_to_qstring(end_bits_s_) : UTF8_EM_DASH);
|
||||||
|
setText(pdus_col_, QString::number(total_pdus_));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a QString, int, double, or invalid QVariant representing the raw column data.
|
// Return a QString, int, double, or invalid QVariant representing the raw column data.
|
||||||
|
@ -110,6 +113,8 @@ public:
|
||||||
return last_bytes_;
|
return last_bytes_;
|
||||||
case (end_bandwidth_col_):
|
case (end_bandwidth_col_):
|
||||||
return end_bits_s_;
|
return end_bits_s_;
|
||||||
|
case (pdus_col_):
|
||||||
|
return total_pdus_;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -137,6 +142,8 @@ public:
|
||||||
return last_bytes_ < other_phtwi.last_bytes_;
|
return last_bytes_ < other_phtwi.last_bytes_;
|
||||||
case end_bandwidth_col_:
|
case end_bandwidth_col_:
|
||||||
return end_bits_s_ < other_phtwi.end_bits_s_;
|
return end_bits_s_ < other_phtwi.end_bits_s_;
|
||||||
|
case pdus_col_:
|
||||||
|
return total_pdus_ < other_phtwi.total_pdus_;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -150,6 +157,7 @@ public:
|
||||||
private:
|
private:
|
||||||
QString filter_name_;
|
QString filter_name_;
|
||||||
unsigned total_packets_;
|
unsigned total_packets_;
|
||||||
|
unsigned total_pdus_;
|
||||||
unsigned last_packets_;
|
unsigned last_packets_;
|
||||||
unsigned total_bytes_;
|
unsigned total_bytes_;
|
||||||
unsigned last_bytes_;
|
unsigned last_bytes_;
|
||||||
|
|
|
@ -70,6 +70,11 @@
|
||||||
<string>End Bits/s</string>
|
<string>End Bits/s</string>
|
||||||
</property>
|
</property>
|
||||||
</column>
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>PDUs</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|
Loading…
Reference in New Issue