X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/0e884cd210eca747172b4b0ce03d4d5b446ff4be..5663cdab5ec8730ade9938c1ace64a4859d9ef7b:/print-vtp.c diff --git a/print-vtp.c b/print-vtp.c index 6f3c18ba..cbc5868e 100644 --- a/print-vtp.c +++ b/print-vtp.c @@ -15,8 +15,9 @@ * VLAN TRUNKING PROTOCOL (VTP) * * Reference documentation: - * http://www.cisco.com/en/US/tech/tk389/tk689/technologies_tech_note09186a0080094c52.shtml - * http://www.cisco.com/warp/public/473/21.html + * http://www.cisco.com/en/US/tech/tk389/tk689/technologies_tech_note09186a0080094c52.shtml + * http://www.cisco.com/warp/public/473/21.html + * http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm * * Original code ode by Carles Kishimoto */ @@ -32,7 +33,7 @@ #include "interface.h" #include "addrtoname.h" -#include "extract.h" +#include "extract.h" #include "nlpid.h" #define VTP_HEADER_LEN 36 @@ -56,7 +57,7 @@ struct vtp_vlan_ { u_int32_t index; }; -static struct tok vtp_message_type_values[] = { +static const struct tok vtp_message_type_values[] = { { VTP_SUMMARY_ADV, "Summary advertisement"}, { VTP_SUBSET_ADV, "Subset advertisement"}, { VTP_ADV_REQUEST, "Advertisement request"}, @@ -64,7 +65,7 @@ static struct tok vtp_message_type_values[] = { { 0, NULL } }; -static struct tok vtp_header_values[] = { +static const struct tok vtp_header_values[] = { { 0x01, "Followers"}, /* On Summary advertisement, 3rd byte is Followers */ { 0x02, "Seq number"}, /* On Subset advertisement, 3rd byte is Sequence number */ { 0x03, "Rsvd"}, /* On Adver. requests 3rd byte is Rsvd */ @@ -72,7 +73,7 @@ static struct tok vtp_header_values[] = { { 0, NULL } }; -static struct tok vtp_vlan_type_values[] = { +static const struct tok vtp_vlan_type_values[] = { { 0x01, "Ethernet"}, { 0x02, "FDDI"}, { 0x03, "TrCRF"}, @@ -81,30 +82,62 @@ static struct tok vtp_vlan_type_values[] = { { 0, NULL } }; -static struct tok vtp_vlan_status[] = { +static const struct tok vtp_vlan_status[] = { { 0x00, "Operational"}, { 0x01, "Suspended"}, { 0, NULL } }; +#define VTP_VLAN_SOURCE_ROUTING_RING_NUMBER 0x01 +#define VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER 0x02 +#define VTP_VLAN_STP_TYPE 0x03 +#define VTP_VLAN_PARENT_VLAN 0x04 +#define VTP_VLAN_TRANS_BRIDGED_VLAN 0x05 +#define VTP_VLAN_PRUNING 0x06 +#define VTP_VLAN_BRIDGE_TYPE 0x07 +#define VTP_VLAN_ARP_HOP_COUNT 0x08 +#define VTP_VLAN_STE_HOP_COUNT 0x09 +#define VTP_VLAN_BACKUP_CRF_MODE 0x0A + +static const struct tok vtp_vlan_tlv_values[] = { + { VTP_VLAN_SOURCE_ROUTING_RING_NUMBER, "Source-Routing Ring Number TLV"}, + { VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER, "Source-Routing Bridge Number TLV"}, + { VTP_VLAN_STP_TYPE, "STP type TLV"}, + { VTP_VLAN_PARENT_VLAN, "Parent VLAN TLV"}, + { VTP_VLAN_TRANS_BRIDGED_VLAN, "Translationally bridged VLANs TLV"}, + { VTP_VLAN_PRUNING, "Pruning TLV"}, + { VTP_VLAN_BRIDGE_TYPE, "Bridge Type TLV"}, + { VTP_VLAN_ARP_HOP_COUNT, "Max ARP Hop Count TLV"}, + { VTP_VLAN_STE_HOP_COUNT, "Max STE Hop Count TLV"}, + { VTP_VLAN_BACKUP_CRF_MODE, "Backup CRF Mode TLV"}, + { 0, NULL } +}; + +static const struct tok vtp_stp_type_values[] = { + { 1, "SRT"}, + { 2, "SRB"}, + { 3, "Auto"}, + { 0, NULL } +}; + void vtp_print (const u_char *pptr, u_int length) { - int type, len; + int type, len, tlv_len, tlv_value; const u_char *tptr; const struct vtp_vlan_ *vtp_vlan; if (length < VTP_HEADER_LEN) goto trunc; - tptr = pptr; + tptr = pptr; - if (!TTEST2(*tptr, VTP_HEADER_LEN)) + if (!TTEST2(*tptr, VTP_HEADER_LEN)) goto trunc; type = *(tptr+1); printf("VTPv%u, Message %s (0x%02x), length %u", - *tptr, + *tptr, tok2str(vtp_message_type_values,"Unknown message type", type), *(tptr+1), length); @@ -115,7 +148,7 @@ vtp_print (const u_char *pptr, u_int length) } /* verbose mode print all fields */ - printf("\n\tDomain name: %s, Flags [%s] %u", + printf("\n\tDomain name: %s, %s: %u", (tptr+4), tok2str(vtp_header_values,"Unknown",*(tptr+1)), *(tptr+2)); @@ -143,13 +176,13 @@ vtp_print (const u_char *pptr, u_int length) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | MD5 digest (16 bytes) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * + * */ printf("\n\t Config Rev %x, Updater %s", EXTRACT_32BITS(tptr), ipaddr_string(tptr+4)); - tptr += 8; + tptr += 8; printf(", Timestamp 0x%08x 0x%08x 0x%08x", EXTRACT_32BITS(tptr), EXTRACT_32BITS(tptr + 4), @@ -182,12 +215,12 @@ vtp_print (const u_char *pptr, u_int length) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | VLAN info field N | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * + * */ printf(", Config Rev %x", EXTRACT_32BITS(tptr)); - /* + /* * VLAN INFORMATION * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -220,14 +253,86 @@ vtp_print (const u_char *pptr, u_int length) EXTRACT_16BITS(&vtp_vlan->mtu), EXTRACT_32BITS(&vtp_vlan->index), (tptr + VTP_VLAN_INFO_OFFSET)); - tptr += len; - - /* FIXME: TLV dissector missing */ - - /* The following URL: - http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm - talks about type (2 bytes) and length (2 bytes), that is not true... - */ + + /* + * Vlan names are aligned to 32-bit boundaries. + */ + len -= VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4); + tptr += VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4); + + /* TLV information follows */ + + while (len > 0) { + + /* + * Cisco specs says 2 bytes for type + 2 bytes for length, take only 1 + * See: http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm + */ + type = *tptr; + tlv_len = *(tptr+1); + + printf("\n\t\t%s (0x%04x) TLV", + tok2str(vtp_vlan_tlv_values, "Unknown", type), + type); + + /* + * infinite loop check + */ + if (type == 0 || tlv_len == 0) { + return; + } + + if (!TTEST2(*tptr, tlv_len*2 +2)) + goto trunc; + + tlv_value = EXTRACT_16BITS(tptr+2); + + switch (type) { + case VTP_VLAN_STE_HOP_COUNT: + printf(", %u", tlv_value); + break; + + case VTP_VLAN_PRUNING: + printf(", %s (%u)", + tlv_value == 1 ? "Enabled" : "Disabled", + tlv_value); + break; + + case VTP_VLAN_STP_TYPE: + printf(", %s (%u)", + tok2str(vtp_stp_type_values, "Unknown", tlv_value), + tlv_value); + break; + + case VTP_VLAN_BRIDGE_TYPE: + printf(", %s (%u)", + tlv_value == 1 ? "SRB" : "SRT", + tlv_value); + break; + + case VTP_VLAN_BACKUP_CRF_MODE: + printf(", %s (%u)", + tlv_value == 1 ? "Backup" : "Not backup", + tlv_value); + break; + + /* + * FIXME those are the defined TLVs that lack a decoder + * you are welcome to contribute code ;-) + */ + + case VTP_VLAN_SOURCE_ROUTING_RING_NUMBER: + case VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER: + case VTP_VLAN_PARENT_VLAN: + case VTP_VLAN_TRANS_BRIDGED_VLAN: + case VTP_VLAN_ARP_HOP_COUNT: + default: + print_unknown_data(gndo,tptr, "\n\t\t ", 2 + tlv_len*2); + break; + } + len -= 2 + tlv_len*2; + tptr += 2 + tlv_len*2; + } } break;