From 3cbb83e490f8e553f2f688577c9788c884787727 Mon Sep 17 00:00:00 2001 From: Luis Ontanon Date: Wed, 25 Jan 2006 22:39:07 +0000 Subject: One step at a time several fixes and additions svn path=/trunk/; revision=17103 --- plugins/lua/lua_pinfo.c | 13 +++-- plugins/lua/lua_proto.c | 139 ++++++++++++++++++++++++++++++++--------------- plugins/lua/lua_tap.c | 133 +++++++++++++++++++++++++++------------------ plugins/lua/lua_tvb.c | 4 +- plugins/lua/packet-lua.c | 6 ++ plugins/lua/packet-lua.h | 2 + 6 files changed, 190 insertions(+), 107 deletions(-) (limited to 'plugins') diff --git a/plugins/lua/lua_pinfo.c b/plugins/lua/lua_pinfo.c index d6ba4a6a74..0da1f555d7 100644 --- a/plugins/lua/lua_pinfo.c +++ b/plugins/lua/lua_pinfo.c @@ -300,10 +300,11 @@ static int Column_tostring(lua_State *L) { Column c = checkColumn(L,1); const gchar* name; - if (!(c && c->cinfo)) { - lua_pushstring(L,"Bad Column"); - return 1; + if (!(c)) { + luaL_error(L,"Bad column"); + return 0; } else { + /* TODO: format the column */ name = col_id_to_name(c->col); lua_pushstring(L,name ? name : "Unknown Column"); } @@ -433,18 +434,18 @@ static int Columns_newindex(lua_State *L) { static int Columns_index(lua_State *L) { Columns cols = checkColumns(L,1); const struct col_names_t* cn; - const char* colname; + const char* colname = luaL_checkstring(L,2); if (!cols) { Column c = g_malloc(sizeof(struct _eth_col_info)); c->cinfo = NULL; - c->col = 0; + c->col = col_name_to_id(colname); pushColumn(L,c); return 1; } - colname = luaL_checkstring(L,2); + if (!colname) return 0; 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} diff --git a/plugins/lua/lua_tap.c b/plugins/lua/lua_tap.c index 54aa9a1c30..fa3c895cb0 100644 --- a/plugins/lua/lua_tap.c +++ b/plugins/lua/lua_tap.c @@ -33,18 +33,18 @@ LUA_CLASS_DEFINE(Field,FIELD,NOP); static int Field_get (lua_State *L) { const gchar* name = luaL_checkstring(L,1); - Field i; + Field f; if (!name) return 0; - i = proto_registrar_get_byname(name); + f = proto_registrar_get_byname(name); - if (!i) { + if (!f) { luaL_error(L,"Could not find field `%s'",name); return 0; } - pushField(L,i); + pushField(L,f); return 1; } @@ -55,50 +55,51 @@ static int Field_fetch (lua_State* L) { for (;in;in = in->same_name_next) { GPtrArray* found = proto_find_finfo(lua_tree, in->id); guint i; - - for (i=0; ilen; i++) { - field_info* fi = g_ptr_array_index(found,i); - switch(fi->hfinfo->type) { - case FT_UINT8: - case FT_UINT16: - case FT_UINT24: - case FT_UINT32: - case FT_FRAMENUM: - case FT_INT8: - case FT_INT16: - case FT_INT24: - case FT_INT32: - lua_pushnumber(L,(lua_Number)fvalue_get_integer(&(fi->value))); - items_found++; - break; - case FT_FLOAT: - case FT_DOUBLE: - lua_pushnumber(L,(lua_Number)fvalue_get_floating(&(fi->value))); - items_found++; - break; - case FT_UINT64: - case FT_INT64: - /* XXX: get them as strings for now */ - case FT_STRING: - case FT_STRINGZ: - case FT_ETHER: - case FT_BYTES: - case FT_UINT_BYTES: - case FT_IPv4: - case FT_IPv6: - case FT_IPXNET: - case FT_GUID: - case FT_OID: - lua_pushstring(L,fvalue_to_string_repr(&fi->value,FTREPR_DISPLAY,NULL)); - items_found++; - break; - default: - luaL_error(L,"FT_ not yet supported"); - return items_found; + if (found) { + for (i=0; ilen; i++) { + field_info* fi = g_ptr_array_index(found,i); + switch(fi->hfinfo->type) { + case FT_UINT8: + case FT_UINT16: + case FT_UINT24: + case FT_UINT32: + case FT_FRAMENUM: + case FT_INT8: + case FT_INT16: + case FT_INT24: + case FT_INT32: + lua_pushnumber(L,(lua_Number)fvalue_get_integer(&(fi->value))); + items_found++; + break; + case FT_FLOAT: + case FT_DOUBLE: + lua_pushnumber(L,(lua_Number)fvalue_get_floating(&(fi->value))); + items_found++; + break; + case FT_UINT64: + case FT_INT64: + /* XXX: get them as strings for now */ + case FT_ETHER: + case FT_IPv4: + case FT_IPv6: + case FT_IPXNET: + /* XXX -> Address */ + case FT_STRING: + case FT_STRINGZ: + case FT_BYTES: + case FT_UINT_BYTES: + case FT_GUID: + case FT_OID: + lua_pushstring(L,fvalue_to_string_repr(&fi->value,FTREPR_DISPLAY,NULL)); + items_found++; + break; + default: + luaL_error(L,"FT_ not yet supported"); + return items_found; + } } } } - return items_found; } @@ -198,10 +199,33 @@ static int Tap_set_filter(lua_State* L) { return 0; } +GPtrArray* lua_taps = NULL; +gboolean taps_registered = FALSE; + +GString* register_all_lua_taps(void) { + + if (!lua_taps || taps_registered) return NULL; + + while (lua_taps->len) { + Tap tap = g_ptr_array_remove_index(lua_taps,0); + GString* error; + + error = register_tap_listener("frame", tap, tap->filter, lua_tap_reset, lua_tap_packet, lua_tap_draw); + + if (error) { + return error; + } + + taps_registered = TRUE; + } + + + return NULL; + +} static int Tap_register_to_ethereal(lua_State*L) { Tap tap = checkTap(L,1); GString* filter_s; - GString* error; GPtrArray* ins; guint i; @@ -211,25 +235,26 @@ static int Tap_register_to_ethereal(lua_State*L) { if (tap->filter) g_string_sprintfa(filter_s,"( %s ) && frame ",tap->filter); + else + g_string_sprintfa(filter_s,"frame "); g_free(tap->filter); - + ins = tap->interesting_fields; - + for (i=0; i < ins->len; i++) { Field in = g_ptr_array_index(ins,i); g_string_sprintfa(filter_s," ||%s",in->abbrev); } tap->filter = filter_s->str; + g_string_free(filter_s,FALSE); - error = register_tap_listener("frame", tap, tap->filter, lua_tap_reset, lua_tap_packet, lua_tap_draw); - - if (error) { - luaL_error(L,"tap registration error: %s",error); - g_string_free(error,TRUE); - } + if (!lua_taps) + lua_taps = g_ptr_array_new(); + + g_ptr_array_add(lua_taps,tap); return 0; } diff --git a/plugins/lua/lua_tvb.c b/plugins/lua/lua_tvb.c index aa04976f1e..9cb7a6923a 100644 --- a/plugins/lua/lua_tvb.c +++ b/plugins/lua/lua_tvb.c @@ -237,9 +237,7 @@ static int ByteArray_tostring(lua_State* L) { if (!ba) return 0; - s = g_string_new("ByteArray"); - - g_string_sprintfa(s,"(%u): ",ba->len); + s = g_string_new(""); for (i = 0; i < (int)ba->len; i++) { g_string_append(s,byte_to_str[(ba->data)[i]]); diff --git a/plugins/lua/packet-lua.c b/plugins/lua/packet-lua.c index 69d45b58f6..75a13acd9b 100644 --- a/plugins/lua/packet-lua.c +++ b/plugins/lua/packet-lua.c @@ -119,6 +119,12 @@ void dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) { } static void init_lua(void) { + GString* tap_error = register_all_lua_taps(); + + if ( tap_error ) { + report_failure("lua tap registration problem: %s",tap_error->str); + } + /* XXX in C */ if (L) lua_dostring(L, "for k in init_routines do init_routines[k]() end;"); diff --git a/plugins/lua/packet-lua.h b/plugins/lua/packet-lua.h index 3a8618ccde..e51c040229 100644 --- a/plugins/lua/packet-lua.h +++ b/plugins/lua/packet-lua.h @@ -209,4 +209,6 @@ extern int lua_tap_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt extern void lua_tap_reset(void *tapdata); extern void lua_tap_draw(void *tapdata); +extern GString* register_all_lua_taps(void); + #endif -- cgit v1.2.3