Ask Your Question
0

How to handle 6 byte unsigned integer field in lua dissector?

asked 2019-01-07 04:56:59 +0000

wwtegel gravatar image

updated 2019-01-07 18:59:02 +0000

Certain exchange protocols have started sending their timestamp fields as a 6 byte unsigned integer. The field data contains nanoseconds since midnight. If I promote this value to a uint64 via:

local range = buffer(offset, 6)
local value = range:uint64()
local display = "Timestamp"..value

parent:add(fields.timestamp, range, value, display)

I get:

Lua Error: [...]:370: calling 'add' on bad self (string expected, got userdata)

Is there a way to use the internal field parsers to handle 6 bytes as an integer? Do I need to write a custom function for this data?

edit retag flag offensive close merge delete

Comments

Note: this displays the correct value but converts to a string:

local range = buffer(offset, 6)
local value = tostring(UInt64.fromhex("0000"..range))
local display = "Timestamp"..value

parent:add(fields.timestamp, range, value, display)
wwtegel gravatar imagewwtegel ( 2019-01-07 05:20:08 +0000 )edit

Caution, I only know enough Lua to be dangerous, but can't you use a tvbrange:uint64() with the 6 byte range, to retrieve the value into a uint64 variable. e.g.

local timeRange = buffer(offset, 6)
local nanosecs = timeRange:uint64()
grahamb gravatar imagegrahamb ( 2019-01-07 14:10:40 +0000 )edit

Thanks for taking a look, I added the original script that caused the error. Your suggestion was my original line of thought.

wwtegel gravatar imagewwtegel ( 2019-01-07 16:45:39 +0000 )edit

You have a "::" on the range object, have you tried a single ":"?

grahamb gravatar imagegrahamb ( 2019-01-07 18:39:35 +0000 )edit

I was copying from memory since this source is on a branch on my home cpu. :: was because my fingers know c++. I updated the example. Thanks.

wwtegel gravatar imagewwtegel ( 2019-01-07 19:00:42 +0000 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2019-01-07 19:57:50 +0000

cmaynard gravatar image

Below is a working example of adding a 64-bit value to a tree, as well as grabbing the 64-bit value to do something else with it - in this case, adding it to the Info column:

-- Protocol
local p_foo = Proto("foo", "FOO Protocol")

-- Fields
local f_foo_val8 = ProtoField.uint8("foo.val8", "Value 8", base.OCT)
local f_foo_val64 = ProtoField.uint64("foo.val16", "Value 64", base.DEC)

p_foo.fields = { f_foo_val8, f_foo_val64 }

-- Dissection
function p_foo.dissector(buf, pinfo, tree)
    local foo_tree = tree:add(p_foo, buf(0,-1))
    local val64

    pinfo.cols.protocol:set("FOO")

    foo_tree:add(f_foo_val8, buf(0, 1))
    foo_tree:add(f_foo_val64, buf(1, 6))
    val64 = buf(1, 6):uint64()
    pinfo.cols.info:set("Value 64: " .. val64)
end

-- Registration
local udp_table = DissectorTable.get("udp.port")
udp_table:add(33333, p_foo)

You can use the foo.pcapng file I uploaded to cloudshark long ago to test this if you wish.

edit flag offensive delete link more

Comments

Thanks. My script example might already be right... hardest bug to find. Your example reminded me that parent:add is using a declared ProtoField. The issue might be there.

 fields.timestamp = ProtoField.new("Timestamp", "timestamp", ftypes.BYTES)

I will take another swing tonight.

wwtegel gravatar imagewwtegel ( 2019-01-07 20:11:58 +0000 )edit

So it appears your issue wasn't with extracting the 6 byte value as a uint64, but rather adding it to the tree.

grahamb gravatar imagegrahamb ( 2019-01-08 07:50:58 +0000 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2019-01-07 04:56:59 +0000

Seen: 36 times

Last updated: Jan 07