aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorStig Bjørlykke <stig@bjorlykke.org>2011-10-18 17:46:00 +0000
committerStig Bjørlykke <stig@bjorlykke.org>2011-10-18 17:46:00 +0000
commit82e0b650388aa4f89c4fc371eab057b278b59f92 (patch)
tree1e4c56840b5168eaee0ac033059ea671f00f79a4 /epan
parentcc4fe5789b6f294df614afafb6c265e3171370ee (diff)
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
Diffstat (limited to 'epan')
-rw-r--r--epan/packet_info.h1
-rw-r--r--epan/wslua/init_wslua.c1
-rw-r--r--epan/wslua/wslua.h8
-rw-r--r--epan/wslua/wslua_pinfo.c152
4 files changed, 162 insertions, 0 deletions
diff --git a/epan/packet_info.h b/epan/packet_info.h
index 646a24a7be..94ee3c1b42 100644
--- a/epan/packet_info.h
+++ b/epan/packet_info.h
@@ -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;
diff --git a/epan/wslua/init_wslua.c b/epan/wslua/init_wslua.c
index ede501fd38..a49204f7e0 100644
--- a/epan/wslua/init_wslua.c
+++ b/epan/wslua/init_wslua.c
@@ -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();
}
diff --git a/epan/wslua/wslua.h b/epan/wslua/wslua.h
index a7a6447354..ffa2a84c37 100644
--- a/epan/wslua/wslua.h
+++ b/epan/wslua/wslua.h
@@ -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);
diff --git a/epan/wslua/wslua_pinfo.c b/epan/wslua/wslua_pinfo.c
index b6e87cb404..4b197ae60b 100644
--- a/epan/wslua/wslua_pinfo.c
+++ b/epan/wslua/wslua_pinfo.c
@@ -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;
}