summaryrefslogtreecommitdiffstats
path: root/ui/qt/models/dissector_tables_model.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ui/qt/models/dissector_tables_model.cpp')
-rw-r--r--ui/qt/models/dissector_tables_model.cpp434
1 files changed, 434 insertions, 0 deletions
diff --git a/ui/qt/models/dissector_tables_model.cpp b/ui/qt/models/dissector_tables_model.cpp
new file mode 100644
index 0000000..73c757e
--- /dev/null
+++ b/ui/qt/models/dissector_tables_model.cpp
@@ -0,0 +1,434 @@
+/* dissector_tables_model.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/dissector_tables_model.h>
+#include <epan/ftypes/ftypes.h>
+#include <epan/packet.h>
+
+#include <ui/qt/utils/variant_pointer.h>
+#include "main_application.h"
+
+static const char* CUSTOM_TABLE_NAME = "Custom Tables";
+static const char* INTEGER_TABLE_NAME = "Integer Tables";
+static const char* STRING_TABLE_NAME = "String Tables";
+static const char* HEURISTIC_TABLE_NAME = "Heuristic Tables";
+
+class IntegerTablesItem : public DissectorTablesItem
+{
+public:
+ IntegerTablesItem(unsigned int value, QString dissectorDescription, DissectorTablesItem* parent);
+ virtual ~IntegerTablesItem();
+
+ virtual bool lessThan(DissectorTablesItem &right) const;
+
+protected:
+ unsigned int value_;
+};
+
+
+DissectorTablesItem::DissectorTablesItem(QString tableName, QString dissectorDescription, DissectorTablesItem* parent) :
+ ModelHelperTreeItem<DissectorTablesItem>(parent),
+ tableName_(tableName),
+ dissectorDescription_(dissectorDescription)
+{
+}
+
+DissectorTablesItem::~DissectorTablesItem()
+{
+}
+
+bool DissectorTablesItem::lessThan(DissectorTablesItem &right) const
+{
+ if (tableName().compare(right.tableName(), Qt::CaseInsensitive) < 0)
+ return true;
+
+ return false;
+}
+
+
+IntegerTablesItem::IntegerTablesItem(unsigned int value, QString dissectorDescription, DissectorTablesItem* parent)
+ : DissectorTablesItem(QString("%1").arg(value), dissectorDescription, parent)
+ , value_(value)
+{
+}
+
+IntegerTablesItem::~IntegerTablesItem()
+{
+}
+
+bool IntegerTablesItem::lessThan(DissectorTablesItem &right) const
+{
+ if (value_ == ((IntegerTablesItem&)right).value_) {
+ return DissectorTablesItem::lessThan(right);
+ }
+
+ if (value_ < ((IntegerTablesItem&)right).value_) {
+ return true;
+ }
+
+ return false;
+}
+
+
+
+
+
+
+
+
+DissectorTablesModel::DissectorTablesModel(QObject *parent) :
+ QAbstractItemModel(parent),
+ root_(new DissectorTablesItem(QString("ROOT"), QString("ROOT"), NULL))
+{
+ populate();
+}
+
+DissectorTablesModel::~DissectorTablesModel()
+{
+ delete root_;
+}
+
+int DissectorTablesModel::rowCount(const QModelIndex &parent) const
+{
+ DissectorTablesItem *parent_item;
+ if (parent.column() > 0)
+ return 0;
+
+ if (!parent.isValid())
+ parent_item = root_;
+ else
+ parent_item = static_cast<DissectorTablesItem*>(parent.internalPointer());
+
+ if (parent_item == NULL)
+ return 0;
+
+ return parent_item->childCount();
+}
+
+int DissectorTablesModel::columnCount(const QModelIndex&) const
+{
+ return colLast;
+}
+
+QModelIndex DissectorTablesModel::parent(const QModelIndex& index) const
+{
+ if (!index.isValid())
+ return QModelIndex();
+
+ DissectorTablesItem* item = static_cast<DissectorTablesItem*>(index.internalPointer());
+ if (item != NULL) {
+ DissectorTablesItem* parent_item = item->parentItem();
+ if (parent_item != NULL) {
+ if (parent_item == root_)
+ return QModelIndex();
+
+ return createIndex(parent_item->row(), 0, parent_item);
+ }
+ }
+
+ return QModelIndex();
+}
+
+QModelIndex DissectorTablesModel::index(int row, int column, const QModelIndex& parent) const
+{
+ if (!hasIndex(row, column, parent))
+ return QModelIndex();
+
+ DissectorTablesItem *parent_item, *child_item;
+
+ if (!parent.isValid())
+ parent_item = root_;
+ else
+ parent_item = static_cast<DissectorTablesItem*>(parent.internalPointer());
+
+ Q_ASSERT(parent_item);
+
+ child_item = parent_item->child(row);
+ if (child_item) {
+ return createIndex(row, column, child_item);
+ }
+
+ return QModelIndex();
+}
+
+QVariant DissectorTablesModel::data(const QModelIndex &index, int role) const
+{
+ if ((!index.isValid()) || (role != Qt::DisplayRole))
+ return QVariant();
+
+ DissectorTablesItem* item = static_cast<DissectorTablesItem*>(index.internalPointer());
+ if (item == NULL)
+ return QVariant();
+
+ switch ((enum DissectorTablesColumn)index.column())
+ {
+ case colTableName:
+ return item->tableName();
+ case colDissectorDescription:
+ return item->dissectorDescription();
+ default:
+ break;
+ }
+
+ return QVariant();
+}
+
+static void gatherProtocolDecodes(const char *, ftenum_t selector_type, gpointer key, gpointer value, gpointer item_ptr)
+{
+ DissectorTablesItem* pdl_ptr = (DissectorTablesItem*)item_ptr;
+ if (pdl_ptr == NULL)
+ return;
+
+ dtbl_entry_t *dtbl_entry = (dtbl_entry_t*)value;
+ dissector_handle_t handle = dtbl_entry_get_handle(dtbl_entry);
+ const QString dissector_description = dissector_handle_get_description(handle);
+ DissectorTablesItem *ti = NULL;
+
+ switch (selector_type) {
+ case FT_UINT8:
+ case FT_UINT16:
+ case FT_UINT24:
+ case FT_UINT32:
+ ti = new IntegerTablesItem(GPOINTER_TO_UINT(key), dissector_description, pdl_ptr);
+ pdl_ptr->prependChild(ti);
+ break;
+
+ case FT_STRING:
+ case FT_STRINGZ:
+ case FT_UINT_STRING:
+ case FT_STRINGZPAD:
+ case FT_STRINGZTRUNC:
+ ti = new DissectorTablesItem((const char *)key, dissector_description, pdl_ptr);
+ pdl_ptr->prependChild(ti);
+ break;
+
+ case FT_BYTES:
+ ti = new DissectorTablesItem(dissector_handle_get_description(handle), dissector_description, pdl_ptr);
+ pdl_ptr->prependChild(ti);
+ break;
+
+ default:
+ break;
+ }
+}
+
+struct tables_root
+{
+ DissectorTablesItem* custom_table;
+ DissectorTablesItem* integer_table;
+ DissectorTablesItem* string_table;
+};
+
+static void gatherTableNames(const char *short_name, const char *table_name, gpointer model_ptr)
+{
+ struct tables_root* tables = (struct tables_root*)model_ptr;
+ if (model_ptr == NULL)
+ return;
+
+ ftenum_t selector_type = get_dissector_table_selector_type(short_name);
+ DissectorTablesItem *dt_ti = NULL;
+
+ switch (selector_type) {
+ case FT_UINT8:
+ case FT_UINT16:
+ case FT_UINT24:
+ case FT_UINT32:
+ dt_ti = new DissectorTablesItem(table_name, short_name, tables->integer_table);
+ tables->integer_table->prependChild(dt_ti);
+ break;
+ case FT_STRING:
+ case FT_STRINGZ:
+ case FT_UINT_STRING:
+ case FT_STRINGZPAD:
+ case FT_STRINGZTRUNC:
+ dt_ti = new DissectorTablesItem(table_name, short_name, tables->string_table);
+ tables->string_table->prependChild(dt_ti);
+ break;
+ case FT_BYTES:
+ dt_ti = new DissectorTablesItem(table_name, short_name, tables->custom_table);
+ tables->custom_table->prependChild(dt_ti);
+ break;
+ default:
+ // Assert?
+ return;
+ }
+
+ dissector_table_foreach(short_name, gatherProtocolDecodes, dt_ti);
+}
+
+static void gatherHeurProtocolDecodes(const char *, struct heur_dtbl_entry *dtbl_entry, gpointer list_ptr)
+{
+ DissectorTablesItem* hdl_ptr = (DissectorTablesItem*)list_ptr;
+ if (hdl_ptr == NULL)
+ return;
+
+ if (dtbl_entry->protocol) {
+ QString longName = proto_get_protocol_long_name(dtbl_entry->protocol);
+ QString heurDisplayName = dtbl_entry->display_name;
+ if (! heurDisplayName.isEmpty())
+ longName.append(QString(" (%1)").arg(heurDisplayName));
+
+ DissectorTablesItem *heur = new DissectorTablesItem(longName, proto_get_protocol_short_name(dtbl_entry->protocol), hdl_ptr);
+ hdl_ptr->prependChild(heur);
+ }
+}
+
+static void gatherHeurTableNames(const char *table_name, heur_dissector_list *list, gpointer heur_tables)
+{
+ DissectorTablesItem* table = (DissectorTablesItem*)heur_tables;
+ if (table == NULL)
+ return;
+
+ DissectorTablesItem *heur = new DissectorTablesItem(table_name, QString(""), table);
+ table->prependChild(heur);
+
+ if (list) {
+ heur_dissector_table_foreach(table_name, gatherHeurProtocolDecodes, heur);
+ }
+}
+
+void DissectorTablesModel::populate()
+{
+ beginResetModel();
+
+ struct tables_root tables;
+
+ tables.custom_table = new DissectorTablesItem(tr(CUSTOM_TABLE_NAME), QString(""), root_);
+ root_->prependChild(tables.custom_table);
+ tables.integer_table = new DissectorTablesItem(tr(INTEGER_TABLE_NAME), QString(""), root_);
+ root_->prependChild(tables.integer_table);
+ tables.string_table = new DissectorTablesItem(tr(STRING_TABLE_NAME), QString(""), root_);
+ root_->prependChild(tables.string_table);
+
+ dissector_all_tables_foreach_table(gatherTableNames, &tables, NULL);
+
+ DissectorTablesItem* heuristic_table = new DissectorTablesItem(tr(HEURISTIC_TABLE_NAME), QString(""), root_);
+ root_->prependChild(heuristic_table);
+
+ dissector_all_heur_tables_foreach_table(gatherHeurTableNames, heuristic_table, NULL);
+
+ endResetModel();
+}
+
+
+
+
+
+DissectorTablesProxyModel::DissectorTablesProxyModel(QObject * parent)
+: QSortFilterProxyModel(parent),
+tableName_(tr("Table Type")),
+dissectorDescription_(),
+filter_()
+{
+}
+
+QVariant DissectorTablesProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
+
+ switch ((enum DissectorTablesModel::DissectorTablesColumn)section) {
+ case DissectorTablesModel::colTableName:
+ return tableName_;
+ case DissectorTablesModel::colDissectorDescription:
+ return dissectorDescription_;
+ default:
+ break;
+ }
+ }
+ return QVariant();
+}
+
+bool DissectorTablesProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
+{
+ //Use DissectorTablesItem directly for better performance
+ DissectorTablesItem* left_item = static_cast<DissectorTablesItem*>(left.internalPointer());
+ DissectorTablesItem* right_item = static_cast<DissectorTablesItem*>(right.internalPointer());
+
+ if ((left_item != NULL) && (right_item != NULL)) {
+ return left_item->lessThan(*right_item);
+ }
+
+ return false;
+}
+
+bool DissectorTablesProxyModel::filterAcceptItem(DissectorTablesItem& item) const
+{
+ if (filter_.isEmpty())
+ return true;
+
+ if (item.tableName().contains(filter_, Qt::CaseInsensitive) || item.dissectorDescription().contains(filter_, Qt::CaseInsensitive))
+ return true;
+
+ DissectorTablesItem *child_item;
+ for (int child_row = 0; child_row < item.childCount(); child_row++)
+ {
+ child_item = item.child(child_row);
+ if ((child_item != NULL) && (filterAcceptItem(*child_item)))
+ return true;
+ }
+
+ return false;
+}
+
+bool DissectorTablesProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
+{
+ QModelIndex nameIdx = sourceModel()->index(sourceRow, DissectorTablesModel::colTableName, sourceParent);
+ DissectorTablesItem* item = static_cast<DissectorTablesItem*>(nameIdx.internalPointer());
+ if (item == NULL)
+ return false;
+
+ if (filterAcceptItem(*item))
+ return true;
+
+ return false;
+}
+
+void DissectorTablesProxyModel::setFilter(const QString& filter)
+{
+ filter_ = filter;
+ invalidateFilter();
+}
+
+void DissectorTablesProxyModel::adjustHeader(const QModelIndex &currentIndex)
+{
+ tableName_ = tr("Table Type");
+ dissectorDescription_ = QString();
+ if (currentIndex.isValid() && currentIndex.parent().isValid()) {
+ QString table;
+
+ if (currentIndex.parent().parent().isValid()) {
+ table = data(index(currentIndex.parent().parent().row(), DissectorTablesModel::colTableName), Qt::DisplayRole).toString();
+ if ((table.compare(CUSTOM_TABLE_NAME) == 0) ||
+ (table.compare(STRING_TABLE_NAME) == 0)) {
+ tableName_ = tr("String");
+ dissectorDescription_ = tr("Dissector Description");
+ } else if (table.compare(INTEGER_TABLE_NAME) == 0) {
+ tableName_ = tr("Integer");
+ dissectorDescription_ = tr("Dissector Description");
+ } else if (table.compare(HEURISTIC_TABLE_NAME) == 0) {
+ tableName_ = tr("Protocol");
+ dissectorDescription_ = tr("Short Name");
+ }
+ } else {
+ table = data(index(currentIndex.parent().row(), DissectorTablesModel::colTableName), Qt::DisplayRole).toString();
+ if ((table.compare(CUSTOM_TABLE_NAME) == 0) ||
+ (table.compare(INTEGER_TABLE_NAME) == 0) ||
+ (table.compare(STRING_TABLE_NAME) == 0)) {
+ tableName_ = tr("Table Name");
+ dissectorDescription_ = tr("Selector Name");
+ } else if (table.compare(HEURISTIC_TABLE_NAME) == 0) {
+ tableName_ = tr("Protocol");
+ dissectorDescription_ = tr("Short Name");
+ }
+ }
+ }
+
+
+ emit headerDataChanged(Qt::Vertical, 0, 1);
+}