1
votes

I would like to do some analysis on top of my custom protocol that is dissected via my lua dissector. Therefore I tried to do this

myproto_proto = Proto("myproto", "Myproto Protocol")
m_dest = ProtoField.uint16("myproto.dest", "Destination", base.HEX)
m_src = ProtoField.uint16("myproto.src", "Source", base.HEX)
myproto_proto.fields = { sm_dest, sm_src }

dofile(MYPROTO_PROTO_PATH.."parser.lua")

function myproto_proto.dissector(buffer, pinfo, tree)
   pinfo.cols.protocol = "MYPROTO"

   local subtree = tree:add(myproto_proto, buffer(), "Myproto Protocol Data")
   parse_msg(buffer, pinfo, subtree) -- does the actual parsing and sets the fields
end

udp_table = DissectorTable.get("udp.port")
udp_table:add(9000,myproto_proto)

-- LISTENER / TAP

f_test = Field.new("myproto.dest") -- fails because "field does not exist"
local function my_tap()
   local window = TextWindow.new("Myproto Tap")
   local tap = Listener.new(nil, "myproto")

   local counter = 0
   function remove()
      tap:remove()
   end

   window:set_atclose(remove)

   function tap.packet(pinfo, buffer)
      counter = counter + 1
   end

   function tap.draw(t)
      window:append("Counter: \t" .. counter .. "\n")
   end

   function tap.reset()
      window:clear()
      counter = 0
   end
   retap_packets()
end

register_menu("My Tap", my_tap, MENU_TOOLS_UNSORTED)

My problem is, I'm unable to access the dissected data with a field extractor. So how else could I get the dissected data in my lua tap?

Thanks in advance.

1

1 Answers

3
votes

It's a known problem that custom Lua Field objects aren't usable in OSX (it apparently works in Windows XP but not Windows 7).

There are a few ways to pass data from your dissector to your tap.


Option 1: Use a shared Lua table

  1. Create a global dictionary that is keyed by the packet number (from pinfo.number, which is visible to both dissector and tap).

    -- we omit the 'local' keyword to make `dict` a global variable
    dict = {}
    
  2. In your dissector, add the packet data to the dictionary:

    dict[pinfo.number] = { dest = m_dest, src = m_src }
    
  3. In your tap, you can access the data by a simple lookup.

    print('dest', dict[pinfo.number].dest )
    

XXX: Requires a global; Duplicates storage for a variable that is already held in the protocol tree (and should be accessible from the tap).


Option 2: Use pinfo.private

This was added in the dev build (1.7.0). It's similar to the solution above. pinfo.private is a PrivateTable, which is a hash table that stores only strings.

  1. In your dissector, add your data to the packet's private table:

    pinfo.private["src"] = tostring(m_src)
    pinfo.private["dest"] = tostring(m_dest)
    
  2. In your tap, access the data from the pinfo object:

    print('dest', pinfo.private["dest"] )
    

XXX: Can only store string values


Option 3: Reparse the buffer

  1. In your tap, call your parser (i.e., from parser.lua) to reparse the data in buffer, which is passed to the tap.

XXX: Duplicates work already done by dissector (can double processing time for X-large capture files)