xref: /dflybsd-src/contrib/tcpdump/print-vtp.c (revision 59c07fbdf8168fa08c76c515186d561b5a92690c)
1ea7b4bf5SPeter Avalos /*
2ea7b4bf5SPeter Avalos  * Copyright (c) 1998-2007 The TCPDUMP project
3ea7b4bf5SPeter Avalos  *
4ea7b4bf5SPeter Avalos  * Redistribution and use in source and binary forms, with or without
5ea7b4bf5SPeter Avalos  * modification, are permitted provided that: (1) source code
6ea7b4bf5SPeter Avalos  * distributions retain the above copyright notice and this paragraph
7ea7b4bf5SPeter Avalos  * in its entirety, and (2) distributions including binary code include
8ea7b4bf5SPeter Avalos  * the above copyright notice and this paragraph in its entirety in
9ea7b4bf5SPeter Avalos  * the documentation or other materials provided with the distribution.
10ea7b4bf5SPeter Avalos  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
11ea7b4bf5SPeter Avalos  * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
12ea7b4bf5SPeter Avalos  * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13ea7b4bf5SPeter Avalos  * FOR A PARTICULAR PURPOSE.
14ea7b4bf5SPeter Avalos  *
15ea7b4bf5SPeter Avalos  * Reference documentation:
16*ed775ee7SAntonio Huete Jimenez  *  https://www.cisco.com/c/en/us/support/docs/lan-switching/vtp/10558-21.html
17*ed775ee7SAntonio Huete Jimenez  *  https://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm
18ea7b4bf5SPeter Avalos  *
19ea7b4bf5SPeter Avalos  * Original code ode by Carles Kishimoto <carles.kishimoto@gmail.com>
20ea7b4bf5SPeter Avalos  */
21ea7b4bf5SPeter Avalos 
22411677aeSAaron LI /* \summary: Cisco VLAN Trunking Protocol (VTP) printer */
23411677aeSAaron LI 
24ea7b4bf5SPeter Avalos #ifdef HAVE_CONFIG_H
25*ed775ee7SAntonio Huete Jimenez #include <config.h>
26ea7b4bf5SPeter Avalos #endif
27ea7b4bf5SPeter Avalos 
28*ed775ee7SAntonio Huete Jimenez #include "netdissect-stdinc.h"
29ea7b4bf5SPeter Avalos 
30*ed775ee7SAntonio Huete Jimenez #define ND_LONGJMP_FROM_TCHECK
31411677aeSAaron LI #include "netdissect.h"
32ea7b4bf5SPeter Avalos #include "addrtoname.h"
33ea7b4bf5SPeter Avalos #include "extract.h"
34ea7b4bf5SPeter Avalos 
35ea7b4bf5SPeter Avalos #define VTP_HEADER_LEN			36
36ea7b4bf5SPeter Avalos #define	VTP_DOMAIN_NAME_LEN		32
37ea7b4bf5SPeter Avalos #define	VTP_MD5_DIGEST_LEN		16
38ea7b4bf5SPeter Avalos #define VTP_UPDATE_TIMESTAMP_LEN	12
39411677aeSAaron LI #define VTP_VLAN_INFO_FIXED_PART_LEN	12	/* length of VLAN info before VLAN name */
40ea7b4bf5SPeter Avalos 
41ea7b4bf5SPeter Avalos #define VTP_SUMMARY_ADV			0x01
42ea7b4bf5SPeter Avalos #define VTP_SUBSET_ADV			0x02
43ea7b4bf5SPeter Avalos #define VTP_ADV_REQUEST			0x03
44ea7b4bf5SPeter Avalos #define VTP_JOIN_MESSAGE		0x04
45ea7b4bf5SPeter Avalos 
46ea7b4bf5SPeter Avalos struct vtp_vlan_ {
47*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  len;
48*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  status;
49*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  type;
50*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  name_len;
51*ed775ee7SAntonio Huete Jimenez     nd_uint16_t vlanid;
52*ed775ee7SAntonio Huete Jimenez     nd_uint16_t mtu;
53*ed775ee7SAntonio Huete Jimenez     nd_uint32_t index;
54ea7b4bf5SPeter Avalos };
55ea7b4bf5SPeter Avalos 
56411677aeSAaron LI static const struct tok vtp_message_type_values[] = {
57ea7b4bf5SPeter Avalos     { VTP_SUMMARY_ADV, "Summary advertisement"},
58ea7b4bf5SPeter Avalos     { VTP_SUBSET_ADV, "Subset advertisement"},
59ea7b4bf5SPeter Avalos     { VTP_ADV_REQUEST, "Advertisement request"},
60ea7b4bf5SPeter Avalos     { VTP_JOIN_MESSAGE, "Join message"},
61ea7b4bf5SPeter Avalos     { 0, NULL }
62ea7b4bf5SPeter Avalos };
63ea7b4bf5SPeter Avalos 
64411677aeSAaron LI static const struct tok vtp_header_values[] = {
65ea7b4bf5SPeter Avalos     { 0x01, "Followers"}, /* On Summary advertisement, 3rd byte is Followers */
66ea7b4bf5SPeter Avalos     { 0x02, "Seq number"}, /* On Subset  advertisement, 3rd byte is Sequence number */
67ea7b4bf5SPeter Avalos     { 0x03, "Rsvd"}, /* On Adver. requests 3rd byte is Rsvd */
68ea7b4bf5SPeter Avalos     { 0x04, "Rsvd"}, /* On Adver. requests 3rd byte is Rsvd */
69ea7b4bf5SPeter Avalos     { 0, NULL }
70ea7b4bf5SPeter Avalos };
71ea7b4bf5SPeter Avalos 
72411677aeSAaron LI static const struct tok vtp_vlan_type_values[] = {
73ea7b4bf5SPeter Avalos     { 0x01, "Ethernet"},
74ea7b4bf5SPeter Avalos     { 0x02, "FDDI"},
75ea7b4bf5SPeter Avalos     { 0x03, "TrCRF"},
76ea7b4bf5SPeter Avalos     { 0x04, "FDDI-net"},
77ea7b4bf5SPeter Avalos     { 0x05, "TrBRF"},
78ea7b4bf5SPeter Avalos     { 0, NULL }
79ea7b4bf5SPeter Avalos };
80ea7b4bf5SPeter Avalos 
81411677aeSAaron LI static const struct tok vtp_vlan_status[] = {
82ea7b4bf5SPeter Avalos     { 0x00, "Operational"},
83ea7b4bf5SPeter Avalos     { 0x01, "Suspended"},
84ea7b4bf5SPeter Avalos     { 0, NULL }
85ea7b4bf5SPeter Avalos };
86ea7b4bf5SPeter Avalos 
87ea7b4bf5SPeter Avalos #define VTP_VLAN_SOURCE_ROUTING_RING_NUMBER      0x01
88ea7b4bf5SPeter Avalos #define VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER    0x02
89ea7b4bf5SPeter Avalos #define VTP_VLAN_STP_TYPE                        0x03
90ea7b4bf5SPeter Avalos #define VTP_VLAN_PARENT_VLAN                     0x04
91ea7b4bf5SPeter Avalos #define VTP_VLAN_TRANS_BRIDGED_VLAN              0x05
92ea7b4bf5SPeter Avalos #define VTP_VLAN_PRUNING                         0x06
93ea7b4bf5SPeter Avalos #define VTP_VLAN_BRIDGE_TYPE                     0x07
94ea7b4bf5SPeter Avalos #define VTP_VLAN_ARP_HOP_COUNT                   0x08
95ea7b4bf5SPeter Avalos #define VTP_VLAN_STE_HOP_COUNT                   0x09
96ea7b4bf5SPeter Avalos #define VTP_VLAN_BACKUP_CRF_MODE                 0x0A
97ea7b4bf5SPeter Avalos 
98411677aeSAaron LI static const struct tok vtp_vlan_tlv_values[] = {
99ea7b4bf5SPeter Avalos     { VTP_VLAN_SOURCE_ROUTING_RING_NUMBER, "Source-Routing Ring Number TLV"},
100ea7b4bf5SPeter Avalos     { VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER, "Source-Routing Bridge Number TLV"},
101ea7b4bf5SPeter Avalos     { VTP_VLAN_STP_TYPE, "STP type TLV"},
102ea7b4bf5SPeter Avalos     { VTP_VLAN_PARENT_VLAN, "Parent VLAN TLV"},
103ea7b4bf5SPeter Avalos     { VTP_VLAN_TRANS_BRIDGED_VLAN, "Translationally bridged VLANs TLV"},
104ea7b4bf5SPeter Avalos     { VTP_VLAN_PRUNING, "Pruning TLV"},
105ea7b4bf5SPeter Avalos     { VTP_VLAN_BRIDGE_TYPE, "Bridge Type TLV"},
106ea7b4bf5SPeter Avalos     { VTP_VLAN_ARP_HOP_COUNT, "Max ARP Hop Count TLV"},
107ea7b4bf5SPeter Avalos     { VTP_VLAN_STE_HOP_COUNT, "Max STE Hop Count TLV"},
108ea7b4bf5SPeter Avalos     { VTP_VLAN_BACKUP_CRF_MODE, "Backup CRF Mode TLV"},
109ea7b4bf5SPeter Avalos     { 0,                                  NULL }
110ea7b4bf5SPeter Avalos };
111ea7b4bf5SPeter Avalos 
112411677aeSAaron LI static const struct tok vtp_stp_type_values[] = {
113ea7b4bf5SPeter Avalos     { 1, "SRT"},
114ea7b4bf5SPeter Avalos     { 2, "SRB"},
115ea7b4bf5SPeter Avalos     { 3, "Auto"},
116ea7b4bf5SPeter Avalos     { 0, NULL }
117ea7b4bf5SPeter Avalos };
118ea7b4bf5SPeter Avalos 
119ea7b4bf5SPeter Avalos void
vtp_print(netdissect_options * ndo,const u_char * pptr,const u_int length)120411677aeSAaron LI vtp_print(netdissect_options *ndo,
121*ed775ee7SAntonio Huete Jimenez           const u_char *pptr, const u_int length)
122ea7b4bf5SPeter Avalos {
123*ed775ee7SAntonio Huete Jimenez     u_int type, len, name_len, tlv_len, tlv_value, mgmtd_len;
124ea7b4bf5SPeter Avalos     const u_char *tptr;
125ea7b4bf5SPeter Avalos     const struct vtp_vlan_ *vtp_vlan;
126ea7b4bf5SPeter Avalos 
127*ed775ee7SAntonio Huete Jimenez     ndo->ndo_protocol = "vtp";
128ea7b4bf5SPeter Avalos     if (length < VTP_HEADER_LEN)
129*ed775ee7SAntonio Huete Jimenez         goto invalid;
130ea7b4bf5SPeter Avalos 
131ea7b4bf5SPeter Avalos     tptr = pptr;
132ea7b4bf5SPeter Avalos 
133*ed775ee7SAntonio Huete Jimenez     ND_TCHECK_LEN(tptr, VTP_HEADER_LEN);
134ea7b4bf5SPeter Avalos 
135*ed775ee7SAntonio Huete Jimenez     type = GET_U_1(tptr + 1);
136*ed775ee7SAntonio Huete Jimenez     ND_PRINT("VTPv%u, Message %s (0x%02x), length %u",
137*ed775ee7SAntonio Huete Jimenez 	   GET_U_1(tptr),
138ea7b4bf5SPeter Avalos 	   tok2str(vtp_message_type_values,"Unknown message type", type),
139411677aeSAaron LI 	   type,
140*ed775ee7SAntonio Huete Jimenez 	   length);
141ea7b4bf5SPeter Avalos 
142ea7b4bf5SPeter Avalos     /* In non-verbose mode, just print version and message type */
143411677aeSAaron LI     if (ndo->ndo_vflag < 1) {
144*ed775ee7SAntonio Huete Jimenez         goto tcheck_full_packet;
145ea7b4bf5SPeter Avalos     }
146ea7b4bf5SPeter Avalos 
147ea7b4bf5SPeter Avalos     /* verbose mode print all fields */
148*ed775ee7SAntonio Huete Jimenez     ND_PRINT("\n\tDomain name: ");
149*ed775ee7SAntonio Huete Jimenez     mgmtd_len = GET_U_1(tptr + 3);
150*ed775ee7SAntonio Huete Jimenez     if (mgmtd_len < 1 ||  mgmtd_len > VTP_DOMAIN_NAME_LEN) {
151*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(" [invalid MgmtD Len %u]", mgmtd_len);
152*ed775ee7SAntonio Huete Jimenez 	goto invalid;
153411677aeSAaron LI     }
154*ed775ee7SAntonio Huete Jimenez     nd_printjnp(ndo, tptr + 4, mgmtd_len);
155*ed775ee7SAntonio Huete Jimenez     ND_PRINT(", %s: %u",
156411677aeSAaron LI 	   tok2str(vtp_header_values, "Unknown", type),
157*ed775ee7SAntonio Huete Jimenez 	   GET_U_1(tptr + 2));
158ea7b4bf5SPeter Avalos 
159ea7b4bf5SPeter Avalos     tptr += VTP_HEADER_LEN;
160ea7b4bf5SPeter Avalos 
161ea7b4bf5SPeter Avalos     switch (type) {
162ea7b4bf5SPeter Avalos 
163ea7b4bf5SPeter Avalos     case VTP_SUMMARY_ADV:
164ea7b4bf5SPeter Avalos 
165ea7b4bf5SPeter Avalos 	/*
166ea7b4bf5SPeter Avalos 	 *  SUMMARY ADVERTISEMENT
167ea7b4bf5SPeter Avalos 	 *
168ea7b4bf5SPeter Avalos 	 *  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
169ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
170411677aeSAaron LI 	 *  |     Version   |     Code      |    Followers  |    MgmtD Len  |
171ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
172411677aeSAaron LI 	 *  |       Management Domain Name  (zero-padded to 32 bytes)       |
173ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
174ea7b4bf5SPeter Avalos 	 *  |                    Configuration revision number              |
175ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
176ea7b4bf5SPeter Avalos 	 *  |                  Updater Identity IP address                  |
177ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
178ea7b4bf5SPeter Avalos 	 *  |                    Update Timestamp (12 bytes)                |
179ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
180ea7b4bf5SPeter Avalos 	 *  |                        MD5 digest (16 bytes)                  |
181ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
182ea7b4bf5SPeter Avalos 	 *
183ea7b4bf5SPeter Avalos 	 */
184ea7b4bf5SPeter Avalos 
185*ed775ee7SAntonio Huete Jimenez 	ND_PRINT("\n\t  Config Rev %x, Updater %s",
186*ed775ee7SAntonio Huete Jimenez 	       GET_BE_U_4(tptr),
187*ed775ee7SAntonio Huete Jimenez 	       GET_IPADDR_STRING(tptr+4));
188ea7b4bf5SPeter Avalos 	tptr += 8;
189*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(", Timestamp 0x%08x 0x%08x 0x%08x",
190*ed775ee7SAntonio Huete Jimenez 	       GET_BE_U_4(tptr),
191*ed775ee7SAntonio Huete Jimenez 	       GET_BE_U_4(tptr + 4),
192*ed775ee7SAntonio Huete Jimenez 	       GET_BE_U_4(tptr + 8));
193ea7b4bf5SPeter Avalos 	tptr += VTP_UPDATE_TIMESTAMP_LEN;
194*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(", MD5 digest: %08x%08x%08x%08x",
195*ed775ee7SAntonio Huete Jimenez 	       GET_BE_U_4(tptr),
196*ed775ee7SAntonio Huete Jimenez 	       GET_BE_U_4(tptr + 4),
197*ed775ee7SAntonio Huete Jimenez 	       GET_BE_U_4(tptr + 8),
198*ed775ee7SAntonio Huete Jimenez 	       GET_BE_U_4(tptr + 12));
199ea7b4bf5SPeter Avalos 	tptr += VTP_MD5_DIGEST_LEN;
200ea7b4bf5SPeter Avalos 	break;
201ea7b4bf5SPeter Avalos 
202ea7b4bf5SPeter Avalos     case VTP_SUBSET_ADV:
203ea7b4bf5SPeter Avalos 
204ea7b4bf5SPeter Avalos 	/*
205ea7b4bf5SPeter Avalos 	 *  SUBSET ADVERTISEMENT
206ea7b4bf5SPeter Avalos 	 *
207ea7b4bf5SPeter Avalos 	 *  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
208ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
209411677aeSAaron LI 	 *  |     Version   |     Code      |   Seq number  |    MgmtD Len  |
210ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
211411677aeSAaron LI 	 *  |       Management Domain Name  (zero-padded to 32 bytes)       |
212ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
213ea7b4bf5SPeter Avalos 	 *  |                    Configuration revision number              |
214ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
215ea7b4bf5SPeter Avalos 	 *  |                         VLAN info field 1                     |
216ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
217ea7b4bf5SPeter Avalos 	 *  |                         ................                      |
218ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
219ea7b4bf5SPeter Avalos 	 *  |                         VLAN info field N                     |
220ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
221ea7b4bf5SPeter Avalos 	 *
222ea7b4bf5SPeter Avalos 	 */
223ea7b4bf5SPeter Avalos 
224*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(", Config Rev %x", GET_BE_U_4(tptr));
225ea7b4bf5SPeter Avalos 
226ea7b4bf5SPeter Avalos 	/*
227ea7b4bf5SPeter Avalos 	 *  VLAN INFORMATION
228ea7b4bf5SPeter Avalos 	 *  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
229ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
230ea7b4bf5SPeter Avalos 	 *  | V info len    |    Status     |  VLAN type    | VLAN name len |
231ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
232ea7b4bf5SPeter Avalos 	 *  |       ISL vlan id             |            MTU size           |
233ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
234ea7b4bf5SPeter Avalos 	 *  |                     802.10 index (SAID)                       |
235ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
236ea7b4bf5SPeter Avalos 	 *  |                         VLAN name                             |
237ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
238ea7b4bf5SPeter Avalos 	 *
239ea7b4bf5SPeter Avalos 	 */
240ea7b4bf5SPeter Avalos 
241ea7b4bf5SPeter Avalos 	tptr += 4;
242411677aeSAaron LI 	while ((unsigned)(tptr - pptr) < length) {
243ea7b4bf5SPeter Avalos 
244*ed775ee7SAntonio Huete Jimenez 	    len = GET_U_1(tptr);
245ea7b4bf5SPeter Avalos 	    if (len == 0)
246ea7b4bf5SPeter Avalos 		break;
247ea7b4bf5SPeter Avalos 
248*ed775ee7SAntonio Huete Jimenez 	    ND_TCHECK_LEN(tptr, len);
249ea7b4bf5SPeter Avalos 
250411677aeSAaron LI 	    vtp_vlan = (const struct vtp_vlan_*)tptr;
251411677aeSAaron LI 	    if (len < VTP_VLAN_INFO_FIXED_PART_LEN)
252*ed775ee7SAntonio Huete Jimenez 		goto invalid;
253*ed775ee7SAntonio Huete Jimenez 	    ND_PRINT("\n\tVLAN info status %s, type %s, VLAN-id %u, MTU %u, SAID 0x%08x, Name ",
254*ed775ee7SAntonio Huete Jimenez 		   tok2str(vtp_vlan_status,"Unknown",GET_U_1(vtp_vlan->status)),
255*ed775ee7SAntonio Huete Jimenez 		   tok2str(vtp_vlan_type_values,"Unknown",GET_U_1(vtp_vlan->type)),
256*ed775ee7SAntonio Huete Jimenez 		   GET_BE_U_2(vtp_vlan->vlanid),
257*ed775ee7SAntonio Huete Jimenez 		   GET_BE_U_2(vtp_vlan->mtu),
258*ed775ee7SAntonio Huete Jimenez 		   GET_BE_U_4(vtp_vlan->index));
259411677aeSAaron LI 	    len  -= VTP_VLAN_INFO_FIXED_PART_LEN;
260411677aeSAaron LI 	    tptr += VTP_VLAN_INFO_FIXED_PART_LEN;
261*ed775ee7SAntonio Huete Jimenez 	    name_len = GET_U_1(vtp_vlan->name_len);
262*ed775ee7SAntonio Huete Jimenez 	    if (len < 4*((name_len + 3)/4))
263*ed775ee7SAntonio Huete Jimenez 		goto invalid;
264*ed775ee7SAntonio Huete Jimenez 	    nd_printjnp(ndo, tptr, name_len);
265ea7b4bf5SPeter Avalos 
266ea7b4bf5SPeter Avalos 	    /*
267ea7b4bf5SPeter Avalos 	     * Vlan names are aligned to 32-bit boundaries.
268ea7b4bf5SPeter Avalos 	     */
269*ed775ee7SAntonio Huete Jimenez 	    len  -= 4*((name_len + 3)/4);
270*ed775ee7SAntonio Huete Jimenez 	    tptr += 4*((name_len + 3)/4);
271ea7b4bf5SPeter Avalos 
272ea7b4bf5SPeter Avalos             /* TLV information follows */
273ea7b4bf5SPeter Avalos 
274ea7b4bf5SPeter Avalos             while (len > 0) {
275ea7b4bf5SPeter Avalos 
276ea7b4bf5SPeter Avalos                 /*
277411677aeSAaron LI                  * Cisco specs say 2 bytes for type + 2 bytes for length;
278*ed775ee7SAntonio Huete Jimenez                  * see https://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm
279411677aeSAaron LI                  * However, actual packets on the wire appear to use 1
280411677aeSAaron LI                  * byte for the type and 1 byte for the length, so that's
281411677aeSAaron LI                  * what we do.
282ea7b4bf5SPeter Avalos                  */
283411677aeSAaron LI                 if (len < 2)
284*ed775ee7SAntonio Huete Jimenez                     goto invalid;
285*ed775ee7SAntonio Huete Jimenez                 type = GET_U_1(tptr);
286*ed775ee7SAntonio Huete Jimenez                 tlv_len = GET_U_1(tptr + 1);
287ea7b4bf5SPeter Avalos 
288*ed775ee7SAntonio Huete Jimenez                 ND_PRINT("\n\t\t%s (0x%04x) TLV",
289ea7b4bf5SPeter Avalos                        tok2str(vtp_vlan_tlv_values, "Unknown", type),
290*ed775ee7SAntonio Huete Jimenez                        type);
291ea7b4bf5SPeter Avalos 
292411677aeSAaron LI                 if (len < tlv_len * 2 + 2) {
293*ed775ee7SAntonio Huete Jimenez                     ND_PRINT(" (TLV goes past the end of the packet)");
294*ed775ee7SAntonio Huete Jimenez                     goto invalid;
295ea7b4bf5SPeter Avalos                 }
296*ed775ee7SAntonio Huete Jimenez                 ND_TCHECK_LEN(tptr, tlv_len * 2 + 2);
297ea7b4bf5SPeter Avalos 
298411677aeSAaron LI                 /*
299411677aeSAaron LI                  * We assume the value is a 2-byte integer; the length is
300411677aeSAaron LI                  * in units of 16-bit words.
301411677aeSAaron LI                  */
302411677aeSAaron LI                 if (tlv_len != 1) {
303*ed775ee7SAntonio Huete Jimenez                     ND_PRINT(" (invalid TLV length %u != 1)", tlv_len);
304*ed775ee7SAntonio Huete Jimenez                     goto invalid;
305411677aeSAaron LI                 } else {
306*ed775ee7SAntonio Huete Jimenez                     tlv_value = GET_BE_U_2(tptr + 2);
307ea7b4bf5SPeter Avalos 
308ea7b4bf5SPeter Avalos                     switch (type) {
309ea7b4bf5SPeter Avalos                     case VTP_VLAN_STE_HOP_COUNT:
310*ed775ee7SAntonio Huete Jimenez                         ND_PRINT(", %u", tlv_value);
311ea7b4bf5SPeter Avalos                         break;
312ea7b4bf5SPeter Avalos 
313ea7b4bf5SPeter Avalos                     case VTP_VLAN_PRUNING:
314*ed775ee7SAntonio Huete Jimenez                         ND_PRINT(", %s (%u)",
315ea7b4bf5SPeter Avalos                                tlv_value == 1 ? "Enabled" : "Disabled",
316*ed775ee7SAntonio Huete Jimenez                                tlv_value);
317ea7b4bf5SPeter Avalos                         break;
318ea7b4bf5SPeter Avalos 
319ea7b4bf5SPeter Avalos                     case VTP_VLAN_STP_TYPE:
320*ed775ee7SAntonio Huete Jimenez                         ND_PRINT(", %s (%u)",
321ea7b4bf5SPeter Avalos                                tok2str(vtp_stp_type_values, "Unknown", tlv_value),
322*ed775ee7SAntonio Huete Jimenez                                tlv_value);
323ea7b4bf5SPeter Avalos                         break;
324ea7b4bf5SPeter Avalos 
325ea7b4bf5SPeter Avalos                     case VTP_VLAN_BRIDGE_TYPE:
326*ed775ee7SAntonio Huete Jimenez                         ND_PRINT(", %s (%u)",
327ea7b4bf5SPeter Avalos                                tlv_value == 1 ? "SRB" : "SRT",
328*ed775ee7SAntonio Huete Jimenez                                tlv_value);
329ea7b4bf5SPeter Avalos                         break;
330ea7b4bf5SPeter Avalos 
331ea7b4bf5SPeter Avalos                     case VTP_VLAN_BACKUP_CRF_MODE:
332*ed775ee7SAntonio Huete Jimenez                         ND_PRINT(", %s (%u)",
333ea7b4bf5SPeter Avalos                                tlv_value == 1 ? "Backup" : "Not backup",
334*ed775ee7SAntonio Huete Jimenez                                tlv_value);
335ea7b4bf5SPeter Avalos                         break;
336ea7b4bf5SPeter Avalos 
337ea7b4bf5SPeter Avalos                         /*
338ea7b4bf5SPeter Avalos                          * FIXME those are the defined TLVs that lack a decoder
339ea7b4bf5SPeter Avalos                          * you are welcome to contribute code ;-)
340ea7b4bf5SPeter Avalos                          */
341ea7b4bf5SPeter Avalos 
342ea7b4bf5SPeter Avalos                     case VTP_VLAN_SOURCE_ROUTING_RING_NUMBER:
343ea7b4bf5SPeter Avalos                     case VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER:
344ea7b4bf5SPeter Avalos                     case VTP_VLAN_PARENT_VLAN:
345ea7b4bf5SPeter Avalos                     case VTP_VLAN_TRANS_BRIDGED_VLAN:
346ea7b4bf5SPeter Avalos                     case VTP_VLAN_ARP_HOP_COUNT:
347ea7b4bf5SPeter Avalos                     default:
348411677aeSAaron LI                         print_unknown_data(ndo, tptr, "\n\t\t  ", 2 + tlv_len*2);
349ea7b4bf5SPeter Avalos                         break;
350ea7b4bf5SPeter Avalos                     }
351411677aeSAaron LI                 }
352ea7b4bf5SPeter Avalos                 len -= 2 + tlv_len*2;
353ea7b4bf5SPeter Avalos                 tptr += 2 + tlv_len*2;
354ea7b4bf5SPeter Avalos             }
355ea7b4bf5SPeter Avalos 	}
356ea7b4bf5SPeter Avalos 	break;
357ea7b4bf5SPeter Avalos 
358ea7b4bf5SPeter Avalos     case VTP_ADV_REQUEST:
359ea7b4bf5SPeter Avalos 
360ea7b4bf5SPeter Avalos 	/*
361ea7b4bf5SPeter Avalos 	 *  ADVERTISEMENT REQUEST
362ea7b4bf5SPeter Avalos 	 *
363ea7b4bf5SPeter Avalos 	 *  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
364ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
365411677aeSAaron LI 	 *  |     Version   |     Code      |   Reserved    |    MgmtD Len  |
366ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
367411677aeSAaron LI 	 *  |       Management Domain Name  (zero-padded to 32 bytes)       |
368ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
369ea7b4bf5SPeter Avalos 	 *  |                          Start value                          |
370ea7b4bf5SPeter Avalos 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
371ea7b4bf5SPeter Avalos 	 *
372ea7b4bf5SPeter Avalos 	 */
373ea7b4bf5SPeter Avalos 
374*ed775ee7SAntonio Huete Jimenez 	ND_PRINT("\n\tStart value: %u", GET_BE_U_4(tptr));
375ea7b4bf5SPeter Avalos 	break;
376ea7b4bf5SPeter Avalos 
377ea7b4bf5SPeter Avalos     case VTP_JOIN_MESSAGE:
378ea7b4bf5SPeter Avalos 
379ea7b4bf5SPeter Avalos 	/* FIXME - Could not find message format */
380ea7b4bf5SPeter Avalos 	break;
381ea7b4bf5SPeter Avalos 
382ea7b4bf5SPeter Avalos     default:
383ea7b4bf5SPeter Avalos 	break;
384ea7b4bf5SPeter Avalos     }
385ea7b4bf5SPeter Avalos 
386ea7b4bf5SPeter Avalos     return;
387ea7b4bf5SPeter Avalos 
388*ed775ee7SAntonio Huete Jimenez invalid:
389*ed775ee7SAntonio Huete Jimenez     nd_print_invalid(ndo);
390*ed775ee7SAntonio Huete Jimenez tcheck_full_packet:
391*ed775ee7SAntonio Huete Jimenez     ND_TCHECK_LEN(pptr, length);
392ea7b4bf5SPeter Avalos }
393