From 9fd26b71eff056fa2aab6bd7200328c0f7072edc Mon Sep 17 00:00:00 2001 From: Luis Ontanon Date: Wed, 8 Feb 2006 23:26:52 +0000 Subject: * DissectorTable.add does not allow to add lua protocols that don't have a dissector. * ProtoFiled.uint checks the base to be a valid value to avoid an assertion in proto.c while registering the field array * save one lua table lookup by using a reference to the dissectors table instead of looking for it by name * set data_hanlde's value to avoid a crash while invoking it. * make the TvbRange of Tree:add_item really optional. svn path=/trunk/; revision=17220 --- plugins/lua/lua_proto.c | 23 ++++++++++++++++++----- plugins/lua/lua_tree.c | 9 ++++++++- plugins/lua/lua_tvb.c | 23 +++++++++++++++++------ plugins/lua/packet-lua.c | 48 ++++++++++++++++++++---------------------------- plugins/lua/packet-lua.h | 6 +++--- 5 files changed, 66 insertions(+), 43 deletions(-) diff --git a/plugins/lua/lua_proto.c b/plugins/lua/lua_proto.c index dd288cb192..31da270b10 100644 --- a/plugins/lua/lua_proto.c +++ b/plugins/lua/lua_proto.c @@ -427,21 +427,28 @@ static int ProtoField_integer(lua_State* L, enum ftenum type) { ProtoField f = g_malloc(sizeof(eth_field_t)); const gchar* abbr = luaL_checkstring(L,1); const gchar* name = luaL_optstring(L,2,abbr); - const gchar* base = luaL_optstring(L, 3, "BASE_DEC"); + const gchar* base_str = luaL_optstring(L, 3, "BASE_DEC"); value_string* vs = (lua_gettop(L) > 3) ? value_string_from_table(L,4) : NULL; int mask = luaL_optint(L, 5, 0x0); const gchar* blob = luaL_optstring(L,6,""); + base_display_e base = string_to_base(base_str); + if (base < BASE_DEC || base > BASE_HEX_DEC) { + luaL_argerror(L,3,"Base must be either BASE_DEC, BASE_HEX, BASE_OCT," + " BASE_DEC_HEX, BASE_DEC_HEX or BASE_HEX_DEC"); + return 0; + } f->hfid = -2; f->name = g_strdup(name); f->abbr = g_strdup(abbr); f->type = type; f->vs = vs; - f->base = string_to_base(base); + f->base = base; f->mask = mask; f->blob = g_strdup(blob); + pushProtoField(L,f); return 1; @@ -844,9 +851,7 @@ static int Proto_set_dissector(lua_State* L) { if (lua_isfunction(L,3)) { /* insert the dissector into the dissectors table */ - lua_pushstring(L, LUA_DISSECTORS_TABLE); - lua_gettable(L, LUA_REGISTRYINDEX); - + lua_rawgeti(L, LUA_REGISTRYINDEX, lua_dissectors_table_ref); lua_replace(L, 1); lua_pushstring(L,proto->name); lua_replace(L, 2); @@ -1129,6 +1134,12 @@ static int DissectorTable_add (lua_State *L) { Proto p; p = toProto(L,3); handle = p->handle; + + if (! handle) { + luaL_error(L,"Protocol %s cannot be added to a table as it does not have a dissector",p->name); + return 0; + } + } else if ( isDissector(L,3) ) { handle = toDissector(L,3); } else { @@ -1144,6 +1155,8 @@ static int DissectorTable_add (lua_State *L) { } 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, handle); + } else { + luaL_error(L,"Strange type %d for a DissectorTable",type); } return 0; diff --git a/plugins/lua/lua_tree.c b/plugins/lua/lua_tree.c index 2b9c79dbe8..3841dc5edd 100644 --- a/plugins/lua/lua_tree.c +++ b/plugins/lua/lua_tree.c @@ -141,7 +141,14 @@ static int ProtoTree_add_item_any(lua_State *L, gboolean little_endian) { tvbr = shiftTvbRange(L,1); - if (hfid > 0 && tvbr ) { + if (!tvbr) { + tvbr = ep_alloc(sizeof(struct _eth_tvbrange)); + tvbr->tvb = lua_tvb; + tvbr->offset = 0; + tvbr->len = 0; + } + + if (hfid > 0 ) { if (lua_gettop(L)) { switch(type) { case FT_PROTOCOL: diff --git a/plugins/lua/lua_tvb.c b/plugins/lua/lua_tvb.c index 5b86af79e2..91d46317fd 100644 --- a/plugins/lua/lua_tvb.c +++ b/plugins/lua/lua_tvb.c @@ -26,6 +26,22 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* + * XXX: TODO + * + * having Tvbs and TvbRanges have a lifetime of just the dissector callback + * but being user able to save them in global variables for later use + * every lua value created with these should be NULLified after the dissector's + * callback, pushXxx() gives back a pointer to the pointer it saves that has to be pushed + * to a queue and NULLified before returning from packet_lua. + * + * in order to do that we need to verify that every function in this file yields an + * error if the Xxx ptr it uses is NULL. + * + * the same would applies to Pinfo, Item and Tree + * Item and Tree are protected in the sense that the callbacks to these + */ + #include "packet-lua.h" LUA_CLASS_DEFINE(Tvb,TVB,if (! *p) luaL_error(L,"null tvb")) @@ -35,7 +51,6 @@ LUA_CLASS_DEFINE(ByteArray,BYTE_ARRAY,if (! *p) luaL_argerror(L,index,"null byte static int ByteArray_new(lua_State* L) { GByteArray* ba = g_byte_array_new(); const gchar* s; - /* XXX: slow! */ int nibble[2]; int i = 0; gchar c; @@ -48,6 +63,7 @@ static int ByteArray_new(lua_State* L) { return 0; } + /* XXX: slow! */ for (; (c = *s); s++) { switch(c) { case '0': case '1': case '2': case '3': case '4': case '5' : case '6' : case '7': case '8' : case '9' : @@ -120,8 +136,6 @@ static int ByteArray_set_index(lua_State* L) { int idx = luaL_checkint(L,2); int v = luaL_checkint(L,3); - g_warning(">%p %d",ba,idx); - if (!ba) return 0; if (idx == 0 && ! g_str_equal(luaL_optstring(L,2,""),"0") ) { @@ -149,8 +163,6 @@ static int ByteArray_get_index(lua_State* L) { ByteArray ba = checkByteArray(L,1); int idx = luaL_checkint(L,2); - g_warning(">%p %d",ba,idx); - if (!ba) return 0; if (idx == 0 && ! g_str_equal(luaL_optstring(L,2,""),"0") ) { @@ -162,7 +174,6 @@ static int ByteArray_get_index(lua_State* L) { luaL_argerror(L,2,"index out of range"); return 0; } - g_warning(">%d",idx); lua_pushnumber(L,ba->data[idx]); return 1; diff --git a/plugins/lua/packet-lua.c b/plugins/lua/packet-lua.c index 863c0a70d5..7ff4bee583 100644 --- a/plugins/lua/packet-lua.c +++ b/plugins/lua/packet-lua.c @@ -39,6 +39,8 @@ packet_info* lua_pinfo; proto_tree* lua_tree; tvbuff_t* lua_tvb; int lua_malformed; +int lua_dissectors_table_ref; + dissector_handle_t lua_data_handle; @@ -99,28 +101,13 @@ void dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) { /* * almost equivalent to Lua: * dissectors[current_proto](tvb,pinfo,tree) - * but it wont give an error if dissectors[current_proto] doesn't exist */ lua_settop(L,0); - lua_pushstring(L, LUA_DISSECTORS_TABLE); - lua_gettable(L, LUA_REGISTRYINDEX); - - if (!lua_istable(L, -1)) { - proto_item* pi = proto_tree_add_text(tree,tvb,0,0,"Lua: either `" LUA_DISSECTORS_TABLE "' does not exist or it is not a table!"); - expert_add_info_format(pinfo, pi, PI_DEBUG, PI_ERROR,"Lua Error"); - - lua_pinfo = NULL; - lua_tree = NULL; - lua_tvb = NULL; - - return; - } - + lua_rawgeti(L, LUA_REGISTRYINDEX, lua_dissectors_table_ref); lua_pushstring(L, pinfo->current_proto); - lua_gettable(L, -2); lua_remove(L,1); @@ -134,11 +121,15 @@ void dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) { if ( lua_pcall(L,3,0,0) ) { const gchar* error = lua_tostring(L,-1); + proto_item* pi = proto_tree_add_text(tree,tvb,0,0,"Lua Error: %s",error); expert_add_info_format(pinfo, pi, PI_DEBUG, PI_ERROR ,"Lua Error"); } } else { - /* XXX */ + proto_item* pi = proto_tree_add_text(tree,tvb,0,0,"Lua Error: did not find the %s dissector" + " in the dissectors table",pinfo->current_proto); + + expert_add_info_format(pinfo, pi, PI_DEBUG, PI_ERROR ,"Lua Error"); } lua_pinfo = NULL; @@ -229,6 +220,8 @@ void lua_load_script(const gchar* filename) { report_open_failure(filename,errno,FALSE); return; } + + lua_settop(L,0); lua_pushcfunction(L,lua_main_error_handler); @@ -236,25 +229,18 @@ void lua_load_script(const gchar* filename) { case 0: lua_pcall(L,0,0,1); fclose(file); - - lua_data_handle = NULL; - lua_pinfo = NULL; - lua_tree = NULL; - lua_tvb = NULL; - - lua_malformed = proto_get_id_by_filter_name("malformed"); - return; case LUA_ERRSYNTAX: { report_failure("Lua: syntax error during precompilation of `%s':\n%s",filename,lua_tostring(L,-1)); + fclose(file); return; } case LUA_ERRMEM: report_failure("Lua: memory allocation error during execution of %s",filename); + fclose(file); return; } - lua_settop(L,0); } void register_lua(void) { @@ -342,9 +328,8 @@ void register_lua(void) { lua_newtable (L); lua_settable(L, LUA_GLOBALSINDEX); - lua_pushstring(L, LUA_DISSECTORS_TABLE); lua_newtable (L); - lua_settable(L, LUA_REGISTRYINDEX); + lua_dissectors_table_ref = luaL_ref(L, LUA_REGISTRYINDEX); for (i=0 ; i < filenames->len ; i++) { filename = g_ptr_array_index(filenames,i); @@ -358,6 +343,13 @@ void register_lua(void) { lua_pushcfunction(L, lua_not_register_menu); lua_settable(L, LUA_GLOBALSINDEX); + lua_pinfo = NULL; + lua_tree = NULL; + lua_tvb = NULL; + + lua_data_handle = find_dissector("data"); + lua_malformed = proto_get_id_by_filter_name("malformed"); + return; } diff --git a/plugins/lua/packet-lua.h b/plugins/lua/packet-lua.h index d6e8b626f6..954ab41587 100644 --- a/plugins/lua/packet-lua.h +++ b/plugins/lua/packet-lua.h @@ -209,7 +209,7 @@ extern tvbuff_t* lua_tvb; extern int lua_malformed; extern dissector_handle_t lua_data_handle; extern gboolean lua_initialized; - +extern int lua_dissectors_table_ref; #define LUA_CLASS_DECLARE(C,CN) \ extern C to##C(lua_State* L, int index); \ @@ -250,9 +250,9 @@ extern const gchar* lua_shiftstring(lua_State* L,int idx); extern int lua_register_menu(lua_State* L); extern int lua_new_dialog(lua_State* L); extern int lua_gui_enabled(lua_State* L); - +extern void proto_register_lua(void); extern GString* lua_register_all_taps(void); extern void lua_prime_all_fields(proto_tree* tree); -void lua_register_subtrees(void); +extern void lua_register_subtrees(void); #endif -- cgit v1.2.3