aboutsummaryrefslogtreecommitdiffstats
path: root/epan/wslua
diff options
context:
space:
mode:
authorStig Bjørlykke <stig@bjorlykke.org>2011-08-19 08:36:02 +0000
committerStig Bjørlykke <stig@bjorlykke.org>2011-08-19 08:36:02 +0000
commit9c7e12c572566a0a8a021f273a511014f8a5bd8c (patch)
tree8cb79f583fd1a73aaf2de293c010a8c3a22bc0ad /epan/wslua
parentc65403769a0465303b5ae45558609c1a680cf77d (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.h2
-rw-r--r--epan/wslua/wslua_field.c7
-rw-r--r--epan/wslua/wslua_pinfo.c200
-rw-r--r--epan/wslua/wslua_proto.c64
-rw-r--r--epan/wslua/wslua_tree.c4
-rw-r--r--epan/wslua/wslua_tvb.c55
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},