Wireshark-dev: Re: [Wireshark-dev] [Patch] CDP dissector (revised)
From: Stephen Fisher <stephentfisher@xxxxxxxxx>
Date: Fri, 23 Jun 2006 16:29:40 -0700
Sorry, here is the revised patch that I forgot to attach :)
Index: epan/dissectors/packet-cdp.c =================================================================== --- epan/dissectors/packet-cdp.c (revision 18564) +++ epan/dissectors/packet-cdp.c (working copy) @@ -167,69 +167,56 @@ offset += 1; proto_tree_add_item(cdp_tree, hf_cdp_checksum, tvb, offset, 2, FALSE); offset += 2; + } + else + { + offset += 4; /* The version/ttl/checksum fields from above */ + } 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) { - 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; + 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 */ - 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_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; + 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)); - naddresses--; - } - offset += length; - break; + 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; @@ -242,6 +229,14 @@ 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)); @@ -254,402 +249,450 @@ real_length - 4, "Sent through Interface: %s", tvb_format_text(tvb, offset + 4, real_length - 4)); + } offset += real_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; + 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_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_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_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, - 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 */ + case TYPE_IOS_VERSION: tlvi = proto_tree_add_text(cdp_tree, tvb, offset, - length, "ODR Default gateway: %s", - ip_to_str(tvb_get_ptr(tvb, offset+4, 4))); + 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); + 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", + 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, + 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 */ + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, + length, "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); + 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 :) */ + /* 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); + 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 + 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: - 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) + 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 + 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: + 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; - 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; - 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; + + 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; + } + + 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; } } - call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1), pinfo, + call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1), pinfo, cdp_tree); - } } #define PROTO_TYPE_NLPID 1
- References:
- Re: [Wireshark-dev] [Patch] CDP dissector
- From: Stephen Fisher
- Re: [Wireshark-dev] [Patch] CDP dissector
- From: Jaap Keuter
- Re: [Wireshark-dev] [Patch] CDP dissector (revised)
- From: Stephen Fisher
- Re: [Wireshark-dev] [Patch] CDP dissector
- Prev by Date: Re: [Wireshark-dev] [Patch] CDP dissector (revised)
- Next by Date: [Wireshark-dev] difference between windows and linux behavior
- Previous by thread: Re: [Wireshark-dev] [Patch] CDP dissector (revised)
- Next by thread: [Wireshark-dev] Question about the 0.99.1pre1 Release
- Index(es):