aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docbook/wsug_graphics/ws-stats-conversations.pngbin250943 -> 240607 bytes
-rw-r--r--docbook/wsug_src/WSUG_chapter_statistics.asciidoc13
-rw-r--r--epan/column.c2
-rw-r--r--ui/qt/capture_file.cpp8
-rw-r--r--ui/qt/capture_file.h6
-rw-r--r--ui/qt/conversation_dialog.cpp48
-rw-r--r--ui/qt/conversation_dialog.h3
-rw-r--r--ui/qt/traffic_table_dialog.cpp18
-rw-r--r--ui/qt/traffic_table_dialog.h14
-rw-r--r--ui/qt/traffic_table_dialog.ui26
-rw-r--r--ui/traffic_table_ui.c1
-rw-r--r--ui/traffic_table_ui.h1
12 files changed, 130 insertions, 10 deletions
diff --git a/docbook/wsug_graphics/ws-stats-conversations.png b/docbook/wsug_graphics/ws-stats-conversations.png
index 763188a368..b37936b035 100644
--- a/docbook/wsug_graphics/ws-stats-conversations.png
+++ b/docbook/wsug_graphics/ws-stats-conversations.png
Binary files differ
diff --git a/docbook/wsug_src/WSUG_chapter_statistics.asciidoc b/docbook/wsug_src/WSUG_chapter_statistics.asciidoc
index 5255ef7ad0..d88a54b84e 100644
--- a/docbook/wsug_src/WSUG_chapter_statistics.asciidoc
+++ b/docbook/wsug_src/WSUG_chapter_statistics.asciidoc
@@ -141,10 +141,10 @@ description of the known endpoint types can be found in
The conversations window is similar to the endpoint Window. See
<<ChStatEndpointsWindow>> for a description of their common features. Along with
addresses, packet counters, and byte counters the conversation window adds four
-columns: the time in seconds between the start of the capture and the start of
-the conversation (``Rel Start''), the duration of the conversation in seconds, and
-the average bits (not bytes) per second in each direction. A timeline graph is
-also drawn across the ``Rel Start'' and ``Duration'' columns.
+columns: the start time of the conversation (``Rel Start'') or (``Abs Start''),
+the duration of the conversation in seconds, and the average bits (not bytes)
+per second in each direction. A timeline graph is also drawn across the
+``Rel Start'' / ``Abs Start'' and ``Duration'' columns.
.The ``Conversations'' window
image::wsug_graphics/ws-stats-conversations.png[scaledwidth="100%"]
@@ -154,7 +154,10 @@ Each row in the list shows the statistical values for exactly one conversation.
_Name resolution_ will be done if selected in the window and if it is active for
the specific protocol layer (MAC layer for the selected Ethernet endpoints
page). _Limit to display filter_ will only show conversations matching the
-current display filter.
+current display filter. _Absolute start time_ switches the start time column
+between relative (``Rel Start'') and absolute (``Abs Start'') times. Relative start
+times match the ``Seconds Since Beginning of Capture'' time display format in the
+packet list and absolute start times match the ``Time of Day'' display format.
The button:[Copy] button will copy the list values to the clipboard in CSV
(Comma Separated Values) or YAML format. The button:[Follow Stream...] button
diff --git a/epan/column.c b/epan/column.c
index 1f7b2fa518..2a67019591 100644
--- a/epan/column.c
+++ b/epan/column.c
@@ -48,7 +48,7 @@ col_format_to_string(const gint fmt) {
"%At", /* 3) COL_ABS_TIME */
"%V", /* 4) COL_VSAN - !! DEPRECATED !!*/
"%B", /* 5) COL_CUMULATIVE_BYTES */
- "%Cus", /* 6 COL_CUSTOM */
+ "%Cus", /* 6) COL_CUSTOM */
"%y", /* 7) COL_DCE_CALL */
"%Tt", /* 8) COL_DELTA_TIME */
"%Gt", /* 9) COL_DELTA_TIME_DIS */
diff --git a/ui/qt/capture_file.cpp b/ui/qt/capture_file.cpp
index 2df533ea75..2c04a35261 100644
--- a/ui/qt/capture_file.cpp
+++ b/ui/qt/capture_file.cpp
@@ -99,6 +99,14 @@ struct _packet_info *CaptureFile::packetInfo()
return NULL;
}
+int CaptureFile::timestampPrecision()
+{
+ if (capFile() && capFile()->wth) {
+ return wtap_file_tsprec(capFile()->wth);
+ }
+ return WTAP_TSPREC_UNKNOWN;
+}
+
void CaptureFile::retapPackets()
{
if (cap_file_) {
diff --git a/ui/qt/capture_file.h b/ui/qt/capture_file.h
index 033fa06efa..61487032c0 100644
--- a/ui/qt/capture_file.h
+++ b/ui/qt/capture_file.h
@@ -76,6 +76,12 @@ public:
*/
struct _packet_info *packetInfo();
+ /** Timestamp precision for the current file.
+ * @return One of the WTAP_TSPREC_x values defined in wiretap/wtap.h,
+ * or WTAP_TSPREC_UNKNOWN if no file is open.
+ */
+ int timestampPrecision();
+
/** Reload the capture file
*/
void reload();
diff --git a/ui/qt/conversation_dialog.cpp b/ui/qt/conversation_dialog.cpp
index 4ace205e19..8810223790 100644
--- a/ui/qt/conversation_dialog.cpp
+++ b/ui/qt/conversation_dialog.cpp
@@ -35,6 +35,7 @@
#include "wireshark_application.h"
#include <QCheckBox>
+#include <QDateTime>
#include <QDialogButtonBox>
#include <QPushButton>
@@ -58,6 +59,9 @@
// Fixed bugs:
// - Friendly unit displays https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9231
// - Misleading bps calculation https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8703
+// - Show Absolute time in conversation tables https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=11618
+// - The value of 'Rel start' and 'Duration' in "Conversations" no need too precise https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=12803
+
static const QString table_name_ = QObject::tr("Conversation");
ConversationDialog::ConversationDialog(QWidget &parent, CaptureFile &cf, int cli_proto_id, const char *filter) :
@@ -71,6 +75,8 @@ ConversationDialog::ConversationDialog(QWidget &parent, CaptureFile &cf, int cli
graph_bt_->setToolTip(tr("Graph a TCP conversation."));
connect(graph_bt_, SIGNAL(clicked()), this, SLOT(graphTcp()));
+ absoluteTimeCheckBox()->show();
+
addProgressFrame(&parent);
QList<int> conv_protos;
@@ -163,6 +169,9 @@ bool ConversationDialog::addTrafficTable(register_ct_t* table)
this, SIGNAL(filterAction(QString,FilterAction::Action,FilterAction::ActionType)));
connect(nameResolutionCheckBox(), SIGNAL(toggled(bool)),
conv_tree, SLOT(setNameResolutionEnabled(bool)));
+ connect(absoluteTimeCheckBox(), SIGNAL(toggled(bool)),
+ conv_tree, SLOT(updateStartTime(bool)));
+
// XXX Move to ConversationTreeWidget ctor?
QByteArray filter_utf8;
@@ -365,9 +374,31 @@ public:
case CONV_COLUMN_BYTES_BA:
return gchar_free_to_qstring(format_size(conv_item->rx_bytes, format_size_unit_none|format_size_prefix_si));
case CONV_COLUMN_START:
- return QString::number(nstime_to_sec(&conv_item->start_time), 'f', 9);
+ {
+ bool use_ns = treeWidget()->window()->property("nanosecond_precision").toBool();
+ int width = use_ns ? 9 : 6;
+
+ if (treeWidget()->window()->property("absolute_start_time").toBool()) {
+ nstime_t *abs_time = &conv_item->start_abs_time;
+ QDateTime abs_dt = QDateTime::fromMSecsSinceEpoch(nstime_to_msec(abs_time));
+ return QString("%1.%2")
+ // Mimic column-utils:set_abs_time as best we can
+ .arg(abs_dt.toString("hh:mm:ss"))
+ .arg(use_ns ? abs_time->nsecs : abs_time->nsecs / 1000, width, 10, QChar('0'));
+ }
+
+ return QString::number(nstime_to_sec(&conv_item->start_time), 'f', width);
+ }
case CONV_COLUMN_DURATION:
- return QString::number(duration, 'f', 6);
+ {
+ // The GTK+ UI uses 9 digit precision for the start time and 4 for the duration.
+ // Do the same here and above for non-nanosecond precision and add a couple
+ // of digits for nanosecond precision.
+ bool use_ns = treeWidget()->window()->property("nanosecond_precision").toBool();
+ int width = use_ns ? 6 : 4;
+
+ return QString::number(duration, 'f', width);
+ }
case CONV_COLUMN_BPS_AB:
if (duration > min_bw_calc_duration_) {
bps_ab = gchar_free_to_qstring(format_size((gint64) conv_item->tx_bytes * 8 / duration, format_size_unit_none|format_size_prefix_si));
@@ -665,6 +696,19 @@ void ConversationTreeWidget::tapDraw(void *conv_hash_ptr)
conv_tree->updateItems();
}
+void ConversationTreeWidget::updateStartTime(bool absolute)
+{
+ headerItem()->setText(CONV_COLUMN_START, absolute
+ ? conv_abs_start_title
+ : conv_column_titles[CONV_COLUMN_START]);
+
+ dataChanged(QModelIndex(), QModelIndex());
+
+ if (topLevelItemCount() > 0) {
+ resizeColumnToContents(CONV_COLUMN_START);
+ }
+}
+
QMap<FilterAction::ActionDirection, conv_direction_e> fad_to_cd_;
void ConversationTreeWidget::initDirectionMap()
diff --git a/ui/qt/conversation_dialog.h b/ui/qt/conversation_dialog.h
index d962684ac3..1aeaf39a7a 100644
--- a/ui/qt/conversation_dialog.h
+++ b/ui/qt/conversation_dialog.h
@@ -38,6 +38,9 @@ public:
double minRelStartTime() { return min_rel_start_time_; }
double maxRelStopTime() { return max_rel_stop_time_; }
+public slots:
+ void updateStartTime(bool absolute);
+
private:
void initDirectionMap();
void updateItems();
diff --git a/ui/qt/traffic_table_dialog.cpp b/ui/qt/traffic_table_dialog.cpp
index ba43afd52f..c81fc1bf2f 100644
--- a/ui/qt/traffic_table_dialog.cpp
+++ b/ui/qt/traffic_table_dialog.cpp
@@ -56,12 +56,14 @@ TrafficTableDialog::TrafficTableDialog(QWidget &parent, CaptureFile &cf, const c
ui(new Ui::TrafficTableDialog),
cap_file_(cf),
file_closed_(false),
- filter_(filter)
+ filter_(filter),
+ nanosecond_timestamps_(false)
{
ui->setupUi(this);
loadGeometry(parent.width(), parent.height() * 3 / 4);
ui->enabledTypesPushButton->setText(tr("%1 Types").arg(table_name));
+ ui->absoluteTimeCheckBox->hide();
setWindowSubtitle(QString("%1s").arg(table_name));
QMenu *copy_menu = new QMenu();
@@ -78,6 +80,10 @@ TrafficTableDialog::TrafficTableDialog(QWidget &parent, CaptureFile &cf, const c
ui->enabledTypesPushButton->setMenu(&traffic_type_menu_);
ui->trafficTableTabWidget->setFocus();
+ if (cf.timestampPrecision() == WTAP_TSPREC_NSEC) {
+ nanosecond_timestamps_ = true;
+ }
+
connect(wsApp, SIGNAL(addressResolutionChanged()), this, SLOT(currentTabChanged()));
connect(wsApp, SIGNAL(addressResolutionChanged()), this, SLOT(updateWidgets()));
connect(ui->trafficTableTabWidget, SIGNAL(currentChanged(int)),
@@ -93,6 +99,11 @@ TrafficTableDialog::~TrafficTableDialog()
delete ui;
}
+bool TrafficTableDialog::absoluteStartTime()
+{
+ return absoluteTimeCheckBox()->isChecked();
+}
+
const QList<int> TrafficTableDialog::defaultProtos() const
{
// Reasonable defaults?
@@ -144,6 +155,11 @@ QCheckBox *TrafficTableDialog::nameResolutionCheckBox() const
return ui->nameResolutionCheckBox;
}
+QCheckBox *TrafficTableDialog::absoluteTimeCheckBox() const
+{
+ return ui->absoluteTimeCheckBox;
+}
+
QPushButton *TrafficTableDialog::enabledTypesPushButton() const
{
return ui->enabledTypesPushButton;
diff --git a/ui/qt/traffic_table_dialog.h b/ui/qt/traffic_table_dialog.h
index 5abe5b2a24..9d46c77906 100644
--- a/ui/qt/traffic_table_dialog.h
+++ b/ui/qt/traffic_table_dialog.h
@@ -103,6 +103,8 @@ signals:
class TrafficTableDialog : public WiresharkDialog
{
Q_OBJECT
+ Q_PROPERTY(bool absolute_start_time READ absoluteStartTime)
+ Q_PROPERTY(bool nanosecond_timestamps READ nanosecondTimestamps)
public:
/** Create a new conversation window.
@@ -115,6 +117,16 @@ public:
explicit TrafficTableDialog(QWidget &parent, CaptureFile &cf, const char *filter = NULL, const QString &table_name = tr("Unknown"));
~TrafficTableDialog();
+ /** Use absolute start times.
+ * @return true if the "Absolute start time" checkbox is checked, false otherwise.
+ */
+ bool absoluteStartTime();
+
+ /** Use nanosecond timestamps.
+ * @return true if the current capture file uses nanosecond timestamps, false otherwise.
+ */
+ bool nanosecondTimestamps() { return nanosecond_timestamps_; }
+
public slots:
signals:
@@ -143,6 +155,7 @@ protected:
QTabWidget *trafficTableTabWidget() const;
QCheckBox *displayFilterCheckBox() const;
QCheckBox *nameResolutionCheckBox() const;
+ QCheckBox *absoluteTimeCheckBox() const;
QPushButton *enabledTypesPushButton() const;
protected slots:
@@ -151,6 +164,7 @@ protected slots:
private:
QString window_name_;
+ bool nanosecond_timestamps_;
QList<QVariant> curTreeRowData(int row) const;
diff --git a/ui/qt/traffic_table_dialog.ui b/ui/qt/traffic_table_dialog.ui
index b10dd41bac..11fe478282 100644
--- a/ui/qt/traffic_table_dialog.ui
+++ b/ui/qt/traffic_table_dialog.ui
@@ -15,7 +15,7 @@
<widget class="QTabWidget" name="trafficTableTabWidget"/>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,1,0">
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0,1,0">
<item>
<widget class="QCheckBox" name="nameResolutionCheckBox">
<property name="toolTip">
@@ -50,6 +50,29 @@
</widget>
</item>
<item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="absoluteTimeCheckBox">
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Show absolute times in the start time column.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Absolute start time</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -83,6 +106,7 @@
</item>
</layout>
</widget>
+ <resources/>
<connections>
<connection>
<sender>buttonBox</sender>
diff --git a/ui/traffic_table_ui.c b/ui/traffic_table_ui.c
index fb37ab74c6..69771b0c10 100644
--- a/ui/traffic_table_ui.c
+++ b/ui/traffic_table_ui.c
@@ -65,6 +65,7 @@ const char *conv_column_titles[CONV_NUM_COLUMNS] = {
const char *conv_conn_a_title = "Connection A";
const char *conv_conn_b_title = "Connection B";
+const char *conv_abs_start_title = "Abs Start";
const char *endp_column_titles[ENDP_NUM_COLUMNS] = {
"Address",
diff --git a/ui/traffic_table_ui.h b/ui/traffic_table_ui.h
index 3edf13b0fd..66e711a53a 100644
--- a/ui/traffic_table_ui.h
+++ b/ui/traffic_table_ui.h
@@ -54,6 +54,7 @@ typedef enum {
extern const char *conv_column_titles[CONV_NUM_COLUMNS];
extern const char *conv_conn_a_title;
extern const char *conv_conn_b_title;
+extern const char *conv_abs_start_title;
typedef enum
{