Wireshark mailing list archives

wslua tcp reconstruct behaves strange when multiple messages span multiple packets


From: Sjoerd van Doorn <sjoerd.van.doorn () group2000 eu>
Date: Tue, 5 Nov 2013 12:40:45 +0000

I have been working on various Lua based dissectors.
I found something that I would entitle as undesirable, however I'm not sure if it is a actual bug.
For example if I have a TCP connection with packets over it and the packets contain messages including a header.
it would be very well possible that there are two TCP packets.
            One including the first message and the first part of the second message
            The second with the second part of the second message and the third message
In order to instruct the Lua dissector to combine multiple packets, TCP reconstruction is (ab)used.
            when dissecting the first packet, there is not enough data for the second message therefore a negative 
value of the second part of the second message is returned
                        and the pinfo.desegment_len and pinfo.desegment_offset are set
            when the second packet is received, it takes the number of bytes as specified in pinfo.desegment_len and 
adds it to the buffer of the previous dissect.
                        It than reruns the dissector.
                        next it calls the dissector again with the remaining part of the second packet.
To me this appears to be strange since in the GUI, the frame tab is not fully included in the Reassembled TCP tab.
The third message is not in the reassembled data and I don't know how to handle it as a big block ( since I am not 
aware of the third message while handling the first packet)

Please see http://www.cloudshark.org/captures/2a86e8fd2c69 for a demo pcap including the scenarion above and one with 4 
messages over 3 packets.
the dissector used :

            do
           local p_nuffproto     = Proto("nuff_protocol", "Nuff Protocol")

           local f_tag     = ProtoField.string ("nuff_protocol.starttag" , "Start Tag " )
           local f_length  = ProtoField.uint16 ("nuff_protocol.length"   , "Length    ", base.DEC)
           local f_data    = ProtoField.bytes  ("nuff_protocol.data"     , "Data      ", base.HEX)
           p_nuffproto.fields = {f_tag,f_length,f_data}

           local STARTTAGLENGTH = 8
           local LENGTHLENGTH   = 2
           local HEADERLENGTH   = STARTTAGLENGTH + LENGTHLENGTH

           function p_nuffproto.dissector(buf,pinfo,root)
             local offset = 0
             local remaining = buf:len() - offset
             while ( remaining > 0 ) do
                 -- make sure we have enough data to read the header
                 if ( remaining < HEADERLENGTH) then
                    pinfo.desegment_len    = (HEADERLENGTH - remaining) -- how much more do we need
                    pinfo.desegment_offset = 0 -- start with disector from 0 next run
                    return (remaining - HEADERLENGTH)
                 end
                 local len = buf(offset+STARTTAGLENGTH,LENGTHLENGTH):uint()
                 if ( len > remaining ) then
                    pinfo.desegment_len    = (len - remaining) -- how much more do we need
                    pinfo.desegment_offset = 0 -- start with disector from 0 next run
                    return (remaining - len)
                  end
                 local subtree = root:add(p_nuffproto,buf(offset,len))
                 subtree:add(f_tag   , buf(offset ,STARTTAGLENGTH))
                 subtree:add(f_length, buf(offset + STARTTAGLENGTH,LENGTHLENGTH))
                 subtree:add(f_data  , buf(offset + HEADERLENGTH,(len - HEADERLENGTH)))
                 pinfo.cols.protocol = "NUFF"
                 offset = offset + len
                 remaining = buf:len() - offset
             end
           end
           -- register to the UDP port
           local tcp_encap_table = DissectorTable.get("tcp.port")
           tcp_encap_table:add(33445, p_nuffproto)
       end

Please note that both the data and the dissector are "created" to demo the effect.
I would like to know if:
            * The effect is intended to behave this way
            * Is there a way to keep rerunning the dissector until it no longer returns a negative value ?
            * Is there another way of combining the data from various packets with the wslua api ?

Thanks and all the best,

Sjoerd van doorn
___________________________________________________________________________
Sent via:    Wireshark-dev mailing list <wireshark-dev () wireshark org>
Archives:    http://www.wireshark.org/lists/wireshark-dev
Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev
             mailto:wireshark-dev-request () wireshark org?subject=unsubscribe

Current thread: