diff options
author | Stig Bjørlykke <stig@bjorlykke.org> | 2011-08-19 08:36:02 +0000 |
---|---|---|
committer | Stig Bjørlykke <stig@bjorlykke.org> | 2011-08-19 08:36:02 +0000 |
commit | 9c7e12c572566a0a8a021f273a511014f8a5bd8c (patch) | |
tree | 8cb79f583fd1a73aaf2de293c010a8c3a22bc0ad /epan/wslua | |
parent | c65403769a0465303b5ae45558609c1a680cf77d (diff) |
Introduce NSTime Lua object to handle nstime_t.
This object can be used to retreive other absolute and relative time fields,
create and modify nstime_t values and put generated time values in the tree.
Also added ProtoField.absolute_time and ProtoField.relative_time.
svn path=/trunk/; revision=38616
Diffstat (limited to 'epan/wslua')
-rw-r--r-- | epan/wslua/wslua.h | 2 | ||||
-rw-r--r-- | epan/wslua/wslua_field.c | 7 | ||||
-rw-r--r-- | epan/wslua/wslua_pinfo.c | 200 | ||||
-rw-r--r-- | epan/wslua/wslua_proto.c | 64 | ||||
-rw-r--r-- | epan/wslua/wslua_tree.c | 4 | ||||
-rw-r--r-- | epan/wslua/wslua_tvb.c | 55 |
6 files changed, 332 insertions, 0 deletions
diff --git a/epan/wslua/wslua.h b/epan/wslua/wslua.h index 7c595770d1..a5d38d6658 100644 --- a/epan/wslua/wslua.h +++ b/epan/wslua/wslua.h @@ -51,6 +51,7 @@ #include <epan/funnel.h> #include <epan/tvbparse.h> #include <epan/epan.h> +#include <epan/nstime.h> #include "declare_wslua.h" @@ -220,6 +221,7 @@ typedef struct _wslua_cols* Columns; typedef struct _wslua_pinfo* Pinfo; typedef struct _wslua_treeitem* TreeItem; typedef address* Address; +typedef nstime_t* NSTime; typedef gint64* Int64; typedef guint64* UInt64; typedef header_field_info** Field; diff --git a/epan/wslua/wslua_field.c b/epan/wslua/wslua_field.c index 9d140b8d25..b9505b753e 100644 --- a/epan/wslua/wslua_field.c +++ b/epan/wslua/wslua_field.c @@ -131,6 +131,13 @@ WSLUA_METAMETHOD FieldInfo__call(lua_State* L) { pushAddress(L,ipx); return 1; } + case FT_ABSOLUTE_TIME: + case FT_RELATIVE_TIME: { + NSTime nstime = g_malloc(sizeof(nstime_t)); + *nstime = *(NSTime)fvalue_get(&(fi->value)); + pushNSTime(L,nstime); + return 1; + } case FT_STRING: case FT_STRINGZ: { gchar* repr = fvalue_to_string_repr(&fi->value,FTREPR_DISPLAY,NULL); diff --git a/epan/wslua/wslua_pinfo.c b/epan/wslua/wslua_pinfo.c index 9a0969dcfc..d345156756 100644 --- a/epan/wslua/wslua_pinfo.c +++ b/epan/wslua/wslua_pinfo.c @@ -67,6 +67,206 @@ Pinfo* push_Pinfo(lua_State* L, packet_info* ws_pinfo) { #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(NSTime,NOP,NOP); + /* NSTime represents a nstime_t. This is an object with seconds and nano seconds. */ + +WSLUA_CONSTRUCTOR NSTime_new(lua_State *L) { + /* Creates a new NSTime object */ +#define WSLUA_OPTARG_NSTime_new_SECONDS 1 /* Seconds */ +#define WSLUA_OPTARG_NSTime_new_NSECONDS 2 /* Nano seconds */ + NSTime time = g_malloc(sizeof(nstime_t)); + + if (!time) return 0; + + time->secs = (time_t) luaL_optint(L,WSLUA_OPTARG_NSTime_new_SECONDS,0); + time->nsecs = luaL_optint(L,WSLUA_OPTARG_NSTime_new_NSECONDS,0); + + pushNSTime(L,time); + + WSLUA_RETURN(1); /* The new NSTime object. */ +} + +WSLUA_METAMETHOD NSTime__tostring(lua_State* L) { + NSTime nstime = checkNSTime(L,1); + + if (!nstime) return 0; + + lua_pushstring(L,ep_strdup_printf("%ld.%09d", nstime->secs, nstime->nsecs)); + + WSLUA_RETURN(1); /* The string representing the nstime. */ +} +WSLUA_METAMETHOD NSTime__eq(lua_State* L) { /* Compares two NSTimes */ + NSTime time1 = checkNSTime(L,1); + NSTime time2 = checkNSTime(L,2); + gboolean result = FALSE; + + if (!time1 || !time2) + WSLUA_ERROR(FieldInfo__eq,"Data source must be the same for both fields"); + + if (nstime_cmp(time1, time2) == 0) + result = TRUE; + + lua_pushboolean(L,result); + + return 1; +} + +WSLUA_METAMETHOD NSTime__le(lua_State* L) { /* Compares two NSTimes */ + NSTime time1 = checkNSTime(L,1); + NSTime time2 = checkNSTime(L,2); + gboolean result = FALSE; + + if (!time1 || !time2) + WSLUA_ERROR(FieldInfo__eq,"Data source must be the same for both fields"); + + if (nstime_cmp(time1, time2) <= 0) + result = TRUE; + + lua_pushboolean(L,result); + + return 1; +} + +WSLUA_METAMETHOD NSTime__lt(lua_State* L) { /* Compares two NSTimes */ + NSTime time1 = checkNSTime(L,1); + NSTime time2 = checkNSTime(L,2); + gboolean result = FALSE; + + if (!time1 || !time2) + WSLUA_ERROR(FieldInfo__eq,"Data source must be the same for both fields"); + + if (nstime_cmp(time1, time2) < 0) + result = TRUE; + + lua_pushboolean(L,result); + + return 1; +} + +typedef struct { + gchar* name; + lua_CFunction get; + lua_CFunction set; +} nstime_actions_t; + +static int NSTime_get_secs(lua_State* L) { + NSTime time = toNSTime(L,1); + + lua_pushnumber (L,(lua_Number)(time->secs)); + + return 1; +} + +static int NSTime_set_secs(lua_State* L) + { + NSTime time = toNSTime(L,1); + time_t secs = luaL_checkint(L,3); + + time->secs = secs; + + return 0; +} + +static int NSTime_get_nsecs(lua_State* L) { + NSTime time = toNSTime(L,1); + + lua_pushnumber (L,(lua_Number)(time->nsecs)); + + return 1; +} + +static int NSTime_set_nsecs(lua_State* L) { + NSTime time = toNSTime(L,1); + int nsecs = luaL_checkint(L,3); + + time->nsecs = nsecs; + + return 0; +} + +static const nstime_actions_t nstime_actions[] = { + /* WSLUA_ATTRIBUTE NSTime_secs RW The NSTime seconds */ + {"secs", NSTime_get_secs, NSTime_set_secs}, + + /* WSLUA_ATTRIBUTE NSTime_nsecs RW The NSTime nano seconds */ + {"nsecs", NSTime_get_nsecs, NSTime_set_nsecs}, + + {NULL,NULL,NULL} +}; + +static int NSTime__index(lua_State* L) { + NSTime time = checkNSTime(L,1); + const gchar* name = luaL_checkstring(L,2); + const nstime_actions_t* pa; + + if (! (time && name) ) return 0; + + for (pa = nstime_actions; pa->name; pa++) { + if ( g_str_equal(name,pa->name) ) { + if (pa->get) { + return pa->get(L); + } else { + luaL_error(L,"You cannot get the `%s' attribute of a nstime",name); + return 0; + } + } + } + + luaL_error(L,"A protocol doesn't have a `%s' nstime",name); + return 0; +} + +static int NSTime__newindex(lua_State* L) { + NSTime time = checkNSTime(L,1); + const gchar* name = luaL_checkstring(L,2); + const nstime_actions_t* pa; + + if (! (time && name) ) return 0; + + for (pa = nstime_actions; pa->name; pa++) { + if ( g_str_equal(name,pa->name) ) { + if (pa->set) { + return pa->set(L); + } else { + luaL_error(L,"You cannot set the `%s' attribute of a nstime",name); + return 0; + } + } + } + + luaL_error(L,"A protocol doesn't have a `%s' nstime",name); + return 0; +} + +static int NSTime__gc(lua_State* L) { + NSTime nstime = checkNSTime(L,1); + + if (!nstime) return 0; + + g_free (nstime); + return 0; +} + +WSLUA_META NSTime_meta[] = { + {"__index", NSTime__index}, + {"__newindex", NSTime__newindex}, + {"__tostring", NSTime__tostring}, + {"__eq", NSTime__eq}, + {"__le", NSTime__le}, + {"__lt", NSTime__lt}, + {"__gc", NSTime__gc}, + { NULL, NULL} +}; + +int NSTime_register(lua_State* L) { + WSLUA_REGISTER_META(NSTime); + + lua_pushstring(L, "NSTime"); + lua_pushcfunction(L, NSTime_new); + lua_settable(L, LUA_GLOBALSINDEX); + return 1; +} + WSLUA_CLASS_DEFINE(Address,NOP,NOP); /* Represents an address */ WSLUA_CONSTRUCTOR Address_ip(lua_State* L) { diff --git a/epan/wslua/wslua_proto.c b/epan/wslua/wslua_proto.c index 298ac613f6..2794b03d00 100644 --- a/epan/wslua/wslua_proto.c +++ b/epan/wslua/wslua_proto.c @@ -421,6 +421,8 @@ static const wslua_ft_types_t ftenums[] = { {"FT_INT64",FT_INT64}, {"FT_FLOAT",FT_FLOAT}, {"FT_DOUBLE",FT_DOUBLE}, + {"FT_ABSOLUTE_TIME",FT_ABSOLUTE_TIME}, + {"FT_RELATIVE_TIME",FT_RELATIVE_TIME}, {"FT_STRING",FT_STRING}, {"FT_STRINGZ",FT_STRINGZ}, {"FT_ETHER",FT_ETHER}, @@ -472,6 +474,10 @@ static const struct base_display_string_t base_displays[] = { {"16",16}, {"24",24}, {"32",32}, + /* for FT_ABSOLUTE_TIME use values in absolute_time_display_e */ + {"LOCAL", ABSOLUTE_TIME_LOCAL}, + {"UTC", ABSOLUTE_TIME_UTC}, + {"DOY_UTC", ABSOLUTE_TIME_DOY_UTC}, {NULL,0} }; @@ -863,6 +869,61 @@ static int ProtoField_boolean(lua_State* L, enum ftenum type) { /* XXX: T/F strings */ PROTOFIELD_BOOL(bool,FT_BOOLEAN) +static int ProtoField_time(lua_State* L,enum ftenum type) { + ProtoField f = g_malloc(sizeof(wslua_field_t)); + const gchar* abbr = luaL_checkstring(L,1); + const gchar* name = luaL_optstring(L,2,abbr); + absolute_time_display_e base = luaL_optint(L,3,ABSOLUTE_TIME_LOCAL); + const gchar* blob = luaL_optstring(L,4,NULL); + + if (proto_check_field_name(abbr)) { + luaL_argerror(L,1,"Invalid char in abbrev"); + return 0; + } + + if (type == FT_ABSOLUTE_TIME) { + if (base < ABSOLUTE_TIME_LOCAL || base > ABSOLUTE_TIME_DOY_UTC) { + luaL_argerror(L, 3, "Base must be either LOCAL, UTC or DOY_UTC"); + return 0; + } + } + + f->hfid = -2; + f->ett = -1; + f->name = g_strdup(name); + f->abbr = g_strdup(abbr); + f->type = type; + f->vs = NULL; + f->base = base; + f->mask = 0; + if (blob && strcmp(blob, f->name) != 0) { + f->blob = g_strdup(blob); + } else { + f->blob = NULL; + } + + pushProtoField(L,f); + + return 1; +} + +#define PROTOFIELD_TIME(lower,FT) static int ProtoField_##lower(lua_State* L) { return ProtoField_time(L,FT); } +/* _WSLUA_CONSTRUCTOR_ ProtoField_absolute_time */ +/* WSLUA_ARG_Protofield_absolute_time_ABBR Abbreviated name of the field (the string used in filters) */ +/* WSLUA_OPTARG_Protofield_absolute_time_NAME Actual name of the field (the string that appears in the tree) */ +/* WSLUA_OPTARG_Protofield_absolute_time_BASE One of base.LOCAL, base.UTC or base.DOY_UTC */ +/* WSLUA_OPTARG_Protofield_absolute_time_DESC Description of the field */ +/* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */ + +/* _WSLUA_CONSTRUCTOR_ ProtoField_relative_time */ +/* WSLUA_ARG_Protofield_relative_ABBR Abbreviated name of the field (the string used in filters) */ +/* WSLUA_OPTARG_Protofield_relative_NAME Actual name of the field (the string that appears in the tree) */ +/* WSLUA_OPTARG_Protofield_relative_DESC Description of the field */ +/* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */ + + +PROTOFIELD_TIME(absolute_time,FT_ABSOLUTE_TIME) + static int ProtoField_other(lua_State* L,enum ftenum type) { ProtoField f = g_malloc(sizeof(wslua_field_t)); const gchar* abbr = luaL_checkstring(L,1); @@ -972,6 +1033,7 @@ PROTOFIELD_OTHER(ipx,FT_IPXNET) PROTOFIELD_OTHER(ether,FT_ETHER) PROTOFIELD_OTHER(float,FT_FLOAT) PROTOFIELD_OTHER(double,FT_DOUBLE) +PROTOFIELD_OTHER(relative_time,FT_RELATIVE_TIME) PROTOFIELD_OTHER(string,FT_STRING) PROTOFIELD_OTHER(stringz,FT_STRINGZ) PROTOFIELD_OTHER(bytes,FT_BYTES) @@ -1031,6 +1093,8 @@ static const luaL_reg ProtoField_methods[] = { {"bool",ProtoField_bool}, {"float",ProtoField_float}, {"double",ProtoField_double}, + {"absolute_time",ProtoField_absolute_time}, + {"relative_time",ProtoField_relative_time}, {"string",ProtoField_string}, {"stringz",ProtoField_stringz}, {"bytes",ProtoField_bytes}, diff --git a/epan/wslua/wslua_tree.c b/epan/wslua/wslua_tree.c index 1c90c7964d..26b2b42ce6 100644 --- a/epan/wslua/wslua_tree.c +++ b/epan/wslua/wslua_tree.c @@ -123,6 +123,10 @@ static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) { case FT_DOUBLE: 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_ABSOLUTE_TIME: + case FT_RELATIVE_TIME: + item = proto_tree_add_time(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,checkNSTime(L,1)); + break; case FT_STRING: item = proto_tree_add_string(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,luaL_checkstring(L,1)); break; diff --git a/epan/wslua/wslua_tvb.c b/epan/wslua/wslua_tvb.c index 041a8c3650..49be5ebbec 100644 --- a/epan/wslua/wslua_tvb.c +++ b/epan/wslua/wslua_tvb.c @@ -996,6 +996,59 @@ WSLUA_METHOD TvbRange_ether(lua_State* L) { WSLUA_RETURN(1); /* The Ethernet Address */ } +WSLUA_METHOD TvbRange_nstime(lua_State* L) { + /* Obtain a nstime from a TvbRange */ + TvbRange tvbr = checkTvbRange(L,1); + NSTime nstime = g_malloc (sizeof(nstime_t)); + + if ( !(tvbr && tvbr->tvb)) return 0; + if (tvbr->tvb->expired) { + luaL_error(L,"expired tvb"); + return 0; + } + + if (tvbr->len == 4) { + nstime->secs = tvb_get_ntohl(tvbr->tvb->ws_tvb, tvbr->offset); + nstime->nsecs = 0; + } else if (tvbr->len == 8) { + nstime->secs = tvb_get_ntohl(tvbr->tvb->ws_tvb, tvbr->offset); + nstime->nsecs = tvb_get_ntohl(tvbr->tvb->ws_tvb, tvbr->offset + 4); + } else { + WSLUA_ERROR(TvbRange_nstime,"The range must be 4 or 8 bytes long"); + return 0; + } + + pushNSTime(L, nstime); + + WSLUA_RETURN(1); /* The NSTime */ +} + +WSLUA_METHOD TvbRange_le_nstime(lua_State* L) { + /* Obtain a nstime from a TvbRange */ + TvbRange tvbr = checkTvbRange(L,1); + NSTime nstime = g_malloc (sizeof(nstime_t)); + + if ( !(tvbr && tvbr->tvb)) return 0; + if (tvbr->tvb->expired) { + luaL_error(L,"expired tvb"); + return 0; + } + + if (tvbr->len == 4) { + nstime->secs = tvb_get_letohl(tvbr->tvb->ws_tvb, tvbr->offset); + nstime->nsecs = 0; + } else if (tvbr->len == 8) { + nstime->secs = tvb_get_letohl(tvbr->tvb->ws_tvb, tvbr->offset); + nstime->nsecs = tvb_get_letohl(tvbr->tvb->ws_tvb, tvbr->offset + 4); + } else { + WSLUA_ERROR(TvbRange_nstime,"The range must be 4 or 8 bytes long"); + return 0; + } + + pushNSTime(L, nstime); + + WSLUA_RETURN(1); /* The NSTime */ +} WSLUA_METHOD TvbRange_string(lua_State* L) { /* Obtain a string from a TvbRange */ @@ -1171,6 +1224,8 @@ static const luaL_reg TvbRange_methods[] = { {"ether", TvbRange_ether}, {"ipv4", TvbRange_ipv4}, {"le_ipv4", TvbRange_le_ipv4}, + {"nstime", TvbRange_nstime}, + {"le_nstime", TvbRange_le_nstime}, {"string", TvbRange_string}, {"stringz", TvbRange_stringz}, {"bytes", TvbRange_bytes}, |