diff options
author | Gerald Combs <gerald@wireshark.org> | 2015-08-12 14:09:35 -0700 |
---|---|---|
committer | Gerald Combs <gerald@wireshark.org> | 2015-08-18 20:17:20 +0000 |
commit | 0e8cc9ab0ad41d09cbc886d1283266aea989c563 (patch) | |
tree | 4baceddfc9d74c8754dce9226f82678bf4a050ae | |
parent | 9a3d4e6eef9851f7368c89364add3759919b8f95 (diff) |
UDP multicast stream dialog.
Add the UDP multicast stream dialog. Abuse TapParameterDialog a bit more
so that we can edit parameters.
Remove some unused struct members and an unused function.
Change-Id: I962c70344e792f0959527e4bcba8a20bd7e8acf9
Reviewed-on: https://code.wireshark.org/review/10084
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Reviewed-by: Gerald Combs <gerald@wireshark.org>
-rw-r--r-- | doc/wireshark.pod.template | 4 | ||||
-rw-r--r-- | ui/cli/tap-rtp.c | 2 | ||||
-rw-r--r-- | ui/gtk/mcast_stream_dlg.c | 18 | ||||
-rw-r--r-- | ui/gtk/rtp_stream_dlg.c | 2 | ||||
-rw-r--r-- | ui/mcast_stream.c | 27 | ||||
-rw-r--r-- | ui/mcast_stream.h | 14 | ||||
-rw-r--r-- | ui/qt/CMakeLists.txt | 2 | ||||
-rw-r--r-- | ui/qt/Makefile.common | 2 | ||||
-rw-r--r-- | ui/qt/Wireshark.pro | 2 | ||||
-rw-r--r-- | ui/qt/main_window.h | 2 | ||||
-rw-r--r-- | ui/qt/main_window.ui | 9 | ||||
-rw-r--r-- | ui/qt/main_window_slots.cpp | 14 | ||||
-rw-r--r-- | ui/qt/multicast_statistics_dialog.cpp | 491 | ||||
-rw-r--r-- | ui/qt/multicast_statistics_dialog.h | 72 | ||||
-rw-r--r-- | ui/qt/response_time_delay_dialog.cpp | 20 | ||||
-rw-r--r-- | ui/qt/service_response_time_dialog.cpp | 44 | ||||
-rw-r--r-- | ui/qt/tap_parameter_dialog.cpp | 62 | ||||
-rw-r--r-- | ui/qt/tap_parameter_dialog.h | 13 | ||||
-rw-r--r-- | ui/qt/tap_parameter_dialog.ui | 3 | ||||
-rw-r--r-- | ui/rtp_stream.h | 1 | ||||
-rw-r--r-- | ui/tap-rtp-common.c | 2 | ||||
-rw-r--r-- | wsutil/str_util.c | 1 |
22 files changed, 713 insertions, 94 deletions
diff --git a/doc/wireshark.pod.template b/doc/wireshark.pod.template index 55fcf7260c..f414d4bf90 100644 --- a/doc/wireshark.pod.template +++ b/doc/wireshark.pod.template @@ -836,6 +836,10 @@ on those calls that match that filter. Example: B<-z "mgcp,srt,ip.addr==1.2.3.4"> will collect stats only for MGCP packets exchanged by the host at IP address 1.2.3.4 . +=item B<-z> multicast,stat[,<filter>] + +Show UDP multicast stream statistics. + =item B<-z> rpc,programs Collect call/reply SRT data for all known ONC-RPC programs/versions. diff --git a/ui/cli/tap-rtp.c b/ui/cli/tap-rtp.c index 0b9635f26b..eee1f13e9e 100644 --- a/ui/cli/tap-rtp.c +++ b/ui/cli/tap-rtp.c @@ -51,7 +51,7 @@ void register_tap_listener_rtp_streams(void); /* The one and only global rtpstream_tapinfo_t structure for tshark and wireshark. */ static rtpstream_tapinfo_t the_tapinfo_struct = - {NULL, NULL, NULL, 0, NULL, 0, TAP_ANALYSE, NULL, NULL, NULL, 0, FALSE}; + {NULL, NULL, NULL, 0, NULL, 0, TAP_ANALYSE, NULL, NULL, NULL, FALSE}; static void rtp_streams_stat_draw(void *arg _U_) diff --git a/ui/gtk/mcast_stream_dlg.c b/ui/gtk/mcast_stream_dlg.c index 716a4eb305..faba11c867 100644 --- a/ui/gtk/mcast_stream_dlg.c +++ b/ui/gtk/mcast_stream_dlg.c @@ -50,13 +50,11 @@ static void mcaststream_dlg_update(void *ti_ptr); -void register_tap_listener_mcast_stream_dlg(void); - /****************************************************************************/ /* the one and only global mcaststream_tapinfo_t structure for tshark and wireshark. */ static mcaststream_tapinfo_t the_tapinfo_struct = - {mcaststream_dlg_update, 0, NULL, 0, NULL, 0, FALSE}; + {NULL, NULL, mcaststream_dlg_update, NULL, 0, NULL, FALSE}; /* Capture callback data keys */ #define E_MCAST_ENTRY_1 "burst_interval" @@ -397,9 +395,9 @@ add_to_list_store(mcast_stream_info_t* strinfo) data[2] = g_strdup(dst_addr); data[3] = g_strdup_printf("%u", strinfo->dest_port); data[4] = g_strdup_printf("%u", strinfo->npackets); - data[5] = g_strdup_printf("%u /s", strinfo->apackets); - data[6] = g_strdup_printf("%2.1f Mbps", strinfo->average_bw); - data[7] = g_strdup_printf("%2.1f Mbps", strinfo->element.maxbw); + data[5] = g_strdup_printf("%.1f /s", strinfo->apackets); + data[6] = g_strdup_printf("%2.1f Mbps", strinfo->average_bw/1000000); + data[7] = g_strdup_printf("%2.1f Mbps", strinfo->element.maxbw/1000000); data[8] = g_strdup_printf("%u / %dms", strinfo->element.topburstsize, mcast_stream_burstint); data[9] = g_strdup_printf("%u", strinfo->element.numbursts); data[10] = g_strdup_printf("%.1f KB", (float)strinfo->element.topbuffusage/1000); @@ -438,7 +436,7 @@ add_to_list_store(mcast_stream_info_t* strinfo) g_snprintf(label_text, sizeof(label_text), "Detected %d Multicast streams, Average Bw: %.1f Mbps Max Bw: %.1f Mbps Max burst: %d / %dms Max buffer: %.1f KB", ++streams_nb, - mcaststream_dlg_get_tapinfo()->allstreams->average_bw, mcaststream_dlg_get_tapinfo()->allstreams->element.maxbw, + mcaststream_dlg_get_tapinfo()->allstreams->average_bw/1000000, mcaststream_dlg_get_tapinfo()->allstreams->element.maxbw/1000000, mcaststream_dlg_get_tapinfo()->allstreams->element.topburstsize, mcast_stream_burstint, (float)(mcaststream_dlg_get_tapinfo()->allstreams->element.topbuffusage)/1000); gtk_label_set_text(GTK_LABEL(top_label), label_text); @@ -826,12 +824,6 @@ mcaststream_launch(GtkAction *action _U_, gpointer user_data _U_) /* Tap listener will be removed and cleaned up in mcaststream_on_destroy */ } -/****************************************************************************/ -void -register_tap_listener_mcast_stream_dlg(void) -{ -} - mcaststream_tapinfo_t *mcaststream_dlg_get_tapinfo(void) { return &the_tapinfo_struct; } diff --git a/ui/gtk/rtp_stream_dlg.c b/ui/gtk/rtp_stream_dlg.c index 1762f7e6d2..8916eed598 100644 --- a/ui/gtk/rtp_stream_dlg.c +++ b/ui/gtk/rtp_stream_dlg.c @@ -59,7 +59,7 @@ void register_tap_listener_rtp_stream_dlg(void); */ static rtpstream_tapinfo_t the_tapinfo_struct = { rtpstream_tap_draw, rtpstream_dlg_mark_packet, NULL, 0, NULL, 0, - TAP_ANALYSE, NULL, NULL, NULL, 0, FALSE + TAP_ANALYSE, NULL, NULL, NULL, FALSE }; /****************************************************************************/ diff --git a/ui/mcast_stream.c b/ui/mcast_stream.c index 6a845a384b..0a0790038f 100644 --- a/ui/mcast_stream.c +++ b/ui/mcast_stream.c @@ -110,18 +110,19 @@ mcaststream_reset(mcaststream_tapinfo_t *tapinfo) g_free(tapinfo->allstreams); tapinfo->allstreams = NULL; - tapinfo->nstreams = 0; tapinfo->npackets = 0; - ++(tapinfo->launch_count); - return; } static void -mcaststream_reset_cb(void *arg) +mcaststream_reset_cb(void *ti_ptr) { - mcaststream_reset((mcaststream_tapinfo_t *)arg); + mcaststream_tapinfo_t *tapinfo = (mcaststream_tapinfo_t *)ti_ptr; + if (tapinfo && tapinfo->tap_reset) { + tapinfo->tap_reset(ti_ptr); + } + mcaststream_reset(tapinfo); } /****************************************************************************/ @@ -143,7 +144,7 @@ mcaststream_draw(void *ti_ptr) /****************************************************************************/ /* whenever a udp packet is seen by the tap listener */ -static int +static gboolean mcaststream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *arg2 _U_) { mcaststream_tapinfo_t *tapinfo = (mcaststream_tapinfo_t *)arg; @@ -256,12 +257,16 @@ mcaststream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const /* calculate average bandwidth for this stream */ strinfo->total_bytes = strinfo->total_bytes + pinfo->fd->pkt_len; - if (deltatime > 0) - strinfo->average_bw = (((double)(strinfo->total_bytes*8) / deltatime) / 1000000); /* increment the packets counter for this stream and calculate average pps */ ++(strinfo->npackets); - strinfo->apackets = (guint32) (strinfo->npackets / deltatime); + + if (deltatime > 0) { + strinfo->apackets = strinfo->npackets / deltatime; + strinfo->average_bw = ((double)(strinfo->total_bytes*8) / deltatime); + } else { + strinfo->apackets = strinfo->average_bw = 0.0; + } /* time between first and last packet in any group */ tapinfo->allstreams->stop_rel = pinfo->rel_ts; @@ -274,7 +279,7 @@ mcaststream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const /* calculate average bandwidth for all streams */ tapinfo->allstreams->total_bytes = tapinfo->allstreams->total_bytes + pinfo->fd->pkt_len; if (deltatime > 0) - tapinfo->allstreams->average_bw = (((double)(tapinfo->allstreams->total_bytes *8) / deltatime) / 1000000); + tapinfo->allstreams->average_bw = ((double)(tapinfo->allstreams->total_bytes*8) / deltatime); /* sliding window and buffercalc for this group*/ slidingwindow(strinfo, pinfo); @@ -439,7 +444,7 @@ slidingwindow(mcast_stream_info_t *strinfo, packet_info *pinfo) strinfo->element.burstsize = diff; if(strinfo->element.burstsize > strinfo->element.topburstsize) { strinfo->element.topburstsize = strinfo->element.burstsize; - strinfo->element.maxbw = (double)(strinfo->element.topburstsize) * 1000 / mcast_stream_burstint * pinfo->fd->pkt_len * 8 / 1000000; + strinfo->element.maxbw = (double)(strinfo->element.topburstsize) * 1000 / mcast_stream_burstint * pinfo->fd->pkt_len * 8; } strinfo->element.last++; diff --git a/ui/mcast_stream.h b/ui/mcast_stream.h index f3417aee73..e780f8e885 100644 --- a/ui/mcast_stream.h +++ b/ui/mcast_stream.h @@ -52,7 +52,7 @@ typedef struct buffer{ gint32 buffstatus; /* buffer status */ gint32 numbuffalarms; /* number of alarms triggered by buffer underruns */ gint32 topbuffusage; /* top buffer usage in refresh interval */ - double maxbw; /* maximum bandwidth usage */ + double maxbw; /* Maximum bandwidth usage. Bits/s */ } t_buffer; @@ -63,9 +63,9 @@ typedef struct _mcast_stream_info { address dest_addr; guint16 dest_port; guint32 npackets; - guint32 apackets; + double apackets; guint32 total_bytes; - double average_bw; + double average_bw; /* Bits/s */ guint32 first_frame_num; /* frame number of first frame */ /* start of recording (GMT) of this stream */ @@ -83,13 +83,13 @@ typedef struct _mcast_stream_info { /* structure that holds the information about all detected streams */ /* struct holding all information of the tap */ typedef struct _mcaststream_tapinfo { - tap_draw_cb tap_draw; /**< tap draw callback */ - int nstreams; /* number of streams in the list */ - GList* strinfo_list; /* list with all streams */ + gpointer user_data; /* User data pointer */ + tap_reset_cb tap_reset; /**< tap reset callback */ + tap_draw_cb tap_draw; /**< tap draw callback */ + GList* strinfo_list; /* list of mcast_stream_info_t */ guint32 npackets; /* total number of mcast packets of all streams */ mcast_stream_info_t* allstreams; /* structure holding information common for all streams */ - guint32 launch_count; /* number of times the tap has been run */ gboolean is_registered; /* if the tap listener is currently registered or not */ } mcaststream_tapinfo_t; diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt index 370a18261b..b43922fedb 100644 --- a/ui/qt/CMakeLists.txt +++ b/ui/qt/CMakeLists.txt @@ -84,6 +84,7 @@ set(WIRESHARK_QT_HEADERS main_window_preferences_frame.h manage_interfaces_dialog.h module_preferences_scroll_area.h + multicast_statistics_dialog.h overlay_scroll_bar.h packet_comment_dialog.h packet_dialog.h @@ -286,6 +287,7 @@ set(WIRESHARK_QT_TAP_SRC funnel_statistics.cpp gsm_map_summary_dialog.cpp io_graph_dialog.cpp + multicast_statistics_dialog.cpp rtp_stream_dialog.cpp sctp_all_assocs_dialog.cpp sctp_assoc_analyse_dialog.cpp diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common index 87a5fa735c..142b511444 100644 --- a/ui/qt/Makefile.common +++ b/ui/qt/Makefile.common @@ -198,6 +198,7 @@ MOC_HDRS = \ main_window_preferences_frame.h \ manage_interfaces_dialog.h \ module_preferences_scroll_area.h \ + multicast_statistics_dialog.h \ overlay_scroll_bar.h \ packet_comment_dialog.h \ packet_dialog.h \ @@ -490,6 +491,7 @@ WIRESHARK_QT_TAP_SRC = \ funnel_statistics.cpp \ gsm_map_summary_dialog.cpp \ io_graph_dialog.cpp \ + multicast_statistics_dialog.cpp \ rtp_stream_dialog.cpp \ sctp_all_assocs_dialog.cpp \ sctp_assoc_analyse_dialog.cpp \ diff --git a/ui/qt/Wireshark.pro b/ui/qt/Wireshark.pro index 46d313d873..627a66e8e4 100644 --- a/ui/qt/Wireshark.pro +++ b/ui/qt/Wireshark.pro @@ -324,6 +324,7 @@ HEADERS += $$HEADERS_WS_C \ main_window_preferences_frame.h \ manage_interfaces_dialog.h \ module_preferences_scroll_area.h \ + multicast_statistics_dialog.h \ overlay_scroll_bar.h \ packet_comment_dialog.h \ packet_dialog.h \ @@ -708,6 +709,7 @@ SOURCES += \ main_window_slots.cpp \ manage_interfaces_dialog.cpp \ module_preferences_scroll_area.cpp \ + multicast_statistics_dialog.cpp \ overlay_scroll_bar.cpp \ packet_comment_dialog.cpp \ packet_dialog.cpp \ diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h index 49e9a90cde..ad17ef355d 100644 --- a/ui/qt/main_window.h +++ b/ui/qt/main_window.h @@ -477,6 +477,8 @@ private slots: void on_actionSCTPShowAllAssociations_triggered(); void on_actionSCTPAnalyseThisAssociation_triggered(); void on_actionSCTPFilterThisAssociation_triggered(); + void statCommandMulticastStatistics(const char *arg, void *); + void on_actionStatisticsUdpMulticastStreams_triggered(); void openStatisticsTreeDialog(const gchar *abbr); void on_actionStatistics29WestTopics_Advertisements_by_Topic_triggered(); diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui index 7a0e8ec493..f3f621c799 100644 --- a/ui/qt/main_window.ui +++ b/ui/qt/main_window.ui @@ -492,6 +492,7 @@ <addaction name="actionStatisticsHTTP2"/> <addaction name="actionStatisticsSametime"/> <addaction name="menuTcpStreamGraphs"/> + <addaction name="actionStatisticsUdpMulticastStreams"/> </widget> <widget class="QMenu" name="menuTelephony"> <property name="title"> @@ -2637,6 +2638,14 @@ <string>Go to the packet referenced by the selected field.</string> </property> </action> + <action name="actionStatisticsUdpMulticastStreams"> + <property name="text"> + <string>UDP Multicast Streams</string> + </property> + <property name="toolTip"> + <string>Show UTP multicast stream statistics.</string> + </property> + </action> </widget> <layoutdefault spacing="6" margin="11"/> <customwidgets> diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp index 9663744b16..a98a84cba9 100644 --- a/ui/qt/main_window_slots.cpp +++ b/ui/qt/main_window_slots.cpp @@ -127,6 +127,7 @@ #include "tap_parameter_dialog.h" #include "tcp_stream_dialog.h" #include "time_shift_dialog.h" +#include "multicast_statistics_dialog.h" #include "voip_calls_dialog.h" #include "wireshark_application.h" #include "filter_action.h" @@ -2635,6 +2636,19 @@ void MainWindow::on_actionStatisticsTcpStreamWindowScaling_triggered() openTcpStreamDialog(GRAPH_WSCALE); } +void MainWindow::statCommandMulticastStatistics(const char *arg, void *) +{ + MulticastStatisticsDialog *mcast_stats_dlg = new MulticastStatisticsDialog(*this, capture_file_, arg); + connect(mcast_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)), + this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType))); + mcast_stats_dlg->show(); +} + +void MainWindow::on_actionStatisticsUdpMulticastStreams_triggered() +{ + statCommandMulticastStatistics(NULL, NULL); +} + void MainWindow::openStatisticsTreeDialog(const gchar *abbr) { StatsTreeDialog *st_dialog = new StatsTreeDialog(*this, capture_file_, abbr); diff --git a/ui/qt/multicast_statistics_dialog.cpp b/ui/qt/multicast_statistics_dialog.cpp new file mode 100644 index 0000000000..4b4da27446 --- /dev/null +++ b/ui/qt/multicast_statistics_dialog.cpp @@ -0,0 +1,491 @@ +/* multicast_statistics_dialog.cpp + * + * 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 + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "multicast_statistics_dialog.h" + +#include "ui/mcast_stream.h" + +#include <QFormLayout> +#include <QLabel> +#include <QPushButton> +#include <QTreeWidget> + +#include "qt_ui_utils.h" +#include "syntax_line_edit.h" +#include "wireshark_application.h" + +enum { + col_src_addr_, + col_src_port_, + col_dst_addr_, + col_dst_port_, + col_packets_, + col_packets_s_, + col_avg_bw_, + col_max_bw_, + col_max_burst_, + col_burst_alarms_, + col_max_buffers_, + col_buffer_alarms_ +}; + +enum { + mcast_table_type_ = 1000 +}; + +class MulticastStatTreeWidgetItem : public QTreeWidgetItem +{ +public: + MulticastStatTreeWidgetItem(QTreeWidget *parent) : + QTreeWidgetItem (parent, mcast_table_type_) + { + memset(&src_addr_, 0, sizeof(src_addr_)); + memset(&dst_addr_, 0, sizeof(dst_addr_)); + } + + void updateStreamInfo(const mcast_stream_info_t *stream_info) { + copy_address(&src_addr_, &stream_info->src_addr); + src_port_ = stream_info->src_port; + copy_address(&dst_addr_, &stream_info->dest_addr); + dst_port_ = stream_info->dest_port; + num_packets_ = stream_info->npackets; + avg_pps_ = stream_info->apackets; + avg_bw_ = stream_info->average_bw; + max_bw_ = stream_info->element.maxbw; + top_burst_size_ = stream_info->element.topburstsize; + num_bursts_ = stream_info->element.numbursts; + top_buff_usage_ = stream_info->element.topbuffusage; + num_buff_alarms_ = stream_info->element.numbuffalarms; + + draw(); + } + + void draw() { + setText(col_src_addr_, address_to_qstring(&src_addr_)); + setText(col_src_port_, QString::number(src_port_)); + setText(col_dst_addr_, address_to_qstring(&dst_addr_)); + setText(col_dst_port_, QString::number(dst_port_)); + setText(col_packets_, QString::number(num_packets_)); + setText(col_packets_s_, QString::number(avg_pps_, 'f', 2)); + setText(col_avg_bw_, bits_s_to_qstring(avg_bw_)); + setText(col_max_bw_, bits_s_to_qstring(max_bw_)); + setText(col_max_burst_, QString("%1 / %2ms").arg(top_burst_size_).arg(mcast_stream_burstint)); + setText(col_burst_alarms_, QString::number(num_bursts_)); + setText(col_max_buffers_, bits_s_to_qstring(top_buff_usage_)); + setText(col_buffer_alarms_, QString::number(num_buff_alarms_)); + } + + bool operator< (const QTreeWidgetItem &other) const + { + if (other.type() != mcast_table_type_) return QTreeWidgetItem::operator< (other); + const MulticastStatTreeWidgetItem *other_row = static_cast<const MulticastStatTreeWidgetItem *>(&other); + + switch (treeWidget()->sortColumn()) { + case col_src_addr_: + return cmp_address(&src_addr_, &other_row->src_addr_) < 0; + case col_src_port_: + return src_port_ < other_row->src_port_; + case col_dst_addr_: + return cmp_address(&dst_addr_, &other_row->dst_addr_) < 0; + case col_dst_port_: + return dst_port_ < other_row->dst_port_; + case col_packets_: + return num_packets_ < other_row->num_packets_; + case col_packets_s_: + return avg_pps_ < other_row->avg_pps_; + case col_avg_bw_: + return avg_bw_ < other_row->avg_bw_; + case col_max_bw_: + return max_bw_ < other_row->max_bw_; + case col_max_burst_: + return top_burst_size_ < other_row->top_burst_size_; + case col_burst_alarms_: + return num_bursts_ < other_row->num_bursts_; + case col_max_buffers_: + return top_buff_usage_ < other_row->top_buff_usage_; + case col_buffer_alarms_: + return num_buff_alarms_ < other_row->num_buff_alarms_; + default: + break; + } + + return QTreeWidgetItem::operator< (other); + } + QList<QVariant> rowData() { + return QList<QVariant>() + << address_to_qstring(&src_addr_) << src_port_ + << address_to_qstring(&dst_addr_) << dst_port_ + << num_packets_ << avg_pps_ + << avg_bw_ << max_bw_ + << top_burst_size_ << num_bursts_ + << top_buff_usage_ << num_buff_alarms_; + } + const QString filterExpression() { + QString ip_version; + + if (src_addr_.type == AT_IPv6) ip_version = "v6"; + + const QString filter_expr = QString("(ip%1.src==%2 && udp.srcport==%3 && ip%1.dst==%4 && udp.dstport==%5)") + .arg(ip_version) + .arg(address_to_qstring(&src_addr_)) + .arg(src_port_) + .arg(address_to_qstring(&dst_addr_)) + .arg(dst_port_); + return filter_expr; + } + +private: + address src_addr_; + guint16 src_port_; + address dst_addr_; + guint16 dst_port_; + unsigned num_packets_; + double avg_pps_; + double avg_bw_; + double max_bw_; + int top_burst_size_; + int num_bursts_; + int top_buff_usage_; + int num_buff_alarms_; +}; + +MulticastStatisticsDialog::MulticastStatisticsDialog(QWidget &parent, CaptureFile &cf, const char *filter) : + TapParameterDialog(parent, cf) +{ + setWindowSubtitle(tr("UDP Multicast Streams")); + + // XXX Use recent settings instead + resize(parent.width() * 4 / 5, parent.height() * 3 / 4); + + tapinfo_ = new mcaststream_tapinfo_t(); + tapinfo_->user_data = this; + tapinfo_->tap_reset = tapReset; + tapinfo_->tap_draw = tapDraw; + + QStringList header_names = QStringList() + << tr("Source Address") << tr("Source Port") + << tr("Destination Address") << tr("Destination Port") + << tr("Packets") << tr("Packets/s") + << tr("Avg BW (bps)") << tr("Max BW (bps)") + << tr("Max Burst") << tr("Burst Alarms") + << tr("Max Buffers (B)") << tr("Buffer Alarms"); + + statsTreeWidget()->setHeaderLabels(header_names); + + for (int col = 0; col < statsTreeWidget()->columnCount(); col++) { + if (col == col_src_addr_ || col == col_dst_addr_) continue; + statsTreeWidget()->headerItem()->setTextAlignment(col, Qt::AlignRight); + } + + burst_measurement_interval_le_ = new SyntaxLineEdit(this); + burst_alarm_threshold_le_ = new SyntaxLineEdit(this); + buffer_alarm_threshold_le_ = new SyntaxLineEdit(this); + stream_empty_speed_le_ = new SyntaxLineEdit(this); + total_empty_speed_le_ = new SyntaxLineEdit(this); + + int filter_layout_idx = verticalLayout()->indexOf(filterLayout()->widget()); + QGridLayout *param_grid = new QGridLayout(); + int one_em = fontMetrics().height(); + verticalLayout()->insertLayout(filter_layout_idx, param_grid); + + // Label | LineEdit | | Label | LineEdit | | Label | LineEdit + // 0 1 2 3 4 5 6 7 + param_grid->setColumnMinimumWidth(2, one_em * 2); + param_grid->setColumnStretch(2, 1); + param_grid->setColumnMinimumWidth(5, one_em * 2); + param_grid->setColumnStretch(5, 1); + param_grid->addWidget(new QLabel(tr("Burst measurement interval (ms):")), 0, 0, Qt::AlignRight); + param_grid->addWidget(burst_measurement_interval_le_, 0, 1); + param_grid->addWidget(new QLabel(tr("Burst alarm threshold (packets):")), 0, 3, Qt::AlignRight); + param_grid->addWidget(burst_alarm_threshold_le_, 0, 4); + param_grid->addWidget(new QLabel(tr("Buffer alarm threshold (B):")), 0, 6, Qt::AlignRight); + param_grid->addWidget(buffer_alarm_threshold_le_, 0, 7); + + param_grid->addWidget(new QLabel(tr("Stream empty speed (Kb/s:")), 1, 0, Qt::AlignRight); + param_grid->addWidget(stream_empty_speed_le_, 1, 1); + param_grid->addWidget(new QLabel(tr("Total empty speed (Kb/s:")), 1, 3, Qt::AlignRight); + param_grid->addWidget(total_empty_speed_le_, 1, 4); + + burst_measurement_interval_le_->setText(QString::number(mcast_stream_burstint)); + burst_alarm_threshold_le_->setText(QString::number(mcast_stream_trigger)); + buffer_alarm_threshold_le_->setText(QString::number(mcast_stream_bufferalarm)); + stream_empty_speed_le_->setText(QString::number(mcast_stream_emptyspeed)); + total_empty_speed_le_->setText(QString::number(mcast_stream_cumulemptyspeed)); + + line_edits_ = QList<QWidget *>() + << burst_measurement_interval_le_ << burst_alarm_threshold_le_ + << buffer_alarm_threshold_le_ << stream_empty_speed_le_ + << total_empty_speed_le_; + + foreach (QWidget *line_edit, line_edits_) { + line_edit->setMinimumWidth(one_em * 5); + connect(line_edit, SIGNAL(textEdited(QString)), this, SLOT(updateWidgets())); + } + + addFilterActions(); + + if (filter) { + setDisplayFilter(filter); + } + + connect(this, SIGNAL(updateFilter(QString&,bool)), + this, SLOT(updateMulticastParameters())); + + connect(&cap_file_, SIGNAL(captureFileClosing()), + this, SLOT(captureFileClosing())); + + /* Register the tap listener */ + register_tap_listener_mcast_stream(tapinfo_); + + updateWidgets(); + QTimer::singleShot(0, this, SLOT(fillTree())); +} + +MulticastStatisticsDialog::~MulticastStatisticsDialog() +{ + /* Remove the stream tap listener */ + remove_tap_listener_mcast_stream(tapinfo_); + + /* Clean up memory used by stream tap */ + mcaststream_reset(tapinfo_); + + delete tapinfo_; +} + +void MulticastStatisticsDialog::tapReset(void *mti_ptr) +{ + mcaststream_tapinfo_t *tapinfo = (mcaststream_tapinfo_t *)mti_ptr; + MulticastStatisticsDialog *ms_dlg = dynamic_cast<MulticastStatisticsDialog *>((MulticastStatisticsDialog*)tapinfo->user_data); + if (!ms_dlg || !ms_dlg->statsTreeWidget()) return; + + ms_dlg->statsTreeWidget()->clear(); +} + +void MulticastStatisticsDialog::tapDraw(void *mti_ptr) +{ + mcaststream_tapinfo_t *tapinfo = (mcaststream_tapinfo_t *)mti_ptr; + MulticastStatisticsDialog *ms_dlg = dynamic_cast<MulticastStatisticsDialog *>((MulticastStatisticsDialog*)tapinfo->user_data); + if (!ms_dlg || !ms_dlg->statsTreeWidget()) return; + + // Add missing rows and update stats + int cur_row = 0; + for (GList *cur = g_list_first(tapinfo->strinfo_list); cur; cur = g_list_next(cur)) { + mcast_stream_info_t *stream_info = (mcast_stream_info_t *) cur->data; + if (!stream_info) continue; + + MulticastStatTreeWidgetItem *ms_ti; + QTreeWidgetItem *ti = ms_dlg->statsTreeWidget()->topLevelItem(cur_row); + if (!ti) { + ms_ti = new MulticastStatTreeWidgetItem(ms_dlg->statsTreeWidget()); + for (int col = 0; col < ms_dlg->statsTreeWidget()->columnCount(); col++) { + if (col == col_src_addr_ || col == col_dst_addr_) continue; + ms_ti->setTextAlignment(col, Qt::AlignRight); + } + } else { + ms_ti = static_cast<MulticastStatTreeWidgetItem *>(ti); + } + + ms_ti->updateStreamInfo(stream_info); + cur_row++; + } + + for (int col = 0; col < ms_dlg->statsTreeWidget()->columnCount() - 1; col++) { + ms_dlg->statsTreeWidget()->resizeColumnToContents(col); + } +} + +const QString MulticastStatisticsDialog::filterExpression() +{ + QString filter_expr; + if (statsTreeWidget()->selectedItems().count() > 0) { + QTreeWidgetItem *ti = statsTreeWidget()->selectedItems()[0]; + + MulticastStatTreeWidgetItem *ms_ti = static_cast<MulticastStatTreeWidgetItem *>(ti); + filter_expr = ms_ti->filterExpression(); + } + return filter_expr; +} + +void MulticastStatisticsDialog::updateWidgets() +{ + QString hint; + bool enable_apply = true; + bool enable_edits = cap_file_.isValid(); + bool ok = false; + int param; + + param = burst_measurement_interval_le_->text().toUInt(&ok); + if (!ok || param < 1 || param > 1000) { + hint += tr("The burst interval must be between 1 and 1000. "); + enable_apply = false; + burst_measurement_interval_le_->setSyntaxState(SyntaxLineEdit::Invalid); + } else { + burst_measurement_interval_le_->setSyntaxState(SyntaxLineEdit::Valid); + } + + param = burst_alarm_threshold_le_->text().toInt(&ok); + if (!ok) { + hint += tr("The burst alarm threshold isn't valid. "); + enable_apply = false; + burst_alarm_threshold_le_->setSyntaxState(SyntaxLineEdit::Invalid); + } else { + burst_alarm_threshold_le_->setSyntaxState(SyntaxLineEdit::Valid); + } + + param = buffer_alarm_threshold_le_->text().toInt(&ok); + if (!ok || param < 1) { + hint += tr("The buffer alarm threshold isn't valid. "); + enable_apply = false; + buffer_alarm_threshold_le_->setSyntaxState(SyntaxLineEdit::Invalid); + } else { + buffer_alarm_threshold_le_->setSyntaxState(SyntaxLineEdit::Valid); + } + + param = stream_empty_speed_le_->text().toInt(&ok); + if (!ok || param < 1 || param > 10000000) { + hint += tr("The stream empty speed should be between 1 and 10000000. "); + enable_apply = false; + stream_empty_speed_le_->setSyntaxState(SyntaxLineEdit::Invalid); + } else { + stream_empty_speed_le_->setSyntaxState(SyntaxLineEdit::Valid); + } + + param = total_empty_speed_le_->text().toInt(&ok); + if (!ok || param < 1 || param > 10000000) { + hint += tr("The total empty speed should be between 1 and 10000000. "); + enable_apply = false; + total_empty_speed_le_->setSyntaxState(SyntaxLineEdit::Invalid); + } else { + total_empty_speed_le_->setSyntaxState(SyntaxLineEdit::Valid); + } + + foreach (QWidget *line_edit, line_edits_) { + line_edit->setEnabled(enable_edits); + } + + applyFilterButton()->setEnabled(enable_apply); + + if (hint.isEmpty() && tapinfo_->allstreams) { + const QString stats = tr("%1 streams, avg bw: %2bps, max bw: %3bps, max burst: %4 / %5ms, max buffer: %6B") + .arg(statsTreeWidget()->topLevelItemCount()) + .arg(bits_s_to_qstring(tapinfo_->allstreams->average_bw)) + .arg(bits_s_to_qstring(tapinfo_->allstreams->element.maxbw)) + .arg(tapinfo_->allstreams->element.topburstsize) + .arg(mcast_stream_burstint) + .arg(bits_s_to_qstring(tapinfo_->allstreams->element.topbuffusage)); + hint.append(stats); + } + hint.prepend("<small><i>"); + hint.append("</i></small>"); + setHint(hint); + TapParameterDialog::updateWidgets(); +} + +void MulticastStatisticsDialog::updateMulticastParameters() +{ + bool ok = false; + int param; + + param = burst_measurement_interval_le_->text().toUInt(&ok); + if (ok && param > 0 && param <= 1000) { + mcast_stream_burstint = (guint16) param; + } + + param = burst_alarm_threshold_le_->text().toInt(&ok); + if (ok) { + mcast_stream_trigger = param; + } + + param = buffer_alarm_threshold_le_->text().toInt(&ok); + if (ok && param > 0) { + mcast_stream_trigger = param; + } + + param = stream_empty_speed_le_->text().toInt(&ok); + if (ok && param > 0 && param <= 10000000) { + mcast_stream_emptyspeed = param; + } + + param = total_empty_speed_le_->text().toInt(&ok); + if (ok && param > 0 && param <= 10000000) { + mcast_stream_cumulemptyspeed = param; + } +} + +void MulticastStatisticsDialog::fillTree() +{ + QList<QWidget *> disable_widgets = QList<QWidget *>() + << line_edits_ << displayFilterLineEdit() << applyFilterButton(); + + foreach (QWidget *w, disable_widgets) w->setEnabled(false); + + /* Scan for Mcast streams (redissect all packets) */ + mcaststream_scan(tapinfo_, cap_file_.capFile()); + tapDraw(tapinfo_); + + foreach (QWidget *w, disable_widgets) w->setEnabled(true); + updateWidgets(); +} + +void MulticastStatisticsDialog::captureFileClosing() +{ + /* Remove the stream tap listener */ + remove_tap_listener_mcast_stream(tapinfo_); + + updateWidgets(); +} + +// Stat command + args + +static void +multicast_statistics_init(const char *, void*) { + wsApp->emitStatCommandSignal("MulticastStatistics", NULL, NULL); +} + +static stat_tap_ui multicast_statistics_ui = { + REGISTER_STAT_GROUP_GENERIC, + NULL, + "multicast,stat", + multicast_statistics_init, + 0, + NULL +}; + +extern "C" { +void +register_tap_listener_qt_multicast_statistics(void) +{ + register_stat_tap_ui(&multicast_statistics_ui, NULL); +} +} + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/qt/multicast_statistics_dialog.h b/ui/qt/multicast_statistics_dialog.h new file mode 100644 index 0000000000..5e6a56d7f3 --- /dev/null +++ b/ui/qt/multicast_statistics_dialog.h @@ -0,0 +1,72 @@ +/* multicast_statistics_dialog.h + * + * 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 + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MULTICASTSTATISTICSDIALOG_H +#define MULTICASTSTATISTICSDIALOG_H + +#include "tap_parameter_dialog.h" + +class SyntaxLineEdit; + +class MulticastStatisticsDialog : public TapParameterDialog +{ + Q_OBJECT + +public: + MulticastStatisticsDialog(QWidget &parent, CaptureFile &cf, const char *filter = NULL); + ~MulticastStatisticsDialog(); + +private: + struct _mcaststream_tapinfo *tapinfo_; + SyntaxLineEdit *burst_measurement_interval_le_; + SyntaxLineEdit *burst_alarm_threshold_le_; + SyntaxLineEdit *buffer_alarm_threshold_le_; + SyntaxLineEdit *stream_empty_speed_le_; + SyntaxLineEdit *total_empty_speed_le_; + QList<QWidget *> line_edits_; + + // Callbacks for register_tap_listener + static void tapReset(void *mti_ptr); + static void tapDraw(void *mti_ptr); + + virtual const QString filterExpression(); + +private slots: + void updateWidgets(); + void updateMulticastParameters(); + virtual void fillTree(); + void captureFileClosing(); +}; + +#endif // MULTICASTSTATISTICSDIALOG_H + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/qt/response_time_delay_dialog.cpp b/ui/qt/response_time_delay_dialog.cpp index dd80261c3c..2e2de37c7a 100644 --- a/ui/qt/response_time_delay_dialog.cpp +++ b/ui/qt/response_time_delay_dialog.cpp @@ -78,13 +78,6 @@ enum { col_repeated_responses_ }; -QStringList header_names_ = QStringList() - << "Type" << "Messages" - << "Min SRT" << "Max SRT" << "Avg SRT" - << "Min in Frame" << "Max in Frame" - << "Open Requests" << "Discarded Responses" - << "Repeated Requests" << "Repeated Responses"; - enum { rtd_table_type_ = 1000, rtd_time_stat_type_ @@ -169,19 +162,24 @@ ResponseTimeDelayDialog::ResponseTimeDelayDialog(QWidget &parent, CaptureFile &c TapParameterDialog(parent, cf, help_topic), rtd_(rtd) { - QString subtitle = QString("%1 Response Time Delay Statistics") + QString subtitle = tr("%1 Response Time Delay Statistics") .arg(proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rtd)))); setWindowSubtitle(subtitle); - statsTreeWidget()->setHeaderLabels(header_names_); + QStringList header_names = QStringList() + << tr("Type") << tr("Messages") + << tr("Min SRT") << tr("Max SRT") << tr("Avg SRT") + << tr("Min in Frame") << tr("Max in Frame") + << tr("Open Requests") << tr("Discarded Responses") + << tr("Repeated Requests") << tr("Repeated Responses"); + + statsTreeWidget()->setHeaderLabels(header_names); for (int col = 0; col < statsTreeWidget()->columnCount(); col++) { if (col == col_type_) continue; statsTreeWidget()->headerItem()->setTextAlignment(col, Qt::AlignRight); } - setDisplayFilter(filter); - if (!filter.isEmpty()) { setDisplayFilter(filter); } diff --git a/ui/qt/service_response_time_dialog.cpp b/ui/qt/service_response_time_dialog.cpp index b976b5f0f2..b7e1d14b23 100644 --- a/ui/qt/service_response_time_dialog.cpp +++ b/ui/qt/service_response_time_dialog.cpp @@ -195,49 +195,7 @@ ServiceResponseTimeDialog::ServiceResponseTimeDialog(QWidget &parent, CaptureFil statsTreeWidget()->headerItem()->setTextAlignment(col, Qt::AlignRight); } - QMenu *submenu; - QAction *insert_action = ctx_menu_.actions().first(); - - FilterAction::Action cur_action = FilterAction::ActionApply; - submenu = ctx_menu_.addMenu(FilterAction::actionName(cur_action)); - foreach (FilterAction::ActionType at, FilterAction::actionTypes()) { - FilterAction *fa = new FilterAction(submenu, cur_action, at); - submenu->addAction(fa); - connect(fa, SIGNAL(triggered()), this, SLOT(filterActionTriggered())); - filter_actions_ << fa; - } - ctx_menu_.insertMenu(insert_action, submenu); - - cur_action = FilterAction::ActionPrepare; - submenu = ctx_menu_.addMenu(FilterAction::actionName(cur_action)); - foreach (FilterAction::ActionType at, FilterAction::actionTypes()) { - FilterAction *fa = new FilterAction(submenu, cur_action, at); - submenu->addAction(fa); - connect(fa, SIGNAL(triggered()), this, SLOT(filterActionTriggered())); - filter_actions_ << fa; - } - ctx_menu_.insertMenu(insert_action, submenu); - - cur_action = FilterAction::ActionFind; - submenu = ctx_menu_.addMenu(FilterAction::actionName(cur_action)); - foreach (FilterAction::ActionType at, FilterAction::actionTypes(cur_action)) { - FilterAction *fa = new FilterAction(submenu, cur_action, at); - submenu->addAction(fa); - connect(fa, SIGNAL(triggered()), this, SLOT(filterActionTriggered())); - filter_actions_ << fa; - } - ctx_menu_.insertMenu(insert_action, submenu); - - cur_action = FilterAction::ActionColorize; - submenu = ctx_menu_.addMenu(FilterAction::actionName(cur_action)); - foreach (FilterAction::ActionType at, FilterAction::actionTypes(cur_action)) { - FilterAction *fa = new FilterAction(submenu, cur_action, at); - submenu->addAction(fa); - connect(fa, SIGNAL(triggered()), this, SLOT(filterActionTriggered())); - filter_actions_ << fa; - } - ctx_menu_.insertMenu(insert_action, submenu); - ctx_menu_.insertSeparator(insert_action); + addFilterActions(); if (!filter.isEmpty()) { setDisplayFilter(filter); diff --git a/ui/qt/tap_parameter_dialog.cpp b/ui/qt/tap_parameter_dialog.cpp index fb2922cc10..83837105d3 100644 --- a/ui/qt/tap_parameter_dialog.cpp +++ b/ui/qt/tap_parameter_dialog.cpp @@ -141,6 +141,21 @@ QTreeWidget *TapParameterDialog::statsTreeWidget() return ui->statsTreeWidget; } +QLineEdit *TapParameterDialog::displayFilterLineEdit() +{ + return ui->displayFilterLineEdit; +} + +QPushButton *TapParameterDialog::applyFilterButton() +{ + return ui->applyFilterButton; +} + +QVBoxLayout *TapParameterDialog::verticalLayout() +{ + return ui->verticalLayout; +} + QHBoxLayout *TapParameterDialog::filterLayout() { return ui->filterLayout; @@ -423,6 +438,53 @@ void TapParameterDialog::contextMenuEvent(QContextMenuEvent *event) ctx_menu_.exec(event->globalPos()); } +void TapParameterDialog::addFilterActions() +{ + QMenu *submenu; + QAction *insert_action = ctx_menu_.actions().first(); + + FilterAction::Action cur_action = FilterAction::ActionApply; + submenu = ctx_menu_.addMenu(FilterAction::actionName(cur_action)); + foreach (FilterAction::ActionType at, FilterAction::actionTypes()) { + FilterAction *fa = new FilterAction(submenu, cur_action, at); + submenu->addAction(fa); + connect(fa, SIGNAL(triggered()), this, SLOT(filterActionTriggered())); + filter_actions_ << fa; + } + ctx_menu_.insertMenu(insert_action, submenu); + + cur_action = FilterAction::ActionPrepare; + submenu = ctx_menu_.addMenu(FilterAction::actionName(cur_action)); + foreach (FilterAction::ActionType at, FilterAction::actionTypes()) { + FilterAction *fa = new FilterAction(submenu, cur_action, at); + submenu->addAction(fa); + connect(fa, SIGNAL(triggered()), this, SLOT(filterActionTriggered())); + filter_actions_ << fa; + } + ctx_menu_.insertMenu(insert_action, submenu); + + cur_action = FilterAction::ActionFind; + submenu = ctx_menu_.addMenu(FilterAction::actionName(cur_action)); + foreach (FilterAction::ActionType at, FilterAction::actionTypes(cur_action)) { + FilterAction *fa = new FilterAction(submenu, cur_action, at); + submenu->addAction(fa); + connect(fa, SIGNAL(triggered()), this, SLOT(filterActionTriggered())); + filter_actions_ << fa; + } + ctx_menu_.insertMenu(insert_action, submenu); + + cur_action = FilterAction::ActionColorize; + submenu = ctx_menu_.addMenu(FilterAction::actionName(cur_action)); + foreach (FilterAction::ActionType at, FilterAction::actionTypes(cur_action)) { + FilterAction *fa = new FilterAction(submenu, cur_action, at); + submenu->addAction(fa); + connect(fa, SIGNAL(triggered()), this, SLOT(filterActionTriggered())); + filter_actions_ << fa; + } + ctx_menu_.insertMenu(insert_action, submenu); + ctx_menu_.insertSeparator(insert_action); +} + void TapParameterDialog::updateWidgets() { if (file_closed_) { diff --git a/ui/qt/tap_parameter_dialog.h b/ui/qt/tap_parameter_dialog.h index c9188829fb..281274b298 100644 --- a/ui/qt/tap_parameter_dialog.h +++ b/ui/qt/tap_parameter_dialog.h @@ -35,8 +35,10 @@ #include "wireshark_dialog.h" class QHBoxLayout; +class QLineEdit; class QTreeWidget; class QTreeWidgetItem; +class QVBoxLayout; namespace Ui { class TapParameterDialog; @@ -60,6 +62,9 @@ public: // Needed by static member functions in subclasses. Should we just make // "ui" available instead? QTreeWidget *statsTreeWidget(); + QLineEdit *displayFilterLineEdit(); + QPushButton *applyFilterButton(); + QVBoxLayout *verticalLayout(); QHBoxLayout *filterLayout(); void drawTreeItems(); @@ -71,11 +76,9 @@ signals: public slots: protected: - QMenu ctx_menu_; - QList<QAction *> filter_actions_; - void showEvent(QShowEvent *); void contextMenuEvent(QContextMenuEvent *event); + void addFilterActions(); QString displayFilter(); void setDisplayFilter(const QString &filter); void setHint(const QString &hint); @@ -84,9 +87,12 @@ protected: protected slots: void filterActionTriggered(); + void updateWidgets(); private: Ui::TapParameterDialog *ui; + QMenu ctx_menu_; + QList<QAction *> filter_actions_; int help_topic_; static const QString action_name_; bool retap_on_show_; @@ -99,7 +105,6 @@ private: virtual QByteArray getTreeAsString(st_format_type format); private slots: - void updateWidgets(); void on_applyFilterButton_clicked(); void on_actionCopyToClipboard_triggered(); void on_actionSaveAs_triggered(); diff --git a/ui/qt/tap_parameter_dialog.ui b/ui/qt/tap_parameter_dialog.ui index c7c624fc1c..bcaad122ea 100644 --- a/ui/qt/tap_parameter_dialog.ui +++ b/ui/qt/tap_parameter_dialog.ui @@ -16,6 +16,9 @@ <layout class="QVBoxLayout" name="verticalLayout"> <item> <widget class="QTreeWidget" name="statsTreeWidget"> + <property name="sortingEnabled"> + <bool>true</bool> + </property> <column> <property name="text"> <string notr="true">Item</string> diff --git a/ui/rtp_stream.h b/ui/rtp_stream.h index f6097561ff..2df54e9a03 100644 --- a/ui/rtp_stream.h +++ b/ui/rtp_stream.h @@ -106,7 +106,6 @@ struct _rtpstream_tapinfo { rtp_stream_info_t *filter_stream_fwd; /**< used as filter in some tap modes */ rtp_stream_info_t *filter_stream_rev; /**< used as filter in some tap modes */ FILE *save_file; - guint32 launch_count; /**< number of times the tap has been run */ gboolean is_registered; /**< if the tap listener is currently registered or not */ }; diff --git a/ui/tap-rtp-common.c b/ui/tap-rtp-common.c index a95e261b50..b164c39ed3 100644 --- a/ui/tap-rtp-common.c +++ b/ui/tap-rtp-common.c @@ -94,8 +94,6 @@ void rtpstream_reset(rtpstream_tapinfo_t *tapinfo) tapinfo->npackets = 0; } - ++(tapinfo->launch_count); - return; } diff --git a/wsutil/str_util.c b/wsutil/str_util.c index ba1c486282..adcbb91e03 100644 --- a/wsutil/str_util.c +++ b/wsutil/str_util.c @@ -121,6 +121,7 @@ isdigit_string(guchar *str) #endif /* Given a size, return its value in a human-readable format */ +/* This doesn't handle fractional values. We might want to make size a double. */ gchar * format_size(gint64 size, format_size_flags_e flags) { |