static void dissect_vtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *vtp_tree = NULL, *vtp_pruning_tree = NULL; int offset = 0; guint8 code; guint8 *upd_timestamp; int vlan_info_len; int pruning_vlan_id; col_set_str(pinfo->cinfo, COL_PROTOCOL, "VTP"); set_vtp_info_col(tvb, pinfo); ti = proto_tree_add_item(tree, proto_vtp, tvb, offset, -1, ENC_NA); vtp_tree = proto_item_add_subtree(ti, ett_vtp); proto_tree_add_item(vtp_tree, hf_vtp_version, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; code = tvb_get_guint8(tvb, offset); proto_tree_add_item(vtp_tree, hf_vtp_code, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; switch (code) { case SUMMARY_ADVERT: proto_tree_add_item(vtp_tree, hf_vtp_followers, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(vtp_tree, hf_vtp_md_len, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(vtp_tree, hf_vtp_md, tvb, offset, 32, ENC_ASCII|ENC_NA); offset += 32; proto_tree_add_item(vtp_tree, hf_vtp_conf_rev_num, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(vtp_tree, hf_vtp_upd_id, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; upd_timestamp = tvb_get_ephemeral_string(tvb, offset, 12); proto_tree_add_string_format(vtp_tree, hf_vtp_upd_ts, tvb, offset, 12, (gchar*)upd_timestamp, "Update Timestamp: %.2s-%.2s-%.2s %.2s:%.2s:%.2s", &upd_timestamp[0], &upd_timestamp[2], &upd_timestamp[4], &upd_timestamp[6], &upd_timestamp[8], &upd_timestamp[10]); offset += 12; proto_tree_add_item(vtp_tree, hf_vtp_md5_digest, tvb, offset, 16, ENC_NA); break; case SUBSET_ADVERT: proto_tree_add_item(vtp_tree, hf_vtp_seq_num, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(vtp_tree, hf_vtp_md_len, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(vtp_tree, hf_vtp_md, tvb, offset, 32, ENC_ASCII|ENC_NA); offset += 32; proto_tree_add_item(vtp_tree, hf_vtp_conf_rev_num, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; while (tvb_reported_length_remaining(tvb, offset) > 0) { vlan_info_len = dissect_vlan_info(tvb, pinfo, offset, vtp_tree); if (vlan_info_len <= 0) break; offset += vlan_info_len; } break; case ADVERT_REQUEST: offset += 1; /* skip reserved field */ proto_tree_add_item(vtp_tree, hf_vtp_md_len, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(vtp_tree, hf_vtp_md, tvb, offset, 32, ENC_ASCII|ENC_NA); offset += 32; proto_tree_add_item(vtp_tree, hf_vtp_start_value, tvb, offset, 2, ENC_BIG_ENDIAN); break; case JOIN_MSG: offset += 1; /* skip reserved/unused field */ proto_tree_add_item(vtp_tree, hf_vtp_md_len, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(vtp_tree, hf_vtp_md, tvb, offset, 32, ENC_ASCII|ENC_NA); offset += 32; proto_tree_add_item(vtp_tree, hf_vtp_pruning_first_vid, tvb, offset, 2, ENC_BIG_ENDIAN); pruning_vlan_id = tvb_get_ntohs(tvb, offset); offset += 2; proto_tree_add_item(vtp_tree, hf_vtp_pruning_last_vid, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; ti = proto_tree_add_text (vtp_tree, tvb, offset, -1, "Advertised active (i.e. not pruned) VLANs"); vtp_pruning_tree = proto_item_add_subtree(ti, ett_vtp_pruning); while (tvb_reported_length_remaining(tvb, offset) > 0) { guint8 vlan_usage_bitmap; int shift; vlan_usage_bitmap = tvb_get_guint8(tvb, offset); for (shift = 0; shift < 8; shift++) { if (vlan_usage_bitmap & (1<<7)) { proto_tree_add_uint(vtp_pruning_tree, hf_vtp_pruning_active_vid, tvb, offset, 1, pruning_vlan_id); } pruning_vlan_id += 1; vlan_usage_bitmap <<= 1; } offset += 1; } break; } }
static void dissect_vtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *vtp_tree = NULL; int offset = 0; guint8 code; guint8 md_len; const guint8 *upd_timestamp; int vlan_info_len; col_set_str(pinfo->cinfo, COL_PROTOCOL, "VTP"); col_set_str(pinfo->cinfo, COL_INFO, "Virtual Trunking Protocol"); if (tree) { ti = proto_tree_add_item(tree, proto_vtp, tvb, offset, -1, FALSE); vtp_tree = proto_item_add_subtree(ti, ett_vtp); proto_tree_add_item(vtp_tree, hf_vtp_version, tvb, offset, 1, FALSE); offset += 1; code = tvb_get_guint8(tvb, offset); proto_tree_add_uint(vtp_tree, hf_vtp_code, tvb, offset, 1, code); offset += 1; switch (code) { case SUMMARY_ADVERT: proto_tree_add_item(vtp_tree, hf_vtp_followers, tvb, offset, 1, FALSE); offset += 1; md_len = tvb_get_guint8(tvb, offset); proto_tree_add_uint(vtp_tree, hf_vtp_md_len, tvb, offset, 1, md_len); offset += 1; proto_tree_add_item(vtp_tree, hf_vtp_md, tvb, offset, 32, FALSE); offset += 32; proto_tree_add_item(vtp_tree, hf_vtp_conf_rev_num, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(vtp_tree, hf_vtp_upd_id, tvb, offset, 4, FALSE); offset += 4; upd_timestamp = tvb_get_ptr(tvb, offset, 12); proto_tree_add_string_format(vtp_tree, hf_vtp_upd_ts, tvb, offset, 12, (gchar*)upd_timestamp, "Update Timestamp: %.2s-%.2s-%.2s %.2s:%.2s:%.2s", &upd_timestamp[0], &upd_timestamp[2], &upd_timestamp[4], &upd_timestamp[6], &upd_timestamp[8], &upd_timestamp[10]); offset += 12; proto_tree_add_item(vtp_tree, hf_vtp_md5_digest, tvb, offset, 16, FALSE); break; case SUBSET_ADVERT: proto_tree_add_item(vtp_tree, hf_vtp_seq_num, tvb, offset, 1, FALSE); offset += 1; md_len = tvb_get_guint8(tvb, offset); proto_tree_add_uint(vtp_tree, hf_vtp_md_len, tvb, offset, 1, md_len); offset += 1; proto_tree_add_item(vtp_tree, hf_vtp_md, tvb, offset, 32, FALSE); offset += 32; proto_tree_add_item(vtp_tree, hf_vtp_conf_rev_num, tvb, offset, 4, FALSE); offset += 4; while (tvb_reported_length_remaining(tvb, offset) > 0) { vlan_info_len = dissect_vlan_info(tvb, offset, vtp_tree); if (vlan_info_len < 0) break; offset += vlan_info_len; } break; case ADVERT_REQUEST: offset += 1; /* skip reserved field */ md_len = tvb_get_guint8(tvb, offset); proto_tree_add_uint(vtp_tree, hf_vtp_md_len, tvb, offset, 1, md_len); offset += 1; proto_tree_add_item(vtp_tree, hf_vtp_start_value, tvb, offset, 2, FALSE); break; case 0x04: /* * Mysterious type, seen a lot. * Is this some mutant variant of Advert-Request? */ offset += 1; /* skip unknown field */ md_len = tvb_get_guint8(tvb, offset); proto_tree_add_uint(vtp_tree, hf_vtp_md_len, tvb, offset, 1, md_len); offset += 1; proto_tree_add_item(vtp_tree, hf_vtp_md, tvb, offset, 32, FALSE); offset += 32; offset += 2; /* skip unknown field */ proto_tree_add_text(vtp_tree, tvb, offset, 2, "VLAN ID of some sort: 0x%04x", tvb_get_ntohs(tvb, offset)); offset += 2; break; } } }