diff options
-rwxr-xr-x | epan/wslua/make-reg.pl | 4 | ||||
-rw-r--r-- | epan/wslua/wslua.h | 2 | ||||
-rw-r--r-- | epan/wslua/wslua_field.c | 17 | ||||
-rw-r--r-- | epan/wslua/wslua_tree.c | 4 | ||||
-rw-r--r-- | epan/wslua/wslua_tvb.c | 129 |
5 files changed, 142 insertions, 14 deletions
diff --git a/epan/wslua/make-reg.pl b/epan/wslua/make-reg.pl index 3dc2453154..ba555900c2 100755 --- a/epan/wslua/make-reg.pl +++ b/epan/wslua/make-reg.pl @@ -31,8 +31,8 @@ my @classes = (); my @functions = (); while (<>) { - push @classes, $1 if /WSLUA_CLASS_DEFINE\050\s*([A-Za-z]+)/; - push @functions, $1 if /WSLUA_FUNCTION\s+wslua_([a-z_]+)/; + push @classes, $1 if /WSLUA_CLASS_DEFINE\050\s*([A-Za-z0-9]+)/; + push @functions, $1 if /WSLUA_FUNCTION\s+wslua_([a-z_0-9]+)/; } open C, ">register_wslua.c"; diff --git a/epan/wslua/wslua.h b/epan/wslua/wslua.h index a5fcd87398..726b98ac37 100644 --- a/epan/wslua/wslua.h +++ b/epan/wslua/wslua.h @@ -214,6 +214,8 @@ typedef struct _wslua_cols* Columns; typedef struct _wslua_pinfo* Pinfo; typedef struct _wslua_treeitem* TreeItem; typedef address* Address; +typedef gint64* Int64; +typedef guint64* UInt64; typedef header_field_info** Field; typedef field_info* FieldInfo; typedef struct _wslua_tap* Listener; diff --git a/epan/wslua/wslua_field.c b/epan/wslua/wslua_field.c index ebc041ea1f..3b8a46d8ca 100644 --- a/epan/wslua/wslua_field.c +++ b/epan/wslua/wslua_field.c @@ -80,13 +80,18 @@ WSLUA_METAMETHOD FieldInfo__call(lua_State* L) { case FT_DOUBLE: lua_pushnumber(L,(lua_Number)fvalue_get_floating(&(fi->value))); return 1; - case FT_INT64: - case FT_UINT64: - /* - * XXX: double has 53 bits integer precision, n > 2^22 will cause a loss in precision - */ - lua_pushnumber(L,(lua_Number)(gint64)fvalue_get_integer64(&(fi->value))); + case FT_INT64: { + Int64 num = g_malloc(sizeof(Int64)); + *num = fvalue_get_integer64(&(fi->value)); + pushInt64(L,num); return 1; + } + case FT_UINT64: { + UInt64 num = g_malloc(sizeof(UInt64)); + *num = fvalue_get_integer64(&(fi->value)); + pushUInt64(L,num); + return 1; + } case FT_ETHER: { Address eth = g_malloc(sizeof(address)); eth->type = AT_ETHER; diff --git a/epan/wslua/wslua_tree.c b/epan/wslua/wslua_tree.c index d67b4f722a..362327fb90 100644 --- a/epan/wslua/wslua_tree.c +++ b/epan/wslua/wslua_tree.c @@ -124,10 +124,10 @@ static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) { 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->ws_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,*(UInt64)checkUInt64(L,1)); break; case FT_INT64: - item = proto_tree_add_int64(tree_item->tree,hfid,tvbr->tvb->ws_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,*(Int64)checkInt64(L,1)); break; case FT_IPv4: item = proto_tree_add_ipv4(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,*((guint32*)(checkAddress(L,1)->data))); diff --git a/epan/wslua/wslua_tvb.c b/epan/wslua/wslua_tvb.c index 5835bd9a67..37f9b2d9e7 100644 --- a/epan/wslua/wslua_tvb.c +++ b/epan/wslua/wslua_tvb.c @@ -652,8 +652,7 @@ static int TvbRange_newindex(lua_State* L) { * get a Blefuscuoan unsigned integer from a tvb */ 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*/ + /* get a Big Endian (network order) unsigned integer from a TvbRange. The range must be 1, 2, 3 or 4 octets long. */ TvbRange tvbr = checkTvbRange(L,1); if (!(tvbr && tvbr->tvb)) return 0; if (tvbr->tvb->expired) { @@ -691,8 +690,7 @@ WSLUA_METHOD TvbRange_uint(lua_State* L) { * get a Lilliputian unsigned integer from a tvb */ 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*/ + /* get a Little Endian unsigned integer from a TvbRange. The range must be 1, 2, 3 or 4 octets long. */ TvbRange tvbr = checkTvbRange(L,1); if (!(tvbr && tvbr->tvb)) return 0; if (tvbr->tvb->expired) { @@ -721,6 +719,70 @@ WSLUA_METHOD TvbRange_le_uint(lua_State* L) { } /* + * get a Blefuscuoan unsigned 64 bit integer from a tvb + */ +WSLUA_METHOD TvbRange_uint64(lua_State* L) { + /* get a Big Endian (network order) unsigned 64 bit integer from a TvbRange. The range must be 1-8 octets long. */ + TvbRange tvbr = checkTvbRange(L,1); + if (!(tvbr && tvbr->tvb)) return 0; + if (tvbr->tvb->expired) { + luaL_error(L,"expired tvb"); + return 0; + } + + switch (tvbr->len) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: { + UInt64 num = g_malloc(sizeof(guint64)); + *num = tvb_get_ntoh64(tvbr->tvb->ws_tvb,tvbr->offset); + pushUInt64(L,num); + WSLUA_RETURN(1); + } + default: + luaL_error(L,"TvbRange:get_uint64() does not handle %d byte integers",tvbr->len); + return 0; + } +} + +/* + * get a Lilliputian unsigned 64 bit integer from a tvb + */ +WSLUA_METHOD TvbRange_le_uint64(lua_State* L) { + /* get a Little Endian unsigned 64 bit integer from a TvbRange. The range must be 1-8 octets long. */ + TvbRange tvbr = checkTvbRange(L,1); + if (!(tvbr && tvbr->tvb)) return 0; + if (tvbr->tvb->expired) { + luaL_error(L,"expired tvb"); + return 0; + } + + switch (tvbr->len) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: { + UInt64 num = g_malloc(sizeof(guint64)); + *num = tvb_get_ntoh64(tvbr->tvb->ws_tvb,tvbr->offset); + pushUInt64(L,num); + WSLUA_RETURN(1); + } + default: + luaL_error(L,"TvbRange:get_le_uint64() does not handle %d byte integers",tvbr->len); + return 0; + } +} + +/* * get a Blefuscuoan float */ WSLUA_METHOD TvbRange_float(lua_State* L) { @@ -900,6 +962,8 @@ WSLUA_METAMETHOD TvbRange__tostring(lua_State* L) { static const luaL_reg TvbRange_methods[] = { {"uint", TvbRange_uint}, {"le_uint", TvbRange_le_uint}, + {"uint64", TvbRange_uint64}, + {"le_uint64", TvbRange_le_uint64}, {"float", TvbRange_float}, {"le_float", TvbRange_le_float}, {"ether", TvbRange_ether}, @@ -924,3 +988,60 @@ int TvbRange_register(lua_State* L) { WSLUA_REGISTER_CLASS(TvbRange); return 1; } + +WSLUA_CLASS_DEFINE(Int64,NOP,NOP); +/* + * Int64 represents a 64 bit integer. + * Lua uses one single number representation which can be chosen at compile time and since + * it is often set to IEEE 754 double precision floating point, we cannot store a 64 bit integer + * with full precision. + * For details, see: http://lua-users.org/wiki/FloatingPoint + */ + +WSLUA_METAMETHOD Int64__tostring(lua_State* L) { + /* converts the Int64 into a string */ + Int64 num = checkInt64(L,1); + lua_pushstring(L,g_strdup_printf("%ld",(long int)*(num))); + return 1; +} + +static const luaL_reg Int64_methods[] = { + { NULL, NULL } +}; + +static const luaL_reg Int64_meta[] = { + {"__tostring", Int64__tostring}, + { NULL, NULL } +}; + +int Int64_register(lua_State* L) { + WSLUA_REGISTER_CLASS(Int64); + return 1; +} + +WSLUA_CLASS_DEFINE(UInt64,NOP,NOP); +/* + * Int64 represents a 64 bit integer. + */ + +WSLUA_METAMETHOD UInt64__tostring(lua_State* L) { + /* converts the UInt64 into a string */ + UInt64 num = checkUInt64(L,1); + lua_pushstring(L,g_strdup_printf("%ld",(unsigned long int)*(num))); + return 1; +} + +static const luaL_reg UInt64_methods[] = { + { NULL, NULL } +}; + +static const luaL_reg UInt64_meta[] = { + {"__tostring", UInt64__tostring}, + { NULL, NULL } +}; + +int UInt64_register(lua_State* L) { + WSLUA_REGISTER_CLASS(UInt64); + return 1; +} + |