forked from osmocom/wireshark
Added HPFEEDS stats_tree.
Change-Id: I256fd5395b062fa954ebd60598721323ea1d7ff1 Bug: 10875 Reviewed-on: https://code.wireshark.org/review/6713 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
parent
c80aa10415
commit
9bbc337306
|
@ -1111,6 +1111,11 @@ and IPv6 addresses are dumped by default.
|
||||||
Addresses are collected from a number of sources, including standard "hosts"
|
Addresses are collected from a number of sources, including standard "hosts"
|
||||||
files and captured traffic.
|
files and captured traffic.
|
||||||
|
|
||||||
|
=item B<-z> hpfeeds,tree[,I<filter>]
|
||||||
|
|
||||||
|
Calculate statistics for HPFEEDS traffic such as publish per channel, and opcode
|
||||||
|
distribution.
|
||||||
|
|
||||||
=item B<-z> http,stat,
|
=item B<-z> http,stat,
|
||||||
|
|
||||||
Calculate the HTTP statistics distribution. Displayed values are
|
Calculate the HTTP statistics distribution. Displayed values are
|
||||||
|
|
|
@ -44,6 +44,11 @@ field and shows a description in the status bar.
|
||||||
(min, max, avg) for values such as query name length or DNS
|
(min, max, avg) for values such as query name length or DNS
|
||||||
payload.
|
payload.
|
||||||
|
|
||||||
|
* HPFEEDS stats:
|
||||||
|
+ A new stats tree has been added to the statistics menu. Now it
|
||||||
|
is possible to collect stats per channel (messages count and payload
|
||||||
|
size), and opcode distribution.
|
||||||
|
|
||||||
The following features are new (or have been significantly updated)
|
The following features are new (or have been significantly updated)
|
||||||
since version 1.12.0:
|
since version 1.12.0:
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,33 @@
|
||||||
#include <epan/packet.h>
|
#include <epan/packet.h>
|
||||||
#include <epan/prefs.h>
|
#include <epan/prefs.h>
|
||||||
#include <epan/expert.h>
|
#include <epan/expert.h>
|
||||||
|
#include <epan/tap.h>
|
||||||
|
#include <epan/stats_tree.h>
|
||||||
|
#include <epan/wmem/wmem_list.h>
|
||||||
|
|
||||||
#include "packet-tcp.h"
|
#include "packet-tcp.h"
|
||||||
|
|
||||||
|
struct HpfeedsTap {
|
||||||
|
guint payload_size;
|
||||||
|
guint8* channel;
|
||||||
|
guint8 opcode;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int hpfeeds_tap = -1;
|
||||||
|
|
||||||
|
static const guint8* st_str_channels_payload = "Payload size per channel";
|
||||||
|
static const guint8* st_str_opcodes = "Opcodes";
|
||||||
|
|
||||||
|
static int st_node_channels_payload = -1;
|
||||||
|
static int st_node_opcodes = -1;
|
||||||
|
|
||||||
|
static wmem_list_t* channels_list;
|
||||||
|
|
||||||
|
struct channel_node {
|
||||||
|
guint8* channel;
|
||||||
|
guint st_node_channel_payload;
|
||||||
|
};
|
||||||
|
|
||||||
void proto_register_hpfeeds(void);
|
void proto_register_hpfeeds(void);
|
||||||
void proto_reg_handoff_hpfeeds(void);
|
void proto_reg_handoff_hpfeeds(void);
|
||||||
|
|
||||||
|
@ -130,6 +154,25 @@ dissect_hpfeeds_auth_pdu(tvbuff_t *tvb, proto_tree *tree, guint offset)
|
||||||
offset, -1, ENC_NA);
|
offset, -1, ENC_NA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static guint8*
|
||||||
|
hpfeeds_get_channel_name(tvbuff_t* tvb, guint offset)
|
||||||
|
{
|
||||||
|
guint8 len = tvb_get_guint8(tvb, offset);
|
||||||
|
offset += len + 1;
|
||||||
|
len = tvb_get_guint8(tvb, offset);
|
||||||
|
offset += 1;
|
||||||
|
return tvb_get_string_enc(wmem_file_scope(), tvb, offset, len, ENC_ASCII);
|
||||||
|
}
|
||||||
|
|
||||||
|
static guint
|
||||||
|
hpfeeds_get_payload_size(tvbuff_t* tvb, guint offset)
|
||||||
|
{
|
||||||
|
guint message_len = tvb_get_ntohl(tvb, offset);
|
||||||
|
guint ident_len = tvb_get_guint8(tvb, offset + 5);
|
||||||
|
guint channel_len = tvb_get_guint8(tvb, offset + 6 + ident_len);
|
||||||
|
return (message_len - 2 - ident_len - 1 - channel_len);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dissect_hpfeeds_publish_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
dissect_hpfeeds_publish_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||||
guint offset)
|
guint offset)
|
||||||
|
@ -166,6 +209,48 @@ dissect_hpfeeds_publish_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||||
proto_tree_add_item(tree, hf_hpfeeds_payload, tvb, offset, -1, ENC_NA);
|
proto_tree_add_item(tree, hf_hpfeeds_payload, tvb, offset, -1, ENC_NA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hpfeeds_stats_tree_init(stats_tree* st)
|
||||||
|
{
|
||||||
|
st_node_channels_payload = stats_tree_create_node(st, st_str_channels_payload, 0, TRUE);
|
||||||
|
st_node_opcodes = stats_tree_create_pivot(st, st_str_opcodes, 0);
|
||||||
|
|
||||||
|
channels_list = wmem_list_new(wmem_epan_scope());
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hpfeeds_stats_tree_packet(stats_tree* st _U_, packet_info* pinfo _U_, epan_dissect_t* edt _U_, const void* p)
|
||||||
|
{
|
||||||
|
struct HpfeedsTap *pi = (struct HpfeedsTap *)p;
|
||||||
|
wmem_list_frame_t* head = wmem_list_head(channels_list);
|
||||||
|
wmem_list_frame_t* cur = head;
|
||||||
|
struct channel_node* ch_node;
|
||||||
|
|
||||||
|
if (pi->opcode == OP_PUBLISH) {
|
||||||
|
/* search an existing channel node and create it if it does not */
|
||||||
|
while(cur != NULL) {
|
||||||
|
ch_node = (struct channel_node*)wmem_list_frame_data(cur);
|
||||||
|
if (strncmp(ch_node->channel, pi->channel, strlen(pi->channel)) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cur = wmem_list_frame_next(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur == NULL) {
|
||||||
|
ch_node = (struct channel_node*)wmem_alloc0(wmem_file_scope(), sizeof(struct channel_node));
|
||||||
|
ch_node->channel = wmem_strdup(wmem_file_scope(), pi->channel);
|
||||||
|
ch_node->st_node_channel_payload = stats_tree_create_node(st, ch_node->channel,
|
||||||
|
st_node_channels_payload, FALSE);
|
||||||
|
wmem_list_append(channels_list, ch_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
avg_stat_node_add_value(st, st_str_channels_payload, 0, FALSE, pi->payload_size);
|
||||||
|
avg_stat_node_add_value(st, ch_node->channel, 0, FALSE, pi->payload_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
stats_tree_tick_pivot(st, st_node_opcodes,
|
||||||
|
val_to_str(pi->opcode, opcode_vals, "Unknown opcode (%d)"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dissect_hpfeeds_subscribe_pdu(tvbuff_t *tvb, proto_tree *tree, guint offset)
|
dissect_hpfeeds_subscribe_pdu(tvbuff_t *tvb, proto_tree *tree, guint offset)
|
||||||
{
|
{
|
||||||
|
@ -198,6 +283,8 @@ get_hpfeeds_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
|
||||||
static int
|
static int
|
||||||
dissect_hpfeeds_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
|
dissect_hpfeeds_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
|
||||||
{
|
{
|
||||||
|
struct HpfeedsTap *hpfeeds_stats;
|
||||||
|
|
||||||
/* We have already parsed msg length we need to skip to opcode offset */
|
/* We have already parsed msg length we need to skip to opcode offset */
|
||||||
guint offset = 0;
|
guint offset = 0;
|
||||||
|
|
||||||
|
@ -252,6 +339,15 @@ dissect_hpfeeds_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* In publish, generate stats every packet, even not in tree */
|
||||||
|
hpfeeds_stats = wmem_new0(wmem_file_scope(), struct HpfeedsTap);
|
||||||
|
if (opcode == OP_PUBLISH) {
|
||||||
|
hpfeeds_stats->channel = hpfeeds_get_channel_name(tvb, offset);
|
||||||
|
hpfeeds_stats->payload_size = hpfeeds_get_payload_size(tvb, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
hpfeeds_stats->opcode = opcode;
|
||||||
|
tap_queue_packet(hpfeeds_tap, pinfo, hpfeeds_stats);
|
||||||
return tvb_captured_length(tvb);
|
return tvb_captured_length(tvb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,6 +487,8 @@ proto_register_hpfeeds(void)
|
||||||
"Try heuristic sub-dissectors",
|
"Try heuristic sub-dissectors",
|
||||||
"Try to decode the payload using an heuristic sub-dissector",
|
"Try to decode the payload using an heuristic sub-dissector",
|
||||||
&try_heuristic);
|
&try_heuristic);
|
||||||
|
|
||||||
|
hpfeeds_tap = register_tap("hpfeeds");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -402,6 +500,7 @@ proto_reg_handoff_hpfeeds(void)
|
||||||
|
|
||||||
if (!hpfeeds_prefs_initialized) {
|
if (!hpfeeds_prefs_initialized) {
|
||||||
hpfeeds_handle = new_create_dissector_handle(dissect_hpfeeds, proto_hpfeeds);
|
hpfeeds_handle = new_create_dissector_handle(dissect_hpfeeds, proto_hpfeeds);
|
||||||
|
stats_tree_register("hpfeeds", "hpfeeds", "HPFEEDS", 0, hpfeeds_stats_tree_packet, hpfeeds_stats_tree_init, NULL);
|
||||||
hpfeeds_prefs_initialized = TRUE;
|
hpfeeds_prefs_initialized = TRUE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -1048,6 +1048,7 @@ static const char *ui_desc_menubar =
|
||||||
" <menuitem name= 'DNS' action='/Statistics/dns'/>\n"
|
" <menuitem name= 'DNS' action='/Statistics/dns'/>\n"
|
||||||
" <menuitem name='FlowGraph' action='/Statistics/FlowGraph'/>\n"
|
" <menuitem name='FlowGraph' action='/Statistics/FlowGraph'/>\n"
|
||||||
" <menuitem name='HART-IP' action='/Statistics/hart_ip'/>\n"
|
" <menuitem name='HART-IP' action='/Statistics/hart_ip'/>\n"
|
||||||
|
" <menuitem name= 'Hpfeeds' action='/Statistics/hpfeeds'/>\n"
|
||||||
" <menu name= 'HTTPMenu' action='/Statistics/HTTP'>\n"
|
" <menu name= 'HTTPMenu' action='/Statistics/HTTP'>\n"
|
||||||
" <menuitem name='http' action='/Statistics/HTTP/http'/>\n"
|
" <menuitem name='http' action='/Statistics/HTTP/http'/>\n"
|
||||||
" <menuitem name='http_req' action='/Statistics/HTTP/http_req'/>\n"
|
" <menuitem name='http_req' action='/Statistics/HTTP/http_req'/>\n"
|
||||||
|
@ -1481,6 +1482,7 @@ static const GtkActionEntry main_menu_bar_entries[] = {
|
||||||
{ "/Statistics/dns", NULL, "DNS", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
|
{ "/Statistics/dns", NULL, "DNS", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
|
||||||
{ "/Statistics/FlowGraph", WIRESHARK_STOCK_FLOW_GRAPH, "Flo_w Graph...", NULL, NULL, G_CALLBACK(flow_graph_launch) },
|
{ "/Statistics/FlowGraph", WIRESHARK_STOCK_FLOW_GRAPH, "Flo_w Graph...", NULL, NULL, G_CALLBACK(flow_graph_launch) },
|
||||||
{ "/Statistics/hart_ip", NULL, "HART-IP", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
|
{ "/Statistics/hart_ip", NULL, "HART-IP", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
|
||||||
|
{ "/Statistics/hpfeeds", NULL, "HPFEEDS", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
|
||||||
{ "/Statistics/HTTP", NULL, "HTTP", NULL, NULL, NULL },
|
{ "/Statistics/HTTP", NULL, "HTTP", NULL, NULL, NULL },
|
||||||
{ "/Statistics/HTTP/http", NULL, "Packet Counter", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
|
{ "/Statistics/HTTP/http", NULL, "Packet Counter", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
|
||||||
{ "/Statistics/HTTP/http_req", NULL, "Requests", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
|
{ "/Statistics/HTTP/http_req", NULL, "Requests", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
|
||||||
|
|
|
@ -423,6 +423,7 @@ private slots:
|
||||||
void on_actionStatisticsSametime_triggered();
|
void on_actionStatisticsSametime_triggered();
|
||||||
void on_actionStatisticsDNS_triggered();
|
void on_actionStatisticsDNS_triggered();
|
||||||
void actionStatisticsPlugin_triggered();
|
void actionStatisticsPlugin_triggered();
|
||||||
|
void on_actionStatisticsHpfeeds_triggered();
|
||||||
|
|
||||||
void openVoipCallsDialog(bool all_flows = false);
|
void openVoipCallsDialog(bool all_flows = false);
|
||||||
void on_actionTelephonyVoipCalls_triggered();
|
void on_actionTelephonyVoipCalls_triggered();
|
||||||
|
|
|
@ -427,6 +427,7 @@
|
||||||
<addaction name="actionStatisticsDNS"/>
|
<addaction name="actionStatisticsDNS"/>
|
||||||
<addaction name="actionStatisticsFlowGraph"/>
|
<addaction name="actionStatisticsFlowGraph"/>
|
||||||
<addaction name="actionStatisticsHART_IP"/>
|
<addaction name="actionStatisticsHART_IP"/>
|
||||||
|
<addaction name="actionStatisticsHpfeeds"/>
|
||||||
<addaction name="menuHTTP"/>
|
<addaction name="menuHTTP"/>
|
||||||
<addaction name="actionStatisticsSametime"/>
|
<addaction name="actionStatisticsSametime"/>
|
||||||
<addaction name="menuTcpStreamGraphs"/>
|
<addaction name="menuTcpStreamGraphs"/>
|
||||||
|
@ -1569,6 +1570,14 @@
|
||||||
<string>HART-IP statistics</string>
|
<string>HART-IP statistics</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionStatisticsHpfeeds">
|
||||||
|
<property name="text">
|
||||||
|
<string>HPFEEDS</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>hpfeeds statistics</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
<action name="actionStatisticsHTTPPacketCounter">
|
<action name="actionStatisticsHTTPPacketCounter">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Packet Counter</string>
|
<string>Packet Counter</string>
|
||||||
|
|
|
@ -1593,6 +1593,11 @@ void MainWindow::on_actionFileExportObjectsDICOM_triggered()
|
||||||
new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Dicom);
|
new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Dicom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionStatisticsHpfeeds_triggered()
|
||||||
|
{
|
||||||
|
openStatisticsTreeDialog("hpfeeds");
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionFileExportObjectsHTTP_triggered()
|
void MainWindow::on_actionFileExportObjectsHTTP_triggered()
|
||||||
{
|
{
|
||||||
new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Http);
|
new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Http);
|
||||||
|
|
Loading…
Reference in New Issue