From Balint Reczey

Fix for https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=2453

The patch fixes the problem by extending the original "outstanding stuff"
approach.

Now the pointer itself won't be NULLified, instead we track the pointers with
their expiry state in structs in the outstanding_stuff list.
The Lua objects refers to those structs instead of the actual pointers and
checks the expiry state of the pointers before accessing them.
The pointers are marked expired when the dissection of the frame is finished
and the allocated struct is freed by Lua's garbage collector.

If the garbage collector hits the struct when it holds a not expired pointer,
it marks it as expired (that means we don't have any object in Lua referring to
the pointer) and the struct will be freed at the end of the dissection of the
frame.

this is for the 1.0 branch


svn path=/trunk/; revision=25845
This commit is contained in:
Luis Ontanon 2008-07-26 23:41:31 +00:00
parent 5ad5441634
commit 006e41af12
8 changed files with 461 additions and 168 deletions

View File

@ -55,9 +55,10 @@ int dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
lua_pinfo = pinfo;
lua_tvb = tvb;
lua_tree = ep_alloc(sizeof(struct _wslua_treeitem));
lua_tree = g_malloc(sizeof(struct _wslua_treeitem));
lua_tree->tree = tree;
lua_tree->item = proto_tree_add_text(tree,tvb,0,0,"lua fake item");
lua_tree->expired = FALSE;
PROTO_ITEM_SET_HIDDEN(lua_tree->item);
/*
@ -102,9 +103,11 @@ int dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
expert_add_info_format(pinfo, pi, PI_DEBUG, PI_ERROR ,"Lua Error");
}
clear_outstanding_tvbs();
clear_outstanding_pinfos();
clear_outstanding_trees();
clear_outstanding_Tvb();
clear_outstanding_Pinfo();
clear_outstanding_Column();
clear_outstanding_Columns();
clear_outstanding_TreeItem();
lua_pinfo = NULL;

View File

@ -5,6 +5,7 @@
*
* (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
* (c) 2007, Tamas Regos <tamas.regos@ericsson.com>
* (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
*
* $Id$
*
@ -59,8 +60,18 @@
#define WSLUA_INIT_ROUTINES "init_routines"
#define LOG_DOMAIN_LUA "wslua"
struct _wslua_tvb {
tvbuff_t* ws_tvb;
gboolean expired;
};
struct _wslua_pinfo {
packet_info* ws_pinfo;
gboolean expired;
};
struct _wslua_tvbrange {
tvbuff_t* tvb;
struct _wslua_tvb* tvb;
int offset;
int len;
};
@ -139,11 +150,19 @@ struct _wslua_distbl_t {
struct _wslua_col_info {
column_info* cinfo;
gint col;
gboolean expired;
};
struct _wslua_cols {
column_info* cinfo;
gboolean expired;
};
struct _wslua_treeitem {
proto_item* item;
proto_tree* tree;
gboolean expired;
};
typedef void (*tap_extractor_t)(lua_State*,const void*);
@ -183,11 +202,11 @@ typedef struct _wslua_proto_t* Proto;
typedef struct _wslua_distbl_t* DissectorTable;
typedef dissector_handle_t Dissector;
typedef GByteArray* ByteArray;
typedef tvbuff_t* Tvb;
typedef struct _wslua_tvb* Tvb;
typedef struct _wslua_tvbrange* TvbRange;
typedef struct _wslua_col_info* Column;
typedef column_info* Columns;
typedef packet_info* Pinfo;
typedef struct _wslua_cols* Columns;
typedef struct _wslua_pinfo* Pinfo;
typedef struct _wslua_treeitem* TreeItem;
typedef address* Address;
typedef header_field_info** Field;
@ -307,6 +326,18 @@ typedef int dummy##C
#define NOP
#define FAIL_ON_NULL(s) if (! *p) luaL_argerror(L,index,s)
/* Clears or marks references that connects Lua to Wireshark structures */
#define CLEAR_OUTSTANDING(C, marker, marker_val) void clear_outstanding_##C(void) { \
while (outstanding_##C->len) { \
C p = (C)g_ptr_array_remove_index_fast(outstanding_##C,0); \
if (p) { \
if (p->marker != marker_val) \
p->marker = marker_val; \
else \
g_free(p); \
} \
} \
}
#define WSLUA_CLASS_DECLARE(C) \
@ -341,14 +372,16 @@ extern void lua_prime_all_fields(proto_tree* tree);
extern int Proto_commit(lua_State* L);
extern void* push_Tvb(lua_State* L, Tvb tvb);
extern void clear_outstanding_tvbs(void);
extern Tvb* push_Tvb(lua_State* L, tvbuff_t* tvb);
extern void clear_outstanding_Tvb(void);
extern void* push_Pinfo(lua_State* L, Pinfo p);
extern void clear_outstanding_pinfos(void);
extern Pinfo* push_Pinfo(lua_State* L, packet_info* p);
extern void clear_outstanding_Pinfo(void);
extern void clear_outstanding_Column(void);
extern void clear_outstanding_Columns(void);
extern void* push_TreeItem(lua_State* L, TreeItem ti);
extern void clear_outstanding_trees(void);
extern TreeItem* push_TreeItem(lua_State* L, TreeItem ti);
extern void clear_outstanding_TreeItem(void);
extern void wslua_print_stack(char* s, lua_State* L);

View File

@ -154,8 +154,9 @@ int FieldInfo_get_range(lua_State* L) {
/* the TvbRange covering this field */
FieldInfo fi = checkFieldInfo(L,1);
TvbRange r = ep_alloc(sizeof(struct _wslua_tvbrange));
r->tvb = ep_alloc(sizeof(struct _wslua_tvb));
r->tvb = fi->ds_tvb;
r->tvb->ws_tvb = fi->ds_tvb;
r->offset = fi->start;
r->len = fi->length;

View File

@ -100,9 +100,10 @@ int lua_tap_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, const
lua_pinfo = pinfo;
lua_tvb = edt->tvb;
lua_tree = ep_alloc(sizeof(struct _wslua_treeitem));
lua_tree = g_malloc(sizeof(struct _wslua_treeitem));
lua_tree->tree = edt->tree;
lua_tree->item = NULL;
lua_tree->expired = FALSE;
switch ( lua_pcall(tap->L,3,1,1) ) {
case 0:
@ -118,8 +119,8 @@ int lua_tap_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, const
break;
}
clear_outstanding_pinfos();
clear_outstanding_tvbs();
clear_outstanding_Pinfo();
clear_outstanding_Tvb();
lua_pinfo = NULL;
lua_tvb = NULL;

View File

@ -4,6 +4,7 @@
* Wireshark's interface to the Lua Programming Language
*
* (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
* (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
*
* $Id$
*
@ -36,29 +37,31 @@
/*
* NULLify lua userdata to avoid crashing when trying to
* access saved copies of invalid stuff.
*
* see comment on lua_tvb.c
* Track pointers to wireshark's structures.
* see comment on wslua_tvb.c
*/
static GPtrArray* outstanding_stuff = NULL;
static GPtrArray* outstanding_Pinfo = NULL;
static GPtrArray* outstanding_Column = NULL;
static GPtrArray* outstanding_Columns = NULL;
void clear_outstanding_pinfos(void) {
while (outstanding_stuff->len) {
void** p = (void**)g_ptr_array_remove_index_fast(outstanding_stuff,0);
*p = NULL;
CLEAR_OUTSTANDING(Pinfo,expired, TRUE)
CLEAR_OUTSTANDING(Column,expired, TRUE)
CLEAR_OUTSTANDING(Columns,expired, TRUE)
Pinfo* push_Pinfo(lua_State* L, packet_info* ws_pinfo) {
Pinfo pinfo = NULL;
if (ws_pinfo) {
pinfo = g_malloc(sizeof(struct _wslua_pinfo));
pinfo->ws_pinfo = ws_pinfo;
pinfo->expired = FALSE;
g_ptr_array_add(outstanding_Pinfo,pinfo);
}
return pushPinfo(L,pinfo);
}
void* push_Pinfo(lua_State* L, Pinfo pinfo) {
void** p = (void**)pushPinfo(L,pinfo);
g_ptr_array_add(outstanding_stuff,p);
return p;
}
#define PUSH_COLUMN(L,c) g_ptr_array_add(outstanding_stuff,pushColumn(L,c))
#define PUSH_COLUMNS(L,c) g_ptr_array_add(outstanding_stuff,pushColumns(L,c))
#define PUSH_COLUMN(L,c) {g_ptr_array_add(outstanding_Column,c);pushColumn(L,c);}
#define PUSH_COLUMNS(L,c) {g_ptr_array_add(outstanding_Columns,c);pushColumns(L,c);}
WSLUA_CLASS_DEFINE(Address,NOP,NOP); /* Represents an address */
@ -377,6 +380,20 @@ WSLUA_METAMETHOD Column__tostring(lua_State *L) {
WSLUA_RETURN(1); /* A string representing the column */
}
WSLUA_METAMETHOD Column__gc(lua_State* L) {
Column col = checkColumn(L,1);
if (!col) return 0;
if (!col->expired)
col->expired = TRUE;
else
g_free(col);
return 0;
}
WSLUA_METHOD Column_clear(lua_State *L) {
/* Clears a Column */
Column c = checkColumn(L,1);
@ -452,6 +469,7 @@ WSLUA_METHODS Column_methods[] = {
WSLUA_META Column_meta[] = {
{"__tostring", Column__tostring },
{"__gc", Column__gc },
{0,0}
};
@ -485,14 +503,18 @@ WSLUA_METAMETHOD Columns__newindex(lua_State *L) {
const char* text;
if (!cols) return 0;
if (cols->expired) {
luaL_error(L,"expired column");
return 0;
}
colname = luaL_checkstring(L,WSLUA_ARG_Columns__newindex_COLUMN);
text = luaL_checkstring(L,WSLUA_ARG_Columns__newindex_TEXT);
for(cn = colnames; cn->name; cn++) {
if( g_str_equal(cn->name,colname) ) {
if (check_col(cols, cn->id))
col_set_str(cols, cn->id, text);
if (check_col(cols->cinfo, cn->id))
col_set_str(cols->cinfo, cn->id, text);
return 0;
}
}
@ -508,23 +530,29 @@ WSLUA_METAMETHOD Columns_index(lua_State *L) {
const char* colname = luaL_checkstring(L,2);
if (!cols) {
Column c = ep_alloc(sizeof(struct _wslua_col_info));
Column c = g_malloc(sizeof(struct _wslua_col_info));
c->cinfo = NULL;
c->col = col_name_to_id(colname);
c->expired = FALSE;
PUSH_COLUMN(L,c);
return 1;
}
if (cols->expired) {
luaL_error(L,"expired column");
return 0;
}
if (!colname) return 0;
for(cn = colnames; cn->name; cn++) {
if( g_str_equal(cn->name,colname) ) {
Column c = ep_alloc(sizeof(struct _wslua_col_info));
c->cinfo = cols;
Column c = g_malloc(sizeof(struct _wslua_col_info));
c->cinfo = cols->cinfo;
c->col = col_name_to_id(colname);
c->expired = FALSE;
PUSH_COLUMN(L,c);
return 1;
@ -534,11 +562,26 @@ WSLUA_METAMETHOD Columns_index(lua_State *L) {
return 0;
}
WSLUA_METAMETHOD Columns_gc(lua_State* L) {
Columns cols = checkColumns(L,1);
if (!cols) return 0;
if (!cols->expired)
cols->expired = TRUE;
else
g_free(cols);
return 0;
}
static const luaL_reg Columns_meta[] = {
{"__tostring", Columns__tostring },
{"__newindex", Columns__newindex },
{"__index", Columns_index},
{"__gc", Columns_gc},
{ NULL, NULL }
};
@ -557,6 +600,10 @@ static int Pinfo_tostring(lua_State *L) { lua_pushstring(L,"a Pinfo"); return 1;
#define PINFO_GET_NUMBER(name,val) static int name(lua_State *L) { \
Pinfo pinfo = checkPinfo(L,1); \
if (!pinfo) return 0;\
if (pinfo->expired) { \
luaL_error(L,"expired_pinfo"); \
return 0; \
} \
lua_pushnumber(L,(lua_Number)(val));\
return 1;\
}
@ -565,6 +612,10 @@ static int Pinfo_tostring(lua_State *L) { lua_pushstring(L,"a Pinfo"); return 1;
Pinfo pinfo = checkPinfo(L,1); \
const gchar* value; \
if (!pinfo) return 0; \
if (pinfo->expired) { \
luaL_error(L,"expired_pinfo"); \
return 0; \
} \
value = val; \
if (value) lua_pushstring(L,(const char*)(value)); else lua_pushnil(L); \
return 1; \
@ -574,25 +625,29 @@ static int Pinfo_tostring(lua_State *L) { lua_pushstring(L,"a Pinfo"); return 1;
Pinfo pinfo = checkPinfo(L,1); \
Address addr = g_malloc(sizeof(address)); \
if (!pinfo) return 0; \
COPY_ADDRESS(addr, &(pinfo->role)); \
if (pinfo->expired) { \
luaL_error(L,"expired_pinfo"); \
return 0; \
} \
COPY_ADDRESS(addr, &(pinfo->ws_pinfo->role)); \
pushAddress(L,addr); \
return 1; \
}
PINFO_GET_NUMBER(Pinfo_number,pinfo->fd->num)
PINFO_GET_NUMBER(Pinfo_len,pinfo->fd->pkt_len)
PINFO_GET_NUMBER(Pinfo_caplen,pinfo->fd->cap_len)
PINFO_GET_NUMBER(Pinfo_abs_ts,(((double)pinfo->fd->abs_ts.secs) + (((double)pinfo->fd->abs_ts.nsecs) / 1000000000.0) ))
PINFO_GET_NUMBER(Pinfo_rel_ts,(((double)pinfo->fd->rel_ts.secs) + (((double)pinfo->fd->rel_ts.nsecs) / 1000000000.0) ))
PINFO_GET_NUMBER(Pinfo_delta_ts,(((double)pinfo->fd->del_cap_ts.secs) + (((double)pinfo->fd->del_cap_ts.nsecs) / 1000000000.0) ))
PINFO_GET_NUMBER(Pinfo_delta_dis_ts,(((double)pinfo->fd->del_dis_ts.secs) + (((double)pinfo->fd->del_dis_ts.nsecs) / 1000000000.0) ))
PINFO_GET_NUMBER(Pinfo_ipproto,pinfo->ipproto)
PINFO_GET_NUMBER(Pinfo_circuit_id,pinfo->circuit_id)
PINFO_GET_NUMBER(Pinfo_ptype,pinfo->ptype)
PINFO_GET_NUMBER(Pinfo_src_port,pinfo->srcport)
PINFO_GET_NUMBER(Pinfo_dst_port,pinfo->destport)
PINFO_GET_NUMBER(Pinfo_number,pinfo->ws_pinfo->fd->num)
PINFO_GET_NUMBER(Pinfo_len,pinfo->ws_pinfo->fd->pkt_len)
PINFO_GET_NUMBER(Pinfo_caplen,pinfo->ws_pinfo->fd->cap_len)
PINFO_GET_NUMBER(Pinfo_abs_ts,(((double)pinfo->ws_pinfo->fd->abs_ts.secs) + (((double)pinfo->ws_pinfo->fd->abs_ts.nsecs) / 1000000000.0) ))
PINFO_GET_NUMBER(Pinfo_rel_ts,(((double)pinfo->ws_pinfo->fd->rel_ts.secs) + (((double)pinfo->ws_pinfo->fd->rel_ts.nsecs) / 1000000000.0) ))
PINFO_GET_NUMBER(Pinfo_delta_ts,(((double)pinfo->ws_pinfo->fd->del_cap_ts.secs) + (((double)pinfo->ws_pinfo->fd->del_cap_ts.nsecs) / 1000000000.0) ))
PINFO_GET_NUMBER(Pinfo_delta_dis_ts,(((double)pinfo->ws_pinfo->fd->del_dis_ts.secs) + (((double)pinfo->ws_pinfo->fd->del_dis_ts.nsecs) / 1000000000.0) ))
PINFO_GET_NUMBER(Pinfo_ipproto,pinfo->ws_pinfo->ipproto)
PINFO_GET_NUMBER(Pinfo_circuit_id,pinfo->ws_pinfo->circuit_id)
PINFO_GET_NUMBER(Pinfo_ptype,pinfo->ws_pinfo->ptype)
PINFO_GET_NUMBER(Pinfo_src_port,pinfo->ws_pinfo->srcport)
PINFO_GET_NUMBER(Pinfo_dst_port,pinfo->ws_pinfo->destport)
PINFO_GET_STRING(Pinfo_curr_proto,pinfo->current_proto)
PINFO_GET_STRING(Pinfo_curr_proto,pinfo->ws_pinfo->current_proto)
PINFO_GET_ADDRESS(Pinfo_net_src,net_src)
PINFO_GET_ADDRESS(Pinfo_net_dst,net_dst)
@ -604,7 +659,11 @@ PINFO_GET_ADDRESS(Pinfo_dst,dst)
static int Pinfo_visited(lua_State *L) {
Pinfo pinfo = checkPinfo(L,1);
if (!pinfo) return 0;
lua_pushboolean(L,pinfo->fd->flags.visited);
if (pinfo->expired) {
luaL_error(L,"expired_pinfo");
return 0;
}
lua_pushboolean(L,pinfo->ws_pinfo->fd->flags.visited);
return 1;
}
@ -613,25 +672,39 @@ static int Pinfo_match(lua_State *L) {
Pinfo pinfo = checkPinfo(L,1);
if (!pinfo) return 0;
if (pinfo->expired) {
luaL_error(L,"expired_pinfo");
return 0;
}
if (pinfo->match_string) {
lua_pushstring(L,pinfo->match_string);
if (pinfo->ws_pinfo->match_string) {
lua_pushstring(L,pinfo->ws_pinfo->match_string);
} else {
lua_pushnumber(L,(lua_Number)(pinfo->match_port));
lua_pushnumber(L,(lua_Number)(pinfo->ws_pinfo->match_port));
}
return 1;
}
static int Pinfo_columns(lua_State *L) {
Columns cols = NULL;
Pinfo pinfo = checkPinfo(L,1);
const gchar* colname = luaL_optstring(L,2,NULL);
if (pinfo->expired) {
luaL_error(L,"expired_pinfo");
return 0;
}
cols = g_malloc(sizeof(struct _wslua_cols));
cols->cinfo = pinfo->ws_pinfo->cinfo;
cols->expired = FALSE;
if (!colname) {
PUSH_COLUMNS(L,pinfo->cinfo);
PUSH_COLUMNS(L,cols);
} else {
lua_settop(L,0);
PUSH_COLUMNS(L,pinfo->cinfo);
PUSH_COLUMNS(L,cols);
lua_pushstring(L,colname);
return Columns_index(L);
}
@ -666,6 +739,11 @@ int Pinfo_set_addr(lua_State* L, packet_info* pinfo, pinfo_param_type_t pt) {
luaL_error(L,"Not an OK address");
return 0;
}
if (!pinfo) {
luaL_error(L,"expired_pinfo");
return 0;
}
switch(pt) {
case PARAM_ADDR_SRC:
@ -698,6 +776,11 @@ int Pinfo_set_addr(lua_State* L, packet_info* pinfo, pinfo_param_type_t pt) {
int Pinfo_set_int(lua_State* L, packet_info* pinfo, pinfo_param_type_t pt) {
guint v = luaL_checkint(L,1);
if (!pinfo) {
luaL_error(L,"expired_pinfo");
return 0;
}
switch(pt) {
case PARAM_PORT_SRC:
pinfo->srcport = v;
@ -727,11 +810,15 @@ static int Pinfo_hi(lua_State *L) {
Address addr = g_malloc(sizeof(address));
if (!pinfo) return 0;
if (pinfo->expired) {
luaL_error(L,"expired_pinfo");
return 0;
}
if (CMP_ADDRESS(&(pinfo->src), &(pinfo->dst) ) >= 0) {
COPY_ADDRESS(addr, &(pinfo->src));
if (CMP_ADDRESS(&(pinfo->ws_pinfo->src), &(pinfo->ws_pinfo->dst) ) >= 0) {
COPY_ADDRESS(addr, &(pinfo->ws_pinfo->src));
} else {
COPY_ADDRESS(addr, &(pinfo->dst));
COPY_ADDRESS(addr, &(pinfo->ws_pinfo->dst));
}
pushAddress(L,addr);
@ -743,11 +830,15 @@ static int Pinfo_lo(lua_State *L) {
Address addr = g_malloc(sizeof(address));
if (!pinfo) return 0;
if (pinfo->expired) {
luaL_error(L,"expired_pinfo");
return 0;
}
if (CMP_ADDRESS(&(pinfo->src), &(pinfo->dst) ) < 0) {
COPY_ADDRESS(addr, &(pinfo->src));
if (CMP_ADDRESS(&(pinfo->ws_pinfo->src), &(pinfo->ws_pinfo->dst) ) < 0) {
COPY_ADDRESS(addr, &(pinfo->ws_pinfo->src));
} else {
COPY_ADDRESS(addr, &(pinfo->dst));
COPY_ADDRESS(addr, &(pinfo->ws_pinfo->dst));
}
pushAddress(L,addr);
@ -851,6 +942,10 @@ static int Pinfo_index(lua_State* L) {
lua_pushnil(L);
return 1;
}
if (pinfo->expired) {
luaL_error(L,"expired_pinfo");
return 0;
}
for (curr = Pinfo_methods ; curr->name ; curr++) {
if (g_str_equal(curr->name,name)) {
@ -873,6 +968,10 @@ static int Pinfo_setindex(lua_State* L) {
if (! (pinfo && name) ) {
return 0;
}
if (pinfo->expired) {
luaL_error(L,"expired_pinfo");
return 0;
}
for (curr = Pinfo_methods ; curr->name ; curr++) {
if (g_str_equal(curr->name,name)) {
@ -884,19 +983,36 @@ static int Pinfo_setindex(lua_State* L) {
lua_remove(L,1);
lua_remove(L,1);
return method(L,pinfo,param_type);
return method(L,pinfo->ws_pinfo,param_type);
}
WSLUA_METAMETHOD Pinfo_gc(lua_State* L) {
Pinfo pinfo = checkPinfo(L,1);
if (!pinfo) return 0;
if (!pinfo->expired)
pinfo->expired = TRUE;
else
g_free(pinfo);
return 0;
}
static const luaL_reg Pinfo_meta[] = {
{"__index", Pinfo_index},
{"__newindex",Pinfo_setindex},
{"__tostring", Pinfo_tostring},
{"__gc", Pinfo_gc},
{ NULL, NULL }
};
int Pinfo_register(lua_State* L) {
WSLUA_REGISTER_META(Pinfo);
outstanding_stuff = g_ptr_array_new();
outstanding_Pinfo = g_ptr_array_new();
outstanding_Column = g_ptr_array_new();
outstanding_Columns = g_ptr_array_new();
return 1;
}

View File

@ -1317,7 +1317,7 @@ WSLUA_METHOD Dissector_call(lua_State* L) {
if (! ( d && tvb && pinfo) ) return 0;
TRY {
call_dissector(d, tvb, pinfo, ti->tree);
call_dissector(d, tvb->ws_tvb, pinfo->ws_pinfo, ti->tree);
/* XXX Are we sure about this??? is this the right/only thing to catch */
} CATCH(ReportedBoundsError) {
proto_tree_add_protocol_format(lua_tree->tree, lua_malformed, lua_tvb, 0, 0, "[Malformed Frame: Packet Length]" );
@ -1516,7 +1516,7 @@ WSLUA_METHOD DissectorTable_try (lua_State *L) {
ftenum_t type;
gchar* error = NULL;
if (! (dt && tvb && pinfo && ti) ) return 0;
if (! (dt && tvb && tvb->ws_tvb && pinfo && ti) ) return 0;
type = get_dissector_table_selector_type(dt->name);
@ -1527,20 +1527,20 @@ WSLUA_METHOD DissectorTable_try (lua_State *L) {
if (!pattern) return 0;
if (dissector_try_string(dt->table,pattern,tvb,pinfo,ti->tree))
if (dissector_try_string(dt->table,pattern,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree))
return 0;
} 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,ti->tree))
if (dissector_try_port(dt->table,port,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree))
return 0;
} else {
luaL_error(L,"No such type of dissector_table");
}
call_dissector(lua_data_handle,tvb,pinfo,ti->tree);
call_dissector(lua_data_handle,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree);
/* XXX Are we sure about this??? is this the right/only thing to catch */
} CATCH(ReportedBoundsError) {

View File

@ -4,6 +4,7 @@
* Wireshark's interface to the Lua Programming Language
*
* (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
* (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
*
* $Id$
*
@ -33,22 +34,16 @@
static gint wslua_ett = -1;
static GPtrArray* outstanding_stuff = NULL;
static GPtrArray* outstanding_TreeItem = NULL;
#define PUSH_TREEITEM(L,i) g_ptr_array_add(outstanding_stuff,push_TreeItem(L,i))
#define PUSH_TREEITEM(L,i) {g_ptr_array_add(outstanding_TreeItem,i);pushTreeItem(L,i);}
void* push_TreeItem(lua_State*L, TreeItem t) {
void** p = (void**)pushTreeItem(L,t);
g_ptr_array_add(outstanding_stuff,p);
return p;
TreeItem* push_TreeItem(lua_State*L, TreeItem t) {
g_ptr_array_add(outstanding_TreeItem,t);
return pushTreeItem(L,t);
}
void clear_outstanding_trees(void) {
while (outstanding_stuff->len) {
void** p = (void**)g_ptr_array_remove_index_fast(outstanding_stuff,0);
*p = NULL;
}
}
CLEAR_OUTSTANDING(TreeItem, expired, TRUE)
WSLUA_CLASS_DEFINE(TreeItem,NOP,NOP);
/* TreeItems represent information in the packet-details pane.
@ -67,6 +62,11 @@ static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) {
if (!tree_item) {
return luaL_error(L,"not a TreeItem!");
}
if (tree_item->expired) {
luaL_error(L,"expired TreeItem");
return 0;
}
if (! ( field = shiftProtoField(L,1) ) ) {
if (( proto = shiftProto(L,1) )) {
hfid = proto->hfid;
@ -83,7 +83,8 @@ static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) {
if (!tvbr) {
tvbr = ep_alloc(sizeof(struct _wslua_tvbrange));
tvbr->tvb = lua_tvb;
tvbr->tvb = ep_alloc(sizeof(struct _wslua_tvb));
tvbr->tvb->ws_tvb = lua_tvb;
tvbr->offset = 0;
tvbr->len = 0;
}
@ -92,7 +93,7 @@ static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) {
if (lua_gettop(L)) {
switch(type) {
case FT_PROTOCOL:
item = proto_tree_add_item(tree_item->tree,hfid,tvbr->tvb,tvbr->offset,tvbr->len,FALSE);
item = proto_tree_add_item(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,FALSE);
lua_pushnumber(L,0);
lua_insert(L,1);
break;
@ -101,35 +102,35 @@ static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) {
case FT_UINT24:
case FT_UINT32:
case FT_FRAMENUM:
item = proto_tree_add_uint(tree_item->tree,hfid,tvbr->tvb,tvbr->offset,tvbr->len,(guint32)luaL_checknumber(L,1));
item = proto_tree_add_uint(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(guint32)luaL_checknumber(L,1));
break;
case FT_INT8:
case FT_INT16:
case FT_INT24:
case FT_INT32:
item = proto_tree_add_int(tree_item->tree,hfid,tvbr->tvb,tvbr->offset,tvbr->len,(gint32)luaL_checknumber(L,1));
item = proto_tree_add_int(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(gint32)luaL_checknumber(L,1));
break;
case FT_FLOAT:
item = proto_tree_add_float(tree_item->tree,hfid,tvbr->tvb,tvbr->offset,tvbr->len,(float)luaL_checknumber(L,1));
item = proto_tree_add_float(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(float)luaL_checknumber(L,1));
break;
case FT_DOUBLE:
item = proto_tree_add_double(tree_item->tree,hfid,tvbr->tvb,tvbr->offset,tvbr->len,(double)luaL_checknumber(L,1));
item = proto_tree_add_double(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(double)luaL_checknumber(L,1));
break;
case FT_STRING:
case FT_STRINGZ:
item = proto_tree_add_string(tree_item->tree,hfid,tvbr->tvb,tvbr->offset,tvbr->len,luaL_checkstring(L,1));
item = proto_tree_add_string(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,luaL_checkstring(L,1));
break;
case FT_BYTES:
item = proto_tree_add_bytes(tree_item->tree,hfid,tvbr->tvb,tvbr->offset,tvbr->len, (const guint8*) luaL_checkstring(L,1));
item = proto_tree_add_bytes(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len, (const guint8*) luaL_checkstring(L,1));
break;
case FT_UINT64:
item = proto_tree_add_uint64(tree_item->tree,hfid,tvbr->tvb,tvbr->offset,tvbr->len,(guint64)luaL_checknumber(L,1));
item = proto_tree_add_uint64(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(guint64)luaL_checknumber(L,1));
break;
case FT_INT64:
item = proto_tree_add_int64(tree_item->tree,hfid,tvbr->tvb,tvbr->offset,tvbr->len,(gint64)luaL_checknumber(L,1));
item = proto_tree_add_int64(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(gint64)luaL_checknumber(L,1));
break;
case FT_IPv4:
item = proto_tree_add_ipv4(tree_item->tree,hfid,tvbr->tvb,tvbr->offset,tvbr->len,*((guint32*)(checkAddress(L,1)->data)));
item = proto_tree_add_ipv4(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,*((guint32*)(checkAddress(L,1)->data)));
break;
case FT_ETHER:
case FT_UINT_BYTES:
@ -145,7 +146,7 @@ static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) {
lua_remove(L,1);
} else {
item = proto_tree_add_item(tree_item->tree, hfid, tvbr->tvb, tvbr->offset, tvbr->len, little_endian);
item = proto_tree_add_item(tree_item->tree, hfid, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, little_endian);
}
if ( lua_gettop(L) ) {
@ -161,7 +162,7 @@ static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) {
if (lua_gettop(L)) {
const gchar* s = lua_tostring(L,1);
item = proto_tree_add_text(tree_item->tree, tvbr->tvb, tvbr->offset, tvbr->len,"%s",s);
item = proto_tree_add_text(tree_item->tree, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len,"%s",s);
lua_remove(L,1);
}
} else {
@ -182,9 +183,10 @@ static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) {
}
tree_item = ep_alloc(sizeof(struct _wslua_treeitem));
tree_item = g_malloc(sizeof(struct _wslua_treeitem));
tree_item->item = item;
tree_item->tree = proto_item_add_subtree(item,ett > 0 ? ett : wslua_ett);
tree_item->expired = FALSE;
PUSH_TREEITEM(L,tree_item);
@ -231,6 +233,11 @@ WSLUA_METHOD TreeItem_append_text(lua_State *L) {
const gchar* s;
if (ti) {
if (ti->expired) {
luaL_error(L,"expired TreeItem");
return 0;
}
s = luaL_checkstring(L,2);
proto_item_append_text(ti->item,"%s",s);
}
@ -246,7 +253,11 @@ WSLUA_METHOD TreeItem_set_expert_flags(lua_State *L) {
int severity = luaL_optint(L,3,PI_CHAT);
if ( ti && ti->item ) {
proto_item_set_expert_flags(ti->item,group,severity);
if (ti->expired) {
luaL_error(L,"expired TreeItem");
return 0;
}
proto_item_set_expert_flags(ti->item,group,severity);
}
return 0;
@ -263,6 +274,10 @@ WSLUA_METHOD TreeItem_add_expert_info(lua_State *L) {
const gchar* str = luaL_optstring(L,4,"Expert Info");
if ( ti && ti->item ) {
if (ti->expired) {
luaL_error(L,"expired TreeItem");
return 0;
}
expert_add_info_format(lua_pinfo, ti->item, group, severity, "%s", str);
}
@ -273,6 +288,10 @@ WSLUA_METHOD TreeItem_set_generated(lua_State *L) {
/* marks the TreeItem as a generated field (with data infered but not contained in the packet). */
TreeItem ti = checkTreeItem(L,1);
if (ti) {
if (ti->expired) {
luaL_error(L,"expired TreeItem");
return 0;
}
PROTO_ITEM_SET_GENERATED(ti->item);
}
return 0;
@ -283,11 +302,29 @@ WSLUA_METHOD TreeItem_set_hidden(lua_State *L) {
/* should not be used */
TreeItem ti = checkTreeItem(L,1);
if (ti) {
if (ti->expired) {
luaL_error(L,"expired TreeItem");
return 0;
}
PROTO_ITEM_SET_HIDDEN(ti->item);
}
return 0;
}
WSLUA_METAMETHOD TreeItem_gc(lua_State* L) {
TreeItem ti = checkTreeItem(L,1);
if (!ti) return 0;
if (!ti->expired)
ti->expired = TRUE;
else
g_free(ti);
return 0;
}
static const luaL_reg TreeItem_methods[] = {
{"add", TreeItem_add},
{"add_le", TreeItem_add_le},
@ -300,6 +337,7 @@ static const luaL_reg TreeItem_methods[] = {
{ NULL, NULL }
};
static const luaL_reg TreeItem_meta[] = {
{"__gc", TreeItem_gc},
{ NULL, NULL }
};
@ -309,7 +347,7 @@ int TreeItem_register(lua_State *L) {
gint* etts[] = { &wslua_ett };
WSLUA_REGISTER_CLASS(TreeItem);
outstanding_stuff = g_ptr_array_new();
outstanding_TreeItem = g_ptr_array_new();
proto_register_subtree_array(etts,1);

View File

@ -4,6 +4,7 @@
* Wireshark's interface to the Lua Programming Language
*
* (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
* (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
*
* $Id$
*
@ -310,14 +311,18 @@ int ByteArray_register(lua_State* L) {
* not already done by the TVB itself. In lua's terms is necessary to avoid abusing TRY{}CATCH(){}
* via preemptive bounds checking.
*
* These lua objects have to be "NULLified after use", that is, we cannot leave pointers in the
* lua machine to a tvb or a tvbr that might exist anymore.
* These lua objects refers to structures in wireshak that are freed independently from Lua's garbage collector.
* To avoid using a pointer from Lua to Wireshark's that is already freed, we maintain a list of the pointers with
* a marker that track's it's expiry.
*
* To do so we are going to keep a pointer to every "box" in which lua has placed a pointer to our object
* and then NULLify the object lua points to.
* All pointers are marked as expired when the dissection of the current frame is finished of when the garbage
* collector tries to free the object referring to the pointer, whichever comes first.
*
* All allocated memory chunks used for tracking the pointers' state are freed after marking the pointer as expired
* by the garbage collector or by the end of the dissection of the current frame, whichever comes second.
*
* We check the expiry state of the pointer before each acces.
*
* Other than that we are going to check every instance of a potentialy NULLified object before using it
* and report an error to the lua machine if it happens to be NULLified.
*/
WSLUA_CLASS_DEFINE(Tvb,FAIL_ON_NULL("expired tvb"),NOP);
@ -327,22 +332,21 @@ listener or dissector call and are destroyed as soon as the listener/dissector r
to them are unusable once the function has returned.
To create a tvbrange the tvb must be called with offset and length as optional arguments ( the offset defaults to 0 and the length to tvb:len() )*/
static GPtrArray* outstanding_stuff = NULL;
static GPtrArray* outstanding_Tvb = NULL;
static GPtrArray* outstanding_TvbRange = NULL;
#define PUSH_TVB(L,t) g_ptr_array_add(outstanding_stuff,pushTvb(L,t))
#define PUSH_TVBRANGE(L,t) g_ptr_array_add(outstanding_stuff,pushTvbRange(L,t))
#define PUSH_TVB(L,t) {g_ptr_array_add(outstanding_Tvb,t);pushTvb(L,t);}
#define PUSH_TVBRANGE(L,t) {g_ptr_array_add(outstanding_TvbRange,t);pushTvbRange(L,t);}
void clear_outstanding_tvbs(void) {
while (outstanding_stuff->len) {
void** p = (void**)g_ptr_array_remove_index_fast(outstanding_stuff,0);
*p = NULL;
}
}
CLEAR_OUTSTANDING(Tvb,expired, TRUE)
void* push_Tvb(lua_State* L, Tvb tvb) {
void** p = (void**)pushTvb(L,tvb);
g_ptr_array_add(outstanding_stuff,p);
return p;
Tvb* push_Tvb(lua_State* L, tvbuff_t* ws_tvb) {
Tvb tvb = g_malloc(sizeof(struct _wslua_tvb));
tvb->ws_tvb = ws_tvb;
tvb->expired = FALSE;
g_ptr_array_add(outstanding_Tvb,tvb);
return pushTvb(L,tvb);
}
@ -368,10 +372,12 @@ WSLUA_CONSTRUCTOR Tvb_new_real (lua_State *L) {
data = g_memdup(ba->data, ba->len);
tvb = tvb_new_real_data(data, ba->len,ba->len);
tvb_set_free_cb(tvb, g_free);
tvb = g_malloc(sizeof(struct _wslua_tvb));
tvb->ws_tvb = tvb_new_real_data(data, ba->len,ba->len);
tvb->expired = FALSE;
tvb_set_free_cb(tvb->ws_tvb, g_free);
add_new_data_source(lua_pinfo, tvb, name);
add_new_data_source(lua_pinfo, tvb->ws_tvb, name);
PUSH_TVB(L,tvb);
WSLUA_RETURN(1); /* the created Tvb. */
}
@ -381,11 +387,19 @@ WSLUA_CONSTRUCTOR Tvb_tvb (lua_State *L) {
#define WSLUA_ARG_Tvb_new_subset_RANGE 2 /* the TvbRange from which to create the new Tvb. */
TvbRange tvbr = checkTvbRange(L,1);
Tvb tvb;
if (! tvbr) return 0;
if (! (tvbr && tvbr->tvb)) return 0;
if (tvbr->tvb->expired) {
luaL_error(L,"expired tvb");
return 0;
}
if (tvb_offset_exists(tvbr->tvb, tvbr->offset + tvbr->len -1 )) {
PUSH_TVB(L, tvb_new_subset(tvbr->tvb,tvbr->offset,tvbr->len, tvbr->len) );
if (tvb_offset_exists(tvbr->tvb->ws_tvb, tvbr->offset + tvbr->len -1 )) {
tvb = g_malloc(sizeof(struct _wslua_tvb));
tvb->expired = FALSE;
tvb->ws_tvb = tvb_new_subset(tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len, tvbr->len);
PUSH_TVB(L, tvb);
return 1;
} else {
luaL_error(L,"Out Of Bounds");
@ -400,21 +414,42 @@ WSLUA_METAMETHOD Tvb__tostring(lua_State* L) {
gchar* str;
if (!tvb) return 0;
if (tvb->expired) {
luaL_error(L,"expired tvb");
return 0;
}
len = tvb_length(tvb);
str = ep_strdup_printf("TVB(%i) : %s",len,tvb_bytes_to_str(tvb,0,len));
len = tvb_length(tvb->ws_tvb);
str = ep_strdup_printf("TVB(%i) : %s",len,tvb_bytes_to_str(tvb->ws_tvb,0,len));
lua_pushstring(L,str);
WSLUA_RETURN(1); /* the string. */
}
WSLUA_METAMETHOD Tvb__gc(lua_State* L) {
Tvb tvb = checkTvb(L,1);
if (!tvb) return 0;
if (!tvb->expired)
tvb->expired = TRUE;
else
g_free(tvb);
return 0;
}
WSLUA_METHOD Tvb_len(lua_State* L) {
/* obtain the length of a TVB */
Tvb tvb = checkTvb(L,1);
if (!tvb) return 0;
if (tvb->expired) {
luaL_error(L,"expired tvb");
return 0;
}
lua_pushnumber(L,tvb_length(tvb));
lua_pushnumber(L,tvb_length(tvb->ws_tvb));
WSLUA_RETURN(1); /* the length of the Tvb. */
}
@ -423,8 +458,12 @@ WSLUA_METHOD Tvb_offset(lua_State* L) {
Tvb tvb = checkTvb(L,1);
if (!tvb) return 0;
if (tvb->expired) {
luaL_error(L,"expired tvb");
return 0;
}
lua_pushnumber(L,TVB_RAW_OFFSET(tvb));
lua_pushnumber(L,TVB_RAW_OFFSET(tvb->ws_tvb));
WSLUA_RETURN(1); /* the raw offset of the Tvb. */
}
@ -442,22 +481,30 @@ WSLUA_CLASS_DEFINE(TvbRange,FAIL_ON_NULL("expired tvbrange"),NOP);
* TvbRanges are created by calling a tvb (e.g. tvb(offset,length)). If the TvbRange span is outside the Tvb's range the creation will cause a runtime error.
*/
TvbRange new_TvbRange(lua_State* L, tvbuff_t* tvb, int offset, int len) {
TvbRange new_TvbRange(lua_State* L, tvbuff_t* ws_tvb, int offset, int len) {
TvbRange tvbr;
if (!ws_tvb) {
luaL_error(L,"expired tvb");
return 0;
}
if (len == -1) {
len = tvb_length_remaining(tvb,offset);
len = tvb_length_remaining(ws_tvb,offset);
if (len < 0) {
luaL_error(L,"out of bounds");
return 0;
}
} else if ( (guint)(len + offset) > tvb_length(tvb)) {
} else if ( (guint)(len + offset) > tvb_length(ws_tvb)) {
luaL_error(L,"Range is out of bounds");
return NULL;
}
tvbr = ep_alloc(sizeof(struct _wslua_tvbrange));
tvbr->tvb = tvb;
tvbr->tvb = g_malloc(sizeof(struct _wslua_tvb));
tvbr->tvb->ws_tvb = ws_tvb;
tvbr->tvb->expired = FALSE;
tvbr->offset = offset;
tvbr->len = len;
@ -476,8 +523,12 @@ WSLUA_METHOD Tvb_range(lua_State* L) {
TvbRange tvbr;
if (!tvb) return 0;
if (tvb->expired) {
luaL_error(L,"expired tvb");
return 0;
}
if ((tvbr = new_TvbRange(L,tvb,offset,len))) {
if ((tvbr = new_TvbRange(L,tvb->ws_tvb,offset,len))) {
PUSH_TVBRANGE(L,tvbr);
WSLUA_RETURN(1); /* the TvbRange */
}
@ -497,6 +548,7 @@ static int Tvb_range(lua_State* L);
static const luaL_reg Tvb_meta[] = {
{"__call", Tvb_range},
{"__tostring", Tvb__tostring},
{"__gc", Tvb__gc},
{ NULL, NULL }
};
@ -514,9 +566,14 @@ static int TvbRange_index(lua_State* L) {
/* WSLUA_ATTRIBUTE TvbRange_offset RW The offset (in octets) of this TvbRange */
TvbRange tvbr = checkTvbRange(L,1);
Tvb tvb;
const gchar* index = luaL_checkstring(L,2);
if (!(tvbr && index)) return 0;
if (!(tvbr && index && tvbr->tvb)) return 0;
if (tvbr->tvb->expired) {
luaL_error(L,"expired tvb");
return 0;
}
if (g_str_equal(index,"offset")) {
lua_pushnumber(L,(lua_Number)tvbr->offset);
@ -525,6 +582,9 @@ static int TvbRange_index(lua_State* L) {
lua_pushnumber(L,(lua_Number)tvbr->len);
return 1;
} else if (g_str_equal(index,"tvb")) {
tvb = g_malloc(sizeof(struct _wslua_tvb));
tvb->ws_tvb = tvb_new_subset(tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len, tvbr->len);
tvb->expired = FALSE;
PUSH_TVB(L,tvbr->tvb);
return 1;
} else {
@ -541,12 +601,16 @@ static int TvbRange_newindex(lua_State* L) {
TvbRange tvbr = checkTvbRange(L,1);
const gchar* index = luaL_checkstring(L,2);
if (!tvbr) return 0;
if (!(tvbr && !tvbr->tvb)) return 0;
if (tvbr->tvb->expired) {
luaL_error(L,"expired tvb");
return 0;
}
if (g_str_equal(index,"offset")) {
int offset = (int)lua_tonumber(L,3);
if ( (guint)(tvbr->len + offset) > tvb_length(tvbr->tvb)) {
if ( (guint)(tvbr->len + offset) > tvb_length(tvbr->tvb->ws_tvb)) {
luaL_error(L,"out of bounds");
return 0;
} else {
@ -557,7 +621,7 @@ static int TvbRange_newindex(lua_State* L) {
} else if (g_str_equal(index,"len")) {
int len = (int)lua_tonumber(L,3);
if ( (guint)(tvbr->offset + len) > tvb_length(tvbr->tvb)) {
if ( (guint)(tvbr->offset + len) > tvb_length(tvbr->tvb->ws_tvb)) {
luaL_error(L,"out of bounds");
return 0;
} else {
@ -580,20 +644,24 @@ WSLUA_METHOD TvbRange_uint(lua_State* L) {
/* get a Big Endian (network order) unsigned integer from a TvbRange. The range must be 1, 2, 3 or 4 octets long.
There's no support yet for 64 bit integers*/
TvbRange tvbr = checkTvbRange(L,1);
if (!tvbr) return 0;
if (!(tvbr && tvbr->tvb)) return 0;
if (tvbr->tvb->expired) {
luaL_error(L,"expired tvb");
return 0;
}
switch (tvbr->len) {
case 1:
lua_pushnumber(L,tvb_get_guint8(tvbr->tvb,tvbr->offset));
lua_pushnumber(L,tvb_get_guint8(tvbr->tvb->ws_tvb,tvbr->offset));
return 1;
case 2:
lua_pushnumber(L,tvb_get_ntohs(tvbr->tvb,tvbr->offset));
lua_pushnumber(L,tvb_get_ntohs(tvbr->tvb->ws_tvb,tvbr->offset));
return 1;
case 3:
lua_pushnumber(L,tvb_get_ntoh24(tvbr->tvb,tvbr->offset));
lua_pushnumber(L,tvb_get_ntoh24(tvbr->tvb->ws_tvb,tvbr->offset));
return 1;
case 4:
lua_pushnumber(L,tvb_get_ntohl(tvbr->tvb,tvbr->offset));
lua_pushnumber(L,tvb_get_ntohl(tvbr->tvb->ws_tvb,tvbr->offset));
WSLUA_RETURN(1); /* the unsigned integer value */
/*
* XXX:
@ -615,21 +683,25 @@ WSLUA_METHOD TvbRange_le_uint(lua_State* L) {
/* get a Little Endian unsigned integer from a TvbRange. The range must be 1, 2, 3 or 4 octets long.
There's no support yet for 64 bit integers*/
TvbRange tvbr = checkTvbRange(L,1);
if (!tvbr) return 0;
if (!(tvbr && tvbr->tvb)) return 0;
if (tvbr->tvb->expired) {
luaL_error(L,"expired tvb");
return 0;
}
switch (tvbr->len) {
case 1:
/* XXX unsigned anyway */
lua_pushnumber(L,(lua_Number)tvb_get_guint8(tvbr->tvb,tvbr->offset));
lua_pushnumber(L,(lua_Number)tvb_get_guint8(tvbr->tvb->ws_tvb,tvbr->offset));
return 1;
case 2:
lua_pushnumber(L,tvb_get_letohs(tvbr->tvb,tvbr->offset));
lua_pushnumber(L,tvb_get_letohs(tvbr->tvb->ws_tvb,tvbr->offset));
return 1;
case 3:
lua_pushnumber(L,tvb_get_letoh24(tvbr->tvb,tvbr->offset));
lua_pushnumber(L,tvb_get_letoh24(tvbr->tvb->ws_tvb,tvbr->offset));
return 1;
case 4:
lua_pushnumber(L,tvb_get_letohl(tvbr->tvb,tvbr->offset));
lua_pushnumber(L,tvb_get_letohl(tvbr->tvb->ws_tvb,tvbr->offset));
WSLUA_RETURN(1); /* the unsigned integer value */
default:
luaL_error(L,"TvbRange:get_le_uint() does not handle %d byte integers",tvbr->len);
@ -643,14 +715,18 @@ WSLUA_METHOD TvbRange_le_uint(lua_State* L) {
WSLUA_METHOD TvbRange_float(lua_State* L) {
/* get a Big Endian (network order) floating point number from a TvbRange. The range must be 4 or 8 octets long. */
TvbRange tvbr = checkTvbRange(L,1);
if (!tvbr) return 0;
if (!(tvbr && tvbr->tvb)) return 0;
if (tvbr->tvb->expired) {
luaL_error(L,"expired tvb");
return 0;
}
switch (tvbr->len) {
case 4:
lua_pushnumber(L,(double)tvb_get_ntohieee_float(tvbr->tvb,tvbr->offset));
lua_pushnumber(L,(double)tvb_get_ntohieee_float(tvbr->tvb->ws_tvb,tvbr->offset));
return 1;
case 8:
lua_pushnumber(L,tvb_get_ntohieee_double(tvbr->tvb,tvbr->offset));
lua_pushnumber(L,tvb_get_ntohieee_double(tvbr->tvb->ws_tvb,tvbr->offset));
WSLUA_RETURN(1); /* the flaoting point value */
default:
luaL_error(L,"TvbRange:get_float() does not handle %d byte floating numbers",tvbr->len);
@ -664,14 +740,14 @@ WSLUA_METHOD TvbRange_float(lua_State* L) {
WSLUA_METHOD TvbRange_le_float(lua_State* L) {
/* get a Little Endian floating point number from a TvbRange. The range must be 4 or 8 octets long. */
TvbRange tvbr = checkTvbRange(L,1);
if (!tvbr) return 0;
if (!(tvbr && tvbr->tvb)) return 0;
switch (tvbr->len) {
case 4:
lua_pushnumber(L,tvb_get_letohieee_float(tvbr->tvb,tvbr->offset));
lua_pushnumber(L,tvb_get_letohieee_float(tvbr->tvb->ws_tvb,tvbr->offset));
return 1;
case 8:
lua_pushnumber(L,tvb_get_letohieee_double(tvbr->tvb,tvbr->offset));
lua_pushnumber(L,tvb_get_letohieee_double(tvbr->tvb->ws_tvb,tvbr->offset));
WSLUA_RETURN(1); /* the flaoting point value */
default:
luaL_error(L,"TvbRange:get_float() does not handle %d byte floating numbers",tvbr->len);
@ -686,7 +762,11 @@ WSLUA_METHOD TvbRange_ipv4(lua_State* L) {
Address addr;
guint32* ip_addr;
if ( !tvbr ) return 0;
if ( !(tvbr && tvbr->tvb)) return 0;
if (tvbr->tvb->expired) {
luaL_error(L,"expired tvb");
return 0;
}
if (tvbr->len != 4)
WSLUA_ERROR(TvbRange_ipv4,"The range must be 4 octets long");
@ -694,7 +774,7 @@ WSLUA_METHOD TvbRange_ipv4(lua_State* L) {
addr = g_malloc(sizeof(address));
ip_addr = g_malloc(sizeof(guint32));
*ip_addr = tvb_get_ipv4(tvbr->tvb,tvbr->offset);
*ip_addr = tvb_get_ipv4(tvbr->tvb->ws_tvb,tvbr->offset);
SET_ADDRESS(addr, AT_IPv4, 4, ip_addr);
pushAddress(L,addr);
@ -709,7 +789,11 @@ WSLUA_METHOD TvbRange_le_ipv4(lua_State* L) {
Address addr;
guint32* ip_addr;
if ( !tvbr ) return 0;
if ( !(tvbr && tvbr->tvb)) return 0;
if (tvbr->tvb->expired) {
luaL_error(L,"expired tvb");
return 0;
}
if (tvbr->len != 4)
WSLUA_ERROR(TvbRange_ipv4,"The range must be 4 octets long");
@ -717,7 +801,7 @@ WSLUA_METHOD TvbRange_le_ipv4(lua_State* L) {
addr = g_malloc(sizeof(address));
ip_addr = g_malloc(sizeof(guint32));
*ip_addr = tvb_get_ipv4(tvbr->tvb,tvbr->offset);
*ip_addr = tvb_get_ipv4(tvbr->tvb->ws_tvb,tvbr->offset);
*((guint32 *)ip_addr) = GUINT32_SWAP_LE_BE(*((guint32 *)ip_addr));
SET_ADDRESS(addr, AT_IPv4, 4, ip_addr);
@ -732,14 +816,18 @@ WSLUA_METHOD TvbRange_ether(lua_State* L) {
Address addr;
guint8* buff;
if ( !tvbr ) return 0;
if ( !(tvbr && tvbr->tvb)) return 0;
if (tvbr->tvb->expired) {
luaL_error(L,"expired tvb");
return 0;
}
addr = g_malloc(sizeof(address));
if (tvbr->len != 6)
WSLUA_ERROR(TvbRange_ether,"The range must be 6 bytes long");
buff = tvb_memdup(tvbr->tvb,tvbr->offset,tvbr->len);
buff = tvb_memdup(tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len);
SET_ADDRESS(addr, AT_ETHER, 6, buff);
pushAddress(L,addr);
@ -752,9 +840,13 @@ WSLUA_METHOD TvbRange_string(lua_State* L) {
/* obtain a string from a TvbRange */
TvbRange tvbr = checkTvbRange(L,1);
if ( !tvbr ) return 0;
if ( !(tvbr && tvbr->tvb)) return 0;
if (tvbr->tvb->expired) {
luaL_error(L,"expired tvb");
return 0;
}
lua_pushstring(L, (gchar*)tvb_get_ephemeral_string(tvbr->tvb,tvbr->offset,tvbr->len) );
lua_pushstring(L, (gchar*)tvb_get_ephemeral_string(tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len) );
WSLUA_RETURN(1); /* the string */
}
@ -764,10 +856,14 @@ WSLUA_METHOD TvbRange_bytes(lua_State* L) {
TvbRange tvbr = checkTvbRange(L,1);
GByteArray* ba;
if ( !tvbr ) return 0;
if ( !(tvbr && tvbr->tvb)) return 0;
if (tvbr->tvb->expired) {
luaL_error(L,"expired tvb");
return 0;
}
ba = g_byte_array_new();
g_byte_array_append(ba,ep_tvb_memdup(tvbr->tvb,tvbr->offset,tvbr->len),tvbr->len);
g_byte_array_append(ba,ep_tvb_memdup(tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len),tvbr->len);
pushByteArray(L,ba);
@ -780,9 +876,13 @@ WSLUA_METAMETHOD TvbRange__tostring(lua_State* L) {
or if what you want is to have a truncated string in the format 67:89:AB:... */
TvbRange tvbr = checkTvbRange(L,1);
if (!tvbr) return 0;
if (!(tvbr && tvbr->tvb)) return 0;
if (tvbr->tvb->expired) {
luaL_error(L,"expired tvb");
return 0;
}
lua_pushstring(L,tvb_bytes_to_str(tvbr->tvb,tvbr->offset,tvbr->len));
lua_pushstring(L,tvb_bytes_to_str(tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len));
return 1;
}
@ -808,7 +908,8 @@ static const luaL_reg TvbRange_meta[] = {
};
int TvbRange_register(lua_State* L) {
outstanding_stuff = g_ptr_array_new();
outstanding_Tvb = g_ptr_array_new();
outstanding_TvbRange = g_ptr_array_new();
WSLUA_REGISTER_CLASS(TvbRange);
return 1;
}