xref: /freebsd/contrib/tcpdump/print-stp.c (revision 4df395f42edf94a848c3a2ef908b406d888207d6)
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[] =
14     "@(#) $Header: /tcpdump/master/tcpdump/print-stp.c,v 1.6 2000/09/29 04:58:50 guy Exp $";
15 #endif
16 
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20 
21 #include <sys/param.h>
22 #include <sys/time.h>
23 #include <sys/socket.h>
24 
25 #include <netinet/in.h>
26 
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 
31 #include "interface.h"
32 #include "addrtoname.h"
33 #include "extract.h"
34 
35 static void
36 stp_print_bridge_id(const u_char *p)
37 {
38 	printf("%.2x%.2x.%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
39 	       p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
40 }
41 
42 static void
43 stp_print_config_bpdu(const u_char *p, u_int length)
44 {
45 	printf("config ");
46 	if (p[7] & 1)
47 		printf("TOP_CHANGE ");
48 	if (p[7] & 0x80)
49 		printf("TOP_CHANGE_ACK ");
50 
51 	stp_print_bridge_id(p+20);
52 	printf(".%.2x%.2x ", p[28], p[29]);
53 
54 	printf("root ");
55 	stp_print_bridge_id(p+8);
56 
57 	printf(" pathcost %i ", (p[16] << 24) | (p[17] << 16) | (p[18] << 8) | p[19]);
58 
59 	printf("age %i ", p[30]);
60 	printf("max %i ", p[32]);
61 	printf("hello %i ", p[34]);
62 	printf("fdelay %i ", p[36]);
63 }
64 
65 static void
66 stp_print_tcn_bpdu(const u_char *p, u_int length)
67 {
68 	printf("tcn");
69 }
70 
71 /*
72  * Print 802.1d packets.
73  */
74 void
75 stp_print(const u_char *p, u_int length)
76 {
77 	if (length < 7)
78 		goto trunc;
79 
80 	printf("802.1d ");
81 	if (p[2] != 0x03 || p[3] || p[4] || p[5]) {
82 		printf("unknown version");
83 		return;
84 	}
85 
86 	switch (p[6])
87 	{
88 	case 0:
89 		if (length < 10)
90 			goto trunc;
91 		stp_print_config_bpdu(p, length);
92 		break;
93 
94 	case 1:
95 		stp_print_tcn_bpdu(p, length);
96 		break;
97 
98 	default:
99 		printf("unknown type %i\n", p[6]);
100 		break;
101 	}
102 
103 	return;
104 trunc:
105 	printf("[|stp %d]", length);
106 }
107