Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-hpsw.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-hpsw.c
2
 * Routines for HP Switch Config protocol
3
 * Charlie Lenahan <clenahan@fortresstech.com>
4
 *
5
 * Wireshark - Network traffic analyzer
6
 * By Gerald Combs <gerald@wireshark.org>
7
 * Copyright 1998 Gerald Combs
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 */
11
12
#include "config.h"
13
14
#include <epan/packet.h>
15
#include <epan/expert.h>
16
17
#include "packet-hpext.h"
18
19
void proto_register_hpsw(void);
20
void proto_reg_handoff_hpsw(void);
21
22
static int proto_hpsw;
23
24
static int hf_hpsw_version;
25
static int hf_hpsw_type;
26
static int hf_hpsw_tlvtype;
27
static int hf_hpsw_tlvlength;
28
static int hf_hpsw_field_10;
29
static int hf_hpsw_own_mac_addr;
30
static int hf_hpsw_neighbor_mac_addr;
31
static int hf_hpsw_field_6;
32
static int hf_hpsw_field_9;
33
static int hf_hpsw_device_version;
34
static int hf_hpsw_device_name;
35
static int hf_hpsw_ip_addr;
36
static int hf_hpsw_field_8;
37
static int hf_hpsw_domain;
38
static int hf_hpsw_field_12;
39
static int hf_hpsw_config_name;
40
static int hf_hpsw_root_mac_addr;
41
static int hf_hpsw_device_id;
42
static int hf_hpsw_device_id_data;
43
static int hf_hpsw_data;
44
45
46
static int ett_hpsw;
47
static int ett_hpsw_tlv;
48
49
static expert_field ei_hpsw_tlvlength_bad;
50
51
static dissector_handle_t hpsw_handle;
52
53
15
#define HPFOO_DEVICE_NAME     0x1
54
0
#define HPFOO_DEVICE_VERSION  0x2
55
1
#define HPFOO_CONFIG_NAME     0x3
56
3
#define HPFOO_ROOT_MAC_ADDR   0x4
57
0
#define HPFOO_IP_ADDR         0x5
58
0
#define HPFOO_FIELD_6         0x6
59
0
#define HPFOO_DOMAIN          0x7
60
1
#define HPFOO_FIELD_8         0x8
61
14
#define HPFOO_FIELD_9         0x9
62
0
#define HPFOO_FIELD_10        0xa
63
7
#define HPFOO_NEIGHBORS       0xb
64
19
#define HPFOO_FIELD_12        0xc
65
8
#define HPFOO_DEVICE_ID       0xd
66
4
#define HPFOO_OWN_MAC_ADDR    0xe
67
68
static const value_string hpsw_tlv_type_vals[] = {
69
    { HPFOO_DEVICE_NAME,    "Device Name" },
70
    { HPFOO_DEVICE_VERSION, "Version" },
71
    { HPFOO_CONFIG_NAME,    "Config Name" },
72
    { HPFOO_ROOT_MAC_ADDR,  "Root MAC Addr" },
73
    { HPFOO_IP_ADDR,        "IP Addr" },
74
    { HPFOO_FIELD_6,        "Field 6" },
75
    { HPFOO_DOMAIN,         "Domain" },
76
    { HPFOO_FIELD_8,        "Field 8" },
77
    { HPFOO_FIELD_9,        "Field 9" },
78
    { HPFOO_FIELD_10,       "Field 10" },
79
    { HPFOO_NEIGHBORS,      "Neighbors" },
80
    { HPFOO_FIELD_12,       "Field 12" },
81
    { HPFOO_DEVICE_ID,      "Device ID" },
82
    { HPFOO_OWN_MAC_ADDR,   "2nd MAC Addr" },
83
    { 0x00,                 NULL }
84
};
85
86
static void
87
dissect_hpsw_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length,
88
                 proto_tree *tree, proto_item *ti, uint8_t type)
89
128
{
90
128
    switch (type) {
91
92
15
    case HPFOO_DEVICE_NAME:
93
15
        if (length > 0) {
94
15
            proto_tree_add_item(tree, hf_hpsw_device_name, tvb, offset, length, ENC_NA|ENC_ASCII);
95
15
        } else {
96
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Device Name: Bad length %u", length);
97
0
        }
98
15
        break;
99
100
0
    case HPFOO_DEVICE_VERSION:
101
0
        if (length > 0) {
102
0
            proto_tree_add_item(tree, hf_hpsw_device_version, tvb, offset, length, ENC_NA|ENC_ASCII);
103
0
        } else {
104
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Version: Bad length %u", length);
105
0
        }
106
0
        break;
107
108
1
    case HPFOO_CONFIG_NAME:
109
1
        if (length > 0) {
110
1
            proto_tree_add_item(tree, hf_hpsw_config_name, tvb, offset, length, ENC_NA|ENC_ASCII);
111
1
        } else {
112
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Config Name: Bad length %u", length);
113
0
        }
114
1
        break;
115
116
3
    case HPFOO_ROOT_MAC_ADDR:
117
3
        if (length == 6) {
118
0
            proto_tree_add_item(tree, hf_hpsw_root_mac_addr, tvb, offset, length, ENC_NA);
119
3
        } else {
120
3
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Root MAC Addr: Bad length %u", length);
121
3
        }
122
3
        break;
123
124
0
    case HPFOO_IP_ADDR:
125
0
        if (length == 4) {
126
0
            proto_tree_add_item(tree, hf_hpsw_ip_addr, tvb, offset, length, ENC_BIG_ENDIAN);
127
0
        } else {
128
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "IP Addr: Bad length %u", length);
129
0
        }
130
0
        break;
131
132
0
    case HPFOO_FIELD_6:
133
0
        if (length == 2) {
134
0
            proto_tree_add_item(tree, hf_hpsw_field_6, tvb, offset, length, ENC_BIG_ENDIAN);
135
0
        } else {
136
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Field 6: Bad length %u", length);
137
0
        }
138
0
        break;
139
140
0
    case HPFOO_DOMAIN:
141
0
        if (length > 0) {
142
0
            proto_tree_add_item(tree, hf_hpsw_domain, tvb, offset, length, ENC_NA|ENC_ASCII);
143
0
        } else {
144
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Domain: Bad length %u", length);
145
0
        }
146
0
        break;
147
148
1
    case HPFOO_FIELD_8:
149
1
        if (length == 2) {
150
0
            proto_tree_add_item(tree, hf_hpsw_field_8, tvb, offset, length, ENC_BIG_ENDIAN);
151
1
        } else {
152
1
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Field 8: Bad length %u", length);
153
1
        }
154
1
        break;
155
156
14
    case HPFOO_FIELD_9:
157
14
        if (length == 2) {
158
0
            proto_tree_add_item(tree, hf_hpsw_field_9, tvb, offset, length, ENC_BIG_ENDIAN);
159
14
        } else {
160
14
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Field 9: Bad length %u", length);
161
14
        }
162
14
        break;
163
164
0
    case HPFOO_FIELD_10:
165
0
        if (length == 4) {
166
0
            proto_tree_add_item(tree, hf_hpsw_field_10, tvb, offset, length, ENC_BIG_ENDIAN);
167
0
        } else {
168
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Field 10: Bad length %u", length);
169
0
        }
170
0
        break;
171
172
7
    case HPFOO_NEIGHBORS:
173
7
        if (!(length % 6))
174
0
        {   int i = length/6;
175
0
            proto_item_set_text(proto_tree_get_parent(tree), "Number of neighbor MAC Addresses: %u", i);
176
0
            for ( ; i; i--)
177
0
            {
178
0
                proto_tree_add_item(tree, hf_hpsw_neighbor_mac_addr, tvb, offset, 6, ENC_NA);
179
0
                offset += 6;
180
0
            }
181
7
        } else {
182
7
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Neighbors: Bad length %u", length);
183
7
        }
184
7
        break;
185
186
19
    case HPFOO_FIELD_12:
187
19
        if (length == 1) {
188
0
            proto_tree_add_item(tree, hf_hpsw_field_12, tvb, offset, length, ENC_BIG_ENDIAN);
189
19
        } else {
190
19
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Field 12: Bad length %u", length);
191
19
        }
192
19
        break;
193
194
8
    case HPFOO_DEVICE_ID:
195
8
        if (length > 6) {
196
8
            proto_tree_add_item(tree, hf_hpsw_device_id, tvb, offset, 6, ENC_NA);
197
8
            proto_tree_add_item(tree, hf_hpsw_device_id_data, tvb, offset+6, length-6, ENC_NA);
198
8
        } else {
199
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Device ID: Bad length %u", length);
200
0
        }
201
8
        break;
202
203
4
    case HPFOO_OWN_MAC_ADDR:
204
4
        if (length == 6) {
205
0
            proto_tree_add_item(tree, hf_hpsw_own_mac_addr, tvb, offset, length, ENC_NA);
206
4
        } else {
207
4
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Own MAC Addr: Bad length %u", length);
208
4
        }
209
4
        break;
210
211
56
    default:
212
56
        proto_tree_add_item(tree, hf_hpsw_data, tvb, offset, length, ENC_NA);
213
56
        break;
214
128
    }
215
128
}
216
217
static int
218
dissect_hpsw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
219
19
{
220
19
    proto_tree *hp_tree;
221
19
    proto_tree *tlv_tree;
222
19
    proto_item *ti;
223
19
    uint8_t     version;
224
19
    int         offset = 0;
225
226
19
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "HP");
227
19
    col_set_str(pinfo->cinfo, COL_INFO, "HP Switch Protocol");
228
229
19
    version = tvb_get_uint8(tvb, 0);
230
231
19
    ti = proto_tree_add_item(tree, proto_hpsw, tvb, 0, -1, ENC_NA);
232
19
    hp_tree = proto_item_add_subtree(ti, ett_hpsw);
233
19
    proto_tree_add_uint(hp_tree, hf_hpsw_version, tvb, 0, 1, version);
234
19
    offset += 1;
235
236
19
    proto_tree_add_item(hp_tree, hf_hpsw_type, tvb, 1, 1, ENC_BIG_ENDIAN);
237
19
    offset += 1;
238
239
147
    while ( tvb_reported_length_remaining(tvb, offset) > 0 )
240
145
    {
241
145
        uint8_t type, length;
242
243
145
        type   = tvb_get_uint8(tvb, offset);
244
145
        length = tvb_get_uint8(tvb, offset+1);
245
246
        /* make sure still in valid tlv */
247
145
        if (( length < 1 ) || ( length > tvb_reported_length_remaining(tvb, offset+2)))
248
17
            break;
249
250
128
        tlv_tree = proto_tree_add_subtree(hp_tree, tvb, offset, length+2, ett_hpsw_tlv, NULL,
251
128
                                 val_to_str(type, hpsw_tlv_type_vals, "Unknown TLV type: 0x%02x"));
252
253
        /* type */
254
128
        proto_tree_add_uint(tlv_tree, hf_hpsw_tlvtype, tvb, offset, 1, type);
255
128
        offset += 1;
256
257
        /* LENGTH (not inclusive of type and length bytes) */
258
128
        ti = proto_tree_add_uint(tlv_tree, hf_hpsw_tlvlength, tvb, offset, 1, length);
259
128
        offset += 1;
260
261
128
        dissect_hpsw_tlv(tvb, pinfo, offset, length, tlv_tree, ti, type);
262
263
128
        offset += length;
264
265
128
    }
266
19
    return tvb_captured_length(tvb);
267
19
}
268
269
void
270
proto_register_hpsw(void)
271
14
{
272
14
    static hf_register_info hf[] = {
273
14
        { &hf_hpsw_version,
274
14
          { "Version", "hpsw.version", FT_UINT8, BASE_HEX,
275
14
            NULL, 0x0, NULL, HFILL }},
276
14
        { &hf_hpsw_type,
277
14
          { "Type", "hpsw.type", FT_UINT8, BASE_HEX,
278
14
            NULL, 0x0, NULL, HFILL }},
279
14
        { &hf_hpsw_tlvtype,
280
14
          { "Type", "hpsw.tlv_type", FT_UINT8, BASE_HEX,
281
14
            VALS(hpsw_tlv_type_vals), 0x0, NULL, HFILL }},
282
14
        { &hf_hpsw_tlvlength,
283
14
          { "Length", "hpsw.tlv_len", FT_UINT8, BASE_DEC,
284
14
            NULL, 0x0, NULL, HFILL }},
285
14
        { &hf_hpsw_device_name,
286
14
          { "Device Name", "hpsw.device_name", FT_STRING, BASE_NONE,
287
14
            NULL, 0x0, NULL, HFILL }},
288
14
        { &hf_hpsw_device_version,
289
14
          { "Version", "hpsw.device_version", FT_STRING, BASE_NONE,
290
14
            NULL, 0x0, NULL, HFILL }},
291
14
        { &hf_hpsw_config_name,
292
14
          { "Config Name", "hpsw.config_name", FT_STRING, BASE_NONE,
293
14
            NULL, 0x0, NULL, HFILL }},
294
14
        { &hf_hpsw_root_mac_addr,
295
14
          { "Root MAC Addr", "hpsw.root_mac_addr", FT_ETHER, BASE_NONE,
296
14
            NULL, 0x0, NULL, HFILL }},
297
14
        { &hf_hpsw_ip_addr,
298
14
          { "IP Addr", "hpsw.ip_addr", FT_IPv4, BASE_NONE,
299
14
            NULL, 0x0, NULL, HFILL }},
300
14
        { &hf_hpsw_field_6,
301
14
          { "Field 6", "hpsw.field_6", FT_UINT16, BASE_HEX,
302
14
            NULL, 0x0, NULL, HFILL }},
303
14
        { &hf_hpsw_domain,
304
14
          { "Domain", "hpsw.domain", FT_STRING, BASE_NONE,
305
14
            NULL, 0x0, NULL, HFILL }},
306
14
        { &hf_hpsw_field_8,
307
14
          { "Field 8", "hpsw.field_8", FT_UINT16, BASE_HEX,
308
14
            NULL, 0x0, NULL, HFILL }},
309
14
        { &hf_hpsw_field_9,
310
14
          { "Field 9", "hpsw.field_9", FT_UINT16, BASE_HEX,
311
14
            NULL, 0x0, NULL, HFILL }},
312
14
        { &hf_hpsw_field_10,
313
14
          { "Field 10", "hpsw.field_10", FT_UINT32, BASE_HEX,
314
14
            NULL, 0x0, NULL, HFILL }},
315
14
        { &hf_hpsw_neighbor_mac_addr,
316
14
          { "MAC Addr", "hpsw.neighbor_mac_addr", FT_ETHER, BASE_NONE,
317
14
            NULL, 0x0, NULL, HFILL }},
318
14
        { &hf_hpsw_field_12,
319
14
          { "Field 12", "hpsw.field_12", FT_UINT8, BASE_HEX,
320
14
            NULL, 0x0, NULL, HFILL }},
321
14
        { &hf_hpsw_own_mac_addr,
322
14
          { "Own MAC Addr", "hpsw.own_mac_addr", FT_ETHER, BASE_NONE,
323
14
            NULL, 0x0, NULL, HFILL }},
324
14
        { &hf_hpsw_device_id,
325
14
          { "Device ID", "hpsw.device_id", FT_ETHER, BASE_NONE,
326
14
            NULL, 0x0, NULL, HFILL }},
327
14
        { &hf_hpsw_device_id_data,
328
14
          { "Data", "hpsw.device_id_data", FT_BYTES, BASE_NONE,
329
14
            NULL, 0x0, NULL, HFILL }},
330
14
        { &hf_hpsw_data,
331
14
          { "Data", "hpsw.data", FT_BYTES, BASE_NONE,
332
14
            NULL, 0x0, NULL, HFILL }},
333
14
    };
334
335
14
    static int *ett[] = {
336
14
        &ett_hpsw,
337
14
        &ett_hpsw_tlv
338
14
    };
339
340
14
    static ei_register_info ei[] = {
341
14
        { &ei_hpsw_tlvlength_bad, { "hpsw.tlv_len.bad", PI_PROTOCOL, PI_WARN, "Bad length", EXPFILL }},
342
14
    };
343
344
14
    expert_module_t* expert_hpsw;
345
346
14
    proto_hpsw = proto_register_protocol( "HP Switch Protocol", "HPSW", "hpsw");
347
14
    proto_register_field_array(proto_hpsw, hf, array_length(hf));
348
14
    proto_register_subtree_array(ett, array_length(ett));
349
14
    expert_hpsw = expert_register_protocol(proto_hpsw);
350
14
    expert_register_field_array(expert_hpsw, ei, array_length(ei));
351
352
14
    hpsw_handle = register_dissector("hpsw", dissect_hpsw, proto_hpsw);
353
14
}
354
355
void
356
proto_reg_handoff_hpsw(void)
357
14
{
358
14
    dissector_add_uint("hpext.dxsap", HPEXT_HPSW, hpsw_handle);
359
14
}
360
361
/*
362
 * Editor modelines
363
 *
364
 * Local Variables:
365
 * c-basic-offset: 4
366
 * tab-width: 8
367
 * indent-tabs-mode: nil
368
 * End:
369
 *
370
 * ex: set shiftwidth=4 tabstop=8 expandtab:
371
 * :indentSize=4:tabSize=8:noTabs=true:
372
 */