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

From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Thu, 20 May 2010 18:15:11 -0700
On May 20, 2010, at 5:58 PM, Scott wrote:

> If I am writing a dissector for a protocol that rides on top of IP but then allows any protocol to follow it,

Do you truly mean "any protocol", so that, for example, you could follow it with X.25 or HTTP or Ethernet, or do you mean, for example, any protocol *that runs atop IP* can follow it?

> how do I register them all correctly with my dissector?  I see that IP does this by enumerating protocol numbers in ipproto.h and then having dissectors call:
> dissector_add("ip.proto", IP_PROTO_.., .._handle);
> 
> but think it would be overkill to do exactly the same thing in my case.

If you mean, for example, "any protocol that runs atop IP", then you should grab hold of the "ip.proto" dissector table:

	dissector_table_t ip_proto_dissector_table;

		...

	ip_proto_dissector_table = find_dissector_table("ip.proto");

and then use that to hand off the payload to the next dissector with that dissector table, the protocol number, and dissector_try_port().  That way, any dissector that has registered itself for a protocol that can run atop IP will also be called by your dissector when appropriate.

> Also, besides all the pre-defined protocols I also tried registering a custom dissector with it and got this:
> 
> ERROR:packet.c:709:dissector_add: assertion failed: (sub_dissectors)

You passed to dissector_add() a first argument that did not correspond to a dissector table that existed at that time.  This means that either

	1) you did this in your register routine rather than your register-handoff routine

or

	2) you passed the name of a dissector table that never gets created.

The register routine is not supposed to register a dissector in *any* dissector tables, it's supposed to register protocol fields and register the dissector tables themselves, it's the register-handoff routine that should register dissectors in dissector tables.  This is because there is no guarantee that register routines will be executed in any particular order, so there's no guarantee that a dissector table will be created before a dissector tries to register in it.  The only guarantee we make is that *all* register routines will be run before *any* register-handoff routine is run, so if all dissector tables are created in register routines, and all registration of dissectors in dissector tables is done in register-handoff routines, the only way a registration of a dissector in a dissector table will fail would be if dissector_add() etc. were passed the name of a dissector table that doesn't exist.