Example #1
0
static void
dissect_tzsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree *tzsp_tree = NULL;
	proto_item *ti = NULL;
	int pos = 0;
	tvbuff_t *next_tvb;
	guint16 encapsulation = 0;
	int wtap_encap;
	dissector_handle_t encap_dissector;
	const char *encap_name;
	const char *info;
	guint8 type;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "TZSP");
	col_clear(pinfo->cinfo, COL_INFO);

	type = tvb_get_guint8(tvb, 1);

	/* Find the dissector. */
	encapsulation = tvb_get_ntohs(tvb, 2);
	if (encapsulation != 0) {
		wtap_encap = tzsp_encap_to_wtap_encap(encapsulation);
		if (wtap_encap != -1 &&
		    (encap_dissector = dissector_get_port_handle(encap_dissector_table, wtap_encap))) {
			encap_name = dissector_handle_get_short_name(encap_dissector);
		}
		else {
			encap_name = "Unknown";
		}
		info = encap_name;
	}
	else {
		wtap_encap = -1;
		encap_name = "Nothing";
		info = val_to_str(type, tzsp_type, "Unknown (%u)");
	}

	col_add_str(pinfo->cinfo, COL_INFO, info);

	if (tree) {
		/* Adding TZSP item and subtree */
		ti = proto_tree_add_protocol_format(tree, proto_tzsp, tvb, 0,
		    -1, "TZSP: %s: ", info);
		tzsp_tree = proto_item_add_subtree(ti, ett_tzsp);

		proto_tree_add_item (tzsp_tree, hf_tzsp_version, tvb, 0, 1,
					FALSE);
		proto_tree_add_uint (tzsp_tree, hf_tzsp_type, tvb, 1, 1,
					type);
		proto_tree_add_uint_format (tzsp_tree, hf_tzsp_encap, tvb, 2, 2,
					encapsulation, "Encapsulates: %s (%d)",
					encap_name, encapsulation);
	}

	if (type != 4 && type != 5) {
		pos = add_option_info(tvb, 4, tzsp_tree, ti);

		if (tree)
			proto_item_set_end(ti, tvb, pos);
		next_tvb = tvb_new_subset_remaining(tvb, pos);
		if (encapsulation != 0
		    && (wtap_encap == -1
			|| !dissector_try_port(encap_dissector_table, wtap_encap,
				next_tvb, pinfo, tree))) {

			col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
			if (check_col(pinfo->cinfo, COL_INFO))
				col_add_fstr(pinfo->cinfo, COL_INFO, "TZSP_ENCAP = %u",
				    encapsulation);
			call_dissector(data_handle, next_tvb, pinfo, tree);
		}
	}
}
static void
dissect_interlink(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	int		offset = 0;
	proto_tree	*il_tree = NULL;
	proto_tree	*ilh_tree = NULL;
	proto_tree	*ilb_tree = NULL;
	guint8		ilb_type;
	guint8		ilb_version;
	guint16		type_version = 0;
	dissector_handle_t	handle;
	tvbuff_t	*next_tvb;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "INTERLINK");
	col_clear(pinfo->cinfo, COL_INFO);

	if (tree) {
		proto_item	*il_item;
		il_item = proto_tree_add_item(tree, proto_interlink,
								tvb, 0, 16, FALSE);
		if (il_item)
			il_tree = proto_item_add_subtree(il_item, ett_interlink);
	}

	if (il_tree) {
		proto_item	*ilh_item = NULL;
		ilh_item = proto_tree_add_text(il_tree, tvb, 0, 12, "Interlink Header");
		if (ilh_item)
			ilh_tree = proto_item_add_subtree(ilh_item, ett_interlink_header);
	}

	if (ilh_tree) {
		proto_tree_add_item(ilh_tree, hf_interlink_id, tvb, offset, 4, FALSE);
		offset += 4;
		proto_tree_add_item(ilh_tree, hf_interlink_version, tvb, offset, 2, TRUE);
		offset += 2;
		proto_tree_add_item(ilh_tree, hf_interlink_cmd, tvb, offset, 2, TRUE);
		offset += 2;
		proto_tree_add_item(ilh_tree, hf_interlink_seq, tvb, offset, 2, TRUE);
		offset += 2;
	} else {
		offset += 10;
	}

	if (ilh_tree) {
		proto_item	*flags_item;
		proto_tree	*flags_tree = NULL;

		flags_item = proto_tree_add_item(ilh_tree, hf_interlink_flags,
			tvb, offset, 2, TRUE);
		if (flags_item) {
			flags_tree = proto_item_add_subtree(flags_item, ett_interlink_flags);
		}
		if (flags_tree) {
			guint16		il_flags;
			il_flags = tvb_get_letohs(tvb, offset);
			proto_tree_add_boolean(flags_tree, hf_interlink_flags_req_ack, tvb, offset, 2, il_flags);
			proto_tree_add_boolean(flags_tree, hf_interlink_flags_inc_ack_port, tvb, offset, 2, il_flags);
		}
	}
	offset += 2;

	if (tree) {
		proto_item	*ilb_item;
		ilb_item = proto_tree_add_text(il_tree, tvb, offset, 4, "Block Header");
		if (ilb_item)
			ilb_tree = proto_item_add_subtree(ilb_item, ett_interlink_block);
	}

	ilb_type = tvb_get_guint8(tvb, offset);
	ilb_version = tvb_get_guint8(tvb, offset + 1);
	type_version = ilb_type << 8 | ilb_version;
	col_append_fstr(pinfo->cinfo, COL_INFO, "Type: 0x%02x, Version: %d",
		ilb_type, ilb_version);

	if (ilb_tree) {
		proto_tree_add_item(ilb_tree, hf_interlink_block_type, tvb, offset, 1, FALSE);
		offset += 1;
		proto_tree_add_item(ilb_tree, hf_interlink_block_version, tvb, offset, 1, FALSE);
		offset += 1;
		proto_tree_add_item(ilb_tree, hf_interlink_block_length, tvb, offset, 2, TRUE);
		offset += 2;
	} else {
		offset += 4;
	}

	/* Generate a new tvb for the rest. */
	next_tvb = tvb_new_subset_remaining(tvb, offset);

	/* Probably a sub-dissector exists for this type/version combination. */
	handle = dissector_get_port_handle(subdissector_table, type_version);

	/* Without a proper sub-dissector, we use "data". */
	if (handle == NULL) handle = data_handle;

	/* Call the sub-dissector. */
	call_dissector(handle, next_tvb, pinfo, tree);
}