Search code examples
luawiresharkwireshark-dissector

How to use add_packet_field in a Wireshark Lua dissector?


I am stumbling my way through writing a dissector for our custom protocol in Lua. While I have basic field extraction working, many of our fields have scale factors associated with them. I'd like to present the scaled value in addition to the raw extracted value.

It seems to me tree_item:add_packet_field is tailor-made for this purpose. Except I can't get it to work.

I found Mika's blog incredibly helpful, and followed his pattern for breaking my dissector into different files, etc. That's all working.

Given a packet type "my_packet", I have a 14-bit signed integer "AOA" that I can extract just fine

local pref = "my_packet"
local m = {
   aoa        = ProtoField.new("AOA", pref .. ".aoa", ftypes.INT16, nil, base.DEC, 0x3FFF, "angle of arrival measurement"),
}

local option=2
local aoa_scale = 0.1

function m.parse(tree_arg, buffer)
   if option == 1 then
      -- basic field extraction. This works just fine. The field is extracted and added to the tree
      tree_arg:add(m.aoa, buffer)

   elseif option == 2 then
      -- This parses and runs. The item is decoded and added to the tree,
      -- but the value of 'v' is always nil
      local c,v = tree_arg:add_packet_field(m.aoa, buffer, ENC_BIG_ENDIAN)

      -- this results in an error, doing arithmetic on 'nil'
      c:append_text(" (scaled= " .. tostring(v*aoa_scale) .. ")")

   end
end

(I use ProtoField.new instead of any of the type-specific variants for consistency in declaring my fields)

The documentation for add_packet_field says that the encoding argument is mandatory.

There is a README in the source code that says ENC_BIG_ENDIAN should be specified for network byte-order data (mine is). I know that section is for proto_tree_add_item, but I traced the code far enough to see that add_packet_field ends up passing the encoding to proto_tree_add_item.

Basically, at this point, I'm lost. I did find this post from 2014 that suggested limited support for add_packet_field but surely by now something as basic as an integer value is supported?

Also, I do know how to declare a Field and extract the value after tree:add does the parsing; worst case I'll fall back to that, but surely there is a more expedient way to access the just-parsed value added to the tree?

Wireshark Version

3.2.4 (v3.2.4-0-g893b5a5e1e3e)

Compiled (64-bit) with Qt 5.12.8, with WinPcap SDK (WpdPack) 4.1.2, with GLib
2.52.3, with zlib 1.2.11, with SMI 0.4.8, with c-ares 1.15.0, with Lua 5.2.4,
with GnuTLS 3.6.3 and PKCS #11 support, with Gcrypt 1.8.3, with MIT Kerberos,
with MaxMind DB resolver, with nghttp2 1.39.2, with brotli, with LZ4, with
Zstandard, with Snappy, with libxml2 2.9.9, with QtMultimedia, with automatic
updates using WinSparkle 0.5.7, with AirPcap, with SpeexDSP (using bundled
resampler), with SBC, with SpanDSP, with bcg729.

Running on 64-bit Windows 10 (1803), build 17134, with Intel(R) Xeon(R) CPU
E3-1505M v6 @ 3.00GHz (with SSE4.2), with 32558 MB of physical memory, with
locale English_United States.1252, with light display mode, without HiDPI, with
Npcap version 0.9991, based on libpcap version 1.9.1, with GnuTLS 3.6.3, with
Gcrypt 1.8.3, with brotli 1.0.2, without AirPcap, binary plugins supported (19
loaded).

Built using Microsoft Visual Studio 2019 (VC++ 14.25, build 28614).

Solution

  • Looking at the try_add_packet_field() source code, only certain FT_ types are supported, namely:

    • FT_BYTES
    • FT_UINT_BYTES
    • FT_OID
    • FT_REL_OID
    • FT_SYSTEM_ID
    • FT_ABSOLUTE_TIME
    • FT_RELATIVE_TIME

    None of the other FT_ types are supported [yet], including FT_UINT16, which is the one you're interested in here, i.e., anything else just needs to be done the old fashioned way.

    If you'd like this to be implemented, I'd suggest filing a Wireshark enhancement bug request for this over at the Wireshark Bug Tracker.