Qt: Rework Resolved Addresses dialog

This is a refactoring/redesign of the "Resolved Addresses" dialog,
allowing for sorting/filtering and searching within the addresses
and ports.

Change-Id: I5071e92ff699323b6c93fc533eeaf92e0db334de
Reviewed-on: https://code.wireshark.org/review/34398
Reviewed-by: Roland Knall <rknall@gmail.com>
Petri-Dish: Roland Knall <rknall@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Roland Knall 2019-08-29 17:30:29 +02:00 committed by Anders Broman
parent b28952afd4
commit 743f8598cd
8 changed files with 613 additions and 394 deletions

View File

@ -94,6 +94,7 @@ set(WIRESHARK_MODEL_HEADERS
models/profile_model.h
models/proto_tree_model.h
models/related_packet_delegate.h
models/resolved_addresses_models.h
models/sparkline_delegate.h
models/supported_protocols_model.h
models/timeline_delegate.h
@ -320,6 +321,7 @@ set(WIRESHARK_MODEL_SRCS
models/profile_model.cpp
models/proto_tree_model.cpp
models/related_packet_delegate.cpp
models/resolved_addresses_models.cpp
models/sparkline_delegate.cpp
models/supported_protocols_model.cpp
models/timeline_delegate.cpp

View File

@ -87,13 +87,21 @@ AStringListListSortFilterProxyModel::AStringListListSortFilterProxyModel(QObject
: QSortFilterProxyModel(parent)
{
filter_ = QString();
type_ = FilterByContains;
types_[-1] = FilterByContains;
}
bool AStringListListSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
QString leftData = sourceModel()->data(left).toStringList().join(",");
QString rightData = sourceModel()->data(right).toStringList().join(",");
QString leftData = left.data().toString();
QString rightData = right.data().toString();
if ( numericColumns_.contains(left.column()) || numericColumns_.contains(right.column() ) )
{
float left = leftData.toFloat();
float right = rightData.toFloat();
return left < right;
}
return leftData.compare(rightData, sortCaseSensitivity()) < 0;
}
@ -104,14 +112,23 @@ void AStringListListSortFilterProxyModel::setFilter(const QString & filter)
invalidateFilter();
}
static bool AContainsB(const QString &a, const QString &b, Qt::CaseSensitivity cs)
static bool AContainsB(const QVariant &a, const QVariant &b, Qt::CaseSensitivity cs)
{
return a.contains(b, cs);
if ( ! a.canConvert(QVariant::String) || ! b.canConvert(QVariant::String) )
return false;
return a.toString().contains(b.toString(), cs);
}
static bool AStartsWithB(const QString &a, const QString &b, Qt::CaseSensitivity cs)
static bool AStartsWithB(const QVariant &a, const QVariant &b, Qt::CaseSensitivity cs)
{
return a.startsWith(b, cs);
if ( ! a.canConvert(QVariant::String) || ! b.canConvert(QVariant::String) )
return false;
return a.toString().startsWith(b.toString(), cs);
}
static bool AIsEquivalentToB(const QVariant &a, const QVariant &b, Qt::CaseSensitivity)
{
return a == b;
}
bool AStringListListSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
@ -125,12 +142,28 @@ bool AStringListListSortFilterProxyModel::filterAcceptsRow(int sourceRow, const
continue;
QModelIndex chkIdx = sourceModel()->index(sourceRow, column, sourceParent);
QString dataString = sourceModel()->data(chkIdx).toString();
QString dataString = chkIdx.data().toString();
/* Default is filter by string a contains string b */
bool (*compareFunc)(const QString&, const QString&, Qt::CaseSensitivity) = AContainsB;
if ( type_ == FilterByStart )
compareFunc = AStartsWithB;
bool (*compareFunc)(const QVariant&, const QVariant&, Qt::CaseSensitivity) = AContainsB;
if ( types_.keys().contains(column) )
{
switch (types_.value(column, FilterByContains))
{
case FilterByStart:
compareFunc = AStartsWithB;
break;
case FilterByEquivalent:
compareFunc = AIsEquivalentToB;
break;
case FilterNone:
return true;
break;
default:
compareFunc = AContainsB;
break;
}
}
if ( compareFunc(dataString, filter_, filterCaseSensitivity()) )
return true;
@ -139,12 +172,20 @@ bool AStringListListSortFilterProxyModel::filterAcceptsRow(int sourceRow, const
return false;
}
void AStringListListSortFilterProxyModel::setFilterType(AStringListListFilterType type)
void AStringListListSortFilterProxyModel::setFilterType(AStringListListFilterType type, int column)
{
if ( type != type_ )
if ( column >= -1 && column < columnCount() )
{
type_ = type;
invalidateFilter();
if ( ! types_.keys().contains(column) )
{
types_.insert(column, type);
invalidateFilter();
}
else if ( types_.keys().contains(column) && type != types_[column] )
{
types_[column] = type;
invalidateFilter();
}
}
}
@ -163,6 +204,49 @@ void AStringListListSortFilterProxyModel::clearColumnsToFilter()
invalidateFilter();
}
void AStringListListSortFilterProxyModel::clearHiddenColumns()
{
hiddenColumns_.clear();
invalidateFilter();
}
void AStringListListSortFilterProxyModel::setColumnToHide(int col)
{
if ( ! hiddenColumns_.contains(col) && col > -1 && sourceModel() && sourceModel()->columnCount() > col )
{
hiddenColumns_ << col;
invalidateFilter();
}
}
bool AStringListListSortFilterProxyModel::filterAcceptsColumn(int sourceColumn, const QModelIndex &sourceParent) const
{
QModelIndex realIndex = sourceModel()->index(0, sourceColumn, sourceParent);
if ( ! realIndex.isValid() )
return false;
if ( hiddenColumns_.contains(sourceColumn) )
return false;
return true;
}
void AStringListListSortFilterProxyModel::clearNumericColumns()
{
numericColumns_.clear();
invalidateFilter();
}
void AStringListListSortFilterProxyModel::setColumnAsNumeric(int col)
{
if ( ! numericColumns_.contains(col) && col > -1 && sourceModel() && sourceModel()->columnCount() > col )
{
numericColumns_ << col;
invalidateFilter();
}
}
AStringListListUrlProxyModel::AStringListListUrlProxyModel(QObject * parent):
QIdentityProxyModel(parent)
{}

View File

@ -50,27 +50,38 @@ public:
enum AStringListListFilterType
{
FilterByContains = 0,
FilterByStart = 1
FilterByStart,
FilterByEquivalent,
FilterNone
};
Q_ENUM(AStringListListFilterType)
explicit AStringListListSortFilterProxyModel(QObject * parent = Q_NULLPTR);
virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
virtual bool filterAcceptsColumn(int column, const QModelIndex &sourceParent) const;
void setFilterType(AStringListListFilterType type);
void setFilterType(AStringListListFilterType type, int column = -1);
void setColumnToFilter(int);
void clearColumnsToFilter();
void clearHiddenColumns();
void setColumnToHide(int col);
void clearNumericColumns();
void setColumnAsNumeric(int col);
public slots:
void setFilter(const QString&);
private:
QString filter_;
AStringListListFilterType type_;
QMap<int, AStringListListFilterType> types_;
QList<int> columnsToFilter_;
QList<int> hiddenColumns_;
QList<int> numericColumns_;
};
class AStringListListUrlProxyModel : public QIdentityProxyModel

View File

@ -0,0 +1,253 @@
/* resolved_addresses_models.cpp
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <ui/qt/models/resolved_addresses_models.h>
#include <glib.h>
#include "file.h"
#include "epan/addr_resolv.h"
#include <wiretap/wtap.h>
extern "C"
{
static void
serv_port_hash_to_qstringlist(gpointer key, gpointer value, gpointer sl_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
serv_port_t *serv_port = (serv_port_t *)value;
guint port = GPOINTER_TO_UINT(key);
QStringList entries;
if (serv_port->tcp_name) entries << QString("%1 %2 tcp").arg(serv_port->tcp_name).arg(port);
if (serv_port->udp_name) entries << QString("%1 %2 udp").arg(serv_port->udp_name).arg(port);
if (serv_port->sctp_name) entries << QString("%1 %2 sctp").arg(serv_port->sctp_name).arg(port);
if (serv_port->dccp_name) entries << QString("%1 %2 dccp").arg(serv_port->dccp_name).arg(port);
if (!entries.isEmpty()) *string_list << entries.join("\n");
}
static void
ipv4_hash_table_resolved_to_qstringlist(gpointer, gpointer value, gpointer sl_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
hashipv4_t *ipv4_hash_table_entry = (hashipv4_t *) value;
if((ipv4_hash_table_entry->flags & NAME_RESOLVED)) {
QString entry = QString("%1\t%2")
.arg(ipv4_hash_table_entry->ip)
.arg(ipv4_hash_table_entry->name);
*string_list << entry;
}
}
static void
ipv6_hash_table_resolved_to_qstringlist(gpointer, gpointer value, gpointer sl_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
hashipv6_t *ipv6_hash_table_entry = (hashipv6_t *) value;
if((ipv6_hash_table_entry->flags & NAME_RESOLVED)) {
QString entry = QString("%1\t%2")
.arg(ipv6_hash_table_entry->ip6)
.arg(ipv6_hash_table_entry->name);
*string_list << entry;
}
}
static void
ipv4_hash_table_to_qstringlist(gpointer key, gpointer value, gpointer sl_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
hashipv4_t *ipv4_hash_table_entry = (hashipv4_t *)value;
guint addr = GPOINTER_TO_UINT(key);
QString entry = QString("Key: 0x%1 IPv4: %2, Name: %3")
.arg(QString::number(addr, 16))
.arg(ipv4_hash_table_entry->ip)
.arg(ipv4_hash_table_entry->name);
*string_list << entry;
}
static void
ipv6_hash_table_to_qstringlist(gpointer key, gpointer value, gpointer sl_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
hashipv6_t *ipv6_hash_table_entry = (hashipv6_t *)value;
guint addr = GPOINTER_TO_UINT(key);
QString entry = QString("Key: 0x%1 IPv4: %2, Name: %3")
.arg(QString::number(addr, 16))
.arg(ipv6_hash_table_entry->ip6)
.arg(ipv6_hash_table_entry->name);
*string_list << entry;
}
static void
eth_hash_to_qstringlist(gpointer, gpointer value, gpointer sl_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
hashether_t* tp = (hashether_t*)value;
QString entry = QString("%1 %2")
.arg(get_hash_ether_hexaddr(tp))
.arg(get_hash_ether_resolved_name(tp));
*string_list << entry;
}
static void
manuf_hash_to_qstringlist(gpointer key, gpointer value, gpointer sl_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
hashmanuf_t *manuf = (hashmanuf_t*)value;
guint eth_as_guint = GPOINTER_TO_UINT(key);
QString entry = QString("%1:%2:%3 %4")
.arg((eth_as_guint >> 16 & 0xff), 2, 16, QChar('0'))
.arg((eth_as_guint >> 8 & 0xff), 2, 16, QChar('0'))
.arg((eth_as_guint & 0xff), 2, 16, QChar('0'))
.arg(get_hash_manuf_resolved_name(manuf));
*string_list << entry;
}
static void
wka_hash_to_qstringlist(gpointer key, gpointer value, gpointer sl_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
gchar *name = (gchar *)value;
guint8 *eth_addr = (guint8*)key;
QString entry = QString("%1:%2:%3:%4:%5:%6 %7")
.arg(eth_addr[0], 2, 16, QChar('0'))
.arg(eth_addr[1], 2, 16, QChar('0'))
.arg(eth_addr[2], 2, 16, QChar('0'))
.arg(eth_addr[3], 2, 16, QChar('0'))
.arg(eth_addr[4], 2, 16, QChar('0'))
.arg(eth_addr[5], 2, 16, QChar('0'))
.arg(name);
*string_list << entry;
}
}
EthernetAddressModel::EthernetAddressModel(QObject * parent):
AStringListListModel(parent)
{
populate();
}
QStringList EthernetAddressModel::headerColumns() const
{
return QStringList() << tr("Type") << tr("Mac Address") << tr("Name");
}
QStringList EthernetAddressModel::filterValues() const
{
return QStringList()
<< tr("All entries")
<< tr("IPv4 Hosts") << tr("IPv4 Hash Table")
<< tr("IPv6 Hosts") << tr("IPv6 Hash Table")
<< tr("Ethernet Addresses") << tr("Ethernet Manufacturers")
<< tr("Ethernet Well-Known Addresses");
}
void EthernetAddressModel::populate()
{
QStringList values;
wmem_map_t *ipv4_hash_table = get_ipv4_hash_table();
if (ipv4_hash_table) {
wmem_map_foreach(ipv4_hash_table, ipv4_hash_table_resolved_to_qstringlist, &values);
foreach(QString line, values)
appendRow(QStringList() << tr("IPv4 Hosts") << line.split(" "));
wmem_map_foreach(ipv4_hash_table, ipv4_hash_table_to_qstringlist, &values);
foreach(QString line, values)
appendRow(QStringList() << tr("IPv4 Hash Table") << line.split(" "));
}
wmem_map_t *ipv6_hash_table = get_ipv6_hash_table();
if (ipv6_hash_table) {
wmem_map_foreach(ipv6_hash_table, ipv6_hash_table_resolved_to_qstringlist, &values);
foreach(QString line, values)
appendRow(QStringList() << tr("IPv6 Hosts") << line.split(" "));
wmem_map_foreach(ipv6_hash_table, ipv6_hash_table_to_qstringlist, &values);
foreach(QString line, values)
appendRow(QStringList() << tr("IPv6 Hash Table") << line.split(" "));
}
wmem_map_t *eth_hashtable = get_eth_hashtable();
if (eth_hashtable)
wmem_map_foreach(eth_hashtable, eth_hash_to_qstringlist, &values);
foreach(QString line, values)
appendRow(QStringList() << tr("Ethernet Addresses") << line.split(" "));
eth_hashtable = get_manuf_hashtable();
if (eth_hashtable)
wmem_map_foreach(eth_hashtable, manuf_hash_to_qstringlist, &values);
foreach(QString line, values)
appendRow(QStringList() << tr("Ethernet Manufacturers") << line.split(" "));
eth_hashtable = get_wka_hashtable();
if (eth_hashtable)
wmem_map_foreach(eth_hashtable, wka_hash_to_qstringlist, &values);
foreach(QString line, values)
appendRow(QStringList() << tr("Ethernet Well-Known Addresses") << line.split(" "));
}
PortsModel::PortsModel(QObject * parent):
AStringListListModel(parent)
{
populate();
}
QStringList PortsModel::filterValues() const
{
return QStringList()
<< tr("All entries") << tr("tcp") << tr("udp") << tr("sctp") << tr("dccp");
}
QStringList PortsModel::headerColumns() const
{
return QStringList() << tr("Name") << tr("Port") << tr("Type");
}
void PortsModel::populate()
{
QStringList values;
wmem_map_t *serv_port_hashtable = get_serv_port_hashtable();
if(serv_port_hashtable){
wmem_map_foreach(serv_port_hashtable, serv_port_hash_to_qstringlist, &values);
}
foreach(QString line, values)
appendRow(QStringList() << line.split(" "));
}
/*
* 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:
*/

View File

@ -0,0 +1,61 @@
/* resolved_addresses_models.h
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef RESOLVED_ADDRESSES_MODELS_H
#define RESOLVED_ADDRESSES_MODELS_H
#include <ui/qt/models/astringlist_list_model.h>
#include <QAbstractListModel>
#include <QSortFilterProxyModel>
class EthernetAddressModel : public AStringListListModel
{
Q_OBJECT
public:
EthernetAddressModel(QObject * parent = Q_NULLPTR);
QStringList filterValues() const;
protected:
QStringList headerColumns() const override;
void populate();
};
class PortsModel : public AStringListListModel
{
Q_OBJECT
public:
PortsModel(QObject * parent = Q_NULLPTR);
QStringList filterValues() const;
protected:
QStringList headerColumns() const override;
void populate();
};
#endif // RESOLVED_ADDRESSES_MODELS_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:
*/

View File

@ -22,150 +22,23 @@
#include <QMenu>
#include <QPushButton>
#include <QTextCursor>
#include <QSortFilterProxyModel>
#include "capture_file.h"
#include "wireshark_application.h"
// To do:
// - We do a *lot* of string copying.
// - We end up with a lot of numeric entries here.
#include <ui/qt/models/astringlist_list_model.h>
#include <ui/qt/models/resolved_addresses_models.h>
extern "C" {
static void
ipv4_hash_table_resolved_to_qstringlist(gpointer, gpointer value, gpointer sl_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
hashipv4_t *ipv4_hash_table_entry = (hashipv4_t *) value;
if((ipv4_hash_table_entry->flags & NAME_RESOLVED)) {
QString entry = QString("%1\t%2")
.arg(ipv4_hash_table_entry->ip)
.arg(ipv4_hash_table_entry->name);
*string_list << entry;
}
}
static void
ipv6_hash_table_resolved_to_qstringlist(gpointer, gpointer value, gpointer sl_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
hashipv6_t *ipv6_hash_table_entry = (hashipv6_t *) value;
if((ipv6_hash_table_entry->flags & NAME_RESOLVED)) {
QString entry = QString("%1\t%2")
.arg(ipv6_hash_table_entry->ip6)
.arg(ipv6_hash_table_entry->name);
*string_list << entry;
}
}
static void
ipv4_hash_table_to_qstringlist(gpointer key, gpointer value, gpointer sl_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
hashipv4_t *ipv4_hash_table_entry = (hashipv4_t *)value;
guint addr = GPOINTER_TO_UINT(key);
QString entry = QString("Key: 0x%1 IPv4: %2, Name: %3")
.arg(QString::number(addr, 16))
.arg(ipv4_hash_table_entry->ip)
.arg(ipv4_hash_table_entry->name);
*string_list << entry;
}
static void
ipv6_hash_table_to_qstringlist(gpointer key, gpointer value, gpointer sl_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
hashipv6_t *ipv6_hash_table_entry = (hashipv6_t *)value;
guint addr = GPOINTER_TO_UINT(key);
QString entry = QString("Key: 0x%1 IPv4: %2, Name: %3")
.arg(QString::number(addr, 16))
.arg(ipv6_hash_table_entry->ip6)
.arg(ipv6_hash_table_entry->name);
*string_list << entry;
}
static void
serv_port_hash_to_qstringlist(gpointer key, gpointer value, gpointer sl_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
serv_port_t *serv_port = (serv_port_t *)value;
guint port = GPOINTER_TO_UINT(key);
QStringList entries;
if (serv_port->tcp_name) entries << QString("%1\t%2/tcp").arg(serv_port->tcp_name).arg(port);
if (serv_port->udp_name) entries << QString("%1\t%2/udp").arg(serv_port->udp_name).arg(port);
if (serv_port->sctp_name) entries << QString("%1\t%2/sctp").arg(serv_port->sctp_name).arg(port);
if (serv_port->dccp_name) entries << QString("%1\t%2/dccp").arg(serv_port->dccp_name).arg(port);
if (!entries.isEmpty()) *string_list << entries.join("\n");
}
static void
eth_hash_to_qstringlist(gpointer, gpointer value, gpointer sl_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
hashether_t* tp = (hashether_t*)value;
QString entry = QString("%1 %2")
.arg(get_hash_ether_hexaddr(tp))
.arg(get_hash_ether_resolved_name(tp));
*string_list << entry;
}
static void
manuf_hash_to_qstringlist(gpointer key, gpointer value, gpointer sl_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
hashmanuf_t *manuf = (hashmanuf_t*)value;
guint eth_as_guint = GPOINTER_TO_UINT(key);
QString entry = QString("%1:%2:%3 %4")
.arg((eth_as_guint >> 16 & 0xff), 2, 16, QChar('0'))
.arg((eth_as_guint >> 8 & 0xff), 2, 16, QChar('0'))
.arg((eth_as_guint & 0xff), 2, 16, QChar('0'))
.arg(get_hash_manuf_resolved_name(manuf));
*string_list << entry;
}
static void
wka_hash_to_qstringlist(gpointer key, gpointer value, gpointer sl_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
gchar *name = (gchar *)value;
guint8 *eth_addr = (guint8*)key;
QString entry = QString("%1:%2:%3:%4:%5:%6 %7")
.arg(eth_addr[0], 2, 16, QChar('0'))
.arg(eth_addr[1], 2, 16, QChar('0'))
.arg(eth_addr[2], 2, 16, QChar('0'))
.arg(eth_addr[3], 2, 16, QChar('0'))
.arg(eth_addr[4], 2, 16, QChar('0'))
.arg(eth_addr[5], 2, 16, QChar('0'))
.arg(name);
*string_list << entry;
}
}
const QString no_entries_ = QObject::tr("No entries.");
const QString entry_count_ = QObject::tr("%1 entries.");
ResolvedAddressesDialog::ResolvedAddressesDialog(QWidget *parent, CaptureFile *capture_file) :
GeometryStateDialog(NULL),
GeometryStateDialog(parent),
ui(new Ui::ResolvedAddressesDialog),
file_name_(tr("[no file]"))
{
ui->setupUi(this);
if (parent) loadGeometry(parent->width() * 2 / 3, parent->height());
setAttribute(Qt::WA_DeleteOnClose, true);
QStringList title_parts = QStringList() << tr("Resolved Addresses");
@ -203,40 +76,39 @@ ResolvedAddressesDialog::ResolvedAddressesDialog(QWidget *parent, CaptureFile *c
}
}
wmem_map_t *ipv4_hash_table = get_ipv4_hash_table();
if (ipv4_hash_table) {
wmem_map_foreach(ipv4_hash_table, ipv4_hash_table_resolved_to_qstringlist, &host_addresses_);
wmem_map_foreach(ipv4_hash_table, ipv4_hash_table_to_qstringlist, &v4_hash_addrs_);
}
wmem_map_t *ipv6_hash_table = get_ipv6_hash_table();
if (ipv6_hash_table) {
wmem_map_foreach(ipv6_hash_table, ipv6_hash_table_resolved_to_qstringlist, &host_addresses_);
wmem_map_foreach(ipv6_hash_table, ipv6_hash_table_to_qstringlist, &v6_hash_addrs_);
}
wmem_map_t *serv_port_hashtable = get_serv_port_hashtable();
if(serv_port_hashtable){
wmem_map_foreach(serv_port_hashtable, serv_port_hash_to_qstringlist, &service_ports_);
}
wmem_map_t *eth_hashtable = get_eth_hashtable();
if (eth_hashtable){
wmem_map_foreach(eth_hashtable, eth_hash_to_qstringlist, &ethernet_addresses_);
}
wmem_map_t *manuf_hashtable = get_manuf_hashtable();
if (manuf_hashtable){
wmem_map_foreach(manuf_hashtable, manuf_hash_to_qstringlist, &ethernet_manufacturers_);
}
wmem_map_t *wka_hashtable = get_wka_hashtable();
if(wka_hashtable){
wmem_map_foreach(wka_hashtable, wka_hash_to_qstringlist, &ethernet_well_known_);
}
fillShowMenu();
fillBlocks();
ethSortModel = new AStringListListSortFilterProxyModel(this);
ethTypeModel = new AStringListListSortFilterProxyModel(this);
EthernetAddressModel * ethModel = new EthernetAddressModel(this);
ethSortModel->setSourceModel(ethModel);
ethSortModel->setColumnToFilter(1);
ethSortModel->setColumnToFilter(2);
ethSortModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
ethTypeModel->setSourceModel(ethSortModel);
ethTypeModel->setColumnToFilter(0);
ethTypeModel->setColumnToHide(0);
ui->tblAddresses->setModel(ethTypeModel);
ui->tblAddresses->resizeColumnsToContents();
ui->tblAddresses->horizontalHeader()->setStretchLastSection(true);
ui->tblAddresses->sortByColumn(1, Qt::AscendingOrder);
ui->cmbDataType->addItems(ethModel->filterValues());
portSortModel = new AStringListListSortFilterProxyModel(this);
portTypeModel = new AStringListListSortFilterProxyModel(this);
PortsModel * portModel = new PortsModel(this);
portSortModel->setSourceModel(portModel);
portSortModel->setColumnAsNumeric(1);
portSortModel->setColumnToFilter(0);
portSortModel->setColumnToFilter(1);
portSortModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
portTypeModel->setSourceModel(portSortModel);
portTypeModel->setColumnToFilter(2);
ui->tblPorts->setModel(portTypeModel);
ui->tblPorts->resizeColumnsToContents();
ui->tblPorts->horizontalHeader()->setStretchLastSection(true);
ui->tblPorts->sortByColumn(1, Qt::AscendingOrder);
ui->cmbPortFilterType->addItems(portModel->filterValues());
}
ResolvedAddressesDialog::~ResolvedAddressesDialog()
@ -244,6 +116,54 @@ ResolvedAddressesDialog::~ResolvedAddressesDialog()
delete ui;
}
void ResolvedAddressesDialog::on_cmbDataType_currentIndexChanged(QString)
{
if ( ! ethSortModel )
return;
QString filter = ui->cmbDataType->currentText();
if ( ui->cmbDataType->currentIndex() == 0 )
{
filter.clear();
ethTypeModel->setFilterType(AStringListListSortFilterProxyModel::FilterNone, 0);
}
else
ethTypeModel->setFilterType(AStringListListSortFilterProxyModel::FilterByEquivalent, 0);
ethTypeModel->setFilter(filter);
}
void ResolvedAddressesDialog::on_txtSearchFilter_textChanged(QString)
{
if ( ! ethSortModel || ui->txtSearchFilter->text().length() < 3 )
return;
ethSortModel->setFilter(ui->txtSearchFilter->text());
}
void ResolvedAddressesDialog::on_cmbPortFilterType_currentIndexChanged(QString)
{
if ( ! portSortModel )
return;
QString filter = ui->cmbPortFilterType->currentText();
if ( ui->cmbPortFilterType->currentIndex() == 0 )
{
filter.clear();
portTypeModel->setFilterType(AStringListListSortFilterProxyModel::FilterNone, 2);
}
else
portTypeModel->setFilterType(AStringListListSortFilterProxyModel::FilterByEquivalent, 2);
portTypeModel->setFilter(filter);
}
void ResolvedAddressesDialog::on_txtPortFilter_textChanged(QString val)
{
if ( ! portSortModel )
return;
portSortModel->setFilter(val);
}
void ResolvedAddressesDialog::changeEvent(QEvent *event)
{
if (0 != event)
@ -252,7 +172,6 @@ void ResolvedAddressesDialog::changeEvent(QEvent *event)
{
case QEvent::LanguageChange:
ui->retranslateUi(this);
fillShowMenu();
fillBlocks();
break;
default:
@ -262,32 +181,6 @@ void ResolvedAddressesDialog::changeEvent(QEvent *event)
QDialog::changeEvent(event);
}
void ResolvedAddressesDialog::fillShowMenu()
{
QPushButton *show_bt = ui->buttonBox->button(QDialogButtonBox::Apply);
show_bt->setText(tr("Show"));
if (!show_bt->menu()) {
show_bt->setMenu(new QMenu(show_bt));
}
QMenu *show_menu = show_bt->menu();
show_menu->clear();
show_menu->addAction(ui->actionAddressesHosts);
show_menu->addAction(ui->actionComment);
show_menu->addAction(ui->actionIPv4HashTable);
show_menu->addAction(ui->actionIPv6HashTable);
show_menu->addAction(ui->actionPortNames);
show_menu->addAction(ui->actionEthernetAddresses);
show_menu->addAction(ui->actionEthernetManufacturers);
show_menu->addAction(ui->actionEthernetWKA);
show_menu->addSeparator();
show_menu->addAction(ui->actionShowAll);
show_menu->addAction(ui->actionHideAll);
}
void ResolvedAddressesDialog::fillBlocks()
{
setUpdatesEnabled(false);
@ -309,169 +202,10 @@ void ResolvedAddressesDialog::fillBlocks()
ui->plainTextEdit->appendPlainText(lines);
}
if (ui->actionAddressesHosts->isChecked()) {
lines = "\n";
lines.append(tr("# Hosts\n#\n# "));
if (!host_addresses_.isEmpty()) {
lines.append(entry_count_.arg(host_addresses_.length()));
lines.append("\n\n");
lines.append(host_addresses_.join("\n"));
} else {
lines.append(no_entries_);
}
ui->plainTextEdit->appendPlainText(lines);
}
if (ui->actionIPv4HashTable->isChecked()) {
lines = "\n";
lines.append(tr("# IPv4 Hash Table\n#\n# "));
if (!v4_hash_addrs_.isEmpty()) {
lines.append(entry_count_.arg(v4_hash_addrs_.length()));
lines.append(tr("\n\n"));
lines.append(v4_hash_addrs_.join("\n"));
} else {
lines.append(no_entries_);
}
ui->plainTextEdit->appendPlainText(lines);
}
if (ui->actionIPv6HashTable->isChecked()) {
lines = "\n";
lines.append(tr("# IPv6 Hash Table\n#\n# "));
if (!v6_hash_addrs_.isEmpty()) {
lines.append(entry_count_.arg(v6_hash_addrs_.length()));
lines.append(tr("\n\n"));
lines.append(v6_hash_addrs_.join("\n"));
} else {
lines.append(no_entries_);
}
ui->plainTextEdit->appendPlainText(lines);
}
if (ui->actionPortNames->isChecked()) {
lines = "\n";
lines.append(tr("# Services\n#\n# "));
if (!service_ports_.isEmpty()) {
lines.append(entry_count_.arg(service_ports_.length()));
lines.append(tr("\n\n"));
lines.append(service_ports_.join("\n"));
} else {
lines.append(no_entries_);
}
ui->plainTextEdit->appendPlainText(lines);
}
if (ui->actionEthernetAddresses->isChecked()) {
lines = "\n";
lines.append(tr("# Ethernet addresses\n#\n# "));
if (!ethernet_addresses_.isEmpty()) {
lines.append(entry_count_.arg(ethernet_addresses_.length()));
lines.append(tr("\n\n"));
lines.append(ethernet_addresses_.join("\n"));
} else {
lines.append(no_entries_);
}
ui->plainTextEdit->appendPlainText(lines);
}
if (ui->actionEthernetManufacturers->isChecked()) {
lines = "\n";
lines.append(tr("# Ethernet manufacturers\n#\n# "));
if (!ethernet_manufacturers_.isEmpty()) {
lines.append(entry_count_.arg(ethernet_manufacturers_.length()));
lines.append(tr("\n\n"));
lines.append(ethernet_manufacturers_.join("\n"));
} else {
lines.append(no_entries_);
}
ui->plainTextEdit->appendPlainText(lines);
}
if (ui->actionEthernetWKA->isChecked()) {
lines = "\n";
lines.append(tr("# Well known Ethernet addresses\n#\n# "));
if (!ethernet_well_known_.isEmpty()) {
lines.append(entry_count_.arg(ethernet_well_known_.length()));
lines.append(tr("\n\n"));
lines.append(ethernet_well_known_.join("\n"));
} else {
lines.append(no_entries_);
}
ui->plainTextEdit->appendPlainText(lines);
}
ui->plainTextEdit->moveCursor(QTextCursor::Start);
setUpdatesEnabled(true);
}
void ResolvedAddressesDialog::on_actionAddressesHosts_triggered()
{
fillBlocks();
}
void ResolvedAddressesDialog::on_actionComment_triggered()
{
fillBlocks();
}
void ResolvedAddressesDialog::on_actionIPv4HashTable_triggered()
{
fillBlocks();
}
void ResolvedAddressesDialog::on_actionIPv6HashTable_triggered()
{
fillBlocks();
}
void ResolvedAddressesDialog::on_actionPortNames_triggered()
{
fillBlocks();
}
void ResolvedAddressesDialog::on_actionEthernetAddresses_triggered()
{
fillBlocks();
}
void ResolvedAddressesDialog::on_actionEthernetManufacturers_triggered()
{
fillBlocks();
}
void ResolvedAddressesDialog::on_actionEthernetWKA_triggered()
{
fillBlocks();
}
void ResolvedAddressesDialog::on_actionShowAll_triggered()
{
ui->actionAddressesHosts->setChecked(true);
ui->actionComment->setChecked(true);
ui->actionIPv4HashTable->setChecked(true);
ui->actionIPv6HashTable->setChecked(true);
ui->actionPortNames->setChecked(true);
ui->actionEthernetAddresses->setChecked(true);
ui->actionEthernetManufacturers->setChecked(true);
ui->actionEthernetWKA->setChecked(true);
fillBlocks();
}
void ResolvedAddressesDialog::on_actionHideAll_triggered()
{
ui->actionAddressesHosts->setChecked(false);
ui->actionComment->setChecked(false);
ui->actionIPv4HashTable->setChecked(false);
ui->actionIPv6HashTable->setChecked(false);
ui->actionPortNames->setChecked(false);
ui->actionEthernetAddresses->setChecked(false);
ui->actionEthernetManufacturers->setChecked(false);
ui->actionEthernetWKA->setChecked(false);
fillBlocks();
}
/*
* Editor modelines
*

View File

@ -13,7 +13,7 @@
#include "geometry_state_dialog.h"
class CaptureFile;
class QTextBlock;
class AStringListListSortFilterProxyModel;
namespace Ui {
class ResolvedAddressesDialog;
@ -28,34 +28,23 @@ public:
~ResolvedAddressesDialog();
protected slots:
void on_cmbDataType_currentIndexChanged(QString val);
void on_txtSearchFilter_textChanged(QString text);
void on_cmbPortFilterType_currentIndexChanged(QString val);
void on_txtPortFilter_textChanged(QString text);
void changeEvent(QEvent* event);
private slots:
void on_actionAddressesHosts_triggered();
void on_actionComment_triggered();
void on_actionIPv4HashTable_triggered();
void on_actionIPv6HashTable_triggered();
void on_actionPortNames_triggered();
void on_actionEthernetAddresses_triggered();
void on_actionEthernetManufacturers_triggered();
void on_actionEthernetWKA_triggered();
void on_actionShowAll_triggered();
void on_actionHideAll_triggered();
private:
Ui::ResolvedAddressesDialog *ui;
QString file_name_;
QString comment_;
QStringList host_addresses_;
QStringList v4_hash_addrs_;
QStringList v6_hash_addrs_;
QStringList service_ports_;
QStringList ethernet_addresses_;
QStringList ethernet_manufacturers_;
QStringList ethernet_well_known_;
void fillShowMenu();
AStringListListSortFilterProxyModel * ethSortModel;
AStringListListSortFilterProxyModel * ethTypeModel;
AStringListListSortFilterProxyModel * portSortModel;
AStringListListSortFilterProxyModel * portTypeModel;
void fillBlocks();
};

View File

@ -13,9 +13,94 @@
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPlainTextEdit" name="plainTextEdit"/>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Hosts</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="txtSearchFilter">
<property name="placeholderText">
<string>Search for entry (min 3 characters)</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cmbDataType"/>
</item>
</layout>
</item>
<item>
<widget class="QTableView" name="tblAddresses">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderShowSortIndicator" stdset="0">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Ports</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="txtPortFilter">
<property name="placeholderText">
<string>Search for port or name</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cmbPortFilterType"/>
</item>
</layout>
</item>
<item>
<widget class="QTableView" name="tblPorts">
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Capture File Comments</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QPlainTextEdit" name="plainTextEdit"/>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
@ -23,7 +108,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>