aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2017-07-09 13:44:06 -0400
committerMichael Mann <mmann78@netscape.net>2017-09-16 11:12:52 +0000
commit69250aa51eac68015e520f5680970ded2db1ee14 (patch)
tree7c437441cf41433d203d24850c7d440d2fa08045
parent7d65b573f2734017be416f31852c4ede42bd987b (diff)
Add support for dissector tables of type FT_NONE.
This is for dissectors that have "payloads" that don't have a unique identifier to determine a sub dissector. For the command line parameter -d, specifying a selector is no longer required for dissector tables of type FT_NONE. Change-Id: I3370d9e0dc147deeca4f26b842fe35dc3bda876e Reviewed-on: https://code.wireshark.org/review/22574 Reviewed-by: Michael Mann <mmann78@netscape.net>
-rw-r--r--epan/decode_as.c26
-rw-r--r--epan/dissectors/packet-bthci_evt.c22
-rw-r--r--epan/packet.c45
-rw-r--r--epan/packet.h19
-rw-r--r--ui/decode_as_utils.c65
-rw-r--r--ui/gtk/decode_as_dlg.c4
-rw-r--r--ui/gtk/dissector_tables_dlg.c2
-rw-r--r--ui/qt/models/decode_as_model.cpp31
8 files changed, 185 insertions, 29 deletions
diff --git a/epan/decode_as.c b/epan/decode_as.c
index 30e60abd86..43405fa3e9 100644
--- a/epan/decode_as.c
+++ b/epan/decode_as.c
@@ -143,6 +143,9 @@ gboolean decode_as_default_reset(const gchar *name, gconstpointer pattern)
case FT_UINT32:
dissector_reset_uint(name, GPOINTER_TO_UINT(pattern));
return TRUE;
+ case FT_NONE:
+ dissector_reset_payload(name);
+ return TRUE;
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
@@ -167,6 +170,9 @@ gboolean decode_as_default_change(const gchar *name, gconstpointer pattern, gpoi
case FT_UINT32:
dissector_change_uint(name, GPOINTER_TO_UINT(pattern), *dissector);
return TRUE;
+ case FT_NONE:
+ dissector_change_payload(name, *dissector);
+ return TRUE;
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
@@ -349,6 +355,17 @@ decode_as_write_entry (const gchar *table_name, ftenum_t selector_type,
table_name, GPOINTER_TO_UINT(key), initial_proto_name,
current_proto_name);
break;
+ case FT_NONE:
+ /*
+ * XXX - Just put a placeholder for the key value. Currently
+ * FT_NONE dissector table uses a single uint value for
+ * a placeholder
+ */
+ fprintf (da_file,
+ DECODE_AS_ENTRY ": %s,0,%s,%s\n",
+ table_name, initial_proto_name,
+ current_proto_name);
+ break;
case FT_STRING:
case FT_STRINGZ:
@@ -436,6 +453,11 @@ decode_build_reset_list (const gchar *table_name, ftenum_t selector_type,
item->ddi_selector.sel_uint = GPOINTER_TO_UINT(key);
break;
+ case FT_NONE:
+ /* Not really needed, but prevents the assert */
+ item->ddi_selector.sel_uint = 0;
+ break;
+
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
@@ -470,6 +492,10 @@ decode_clear_all(void)
item->ddi_selector.sel_uint);
break;
+ case FT_NONE:
+ dissector_reset_payload(item->ddi_table_name);
+ break;
+
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
diff --git a/epan/dissectors/packet-bthci_evt.c b/epan/dissectors/packet-bthci_evt.c
index c32e74c9de..6269e25602 100644
--- a/epan/dissectors/packet-bthci_evt.c
+++ b/epan/dissectors/packet-bthci_evt.c
@@ -918,6 +918,11 @@ static void bthci_evt_vendor_prompt(packet_info *pinfo _U_, gchar* result)
g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Vendor as");
}
+static gpointer bthci_evt_vendor_value(packet_info *pinfo _U_)
+{
+ return NULL;
+}
+
static void add_opcode(wmem_list_t *opcode_list, guint16 opcode, enum command_status command_status) {
opcode_list_data_t *opcode_list_data;
@@ -1924,7 +1929,7 @@ dissect_bthci_evt_command_status(tvbuff_t *tvb, int offset, packet_info *pinfo,
if (ogf == HCI_OGF_VENDOR_SPECIFIC) {
col_append_fstr(pinfo->cinfo, COL_INFO, " (Vendor Command 0x%04X [(opcode 0x%04X])", opcode & 0x03ff, opcode);
- if (!dissector_try_uint_new(vendor_dissector_table, HCI_VENDOR_DEFAULT, tvb, pinfo, main_tree, TRUE, bluetooth_data)) {
+ if (!dissector_try_payload_new(vendor_dissector_table, tvb, pinfo, main_tree, TRUE, bluetooth_data)) {
if (bluetooth_data) {
hci_vendor_data_t *hci_vendor_data;
wmem_tree_key_t key[3];
@@ -2755,7 +2760,7 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset,
if (ogf == HCI_OGF_VENDOR_SPECIFIC) {
col_append_fstr(pinfo->cinfo, COL_INFO, " (Vendor Command 0x%04X [opcode 0x%04X])", opcode & 0x03ff, opcode);
- if (!dissector_try_uint_new(vendor_dissector_table, HCI_VENDOR_DEFAULT, tvb, pinfo, main_tree, TRUE, bluetooth_data)) {
+ if (!dissector_try_payload_new(vendor_dissector_table, tvb, pinfo, main_tree, TRUE, bluetooth_data)) {
if (bluetooth_data) {
hci_vendor_data_t *hci_vendor_data;
@@ -5516,7 +5521,7 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
break;
case 0xff: /* Vendor-Specific */
- if (!dissector_try_uint_new(vendor_dissector_table, HCI_VENDOR_DEFAULT, tvb, pinfo, tree, TRUE, bluetooth_data)) {
+ if (!dissector_try_payload_new(vendor_dissector_table, tvb, pinfo, tree, TRUE, bluetooth_data)) {
if (bluetooth_data) {
hci_vendor_data_t *hci_vendor_data;
wmem_tree_key_t key[3];
@@ -7971,6 +7976,15 @@ proto_register_bthci_evt(void)
&ett_expert
};
+ /* Decode As handling
+ This doesn't use register_decode_as_next_proto because it shares a dissector table
+ with "bthci_cmd.vendor" */
+ static build_valid_func bthci_evt_vendor_da_build_value[1] = {bthci_evt_vendor_value};
+ static decode_as_value_t bthci_evt_vendor_da_values = {bthci_evt_vendor_prompt, 1, bthci_evt_vendor_da_build_value};
+ static decode_as_t bthci_evt_vendor_da = {"bthci_cmd", "Vendor", "bthci_cmd.vendor", 1, 0, &bthci_evt_vendor_da_values, NULL, NULL,
+ decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
+
+
/* Register the protocol name and description */
proto_bthci_evt = proto_register_protocol("Bluetooth HCI Event",
"HCI_EVT", "bthci_evt");
@@ -7988,7 +8002,7 @@ proto_register_bthci_evt(void)
"Bluetooth HCI version: 4.0 (Core) + Addendum 4",
"Version of protocol supported by this dissector.");
- register_decode_as_next_proto("bthci_cmd", "Vendor", "bthci_cmd.vendor", (build_label_func*)&bthci_evt_vendor_prompt);
+ register_decode_as(&bthci_evt_vendor_da);
}
diff --git a/epan/packet.c b/epan/packet.c
index 542277db24..b416c8c03c 100644
--- a/epan/packet.c
+++ b/epan/packet.c
@@ -915,6 +915,9 @@ find_uint_dtbl_entry(dissector_table_t sub_dissectors, const guint32 pattern)
* You can do a uint lookup in these tables.
*/
break;
+ case FT_NONE:
+ /* For now treat as uint */
+ break;
default:
/*
@@ -1856,6 +1859,36 @@ dissector_handle_t dissector_get_guid_handle(
return NULL;
}
+/* Use the currently assigned payload dissector for the dissector table and,
+ if any, call the dissector with the arguments supplied, and return the
+ number of bytes consumed, otherwise return 0. */
+int dissector_try_payload(dissector_table_t sub_dissectors,
+ tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ return dissector_try_uint(sub_dissectors, 0, tvb, pinfo, tree);
+}
+
+/* Use the currently assigned payload dissector for the dissector table and,
+ if any, call the dissector with the arguments supplied, and return the
+ number of bytes consumed, otherwise return 0. */
+int dissector_try_payload_new(dissector_table_t sub_dissectors,
+ tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const gboolean add_proto_name, void *data)
+{
+ return dissector_try_uint_new(sub_dissectors, 0, tvb, pinfo, tree, add_proto_name, data);
+}
+
+/* Change the entry for a dissector in a payload (FT_NONE) dissector table
+ with a particular pattern to use a new dissector handle. */
+void dissector_change_payload(const char *abbrev, dissector_handle_t handle)
+{
+ dissector_change_uint(abbrev, 0, handle);
+}
+
+/* Reset payload (FT_NONE) dissector table to its initial value. */
+void dissector_reset_payload(const char *name)
+{
+ dissector_reset_uint(name, 0);
+}
dissector_handle_t
dtbl_entry_get_handle (dtbl_entry_t *dtbl_entry)
@@ -2349,6 +2382,18 @@ register_dissector_table(const char *name, const char *ui_name, const int proto,
NULL,
&g_free );
break;
+
+ case FT_NONE:
+ /* Dissector tables with FT_NONE don't have values associated with
+ dissectors so this will always be a hash table size of 1 just
+ to store the single dtbl_entry_t */
+ sub_dissectors->hash_func = g_direct_hash;
+ sub_dissectors->hash_table = g_hash_table_new_full( g_direct_hash,
+ g_direct_equal,
+ NULL,
+ &g_free );
+ break;
+
default:
g_error("The dissector table %s (%s) is registering an unsupported type - are you using a buggy plugin?", name, ui_name);
g_assert_not_reached();
diff --git a/epan/packet.h b/epan/packet.h
index 84aa4912f5..ffe23285a4 100644
--- a/epan/packet.h
+++ b/epan/packet.h
@@ -367,6 +367,25 @@ WS_DLL_PUBLIC int dissector_try_guid_new(dissector_table_t sub_dissectors,
WS_DLL_PUBLIC dissector_handle_t dissector_get_guid_handle(
dissector_table_t const sub_dissectors, guid_key* guid_val);
+/* Use the currently assigned payload dissector for the dissector table and,
+ if any, call the dissector with the arguments supplied, and return the
+ number of bytes consumed, otherwise return 0. */
+WS_DLL_PUBLIC int dissector_try_payload(dissector_table_t sub_dissectors,
+ tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+
+/* Use the currently assigned payload dissector for the dissector table and,
+ if any, call the dissector with the arguments supplied, and return the
+ number of bytes consumed, otherwise return 0. */
+WS_DLL_PUBLIC int dissector_try_payload_new(dissector_table_t sub_dissectors,
+ tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const gboolean add_proto_name, void *data);
+
+/* Change the entry for a dissector in a payload (FT_NONE) dissector table
+ with a particular pattern to use a new dissector handle. */
+WS_DLL_PUBLIC void dissector_change_payload(const char *abbrev, dissector_handle_t handle);
+
+/* Reset payload (FT_NONE) dissector table to its initial value. */
+WS_DLL_PUBLIC void dissector_reset_payload(const char *name);
+
/* Add a handle to the list of handles that *could* be used with this
table. That list is used by the "Decode As"/"-d" code in the UI. */
WS_DLL_PUBLIC void dissector_add_for_decode_as(const char *name,
diff --git a/ui/decode_as_utils.c b/ui/decode_as_utils.c
index 173d82fe0b..0cf5942d57 100644
--- a/ui/decode_as_utils.c
+++ b/ui/decode_as_utils.c
@@ -187,7 +187,7 @@ gboolean decode_as_command_option(const gchar *cl_param)
guint32 selector, selector2;
gchar *decoded_param;
gchar *remaining_param;
- gchar *selector_str;
+ gchar *selector_str = NULL;
gchar *dissector_str;
dissector_handle_t dissector_matching;
dissector_table_t table_matching;
@@ -212,7 +212,14 @@ gboolean decode_as_command_option(const gchar *cl_param)
remaining_param = strchr(table_name, '=');
if (remaining_param == NULL) {
- cmdarg_err("Parameter \"%s\" doesn't follow the template \"%s\"", cl_param, DECODE_AS_ARG_TEMPLATE);
+ /* Dissector tables of type FT_NONE aren't required to specify a value, so for now
+ just check for comma */
+ remaining_param = strchr(table_name, ',');
+ if (remaining_param == NULL) {
+ cmdarg_err("Parameter \"%s\" doesn't follow the template \"%s\"", cl_param, DECODE_AS_ARG_TEMPLATE);
+ } else {
+ *remaining_param = '\0'; /* Terminate the layer type string (table_name) where ',' was detected */
+ }
/* If the argument does not follow the template, carry on anyway to check
if the table name is at least correct. If remaining_param is NULL,
we'll exit anyway further down */
@@ -254,31 +261,34 @@ gboolean decode_as_command_option(const gchar *cl_param)
return FALSE;
}
- if (*(remaining_param + 1) != '=') { /* Check for "==" and not only '=' */
- cmdarg_err("WARNING: -d requires \"==\" instead of \"=\". Option will be treated as \"%s==%s\"", table_name, remaining_param + 1);
- }
- else {
- remaining_param++; /* Move to the second '=' */
- *remaining_param = '\0'; /* Remove the second '=' */
- }
- remaining_param++; /* Position after the layer type string */
+ dissector_table_selector_type = get_dissector_table_selector_type(table_name);
- /* This section extracts a selector value (selector_str) from decoded_param */
+ if (dissector_table_selector_type != FT_NONE) {
+ if (*(remaining_param + 1) != '=') { /* Check for "==" and not only '=' */
+ cmdarg_err("WARNING: -d requires \"==\" instead of \"=\". Option will be treated as \"%s==%s\"", table_name, remaining_param + 1);
+ }
+ else {
+ remaining_param++; /* Move to the second '=' */
+ *remaining_param = '\0'; /* Remove the second '=' */
+ }
+ remaining_param++; /* Position after the layer type string */
- selector_str = remaining_param; /* Next part starts with the selector number */
- remaining_param = strchr(selector_str, ',');
- if (remaining_param == NULL) {
- cmdarg_err("Parameter \"%s\" doesn't follow the template \"%s\"", cl_param, DECODE_AS_ARG_TEMPLATE);
- /* If the argument does not follow the template, carry on anyway to check
- if the selector value is at least correct. If remaining_param is NULL,
- we'll exit anyway further down */
- }
- else {
- *remaining_param = '\0'; /* Terminate the selector number string (selector_str) where ',' was detected */
- }
+ /* This section extracts a selector value (selector_str) from decoded_param */
- dissector_table_selector_type = get_dissector_table_selector_type(table_name);
+ selector_str = remaining_param; /* Next part starts with the selector number */
+
+ remaining_param = strchr(selector_str, ',');
+ if (remaining_param == NULL) {
+ cmdarg_err("Parameter \"%s\" doesn't follow the template \"%s\"", cl_param, DECODE_AS_ARG_TEMPLATE);
+ /* If the argument does not follow the template, carry on anyway to check
+ if the selector value is at least correct. If remaining_param is NULL,
+ we'll exit anyway further down */
+ }
+ else {
+ *remaining_param = '\0'; /* Terminate the selector number string (selector_str) where ',' was detected */
+ }
+ }
switch (dissector_table_selector_type) {
@@ -328,6 +338,10 @@ gboolean decode_as_command_option(const gchar *cl_param)
/* The selector for this table is a string. */
break;
+ case FT_NONE:
+ /* There is no selector for this table */
+ break;
+
default:
/* There are currently no dissector tables with any types other
than the ones listed above. */
@@ -440,6 +454,11 @@ gboolean decode_as_command_option(const gchar *cl_param)
dissector_change_string(table_name, selector_str, dissector_matching);
break;
+ case FT_NONE:
+ /* Just directly set the dissector found. */
+ dissector_change_payload(table_name, dissector_matching);
+ break;
+
default:
/* There are currently no dissector tables with any types other
than the ones listed above. */
diff --git a/ui/gtk/decode_as_dlg.c b/ui/gtk/decode_as_dlg.c
index 4e8292b439..86f231bc63 100644
--- a/ui/gtk/decode_as_dlg.c
+++ b/ui/gtk/decode_as_dlg.c
@@ -323,6 +323,10 @@ decode_build_show_list (const gchar *table_name, ftenum_t selector_type,
selector_name = string1;
break;
+ case FT_NONE:
+ selector_name = NULL;
+ break;
+
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
diff --git a/ui/gtk/dissector_tables_dlg.c b/ui/gtk/dissector_tables_dlg.c
index e57a6a6eba..40289936df 100644
--- a/ui/gtk/dissector_tables_dlg.c
+++ b/ui/gtk/dissector_tables_dlg.c
@@ -153,6 +153,7 @@ decode_proto_add_to_list (const gchar *table_name _U_, ftenum_t selector_type,
case FT_BYTES:
case FT_GUID:
+ case FT_NONE:
dissector_name_str = dissector_handle_get_dissector_name(handle);
if (dissector_name_str == NULL)
dissector_name_str = "<Unknown>";
@@ -244,6 +245,7 @@ display_dissector_table_names(const char *table_name, const char *ui_name, void
break;
case FT_BYTES:
case FT_GUID:
+ case FT_NONE:
table_name_add_to_list(tree_info, dis_tbl_trees->custom_tree_wgt, table_name, ui_name);
break;
default:
diff --git a/ui/qt/models/decode_as_model.cpp b/ui/qt/models/decode_as_model.cpp
index 2c15e419fc..e4e654ddb1 100644
--- a/ui/qt/models/decode_as_model.cpp
+++ b/ui/qt/models/decode_as_model.cpp
@@ -61,14 +61,22 @@ Qt::ItemFlags DecodeAsModel::flags(const QModelIndex &index) const
if (!index.isValid())
return 0;
+ DecodeAsItem* item = decode_as_items_[index.row()];
+
Qt::ItemFlags flags = QAbstractTableModel::flags(index);
switch(index.column())
{
case DecodeAsModel::colTable:
- case DecodeAsModel::colSelector:
case DecodeAsModel::colProtocol:
flags |= Qt::ItemIsEditable;
break;
+ case DecodeAsModel::colSelector:
+ {
+ ftenum_t selector_type = get_dissector_table_selector_type(item->tableName_);
+ if (selector_type != FT_NONE)
+ flags |= Qt::ItemIsEditable;
+ break;
+ }
}
return flags;
@@ -126,7 +134,7 @@ QVariant DecodeAsModel::data(const QModelIndex &index, int role) const
if (IS_FT_STRING(selector_type)) {
return tr("String");
- } else {
+ } else if (IS_FT_UINT(selector_type)) {
QString type_desc = tr("Integer, base ");
switch (get_dissector_table_param(item->tableName_)) {
case BASE_OCT:
@@ -142,6 +150,8 @@ QVariant DecodeAsModel::data(const QModelIndex &index, int role) const
type_desc.append(tr("unknown"));
}
return type_desc;
+ } else if (selector_type == FT_NONE) {
+ return tr("<none>");
}
}
case colDefault:
@@ -313,6 +323,9 @@ bool DecodeAsModel::insertRows(int row, int count, const QModelIndex &/*parent*/
}
dissector = dissector_get_default_uint_handle(entry->table_name, item->selectorUint_);
+ } else if (selector_type == FT_NONE) {
+ // There is no default for an FT_NONE dissector table
+ dissector = NULL;
}
if (dissector != NULL) {
@@ -437,6 +450,10 @@ QString DecodeAsModel::entryString(const gchar *table_name, gpointer value)
//TODO: DCE/RPC dissector table
break;
+ case FT_NONE:
+ //doesn't really matter, just avoiding the assert
+ return "0";
+
default:
g_assert_not_reached();
break;
@@ -519,6 +536,12 @@ void DecodeAsModel::gatherChangedEntries(const gchar *table_name,
case FT_UINT32:
model->changed_uint_entries_ << UintPair(table_name, GPOINTER_TO_UINT(key));
break;
+ case FT_NONE:
+ //need to reset dissector table, so this needs to be in a changed list,
+ //might as well be the uint one.
+ model->changed_uint_entries_ << UintPair(table_name, 0);
+ break;
+
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
@@ -597,6 +620,10 @@ void DecodeAsModel::applyChanges()
byteArray = item->selectorString_.toUtf8();
selector_value = (gpointer) byteArray.constData();
break;
+ case FT_NONE:
+ //selector value is ignored, but dissector table needs to happen
+ selector_value = NULL;
+ break;
default:
continue;
}