Wireshark-dev: Re: [Wireshark-dev] Dissecting multiple protocol headers in a single plugin

From: Bob Doolittle <Robert.Doolittle@xxxxxxx>
Date: Wed, 04 Apr 2007 08:18:14 -0400
Guy Harris wrote:
On Apr 3, 2007, at 4:53 PM, Bob Doolittle wrote:

Thanks.  My subdissector is now being called, and is updating the List
window
properly. But for some odd reason the sub-protocol isn't appearing in the
Details window tree, and I'm handling it identically to how I handled
the parent
protocol, which is drawing properly. I've verified that the proto has been
registered properly.  I've verified that the same tree is being
passed into the subdissector, and that it's making the
proto_tree_add_item call
for the proto in the parent tree, but it's not appearing.

So the "tree" argument to the subdissector is non-null?

Yes it is. Under what circumstances is it NULL, by the way? I'm mimic'ing the
appropriate tests/structure but don't understand why yet...

What's the code in the subdissector that adds the top-level entry for the protocol?

Here's the complete top-level dissector. OFFANDSIZE is a macro that expands
into two comma-separated values/args.  dissect_alp_resource does most of the
packet dissection.  The sub-dissector looks quite similar...

static int
dissect_alp_dgram(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
   guint16 seqno = tvb_get_ntohs(tvb, 0);
   guint16 offset = tvb_get_ntohs(tvb, OFFSET(newt_packet_hdr,
					       first_cmd_offset));
   guint packet_type;

   if (check_col(pinfo->cinfo, COL_PROTOCOL))
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALP");
   // Clear out stuff in the info column
   if (check_col(pinfo->cinfo,COL_INFO)){
	col_clear(pinfo->cinfo,COL_INFO);
   }
   if (check_col(pinfo->cinfo,COL_INFO)){
	col_add_fstr(pinfo->cinfo, COL_INFO, "Seq=0x%x", seqno);
   }

   if (tree) { // we are being asked for details
	proto_item *ti = NULL;
	proto_tree *alp_dgram_tree = NULL;

	ti = proto_tree_add_item(tree, proto_alp_dgram, tvb, 0,
				 sizeof(struct newt_packet_hdr)+1, FALSE);
	proto_item_append_text(ti, ", Seq: 0x%x", seqno);
	alp_dgram_tree = proto_item_add_subtree(ti, ett_alp_dgram);
	proto_tree_add_item(alp_dgram_tree, hf_alp_dgram_seq_num, tvb,
			    OFFANDSIZE(newt_packet_hdr, sequence),
			    FALSE);
	proto_tree_add_item(alp_dgram_tree, hf_alp_dgram_offset, tvb,
			    OFFANDSIZE(newt_packet_hdr, first_cmd_offset),
			    FALSE);
	packet_type = dissect_alp_resource(tvb, pinfo, alp_dgram_tree, ti, offset);
   }
   (void)dissector_try_port(alp_dgram_dissector_table, packet_type,
			     tvb_new_subset(tvb,
					    sizeof(struct newt_packet_hdr) + 1,
					    -1,
					    -1),
			     pinfo, tree);
   return(sizeof(struct newt_packet_hdr)+1);
}	



Is there something special that has to occur for a single plugin to add two
separate protos to the tree?

A single plugin can contain multiple dissectors; they can be in a single source file, or multiple source files.

The only thing that's necessary for a single source file to contain multiple dissectors is to make sure that the registration and handoff- registration routines in that source file (there can be more than one such routine) register all the dissectors properly.

Yup.  Similar to the docsis example.

Thanks for any clues...

-Bob