WSLUA_METHOD TvbRange_nstime(lua_State* L) { /* Obtain a time_t structure from a `TvbRange`, as an `NSTime` object. */ #define WSLUA_OPTARG_TvbRange_nstime_ENCODING 2 /* An optional ENC_* encoding value to use */ TvbRange tvbr = checkTvbRange(L,1); NSTime nstime; const guint encoding = (guint) luaL_optinteger(L, WSLUA_OPTARG_TvbRange_nstime_ENCODING, 0); if ( !(tvbr && tvbr->tvb)) return 0; if (tvbr->tvb->expired) { luaL_error(L,"expired tvb"); return 0; } nstime = g_new(nstime_t,1); if (encoding == 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 { g_free(nstime); WSLUA_ERROR(TvbRange_nstime,"The range must be 4 or 8 bytes long"); return 0; } pushNSTime(L, nstime); lua_pushinteger(L, tvbr->len); } else if (encoding & ~ENC_STR_TIME_MASK) { WSLUA_OPTARG_ERROR(TvbRange_nstime, ENCODING, "invalid encoding value"); } else { gint endoff = 0; nstime_t *retval = tvb_get_string_time(tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, encoding, nstime, &endoff); if (!retval || endoff == 0) { g_free(nstime); /* push nil nstime and offset */ lua_pushnil(L); lua_pushnil(L); } else { pushNSTime(L, nstime); lua_pushinteger(L, endoff); } } WSLUA_RETURN(2); /* The `NSTime` object and number of bytes used, or nil on failure. */ }
WSLUA_METHOD TvbRange_le_nstime(lua_State* L) { /* Obtain a nstime from a TvbRange */ TvbRange tvbr = checkTvbRange(L,1); NSTime nstime; if ( !(tvbr && tvbr->tvb)) return 0; if (tvbr->tvb->expired) { luaL_error(L,"expired tvb"); return 0; } nstime = g_new(nstime_t,1); 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 { g_free(nstime); WSLUA_ERROR(TvbRange_nstime,"The range must be 4 or 8 bytes long"); return 0; } pushNSTime(L, nstime); WSLUA_RETURN(1); /* The NSTime */ }
/* the following is used by TreeItem_add_packet_field() - this can THROW errors */ static proto_item * try_add_packet_field(lua_State *L, TreeItem tree_item, TvbRange tvbr, const int hfid, const ftenum_t type, const guint encoding, gint *ret_err) { gint err = 0; proto_item* item = NULL; gint endoff = 0; switch(type) { /* these all generate ByteArrays */ case FT_BYTES: case FT_UINT_BYTES: case FT_OID: case FT_REL_OID: case FT_SYSTEM_ID: { /* GByteArray and its data will be g_free'd by Lua */ GByteArray *gba = g_byte_array_new(); item = proto_tree_add_bytes_item(tree_item->tree, hfid, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, encoding, gba, &endoff, &err); if (err == 0) { pushByteArray(L, gba); lua_pushinteger(L, endoff); } } break; case FT_ABSOLUTE_TIME: case FT_RELATIVE_TIME: { /* nstime_t will be g_free'd by Lua */ nstime_t *nstime = (nstime_t *) g_malloc0(sizeof(nstime_t)); item = proto_tree_add_time_item(tree_item->tree, hfid, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, encoding, nstime, &endoff, &err); if (err == 0) { pushNSTime(L,nstime); lua_pushinteger(L, endoff); } } break; /* XXX: what about these? */ case FT_NONE: case FT_PROTOCOL: /* anything else just needs to be done the old fashioned way */ default: item = proto_tree_add_item(tree_item->tree, hfid, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, encoding); lua_pushnil(L); lua_pushnil(L); break; } if (ret_err) *ret_err = err; return item; }
WSLUA_METAMETHOD NSTime__unm(lua_State* L) { /* Calculates the negative NSTime */ NSTime time1 = checkNSTime(L,1); NSTime time2 = g_malloc (sizeof (nstime_t)); nstime_set_zero (time2); nstime_subtract (time2, time1); pushNSTime (L, time2); return 1; }
WSLUA_METAMETHOD NSTime__sub(lua_State* L) { /* Calculates the diff of two NSTimes */ NSTime time1 = checkNSTime(L,1); NSTime time2 = checkNSTime(L,2); NSTime time3 = g_malloc (sizeof (nstime_t)); nstime_delta (time3, time1, time2); pushNSTime (L, time3); return 1; }
WSLUA_METAMETHOD NSTime__add(lua_State* L) { /* Calculates the sum of two NSTimes. */ NSTime time1 = checkNSTime(L,1); NSTime time2 = checkNSTime(L,2); NSTime time3 = (NSTime)g_malloc (sizeof (nstime_t)); nstime_sum (time3, time1, time2); pushNSTime (L, time3); return 1; }
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 FieldInfo__call(lua_State* L) { /* Obtain the Value of the field */ FieldInfo fi = checkFieldInfo(L,1); switch(fi->hfinfo->type) { case FT_BOOLEAN: lua_pushboolean(L,(int)fvalue_get_uinteger(&(fi->value))); return 1; case FT_UINT8: case FT_UINT16: case FT_UINT24: case FT_UINT32: case FT_FRAMENUM: lua_pushnumber(L,(lua_Number)fvalue_get_uinteger(&(fi->value))); return 1; case FT_INT8: case FT_INT16: case FT_INT24: case FT_INT32: lua_pushnumber(L,(lua_Number)fvalue_get_sinteger(&(fi->value))); return 1; case FT_FLOAT: case FT_DOUBLE: lua_pushnumber(L,(lua_Number)fvalue_get_floating(&(fi->value))); return 1; case FT_INT64: { Int64 num = (Int64)g_malloc(sizeof(gint64)); *num = fvalue_get_integer64(&(fi->value)); pushInt64(L,num); return 1; } case FT_UINT64: { UInt64 num = (UInt64)g_malloc(sizeof(guint64)); *num = fvalue_get_integer64(&(fi->value)); pushUInt64(L,num); return 1; } case FT_ETHER: { Address eth = (Address)g_malloc(sizeof(address)); eth->type = AT_ETHER; eth->len = fi->length; eth->data = tvb_memdup(NULL,fi->ds_tvb,fi->start,fi->length); pushAddress(L,eth); return 1; } case FT_IPv4:{ Address ipv4 = (Address)g_malloc(sizeof(address)); ipv4->type = AT_IPv4; ipv4->len = fi->length; ipv4->data = tvb_memdup(NULL,fi->ds_tvb,fi->start,fi->length); pushAddress(L,ipv4); return 1; } case FT_IPv6: { Address ipv6 = (Address)g_malloc(sizeof(address)); ipv6->type = AT_IPv6; ipv6->len = fi->length; ipv6->data = tvb_memdup(NULL,fi->ds_tvb,fi->start,fi->length); pushAddress(L,ipv6); return 1; } case FT_IPXNET:{ Address ipx = (Address)g_malloc(sizeof(address)); ipx->type = AT_IPX; ipx->len = fi->length; ipx->data = tvb_memdup(NULL,fi->ds_tvb,fi->start,fi->length); pushAddress(L,ipx); return 1; } case FT_ABSOLUTE_TIME: case FT_RELATIVE_TIME: { NSTime 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); if (repr) lua_pushstring(L,repr); else luaL_error(L,"field cannot be represented as string because it may contain invalid characters"); return 1; } case FT_NONE: if (fi->length == 0) { lua_pushnil(L); return 1; } /* FALLTHROUGH */ case FT_BYTES: case FT_UINT_BYTES: case FT_GUID: case FT_PROTOCOL: case FT_REL_OID: case FT_SYSTEM_ID: case FT_OID: { ByteArray ba = g_byte_array_new(); g_byte_array_append(ba, (const guint8 *)tvb_memdup(wmem_packet_scope(),fi->ds_tvb,fi->start,fi->length),fi->length); pushByteArray(L,ba); return 1; } default: luaL_error(L,"FT_ not yet supported"); return 1; } }
/* WSLUA_ATTRIBUTE FieldInfo_value RO The value of this field. */ WSLUA_METAMETHOD FieldInfo__call(lua_State* L) { /* Obtain the Value of the field. Previous to 1.11.4, this function retrieved the value for most field types, but for `ftypes.UINT_BYTES` it retrieved the `ByteArray` of the field's entire `TvbRange`. In other words, it returned a `ByteArray` that included the leading length byte(s), instead of just the *value* bytes. That was a bug, and has been changed in 1.11.4. Furthermore, it retrieved an `ftypes.GUID` as a `ByteArray`, which is also incorrect. If you wish to still get a `ByteArray` of the `TvbRange`, use `FieldInfo:get_range()` to get the `TvbRange`, and then use `Tvb:bytes()` to convert it to a `ByteArray`. */ FieldInfo fi = checkFieldInfo(L,1); switch(fi->ws_fi->hfinfo->type) { case FT_BOOLEAN: lua_pushboolean(L,(int)fvalue_get_uinteger(&(fi->ws_fi->value))); return 1; case FT_UINT8: case FT_UINT16: case FT_UINT24: case FT_UINT32: case FT_FRAMENUM: lua_pushnumber(L,(lua_Number)(fvalue_get_uinteger(&(fi->ws_fi->value)))); return 1; case FT_INT8: case FT_INT16: case FT_INT24: case FT_INT32: lua_pushnumber(L,(lua_Number)(fvalue_get_sinteger(&(fi->ws_fi->value)))); return 1; case FT_FLOAT: case FT_DOUBLE: lua_pushnumber(L,(lua_Number)(fvalue_get_floating(&(fi->ws_fi->value)))); return 1; case FT_INT64: { pushInt64(L,(Int64)(fvalue_get_sinteger64(&(fi->ws_fi->value)))); return 1; } case FT_UINT64: { pushUInt64(L,fvalue_get_uinteger64(&(fi->ws_fi->value))); return 1; } case FT_ETHER: { Address eth = (Address)g_malloc(sizeof(address)); eth->type = AT_ETHER; eth->len = fi->ws_fi->length; eth->data = tvb_memdup(NULL,fi->ws_fi->ds_tvb,fi->ws_fi->start,fi->ws_fi->length); pushAddress(L,eth); return 1; } case FT_IPv4:{ Address ipv4 = (Address)g_malloc(sizeof(address)); ipv4->type = AT_IPv4; ipv4->len = fi->ws_fi->length; ipv4->data = tvb_memdup(NULL,fi->ws_fi->ds_tvb,fi->ws_fi->start,fi->ws_fi->length); pushAddress(L,ipv4); return 1; } case FT_IPv6: { Address ipv6 = (Address)g_malloc(sizeof(address)); ipv6->type = AT_IPv6; ipv6->len = fi->ws_fi->length; ipv6->data = tvb_memdup(NULL,fi->ws_fi->ds_tvb,fi->ws_fi->start,fi->ws_fi->length); pushAddress(L,ipv6); return 1; } case FT_FCWWN: { Address fcwwn = (Address)g_malloc(sizeof(address)); fcwwn->type = AT_FCWWN; fcwwn->len = fi->ws_fi->length; fcwwn->data = tvb_memdup(NULL,fi->ws_fi->ds_tvb,fi->ws_fi->start,fi->ws_fi->length); pushAddress(L,fcwwn); return 1; } case FT_IPXNET:{ Address ipx = (Address)g_malloc(sizeof(address)); ipx->type = AT_IPX; ipx->len = fi->ws_fi->length; ipx->data = tvb_memdup(NULL,fi->ws_fi->ds_tvb,fi->ws_fi->start,fi->ws_fi->length); pushAddress(L,ipx); return 1; } case FT_ABSOLUTE_TIME: case FT_RELATIVE_TIME: { NSTime nstime = (NSTime)g_malloc(sizeof(nstime_t)); *nstime = *(NSTime)fvalue_get(&(fi->ws_fi->value)); pushNSTime(L,nstime); return 1; } case FT_STRING: case FT_STRINGZ: { gchar* repr = fvalue_to_string_repr(&fi->ws_fi->value,FTREPR_DISPLAY,BASE_NONE,NULL); if (repr) lua_pushstring(L,repr); else luaL_error(L,"field cannot be represented as string because it may contain invalid characters"); return 1; } case FT_NONE: if (fi->ws_fi->length > 0 && fi->ws_fi->rep) { /* it has a length, but calling fvalue_get() on an FT_NONE asserts, so get the label instead (it's a FT_NONE, so a label is what it basically is) */ lua_pushstring(L, fi->ws_fi->rep->representation); return 1; } return 0; case FT_BYTES: case FT_UINT_BYTES: case FT_REL_OID: case FT_SYSTEM_ID: case FT_OID: { ByteArray ba = g_byte_array_new(); g_byte_array_append(ba, (const guint8 *) fvalue_get(&fi->ws_fi->value), fvalue_length(&fi->ws_fi->value)); pushByteArray(L,ba); return 1; } case FT_PROTOCOL: { ByteArray ba = g_byte_array_new(); tvbuff_t* tvb = (tvbuff_t *) fvalue_get(&fi->ws_fi->value); g_byte_array_append(ba, (const guint8 *)tvb_memdup(wmem_packet_scope(), tvb, 0, tvb_captured_length(tvb)), tvb_captured_length(tvb)); pushByteArray(L,ba); return 1; } case FT_GUID: default: luaL_error(L,"FT_ not yet supported"); return 1; } }