need help to write a small dissector

asked 2024-02-28 18:48:23 +0000

Pf@nne gravatar image

Moin!

I got some problems to understand the lua script language. I hope someone like to support me... :-)

My first Problem ist to dissect a 16 Byte timestamp. The timestamp is described as follows:

"For timestamp the length in hexadecimal is 16 as mentioned. Converting the hexdecimal to binary we get 128 bits." The timestamp is an Epoch from 01/01/1904 00:00:00.00 UTC. The MSB 64 bits is the 2's complement integer of seconds from Epoch. The LSB 64 is direct decimal N to calc decimal seconds. N*2^(-64).

Right nor I stuck to decode the first 8 Bytes (seconds from 1.1.1904).

atime= ProtoField.absolute_time ("sitipe.atime", "test atime    " ,base.LOCAL),
timeFloat= ProtoField.double("sitipe.timeFloat", "test float    " ),

subtree:add_le(sitipe_fields.timeFloat,  buffer(6,8), time_stamp)

How to convert the seconds from the timestamp + TimeForm(1.1.1904) to a DateString?

edit retag flag offensive close merge delete

Comments

Is there a RFC or spec document you can share a link to?

Chuckc gravatar imageChuckc ( 2024-02-28 20:55:18 +0000 )edit

not realy, but I know the meaning of each byte in the payload.

The TimeStamp is contained in 2 x 8 bytes an was built in 2 steps:
Step 1: MSB - integer time in seconds since 1.1.1904 [0x 00 00 00 00 E1 F6 93 30] = 3.791.033.136 seconds
Step 2: LSB - integer time in micro seconds = description follows

local time_stamp = buffer(6,8):uint64() --seconds
subtree:add_le(sitipe_fields.timeint,  buffer(6,8), time_stamp)

local ts_days = time_stamp /60/60/24
subtree:add_le(sitipe_fields.timeFloat,  buffer(6,8), ts_days:todouble()) --how to print the double?

oletime = ProtoField.double("logger.oletime", "OLE time"),

-- Note: .int64 doesnt work so just using .int32
oletime_days    = ProtoField.int32("sitipe.oletime.days", "Days"),
oletime_partial = ProtoField.double("sitipe.oletime.partial", "Partial"),
oletime_abs     = ProtoField.absolute_time("sitipe.oleabstime", "OLE Abs time", base.UTC),

--local logger_tree = tree:add(p_logger, buffer(0,-1))
local OLE_DIFF_TO_UNIX = 25569  
local SECS_PER_DAY ...
(more)
Pf@nne gravatar imagePf@nne ( 2024-02-28 21:59:43 +0000 )edit

The timestamp format seems similar to LabVIEW Timestamp Overview.

Format timestamp in Python: How do I convert a LabVIEW decimal date into a string datetime format using Python?

Their example done in Wireshark Lua Console (WSDG - 11.1. Utility Functions):

print(format_date(3640111724.4817362 - 2082844800))

May  7, 2019 17:08:44.481736183 Central Daylight Time
Chuckc gravatar imageChuckc ( 2024-02-29 15:43:03 +0000 )edit

Hi Chuckc,

yes, indeed it is a LabView timestamp. My problem isn´t to unterstand how to decode a LabView timestamp. My problem ist to unterstand how to convert / typecast the 2 x 8 Byte in my Lua dissector.

Maybe we should solve it step by step....

local time_stamp = buffer(6,8):uint64() --seconds
subtree:add_le(sitipe_fields.timeint,  buffer(6,8), time_stamp)

This works...

MSB - 0x 00 00 00 00 e1 f6 93 30 = 3.791.033.136 seconds from 1.1.1904.

This converts the seconds into days [double]

local ts_days = time_stamp /60/60/24

How to add the days to my tree?

  timeDouble     = ProtoField.double        ("sitipe.timeDouble"       , "test double    " ),

 local ts_days = 1.1
 ts_days = (time_stamp /60/60/24):double()
 subtree:add_le(sitipe_fields.timeDouble,  buffer(6,8), ts_days)

Lua Error: C:\Program Files\Wireshark\plugins\4.2\epan\SITIPE_MS.lua:58: No such 'double' method/field for object type 'UInt64'

Pf@nne gravatar imagePf@nne ( 2024-02-29 19:22:57 +0000 )edit

11.13.2. UInt64

11.13.2.8. uint64:tonumber() Returns a Lua number of the UInt64 value. This may lose precision. Since: 1.11.3

https://www.lua.org/pil/2.3.html

The number type represents real (double-precision floating-point) numbers.

    timeDouble = ProtoField.double("easypost.timeDouble", "test double" 
...
    local time_stamp = UInt64.fromhex("00000000E1F69330")
    print(time_stamp)
    local ts_days =  (time_stamp /60/60/24):tonumber()
    print(ts_days)
        subtree:add(pf.timeDouble, ts_days

Console output:

3791033136

43877

Tree data:

test double: 43877
Chuckc gravatar imageChuckc ( 2024-02-29 22:49:26 +0000 )edit

OK, :tonumber works... Lua got his own Type... wehere: ...Lua has no integer type,... But I´m missing the decumal places....

3791033136 / 60 /60 /24 = 43877,6983333333

Converting to a formated string will also have no success.

subtree:add_le(sitipe_fields.timeDouble,  buffer(6,8)):set_text(string.format("%.4f", (time_stamp /60/60/24):tonumber()))

Pf@nne gravatar imagePf@nne ( 2024-03-01 12:43:59 +0000 )edit

this works so far:

ts_seconds     = ProtoField.uint64        ("sitipe.ts_seconds"       , "TimeStamp seconds  " ),
ts_days        = ProtoField.double        ("sitipe.ts_days"          , "TimeStamp days     " ),
ts_fractInt    = ProtoField.int64         ("sitipe.ts_fractInt"      , "TimeStamp fractInt " ),
ts_fraction    = ProtoField.double        ("sitipe.ts_fraction"      , "TimeStamp fraction " ),
ts_days        = ProtoField.double        ("sitipe.ts_days"          , "TimeStamp days     " ),

ts_abs         = ProtoField.absolute_time ("sitipe.ts_abs"           , "TimeStamp          "  , base.UTC),

-- HEADER -----------------------------------------------------------------------------
-- subtree:add_le(sitipe_fields.message_type,   buffer(0,2)):append_text(" (" .. type_name .. ")")
subtree:add_le(sitipe_fields.message_type,   buffer(0,2), type_name)
subtree:add_le(sitipe_fields.message_len,  buffer(2,4), buffer(2,4):uint64())
------
local ts_s = buffer(6,8):uint64() --seconds
subtree:add_le(sitipe_fields.ts_seconds,  buffer(6,8), ts_s)

local ts_d = (ts_s /60/60/24):tonumber() --days
subtree:add_le(sitipe_fields.ts_days,  buffer(6,8), ts_d)

local ts_fractInt = buffer(14,8):int64() --fration of seconds as signed integer (2er complement)
subtree:add_le(sitipe_fields.ts_fractInt,  buffer(14,8), ts_fractInt)

-- problems to calc the decimal places
-- LabViev Timstamp 
local ts_fract = (ts_fractInt * -0.0000000000000000000542101086242752):tonumber() --fration in nano 
seconds
subtree:add_le(sitipe_fields ...
(more)
Pf@nne gravatar imagePf@nne ( 2024-03-01 13:51:40 +0000 )edit

But I´m missing the decumal places.... 3791033136 / 60 /60 /24 = 43877,6983333333

Convert to a number before the math.

    local ts_days =  (time_stamp:tonumber() /60/60/24)

Console output: 43877.698333333

Packet details: test double: 43877.6983333333

11.13. Handling 64-bit Integers:

You should be very careful to never use Lua numbers bigger than 32 bits (i.e., the number value 4,294,967,295 or the literal 0xFFFFFFFF) for such arguments,

3.791.033.136 < 4,294,967,295 but at some point the code above breaks. :-(

Maybe this: local ts_days = (time_stamp /60/60):tonumber() / 24 ???

Chuckc gravatar imageChuckc ( 2024-03-01 14:04:33 +0000 )edit

OK, I think I understand slowly the typecast philosophy.

Youre right, the actual date uses only 4 Bytes.... on 06.02.2040, 5 Bytes are needed. your idea is good, but l think it loses precision:

3.791.033.136 / 60 / 60 / 24 = 43877,6983333333 = 17.02.2024 16:45:36,000 3.791.033.136 / 60 / 60 = 1053064,76 (integer) = 1053064 1053064 / 24 = 43877,66667 = 17.02.2024 16:00:00,000

Pf@nne gravatar imagePf@nne ( 2024-03-02 19:10:10 +0000 )edit