Wireshark-dev: Re: [Wireshark-dev] Using Lua to parse TCP encapsulated IP protocol

From: "Scott Robinson" <scott.anthony.robinson@xxxxxxxxx>
Date: Mon, 29 Jan 2007 07:08:15 -0500
Hi Luis,

I tried 0.99.5pre1 (WinXP - still crashes) and even started building the Linux client to test, that's when I noticed the capture file seemed to partially load before crashing.

I switched to tshark and was able to verify a specific packet was always causing the crash. When I investigated further, I found my capture file had traffic that included messages that were not encapsulated IP.

The crash occurred when  a non IP  payload was feed to the IP dissector. I've added some defensive code in my Lua program to check for a valid IP header before passing the tvb off to the IP dissector. Everything works great now.

So I'm not sure there's any to do in the wireshark code base. Ideally a dissector shouldn't crash on bad data, but the only way this got there was my lua code that didn't do enough sanity checking on the payload.

Here's the payload that was passed to the ip dissector that caused the crash.
0a 64 64 14 00 00 00 00 00 00 00 00
versus the expected:
45 00 ...

I'm guessing the 0a -> indicated 40 bytes of ip header length was causing the dissector to go off the end of the packet buffer and cause the crash.

Thanks also for the tip on the sub range creation. I thought that might work, but when the program was crashing, I was a bit leery about going beyond the example code I found.

Thanks again for the help.
-Scott

> Date: Tue, 23 Jan 2007 21:42:32 +0100
> From: "Luis Ontanon" <luis.ontanon@xxxxxxxxx>
> Subject: Re: [Wireshark-dev] Using Lua to parse TCP encapsulated IP
>         protocol
> To: "Developer support list for Wireshark"
>         <wireshark-dev@xxxxxxxxxxxxx>
>
> Hi,
> * Can you test it against 0.99.5pre1?
> I cannot make it crash (works OK for me), could you send the capture
> file that does crash?
> Could you eventually send in also the output of wireshark -v
>
> Thanks
> Luis
>
> BTW
> sub_buf = buffer( 4, buffer:len() - 4 ):tvb()
> is the same as
> sub_buf = buffer(4):tvb()
>
>
> On 1/22/07, Scott Robinson < scott.anthony.robinson@xxxxxxxxx> wrote:
> > Hi,
> >
> > I've been using Lua to create a dissector for a protocol that has IP
> > encapsulated inside TCP with an additional header. Everything works fine
> > until I try to create a new tvb off from a tvbsubrange. When I do this,
> > Wireshark crashes. The new tvb appeared correct when I added debug
> > statements (pointing at the correct data, and length are correct).
> >
> > The Lua and Wireshark docs refered to the Tvb.new_subset function to create
> > a new sub tvb for an encapsulated protocol. I couldn't get that to work and
> > used something like buffer(4,n):tvb().
> >
> > I've only been looking at the Wireshark and Lua code for a short time now,
> > so I'm hoping I'm just coding something up wrong. Any pointers would be
> > greatly appreciated.
> >
> > Here's a sample of the code that was crashing. If I comment out the line
> > that tries to pass the new sub tvb to the ip dissector, or just pass the
> > original buffer to the ip dissector, wireshark doesn't crash (although it
> > doesn't decode like I need it too)
> >
> > Thanks.
> > -Scott
> > -- Define our protocol
> > my_proto  = Proto("myproto", "MINE", "My Protocol")
> >
> >
> > -- Create a function to dissect my_proto
> > function my_proto.dissector( buffer, pinfo, tree )
> >    local subtree = tree:add( my_proto, buffer, "My Proto Header" )
> >
> >    subtree:add( buffer(0,1), "Version: "  .. buffer(0,1):uint() )
> >     subtree:add( buffer(1,1), "Type: "     .. buffer(1,1):uint() )
> >    subtree:add( buffer(2,2), "Sequence: " .. buffer(2,2):uint() )
> >
> >    ip_dissector = Dissector.get("ip")
> >
> >    -- skip over the header in front of the encapsulated ip packet
> >    sub_buf = buffer( 4, buffer:len() - 4 ):tvb()
> >
> >    ip_dissector:call( sub_buf, pinfo, tree )
> >
> > end
> >
> > -- load the tcp port table
> > tcp_table = DissectorTable.get("tcp.port")
> >
> > -- register our protocol
> > tcp_table:add(7000, my_proto)
> >
> >