diff options
-rw-r--r-- | docbook/release-notes.asciidoc | 8 | ||||
-rw-r--r-- | ui/qt/conversation_dialog.cpp | 137 | ||||
-rw-r--r-- | ui/qt/conversation_dialog.h | 4 | ||||
-rw-r--r-- | ui/qt/endpoint_dialog.cpp | 159 | ||||
-rw-r--r-- | ui/qt/endpoint_dialog.h | 2 | ||||
-rw-r--r-- | ui/qt/main_window_slots.cpp | 1 | ||||
-rw-r--r-- | ui/qt/traffic_table_dialog.cpp | 60 | ||||
-rw-r--r-- | ui/qt/traffic_table_dialog.h | 12 | ||||
-rw-r--r-- | ui/qt/wireshark_application.cpp | 3 | ||||
-rw-r--r-- | ui/qt/wireshark_application.h | 1 |
10 files changed, 217 insertions, 170 deletions
diff --git a/docbook/release-notes.asciidoc b/docbook/release-notes.asciidoc index 313f921b53..43a09df9ed 100644 --- a/docbook/release-notes.asciidoc +++ b/docbook/release-notes.asciidoc @@ -28,6 +28,14 @@ since version 2.1.0: * Added -d option for Decode As support in Wireshark (mimics TShark functionality) +* The Qt UI, GTK+ UI, and TShark can now export packets as JSON. + TShark can additionally export packets as Elasticsearch-compatible + JSON. +* The Qt UI now supports the -j, -J, and -l flags. The -m flag is now + deprecated. +* The Conversations and Endpoints dialogs are more responsive when + viewing large numbers of items. +* The RTP player now allows up to 30 minutes of silence frames. The following features are new (or have been significantly updated) since version 2.0.0: diff --git a/ui/qt/conversation_dialog.cpp b/ui/qt/conversation_dialog.cpp index 9160cb4070..2abc5924c2 100644 --- a/ui/qt/conversation_dialog.cpp +++ b/ui/qt/conversation_dialog.cpp @@ -98,7 +98,7 @@ ConversationDialog::ConversationDialog(QWidget &parent, CaptureFile &cf, int cli fillTypeMenu(conv_protos); updateWidgets(); - itemSelectionChanged(); +// currentTabChanged(); cap_file_.delayedRetapPackets(); } @@ -153,8 +153,6 @@ bool ConversationDialog::addTrafficTable(register_ct_t* table) trafficTableTabWidget()->addTab(conv_tree, table_name); - connect(conv_tree, SIGNAL(itemSelectionChanged()), - this, SLOT(itemSelectionChanged())); connect(conv_tree, SIGNAL(titleChanged(QWidget*,QString)), this, SLOT(setTabText(QWidget*,QString))); connect(conv_tree, SIGNAL(filterAction(QString,FilterAction::Action,FilterAction::ActionType)), @@ -252,7 +250,7 @@ void ConversationDialog::graphTcp() openTcpStreamGraph(GRAPH_TSEQ_TCPTRACE); } -void ConversationDialog::itemSelectionChanged() +void ConversationDialog::currentTabChanged() { bool copy_enable = trafficTableTabWidget()->currentWidget() ? true : false; bool follow_enable = false, graph_enable = false; @@ -274,6 +272,8 @@ void ConversationDialog::itemSelectionChanged() copy_bt_->setEnabled(copy_enable); follow_bt_->setEnabled(follow_enable); graph_bt_->setEnabled(graph_enable); + + TrafficTableDialog::currentTabChanged(); } void ConversationDialog::on_displayFilterCheckBox_toggled(bool checked) @@ -320,70 +320,63 @@ static const char *bps_na_ = UTF8_EM_DASH; class ConversationTreeWidgetItem : public TrafficTableTreeWidgetItem { public: - ConversationTreeWidgetItem(QTreeWidget *tree, GArray *conv_array, guint conv_idx) : - TrafficTableTreeWidgetItem(tree), + ConversationTreeWidgetItem(GArray *conv_array, guint conv_idx, bool *resolve_names_ptr) : + TrafficTableTreeWidgetItem(NULL), conv_array_(conv_array), conv_idx_(conv_idx), - last_packets_(0) + resolve_names_ptr_(resolve_names_ptr) {} conv_item_t *convItem() { return &g_array_index(conv_array_, conv_item_t, conv_idx_); } - // Set column text to its cooked representation. - void update(gboolean resolve_names, bool force) { - conv_item_t *conv_item = &g_array_index(conv_array_, conv_item_t, conv_idx_); - char *src_addr, *dst_addr, *src_port, *dst_port; - - if (!conv_item) { - return; - } - - quint64 packets = conv_item->tx_frames + conv_item->rx_frames; - if (!force && last_packets_ == packets) { - return; - } - - src_addr = get_conversation_address(NULL, &conv_item->src_address, resolve_names); - dst_addr = get_conversation_address(NULL, &conv_item->dst_address, resolve_names); - src_port = get_conversation_port(NULL, conv_item->src_port, conv_item->ptype, resolve_names); - dst_port = get_conversation_port(NULL, conv_item->dst_port, conv_item->ptype, resolve_names); - setText(CONV_COLUMN_SRC_ADDR, src_addr); - setText(CONV_COLUMN_SRC_PORT, src_port); - setText(CONV_COLUMN_DST_ADDR, dst_addr); - setText(CONV_COLUMN_DST_PORT, dst_port); - wmem_free(NULL, src_addr); - wmem_free(NULL, dst_addr); - wmem_free(NULL, src_port); - wmem_free(NULL, dst_port); - - double duration = nstime_to_sec(&conv_item->stop_time) - nstime_to_sec(&conv_item->start_time); - QString col_str, bps_ab = bps_na_, bps_ba = bps_na_; - - col_str = QString("%L1").arg(packets); - setText(CONV_COLUMN_PACKETS, col_str); - col_str = gchar_free_to_qstring(format_size(conv_item->tx_bytes + conv_item->rx_bytes, format_size_unit_none|format_size_prefix_si)); - setText(CONV_COLUMN_BYTES, col_str); - col_str = QString("%L1").arg(conv_item->tx_frames); - setText(CONV_COLUMN_PKT_AB, QString::number(conv_item->tx_frames)); - col_str = gchar_free_to_qstring(format_size(conv_item->tx_bytes, format_size_unit_none|format_size_prefix_si)); - setText(CONV_COLUMN_BYTES_AB, col_str); - col_str = QString("%L1").arg(conv_item->rx_frames); - setText(CONV_COLUMN_PKT_BA, QString::number(conv_item->rx_frames)); - col_str = gchar_free_to_qstring(format_size(conv_item->rx_bytes, format_size_unit_none|format_size_prefix_si)); - setText(CONV_COLUMN_BYTES_BA, col_str); - setText(CONV_COLUMN_START, QString::number(nstime_to_sec(&conv_item->start_time), 'f', 9)); - setText(CONV_COLUMN_DURATION, QString::number(duration, 'f', 6)); - 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)); - bps_ba = gchar_free_to_qstring(format_size((gint64) conv_item->rx_bytes * 8 / duration, format_size_unit_none|format_size_prefix_si)); + virtual QVariant data(int column, int role) const { + if (role == Qt::DisplayRole) { + // Column text cooked representation. + conv_item_t *conv_item = &g_array_index(conv_array_, conv_item_t, conv_idx_); + if (!conv_item) return QVariant(); + + bool resolve_names = false; + if (resolve_names_ptr_ && *resolve_names_ptr_) resolve_names = true; + double duration = nstime_to_sec(&conv_item->stop_time) - nstime_to_sec(&conv_item->start_time); + QString bps_ab = bps_na_, bps_ba = bps_na_; + + switch (column) { + case CONV_COLUMN_PACKETS: + return QString("%L1").arg(conv_item->tx_frames + conv_item->rx_frames); + case CONV_COLUMN_BYTES: + return gchar_free_to_qstring(format_size(conv_item->tx_bytes + conv_item->rx_bytes, format_size_unit_none|format_size_prefix_si)); + case CONV_COLUMN_PKT_AB: + return QString("%L1").arg(conv_item->tx_frames); + case CONV_COLUMN_BYTES_AB: + return gchar_free_to_qstring(format_size(conv_item->tx_bytes, format_size_unit_none|format_size_prefix_si)); + case CONV_COLUMN_PKT_BA: + return QString("%L1").arg(conv_item->rx_frames); + 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); + case CONV_COLUMN_DURATION: + return QString::number(duration, 'f', 6); + 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)); + } + return bps_ab; + case CONV_COLUMN_BPS_BA: + if (duration > min_bw_calc_duration_) { + bps_ba = gchar_free_to_qstring(format_size((gint64) conv_item->rx_bytes * 8 / duration, format_size_unit_none|format_size_prefix_si)); + } + return bps_ba; + default: + return colData(column, resolve_names).toString(); + } } - setText(CONV_COLUMN_BPS_AB, bps_ab); - setText(CONV_COLUMN_BPS_BA, bps_ba); - last_packets_ = packets; + return QTreeWidgetItem::data(column, role); } + // Column text raw representation. // Return a QString, qulonglong, double, or invalid QVariant representing the raw column data. QVariant colData(int col, bool resolve_names) const { conv_item_t *conv_item = &g_array_index(conv_array_, conv_item_t, conv_idx_); @@ -507,7 +500,7 @@ public: private: GArray *conv_array_; guint conv_idx_; - quint64 last_packets_; + bool *resolve_names_ptr_; }; // ConversationTreeWidget @@ -517,6 +510,7 @@ ConversationTreeWidget::ConversationTreeWidget(QWidget *parent, register_ct_t* t TrafficTableTreeWidget(parent, table) { setColumnCount(CONV_NUM_COLUMNS); + setUniformRowHeights(true); for (int i = 0; i < CONV_NUM_COLUMNS; i++) { headerItem()->setText(i, conv_column_titles[i]); @@ -608,7 +602,7 @@ ConversationTreeWidget::ConversationTreeWidget(QWidget *parent, register_ct_t* t connect(fa, SIGNAL(triggered()), this, SLOT(filterActionTriggered())); } - updateItems(false); + updateItems(); } ConversationTreeWidget::~ConversationTreeWidget() { @@ -632,7 +626,7 @@ void ConversationTreeWidget::tapDraw(void *conv_hash_ptr) ConversationTreeWidget *conv_tree = qobject_cast<ConversationTreeWidget *>((ConversationTreeWidget *)hash->user_data); if (!conv_tree) return; - conv_tree->updateItems(false); + conv_tree->updateItems(); } QMap<FilterAction::ActionDirection, conv_direction_e> fad_to_cd_; @@ -654,7 +648,8 @@ void ConversationTreeWidget::initDirectionMap() fad_to_cd_[FilterAction::ActionDirectionAnyFromB] = CONV_DIR_ANY_FROM_B; } -void ConversationTreeWidget::updateItems(bool force) { +void ConversationTreeWidget::updateItems() { + bool resize = topLevelItemCount() < resizeThreshold(); title_ = proto_get_protocol_short_name(find_protocol_by_id(get_conversation_proto_id(table_))); if (hash_.conv_array && hash_.conv_array->len > 0) { @@ -667,9 +662,11 @@ void ConversationTreeWidget::updateItems(bool force) { } setSortingEnabled(false); + + QList<QTreeWidgetItem *>new_items; for (int i = topLevelItemCount(); i < (int) hash_.conv_array->len; i++) { - ConversationTreeWidgetItem *ctwi = new ConversationTreeWidgetItem(this, hash_.conv_array, i); - addTopLevelItem(ctwi); + ConversationTreeWidgetItem *ctwi = new ConversationTreeWidgetItem(hash_.conv_array, i, &resolve_names_); + new_items << ctwi; for (int col = 0; col < columnCount(); col++) { switch (col) { @@ -682,16 +679,14 @@ void ConversationTreeWidget::updateItems(bool force) { } } } - QTreeWidgetItemIterator iter(this); - while (*iter) { - ConversationTreeWidgetItem *ci = static_cast<ConversationTreeWidgetItem *>(*iter); - ci->update(resolve_names_, force); - ++iter; - } + addTopLevelItems(new_items); + setSortingEnabled(true); - for (int col = 0; col < columnCount(); col++) { - resizeColumnToContents(col); + if (resize) { + for (int col = 0; col < columnCount(); col++) { + resizeColumnToContents(col); + } } } diff --git a/ui/qt/conversation_dialog.h b/ui/qt/conversation_dialog.h index 354eb89d5d..6e7abf5ca6 100644 --- a/ui/qt/conversation_dialog.h +++ b/ui/qt/conversation_dialog.h @@ -38,7 +38,7 @@ public: private: void initDirectionMap(); - void updateItems(bool force); + void updateItems(); private slots: void filterActionTriggered(); @@ -75,7 +75,7 @@ private: conv_item_t *currentConversation(); private slots: - void itemSelectionChanged(); + void currentTabChanged(); void on_displayFilterCheckBox_toggled(bool checked); void followStream(); void graphTcp(); diff --git a/ui/qt/endpoint_dialog.cpp b/ui/qt/endpoint_dialog.cpp index e4fd6b7f77..2610e01a3a 100644 --- a/ui/qt/endpoint_dialog.cpp +++ b/ui/qt/endpoint_dialog.cpp @@ -83,11 +83,12 @@ EndpointDialog::EndpointDialog(QWidget &parent, CaptureFile &cf, int cli_proto_i fillTypeMenu(endp_protos); - updateWidgets(); #ifdef HAVE_GEOIP tabChanged(); #endif - itemSelectionChanged(); + + updateWidgets(); +// currentTabChanged(); cap_file_.delayedRetapPackets(); } @@ -140,8 +141,6 @@ bool EndpointDialog::addTrafficTable(register_ct_t *table) trafficTableTabWidget()->addTab(endp_tree, table_name); - connect(endp_tree, SIGNAL(itemSelectionChanged()), - this, SLOT(itemSelectionChanged())); connect(endp_tree, SIGNAL(titleChanged(QWidget*,QString)), this, SLOT(setTabText(QWidget*,QString))); connect(endp_tree, SIGNAL(filterAction(QString,FilterAction::Action,FilterAction::ActionType)), @@ -217,80 +216,56 @@ static const char *geoip_none_ = UTF8_EM_DASH; class EndpointTreeWidgetItem : public TrafficTableTreeWidgetItem { public: - EndpointTreeWidgetItem(QTreeWidget *tree, GArray *conv_array, guint conv_idx) : - TrafficTableTreeWidgetItem(tree), + EndpointTreeWidgetItem(GArray *conv_array, guint conv_idx, bool *resolve_names_ptr) : + TrafficTableTreeWidgetItem(NULL), conv_array_(conv_array), conv_idx_(conv_idx), - last_packets_(0) + resolve_names_ptr_(resolve_names_ptr) {} hostlist_talker_t *hostlistTalker() { return &g_array_index(conv_array_, hostlist_talker_t, conv_idx_); } - // Set column text to its cooked representation. - void update(gboolean resolve_names, bool force) { - hostlist_talker_t *endp_item = &g_array_index(conv_array_, hostlist_talker_t, conv_idx_); - char *addr_str, *port_str; - - if (!endp_item) { - return; - } - - quint64 packets = endp_item->tx_frames + endp_item->rx_frames; - if (!force && last_packets_ == packets) { - return; - } - - addr_str = get_conversation_address(NULL, &endp_item->myaddress, resolve_names); - port_str = get_conversation_port(NULL, endp_item->port, endp_item->ptype, resolve_names); - setText(ENDP_COLUMN_ADDR, addr_str); - setText(ENDP_COLUMN_PORT, port_str); - wmem_free(NULL, addr_str); - wmem_free(NULL, port_str); - - QString col_str; - - col_str = QString("%L1").arg(packets); - setText(ENDP_COLUMN_PACKETS, col_str); - col_str = gchar_free_to_qstring(format_size(endp_item->tx_bytes + endp_item->rx_bytes, format_size_unit_none|format_size_prefix_si)); - setText(ENDP_COLUMN_BYTES, col_str); - col_str = QString("%L1").arg(endp_item->tx_frames); - setText(ENDP_COLUMN_PKT_AB, QString::number(endp_item->tx_frames)); - col_str = gchar_free_to_qstring(format_size(endp_item->tx_bytes, format_size_unit_none|format_size_prefix_si)); - setText(ENDP_COLUMN_BYTES_AB, col_str); - col_str = QString("%L1").arg(endp_item->rx_frames); - setText(ENDP_COLUMN_PKT_BA, QString::number(endp_item->rx_frames)); - col_str = gchar_free_to_qstring(format_size(endp_item->rx_bytes, format_size_unit_none|format_size_prefix_si)); - setText(ENDP_COLUMN_BYTES_BA, col_str); - last_packets_ = packets; - + virtual QVariant data(int column, int role) const { + if (role == Qt::DisplayRole) { + // Column text cooked representation. + hostlist_talker_t *endp_item = &g_array_index(conv_array_, hostlist_talker_t, conv_idx_); + + bool resolve_names = false; + if (resolve_names_ptr_ && *resolve_names_ptr_) resolve_names = true; + switch (column) { + case ENDP_COLUMN_PACKETS: + return QString("%L1").arg(endp_item->tx_frames + endp_item->rx_frames); + case ENDP_COLUMN_BYTES: + return gchar_free_to_qstring(format_size(endp_item->tx_bytes + endp_item->rx_bytes, format_size_unit_none|format_size_prefix_si)); + case ENDP_COLUMN_PKT_AB: + return QString("%L1").arg(endp_item->tx_frames); + case ENDP_COLUMN_BYTES_AB: + return gchar_free_to_qstring(format_size(endp_item->tx_bytes, format_size_unit_none|format_size_prefix_si)); + case ENDP_COLUMN_PKT_BA: + return QString("%L1").arg(endp_item->rx_frames); + case ENDP_COLUMN_BYTES_BA: + return gchar_free_to_qstring(format_size(endp_item->rx_bytes, format_size_unit_none|format_size_prefix_si)); #ifdef HAVE_GEOIP - /* Filled in from the GeoIP config, if any */ - EndpointTreeWidget *ep_tree = qobject_cast<EndpointTreeWidget *>(treeWidget()); - if (ep_tree) { - for (int col = ENDP_NUM_COLUMNS; col < ep_tree->columnCount(); col++) { - char *col_text = NULL; - foreach (unsigned db, ep_tree->columnToDb(col)) { - if (endp_item->myaddress.type == AT_IPv4) { - col_text = geoip_db_lookup_ipv4(db, pntoh32(endp_item->myaddress.data), NULL); - } else if (endp_item->myaddress.type == AT_IPv6) { - const struct e_in6_addr *addr = (const struct e_in6_addr *) endp_item->myaddress.data; - col_text = geoip_db_lookup_ipv6(db, *addr, NULL); - } - if (col_text) { - break; - } - } - setText(col, col_text ? col_text : geoip_none_); - wmem_free(NULL, col_text); + default: + { + QString geoip_str = colData(column, resolve_names, true).toString(); + if (geoip_str.isEmpty()) geoip_str = geoip_none_; + return geoip_str; } - } +#else + default: + return colData(column, resolve_names, true); #endif + } + } + return QTreeWidgetItem::data(column, role); } + // Column text raw representation. // Return a string, qulonglong, double, or invalid QVariant representing the raw column data. - QVariant colData(int col, bool resolve_names) const { + QVariant colData(int col, bool resolve_names, bool strings_only) const { hostlist_talker_t *endp_item = &g_array_index(conv_array_, hostlist_talker_t, conv_idx_); if (!endp_item) { @@ -329,24 +304,42 @@ public: #ifdef HAVE_GEOIP default: { + QString geoip_str; + /* Filled in from the GeoIP config, if any */ + EndpointTreeWidget *ep_tree = qobject_cast<EndpointTreeWidget *>(treeWidget()); + if (!ep_tree) return geoip_str; + foreach (unsigned db, ep_tree->columnToDb(col)) { + if (endp_item->myaddress.type == AT_IPv4) { + geoip_str = geoip_db_lookup_ipv4(db, pntoh32(endp_item->myaddress.data), NULL); + } else if (endp_item->myaddress.type == AT_IPv6) { + const struct e_in6_addr *addr = (const struct e_in6_addr *) endp_item->myaddress.data; + geoip_str = geoip_db_lookup_ipv6(db, *addr, NULL); + } + if (!geoip_str.isEmpty()) { + break; + } + } + + if (strings_only) return geoip_str; + bool ok; - double dval = text(col).toDouble(&ok); + double dval = geoip_str.toDouble(&ok); if (ok) { // Assume lat / lon return dval; } - qulonglong ullval = text(col).toULongLong(&ok); + qulonglong ullval = geoip_str.toULongLong(&ok); if (ok) { // Assume uint return ullval; } - qlonglong llval = text(col).toLongLong(&ok); + qlonglong llval = geoip_str.toLongLong(&ok); if (ok) { // Assume int return llval; } - return text(col); + return geoip_str; break; } #else @@ -355,6 +348,7 @@ public: #endif } } + virtual QVariant colData(int col, bool resolve_names) const { return colData(col, resolve_names, false); } bool operator< (const QTreeWidgetItem &other) const { @@ -411,7 +405,7 @@ public: private: GArray *conv_array_; guint conv_idx_; - quint64 last_packets_; + bool *resolve_names_ptr_; }; // @@ -426,6 +420,7 @@ EndpointTreeWidget::EndpointTreeWidget(QWidget *parent, register_ct_t *table) : #endif { setColumnCount(ENDP_NUM_COLUMNS); + setUniformRowHeights(true); for (int i = 0; i < ENDP_NUM_COLUMNS; i++) { headerItem()->setText(i, endp_column_titles[i]); @@ -512,7 +507,7 @@ EndpointTreeWidget::EndpointTreeWidget(QWidget *parent, register_ct_t *table) : connect(fa, SIGNAL(triggered()), this, SLOT(filterActionTriggered())); } - updateItems(false); + updateItems(); } @@ -537,11 +532,12 @@ void EndpointTreeWidget::tapDraw(void *conv_hash_ptr) EndpointTreeWidget *endp_tree = qobject_cast<EndpointTreeWidget *>((EndpointTreeWidget *)hash->user_data); if (!endp_tree) return; - endp_tree->updateItems(false); + endp_tree->updateItems(); } -void EndpointTreeWidget::updateItems(bool force) +void EndpointTreeWidget::updateItems() { + bool resize = topLevelItemCount() < resizeThreshold(); title_ = proto_get_protocol_short_name(find_protocol_by_id(get_conversation_proto_id(table_))); if (hash_.conv_array && hash_.conv_array->len > 0) { @@ -567,9 +563,11 @@ void EndpointTreeWidget::updateItems(bool force) #endif setSortingEnabled(false); + + QList<QTreeWidgetItem *>new_items; for (int i = topLevelItemCount(); i < (int) hash_.conv_array->len; i++) { - EndpointTreeWidgetItem *etwi = new EndpointTreeWidgetItem(this, hash_.conv_array, i); - addTopLevelItem(etwi); + EndpointTreeWidgetItem *etwi = new EndpointTreeWidgetItem(hash_.conv_array, i, &resolve_names_); + new_items << etwi; for (int col = 0; col < columnCount(); col++) { if (col != ENDP_COLUMN_ADDR && col < ENDP_NUM_COLUMNS) { @@ -577,16 +575,13 @@ void EndpointTreeWidget::updateItems(bool force) } } } - QTreeWidgetItemIterator iter(this); - while (*iter) { - EndpointTreeWidgetItem *ei = static_cast<EndpointTreeWidgetItem *>(*iter); - ei->update(resolve_names_, force); - ++iter; - } + addTopLevelItems(new_items); setSortingEnabled(true); - for (int col = 0; col < columnCount(); col++) { - resizeColumnToContents(col); + if (resize) { + for (int col = 0; col < columnCount(); col++) { + resizeColumnToContents(col); + } } } diff --git a/ui/qt/endpoint_dialog.h b/ui/qt/endpoint_dialog.h index d338ea7a5b..fdf2f22d74 100644 --- a/ui/qt/endpoint_dialog.h +++ b/ui/qt/endpoint_dialog.h @@ -53,7 +53,7 @@ private: #endif private: - void updateItems(bool force); + void updateItems(); private slots: void filterActionTriggered(); diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp index d2af1ca3d3..ea01582468 100644 --- a/ui/qt/main_window_slots.cpp +++ b/ui/qt/main_window_slots.cpp @@ -2251,6 +2251,7 @@ void MainWindow::setNameResolution() if (packet_list_) { packet_list_->resetColumns(); } + wsApp->emitAppSignal(WiresharkApplication::NameResolutionChanged); } void MainWindow::on_actionViewNameResolutionPhysical_triggered() diff --git a/ui/qt/traffic_table_dialog.cpp b/ui/qt/traffic_table_dialog.cpp index 727f9ca5cd..ba43afd52f 100644 --- a/ui/qt/traffic_table_dialog.cpp +++ b/ui/qt/traffic_table_dialog.cpp @@ -25,10 +25,7 @@ #include <epan/addr_resolv.h> #include <epan/prefs.h> -//#include <epan/dissectors/packet-tcp.h> - #include "ui/recent.h" -//#include "ui/tap-tcp-stream.h" #include "progress_frame.h" #include "wireshark_application.h" @@ -50,7 +47,7 @@ // - Add "copy" items to the menu. // Bugs: -// - Name resolution doesn't do anything if its preference is disabled. +// - Tabs and menu items don't always end up in the same order. // - Columns don't resize correctly. // - Closing the capture file clears conversation data. @@ -79,11 +76,12 @@ TrafficTableDialog::TrafficTableDialog(QWidget &parent, CaptureFile &cf, const c copy_bt_->setMenu(copy_menu); ui->enabledTypesPushButton->setMenu(&traffic_type_menu_); - ui->nameResolutionCheckBox->setChecked(gbl_resolv_flags.network_name); ui->trafficTableTabWidget->setFocus(); + connect(wsApp, SIGNAL(addressResolutionChanged()), this, SLOT(currentTabChanged())); + connect(wsApp, SIGNAL(addressResolutionChanged()), this, SLOT(updateWidgets())); connect(ui->trafficTableTabWidget, SIGNAL(currentChanged(int)), - this, SLOT(itemSelectionChanged())); + this, SLOT(currentTabChanged())); connect(&cap_file_, SIGNAL(captureFileRetapStarted()), this, SLOT(retapStarted())); connect(&cap_file_, SIGNAL(captureFileRetapFinished()), @@ -151,9 +149,29 @@ QPushButton *TrafficTableDialog::enabledTypesPushButton() const return ui->enabledTypesPushButton; } +void TrafficTableDialog::currentTabChanged() +{ + bool has_resolution = false; + TrafficTableTreeWidget *cur_tree = qobject_cast<TrafficTableTreeWidget *>(ui->trafficTableTabWidget->currentWidget()); + if (cur_tree) has_resolution = cur_tree->hasNameResolution(); + + bool block = blockSignals(true); + if (has_resolution) { + // Don't change the actual setting. + ui->nameResolutionCheckBox->setEnabled(true); + } else { + ui->nameResolutionCheckBox->setChecked(false); + ui->nameResolutionCheckBox->setEnabled(false); + } + blockSignals(block); + + if (cur_tree) cur_tree->setNameResolutionEnabled(ui->nameResolutionCheckBox->isChecked()); +} + void TrafficTableDialog::on_nameResolutionCheckBox_toggled(bool) { - updateWidgets(); + QWidget *cw = ui->trafficTableTabWidget->currentWidget(); + if (cw) cw->update(); } void TrafficTableDialog::on_displayFilterCheckBox_toggled(bool checked) @@ -225,12 +243,12 @@ void TrafficTableDialog::updateWidgets() QWidget *cur_w = ui->trafficTableTabWidget->currentWidget(); ui->trafficTableTabWidget->setUpdatesEnabled(false); ui->trafficTableTabWidget->clear(); + foreach (QAction *ca, traffic_type_menu_.actions()) { int proto_id = ca->data().value<int>(); if (proto_id_to_tree_.contains(proto_id) && ca->isChecked()) { ui->trafficTableTabWidget->addTab(proto_id_to_tree_[proto_id], proto_id_to_tree_[proto_id]->trafficTreeTitle()); - proto_id_to_tree_[proto_id]->setNameResolutionEnabled(ui->nameResolutionCheckBox->isChecked()); } } ui->trafficTableTabWidget->setCurrentWidget(cur_w); @@ -293,7 +311,6 @@ void TrafficTableDialog::copyAsYaml() wsApp->clipboard()->setText(stream.readAll()); } - TrafficTableTreeWidget::TrafficTableTreeWidget(QWidget *parent, register_ct_t *table) : QTreeWidget(parent), table_(table), @@ -335,11 +352,32 @@ QList<QVariant> TrafficTableTreeWidget::rowData(int row) const return row_data; } +// True if name resolution is enabled for the table's address type, false +// otherwise. +// XXX We need a more reliable method of fetching the address type(s) for +// a table. +bool TrafficTableTreeWidget::hasNameResolution() const +{ + if (!table_) return false; + + QStringList mac_protos = QStringList() << "eth" << "tr"<< "wlan"; + QStringList net_protos = QStringList() << "ip" << "ipv6" << "jxta" + << "mptcp" << "rsvp" << "sctp" + << "tcp" << "udp"; + + QString table_proto = proto_get_protocol_filter_name(get_conversation_proto_id(table_)); + + if (mac_protos.contains(table_proto) && gbl_resolv_flags.mac_name) return true; + if (net_protos.contains(table_proto) && gbl_resolv_flags.network_name) return true; + + return false; +} + void TrafficTableTreeWidget::setNameResolutionEnabled(bool enable) { if (resolve_names_ != enable) { resolve_names_ = enable; - updateItems(true); + updateItems(); } } @@ -357,7 +395,7 @@ void TrafficTableTreeWidget::contextMenuEvent(QContextMenuEvent *event) void TrafficTableTreeWidget::updateItemsForSettingChange() { - updateItems(true); + updateItems(); } /* diff --git a/ui/qt/traffic_table_dialog.h b/ui/qt/traffic_table_dialog.h index db53c8931a..5abe5b2a24 100644 --- a/ui/qt/traffic_table_dialog.h +++ b/ui/qt/traffic_table_dialog.h @@ -68,6 +68,8 @@ public: // Passing -1 returns titles. QList<QVariant> rowData(int row) const; + bool hasNameResolution() const; + public slots: void setNameResolutionEnabled(bool enable); @@ -82,10 +84,12 @@ protected: bool resolve_names_; QMenu ctx_menu_; + // When adding rows, resize to contents up to this number. + int resizeThreshold() const { return 200; } void contextMenuEvent(QContextMenuEvent *event); private: - virtual void updateItems(bool) {} + virtual void updateItems() {} private slots: // Updates all items @@ -142,13 +146,15 @@ protected: QPushButton *enabledTypesPushButton() const; protected slots: - virtual void itemSelectionChanged() {} + virtual void currentTabChanged(); void updateWidgets(); private: - QList<QVariant> curTreeRowData(int row) const; QString window_name_; + QList<QVariant> curTreeRowData(int row) const; + + private slots: void on_nameResolutionCheckBox_toggled(bool checked); void on_displayFilterCheckBox_toggled(bool checked); diff --git a/ui/qt/wireshark_application.cpp b/ui/qt/wireshark_application.cpp index 2ddb59af6c..907f99d022 100644 --- a/ui/qt/wireshark_application.cpp +++ b/ui/qt/wireshark_application.cpp @@ -695,6 +695,9 @@ void WiresharkApplication::emitAppSignal(AppSignal signal) case FilterExpressionsChanged: emit filterExpressionsChanged(); break; + case NameResolutionChanged: + emit addressResolutionChanged(); + break; case PreferencesChanged: emit preferencesChanged(); break; diff --git a/ui/qt/wireshark_application.h b/ui/qt/wireshark_application.h index 599cf31b5c..b2adf0a052 100644 --- a/ui/qt/wireshark_application.h +++ b/ui/qt/wireshark_application.h @@ -66,6 +66,7 @@ public: CaptureFilterListChanged, DisplayFilterListChanged, FilterExpressionsChanged, + NameResolutionChanged, PacketDissectionChanged, PreferencesChanged, RecentFilesRead, |