0
votes

I have written several Lua Dissectors for custom protocols we use and they work fine. In order to spot problems with missing packets I need to check the custom protocol sequence numbers against older packets. The IP source and Destination addresses are always the same for device A to device B. Inside this packet we have one custom ID. Each ID has a sequence number so device B can determine if a packet is missing. The sequence number increments by 256 and rolls over when it reaches 65k I have tried using global dictionary but when you scroll up and down the trace the decoder is rerun and the values change. a couple of lines below show where the information is stored.

ID = buffer(0,6):bitfield(12,12)
SeqNum = buffer(0,6):bitfield(32,16)

Ideally I would like to list in each decoded frame if the previous sequence number is more than 256 away and to produce a table lists all these bad frames.

Src IP; Dst IP; ID; Seq

1 10.12.1.2; 10.12.1.3; 10; 0

2 10.12.1.2; 10.12.1.3; 11; 0

3 10.12.1.2; 10.12.1.3; 12; 0

4 10.12.1.2; 10.12.1.3; 11; 255

5 10.12.1.2; 10.12.1.3; 12; 255

6 10.12.1.2; 10.12.1.3; 10; 511 Packet with seq 255 is missing

I have now managed to get the dissector to check the current packet against previous packets by using a global array, where I store specific information about each frame. In the current packet being dissected I recheck the most recent packet and work my way back to the start to find a suitable packet.

 dict[pinfo.number] = {frame = pinfo.number, dID = ID, dSEQNUM = SeqNum} 
local frameCount = 0 
local frameFound = false 
while frameFound == false do 
    if pinfo.number > frameCount then
      frameCount = frameCount + 1
      if dict[(pinfo.number - frameCount)] ~= nil then
          if dict[(pinfo.number - frameCount)].dID == dict[pinfo.number].dID then
              seq_difference = (dict[(pinfo.number)].dSEQNUM - dict[(pinfo.number - frameCount)].dSEQNUM)
              if seq_difference > 256 then
                  pinfo.cols.info = string.format('ID-%d SeqNum-%d  missing packet(s) %d   last frame %d ', ID,SeqNum, seq_difference, dict[(pinfo.number - frameCount)].frame)
              end
              frameFound = true
           end
       end
     else
        frameFound = true
     end
 end
1

1 Answers

0
votes

I'm not sure I see a question to answer? If you're asking "how can I avoid having to deal with the dissector being invoked multiple times and screwing up the previous decoding of the values" - the answer to that is using the pinfo.visited boolean. It will be false the first time a given packet is dissected, and true thereafter no matter how much clicking around the user does - until the file is reloaded or a new one loaded.

To handle the reloading/new-file case, you'd hook into the init() function call for your proto, by defining a function myproto.init() function, and in that you'd clear your entire array table.

Also, you might want to google for related questions/answer on ask.wireshark.org, as that site is more frequently used for wireshark Lua API questions. For example this question/answer is similar and related to your case.