Ethereal-dev: Re: [Ethereal-dev] Request for help - odd dissector bug.

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Guy Harris <gharris@xxxxxxxxx>
Date: Thu, 31 Jan 2002 02:28:19 -0800
On Thu, Jan 31, 2002 at 10:15:17AM +0000, Gylve wrote:
> When running the dissector under normal circumstances,
> the "info" and "protocol" columns do not contain
> accurate information about the packets that are being
> dissected. The protocol column is supposed to contain
> a count of the number of protocol packets in the TCP
> packet, however, this is always incorrectly reported
> as 2. The info column generally contains the correct
> identity of the packet, plus a "rogue" addition.
> Strangely, if any display filter is specified at all,
> the code starts working perfectly, with both colums
> displaying the correct information.

If no display filter is specified, the "tree" argument to a dissector is
null; often, this means that the dissector will skip some dissection,
for efficiency reasons.

However, any dissection that sets the columns must be done *regardless*
of whether the "tree" argument is null.  Furthermore, any dissection
upon which subsequent dissection must be done if the latter dissection
is done regardless of whether the "tree" argument is null, and any
dissection that calls subdissectors must be done regardless of whether
the "tree" argument is null.

I.e., if a dissector does

	if (tree != NULL) {

		...

		if (check_col(pinfo->cinfo, COL_INFO))
			col_append_str(...);

	}

it's buggy, and if a dissector does

	offset = 0;
	type = tvb_get_guint8(tvb, offset);
	if (check_col(pinfo->cinfo, COL_INFO))
		col_add_fstr(pinfo->cinfo, COL_INFO, "Type: %s",
		    val_to_str(type, type_vals, "Unknown (0x%02x)");
	if (tree != NULL)
		proto_tree_add_uint(tree, hf_pdu_type, tvb, offset, 1, type);
	offset++

	if (tree) {
		command_length = tvb_get_guint8(tvb, offset);
		proto_tree_add_uint(tree, hf_command_length, tvb, offset, 1,
		    command_length);
		offset++;
		proto_tree_add_item(tree, hf_command, tvb, offset,
		    command_length, FALSE);
		offset += command_length;
	}

	subtype = tvb_get_guint8(tvb, offset);
	if (check_col(pinfo->cinfo, COL_INFO))
		col_append_fstr(pinfo->cinfo, COL_INFO, ", Subtype: %s",
		    val_to_str(subtype, subtype_vals, "Unknown (0x%02x)");
	if (tree != NULL)
		proto_tree_add_uint(tree, hf_pdu_subtype, tvb, offset, 1,
		    subtype);

it's buggy, and if a dissector does

	offset = 0;
	type = tvb_get_guint8(tvb, offset);
	if (check_col(pinfo->cinfo, COL_INFO))
		col_add_fstr(pinfo->cinfo, COL_INFO, "Type: %s",
		    val_to_str(type, type_vals, "Unknown (0x%02x)");
	if (tree != NULL)
		proto_tree_add_uint(tree, hf_pdu_type, tvb, offset, 1, type);
	offset++

	if (tree) {
		subprotocol = tvb_get_guint8(tvb, offset);
		proto_tree_add_uint(tree, hf_subprotocol tvb, offset, 1,
		    subprotocol);
		offset++;
		next_tvb = tvb_new_subset(tvb, offset, -1, -1);
		if (!dissector_try_port(dissector_table, subprotocol, next_tvb,
		    pinfo, tree))
			call_dissector(data_handle, next_tvb, pinfo, tree);
	}

it's buggy.