Ask Your Question
0

LUA: tlv_tree:add "hex data sequence"

asked 2021-07-29 21:21:03 +0000

sezb51 gravatar image

Hello,

One TLV has length 18... If I try to add to the display tree using:

f.tlvvalue_hex = ProtoField.uint32 ("myproto.tlvvalue_hex", "TLV Value", base.HEX)
tlv_tree:add (f.tlvvalue_hex, buffer(offset, tlvlen))

I get following [(Warning/Malformed) Trying to fetch an unsigned integer with length 18]

How can I just have an hex data sequence displayed instead ? Maybe leveraging on ByteArray ?

Thx!

edit retag flag offensive close merge delete

Comments

this seems to do the trick...

  local bytearr = {}
  for i = 1, tlvlen do
    bytearr[i] = string.format("%X", buffer(offset + i, 1):uint())
  end
  local results = table.concat(bytearr)
  tlv_tree:add (f.tlvvalue_string, results)
  tlv_tree:append_text (": " .. results)

However selecting such information does not get reflected in the raw packet hightlighted... :(

sezb51 gravatar imagesezb51 ( 2021-07-30 18:55:43 +0000 )edit

What I'm really looking after is to implement a kinda of payload concept like this:

payload_example

There the amount of selected data is arbitrary yet it still get highlighted.

Any idea ?

sezb51 gravatar imagesezb51 ( 2021-07-30 19:05:36 +0000 )edit

2 Answers

Sort by ยป oldest newest most voted
0

answered 2021-08-01 23:54:37 +0000

cmaynard gravatar image

updated 2021-08-01 23:56:31 +0000

I think there's an even easier way to achieve the same results using something like this:

f.data = ProtoField.bytes("S8HR_proto.data", "Data Hex")

local tvbr = buffer(offset, tlvlen)
tlv_tree:add(f.data, tvbr):
    append_text(", Data ASCII: " .. Struct.fromhex(tostring(tvbr:bytes())))

Unfortunately, at least as far as I can tell, neither solution displays non-printable characters very well, and if there's a 0 in the bytestream, then the string will be truncated. So to deal with that, here's an alternate solution:

function bytes2ascii(bytearr)
    local ascii = {}

    for i = 1, bytearr:len() do
        local b = bytearr:get_index(i - 1)
        if b >= 32 and b <= 127 then
            ascii[i] = string.char(b)
        else
            ascii[i] = '.'
        end
    end
    return table.concat(ascii)
end

f.data = ProtoField.bytes("S8HR_proto.data", "Data Hex")

local tvbr = buffer(offset, tlvlen)
tlv_tree:add(f.data, tvbr):
    append_text(", Data ASCII: " .. bytes2ascii(tvbr:bytes()))

And if you want to be able to filter the field separately between binary and ASCII data, then you might consider adding separate fields, e.g.:

f.data = ProtoField.bytes("S8HR_proto.data", "Data Hex", base.NONE)
f.asciidata = ProtoField.string("S8HR_proto.asciidata", "Data ASCII", base.ASCII)

local tvbr = buffer(offset, tlvlen)
tlv_tree:add(f.data, tvbr)
tlv_tree:add(f.asciidata, tvbr, bytes2ascii(tvbr:bytes()))

You can also mark it as a Generated field too if you'd like:

tlv_tree:add(f.data, tvbr, bytes2ascii(tvbr:bytes())):set_generated()

There may be other solutions too, depending on what you're expecting for your output. For example, unless I'm misreading the documentation then at least in theory it should be possible to call tvbr:string(), as per the documentation in section 11.8.3.18. tvbrange:string([encoding]); however that didn't work in my testing, so I suspect there's a Wireshark bug here, either in the implementation or in the documentation, because it doesn't work as advertised, namely:

Returns
A string containing all bytes in the TvbRange including all zeroes (e.g., "a\000bc\000").

edit flag offensive delete link more
0

answered 2021-07-31 13:06:45 +0000

sezb51 gravatar image

Final code. I'm happy with that :)

function hex2string(buffer, offset, len)
  local bytearr = {}
  for i = 1, len do
    bytearr[i] = string.format("%.2X", buffer(offset +i-1, 1):uint())
  end
  return table.concat(bytearr)
end

function hex2ascii(buffer, offset, len)
  local bytearr = {}
  for i = 1, len do
    bytearr[i] = string.char(buffer(offset +i-1, 1):uint())
  end
  return table.concat(bytearr)
end


    f.data = ProtoField.bytes ("S8HR_proto.data", "Data Hex")

    local tlv_data = tlv_tree:add (f.data, buffer(offset, tlvlen))
    local data_hex = hex2string(buffer, offset, tlvlen)
    local data_ascii = hex2ascii(buffer, offset, tlvlen)
    tlv_data:set_text("Data Hex: " .. data_hex .. ", Data Ascii: '".. data_ascii .. "'")

It basically set the tree with f.data (so it get highlighted when selected). It also read the sequence and store as hex-string and ascii-string. Finally it update the tree's text with that value.

Hope it could be of any help for other Lua's newbies.

edit flag offensive delete link more

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: 2021-07-29 21:21:03 +0000

Seen: 622 times

Last updated: Aug 01 '21