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); }