xref: /freebsd/contrib/tcpdump/print-stp.c (revision 87e4d12e4a4bdc07ce58513fbd38f898f04899c6)
1 /*
2  * Copyright (c) 2000 Lennert Buytenhek
3  *
4  * This software may be distributed either under the terms of the
5  * BSD-style license that accompanies tcpdump or the GNU General
6  * Public License
7  *
8  * Format and print IEEE 802.1d spanning tree protocol packets.
9  * Contributed by Lennert Buytenhek <buytenh@gnu.org>
10  */
11 
12 #ifndef lint
13 static const char rcsid[] _U_ =
14     "@(#) $Header: /tcpdump/master/tcpdump/print-stp.c,v 1.11.2.2 2003/11/16 08:51:46 guy Exp $";
15 #endif
16 
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20 
21 #include <tcpdump-stdinc.h>
22 
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 
27 #include "interface.h"
28 #include "addrtoname.h"
29 #include "extract.h"
30 
31 static void
32 stp_print_bridge_id(const u_char *p)
33 {
34 	printf("%.2x%.2x.%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
35 	       p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
36 }
37 
38 static void
39 stp_print_config_bpdu(const u_char *p)
40 {
41 	printf("config ");
42 	if (p[7] & 1)
43 		printf("TOP_CHANGE ");
44 	if (p[7] & 0x80)
45 		printf("TOP_CHANGE_ACK ");
46 
47 	stp_print_bridge_id(p+20);
48 	printf(".%.2x%.2x ", p[28], p[29]);
49 
50 	printf("root ");
51 	stp_print_bridge_id(p+8);
52 
53 	printf(" pathcost %i ", (p[16] << 24) | (p[17] << 16) | (p[18] << 8) | p[19]);
54 
55 	printf("age %i ", p[30]);
56 	printf("max %i ", p[32]);
57 	printf("hello %i ", p[34]);
58 	printf("fdelay %i ", p[36]);
59 }
60 
61 static void
62 stp_print_tcn_bpdu(void)
63 {
64 	printf("tcn");
65 }
66 
67 /*
68  * Print 802.1d packets.
69  */
70 void
71 stp_print(const u_char *p, u_int length)
72 {
73 	if (length < 7)
74 		goto trunc;
75 
76 	printf("802.1d ");
77 	if (p[2] != 0x03 || p[3] || p[4] || p[5]) {
78 		printf("unknown version");
79 		return;
80 	}
81 
82 	switch (p[6])
83 	{
84 	case 0x00:
85 		if (length < 10)
86 			goto trunc;
87 		stp_print_config_bpdu(p);
88 		break;
89 
90 	case 0x80:
91 		stp_print_tcn_bpdu();
92 		break;
93 
94 	default:
95 		printf("unknown type %i", p[6]);
96 		break;
97 	}
98 
99 	return;
100 trunc:
101 	printf("[|stp %d]", length);
102 }
103