--- /dev/null
+/*
+ * Copyright (c) 1998-2007 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * 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
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+#include "nlpid.h"
+
+#define VTP_HEADER_LEN 36
+#define VTP_DOMAIN_NAME_LEN 32
+#define VTP_MD5_DIGEST_LEN 16
+#define VTP_UPDATE_TIMESTAMP_LEN 12
+#define VTP_VLAN_INFO_OFFSET 12
+
+#define VTP_SUMMARY_ADV 0x01
+#define VTP_SUBSET_ADV 0x02
+#define VTP_ADV_REQUEST 0x03
+#define VTP_JOIN_MESSAGE 0x04
+
+struct vtp_vlan_ {
+ u_int8_t len;
+ u_int8_t status;
+ u_int8_t type;
+ u_int8_t name_len;
+ u_int16_t vlanid;
+ u_int16_t mtu;
+ u_int32_t index;
+};
+
+static struct tok vtp_message_type_values[] = {
+ { VTP_SUMMARY_ADV, "Summary advertisement"},
+ { VTP_SUBSET_ADV, "Subset advertisement"},
+ { VTP_ADV_REQUEST, "Advertisement request"},
+ { VTP_JOIN_MESSAGE, "Join message"},
+ { 0, NULL }
+};
+
+static 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 */
+ { 0x04, "Rsvd"}, /* On Adver. requests 3rd byte is Rsvd */
+ { 0, NULL }
+};
+
+static struct tok vtp_stp_type_values[] = {
+ { 1, "SRT"},
+ { 2, "SRB"},
+ { 3, "Auto"},
+ { 0, NULL }
+};
+
+static struct tok vtp_vlan_type_values[] = {
+ { 0x01, "Ethernet"},
+ { 0x02, "FDDI"},
+ { 0x03, "TrCRF"},
+ { 0x04, "FDDI-net"},
+ { 0x05, "TrBRF"},
+ { 0, NULL }
+};
+
+static struct tok vtp_vlan_status[] = {
+ { 0x00, "Operational"},
+ { 0x01, "Suspended"},
+ { 0, NULL }
+};
+
+void
+vtp_print (const u_char *pptr, u_int length)
+{
+ int type, len, tlv_len;
+ const u_char *tptr;
+ const struct vtp_vlan_ *vtp_vlan;
+
+ if (length < VTP_HEADER_LEN)
+ goto trunc;
+
+ tptr = pptr;
+
+ if (!TTEST2(*tptr, VTP_HEADER_LEN))
+ goto trunc;
+
+ type = *(tptr+1);
+ printf("VTPv%u, Message %s (0x%02x), length %u",
+ *tptr,
+ tok2str(vtp_message_type_values,"Unknown message type", type),
+ *(tptr+1),
+ length);
+
+ /* In non-verbose mode, just print version and message type */
+ if (vflag < 1) {
+ return;
+ }
+
+ /* verbose mode print all fields */
+ printf("\n\tDomain name: %s, Flags [%s] %u",
+ (tptr+4),
+ tok2str(vtp_header_values,"Unknown",*(tptr+1)),
+ *(tptr+2));
+
+ tptr += VTP_HEADER_LEN;
+
+ switch (type) {
+
+ case VTP_SUMMARY_ADV:
+
+ /*
+ * SUMMARY ADVERTISEMENT
+ *
+ * 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Version | Code | Followers | MmgtD Len |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Management Domain Name |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Configuration revision number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Updater Identity IP address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Update Timestamp (12 bytes) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | MD5 digest (16 bytes) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+ printf("\n\t Config Rev %x, Updater %s",
+ EXTRACT_32BITS(tptr),
+ ipaddr_string(tptr+4));
+ tptr += 8;
+ printf(", Timestamp 0x%08x 0x%08x 0x%08x",
+ EXTRACT_32BITS(tptr),
+ EXTRACT_32BITS(tptr + 4),
+ EXTRACT_32BITS(tptr + 8));
+ tptr += VTP_UPDATE_TIMESTAMP_LEN;
+ printf(", MD5 digest: %08x%08x%08x%08x",
+ EXTRACT_32BITS(tptr),
+ EXTRACT_32BITS(tptr + 4),
+ EXTRACT_32BITS(tptr + 8),
+ EXTRACT_32BITS(tptr + 12));
+ tptr += VTP_MD5_DIGEST_LEN;
+ break;
+
+ case VTP_SUBSET_ADV:
+
+ /*
+ * SUBSET ADVERTISEMENT
+ *
+ * 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Version | Code | Seq number | MmgtD Len |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Management Domain Name |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Configuration revision number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | VLAN info field 1 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | ................ |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | V info len | Status | VLAN type | VLAN name len |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | ISL vlan id | MTU size |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | 802.10 index (SAID) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | VLAN name |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+ tptr += 4;
+ while (tptr < (pptr+length)) {
+
+ len = *tptr;
+ if (len == 0)
+ break;
+
+ if (!TTEST2(*tptr, len))
+ goto trunc;
+
+ vtp_vlan = (struct vtp_vlan_*)tptr;
+ printf("\n\tVLAN info status %s, type %s, VLAN-id %u, MTU %u, SAID 0x%08x, Name %s",
+ tok2str(vtp_vlan_status,"Unknown",vtp_vlan->status),
+ tok2str(vtp_vlan_type_values,"Unknown",vtp_vlan->type),
+ EXTRACT_16BITS(&vtp_vlan->vlanid),
+ 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...
+ */
+ }
+ break;
+
+ case VTP_ADV_REQUEST:
+
+ /*
+ * ADVERTISEMENT REQUEST
+ *
+ * 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Version | Code | Reserved | MmgtD Len |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Management Domain Name |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Start value |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+ printf("\n\tStart value: %u", EXTRACT_32BITS(tptr));
+ break;
+
+ case VTP_JOIN_MESSAGE:
+
+ /* FIXME - Could not find message format */
+ break;
+
+ default:
+ break;
+ }
+
+ return;
+
+ trunc:
+ printf("[|vtp]");
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 4
+ * End:
+ */