Coverage Report

Created: 2025-08-04 07:15

/src/wireshark/epan/dissectors/packet-dec-bpdu.c
Line
Count
Source
1
/* packet-dec-bpdu.c
2
 * Routines for DEC BPDU (DEC Spanning Tree Protocol) disassembly
3
 *
4
 * Copyright 2001 Paul Ionescu <paul@acorp.ro>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
#include "config.h"
14
15
#include <epan/packet.h>
16
#include <epan/etypes.h>
17
#include <epan/ppptypes.h>
18
#include <epan/tfs.h>
19
20
/* Offsets of fields within a BPDU */
21
22
16
#define BPDU_DEC_CODE            0
23
32
#define BPDU_TYPE                1
24
16
#define BPDU_VERSION             2
25
16
#define BPDU_FLAGS               3
26
16
#define BPDU_ROOT_PRI            4
27
16
#define BPDU_ROOT_MAC            6
28
16
#define BPDU_ROOT_PATH_COST     12
29
16
#define BPDU_BRIDGE_PRI         14
30
16
#define BPDU_BRIDGE_MAC         16
31
16
#define BPDU_PORT_IDENTIFIER    22
32
16
#define BPDU_MESSAGE_AGE        23
33
16
#define BPDU_HELLO_TIME         24
34
16
#define BPDU_MAX_AGE            25
35
16
#define BPDU_FORWARD_DELAY      26
36
37
32
#define DEC_BPDU_SIZE           27
38
39
/* Flag bits */
40
41
14
#define BPDU_FLAGS_SHORT_TIMERS         0x80
42
14
#define BPDU_FLAGS_TCACK                0x02
43
14
#define BPDU_FLAGS_TC                   0x01
44
45
void proto_register_dec_bpdu(void);
46
void proto_reg_handoff_dec_bpdu(void);
47
48
static dissector_handle_t dec_bpdu_handle;
49
50
static int proto_dec_bpdu;
51
static int hf_dec_bpdu_proto_id;
52
static int hf_dec_bpdu_type;
53
static int hf_dec_bpdu_version_id;
54
static int hf_dec_bpdu_flags;
55
static int hf_dec_bpdu_flags_short_timers;
56
static int hf_dec_bpdu_flags_tcack;
57
static int hf_dec_bpdu_flags_tc;
58
static int hf_dec_bpdu_root_pri;
59
static int hf_dec_bpdu_root_mac;
60
static int hf_dec_bpdu_root_cost;
61
static int hf_dec_bpdu_bridge_pri;
62
static int hf_dec_bpdu_bridge_mac;
63
static int hf_dec_bpdu_port_id;
64
static int hf_dec_bpdu_msg_age;
65
static int hf_dec_bpdu_hello_time;
66
static int hf_dec_bpdu_max_age;
67
static int hf_dec_bpdu_forward_delay;
68
69
static int ett_dec_bpdu;
70
static int ett_dec_bpdu_flags;
71
72
static const value_string protocol_id_vals[] = {
73
    { 0xe1, "DEC Spanning Tree Protocol" },
74
    { 0,    NULL }
75
};
76
77
#define BPDU_TYPE_TOPOLOGY_CHANGE       2
78
#define BPDU_TYPE_HELLO                 25
79
80
static const value_string bpdu_type_vals[] = {
81
    { BPDU_TYPE_TOPOLOGY_CHANGE, "Topology Change Notification" },
82
    { BPDU_TYPE_HELLO,           "Hello Packet" },
83
    { 0,                         NULL }
84
};
85
86
static int
87
dissect_dec_bpdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
88
16
{
89
16
    uint8_t bpdu_type;
90
16
    proto_tree *bpdu_tree;
91
16
    proto_item *ti;
92
16
    static int * const bpdu_flags[] = {
93
16
        &hf_dec_bpdu_flags_short_timers,
94
16
        &hf_dec_bpdu_flags_tcack,
95
16
        &hf_dec_bpdu_flags_tc,
96
16
        NULL
97
16
    };
98
99
16
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "DEC_STP");
100
16
    col_clear(pinfo->cinfo, COL_INFO);
101
102
16
    bpdu_type = tvb_get_uint8(tvb, BPDU_TYPE);
103
104
16
    col_add_str(pinfo->cinfo, COL_INFO,
105
16
                val_to_str(bpdu_type, bpdu_type_vals,
106
16
                           "Unknown BPDU type (%u)"));
107
108
16
    set_actual_length(tvb, DEC_BPDU_SIZE);
109
110
16
    if (tree) {
111
16
        ti = proto_tree_add_item(tree, proto_dec_bpdu, tvb, 0, DEC_BPDU_SIZE,
112
16
                                 ENC_NA);
113
16
        bpdu_tree = proto_item_add_subtree(ti, ett_dec_bpdu);
114
115
16
        proto_tree_add_item(bpdu_tree, hf_dec_bpdu_proto_id, tvb,
116
16
                            BPDU_DEC_CODE, 1, ENC_BIG_ENDIAN);
117
118
16
        proto_tree_add_uint(bpdu_tree, hf_dec_bpdu_type, tvb,
119
16
                            BPDU_TYPE, 1, bpdu_type);
120
121
16
        proto_tree_add_item(bpdu_tree, hf_dec_bpdu_version_id, tvb,
122
16
                            BPDU_VERSION, 1, ENC_BIG_ENDIAN);
123
124
16
        proto_tree_add_bitmask_with_flags(bpdu_tree, tvb, BPDU_FLAGS, hf_dec_bpdu_flags, ett_dec_bpdu_flags, bpdu_flags, ENC_NA, BMT_NO_FALSE|BMT_NO_TFS);
125
16
        proto_tree_add_item(bpdu_tree, hf_dec_bpdu_root_pri, tvb,
126
16
                            BPDU_ROOT_PRI, 2, ENC_BIG_ENDIAN);
127
16
        proto_tree_add_item(bpdu_tree, hf_dec_bpdu_root_mac, tvb,
128
16
                            BPDU_ROOT_MAC, 6, ENC_NA);
129
16
        proto_tree_add_item(bpdu_tree, hf_dec_bpdu_root_cost, tvb,
130
16
                            BPDU_ROOT_PATH_COST, 2, ENC_BIG_ENDIAN);
131
16
        proto_tree_add_item(bpdu_tree, hf_dec_bpdu_bridge_pri, tvb,
132
16
                            BPDU_BRIDGE_PRI, 2, ENC_BIG_ENDIAN);
133
16
        proto_tree_add_item(bpdu_tree, hf_dec_bpdu_bridge_mac, tvb,
134
16
                            BPDU_BRIDGE_MAC, 6, ENC_NA);
135
16
        proto_tree_add_item(bpdu_tree, hf_dec_bpdu_port_id, tvb,
136
16
                            BPDU_PORT_IDENTIFIER, 1, ENC_BIG_ENDIAN);
137
16
        proto_tree_add_item(bpdu_tree, hf_dec_bpdu_msg_age, tvb,
138
16
                            BPDU_MESSAGE_AGE, 1, ENC_BIG_ENDIAN);
139
16
        proto_tree_add_item(bpdu_tree, hf_dec_bpdu_hello_time, tvb,
140
16
                            BPDU_HELLO_TIME, 1, ENC_BIG_ENDIAN);
141
16
        proto_tree_add_item(bpdu_tree, hf_dec_bpdu_max_age, tvb,
142
16
                            BPDU_MAX_AGE, 1, ENC_BIG_ENDIAN);
143
16
        proto_tree_add_item(bpdu_tree, hf_dec_bpdu_forward_delay, tvb,
144
16
                            BPDU_FORWARD_DELAY, 1, ENC_BIG_ENDIAN);
145
146
16
    }
147
16
    return tvb_captured_length(tvb);
148
16
}
149
150
void
151
proto_register_dec_bpdu(void)
152
14
{
153
154
14
    static hf_register_info hf[] = {
155
14
        { &hf_dec_bpdu_proto_id,
156
14
          { "Protocol Identifier",          "dec_stp.protocol",
157
14
            FT_UINT8,       BASE_HEX,       VALS(protocol_id_vals), 0x0,
158
14
            NULL, HFILL }},
159
14
        { &hf_dec_bpdu_type,
160
14
          { "BPDU Type",                    "dec_stp.type",
161
14
            FT_UINT8,       BASE_DEC,       VALS(bpdu_type_vals),   0x0,
162
14
            NULL, HFILL }},
163
14
        { &hf_dec_bpdu_version_id,
164
14
          { "BPDU Version",                 "dec_stp.version",
165
14
            FT_UINT8,       BASE_DEC,       NULL,   0x0,
166
14
            NULL, HFILL }},
167
14
        { &hf_dec_bpdu_flags,
168
14
          { "BPDU flags",                   "dec_stp.flags",
169
14
            FT_UINT8,       BASE_HEX,       NULL,   0x0,
170
14
            NULL, HFILL }},
171
14
        { &hf_dec_bpdu_flags_short_timers,
172
14
          { "Use short timers",             "dec_stp.flags.short_timers",
173
14
            FT_BOOLEAN,     8,              TFS(&tfs_yes_no),       BPDU_FLAGS_SHORT_TIMERS,
174
14
            NULL, HFILL }},
175
14
        { &hf_dec_bpdu_flags_tcack,
176
14
          { "Topology Change Acknowledgment",  "dec_stp.flags.tcack",
177
14
            FT_BOOLEAN,     8,              TFS(&tfs_yes_no),       BPDU_FLAGS_TCACK,
178
14
            NULL, HFILL }},
179
14
        { &hf_dec_bpdu_flags_tc,
180
14
          { "Topology Change",              "dec_stp.flags.tc",
181
14
            FT_BOOLEAN,     8,              TFS(&tfs_yes_no),       BPDU_FLAGS_TC,
182
14
            NULL, HFILL }},
183
14
        { &hf_dec_bpdu_root_pri,
184
14
          { "Root Priority",                "dec_stp.root.pri",
185
14
            FT_UINT16,      BASE_DEC,       NULL,   0x0,
186
14
            NULL, HFILL }},
187
14
        { &hf_dec_bpdu_root_mac,
188
14
          { "Root MAC",                     "dec_stp.root.mac",
189
14
            FT_ETHER,       BASE_NONE,      NULL,   0x0,
190
14
            NULL, HFILL }},
191
14
        { &hf_dec_bpdu_root_cost,
192
14
          { "Root Path Cost",               "dec_stp.root.cost",
193
14
            FT_UINT16,      BASE_DEC,       NULL,   0x0,
194
14
            NULL, HFILL }},
195
14
        { &hf_dec_bpdu_bridge_pri,
196
14
          { "Bridge Priority",              "dec_stp.bridge.pri",
197
14
            FT_UINT16,      BASE_DEC,       NULL,   0x0,
198
14
            NULL, HFILL }},
199
14
        { &hf_dec_bpdu_bridge_mac,
200
14
          { "Bridge MAC",                   "dec_stp.bridge.mac",
201
14
            FT_ETHER,       BASE_NONE,      NULL,   0x0,
202
14
            NULL, HFILL }},
203
14
        { &hf_dec_bpdu_port_id,
204
14
          { "Port identifier",              "dec_stp.port",
205
14
            FT_UINT8,       BASE_DEC,       NULL,   0x0,
206
14
            NULL, HFILL }},
207
14
        { &hf_dec_bpdu_msg_age,
208
14
          { "Message Age",                  "dec_stp.msg_age",
209
14
            FT_UINT8,       BASE_DEC,       NULL,   0x0,
210
14
            NULL, HFILL }},
211
14
        { &hf_dec_bpdu_hello_time,
212
14
          { "Hello Time",                   "dec_stp.hello",
213
14
            FT_UINT8,       BASE_DEC,       NULL,   0x0,
214
14
            NULL, HFILL }},
215
14
        { &hf_dec_bpdu_max_age,
216
14
          { "Max Age",                      "dec_stp.max_age",
217
14
            FT_UINT8,       BASE_DEC,       NULL,   0x0,
218
14
            NULL, HFILL }},
219
14
        { &hf_dec_bpdu_forward_delay,
220
14
          { "Forward Delay",                "dec_stp.forward",
221
14
            FT_UINT8,       BASE_DEC,       NULL,   0x0,
222
14
            NULL, HFILL }},
223
14
    };
224
14
    static int *ett[] = {
225
14
        &ett_dec_bpdu,
226
14
        &ett_dec_bpdu_flags,
227
14
    };
228
229
14
    proto_dec_bpdu = proto_register_protocol("DEC Spanning Tree Protocol",
230
14
                                             "DEC_STP", "dec_stp");
231
14
    proto_register_field_array(proto_dec_bpdu, hf, array_length(hf));
232
14
    proto_register_subtree_array(ett, array_length(ett));
233
234
14
    dec_bpdu_handle = register_dissector("dec_stp", dissect_dec_bpdu,
235
14
                                              proto_dec_bpdu);
236
14
}
237
238
void
239
proto_reg_handoff_dec_bpdu(void)
240
14
{
241
14
    dissector_add_uint("ethertype", ETHERTYPE_DEC_LB, dec_bpdu_handle);
242
14
    dissector_add_uint("chdlc.protocol", ETHERTYPE_DEC_LB, dec_bpdu_handle);
243
14
    dissector_add_uint("ppp.protocol", PPP_DEC_LB, dec_bpdu_handle);
244
14
}
245
246
/*
247
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
248
 *
249
 * Local variables:
250
 * c-basic-offset: 4
251
 * tab-width: 8
252
 * indent-tabs-mode: nil
253
 * End:
254
 *
255
 * vi: set shiftwidth=4 tabstop=8 expandtab:
256
 * :indentSize=4:tabSize=8:noTabs=true:
257
 */