Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reassembling packets in a Lua Wireshark Dissector

I'm trying to write a dissector for the Safari Remote Debug protocol which is based on bplists and have been reasonably successful (current code is here: https://github.com/andydavies/bplist-dissector).

I'm running into difficultly with reassembling packets though.

Normally the protocol sends a packet with 4 bytes containing the length of the next packet, then the packet with the bplist in.

Unfortunately some packets from the iOS simulator don't follow this convention and the four bytes are either tagged onto the front of the bplist packet, or onto the end of the previous bplist packet, or the data is multiple bplists.

I've tried reassembling them using desegment_len and desegment_offset as follows:

  function p_bplist.dissector(buf, pkt, root)  

    -- length of data packet
    local dataPacketLength = tonumber(buf(0, 4):uint())
    local desiredPacketLength = dataPacketLength + 4

    -- if not enough data indicate how much more we need
    if desiredPacketLen > buf:len() then
      pkt.desegment_len = dataPacketLength
      pkt.desegment_offset = 0
      return
    end

    -- have more than needed so set offset for next dissection
    if buf:len() > desiredPacketLength then
      pkt.desegment_len = DESEGMENT_ONE_MORE_SEGMENT
      pkt.desegment_offset = desiredPacketLength
    end

    -- copy data needed 
    buffer = buf:range(4, dataPacketLen)

    ...

What I'm attempting to do here is always force the size bytes to be the first four bytes of a packet to be dissected but it doesn't work I still see a 4 bytes packet, followed by a x byte packet.

I can think of other ways of managing the extra four bytes on the front, but the protocol contains a lookup table thats 32 bytes from the end of the packet so need a way of accurately splicing the packet into bplists.

Here's an example cap: http://www.cloudshark.org/captures/2a826ee6045b #338 is an example of a packet where the bplist size is at the start of the data and there are multiple plists in the data.

Am I doing this right (looking other questions on SO, and examples around the web I seem to be) or is there a better way?

like image 848
Andy Davies Avatar asked Jan 17 '13 20:01

Andy Davies


1 Answers

TCP Dissector packet-tcp.c has tcp_dissect_pdus(), which

Loop for dissecting PDUs within a TCP stream; assumes that a PDU consists of a fixed-length chunk of data that contains enough information to determine the length of the PDU, followed by rest of the PDU.

There is no such function in lua api, but it is a good example how to do it.

One more example. I used this a year ago for tests:

local slicer = Proto("slicer","Slicer")
function slicer.dissector(tvb, pinfo, tree)
    local offset = pinfo.desegment_offset or 0

    local len = get_len() -- for tests i used a constant, but can be taken from tvb

    while true do
        local nxtpdu = offset + len

        if nxtpdu > tvb:len() then
            pinfo.desegment_len = nxtpdu - tvb:len()
            pinfo.desegment_offset = offset
            return
        end

        tree:add(slicer, tvb(offset, len))

        offset = nxtpdu

        if nxtpdu == tvb:len() then
             return
        end
    end
end
local tcp_table = DissectorTable.get("tcp.port")
tcp_table:add(2506, slicer)
like image 168
graphite Avatar answered Oct 18 '22 06:10

graphite