aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/tshark.pod5
-rw-r--r--docbook/release-notes.asciidoc5
-rw-r--r--epan/dissectors/packet-hpfeeds.c99
-rw-r--r--ui/gtk/main_menubar.c2
-rw-r--r--ui/qt/main_window.h1
-rw-r--r--ui/qt/main_window.ui9
-rw-r--r--ui/qt/main_window_slots.cpp5
7 files changed, 126 insertions, 0 deletions
diff --git a/doc/tshark.pod b/doc/tshark.pod
index c7b79e61cc..a3c7e305af 100644
--- a/doc/tshark.pod
+++ b/doc/tshark.pod
@@ -1111,6 +1111,11 @@ and IPv6 addresses are dumped by default.
Addresses are collected from a number of sources, including standard "hosts"
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,
Calculate the HTTP statistics distribution. Displayed values are
diff --git a/docbook/release-notes.asciidoc b/docbook/release-notes.asciidoc
index 621ea50c2f..1453de9c96 100644
--- a/docbook/release-notes.asciidoc
+++ b/docbook/release-notes.asciidoc
@@ -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
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)
since version 1.12.0:
diff --git a/epan/dissectors/packet-hpfeeds.c b/epan/dissectors/packet-hpfeeds.c
index 2656aeae9b..7a08be509d 100644
--- a/epan/dissectors/packet-hpfeeds.c
+++ b/epan/dissectors/packet-hpfeeds.c
@@ -32,9 +32,33 @@
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/expert.h>
+#include <epan/tap.h>
+#include <epan/stats_tree.h>
+#include <epan/wmem/wmem_list.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_reg_handoff_hpfeeds(void);
@@ -130,6 +154,25 @@ dissect_hpfeeds_auth_pdu(tvbuff_t *tvb, proto_tree *tree, guint offset)
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
dissect_hpfeeds_publish_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
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);
}
+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
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
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 */
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);
}
@@ -391,6 +487,8 @@ proto_register_hpfeeds(void)
"Try heuristic sub-dissectors",
"Try to decode the payload using an heuristic sub-dissector",
&try_heuristic);
+
+ hpfeeds_tap = register_tap("hpfeeds");
}
void
@@ -402,6 +500,7 @@ proto_reg_handoff_hpfeeds(void)
if (!hpfeeds_prefs_initialized) {
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;
}
else {
diff --git a/ui/gtk/main_menubar.c b/ui/gtk/main_menubar.c
index 630dcb13cd..dbff56869a 100644
--- a/ui/gtk/main_menubar.c
+++ b/ui/gtk/main_menubar.c
@@ -1048,6 +1048,7 @@ static const char *ui_desc_menubar =
" <menuitem name= 'DNS' action='/Statistics/dns'/>\n"
" <menuitem name='FlowGraph' action='/Statistics/FlowGraph'/>\n"
" <menuitem name='HART-IP' action='/Statistics/hart_ip'/>\n"
+" <menuitem name= 'Hpfeeds' action='/Statistics/hpfeeds'/>\n"
" <menu name= 'HTTPMenu' action='/Statistics/HTTP'>\n"
" <menuitem name='http' action='/Statistics/HTTP/http'/>\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/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/hpfeeds", NULL, "HPFEEDS", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
{ "/Statistics/HTTP", NULL, "HTTP", NULL, NULL, NULL },
{ "/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) },
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index b254f4214e..d1fedbeaa1 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -423,6 +423,7 @@ private slots:
void on_actionStatisticsSametime_triggered();
void on_actionStatisticsDNS_triggered();
void actionStatisticsPlugin_triggered();
+ void on_actionStatisticsHpfeeds_triggered();
void openVoipCallsDialog(bool all_flows = false);
void on_actionTelephonyVoipCalls_triggered();
diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui
index 2502f8cfa5..0e1888faed 100644
--- a/ui/qt/main_window.ui
+++ b/ui/qt/main_window.ui
@@ -427,6 +427,7 @@
<addaction name="actionStatisticsDNS"/>
<addaction name="actionStatisticsFlowGraph"/>
<addaction name="actionStatisticsHART_IP"/>
+ <addaction name="actionStatisticsHpfeeds"/>
<addaction name="menuHTTP"/>
<addaction name="actionStatisticsSametime"/>
<addaction name="menuTcpStreamGraphs"/>
@@ -1569,6 +1570,14 @@
<string>HART-IP statistics</string>
</property>
</action>
+ <action name="actionStatisticsHpfeeds">
+ <property name="text">
+ <string>HPFEEDS</string>
+ </property>
+ <property name="toolTip">
+ <string>hpfeeds statistics</string>
+ </property>
+ </action>
<action name="actionStatisticsHTTPPacketCounter">
<property name="text">
<string>Packet Counter</string>
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index d53e9545bd..dad5df9943 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -1593,6 +1593,11 @@ void MainWindow::on_actionFileExportObjectsDICOM_triggered()
new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Dicom);
}
+void MainWindow::on_actionStatisticsHpfeeds_triggered()
+{
+ openStatisticsTreeDialog("hpfeeds");
+}
+
void MainWindow::on_actionFileExportObjectsHTTP_triggered()
{
new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Http);