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
13static const char rcsid[] _U_ =
14    "@(#) $Header: /tcpdump/master/tcpdump/print-stp.c,v 1.13.2.1 2005/04/26 07:27:17 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
31static void
32stp_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
38static void
39stp_print_config_bpdu(const u_char *p)
40{
41	printf("config ");
42	if (p[4] & 1)
43		printf("TOP_CHANGE ");
44	if (p[4] & 0x80)
45		printf("TOP_CHANGE_ACK ");
46
47	stp_print_bridge_id(p+17);
48	printf(".%.2x%.2x ", p[25], p[26]);
49
50	printf("root ");
51	stp_print_bridge_id(p+5);
52
53	printf(" pathcost %i ", (p[13] << 24) | (p[14] << 16) | (p[15] << 8) | p[16]);
54
55	printf("age %i ", p[27]);
56	printf("max %i ", p[29]);
57	printf("hello %i ", p[31]);
58	printf("fdelay %i ", p[33]);
59}
60
61static void
62stp_print_tcn_bpdu(void)
63{
64	printf("tcn");
65}
66
67/*
68 * Print 802.1d packets.
69 */
70void
71stp_print(const u_char *p, u_int length)
72{
73	if (length < 4)
74		goto trunc;
75
76	printf("802.1d ");
77	if (p[0] || p[1] || p[2]) {
78		printf("unknown version");
79		return;
80	}
81
82	switch (p[3])
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[3]);
96		break;
97	}
98
99	return;
100trunc:
101	printf("[|stp %d]", length);
102}
103