aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorLuis Ontanon <luis.ontanon@gmail.com>2006-01-26 20:20:55 +0000
committerLuis Ontanon <luis.ontanon@gmail.com>2006-01-26 20:20:55 +0000
commit094840aa97a1e4c6d02786e69f4abd1f0163230f (patch)
tree4daf6498b0541fa36ef8152e0e885bc416248eba /plugins
parent65530eb91278a0c548ea2bcbcf7717f2db153093 (diff)
* lua_tree.c
* protect proto_item_add_* calls with a TRY CATCH to avoid the Lua state getting corrupted * new ProtoItem:add_expert_info() call * lua_proto.c * protect call_dissector() and dissector_try_*() calls with TRY CATCH to avoid the Lua state getting corrupted * ValueString makes no sense, get rid of it we'll use Lua's associative arrays instead * lua_tvb.c * while creating a tvb from a ByteArray copy the ByteArray's data and set the tvb's free_cb * check bounds before calling tvb_*() to avoid a longjmp breaking Lua * do not leak the string in Tvb_tostring() * new Tvb:get_ipv4() call * new Tvb:get_eth() call * packet-lua.[ch] * export lua_tvb and lua_malformed to other modules being the current tvb and the protocol_id of malformed * convert some Lua to C * do not register ValueString (eliminated) svn path=/trunk/; revision=17106
Diffstat (limited to 'plugins')
-rw-r--r--plugins/lua/lua_proto.c182
-rw-r--r--plugins/lua/lua_tree.c154
-rw-r--r--plugins/lua/lua_tvb.c119
-rw-r--r--plugins/lua/packet-lua.c99
-rw-r--r--plugins/lua/packet-lua.h10
5 files changed, 358 insertions, 206 deletions
diff --git a/plugins/lua/lua_proto.c b/plugins/lua/lua_proto.c
index be28e6ec92..479e768b85 100644
--- a/plugins/lua/lua_proto.c
+++ b/plugins/lua/lua_proto.c
@@ -33,7 +33,6 @@ LUA_CLASS_DEFINE(ProtoField,PROTO_FIELD,if (! *p) luaL_error(L,"null ProtoField"
LUA_CLASS_DEFINE(ProtoFieldArray,PROTO_FIELD_ARRAY,if (! *p) luaL_error(L,"null ProtoFieldArray"));
LUA_CLASS_DEFINE(SubTreeType,SUB_TREE_TYPE,NOP);
LUA_CLASS_DEFINE(SubTreeTypeArray,SUB_TREE_TYPE_ARRAY,if (! *p) luaL_error(L,"null SubTreeTypeArray"));
-LUA_CLASS_DEFINE(ValueString,VALUE_STRING,NOP);
LUA_CLASS_DEFINE(Dissector,DISSECTOR,NOP);
LUA_CLASS_DEFINE(DissectorTable,DISSECTOR_TABLE,NOP);
@@ -125,11 +124,54 @@ static base_display_e string_to_base(const gchar* str) {
return BASE_NONE;
}
+static value_string* value_string_from_table(lua_State* L, int idx) {
+ GArray* vs = g_array_new(TRUE,TRUE,sizeof(value_string));
+ value_string* ret;
+
+ if (!lua_istable(L,idx)) {
+ luaL_argerror(L,idx,"must be a table");
+ g_array_free(vs,TRUE);
+ return NULL;
+ }
+
+ lua_pushnil(L);
+
+ while (lua_next(L, idx) != 0) {
+ value_string v = {0,NULL};
+
+ if (! lua_isnumber(L,-2)) {
+ luaL_argerror(L,idx,"All keys of a table used as vaalue_string must be integers");
+ g_array_free(vs,TRUE);
+ return NULL;
+ }
+
+ if (! lua_isstring(L,-1)) {
+ luaL_argerror(L,idx,"All values of a table used as vaalue_string must be strings");
+ g_array_free(vs,TRUE);
+ return NULL;
+ }
+
+ v.value = (guint32)lua_tonumber(L,-2);
+ v.strptr = g_strdup(lua_tostring(L,-1));
+
+ g_array_append_val(vs,v);
+
+ lua_pop(L, 1);
+ }
+
+ lua_pop(L, 1);
+
+ ret = (value_string*)vs->data;
+
+ g_array_free(vs,FALSE);
+ return ret;
+
+}
static int ProtoField_new(lua_State* L) {
ProtoField f = g_malloc(sizeof(eth_field_t));
- GArray* vs;
+ value_string* 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;
@@ -143,11 +185,16 @@ static int ProtoField_new(lua_State* L) {
}
if (! lua_isnil(L,4) ) {
- vs = checkValueString(L,4);
+ vs = value_string_from_table(L,4);
if (vs) {
- f->vs = (value_string*)vs->data;
+ f->vs = vs;
+ } else {
+ g_free(f);
+ return 0;
}
+
+
} else {
f->vs = NULL;
}
@@ -170,15 +217,16 @@ static int ProtoField_integer(lua_State* L, enum ftenum type) {
const gchar* abbr = luaL_checkstring(L,1);
const gchar* name = luaL_optstring(L,2,abbr);
const gchar* base = luaL_optstring(L, 3, "BASE_DEC");
- GArray* vs = (lua_gettop(L) >= 4) ? checkValueString(L,4) : NULL;
+ value_string* vs = (!lua_isnil(L,4)) ? value_string_from_table(L,4) : NULL;
int mask = luaL_optint(L, 5, 0x0);
const gchar* blob = luaL_optstring(L,6,"");
-
+
+
f->hfid = -2;
f->name = g_strdup(name);
f->abbr = g_strdup(abbr);
f->type = type;
- f->vs = (value_string*)vs->data;
+ f->vs = vs;
f->base = string_to_base(base);
f->mask = mask;
f->blob = g_strdup(blob);
@@ -941,7 +989,14 @@ static int Dissector_call(lua_State* L) {
if (! ( d && tvb && pinfo) ) return 0;
- call_dissector(d, tvb, pinfo, tree);
+ TRY {
+ call_dissector(d, tvb, pinfo, tree);
+ } CATCH(ReportedBoundsError) {
+ proto_tree_add_protocol_format(lua_tree, lua_malformed, lua_tvb, 0, 0, "[Malformed Frame: Packet Length]" );
+ luaL_error(L,"Malformed Frame");
+ return 0;
+ } ENDTRY;
+
return 0;
}
@@ -1099,12 +1154,27 @@ static int DissectorTable_try (lua_State *L) {
if (!pattern) return 0;
- if (dissector_try_string(dt->table,pattern,tvb,pinfo,tree))
+ TRY {
+ if (dissector_try_string(dt->table,pattern,tvb,pinfo,tree))
+ return 0;
+ } CATCH(ReportedBoundsError) {
+ proto_tree_add_protocol_format(lua_tree, lua_malformed, lua_tvb, 0, 0, "[Malformed Frame: Packet Length]" );
+ luaL_error(L,"Malformed Frame");
return 0;
+ } ENDTRY;
+
} 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))
+
+ TRY {
+ if (dissector_try_port(dt->table,port,tvb,pinfo,tree))
+ return 0;
+ } CATCH(ReportedBoundsError) {
+ proto_tree_add_protocol_format(lua_tree, lua_malformed, lua_tvb, 0, 0, "[Malformed Frame: Packet Length]" );
+ luaL_error(L,"Malformed Frame");
return 0;
+ } ENDTRY;
+
} else {
luaL_error(L,"No such type of dissector_table");
}
@@ -1202,96 +1272,4 @@ int DissectorTable_register(lua_State* L) {
};
-/*
- * ValueString class
- */
-
-static int ValueString_new(lua_State* L) {
- ValueString vs = g_array_new(TRUE,TRUE,sizeof(value_string));
- pushValueString(L,vs);
- return 1;
-}
-
-
-static int ValueString_add(lua_State* L) {
- ValueString vs = checkValueString(L,1);
- value_string v = {0,NULL};
-
- v.value = luaL_checkint(L,2);
- v.strptr = g_strdup(luaL_checkstring(L,3));
-
- g_array_append_val(vs,v);
-
- return 0;
-}
-
-static int ValueString_match(lua_State* L) {
- ValueString vs = checkValueString(L,1);
- guint32 val = (guint32)luaL_checkint(L,2);
- const gchar* def = luaL_optstring(L,8,"Unknown");
-
- lua_pushstring(L,val_to_str(val, (value_string*)(vs->data), def));
-
- return 1;
-}
-
-static int ValueString_gc(lua_State* L) {
- ValueString vs = checkValueString(L,1);
-
- g_array_free(vs,TRUE);
-
- return 0;
-}
-
-static int ValueString_tostring(lua_State* L) {
- ValueString vs = checkValueString(L,1);
- value_string* c = (value_string*)vs->data;
- GString* s = g_string_new("ValueString:\n");
-
- for(;c->strptr;c++) {
- g_string_sprintfa(s,"\t%u\t%s\n",c->value,c->strptr);
- }
-
- lua_pushstring(L,s->str);
-
- g_string_free(s,TRUE);
-
- return 1;
-}
-
-static const luaL_reg ValueString_methods[] = {
- {"new", ValueString_new},
- {"add", ValueString_add},
- {"match", ValueString_match},
- {0,0}
-};
-
-
-static const luaL_reg ValueString_meta[] = {
- {"__gc", ValueString_gc},
- {"__tostring", ValueString_tostring},
- {0, 0}
-};
-
-
-int ValueString_register(lua_State* L) {
- luaL_openlib(L, VALUE_STRING, ValueString_methods, 0);
- luaL_newmetatable(L, VALUE_STRING);
- luaL_openlib(L, 0, ValueString_meta, 0);
- lua_pushliteral(L, "__index");
- lua_pushvalue(L, -3);
- lua_rawset(L, -3);
- lua_pushliteral(L, "__metatable");
- lua_pushvalue(L, -3);
- lua_rawset(L, -3);
- lua_pop(L, 1);
-
- return 1;
-}
-
-
-
-
-
-
diff --git a/plugins/lua/lua_tree.c b/plugins/lua/lua_tree.c
index 98d68ca841..6a9fdb38a7 100644
--- a/plugins/lua/lua_tree.c
+++ b/plugins/lua/lua_tree.c
@@ -27,6 +27,7 @@
*/
#include "packet-lua.h"
+#include <epan/expert.h>
LUA_CLASS_DEFINE(ProtoTree,PROTO_TREE,NOP);
LUA_CLASS_DEFINE(ProtoItem,ITEM,NOP);
@@ -43,10 +44,8 @@ static int ProtoTree_add_item_any(lua_State *L, gboolean little_endian) {
*/
ProtoTree tree = checkProtoTree(L,1);
ProtoField field;
- ProtoItem item;
+ ProtoItem item = NULL;
Tvb tvb;
- int offset;
- int len;
if (!tree) {
pushProtoItem(L,NULL);
@@ -55,71 +54,88 @@ static int ProtoTree_add_item_any(lua_State *L, gboolean little_endian) {
if (( luaL_checkudata (L, 2, TVB) )) {
tvb = checkTvb(L,2);
- const char* str;
+
+ TRY {
+ const char* str;
+ int offset;
+ int len;
+
+ if (lua_isnumber(L,3)) {
+ offset = luaL_checkint(L,3);
+ len = luaL_checkint(L,4);
+ str = lua_tostring(L,5);
+ } else if (lua_isstring(L,3)) {
+ offset = 0;
+ len = 0;
+ str = lua_tostring(L,3);
+ } else {
+ luaL_error(L,"First arg must be either TVB or ProtoField");
+ return 0;
+ }
- if (lua_isnumber(L,3)) {
- offset = luaL_checkint(L,3);
- len = luaL_checkint(L,4);
- str = lua_tostring(L,5);
- } else if (lua_isstring(L,3)) {
- offset = 0;
- len = 0;
- str = lua_tostring(L,3);
- } else {
- luaL_error(L,"First arg must be either TVB or ProtoField");
+ item = proto_tree_add_text(tree,tvb,offset,len,"%s",str);
+ } CATCH(ReportedBoundsError) {
+ proto_tree_add_protocol_format(lua_tree, lua_malformed, lua_tvb, 0, 0, "[Malformed Frame: Packet Length]" );
+ luaL_error(L,"Malformed Frame");
return 0;
- }
-
- item = proto_tree_add_text(tree,tvb,offset,len,"%s",str);
-
+ } ENDTRY;
+
} else if (( luaL_checkudata (L, 2, PROTO_FIELD) )) {
field = checkProtoField(L,2);
tvb = checkTvb(L,3);
- offset = luaL_checkint(L,4);
- len = luaL_checkint(L,5);
-
- if ( lua_gettop(L) == 6 ) {
- switch(field->type) {
- case FT_UINT8:
- case FT_UINT16:
- case FT_UINT24:
- case FT_UINT32:
- case FT_FRAMENUM:
- item = proto_tree_add_uint(tree,field->hfid,tvb,offset,len,(guint32)luaL_checknumber(L,6));
- break;
- case FT_INT8:
- case FT_INT16:
- case FT_INT24:
- case FT_INT32:
- item = proto_tree_add_int(tree,field->hfid,tvb,offset,len,(gint32)luaL_checknumber(L,6));
- break;
- case FT_FLOAT:
- item = proto_tree_add_float(tree,field->hfid,tvb,offset,len,(float)luaL_checknumber(L,6));
- break;
- case FT_DOUBLE:
- item = proto_tree_add_double(tree,field->hfid,tvb,offset,len,(double)luaL_checknumber(L,6));
- break;
- case FT_STRING:
- case FT_STRINGZ:
- item = proto_tree_add_string(tree,field->hfid,tvb,offset,len,luaL_checkstring(L,6));
- break;
- case FT_UINT64:
- case FT_INT64:
- 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:
- default:
- luaL_error(L,"FT_ not yet supported");
- return 0;
+
+ TRY {
+ int offset = luaL_checkint(L,4);
+ int len = luaL_checkint(L,5);
+
+ if ( lua_gettop(L) == 6 ) {
+ switch(field->type) {
+ case FT_UINT8:
+ case FT_UINT16:
+ case FT_UINT24:
+ case FT_UINT32:
+ case FT_FRAMENUM:
+ item = proto_tree_add_uint(tree,field->hfid,tvb,offset,len,(guint32)luaL_checknumber(L,6));
+ break;
+ case FT_INT8:
+ case FT_INT16:
+ case FT_INT24:
+ case FT_INT32:
+ item = proto_tree_add_int(tree,field->hfid,tvb,offset,len,(gint32)luaL_checknumber(L,6));
+ break;
+ case FT_FLOAT:
+ item = proto_tree_add_float(tree,field->hfid,tvb,offset,len,(float)luaL_checknumber(L,6));
+ break;
+ case FT_DOUBLE:
+ item = proto_tree_add_double(tree,field->hfid,tvb,offset,len,(double)luaL_checknumber(L,6));
+ break;
+ case FT_STRING:
+ case FT_STRINGZ:
+ item = proto_tree_add_string(tree,field->hfid,tvb,offset,len,luaL_checkstring(L,6));
+ break;
+ case FT_UINT64:
+ case FT_INT64:
+ 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:
+ default:
+ luaL_error(L,"FT_ not yet supported");
+ return 0;
+ }
+ } else {
+ item = proto_tree_add_item(tree,field->hfid,tvb,offset,len,little_endian);
}
- } else {
- item = proto_tree_add_item(tree,field->hfid,tvb,offset,len,little_endian);
- }
+ } CATCH(ReportedBoundsError) {
+ proto_tree_add_protocol_format(lua_tree, lua_malformed, lua_tvb, 0, 0, "[Malformed Frame: Packet Length]" );
+ luaL_error(L,"Malformed Frame");
+ return 0;
+ } ENDTRY;
+
} else {
luaL_error(L,"First arg must be either TVB or ProtoField");
return 0;
@@ -301,6 +317,19 @@ static int ProtoItem_set_expert_flags(lua_State *L) {
return 0;
}
+static int ProtoItem_add_expert_info(lua_State *L) {
+ ProtoItem item = checkProtoItem(L,1);
+
+ if (item) {
+ int group = str_to_expert(luaL_checkstring(L,2));
+ int severity = str_to_expert(luaL_checkstring(L,3));
+ const gchar* str = luaL_optstring(L,4,"Expert Info");
+
+ expert_add_info_format(lua_pinfo, item, group, severity, "%s", str);
+ }
+
+ return 0;
+}
static int ProtoItem_set_generated(lua_State *L) {
ProtoItem item = checkProtoItem(L,1);
@@ -325,6 +354,7 @@ static const luaL_reg ProtoItem_methods[] = {
{"append_text", ProtoItem_append_text},
{"set_len", ProtoItem_set_len},
{"set_expert_flags", ProtoItem_set_expert_flags},
+ {"add_expert_info", ProtoItem_add_expert_info},
{"set_generated", ProtoItem_set_generated},
{"set_hidden", ProtoItem_set_hidden},
{0, 0}
diff --git a/plugins/lua/lua_tvb.c b/plugins/lua/lua_tvb.c
index 9cb7a6923a..8b4ff85261 100644
--- a/plugins/lua/lua_tvb.c
+++ b/plugins/lua/lua_tvb.c
@@ -198,7 +198,7 @@ static int ByteArray_subset(lua_State* L) {
if (!ba) return 0;
if ((offset + len) > (int)ba->len) {
- luaL_error(L,"out of bounds");
+ luaL_error(L,"Out Of Bounds");
return 0;
}
@@ -292,8 +292,8 @@ int ByteArray_register(lua_State* L) {
static int Tvb_new (lua_State *L) {
ByteArray ba;
- if (!lua_pinfo) {
- /* XXX: for now tvb should only be used in the frame that created */
+ if (!lua_tvb) {
+ /* XXX: incomplete check, a tvb should only be used in the frame that created it */
luaL_error(L,"Tvb can only be used in dissectors");
return 0;
}
@@ -301,15 +301,30 @@ static int Tvb_new (lua_State *L) {
if (( luaL_checkudata(L,1,BYTE_ARRAY) )) {
ba = toByteArray(L,1);
const gchar* name = luaL_optstring(L,2,"Unnamed") ;
- /* XXX: what if the BA gets garbage collected? */
- Tvb tvb = tvb_new_real_data(ba->data, ba->len,ba->len);
+ guint8* data;
+
+ if (! ba) return 0;
+
+ data = g_memdup(ba->data, ba->len);
+
+ Tvb tvb = tvb_new_real_data(data, ba->len,ba->len);
+ tvb_set_free_cb(tvb, g_free);
+
add_new_data_source(lua_pinfo, tvb, name);
pushTvb(L,tvb);
return 1;
} else {
+ Tvb tvb = checkTvb(L,1);
+ int offset = luaL_optint(L, 2, 0);
int len = luaL_optint(L, 3, -1);
- pushTvb(L, tvb_new_subset( checkTvb(L,1),luaL_optint(L, 2, 0),len, len) );
- return 1;
+
+ if (tvb_offset_exists(tvb, offset+len)) {
+ pushTvb(L, tvb_new_subset(tvb,offset,len, len) );
+ return 1;
+ } else {
+ luaL_error(L,"Out Of Bounds");
+ return 0;
+ }
}
}
@@ -380,9 +395,8 @@ static int Tvb_get_bytearray(lua_State* L) {
}
if (len < 1 || offset+len > o_len) {
- luaL_error(L,"off bounds");
+ luaL_error(L,"Out Of Bounds");
return 0;
-
}
ba = g_byte_array_new();
@@ -395,29 +409,57 @@ static int Tvb_get_bytearray(lua_State* L) {
static int Tvb_get_stringz(lua_State* L) {
Tvb tvb = checkTvb(L,1);
+ int offset;
+ int len;
+ guint8* buf;
if (!tvb) return 0;
+ offset = luaL_checkint(L,2);
+
+ if (!tvb_offset_exists(tvb, offset)) {
+ luaL_error(L,"Out Of Bounds");
+ return 0;
+ }
+
+ len = tvb_length(tvb) - offset;
+ buf = ep_alloc0(len+1);
+
if (!lua_pinfo) {
luaL_error(L,"Tvb can only be used in dissectors");
return 0;
}
- lua_pushstring(L,(gchar*)tvb_get_ephemeral_stringz(tvb,luaL_checkint(L,2),NULL));
- return 1;
+ len = tvb_get_nstringz(tvb, offset, len, buf);
+
+ lua_pushstring(L,(gchar*)buf);
+ lua_pushnumber(L,(lua_Number)len);
+
+ return 2;
}
static int Tvb_get_string(lua_State* L) {
Tvb tvb = checkTvb(L,1);
-
+ int offset;
+ int len;
+
if (!tvb) return 0;
- if (!lua_pinfo) {
+ if (!lua_tvb) {
luaL_error(L,"Tvb can only be used in dissectors");
return 0;
}
- lua_pushstring(L,(gchar*)tvb_get_ephemeral_string(tvb,luaL_checkint(L,2),luaL_checkint(L,3)));
+ offset = luaL_checkint(L,2);
+ len = luaL_checkint(L,3);
+
+ if ( ! tvb_offset_exists(tvb, offset+len)) {
+ luaL_error(L,"Out Of Bounds");
+ return 0;
+ }
+
+ lua_pushstring(L,(gchar*)tvb_get_ephemeral_string(tvb,offset,len));
+
return 1;
}
@@ -428,7 +470,7 @@ static int Tvb_tostring(lua_State* L) {
if (!tvb) return 0;
len = tvb_length(tvb);
- gchar* str = g_strdup_printf("TVB(%i) : %s",len,tvb_bytes_to_str(tvb,0,len));
+ gchar* str = ep_strdup_printf("TVB(%i) : %s",len,tvb_bytes_to_str(tvb,0,len));
lua_pushstring(L,str);
return 1;
}
@@ -449,6 +491,48 @@ static int Tvb_len(lua_State* L) {
return 1;
}
+static int Tvb_get_eth(lua_State* L) {
+ Tvb tvb = checkTvb(L,1);
+ int offset = luaL_checkint(L,2);
+ Address addr;
+ guint8* eth_addr;
+
+ if (!tvb) return 0;
+
+ if (tvb_offset_exists(tvb, offset+6)) {
+ eth_addr = ep_tvb_memdup(tvb,offset,6);
+ addr = g_malloc(sizeof(address));
+ SET_ADDRESS(addr, AT_ETHER, 4, eth_addr);
+ pushAddress(L,addr);
+ return 1;
+ } else {
+ luaL_error(L,"Out Of Bounds");
+ return 0;
+ }
+
+}
+
+static int Tvb_get_ipv4(lua_State* L) {
+ Tvb tvb = checkTvb(L,1);
+ int offset = luaL_checkint(L,2);
+ Address addr;
+ guint32 ip_addr;
+
+ if (!tvb) return 0;
+
+ if (tvb_offset_exists(tvb, offset+4)) {
+ ip_addr = tvb_get_ipv4(tvb,offset);
+ addr = g_malloc(sizeof(address));
+ SET_ADDRESS(addr, AT_IPv4, 4, ip_addr);
+ pushAddress(L,addr);
+ return 1;
+ } else {
+ luaL_error(L,"Out Of Bounds");
+ return 0;
+ }
+
+}
+
static const luaL_reg Tvb_methods[] = {
{"new", Tvb_new},
@@ -467,6 +551,11 @@ static const luaL_reg Tvb_methods[] = {
{"get_stringz", Tvb_get_stringz },
{"get_string", Tvb_get_string },
{"get_bytearray",Tvb_get_bytearray},
+ {"get_ipv4", Tvb_get_ipv4 },
+ {"get_eth",Tvb_get_eth },
+#if 0
+ {"get_ipv6",Tvb_get_ipv6 },
+#endif
{"len", Tvb_len},
{0,0}
};
diff --git a/plugins/lua/packet-lua.c b/plugins/lua/packet-lua.c
index 75a13acd9b..e7a0b25c6c 100644
--- a/plugins/lua/packet-lua.c
+++ b/plugins/lua/packet-lua.c
@@ -31,38 +31,41 @@
#include <math.h>
static lua_State* L = NULL;
+
packet_info* lua_pinfo;
proto_tree* lua_tree;
+tvbuff_t* lua_tvb;
+int lua_malformed;
dissector_handle_t lua_data_handle;
-static int lua_format_date(lua_State* L) {
- lua_Number time = luaL_checknumber(L,1);
+static int lua_format_date(lua_State* LS) {
+ lua_Number time = luaL_checknumber(LS,1);
nstime_t then;
gchar* str;
then.secs = (guint32)floor(time);
then.nsecs = (guint32) ( (time-(double)(then.secs))*1000000000);
str = abs_time_to_str(&then);
- lua_pushstring(L,str);
+ lua_pushstring(LS,str);
return 1;
}
-static int lua_format_time(lua_State* L) {
- lua_Number time = luaL_checknumber(L,1);
+static int lua_format_time(lua_State* LS) {
+ lua_Number time = luaL_checknumber(LS,1);
nstime_t then;
gchar* str;
then.secs = (guint32)floor(time);
then.nsecs = (guint32) ( (time-(double)(then.secs))*1000000000);
str = rel_time_to_str(&then);
- lua_pushstring(L,str);
+ lua_pushstring(LS,str);
return 1;
}
-static int lua_report_failure(lua_State* L) {
- const gchar* s = luaL_checkstring(L,1);
+static int lua_report_failure(lua_State* LS) {
+ const gchar* s = luaL_checkstring(LS,1);
report_failure("%s",s);
return 0;
}
@@ -96,26 +99,72 @@ void lua_tap_draw(void *tapdata) {
lua_dostring(L,ep_strdup_printf("tap_draws.%s();",tap->name));
}
-
void dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
- lua_pushstring(L, "_ethereal_tvb");
- pushTvb(L, tvb);
- lua_settable(L, LUA_GLOBALSINDEX);
+ lua_pinfo = pinfo;
+ lua_tree = tree;
+ lua_tvb = tvb;
- lua_pushstring(L, "_ethereal_pinfo");
- pushPinfo(L, pinfo);
- lua_settable(L, LUA_GLOBALSINDEX);
+ /*
+ * equivalent to Lua:
+ * dissectors[current_proto](tvb,pinfo,tree)
+ */
+
+ lua_settop(L,0);
- lua_pushstring(L, "_ethereal_tree");
- pushProtoTree(L, tree);
- lua_settable(L, LUA_GLOBALSINDEX);
+ lua_getglobal(L, LUA_DISSECTORS_TABLE);
- lua_pinfo = pinfo;
+ if (!lua_istable(L, -1)) {
+ g_warning("either `" LUA_DISSECTORS_TABLE "' does not exist or it is not a table!");
+
+ lua_pinfo = NULL;
+ lua_tree = NULL;
+ lua_tvb = NULL;
+
+ return;
+ }
- /* XXX in C */
- lua_dostring(L,ep_strdup_printf("dissectors.%s(_ethereal_tvb,_ethereal_pinfo,_ethereal_tree);",pinfo->current_proto));
+ lua_pushstring(L, pinfo->current_proto);
+
+ lua_gettable(L, -2);
+
+ lua_remove(L,1);
+
+
+ if (!lua_isfunction(L,1)) {
+ g_warning("`" LUA_DISSECTORS_TABLE ".%s' is not a function, is a %s",
+ pinfo->current_proto,lua_typename(L,lua_type(L,1)));
+
+ lua_pinfo = NULL;
+ lua_tree = NULL;
+ lua_tvb = NULL;
+
+ return;
+ }
+
+ pushTvb(L, tvb);
+ pushPinfo(L, pinfo);
+ pushProtoTree(L, tree);
+
+ switch ( lua_pcall(L,3,0,0) ) {
+ case 0:
+ /* OK */
+ break;
+ case LUA_ERRRUN:
+ g_warning("Runtime error while calling dissectors.%s() ",pinfo->current_proto);
+ break;
+ case LUA_ERRMEM:
+ g_warning("Memory alloc error while calling dissectors.%s() ",pinfo->current_proto);
+ break;
+ default:
+ g_warning("-X2-");
+ g_assert_not_reached();
+ break;
+ }
+
lua_pinfo = NULL;
+ lua_tree = NULL;
+ lua_tvb = NULL;
}
static void init_lua(void) {
@@ -166,11 +215,12 @@ void proto_register_lua(void)
register_init_routine(init_lua);
L = lua_open();
+
luaopen_base(L);
luaopen_table(L);
luaopen_io(L);
luaopen_string(L);
- ValueString_register(L);
+
ProtoField_register(L);
ProtoFieldArray_register(L);
SubTreeType_register(L);
@@ -209,7 +259,7 @@ void proto_register_lua(void)
lua_newtable (L);
lua_settable(L, LUA_GLOBALSINDEX);
- lua_pushstring(L, "dissectors");
+ lua_pushstring(L, LUA_DISSECTORS_TABLE);
lua_newtable (L);
lua_settable(L, LUA_GLOBALSINDEX);
@@ -233,6 +283,9 @@ void proto_register_lua(void)
lua_data_handle = NULL;
lua_pinfo = NULL;
lua_tree = NULL;
+ lua_tvb = NULL;
+
+ lua_malformed = proto_get_id_by_filter_name("malformed");
}
diff --git a/plugins/lua/packet-lua.h b/plugins/lua/packet-lua.h
index e51c040229..c29c049171 100644
--- a/plugins/lua/packet-lua.h
+++ b/plugins/lua/packet-lua.h
@@ -48,6 +48,8 @@
#include <epan/report_err.h>
#include <epan/emem.h>
+#define LUA_DISSECTORS_TABLE "dissectors"
+
typedef struct _eth_field_t {
int hfid;
char* name;
@@ -89,9 +91,6 @@ typedef struct _eth_proto_t {
typedef struct {const gchar* str; enum ftenum id; } eth_ft_types_t;
-#define VALUE_STRING "ValueString"
-typedef GArray* ValueString;
-
#define PROTO_FIELD "ProtoField"
typedef struct _eth_field_t* ProtoField;
@@ -177,6 +176,8 @@ C* push##C(lua_State* L, C v) { \
extern packet_info* lua_pinfo;
extern proto_tree* lua_tree;
+extern tvbuff_t* lua_tvb;
+extern int lua_malformed;
extern dissector_handle_t lua_data_handle;
#define LUA_CLASS_DECLARE(C,CN) \
@@ -187,7 +188,6 @@ extern int C##_register(lua_State* L);
LUA_CLASS_DECLARE(Tap,TAP);
LUA_CLASS_DECLARE(Field,FIELD);
-LUA_CLASS_DECLARE(ValueString,VALUE_STRING);
LUA_CLASS_DECLARE(ProtoField,PROTO_FIELD);
LUA_CLASS_DECLARE(ProtoFieldArray,PROTO_FIELD_ARRAY);
LUA_CLASS_DECLARE(SubTreeType,SUB_TREE_TYPE);
@@ -211,4 +211,6 @@ extern void lua_tap_draw(void *tapdata);
extern GString* register_all_lua_taps(void);
+#define WARNSTACK(s) {int i; for (i = 1; i <= lua_gettop(L); i++) g_warning("-%s-> %i %s",s,i , lua_typename(L,lua_type(L,i))); }
+
#endif