WSLua DissectorTable GUID Support
This commit is contained in:
parent
14a934fb22
commit
ec001766f6
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <guid-utils.h>
|
||||
#include <stdio.h> /* for sscanf() */
|
||||
#include <epan/packet.h>
|
||||
#include <epan/exceptions.h>
|
||||
|
@ -1658,6 +1659,28 @@ dissect_dcerpc_guid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *d
|
|||
return tvb_captured_length(tvb);
|
||||
}
|
||||
|
||||
static void
|
||||
dcerpc_init_finalize(dissector_handle_t guid_handle, guid_key *key, dcerpc_uuid_value *value)
|
||||
{
|
||||
module_t *samr_module;
|
||||
const char *filter_name = proto_get_protocol_filter_name(value->proto_id);
|
||||
|
||||
g_hash_table_insert(dcerpc_uuids, key, value);
|
||||
|
||||
/* Register the GUID with the dissector table */
|
||||
dissector_add_guid( "dcerpc.uuid", key, guid_handle );
|
||||
|
||||
/* add this GUID to the global name resolving */
|
||||
guids_add_uuid(&key->guid, proto_get_protocol_short_name(value->proto));
|
||||
|
||||
/* Register the samr.nt_password preference as obsolete */
|
||||
/* This should be in packet-dcerpc-samr.c */
|
||||
if (strcmp(filter_name, "samr") == 0) {
|
||||
samr_module = prefs_register_protocol_obsolete(value->proto_id);
|
||||
prefs_register_obsolete_preference(samr_module, "nt_password");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dcerpc_init_uuid(int proto, int ett, e_guid_t *uuid, guint16 ver,
|
||||
dcerpc_sub_dissector *procs, int opnum_hf)
|
||||
|
@ -1665,8 +1688,6 @@ dcerpc_init_uuid(int proto, int ett, e_guid_t *uuid, guint16 ver,
|
|||
guid_key *key = (guid_key *)g_malloc(sizeof (*key));
|
||||
dcerpc_uuid_value *value = (dcerpc_uuid_value *)g_malloc(sizeof (*value));
|
||||
header_field_info *hf_info;
|
||||
module_t *samr_module;
|
||||
const char *filter_name = proto_get_protocol_filter_name(proto);
|
||||
dissector_handle_t guid_handle;
|
||||
|
||||
key->guid = *uuid;
|
||||
|
@ -1679,24 +1700,37 @@ dcerpc_init_uuid(int proto, int ett, e_guid_t *uuid, guint16 ver,
|
|||
value->procs = procs;
|
||||
value->opnum_hf = opnum_hf;
|
||||
|
||||
g_hash_table_insert(dcerpc_uuids, key, value);
|
||||
|
||||
hf_info = proto_registrar_get_nth(opnum_hf);
|
||||
hf_info->strings = value_string_from_subdissectors(procs);
|
||||
|
||||
/* Register the GUID with the dissector table */
|
||||
guid_handle = create_dissector_handle( dissect_dcerpc_guid, proto);
|
||||
dissector_add_guid( "dcerpc.uuid", key, guid_handle );
|
||||
|
||||
/* add this GUID to the global name resolving */
|
||||
guids_add_uuid(uuid, proto_get_protocol_short_name(value->proto));
|
||||
dcerpc_init_finalize(guid_handle, key, value);
|
||||
}
|
||||
|
||||
/* Register the samr.nt_password preference as obsolete */
|
||||
/* This should be in packet-dcerpc-samr.c */
|
||||
if (strcmp(filter_name, "samr") == 0) {
|
||||
samr_module = prefs_register_protocol_obsolete(proto);
|
||||
prefs_register_obsolete_preference(samr_module, "nt_password");
|
||||
void
|
||||
dcerpc_init_from_handle(int proto, e_guid_t *uuid, guint16 ver,
|
||||
dissector_handle_t guid_handle)
|
||||
{
|
||||
guid_key *key = (guid_key *)g_malloc(sizeof (*key));
|
||||
dcerpc_uuid_value *value = (dcerpc_uuid_value *)g_malloc(sizeof (*value));
|
||||
|
||||
key->guid = *uuid;
|
||||
key->ver = ver;
|
||||
|
||||
value->proto = find_protocol_by_id(proto);
|
||||
value->proto_id = proto;
|
||||
value->ett = -1;
|
||||
value->name = proto_get_protocol_short_name(value->proto);
|
||||
value->opnum_hf = 0;
|
||||
|
||||
if (g_hash_table_contains(dcerpc_uuids, key)) {
|
||||
g_hash_table_remove(dcerpc_uuids, key);
|
||||
guids_delete_guid(uuid);
|
||||
}
|
||||
|
||||
dcerpc_init_finalize(guid_handle, key, value);
|
||||
}
|
||||
|
||||
/* Function to find the name of a registered protocol
|
||||
|
|
|
@ -392,6 +392,8 @@ typedef struct _dcerpc_sub_dissector {
|
|||
WS_DLL_PUBLIC
|
||||
void dcerpc_init_uuid (int proto, int ett, e_guid_t *uuid, guint16 ver, dcerpc_sub_dissector *procs, int opnum_hf);
|
||||
WS_DLL_PUBLIC
|
||||
void dcerpc_init_from_handle(int proto, e_guid_t *uuid, guint16 ver, dissector_handle_t guid_handle);
|
||||
WS_DLL_PUBLIC
|
||||
const char *dcerpc_get_proto_name(e_guid_t *uuid, guint16 ver);
|
||||
WS_DLL_PUBLIC
|
||||
int dcerpc_get_proto_hf_opnum(e_guid_t *uuid, guint16 ver);
|
||||
|
|
|
@ -106,6 +106,47 @@ guids_add_guid(const e_guid_t *guid, const gchar *name)
|
|||
wmem_tree_insert32_array(guid_to_name_tree, &guidkey[0], (gchar *) name);
|
||||
}
|
||||
|
||||
/* remove a guid to name mapping */
|
||||
void
|
||||
guids_delete_guid(const e_guid_t *guid)
|
||||
{
|
||||
wmem_tree_key_t guidkey[2];
|
||||
guint32 g[4];
|
||||
|
||||
g[0] = guid->data1;
|
||||
|
||||
g[1] = guid->data2;
|
||||
g[1] <<= 16;
|
||||
g[1] |= guid->data3;
|
||||
|
||||
g[2] = guid->data4[0];
|
||||
g[2] <<= 8;
|
||||
g[2] |= guid->data4[1];
|
||||
g[2] <<= 8;
|
||||
g[2] |= guid->data4[2];
|
||||
g[2] <<= 8;
|
||||
g[2] |= guid->data4[3];
|
||||
|
||||
g[3] = guid->data4[4];
|
||||
g[3] <<= 8;
|
||||
g[3] |= guid->data4[5];
|
||||
g[3] <<= 8;
|
||||
g[3] |= guid->data4[6];
|
||||
g[3] <<= 8;
|
||||
g[3] |= guid->data4[7];
|
||||
|
||||
guidkey[0].key = g;
|
||||
guidkey[0].length = 4;
|
||||
guidkey[1].length = 0;
|
||||
|
||||
void *data = wmem_tree_lookup32_array(guid_to_name_tree, &guidkey[0]);
|
||||
|
||||
if (data != NULL) {
|
||||
// This will "remove" the entry by setting its data to NULL
|
||||
wmem_tree_insert32_array(guid_to_name_tree, &guidkey[0], NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* retrieve the registered name for this GUID; uses the scope for the fallback case only */
|
||||
const gchar *
|
||||
|
|
|
@ -35,6 +35,9 @@ WS_DLL_PUBLIC void guids_init(void);
|
|||
/* add a GUID */
|
||||
WS_DLL_PUBLIC void guids_add_guid(const e_guid_t *guid, const gchar *name);
|
||||
|
||||
/* remove a guid to name mapping */
|
||||
WS_DLL_PUBLIC void guids_delete_guid(const e_guid_t *guid);
|
||||
|
||||
/* try to get registered name for this GUID */
|
||||
WS_DLL_PUBLIC const gchar *guids_get_guid_name(const e_guid_t *guid, wmem_allocator_t *scope);
|
||||
|
||||
|
|
|
@ -1381,6 +1381,36 @@ void dissector_delete_uint_range(const char *name, range_t *range,
|
|||
}
|
||||
}
|
||||
|
||||
/* Remove an entry from a guid dissector table. */
|
||||
void dissector_delete_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);
|
||||
|
||||
/* sanity check */
|
||||
ws_assert(sub_dissectors);
|
||||
|
||||
/* Find the table entry */
|
||||
dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, guid_val);
|
||||
|
||||
if (dtbl_entry == NULL) {
|
||||
fprintf(stderr, "OOPS: guid not found in dissector table \"%s\"\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Make sure the handles match */
|
||||
if (dtbl_entry->current != handle) {
|
||||
fprintf(stderr, "OOPS: handle does not match for guid in dissector table \"%s\"\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remove the table entry */
|
||||
g_hash_table_remove(sub_dissectors->hash_table, guid_val);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
dissector_delete_all_check (gpointer key _U_, gpointer value, gpointer user_data)
|
||||
{
|
||||
|
|
|
@ -383,6 +383,10 @@ WS_DLL_PUBLIC int dissector_try_guid(dissector_table_t sub_dissectors,
|
|||
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);
|
||||
|
||||
/* Delete a GUID from a dissector table. */
|
||||
WS_DLL_PUBLIC void dissector_delete_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,
|
||||
* return the current dissector handle for that value.
|
||||
*
|
||||
|
|
|
@ -17,11 +17,15 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include "epan/guid-utils.h"
|
||||
#include "epan/proto.h"
|
||||
#include "wslua.h"
|
||||
|
||||
#include <epan/decode_as.h>
|
||||
#include <epan/exceptions.h>
|
||||
#include <epan/show_exception.h>
|
||||
#include <epan/dissectors/packet-dcerpc.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* WSLUA_CONTINUE_MODULE Proto */
|
||||
|
@ -166,8 +170,8 @@ WSLUA_CONSTRUCTOR DissectorTable_new (lua_State *L) {
|
|||
#define WSLUA_OPTARG_DissectorTable_new_UINAME 2 /* The name of the table in the user interface.
|
||||
Defaults to the name given in `tablename`, but can be any string. */
|
||||
#define WSLUA_OPTARG_DissectorTable_new_TYPE 3 /* One of `ftypes.UINT8`, `ftypes.UINT16`,
|
||||
`ftypes.UINT24`, `ftypes.UINT32`, or
|
||||
`ftypes.STRING`.
|
||||
`ftypes.UINT24`, `ftypes.UINT32`,
|
||||
`ftypes.STRING`, or `ftypes.GUID`.
|
||||
Defaults to `ftypes.UINT32`. */
|
||||
#define WSLUA_OPTARG_DissectorTable_new_BASE 4 /* One of `base.NONE`, `base.DEC`, `base.HEX`,
|
||||
`base.OCT`, `base.DEC_HEX` or `base.HEX_DEC`.
|
||||
|
@ -194,12 +198,16 @@ WSLUA_CONSTRUCTOR DissectorTable_new (lua_State *L) {
|
|||
case FT_UINT32:
|
||||
break;
|
||||
|
||||
case FT_GUID:
|
||||
base = BASE_HEX;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Calling WSLUA_OPTARG_ERROR raises a Lua error and
|
||||
returns from this function. */
|
||||
WSLUA_OPTARG_ERROR(
|
||||
DissectorTable_new, TYPE,
|
||||
"must be ftypes.UINT{8,16,24,32}, ftypes.STRING or ftypes.NONE");
|
||||
"must be ftypes.UINT{8,16,24,32}, ftypes.STRING, ftypes.GUID or ftypes.NONE");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -397,6 +405,21 @@ WSLUA_METHOD DissectorTable_add (lua_State *L) {
|
|||
gchar* pattern = g_strdup(luaL_checkstring(L,WSLUA_ARG_DissectorTable_add_PATTERN));
|
||||
dissector_add_string(dt->name, pattern,handle);
|
||||
g_free (pattern);
|
||||
} else if (type == FT_GUID) {
|
||||
/* Handle GUID type (assuming it is represented as a string in Lua) */
|
||||
const gchar* guid_str = luaL_checkstring(L,WSLUA_ARG_DissectorTable_add_PATTERN);
|
||||
fvalue_t* fval = fvalue_from_literal(type, guid_str, 0, NULL);
|
||||
const e_guid_t* guid = fvalue_get_guid(fval);
|
||||
guid_key gk = {*guid, 0};
|
||||
/* The dcerpc.uuid table requires its own initializer */
|
||||
if(strcmp(DCERPC_TABLE_NAME, dt->name) == 0) {
|
||||
e_guid_t uuid;
|
||||
memcpy(&uuid, guid, sizeof(e_guid_t));
|
||||
dcerpc_init_from_handle(dissector_handle_get_protocol_index(handle), &uuid, 0, handle);
|
||||
} else {
|
||||
dissector_add_guid(dt->name, &gk, handle);
|
||||
guids_add_uuid(guid, dissector_handle_get_protocol_short_name(handle));
|
||||
}
|
||||
} else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
|
||||
if (lua_isnumber(L, WSLUA_ARG_DissectorTable_add_PATTERN)) {
|
||||
int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_add_PATTERN);
|
||||
|
@ -459,6 +482,21 @@ WSLUA_METHOD DissectorTable_set (lua_State *L) {
|
|||
const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_set_PATTERN);
|
||||
dissector_delete_all(dt->name, handle);
|
||||
dissector_add_string(dt->name, pattern,handle);
|
||||
} else if (type == FT_GUID) {
|
||||
/* Handle GUID type (assuming it is represented as a string in Lua) */
|
||||
const gchar* guid_str = luaL_checkstring(L,WSLUA_ARG_DissectorTable_set_PATTERN);
|
||||
fvalue_t* fval = fvalue_from_literal(type, guid_str, 0, NULL);
|
||||
const e_guid_t* guid = fvalue_get_guid(fval);
|
||||
guid_key gk = {*guid, 0};
|
||||
/* The dcerpc.uuid table requires its own initializer */
|
||||
if(strcmp(DCERPC_TABLE_NAME, dt->name) == 0) {
|
||||
e_guid_t uuid;
|
||||
memcpy(&uuid, guid, sizeof(e_guid_t));
|
||||
dcerpc_init_from_handle(dissector_handle_get_protocol_index(handle), &uuid, 0, handle);
|
||||
} else {
|
||||
dissector_add_guid(dt->name, &gk, handle);
|
||||
guids_add_uuid(guid, dissector_handle_get_protocol_short_name(handle));
|
||||
}
|
||||
} else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
|
||||
if (lua_isnumber(L, WSLUA_ARG_DissectorTable_set_PATTERN)) {
|
||||
int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_set_PATTERN);
|
||||
|
@ -515,6 +553,14 @@ WSLUA_METHOD DissectorTable_remove (lua_State *L) {
|
|||
gchar* pattern = g_strdup(luaL_checkstring(L,WSLUA_ARG_DissectorTable_remove_PATTERN));
|
||||
dissector_delete_string(dt->name, pattern,handle);
|
||||
g_free (pattern);
|
||||
} else if (type == FT_GUID) {
|
||||
// Handle GUID type (assuming it is represented as a string in Lua)
|
||||
const gchar* guid_str = luaL_checkstring(L,WSLUA_ARG_DissectorTable_remove_PATTERN);
|
||||
fvalue_t* fval = fvalue_from_literal(type, guid_str, 0, NULL);
|
||||
const e_guid_t* guid = fvalue_get_guid(fval);
|
||||
guid_key gk = {*guid, 0};
|
||||
guids_delete_guid(guid);
|
||||
dissector_delete_guid(dt->name, &gk, handle);
|
||||
} else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
|
||||
if (lua_isnumber(L, WSLUA_ARG_DissectorTable_remove_PATTERN)) {
|
||||
int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_remove_PATTERN);
|
||||
|
@ -596,6 +642,16 @@ WSLUA_METHOD DissectorTable_try (lua_State *L) {
|
|||
if (len > 0) {
|
||||
handled = TRUE;
|
||||
}
|
||||
} else if ( type == FT_GUID ) {
|
||||
const gchar* guid_str = luaL_checkstring(L,WSLUA_ARG_DissectorTable_try_PATTERN);
|
||||
fvalue_t* fval = fvalue_from_literal(type, guid_str, 0, NULL);
|
||||
const e_guid_t* guid = fvalue_get_guid(fval);
|
||||
guid_key gk = {*guid, 0};
|
||||
|
||||
len = dissector_try_guid(dt->table, &gk,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree);
|
||||
if (len > 0) {
|
||||
handled = TRUE;
|
||||
}
|
||||
} else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
|
||||
int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_try_PATTERN);
|
||||
|
||||
|
@ -639,6 +695,12 @@ WSLUA_METHOD DissectorTable_get_dissector (lua_State *L) {
|
|||
if (type == FT_STRING) {
|
||||
const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_get_dissector_PATTERN);
|
||||
handle = dissector_get_string_handle(dt->table,pattern);
|
||||
} else if ( type == FT_GUID ) {
|
||||
const gchar* guid_str = luaL_checkstring(L,WSLUA_ARG_DissectorTable_get_dissector_PATTERN);
|
||||
fvalue_t* fval = fvalue_from_literal(type, guid_str, 0, NULL);
|
||||
const e_guid_t* guid = fvalue_get_guid(fval);
|
||||
guid_key gk = {*guid, 0};
|
||||
handle = dissector_get_guid_handle(dt->table,&gk);
|
||||
} else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
|
||||
int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_get_dissector_PATTERN);
|
||||
handle = dissector_get_uint_handle(dt->table,port);
|
||||
|
@ -703,6 +765,11 @@ WSLUA_METAMETHOD DissectorTable__tostring(lua_State* L) {
|
|||
g_string_append_printf(s,"%s Integer(%i):\n",dt->name,base);
|
||||
break;
|
||||
}
|
||||
case FT_GUID:
|
||||
{
|
||||
g_string_append_printf(s,"%s GUID:\n",dt->name);
|
||||
break;
|
||||
}
|
||||
case FT_NONE:
|
||||
{
|
||||
g_string_append_printf(s,"%s only for Decode As:\n",dt->name);
|
||||
|
|
Loading…
Reference in New Issue