UAT: Have a combobox for Dissectors

Add a drop-down combobox for UATs, including User DLTs, that
have a choice of dissectors. Make the combobox editable, which
will provide suggestions, and pass things through to the existing
UAT validation for dissectors. (It's a very long list, especially
with 1717 entries, including 530 just from various BT GATT UUIDs,
so being able to still type it in seems useful.)

Dissectors are not protocols. Rename the UAT field from PROTO to
DISSECTOR where used. Update the column names and long descriptions
to use dissector instead of protocol in dissectors that used this.
There may at some point be UATs that want protocols instead of
dissectors, but that's not what the current behavior does and
none of the current dissectors that use the existing types want.

Update the documentation to use "dissector" instead of "protocol."
Put the names of the actual current three Ethernet dissectors.
Clarify that the "ip" dissector actually tries IPv4 and IPv6,
instead of just IPv4.

UAT entries are backwards and forwards compatible with versions
without this change.

Fix #18836.
This commit is contained in:
John Thacker 2023-02-05 21:33:10 -05:00
parent 0c79fecac3
commit 994669e5b3
8 changed files with 59 additions and 35 deletions

View File

@ -1085,10 +1085,10 @@ sscop:nbap, ...)
[#ChUserDLTsSection]
=== User DLTs protocol table
=== User DLTs dissector table
When a pcap file uses one of the user DLTs (147 to 162) Wireshark uses this
table to know which protocol(s) to use for each user DLT.
table to know which dissector(s) to use for each user DLT.
This table is a user table, as described in <<ChUserTable>>, with the
following fields:
@ -1096,23 +1096,23 @@ following fields:
DLT::
One of the user dlts.
Payload protocol::
This is the name of the payload protocol (the lowest layer in the packet data).
(e.g., “eth” for ethernet, “ip” for IPv4)
Payload dissector::
This is the name of the payload dissector (the lowest layer in the packet data).
(e.g., “eth_withfcs, "eth_withoutfcs”, and "eth_maybefcs" respectively for Ethernet frames that do, do not, or might possibly include the FCS at the end, “ip” for trying IPv4 then IPv6)
Header size::
If there is a header protocol (before the payload protocol) this tells which
size this header is. A value of 0 disables the header protocol.
If there is a header (before the payload) this tells which
size this header is. A value of 0 disables the header dissector.
Header protocol::
The name of the header protocol to be used (uses “data” as default).
Header dissector::
The name of the header dissector to be used (uses “data” as default).
Trailer size::
If there is a trailer protocol (after the payload protocol) this tells which
size this trailer is. A value of 0 disables the trailer protocol.
If there is a trailer (after the payload) this tells which
size this trailer is. A value of 0 disables the trailer dissector.
Trailer protocol::
The name of the trailer protocol to be used (uses “data” as default).
Trailer dissector::
The name of the trailer dissector to be used (uses “data” as default).
[#ChProtobufSearchPaths]

View File

@ -1635,7 +1635,7 @@ static void amqp_message_decode_free_cb(void *record)
UAT_VS_DEF(message_decode, match_criteria, amqp_message_decode_t, guint32, MATCH_CRITERIA_EQUAL, "Equal to")
UAT_CSTRING_CB_DEF(message_decode, topic_pattern, amqp_message_decode_t)
UAT_PROTO_DEF(message_decode, payload_proto, payload_proto, payload_proto_name, amqp_message_decode_t)
UAT_DISSECTOR_DEF(message_decode, payload_proto, payload_proto, payload_proto_name, amqp_message_decode_t)
UAT_CSTRING_CB_DEF(message_decode, topic_more_info, amqp_message_decode_t)
@ -13650,8 +13650,8 @@ proto_register_amqp(void)
static uat_field_t amqp_message_decode_flds[] = {
UAT_FLD_VS(message_decode, match_criteria, "Match criteria", match_criteria, "Match criteria"),
UAT_FLD_CSTRING(message_decode, topic_pattern, "Topic pattern", "Pattern to match for the topic"),
UAT_FLD_PROTO(message_decode, payload_proto, "Payload protocol",
"Protocol to be used for the message part of the matching topic"),
UAT_FLD_DISSECTOR(message_decode, payload_proto, "Payload dissector",
"Dissector to be used for the message part of the matching topic"),
UAT_FLD_CSTRING(message_decode, topic_more_info, "Additional Data", "Additional Data to pass to the dissector"),
UAT_END_FIELDS
};

View File

@ -134,12 +134,12 @@ static uat_rfcomm_channels_t *rfcomm_channels = NULL;
static guint num_rfcomm_channels = 0;
UAT_DEC_CB_DEF(rfcomm_channels, channel, uat_rfcomm_channels_t)
UAT_PROTO_DEF(rfcomm_channels, payload_proto, payload_proto, payload_proto_name, uat_rfcomm_channels_t)
UAT_DISSECTOR_DEF(rfcomm_channels, payload_proto, payload_proto, payload_proto_name, uat_rfcomm_channels_t)
static uat_field_t uat_rfcomm_channels_fields[] = {
UAT_FLD_DEC(rfcomm_channels, channel, "RFCOMM Channel",
"Range: 0-32"),
UAT_FLD_PROTO(rfcomm_channels, payload_proto, "Payload protocol",
UAT_FLD_DISSECTOR(rfcomm_channels, payload_proto, "Payload dissector",
"Dissector name used to decode RFCOMM channel"),
UAT_END_FIELDS
};

View File

@ -683,7 +683,7 @@ static void mqtt_message_decode_free_cb(void *record)
UAT_VS_DEF(message_decode, match_criteria, mqtt_message_decode_t, guint, MATCH_CRITERIA_EQUAL, "Equal to")
UAT_CSTRING_CB_DEF(message_decode, topic_pattern, mqtt_message_decode_t)
UAT_VS_DEF(message_decode, msg_decoding, mqtt_message_decode_t, guint, MSG_DECODING_NONE, "none")
UAT_PROTO_DEF(message_decode, payload_proto, payload_proto, payload_proto_name, mqtt_message_decode_t)
UAT_DISSECTOR_DEF(message_decode, payload_proto, payload_proto, payload_proto_name, mqtt_message_decode_t)
static gboolean mqtt_user_decode_message(proto_tree *tree, proto_tree *mqtt_tree, packet_info *pinfo, const guint8 *topic_str, tvbuff_t *msg_tvb)
{
@ -1789,8 +1789,8 @@ void proto_register_mqtt(void)
UAT_FLD_VS(message_decode, match_criteria, "Match criteria", match_criteria, "Match criteria"),
UAT_FLD_CSTRING(message_decode, topic_pattern, "Topic pattern", "Pattern to match for the topic"),
UAT_FLD_VS(message_decode, msg_decoding, "Decoding", msg_decoding, "Decode message before dissecting as protocol"),
UAT_FLD_PROTO(message_decode, payload_proto, "Payload protocol",
"Protocol to be used for the message part of the matching topic"),
UAT_FLD_DISSECTOR(message_decode, payload_proto, "Payload dissector",
"Dissector to be used for the message part of the matching topic"),
UAT_END_FIELDS
};

View File

@ -210,11 +210,11 @@ static void user_free_cb(void* record)
}
UAT_VS_DEF(user_encap, encap, user_encap_t, guint, WTAP_ENCAP_USER0, ENCAP0_STR)
UAT_PROTO_DEF(user_encap, payload_proto, payload_proto, payload_proto_name, user_encap_t)
UAT_DISSECTOR_DEF(user_encap, payload_proto, payload_proto, payload_proto_name, user_encap_t)
UAT_DEC_CB_DEF(user_encap, header_size, user_encap_t)
UAT_PROTO_DEF(user_encap, header_proto, header_proto, header_proto_name, user_encap_t)
UAT_DISSECTOR_DEF(user_encap, header_proto, header_proto, header_proto_name, user_encap_t)
UAT_DEC_CB_DEF(user_encap, trailer_size, user_encap_t)
UAT_PROTO_DEF(user_encap, trailer_proto, trailer_proto, trailer_proto_name, user_encap_t)
UAT_DISSECTOR_DEF(user_encap, trailer_proto, trailer_proto, trailer_proto_name, user_encap_t)
void proto_reg_handoff_user_encap(void)
{
@ -234,16 +234,16 @@ void proto_register_user_encap(void)
static uat_field_t user_flds[] = {
UAT_FLD_VS(user_encap,encap,"DLT",user_dlts,"The DLT"),
UAT_FLD_PROTO(user_encap,payload_proto,"Payload protocol",
"Protocol to be used for the payload of this DLT"),
UAT_FLD_DISSECTOR(user_encap,payload_proto,"Payload dissector",
"Dissector to be used for the payload of this DLT"),
UAT_FLD_DEC(user_encap,header_size,"Header size",
"Size of an eventual header that precedes the actual payload, 0 means none"),
UAT_FLD_PROTO(user_encap,header_proto,"Header protocol",
"Protocol to be used for the header (empty = data)"),
UAT_FLD_DISSECTOR(user_encap,header_proto,"Header dissector",
"Dissector to be used for the header (empty = data)"),
UAT_FLD_DEC(user_encap,trailer_size,"Trailer size",
"Size of an eventual trailer that follows the actual payload, 0 means none"),
UAT_FLD_PROTO(user_encap,trailer_proto,"Trailer protocol",
"Protocol to be used for the trailer (empty = data)"),
UAT_FLD_DISSECTOR(user_encap,trailer_proto,"Trailer dissector",
"Dissector to be used for the trailer (empty = data)"),
UAT_END_FIELDS
};

View File

@ -325,7 +325,9 @@ static void putfld(FILE* fp, void* rec, uat_field_t* f) {
case PT_TXTMOD_DISPLAY_FILTER:
case PT_TXTMOD_PROTO_FIELD:
case PT_TXTMOD_COLOR:
case PT_TXTMOD_STRING: {
case PT_TXTMOD_STRING:
case PT_TXTMOD_DISSECTOR:
{
guint i;
putc('"',fp);

View File

@ -202,6 +202,8 @@ typedef enum _uat_text_mode_t {
*/
PT_TXTMOD_ENUM,
/* Read/Writes/displays the string value (not number!) */
PT_TXTMOD_DISSECTOR,
/* Shows a combobox of dissectors */
PT_TXTMOD_COLOR,
/* Reads/Writes/display color in #RRGGBB format */
@ -726,10 +728,10 @@ static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr,
/*
* PROTO macros
* DISSECTOR macros
*/
#define UAT_PROTO_DEF(basename, field_name, dissector_field, name_field, rec_t) \
#define UAT_DISSECTOR_DEF(basename, field_name, dissector_field, name_field, rec_t) \
static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, guint len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
if (len) { \
gchar *tmp = g_strndup(buf,len); \
@ -749,8 +751,8 @@ static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr,
*out_ptr = g_strdup(""); *out_len = 0; } }
#define UAT_FLD_PROTO(basename,field_name,title,desc) \
{#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_proto,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
#define UAT_FLD_DISSECTOR(basename,field_name,title,desc) \
{#field_name, title, PT_TXTMOD_DISSECTOR,{uat_fld_chk_proto,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
/*
* RANGE macros

View File

@ -11,6 +11,7 @@
*/
#include <ui/qt/models/uat_delegate.h>
#include <epan/packet.h> // for get_dissector_names()
#include "epan/value_string.h"
#include <wsutil/ws_assert.h>
#include <QRegularExpression>
@ -77,6 +78,23 @@ QWidget *UatDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &
break;
}
case PT_TXTMOD_DISSECTOR:
{
QComboBox *cb_editor = new QComboBox(parent);
GList* dissector_names = get_dissector_names();
for (GList* l = dissector_names; l != NULL; l = l->next) {
const char *name = (const char *) l->data;
cb_editor->addItem(name, QVariant(name));
}
cb_editor->model()->sort(0);
g_list_free(dissector_names);
cb_editor->setInsertPolicy(QComboBox::NoInsert);
cb_editor->setEditable(true);
editor = cb_editor;
cb_editor->setMinimumWidth(cb_editor->minimumSizeHint().width());
break;
}
case PT_TXTMOD_STRING:
// TODO add a live validator? Should SyntaxLineEdit be used?
editor = QStyledItemDelegate::createEditor(parent, option, index);
@ -135,6 +153,7 @@ void UatDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
qobject_cast<PathSelectionEdit *>(editor)->setPath(index.model()->data(index, Qt::EditRole).toString());
break;
case PT_TXTMOD_ENUM:
case PT_TXTMOD_DISSECTOR:
{
QComboBox *combobox = static_cast<QComboBox *>(editor);
const QString &data = index.model()->data(index, Qt::EditRole).toString();
@ -169,6 +188,7 @@ void UatDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const_cast<QAbstractItemModel *>(index.model())->setData(index, qobject_cast<PathSelectionEdit *>(editor)->path(), Qt::EditRole);
break;
case PT_TXTMOD_ENUM:
case PT_TXTMOD_DISSECTOR:
{
QComboBox *combobox = static_cast<QComboBox *>(editor);
const QString &data = combobox->currentText();