Add GUID dissector table support.
It seems like DCE/RPC could benefit from a GUID dissector table, where a dissector can register it's GUID with a dissector handle. So here is a basic start. Change-Id: Id407117687a1a648d87f6f99c2ecbf858d8c0911 Reviewed-on: https://code.wireshark.org/review/4718 Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
parent
4f04a3cc31
commit
89c96d2772
143
epan/packet.c
143
epan/packet.c
|
@ -1555,6 +1555,124 @@ dissector_handle_t dissector_get_custom_table_handle(dissector_table_t sub_disse
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
/* Add an entry to a guid dissector table. */
|
||||||
|
void dissector_add_guid(const char *name, guid_key* guid_val, dissector_handle_t handle)
|
||||||
|
{
|
||||||
|
dissector_table_t sub_dissectors;
|
||||||
|
dtbl_entry_t *dtbl_entry;
|
||||||
|
|
||||||
|
sub_dissectors = find_dissector_table(name);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure the dissector table exists.
|
||||||
|
*/
|
||||||
|
if (sub_dissectors == NULL) {
|
||||||
|
fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
|
||||||
|
name);
|
||||||
|
fprintf(stderr, "Protocol being registered is \"%s\"\n",
|
||||||
|
proto_get_protocol_long_name(handle->protocol));
|
||||||
|
if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
|
||||||
|
abort();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sanity checks */
|
||||||
|
g_assert(handle!=NULL);
|
||||||
|
if (sub_dissectors->type != FT_GUID) {
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
|
||||||
|
dtbl_entry = (dtbl_entry_t *)g_malloc(sizeof (dtbl_entry_t));
|
||||||
|
dtbl_entry->current = handle;
|
||||||
|
dtbl_entry->initial = dtbl_entry->current;
|
||||||
|
|
||||||
|
/* do the table insertion */
|
||||||
|
g_hash_table_insert( sub_dissectors->hash_table,
|
||||||
|
guid_val, (gpointer)dtbl_entry);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now add it to the list of handles that could be used with this
|
||||||
|
* table, because it *is* being used with this table.
|
||||||
|
*/
|
||||||
|
dissector_add_handle(name, handle);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look for a given value in a given guid dissector table and, if found,
|
||||||
|
call the dissector with the arguments supplied, and return TRUE,
|
||||||
|
otherwise return FALSE. */
|
||||||
|
int dissector_try_guid_new(dissector_table_t sub_dissectors,
|
||||||
|
guid_key* guid_val, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const gboolean add_proto_name, void *data)
|
||||||
|
{
|
||||||
|
dtbl_entry_t *dtbl_entry;
|
||||||
|
struct dissector_handle *handle;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, guid_val);
|
||||||
|
if (dtbl_entry != NULL) {
|
||||||
|
/*
|
||||||
|
* Is there currently a dissector handle for this entry?
|
||||||
|
*/
|
||||||
|
handle = dtbl_entry->current;
|
||||||
|
if (handle == NULL) {
|
||||||
|
/*
|
||||||
|
* No - pretend this dissector didn't exist,
|
||||||
|
* so that other dissectors might have a chance
|
||||||
|
* to dissect this packet.
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save the current value of "pinfo->match_uint",
|
||||||
|
* set it to the uint_val that matched, call the
|
||||||
|
* dissector, and restore "pinfo->match_uint".
|
||||||
|
*/
|
||||||
|
len = call_dissector_work(handle, tvb, pinfo, tree, add_proto_name, data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a new-style dissector returned 0, it means that
|
||||||
|
* it didn't think this tvbuff represented a packet for
|
||||||
|
* its protocol, and didn't dissect anything.
|
||||||
|
*
|
||||||
|
* Old-style dissectors can't reject the packet.
|
||||||
|
*
|
||||||
|
* 0 is also returned if the protocol wasn't enabled.
|
||||||
|
*
|
||||||
|
* If the packet was rejected, we return 0, so that
|
||||||
|
* other dissectors might have a chance to dissect this
|
||||||
|
* packet, otherwise we return the dissected length.
|
||||||
|
*/
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dissector_try_guid(dissector_table_t sub_dissectors,
|
||||||
|
guid_key* guid_val, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||||
|
{
|
||||||
|
return dissector_try_guid_new(sub_dissectors, guid_val, tvb, pinfo, tree, TRUE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Look for a given value in a given guid dissector table and, if found,
|
||||||
|
* return the current dissector handle for that value.
|
||||||
|
*
|
||||||
|
* @param[in] sub_dissectors Dissector table to search.
|
||||||
|
* @param[in] uint_val Value to match, e.g. the port number for the TCP dissector.
|
||||||
|
* @return The matching dissector handle on success, NULL if no match is found.
|
||||||
|
*/
|
||||||
|
dissector_handle_t dissector_get_guid_handle(
|
||||||
|
dissector_table_t const sub_dissectors, guid_key* guid_val)
|
||||||
|
{
|
||||||
|
dtbl_entry_t *dtbl_entry;
|
||||||
|
|
||||||
|
dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, guid_val);
|
||||||
|
if (dtbl_entry != NULL)
|
||||||
|
return dtbl_entry->current;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
dissector_handle_t
|
dissector_handle_t
|
||||||
dtbl_entry_get_handle (dtbl_entry_t *dtbl_entry)
|
dtbl_entry_get_handle (dtbl_entry_t *dtbl_entry)
|
||||||
|
@ -1637,6 +1755,24 @@ dissector_table_get_type(dissector_table_t dissector_table) {
|
||||||
return dissector_table->type;
|
return dissector_table->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
uuid_equal(gconstpointer k1, gconstpointer k2)
|
||||||
|
{
|
||||||
|
const guid_key *key1 = (const guid_key *)k1;
|
||||||
|
const guid_key *key2 = (const guid_key *)k2;
|
||||||
|
return ((memcmp(&key1->guid, &key2->guid, sizeof (e_guid_t)) == 0)
|
||||||
|
&& (key1->ver == key2->ver));
|
||||||
|
}
|
||||||
|
|
||||||
|
static guint
|
||||||
|
uuid_hash(gconstpointer k)
|
||||||
|
{
|
||||||
|
const guid_key *key = (const guid_key *)k;
|
||||||
|
/* This isn't perfect, but the Data1 part of these is almost always
|
||||||
|
unique. */
|
||||||
|
return key->guid.data1;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* Routines to walk dissector tables */
|
/* Routines to walk dissector tables */
|
||||||
|
@ -1915,7 +2051,12 @@ register_dissector_table(const char *name, const char *ui_name, const ftenum_t t
|
||||||
&g_free,
|
&g_free,
|
||||||
&g_free );
|
&g_free );
|
||||||
break;
|
break;
|
||||||
|
case FT_GUID:
|
||||||
|
sub_dissectors->hash_table = g_hash_table_new_full( uuid_hash,
|
||||||
|
uuid_equal,
|
||||||
|
NULL,
|
||||||
|
&g_free );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "frame_data.h"
|
#include "frame_data.h"
|
||||||
#include "packet_info.h"
|
#include "packet_info.h"
|
||||||
#include "column-utils.h"
|
#include "column-utils.h"
|
||||||
|
#include "guid-utils.h"
|
||||||
#include "tfs.h"
|
#include "tfs.h"
|
||||||
#include "ws_symbol_export.h"
|
#include "ws_symbol_export.h"
|
||||||
|
|
||||||
|
@ -235,7 +236,7 @@ WS_DLL_PUBLIC int get_dissector_table_param(const char *name);
|
||||||
WS_DLL_PUBLIC void dissector_dump_dissector_tables(void);
|
WS_DLL_PUBLIC void dissector_dump_dissector_tables(void);
|
||||||
|
|
||||||
/* Add an entry to a uint dissector table. */
|
/* Add an entry to a uint dissector table. */
|
||||||
WS_DLL_PUBLIC void dissector_add_uint(const char *abbrev, const guint32 pattern,
|
WS_DLL_PUBLIC void dissector_add_uint(const char *name, const guint32 pattern,
|
||||||
dissector_handle_t handle);
|
dissector_handle_t handle);
|
||||||
|
|
||||||
/* Add an range of entries to a uint dissector table. */
|
/* Add an range of entries to a uint dissector table. */
|
||||||
|
@ -350,7 +351,39 @@ WS_DLL_PUBLIC void dissector_add_custom_table_handle(const char *name, void *pat
|
||||||
*/
|
*/
|
||||||
WS_DLL_PUBLIC dissector_handle_t dissector_get_custom_table_handle(
|
WS_DLL_PUBLIC dissector_handle_t dissector_get_custom_table_handle(
|
||||||
dissector_table_t sub_dissectors, void *key);
|
dissector_table_t sub_dissectors, void *key);
|
||||||
|
/* Key for GUID dissector tables. This is based off of DCE/RPC needs
|
||||||
|
so some dissector tables may not need the ver portion of the hash
|
||||||
|
*/
|
||||||
|
typedef struct _guid_key {
|
||||||
|
e_guid_t guid;
|
||||||
|
guint16 ver;
|
||||||
|
} guid_key;
|
||||||
|
|
||||||
|
/* Add an entry to a guid dissector table. */
|
||||||
|
WS_DLL_PUBLIC void dissector_add_guid(const char *name, guid_key* guid_val,
|
||||||
|
dissector_handle_t handle);
|
||||||
|
|
||||||
|
/* Look for a given value in a given guid dissector table and, if found,
|
||||||
|
call the dissector with the arguments supplied, and return TRUE,
|
||||||
|
otherwise return FALSE. */
|
||||||
|
WS_DLL_PUBLIC int dissector_try_guid(dissector_table_t sub_dissectors,
|
||||||
|
guid_key* guid_val, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
|
||||||
|
|
||||||
|
/* Look for a given value in a given guid dissector table and, if found,
|
||||||
|
call the dissector with the arguments supplied, and return TRUE,
|
||||||
|
otherwise return FALSE. */
|
||||||
|
WS_DLL_PUBLIC int dissector_try_guid_new(dissector_table_t sub_dissectors,
|
||||||
|
guid_key* guid_val, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const gboolean add_proto_name, void *data);
|
||||||
|
|
||||||
|
/** Look for a given value in a given guid dissector table and, if found,
|
||||||
|
* return the current dissector handle for that value.
|
||||||
|
*
|
||||||
|
* @param[in] sub_dissectors Dissector table to search.
|
||||||
|
* @param[in] uint_val Value to match, e.g. the port number for the TCP dissector.
|
||||||
|
* @return The matching dissector handle on success, NULL if no match is found.
|
||||||
|
*/
|
||||||
|
WS_DLL_PUBLIC dissector_handle_t dissector_get_guid_handle(
|
||||||
|
dissector_table_t const sub_dissectors, guid_key* guid_val);
|
||||||
|
|
||||||
/* Add a handle to the list of handles that *could* be used with this
|
/* 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. */
|
table. That list is used by the "Decode As"/"-d" code in the UI. */
|
||||||
|
|
Loading…
Reference in New Issue