Added a private hash table to transport string values between dissectors.
This works between C and Lua. In C the pinfo.private_table pointer must be initialized using g_hash_table_new (g_str_hash, g_str_equal); In Lua the values are available using pinfo.private.<key>, and the table is created automatically on first usage. It's possible to use this datatypes: nil, boolean, number and string, but every value is converted to string so numbers must be converted using tonumber() on usage. Boolean is either nil or an empty string. svn path=/trunk/; revision=39461
This commit is contained in:
parent
cc4fe5789b
commit
82e0b65038
|
@ -175,6 +175,7 @@ typedef struct _packet_info {
|
|||
* in the SCTP packet
|
||||
*/
|
||||
void *private_data; /* pointer to data passed from one dissector to another */
|
||||
GHashTable *private_table; /* a hash table passed from one dissector to another */
|
||||
/* TODO: Use emem_strbuf_t instead */
|
||||
GString *layer_names; /* layers of each protocol */
|
||||
guint16 link_number;
|
||||
|
|
|
@ -56,6 +56,7 @@ static void lua_frame_end(void)
|
|||
clear_outstanding_Pinfo();
|
||||
clear_outstanding_Column();
|
||||
clear_outstanding_Columns();
|
||||
clear_outstanding_PrivateTable();
|
||||
clear_outstanding_TreeItem();
|
||||
}
|
||||
|
||||
|
|
|
@ -165,6 +165,12 @@ struct _wslua_cols {
|
|||
gboolean expired;
|
||||
};
|
||||
|
||||
struct _wslua_private_table {
|
||||
GHashTable *table;
|
||||
gboolean is_allocated;
|
||||
gboolean expired;
|
||||
};
|
||||
|
||||
struct _wslua_treeitem {
|
||||
proto_item* item;
|
||||
proto_tree* tree;
|
||||
|
@ -237,6 +243,7 @@ typedef tvbparse_elem_t* Node;
|
|||
typedef tvbparse_action_t* Shortcut;
|
||||
typedef struct _wslua_main* WireShark;
|
||||
typedef struct _wslua_dir* Dir;
|
||||
typedef struct _wslua_private_table* PrivateTable;
|
||||
|
||||
/*
|
||||
* toXxx(L,idx) gets a Xxx from an index (Lua Error if fails)
|
||||
|
@ -397,6 +404,7 @@ extern Pinfo* push_Pinfo(lua_State* L, packet_info* p);
|
|||
extern void clear_outstanding_Pinfo(void);
|
||||
extern void clear_outstanding_Column(void);
|
||||
extern void clear_outstanding_Columns(void);
|
||||
extern void clear_outstanding_PrivateTable(void);
|
||||
|
||||
extern TreeItem* push_TreeItem(lua_State* L, TreeItem ti);
|
||||
extern void clear_outstanding_TreeItem(void);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*
|
||||
* (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
|
||||
* (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
|
||||
* (c) 2011, Stig Bjorlykke <stig@bjorlykke.org>
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
|
@ -48,10 +49,12 @@
|
|||
static GPtrArray* outstanding_Pinfo = NULL;
|
||||
static GPtrArray* outstanding_Column = NULL;
|
||||
static GPtrArray* outstanding_Columns = NULL;
|
||||
static GPtrArray* outstanding_PrivateTable = NULL;
|
||||
|
||||
CLEAR_OUTSTANDING(Pinfo,expired, TRUE)
|
||||
CLEAR_OUTSTANDING(Column,expired, TRUE)
|
||||
CLEAR_OUTSTANDING(Columns,expired, TRUE)
|
||||
CLEAR_OUTSTANDING(PrivateTable,expired, TRUE)
|
||||
|
||||
Pinfo* push_Pinfo(lua_State* L, packet_info* ws_pinfo) {
|
||||
Pinfo pinfo = NULL;
|
||||
|
@ -66,6 +69,7 @@ Pinfo* push_Pinfo(lua_State* L, packet_info* ws_pinfo) {
|
|||
|
||||
#define PUSH_COLUMN(L,c) {g_ptr_array_add(outstanding_Column,c);pushColumn(L,c);}
|
||||
#define PUSH_COLUMNS(L,c) {g_ptr_array_add(outstanding_Columns,c);pushColumns(L,c);}
|
||||
#define PUSH_PRIVATE_TABLE(L,c) {g_ptr_array_add(outstanding_PrivateTable,c);pushPrivateTable(L,c);}
|
||||
|
||||
WSLUA_CLASS_DEFINE(NSTime,NOP,NOP);
|
||||
/* NSTime represents a nstime_t. This is an object with seconds and nano seconds. */
|
||||
|
@ -819,6 +823,117 @@ int Columns_register(lua_State *L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
WSLUA_CLASS_DEFINE(PrivateTable,NOP,NOP);
|
||||
/* PrivateTable represents the pinfo->private_table. */
|
||||
|
||||
WSLUA_METAMETHOD PrivateTable__tostring(lua_State* L) {
|
||||
PrivateTable priv = checkPrivateTable(L,1);
|
||||
GString *key_string = g_string_new ("");
|
||||
GList *keys, *key;
|
||||
|
||||
if (!priv) return 0;
|
||||
|
||||
keys = g_hash_table_get_keys (priv->table);
|
||||
key = g_list_first (keys);
|
||||
while (key) {
|
||||
key_string = g_string_append (key_string, key->data);
|
||||
key = g_list_next (key);
|
||||
if (key) {
|
||||
key_string = g_string_append_c (key_string, ',');
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushstring(L,ep_strdup(key_string->str));
|
||||
|
||||
g_string_free (key_string, TRUE);
|
||||
g_list_free (keys);
|
||||
|
||||
WSLUA_RETURN(1); /* A string with all keys in the table, mostly for debugging. */
|
||||
}
|
||||
|
||||
static int PrivateTable__index(lua_State* L) {
|
||||
/* Gets the text of a specific entry */
|
||||
PrivateTable priv = checkPrivateTable(L,1);
|
||||
const gchar* name = luaL_checkstring(L,2);
|
||||
const gchar* string;
|
||||
|
||||
if (! (priv && name) ) return 0;
|
||||
|
||||
if (priv->expired) {
|
||||
luaL_error(L,"expired private_table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
string = g_hash_table_lookup (priv->table, (gpointer) name);
|
||||
|
||||
if (string) {
|
||||
lua_pushstring(L, string);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int PrivateTable__newindex(lua_State* L) {
|
||||
/* Sets the text of a specific entry */
|
||||
PrivateTable priv = checkPrivateTable(L,1);
|
||||
const gchar* name = luaL_checkstring(L,2);
|
||||
const gchar* string = NULL;
|
||||
|
||||
if (! (priv && name) ) return 0;
|
||||
|
||||
if (priv->expired) {
|
||||
luaL_error(L,"expired private_table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isstring(L,3)) {
|
||||
/* This also catches numbers, which is converted to string */
|
||||
string = luaL_checkstring(L,3);
|
||||
} else if (lua_isboolean(L,3)) {
|
||||
/* We support boolean by setting a empty string if true and NULL if false */
|
||||
string = lua_toboolean(L,3) ? "" : NULL;
|
||||
} else if (!lua_isnil(L,3)) {
|
||||
luaL_error(L,"unsupported type: %s", lua_typename(L,3));
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_hash_table_replace (priv->table, (gpointer) name, (gpointer) string);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int PrivateTable__gc(lua_State* L) {
|
||||
PrivateTable priv = checkPrivateTable(L,1);
|
||||
|
||||
if (!priv) return 0;
|
||||
|
||||
if (!priv->expired) {
|
||||
priv->expired = TRUE;
|
||||
} else {
|
||||
if (priv->is_allocated) {
|
||||
g_hash_table_destroy (priv->table);
|
||||
}
|
||||
g_free(priv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_META PrivateTable_meta[] = {
|
||||
{"__index", PrivateTable__index},
|
||||
{"__newindex", PrivateTable__newindex},
|
||||
{"__tostring", PrivateTable__tostring},
|
||||
{"__gc", PrivateTable__gc},
|
||||
{ NULL, NULL}
|
||||
};
|
||||
|
||||
int PrivateTable_register(lua_State* L) {
|
||||
WSLUA_REGISTER_META(PrivateTable);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
WSLUA_CLASS_DEFINE(Pinfo,FAIL_ON_NULL("expired pinfo"),NOP);
|
||||
/* Packet information */
|
||||
|
@ -960,6 +1075,39 @@ static int Pinfo_columns(lua_State *L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int Pinfo_private(lua_State *L) {
|
||||
PrivateTable priv = NULL;
|
||||
Pinfo pinfo = checkPinfo(L,1);
|
||||
const gchar* privname = luaL_optstring(L,2,NULL);
|
||||
gboolean is_allocated = FALSE;
|
||||
|
||||
if (!pinfo) return 0;
|
||||
|
||||
if (pinfo->expired) {
|
||||
luaL_error(L,"expired private_table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pinfo->ws_pinfo->private_table) {
|
||||
pinfo->ws_pinfo->private_table = g_hash_table_new(g_str_hash,g_str_equal);
|
||||
is_allocated = TRUE;
|
||||
}
|
||||
|
||||
priv = g_malloc(sizeof(struct _wslua_private_table));
|
||||
priv->table = pinfo->ws_pinfo->private_table;
|
||||
priv->is_allocated = is_allocated;
|
||||
priv->expired = FALSE;
|
||||
|
||||
if (!privname) {
|
||||
PUSH_PRIVATE_TABLE(L,priv);
|
||||
} else {
|
||||
lua_settop(L,0);
|
||||
PUSH_PRIVATE_TABLE(L,priv);
|
||||
lua_pushstring(L,privname);
|
||||
return PrivateTable__index(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
PARAM_NONE,
|
||||
|
@ -1193,6 +1341,9 @@ static const pinfo_method_t Pinfo_methods[] = {
|
|||
/* WSLUA_ATTRIBUTE Pinfo_private_data RO Access to private data */
|
||||
{"private_data", Pinfo_private_data, pushnil_param, PARAM_NONE},
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_private RW Access to the private table entries */
|
||||
{"private", Pinfo_private, pushnil_param, PARAM_NONE},
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_ethertype RW Ethernet Type Code, if this is an Ethernet packet */
|
||||
{"ethertype", Pinfo_ethertype, Pinfo_set_int, PARAM_ETHERTYPE},
|
||||
|
||||
|
@ -1298,5 +1449,6 @@ int Pinfo_register(lua_State* L) {
|
|||
outstanding_Pinfo = g_ptr_array_new();
|
||||
outstanding_Column = g_ptr_array_new();
|
||||
outstanding_Columns = g_ptr_array_new();
|
||||
outstanding_PrivateTable = g_ptr_array_new();
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue