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
This commit is contained in:
Stig Bjørlykke 2011-08-19 08:36:02 +00:00
parent c65403769a
commit 9c7e12c572
6 changed files with 332 additions and 0 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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) {

View File

@ -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},

View File

@ -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;

View File

@ -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},