On May 21, 2010, at 12:49 PM, Scott wrote:

> I killed the original error of
> ERROR:packet.c:709:dissector_add: assertion failed: (sub_dissectors)
> by calling register_dissector_table() in proto_register_..().  Apparently I 
> didn't know I needed to do that, but it makes sense.

Yes.  As indicated:

        1) you can't register in a dissector table until the dissector table is 
registered;

        2) the *only* ordering guarantee we offer is that all register routines 
are run before any register-handoff routines are run;

so, to make sure that all the dissector tables are registered before any 
registrations are attempted in dissector tables, you must register dissector 
tables in your register routine and register dissectors *in* dissector tables 
in the register-handoff routines (dissector tables are used by dissectors to 
hand off the remaining packet data to the next protocol, hence the "handoff" in 
"register-handoff").

> I mean *any protocol that runs atop IP* can follow it.

Then you want to do what I suggested to find the right dissector for the 
following protocol - just get the "ip.proto" dissector table and use that.

> I am going to work on all protocols registered with IP to follow it as soon 
> as I get *another* custom dissector/protocol that I am working on, which can 
> follow it, to work.  Let's call the custom protocol *custom* and the IP rider 
> *it* to simplify things.
> 
> I have the custom protocol doing dissector_add("[field switch on *it*]", 
> [macro expansion that matches a field value], *custom*_handle) in its handoff 
> routine.  However, for some reason it is apparently not being called upon to 
> dissect because it is not showing up as a header in the packet window.

So what protocols does your custom protocol run on top of?  It needs to 
register with the appropriate dissector table or tables for those protocols, 
using the appropriate value (Ethernet type, IP protocol type, etc.).

> As a "by the way," you mentioned in your reply:
> 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().
> How do I "hand off the payload to the next dissector with that dissector 
> table, the protocol number, and dissector_try_port()?"  Is that through a 
> function call?

Yes.

The name of the function you call is "dissector_try_port".

> And what does dissector_try_port() do?  All I could tell is that it returns a 
> gboolean.

It takes, as arguments:

        1) a handle for a dissector table that uses integral values as keys (it 
should really be dissector_try_uint(); the "port" is historical);

        2) an integral value to use to select a dissector from that dissector 
table;

        3) a tvbuff_t * that refers to a tvbuff with the data to be dissected 
by the selected dissector;

        4) a packet_info *, which should be the one the dissector calling 
dissector_try_port() was handed;

        5) a proto_tree *, which should be the one the dissector calling 
dissector_try_port() was handed.

If it finds a dissector in the dissector table that was registered with the 
integral value in question, it calls it, handing it the tvbuff_t *, the 
packet_info *, and the proto_tree *, and returns TRUE.  If not, it returns 
FALSE; you then need to decide how to dissect the data (for example, just show 
it as raw data).

For example, the Ethernet dissector calls dissector_try_port(), handing it the 
Ethernet-type dissector table, and the Ethernet type value from the packet.

> More questions I haven't been able to find answers to:
> *The proto_handoff_..(void) routine's main job is to register the dissector 
> with other dissectors so it gets called at the right moment, correct?

Yes.

> *What is the difference between create_dissector_handle() and 
> new_create_dissector_handle()?

There are two types of dissectors:

        1) dissectors for protocol fields such as Ethernet types where the 
value used when you select a dissector (integral value for 
dissector_try_port()) is uniquely assigned to a protocol, so that you can 
pretty much guarantee that the selected dissector is the right one;

        2) dissectors for protocol fields such as UDP or TCP ports where the 
value is assigned to the protocol but could be used by other protocols, so you 
*can't* guarantee that the selected dissector is the right one.

In addition, in some cases the calling dissector needs to know how much data 
from the tvbuff was considered part of the data for the called dissector's 
protocol, i.e. where it doesn't always get the rest of the packet.

"New-style" dissectors are for case 2) and for the other case mentioned.  For 
case 2), they do some heuristic checks to see if the packet looks appropriate 
for their protocol and, if not, they return 0 without having done any 
dissection, otherwise they return the amount of data dissected.  For the other 
case, they return the amount of data dissected.

(This has a problem if there's no packet data left to dissect, i.e. the tvbuff 
handed to them is zero-length; you can't distinguish between "this isn't one of 
my packets" and "this is one of my packets, and I dissected all 0 bytes of it". 
 Yes, there are cases where this is a problem.)
___________________________________________________________________________
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-requ...@wireshark.org?subject=unsubscribe

Reply via email to