Wireshark-dev: Re: [Wireshark-dev] Sub_dissectors assertion failed

From: Scott <theerickson@xxxxxxxxx>
Date: Tue, 25 May 2010 16:56:35 -0600
On Mon, May 24, 2010 at 3:54 PM, Guy Harris <guy@xxxxxxxxxxxx> wrote:
OK, so that's a little more complicated.  There are (at least) three ways of handling that:

       1) dissect the IP rider and the custom protocol as separate protocols, and use the standard mechanisms for handing off from the IP rider dissector to the custom protocol dissector;

       2) dissect the IP rider and the custom protocol as separate protocols, and use a specialized mechanism for handing off from the IP rider dissector to the custom protocol dissector;

       3) dissect them as a single protocol.

For 1), you would have to pass the IP protocol number from the IP rider protocol to the custom protocol.  What you would do there is:

In the IP rider dissector:

       in its register-handoff routine, register it in the "ip.proto" dissector table with its IP protocol number, and fetch a handle for the custom protocol dissector with find_dissector(), using the name the custom dissector uses to register itself;

       in its dissection routine, fetch the IP protocol number field's value into a local variable, and, when you want to call the custom protocol's dissector, set "pinfo->private_data" to point to the local variable and call the custom protocol dissector, using its handle, with call_dissector().

In the custom protocol dissector:

       in its register routine, register the dissector handle with register_dissector(), using the same name that the IP rider dissector uses to find it;

       in its register-handoff routine, fetch the "ip.proto" dissector table with find_dissector_table();

       in its dissection routine, when it is to call the dissector for its payload, use dissector_try_port(), using the IP protocol number pointed to by pinfo->private_data.

2) could be done similar to 1), except that you could just directly call the custom protocol dissector and have it take an additional argument, the IP protocol number, as an argument, or you could just dissect both protocol layers in the same routine.  That would, however, mean that some of the work done for you by call_dissector(), such as saving and restoring some state (which might not matter if your dissector doesn't change it), setting the current protocol name that shows up in some messages, and updating the list-of-protocols field, won't be done.  I wouldn't recommend doing it that way.

How 3) would be done should be obvious, but there might be reasons not to do that.

Ok.  I did a mixture of 1 and 2.
 
> Otherwise, here comes another question.  I solved the problem exhibited in:
> http://img80.imageshack.us/img80/5582/malformed.gif

You mean the problem that Wireshark thinks that 0x1bc4 is not equal to 0x1bc4? :-)

Yep :D
 
> by hardcoding a value into the reported_length parameter of tvb_new_subset() instead of using -1.  This is obviously not a long term solution, so what I need to get at is the IP header's value for "Total Length" (ip.len).

That's odd - the reported_length value for the tvbuff handed to the IPR dissector should be the total length value from the IP header unless this is an IP fragment, so changing the value of the length shouldn't matter.

Is the packet in question the first fragment of an IP datagram?

Nope.  The problem had to do with the code in packet-ip.c between lines 2375 and 2394.  If I left it as -1 it equated to 65,535 and the next dissector in line didn't like that I suppose.  Something with what ip_checksum returned triggered it.

Well, I've got it working right now.  I may need more help later with preferences.  There's one more bug hanging around I just saw and I'll work on that tomorrow.  Thanks a ton Guy.

-Scott