aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/lua/lua_proto.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/lua/lua_proto.c')
-rw-r--r--plugins/lua/lua_proto.c139
1 files changed, 95 insertions, 44 deletions
diff --git a/plugins/lua/lua_proto.c b/plugins/lua/lua_proto.c
index 596038b7a0..bfd1c5c30c 100644
--- a/plugins/lua/lua_proto.c
+++ b/plugins/lua/lua_proto.c
@@ -131,6 +131,7 @@ static int ProtoField_new(lua_State* L) {
ProtoField f = g_malloc(sizeof(eth_field_t));
GArray* vs;
+ /* will be using -2 as far as the field has not been added to an array then it will turn -1 */
f->hfid = -2;
f->name = g_strdup(luaL_checkstring(L,1));
f->abbr = g_strdup(luaL_checkstring(L,2));
@@ -246,6 +247,30 @@ static int ProtoField_tostring(lua_State* L) {
return 1;
}
+static int ProtoField_gc(lua_State* L) {
+ ProtoField f = checkProtoField(L,1);
+
+ /*
+ * A garbage collector for ProtoFields makes little sense.
+ * Even if This cannot be used anymore because it has gone out of scope,
+ * we can destroy the ProtoField only if it is not part of a ProtoFieldArray,
+ * if it actualy belongs to one we need to preserve it as it is pointed by
+ * a field array that may be registered afterwards causing a crash or memory corruption.
+ */
+
+ if (!f) {
+ luaL_argerror(L,1,"BUG: ProtoField_gc called for something not ProtoField");
+ /* g_assert() ?? */
+ } else if (f->hfid == -2) {
+ g_free(f->name);
+ g_free(f->abbr);
+ g_free(f->blob);
+ g_free(f);
+ }
+
+ return 0;
+}
+
static const luaL_reg ProtoField_methods[] = {
{"new", ProtoField_new},
@@ -277,7 +302,8 @@ static const luaL_reg ProtoField_methods[] = {
};
static const luaL_reg ProtoField_meta[] = {
- {"__tostring", ProtoField_tostring},
+ {"__gc", ProtoField_gc },
+ {"__tostring", ProtoField_tostring },
{0, 0}
};
@@ -385,9 +411,20 @@ static int ProtoFieldArray_tostring(lua_State* L) {
}
static int ProtoFieldArray_gc(lua_State* L) {
- ProtoFieldArray vs = checkValueString(L,1);
+ ProtoFieldArray fa = checkValueString(L,1);
+ gboolean free_it = FALSE;
- g_array_free(vs,TRUE);
+ /* we'll keep the data if the array was registered to a protocol */
+ if (fa->len) {
+ hf_register_info* f = (hf_register_info*)fa->data;
+
+ if ( *(f->p_id) == -2)
+ free_it = TRUE;
+ } else {
+ free_it = TRUE;
+ }
+
+ g_array_free(fa,free_it);
return 0;
}
@@ -560,6 +597,7 @@ static int SubTreeTypeArray_register_to_ethereal(lua_State* L) {
static int SubTreeTypeArray_gc(lua_State* L) {
SubTreeTypeArray ea = checkSubTreeTypeArray(L,1);
+ /* XXX - free the array if unregistered */
g_array_free(ea,FALSE);
return 0;
@@ -603,51 +641,34 @@ int SubTreeTypeArray_register(lua_State* L) {
static int Proto_new(lua_State* L) {
- Proto proto;
const gchar* name = luaL_checkstring(L,1);
- const gchar* filter = luaL_checkstring(L,2);
- const gchar* desc = luaL_checkstring(L,3);
-
- if (! (name && filter && desc) ) return 0;
-
- proto = g_malloc(sizeof(eth_proto_t));
-
- proto->hfid = -1;
- proto->name = g_strdup(name);
- proto->filter = g_strdup(filter);
- proto->desc = g_strdup(desc);
- proto->hfarray = NULL;
- proto->prefs_module = NULL;
- proto->prefs = NULL;
- proto->handle = NULL;
- proto->is_postdissector = FALSE;
-
- if (proto->name && proto->filter && proto->desc) {
- if ( proto_get_id_by_filter_name(proto->filter) > 0 ) {
- g_free(proto);
- luaL_argerror(L,2,"Protocol exists already");
+ const gchar* desc = luaL_optstring(L,2,"");
+
+ if ( name ) {
+ if ( proto_get_id_by_filter_name(name) > 0 ) {
+ luaL_argerror(L,1,"Protocol exists already");
return 0;
} else {
+ Proto proto = g_malloc(sizeof(eth_proto_t));
+
+ /* XXX - using the same name and filtername to have to deal just with one name */
+ proto->name = g_strdup(name);
+ proto->filter = proto->name;
+ proto->desc = g_strdup(desc);
+ proto->hfarray = NULL;
+ proto->prefs_module = NULL;
+ proto->prefs = NULL;
+ proto->is_postdissector = FALSE;
proto->hfid = proto_register_protocol(proto->desc,proto->name,proto->filter);
proto->handle = create_dissector_handle(dissect_lua,proto->hfid);
+
pushProto(L,proto);
return 1;
}
} else {
- if (! proto->name )
- luaL_argerror(L,1,"missing name");
-
- if (! proto->filter )
- luaL_argerror(L,2,"missing filter");
-
- if (! proto->desc )
- luaL_argerror(L,3,"missing desc");
-
- g_free(proto);
-
- return 0;
+ luaL_argerror(L,1,"missing name");
+ return 0;
}
-
}
static int Proto_register_field_array(lua_State* L) {
@@ -672,6 +693,10 @@ static int Proto_register_field_array(lua_State* L) {
if (proto->hfarray) {
luaL_argerror(L,1,"field_array already registered for this protocol");
}
+
+ if ( *(((hf_register_info*)(fa->data))->p_id) != -1 ) {
+ luaL_argerror(L,1,"this field_array has been already registered to another protocol");
+ }
proto->hfarray = (hf_register_info*)(fa->data);
proto_register_field_array(proto->hfid,proto->hfarray,fa->len);
@@ -771,7 +796,6 @@ static int Proto_add_string_pref(lua_State* L) {
return 0;
}
-
static int Proto_get_pref(lua_State* L) {
Proto proto = checkProto(L,1);
const gchar* abbr = luaL_checkstring(L,2);
@@ -975,6 +999,9 @@ static int DissectorTable_new (lua_State *L) {
switch(type) {
case FT_STRING:
base = BASE_NONE;
+ case FT_UINT8:
+ case FT_UINT16:
+ case FT_UINT24:
case FT_UINT32:
{
DissectorTable dt = g_malloc(sizeof(struct _eth_distbl_t));
@@ -1027,7 +1054,7 @@ static int DissectorTable_add (lua_State *L) {
if (type == FT_STRING) {
gchar* pattern = g_strdup(luaL_checkstring(L,2));
dissector_add_string(dt->name, pattern,p->handle);
- } else if ( type == FT_UINT32 ) {
+ } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
int port = luaL_checkint(L, 2);
dissector_add(dt->name, port, p->handle);
}
@@ -1035,6 +1062,26 @@ static int DissectorTable_add (lua_State *L) {
return 0;
}
+static int DissectorTable_remove (lua_State *L) {
+ DissectorTable dt = checkDissectorTable(L,1);
+ Proto p = checkProto(L,3);
+ ftenum_t type;
+
+ if (!(dt && p)) return 0;
+
+ type = get_dissector_table_selector_type(dt->name);
+
+ if (type == FT_STRING) {
+ gchar* pattern = g_strdup(luaL_checkstring(L,2));
+ dissector_delete_string(dt->name, pattern,p->handle);
+ } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
+ int port = luaL_checkint(L, 2);
+ dissector_delete(dt->name, port, p->handle);
+ }
+
+ return 0;
+}
+
static int DissectorTable_try (lua_State *L) {
DissectorTable dt = checkDissectorTable(L,1);
@@ -1054,7 +1101,7 @@ static int DissectorTable_try (lua_State *L) {
if (dissector_try_string(dt->table,pattern,tvb,pinfo,tree))
return 0;
- } else if ( type == FT_UINT32 ) {
+ } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
int port = luaL_checkint(L, 2);
if (dissector_try_port(dt->table,port,tvb,pinfo,tree))
return 0;
@@ -1078,7 +1125,7 @@ static int DissectorTable_get_dissector (lua_State *L) {
if (type == FT_STRING) {
const gchar* pattern = luaL_checkstring(L,2);
handle = dissector_get_string_handle(dt->table,pattern);
- } else if ( type == FT_UINT32 ) {
+ } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
int port = luaL_checkint(L, 2);
handle = dissector_get_port_handle(dt->table,port);
}
@@ -1106,6 +1153,9 @@ static int DissectorTable_tostring(lua_State* L) {
g_string_sprintfa(s,"%s String:\n",dt->name);
break;
}
+ case FT_UINT8:
+ case FT_UINT16:
+ case FT_UINT24:
case FT_UINT32:
{
int base = get_dissector_table_base(dt->name);
@@ -1122,9 +1172,10 @@ static int DissectorTable_tostring(lua_State* L) {
}
static const luaL_reg DissectorTable_methods[] = {
- {"new", DissectorTable_new},
- {"get", DissectorTable_get},
+ {"new", DissectorTable_new },
+ {"get", DissectorTable_get },
{"add", DissectorTable_add },
+ {"remove", DissectorTable_remove },
{"try", DissectorTable_try },
{"get_dissector", DissectorTable_get_dissector },
{0,0}