diff options
author | Stig Bjørlykke <stig@bjorlykke.org> | 2008-02-07 15:05:42 +0000 |
---|---|---|
committer | Stig Bjørlykke <stig@bjorlykke.org> | 2008-02-07 15:05:42 +0000 |
commit | 64d9306f2936ebc810598b918b1eef3fd4b2d0c1 (patch) | |
tree | 66526f652b7ab0b9f6672d5d4741ea74da808aa0 /epan/dissectors | |
parent | ad5e6ad06b61bc983aa6b8f6efa6dad92c871d95 (diff) |
Rewrote some "if(tree)" code inside a switch-case to avoid unused code
(which did not work as expected).
switch(type) {
case 1:
...
break;
if(tree) {
case 2:
...
break;
}
}
svn path=/trunk/; revision=24284
Diffstat (limited to 'epan/dissectors')
-rw-r--r-- | epan/dissectors/packet-cdp.c | 1241 |
1 files changed, 650 insertions, 591 deletions
diff --git a/epan/dissectors/packet-cdp.c b/epan/dissectors/packet-cdp.c index 8a24c093a5..03585a0912 100644 --- a/epan/dissectors/packet-cdp.c +++ b/epan/dissectors/packet-cdp.c @@ -122,7 +122,6 @@ static const value_string type_vals[] = { { TYPE_VTP_MGMT_DOMAIN, "VTP Management Domain" }, { TYPE_NATIVE_VLAN, "Native VLAN" }, { TYPE_DUPLEX, "Duplex" }, - { TYPE_VOIP_VLAN_REPLY, "VoIP VLAN Reply" }, { TYPE_VOIP_VLAN_QUERY, "VoIP VLAN Query" }, { TYPE_POWER, "Power consumption" }, @@ -156,8 +155,8 @@ dissect_cdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) guint16 type; guint16 length, packet_checksum, computed_checksum, data_length; gboolean checksum_good, checksum_bad; - proto_item *tlvi; - proto_tree *tlv_tree; + proto_item *tlvi = NULL; + proto_tree *tlv_tree = NULL; int real_length; guint32 naddresses; guint32 power_avail_len, power_avail; @@ -171,7 +170,7 @@ dissect_cdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) if (check_col(pinfo->cinfo, COL_INFO)) col_clear(pinfo->cinfo, COL_INFO); - if (tree){ + if (tree) { ti = proto_tree_add_item(tree, proto_cdp, tvb, offset, -1, FALSE); cdp_tree = proto_item_add_subtree(ti, ett_cdp); @@ -221,602 +220,662 @@ dissect_cdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) offset += 2; - while (tvb_reported_length_remaining(tvb, offset) != 0) { - type = tvb_get_ntohs(tvb, offset + TLV_TYPE); - length = tvb_get_ntohs(tvb, offset + TLV_LENGTH); - if (length < 4) { - if(tree) { - tlvi = proto_tree_add_text(cdp_tree, tvb, offset, 4, - "TLV with invalid length %u (< 4)", - length); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - } - offset += 4; - break; - } - - switch (type) { - - case TYPE_DEVICE_ID: - /* Device ID */ - - if(check_col(pinfo->cinfo, COL_INFO)) - col_append_fstr(pinfo->cinfo, COL_INFO, - "Device ID: %s ", - tvb_format_stringzpad(tvb, offset + 4, - length - 4)); + while (tvb_reported_length_remaining(tvb, offset) != 0) { + type = tvb_get_ntohs(tvb, offset + TLV_TYPE); + length = tvb_get_ntohs(tvb, offset + TLV_LENGTH); + if (length < 4) { + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, 4, + "TLV with invalid length %u (< 4)", + length); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + } + offset += 4; + break; + } + + switch (type) { + + case TYPE_DEVICE_ID: + /* Device ID */ + + if(check_col(pinfo->cinfo, COL_INFO)) + col_append_fstr(pinfo->cinfo, COL_INFO, + "Device ID: %s ", + tvb_format_stringzpad(tvb, offset + 4, + length - 4)); + + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, + length, "Device ID: %s", + tvb_format_stringzpad(tvb, offset + 4, length - 4)); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + length - 4, "Device ID: %s", + tvb_format_stringzpad(tvb, offset + 4, length - 4)); + } + offset += length; + break; + + case TYPE_PORT_ID: + real_length = length; + if (tvb_get_guint8(tvb, offset + real_length) != 0x00) { + /* The length in the TLV doesn't appear to be the + length of the TLV, as the byte just past it + isn't the first byte of a 2-byte big-endian + small integer; make the length of the TLV the length + in the TLV, plus 4 bytes for the TLV type and length, + minus 1 because that's what makes one capture work. */ + real_length = length + 3; + } - if(tree){ - tlvi = proto_tree_add_text(cdp_tree, tvb, offset, - length, "Device ID: %s", - tvb_format_stringzpad(tvb, offset + 4, length - 4)); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - length - 4, "Device ID: %s", - tvb_format_stringzpad(tvb, offset + 4, length - 4)); - } - offset += length; - break; - - case TYPE_PORT_ID: - real_length = length; - if (tvb_get_guint8(tvb, offset + real_length) != 0x00) { - /* The length in the TLV doesn't appear to be the - length of the TLV, as the byte just past it - isn't the first byte of a 2-byte big-endian - small integer; make the length of the TLV the length - in the TLV, plus 4 bytes for the TLV type and length, - minus 1 because that's what makes one capture work. */ - real_length = length + 3; - } - - if(check_col(pinfo->cinfo, COL_INFO)) - col_append_fstr(pinfo->cinfo, COL_INFO, - "Port ID: %s ", - tvb_format_stringzpad(tvb, offset + 4, - length - 4)); - - if(tree){ - tlvi = proto_tree_add_text(cdp_tree, tvb, offset, - real_length, "Port ID: %s", - tvb_format_text(tvb, offset + 4, real_length - 4)); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - real_length - 4, - "Sent through Interface: %s", - tvb_format_text(tvb, offset + 4, real_length - 4)); - } - offset += real_length; - break; - - if(tree){ - case TYPE_ADDRESS: - /* Addresses */ - tlvi = proto_tree_add_text(cdp_tree, tvb, offset, - length, "Addresses"); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - offset += 4; - length -= 4; - naddresses = tvb_get_ntohl(tvb, offset); - proto_tree_add_text(tlv_tree, tvb, offset, 4, - "Number of addresses: %u", naddresses); - offset += 4; - length -= 4; - while (naddresses != 0) { - addr_length = dissect_address_tlv(tvb, offset, length, - tlv_tree); - if (addr_length < 0) - break; - offset += addr_length; - length -= addr_length; - - naddresses--; - } - offset += length; - break; - - case TYPE_CAPABILITIES: - tlvi = proto_tree_add_text(cdp_tree, tvb, offset, - length, "Capabilities"); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - offset += 4; - length -= 4; - dissect_capabilities(tvb, offset, length, tlv_tree); - offset += length; - break; - - case TYPE_IOS_VERSION: - tlvi = proto_tree_add_text(cdp_tree, tvb, offset, - length, "Software Version"); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - add_multi_line_string_to_tree(tlv_tree, tvb, offset + 4, - length - 4, "Software Version: "); - offset += length; - break; - - case TYPE_PLATFORM: - /* ??? platform */ - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "Platform: %s", - tvb_format_text(tvb, offset + 4, length - 4)); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + if(check_col(pinfo->cinfo, COL_INFO)) + col_append_fstr(pinfo->cinfo, COL_INFO, + "Port ID: %s ", + tvb_format_stringzpad(tvb, offset + 4, + length - 4)); + + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, + real_length, "Port ID: %s", + tvb_format_text(tvb, offset + 4, real_length - 4)); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + real_length - 4, + "Sent through Interface: %s", + tvb_format_text(tvb, offset + 4, real_length - 4)); + } + offset += real_length; + break; + + case TYPE_ADDRESS: + /* Addresses */ + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, + length, "Addresses"); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + } + offset += 4; + length -= 4; + naddresses = tvb_get_ntohl(tvb, offset); + if (tree) { + proto_tree_add_text(tlv_tree, tvb, offset, 4, + "Number of addresses: %u", naddresses); + } + offset += 4; + length -= 4; + while (naddresses != 0) { + addr_length = dissect_address_tlv(tvb, offset, length, + tlv_tree); + if (addr_length < 0) + break; + offset += addr_length; + length -= addr_length; + + naddresses--; + } + offset += length; + break; + + case TYPE_CAPABILITIES: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, + length, "Capabilities"); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + } + offset += 4; + length -= 4; + dissect_capabilities(tvb, offset, length, tlv_tree); + offset += length; + break; + + case TYPE_IOS_VERSION: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, + length, "Software Version"); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + add_multi_line_string_to_tree(tlv_tree, tvb, offset + 4, + length - 4, "Software Version: "); + } + offset += length; + break; + + case TYPE_PLATFORM: + /* ??? platform */ + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "Platform: %s", + tvb_format_text(tvb, offset + 4, length - 4)); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + length - 4, "Platform: %s", + tvb_format_text(tvb, offset + 4, length - 4)); + } + offset += length; + break; + + case TYPE_IP_PREFIX: + if (length == 8) { + /* if length is 8 then this is default gw not prefix */ + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, + length, "ODR Default gateway: %s", + ip_to_str(tvb_get_ptr(tvb, offset+4, 4))); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - length - 4, "Platform: %s", - tvb_format_text(tvb, offset + 4, length - 4)); - offset += length; - break; - - case TYPE_IP_PREFIX: - if (length == 8) { - /* if length is 8 then this is default gw not prefix */ - tlvi = proto_tree_add_text(cdp_tree, tvb, offset, - length, "ODR Default gateway: %s", + proto_tree_add_text(tlv_tree, tvb, offset+4, 4, + "ODR Default gateway = %s", ip_to_str(tvb_get_ptr(tvb, offset+4, 4))); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset+4, 4, - "ODR Default gateway = %s", - ip_to_str(tvb_get_ptr(tvb, offset+4, 4))); - offset += 8; - } else { - tlvi = proto_tree_add_text(cdp_tree, tvb, offset, - length, "IP Prefixes: %d",length/5); - - /* the actual number of prefixes is (length-4)/5 - but if the variable is not a "float" but "integer" - then length/5=(length-4)/5 :) */ - - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - offset += 4; - length -= 4; - while (length > 0) { - proto_tree_add_text(tlv_tree, tvb, offset, 5, - "IP Prefix = %s/%u", - ip_to_str(tvb_get_ptr(tvb, offset, 4)), - tvb_get_guint8(tvb,offset+4)); - offset += 5; - length -= 5; - } - } - break; - - case TYPE_PROTOCOL_HELLO: - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset,length, "Protocol Hello: %s", - val_to_str(tvb_get_ntohs(tvb, offset+7), type_hello_vals, "Unknown (0x%04x)")); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset+4, 3, - "OUI: 0x%06X (%s)", - tvb_get_ntoh24(tvb,offset+4), - val_to_str(tvb_get_ntoh24(tvb,offset+4), oui_vals, "Unknown")); - proto_tree_add_text(tlv_tree, tvb, offset+7, 2, - "Protocol ID: 0x%04X (%s)", - tvb_get_ntohs(tvb, offset+7), - val_to_str(tvb_get_ntohs(tvb, offset+7), type_hello_vals, "Unknown")); - switch(tvb_get_ntohs(tvb, offset+7)) { - - case TYPE_HELLO_CLUSTER_MGMT: - /* proto_tree_add_text(tlv_tree, tvb, offset+9, - length - 9, "Cluster Management"); - */ - ip_addr = tvb_get_ipv4(tvb, offset+9); - proto_tree_add_text(tlv_tree, tvb, offset+9, 4, - "Cluster Master IP: %s",ip_to_str((guint8 *)&ip_addr)); - ip_addr = tvb_get_ipv4(tvb, offset+13); - proto_tree_add_text(tlv_tree, tvb, offset+13, 4, - "UNKNOWN (IP?): 0x%08X (%s)", - ip_addr, ip_to_str((guint8 *)&ip_addr)); - proto_tree_add_text(tlv_tree, tvb, offset+17, 1, - "Version?: 0x%02X", - tvb_get_guint8(tvb, offset+17)); - proto_tree_add_text(tlv_tree, tvb, offset+18, 1, - "Sub Version?: 0x%02X", - tvb_get_guint8(tvb, offset+18)); - proto_tree_add_text(tlv_tree, tvb, offset+19, 1, - "Status?: 0x%02X", - tvb_get_guint8(tvb, offset+19)); - proto_tree_add_text(tlv_tree, tvb, offset+20, 1, - "UNKNOWN: 0x%02X", - tvb_get_guint8(tvb, offset+20)); - proto_tree_add_text(tlv_tree, tvb, offset+21, 6, - "Cluster Commander MAC: %s", - ether_to_str(tvb_get_ptr(tvb, offset+21, 6))); - proto_tree_add_text(tlv_tree, tvb, offset+27, 6, - "Switch's MAC: %s", - ether_to_str(tvb_get_ptr(tvb, offset+27, 6))); - proto_tree_add_text(tlv_tree, tvb, offset+33, 1, - "UNKNOWN: 0x%02X", - tvb_get_guint8(tvb, offset+33)); - proto_tree_add_text(tlv_tree, tvb, offset+34, 2, - "Management VLAN: %d", - tvb_get_ntohs(tvb, offset+34)); - break; - default: - proto_tree_add_text(tlv_tree, tvb, offset + 9, - length - 9, "Unknown"); - break; - } - offset += length; - break; - - case TYPE_VTP_MGMT_DOMAIN: - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "VTP Management Domain: %s", - tvb_format_text(tvb, offset + 4, length - 4)); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - length - 4, "VTP Management Domain: %s", - tvb_format_text(tvb, offset + 4, length - 4)); - offset += length; - break; - - case TYPE_NATIVE_VLAN: - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "Native VLAN: %u", - tvb_get_ntohs(tvb, offset + 4)); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + } + offset += 8; + } else { + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, + length, "IP Prefixes: %d",length/5); + + /* the actual number of prefixes is (length-4)/5 + but if the variable is not a "float" but "integer" + then length/5=(length-4)/5 :) */ + + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - length - 4, "Native VLAN: %u", - tvb_get_ntohs(tvb, offset + 4)); - offset += length; - break; - - case TYPE_DUPLEX: - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "Duplex: %s", - tvb_get_guint8(tvb, offset + 4) ? - "Full" : "Half" ); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - length - 4, "Duplex: %s", - tvb_get_guint8(tvb, offset + 4) ? - "Full" : "Half" ); - offset += length; - break; - - case TYPE_VOIP_VLAN_REPLY: - if (length >= 7) { - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "VoIP VLAN Reply: %u", tvb_get_ntohs(tvb, offset + 5)); - } else { - /* - * XXX - what are these? I've seen them in some captures; - * they have a length of 6, and run up to the end of - * the packet, so if we try to dissect it the same way - * we dissect the 7-byte ones, we report a malformed - * frame. - */ - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "VoIP VLAN Reply"); - } - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - 1, "Data"); - if (length >= 7) { - proto_tree_add_text(tlv_tree, tvb, offset + 5, - 2, "Voice VLAN: %u", - tvb_get_ntohs(tvb, offset + 5)); - } - offset += length; - break; - - case TYPE_VOIP_VLAN_QUERY: - if (length >= 7) { - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "VoIP VLAN Query: %u", tvb_get_ntohs(tvb, offset + 5)); - } else { - /* - * XXX - what are these? I've seen them in some captures; - * they have a length of 6, and run up to the end of - * the packet, so if we try to dissect it the same way - * we dissect the 7-byte ones, we report a malformed - * frame. - */ - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "VoIP VLAN Query"); - } - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - 1, "Data"); - if (length >= 7) { - proto_tree_add_text(tlv_tree, tvb, offset + 5, - 2, "Voice VLAN: %u", - tvb_get_ntohs(tvb, offset + 5)); - } - offset += length; - break; - - case TYPE_POWER: - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "Power Consumption: %u mW", - tvb_get_ntohs(tvb, offset + 4)); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - length - 4, "Power Consumption: %u mW", - tvb_get_ntohs(tvb, offset + 4)); - offset += length; - break; - - case TYPE_MTU: - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "MTU: %u", - tvb_get_ntohl(tvb,offset + 4)); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - length - 4, "MTU: %u", - tvb_get_ntohl(tvb,offset + 4)); - offset += length; - break; - - case TYPE_TRUST_BITMAP: - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "Trust Bitmap: 0x%02X", - tvb_get_guint8(tvb, offset + 4)); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - length - 4, "Trust Bitmap: %02x", - tvb_get_guint8(tvb, offset + 4)); - offset += length; - break; - - case TYPE_UNTRUSTED_COS: - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "Untrusted port CoS: 0x%02X", - tvb_get_guint8(tvb, offset + 4)); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - length - 4, "Untrusted port CoS: %02x", - tvb_get_guint8(tvb, offset + 4)); - offset += length; - break; - - case TYPE_SYSTEM_NAME: - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "System Name: %s", - tvb_format_text(tvb, offset + 4, length - 4)); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - length - 4, "System Name: %s", - tvb_format_text(tvb, offset + 4, length - 4)); - offset += length; - break; - - case TYPE_SYSTEM_OID: - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "System Object Identifier"); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - length - 4, "System Object Identifier: %s", - tvb_bytes_to_str(tvb, offset + 4, length - 4)); - offset += length; - break; - - case TYPE_MANAGEMENT_ADDR: - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "Management Addresses"); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - offset += 4; - length -= 4; - naddresses = tvb_get_ntohl(tvb, offset); - proto_tree_add_text(tlv_tree, tvb, offset, 4, - "Number of addresses: %u", naddresses); - offset += 4; - length -= 4; - while (naddresses != 0) { - addr_length = dissect_address_tlv(tvb, offset, length, - tlv_tree); - if (addr_length < 0) - break; - offset += addr_length; - length -= addr_length; - - naddresses--; - } - offset += length; - break; - - case TYPE_LOCATION: - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "Location: %s", - tvb_format_text(tvb, offset + 5, length - 5)); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - 1 , "UNKNOWN: 0x%02X", - tvb_get_guint8(tvb, offset + 4)); - proto_tree_add_text(tlv_tree, tvb, offset + 5, - length - 5, "Location: %s", - tvb_format_text(tvb, offset + 5, length - 5)); - offset += length; - break; - } - - case TYPE_POWER_REQUESTED: - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "Power Request: "); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - 2, "Request-ID: %u", - tvb_get_ntohs(tvb, offset + 4)); - proto_tree_add_text(tlv_tree, tvb, offset + 6, - 2, "Management-ID: %u", - tvb_get_ntohs(tvb, offset + 6)); - power_req_len = (tvb_get_ntohs(tvb, offset + TLV_LENGTH)) - 8; - /* Move offset to where the list of Power Request Values Exist */ - offset += 8; - while(power_req_len) { - if (power_req_len > 4) { - power_req = tvb_get_ntohl(tvb, offset); - proto_tree_add_text(tlv_tree, tvb, offset, - 4, "Power Requested: %u mW", power_req); - proto_item_append_text(tlvi, "%u mW, ", power_req); - power_req_len -= 4; - offset += 4; - } else { - if (power_req_len == 4) { - power_req = tvb_get_ntohl(tvb, offset); - proto_tree_add_text(tlv_tree, tvb, offset, - 4, "Power Requested: %u mW", power_req); - proto_item_append_text(tlvi, "%u mW", power_req); - } - offset += power_req_len; - break; - } - } - break; - - case TYPE_POWER_AVAILABLE: - tlvi = proto_tree_add_text(cdp_tree, tvb, - offset, length, "Power Available: "); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, tvb, offset + 4, - 2, "Request-ID: %u", - tvb_get_ntohs(tvb, offset + 4)); - proto_tree_add_text(tlv_tree, tvb, offset + 6, - 2, "Management-ID: %u", - tvb_get_ntohs(tvb, offset + 6)); - power_avail_len = (tvb_get_ntohs(tvb, offset + TLV_LENGTH)) - 8; - /* Move offset to where the list of Power Available Values Exist */ - offset += 8; - while(power_avail_len) { - if (power_avail_len > 4) { - power_avail = tvb_get_ntohl(tvb, offset); - proto_tree_add_text(tlv_tree, tvb, offset, - 4, "Power Available: %u mW", power_avail); - proto_item_append_text(tlvi, "%u mW, ", power_avail); - power_avail_len -= 4; - offset += 4; - } else { - if (power_avail_len == 4) { - power_avail = tvb_get_ntohl(tvb, offset); - proto_tree_add_text(tlv_tree, tvb, offset, - 4, "Power Available: %u mW", power_avail); - proto_item_append_text(tlvi, "%u mW", power_avail); - } - offset += power_avail_len; - break; - } - } - break; - - default: - tlvi = proto_tree_add_text(cdp_tree, tvb, offset, - length, "Type: %s, length: %u", - val_to_str(type, type_vals, "Unknown (0x%04x)"), - length); - tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, - offset + TLV_LENGTH, 2, length); - if (length > 4) { - proto_tree_add_text(tlv_tree, tvb, offset + 4, - length - 4, "Data"); - } else - return; - offset += length; + } + offset += 4; + length -= 4; + while (length > 0) { + if (tree) { + proto_tree_add_text(tlv_tree, tvb, offset, 5, + "IP Prefix = %s/%u", + ip_to_str(tvb_get_ptr(tvb, offset, 4)), + tvb_get_guint8(tvb,offset+4)); + } + offset += 5; + length -= 5; + } + } + break; + + case TYPE_PROTOCOL_HELLO: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset,length, "Protocol Hello: %s", + val_to_str(tvb_get_ntohs(tvb, offset+7), type_hello_vals, "Unknown (0x%04x)")); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset+4, 3, + "OUI: 0x%06X (%s)", + tvb_get_ntoh24(tvb,offset+4), + val_to_str(tvb_get_ntoh24(tvb,offset+4), oui_vals, "Unknown")); + proto_tree_add_text(tlv_tree, tvb, offset+7, 2, + "Protocol ID: 0x%04X (%s)", + tvb_get_ntohs(tvb, offset+7), + val_to_str(tvb_get_ntohs(tvb, offset+7), type_hello_vals, "Unknown")); + + switch(tvb_get_ntohs(tvb, offset+7)) { + + case TYPE_HELLO_CLUSTER_MGMT: + /* proto_tree_add_text(tlv_tree, tvb, offset+9, + length - 9, "Cluster Management"); + */ + ip_addr = tvb_get_ipv4(tvb, offset+9); + proto_tree_add_text(tlv_tree, tvb, offset+9, 4, + "Cluster Master IP: %s",ip_to_str((guint8 *)&ip_addr)); + ip_addr = tvb_get_ipv4(tvb, offset+13); + proto_tree_add_text(tlv_tree, tvb, offset+13, 4, + "UNKNOWN (IP?): 0x%08X (%s)", + ip_addr, ip_to_str((guint8 *)&ip_addr)); + proto_tree_add_text(tlv_tree, tvb, offset+17, 1, + "Version?: 0x%02X", + tvb_get_guint8(tvb, offset+17)); + proto_tree_add_text(tlv_tree, tvb, offset+18, 1, + "Sub Version?: 0x%02X", + tvb_get_guint8(tvb, offset+18)); + proto_tree_add_text(tlv_tree, tvb, offset+19, 1, + "Status?: 0x%02X", + tvb_get_guint8(tvb, offset+19)); + proto_tree_add_text(tlv_tree, tvb, offset+20, 1, + "UNKNOWN: 0x%02X", + tvb_get_guint8(tvb, offset+20)); + proto_tree_add_text(tlv_tree, tvb, offset+21, 6, + "Cluster Commander MAC: %s", + ether_to_str(tvb_get_ptr(tvb, offset+21, 6))); + proto_tree_add_text(tlv_tree, tvb, offset+27, 6, + "Switch's MAC: %s", + ether_to_str(tvb_get_ptr(tvb, offset+27, 6))); + proto_tree_add_text(tlv_tree, tvb, offset+33, 1, + "UNKNOWN: 0x%02X", + tvb_get_guint8(tvb, offset+33)); + proto_tree_add_text(tlv_tree, tvb, offset+34, 2, + "Management VLAN: %d", + tvb_get_ntohs(tvb, offset+34)); + break; + default: + proto_tree_add_text(tlv_tree, tvb, offset + 9, + length - 9, "Unknown"); + break; + } + } + offset += length; + break; + + case TYPE_VTP_MGMT_DOMAIN: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "VTP Management Domain: %s", + tvb_format_text(tvb, offset + 4, length - 4)); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + length - 4, "VTP Management Domain: %s", + tvb_format_text(tvb, offset + 4, length - 4)); + } + offset += length; + break; + + case TYPE_NATIVE_VLAN: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "Native VLAN: %u", + tvb_get_ntohs(tvb, offset + 4)); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + length - 4, "Native VLAN: %u", + tvb_get_ntohs(tvb, offset + 4)); + } + offset += length; + break; + + case TYPE_DUPLEX: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "Duplex: %s", + tvb_get_guint8(tvb, offset + 4) ? + "Full" : "Half" ); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + length - 4, "Duplex: %s", + tvb_get_guint8(tvb, offset + 4) ? + "Full" : "Half" ); + } + offset += length; + break; + + case TYPE_VOIP_VLAN_REPLY: + if (tree) { + if (length >= 7) { + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, length, + "VoIP VLAN Reply: %u", tvb_get_ntohs(tvb, offset + 5)); + } else { + /* + * XXX - what are these? I've seen them in some captures; + * they have a length of 6, and run up to the end of + * the packet, so if we try to dissect it the same way + * we dissect the 7-byte ones, we report a malformed + * frame. + */ + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "VoIP VLAN Reply"); + } + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + 1, "Data"); + if (length >= 7) { + proto_tree_add_text(tlv_tree, tvb, offset + 5, + 2, "Voice VLAN: %u", + tvb_get_ntohs(tvb, offset + 5)); + } + } + offset += length; + break; + + case TYPE_VOIP_VLAN_QUERY: + if (tree) { + if (length >= 7) { + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "VoIP VLAN Query: %u", tvb_get_ntohs(tvb, offset + 5)); + } else { + /* + * XXX - what are these? I've seen them in some captures; + * they have a length of 6, and run up to the end of + * the packet, so if we try to dissect it the same way + * we dissect the 7-byte ones, we report a malformed + * frame. + */ + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "VoIP VLAN Query"); + } + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + 1, "Data"); + if (length >= 7) { + proto_tree_add_text(tlv_tree, tvb, offset + 5, + 2, "Voice VLAN: %u", + tvb_get_ntohs(tvb, offset + 5)); + } + } + offset += length; + break; + + case TYPE_POWER: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "Power Consumption: %u mW", + tvb_get_ntohs(tvb, offset + 4)); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + length - 4, "Power Consumption: %u mW", + tvb_get_ntohs(tvb, offset + 4)); + } + offset += length; + break; + + case TYPE_MTU: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "MTU: %u", + tvb_get_ntohl(tvb,offset + 4)); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + length - 4, "MTU: %u", + tvb_get_ntohl(tvb,offset + 4)); + } + offset += length; + break; + + case TYPE_TRUST_BITMAP: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "Trust Bitmap: 0x%02X", + tvb_get_guint8(tvb, offset + 4)); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + length - 4, "Trust Bitmap: %02x", + tvb_get_guint8(tvb, offset + 4)); + } + offset += length; + break; + + case TYPE_UNTRUSTED_COS: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "Untrusted port CoS: 0x%02X", + tvb_get_guint8(tvb, offset + 4)); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + length - 4, "Untrusted port CoS: %02x", + tvb_get_guint8(tvb, offset + 4)); + } + offset += length; + break; + + case TYPE_SYSTEM_NAME: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "System Name: %s", + tvb_format_text(tvb, offset + 4, length - 4)); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + length - 4, "System Name: %s", + tvb_format_text(tvb, offset + 4, length - 4)); + } + offset += length; + break; + + case TYPE_SYSTEM_OID: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "System Object Identifier"); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + length - 4, "System Object Identifier: %s", + tvb_bytes_to_str(tvb, offset + 4, length - 4)); + } + offset += length; + break; + + case TYPE_MANAGEMENT_ADDR: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "Management Addresses"); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + } + offset += 4; + length -= 4; + naddresses = tvb_get_ntohl(tvb, offset); + if (tree) { + proto_tree_add_text(tlv_tree, tvb, offset, 4, + "Number of addresses: %u", naddresses); + } + offset += 4; + length -= 4; + while (naddresses != 0) { + addr_length = dissect_address_tlv(tvb, offset, length, + tlv_tree); + if (addr_length < 0) + break; + offset += addr_length; + length -= addr_length; + + naddresses--; + } + offset += length; + break; + + case TYPE_LOCATION: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "Location: %s", + tvb_format_text(tvb, offset + 5, length - 5)); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + 1 , "UNKNOWN: 0x%02X", + tvb_get_guint8(tvb, offset + 4)); + proto_tree_add_text(tlv_tree, tvb, offset + 5, + length - 5, "Location: %s", + tvb_format_text(tvb, offset + 5, length - 5)); + } + offset += length; + break; + + case TYPE_POWER_REQUESTED: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "Power Request: "); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + 2, "Request-ID: %u", + tvb_get_ntohs(tvb, offset + 4)); + proto_tree_add_text(tlv_tree, tvb, offset + 6, + 2, "Management-ID: %u", + tvb_get_ntohs(tvb, offset + 6)); + } + power_req_len = (tvb_get_ntohs(tvb, offset + TLV_LENGTH)) - 8; + /* Move offset to where the list of Power Request Values Exist */ + offset += 8; + while(power_req_len) { + if (power_req_len > 4) { + power_req = tvb_get_ntohl(tvb, offset); + if (tree) { + proto_tree_add_text(tlv_tree, tvb, offset, + 4, "Power Requested: %u mW", power_req); + proto_item_append_text(tlvi, "%u mW, ", power_req); + } + power_req_len -= 4; + offset += 4; + } else { + if (power_req_len == 4) { + power_req = tvb_get_ntohl(tvb, offset); + if (tree) { + proto_tree_add_text(tlv_tree, tvb, offset, + 4, "Power Requested: %u mW", power_req); + proto_item_append_text(tlvi, "%u mW", power_req); + } + } + offset += power_req_len; + break; + } + } + break; + + case TYPE_POWER_AVAILABLE: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "Power Available: "); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + 2, "Request-ID: %u", + tvb_get_ntohs(tvb, offset + 4)); + proto_tree_add_text(tlv_tree, tvb, offset + 6, + 2, "Management-ID: %u", + tvb_get_ntohs(tvb, offset + 6)); + } + power_avail_len = (tvb_get_ntohs(tvb, offset + TLV_LENGTH)) - 8; + /* Move offset to where the list of Power Available Values Exist */ + offset += 8; + while(power_avail_len) { + if (power_avail_len > 4) { + power_avail = tvb_get_ntohl(tvb, offset); + if (tree) { + proto_tree_add_text(tlv_tree, tvb, offset, + 4, "Power Available: %u mW", power_avail); + proto_item_append_text(tlvi, "%u mW, ", power_avail); + } + power_avail_len -= 4; + offset += 4; + } else { + if (power_avail_len == 4) { + power_avail = tvb_get_ntohl(tvb, offset); + if (tree) { + proto_tree_add_text(tlv_tree, tvb, offset, + 4, "Power Available: %u mW", power_avail); + proto_item_append_text(tlvi, "%u mW", power_avail); + } } + offset += power_avail_len; + break; + } } + break; + + default: + if (tree) { + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, + length, "Type: %s, length: %u", + val_to_str(type, type_vals, "Unknown (0x%04x)"), + length); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + if (length > 4) { + proto_tree_add_text(tlv_tree, tvb, offset + 4, + length - 4, "Data"); + } else { + return; + } + } + offset += length; + } + } call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1), pinfo, - cdp_tree); + cdp_tree); } #define PROTO_TYPE_NLPID 1 |