* 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
This commit is contained in:
Luis Ontanon 2006-02-08 23:26:52 +00:00
parent 6f4dd2267c
commit 9fd26b71ef
5 changed files with 66 additions and 43 deletions

View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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;
}

View File

@ -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