Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-hpsw.c
Line
Count
Source
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
0
#define HPFOO_DEVICE_NAME     0x1
54
0
#define HPFOO_DEVICE_VERSION  0x2
55
0
#define HPFOO_CONFIG_NAME     0x3
56
0
#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
0
#define HPFOO_FIELD_8         0x8
61
0
#define HPFOO_FIELD_9         0x9
62
0
#define HPFOO_FIELD_10        0xa
63
0
#define HPFOO_NEIGHBORS       0xb
64
0
#define HPFOO_FIELD_12        0xc
65
0
#define HPFOO_DEVICE_ID       0xd
66
0
#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
0
{
90
0
    switch (type) {
91
92
0
    case HPFOO_DEVICE_NAME:
93
0
        if (length > 0) {
94
0
            proto_tree_add_item(tree, hf_hpsw_device_name, tvb, offset, length, ENC_ASCII);
95
0
        } else {
96
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Device Name: Bad length %u", length);
97
0
        }
98
0
        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_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
0
    case HPFOO_CONFIG_NAME:
109
0
        if (length > 0) {
110
0
            proto_tree_add_item(tree, hf_hpsw_config_name, tvb, offset, length, ENC_ASCII);
111
0
        } else {
112
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Config Name: Bad length %u", length);
113
0
        }
114
0
        break;
115
116
0
    case HPFOO_ROOT_MAC_ADDR:
117
0
        if (length == 6) {
118
0
            proto_tree_add_item(tree, hf_hpsw_root_mac_addr, tvb, offset, length, ENC_NA);
119
0
        } else {
120
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Root MAC Addr: Bad length %u", length);
121
0
        }
122
0
        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_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
0
    case HPFOO_FIELD_8:
149
0
        if (length == 2) {
150
0
            proto_tree_add_item(tree, hf_hpsw_field_8, tvb, offset, length, ENC_BIG_ENDIAN);
151
0
        } else {
152
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Field 8: Bad length %u", length);
153
0
        }
154
0
        break;
155
156
0
    case HPFOO_FIELD_9:
157
0
        if (length == 2) {
158
0
            proto_tree_add_item(tree, hf_hpsw_field_9, tvb, offset, length, ENC_BIG_ENDIAN);
159
0
        } else {
160
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Field 9: Bad length %u", length);
161
0
        }
162
0
        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
0
    case HPFOO_NEIGHBORS:
173
0
        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
0
        } else {
182
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Neighbors: Bad length %u", length);
183
0
        }
184
0
        break;
185
186
0
    case HPFOO_FIELD_12:
187
0
        if (length == 1) {
188
0
            proto_tree_add_item(tree, hf_hpsw_field_12, tvb, offset, length, ENC_BIG_ENDIAN);
189
0
        } else {
190
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Field 12: Bad length %u", length);
191
0
        }
192
0
        break;
193
194
0
    case HPFOO_DEVICE_ID:
195
0
        if (length > 6) {
196
0
            proto_tree_add_item(tree, hf_hpsw_device_id, tvb, offset, 6, ENC_NA);
197
0
            proto_tree_add_item(tree, hf_hpsw_device_id_data, tvb, offset+6, length-6, ENC_NA);
198
0
        } else {
199
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Device ID: Bad length %u", length);
200
0
        }
201
0
        break;
202
203
0
    case HPFOO_OWN_MAC_ADDR:
204
0
        if (length == 6) {
205
0
            proto_tree_add_item(tree, hf_hpsw_own_mac_addr, tvb, offset, length, ENC_NA);
206
0
        } else {
207
0
            expert_add_info_format(pinfo, ti, &ei_hpsw_tlvlength_bad, "Own MAC Addr: Bad length %u", length);
208
0
        }
209
0
        break;
210
211
0
    default:
212
0
        proto_tree_add_item(tree, hf_hpsw_data, tvb, offset, length, ENC_NA);
213
0
        break;
214
0
    }
215
0
}
216
217
static int
218
dissect_hpsw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
219
0
{
220
0
    proto_tree *hp_tree;
221
0
    proto_tree *tlv_tree;
222
0
    proto_item *ti;
223
0
    uint8_t     version;
224
0
    int         offset = 0;
225
226
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "HP");
227
0
    col_set_str(pinfo->cinfo, COL_INFO, "HP Switch Protocol");
228
229
0
    version = tvb_get_uint8(tvb, 0);
230
231
0
    ti = proto_tree_add_item(tree, proto_hpsw, tvb, 0, -1, ENC_NA);
232
0
    hp_tree = proto_item_add_subtree(ti, ett_hpsw);
233
0
    proto_tree_add_uint(hp_tree, hf_hpsw_version, tvb, 0, 1, version);
234
0
    offset += 1;
235
236
0
    proto_tree_add_item(hp_tree, hf_hpsw_type, tvb, 1, 1, ENC_BIG_ENDIAN);
237
0
    offset += 1;
238
239
0
    while ( tvb_reported_length_remaining(tvb, offset) > 0 )
240
0
    {
241
0
        uint8_t type, length;
242
243
0
        type   = tvb_get_uint8(tvb, offset);
244
0
        length = tvb_get_uint8(tvb, offset+1);
245
246
        /* make sure still in valid tlv */
247
0
        if (( length < 1 ) || ( length > tvb_reported_length_remaining(tvb, offset+2)))
248
0
            break;
249
250
0
        tlv_tree = proto_tree_add_subtree(hp_tree, tvb, offset, length+2, ett_hpsw_tlv, NULL,
251
0
                                 val_to_str(pinfo->pool, type, hpsw_tlv_type_vals, "Unknown TLV type: 0x%02x"));
252
253
        /* type */
254
0
        proto_tree_add_uint(tlv_tree, hf_hpsw_tlvtype, tvb, offset, 1, type);
255
0
        offset += 1;
256
257
        /* LENGTH (not inclusive of type and length bytes) */
258
0
        ti = proto_tree_add_uint(tlv_tree, hf_hpsw_tlvlength, tvb, offset, 1, length);
259
0
        offset += 1;
260
261
0
        dissect_hpsw_tlv(tvb, pinfo, offset, length, tlv_tree, ti, type);
262
263
0
        offset += length;
264
265
0
    }
266
0
    return tvb_captured_length(tvb);
267
0
}
268
269
void
270
proto_register_hpsw(void)
271
16
{
272
16
    static hf_register_info hf[] = {
273
16
        { &hf_hpsw_version,
274
16
          { "Version", "hpsw.version", FT_UINT8, BASE_HEX,
275
16
            NULL, 0x0, NULL, HFILL }},
276
16
        { &hf_hpsw_type,
277
16
          { "Type", "hpsw.type", FT_UINT8, BASE_HEX,
278
16
            NULL, 0x0, NULL, HFILL }},
279
16
        { &hf_hpsw_tlvtype,
280
16
          { "Type", "hpsw.tlv_type", FT_UINT8, BASE_HEX,
281
16
            VALS(hpsw_tlv_type_vals), 0x0, NULL, HFILL }},
282
16
        { &hf_hpsw_tlvlength,
283
16
          { "Length", "hpsw.tlv_len", FT_UINT8, BASE_DEC,
284
16
            NULL, 0x0, NULL, HFILL }},
285
16
        { &hf_hpsw_device_name,
286
16
          { "Device Name", "hpsw.device_name", FT_STRING, BASE_NONE,
287
16
            NULL, 0x0, NULL, HFILL }},
288
16
        { &hf_hpsw_device_version,
289
16
          { "Version", "hpsw.device_version", FT_STRING, BASE_NONE,
290
16
            NULL, 0x0, NULL, HFILL }},
291
16
        { &hf_hpsw_config_name,
292
16
          { "Config Name", "hpsw.config_name", FT_STRING, BASE_NONE,
293
16
            NULL, 0x0, NULL, HFILL }},
294
16
        { &hf_hpsw_root_mac_addr,
295
16
          { "Root MAC Addr", "hpsw.root_mac_addr", FT_ETHER, BASE_NONE,
296
16
            NULL, 0x0, NULL, HFILL }},
297
16
        { &hf_hpsw_ip_addr,
298
16
          { "IP Addr", "hpsw.ip_addr", FT_IPv4, BASE_NONE,
299
16
            NULL, 0x0, NULL, HFILL }},
300
16
        { &hf_hpsw_field_6,
301
16
          { "Field 6", "hpsw.field_6", FT_UINT16, BASE_HEX,
302
16
            NULL, 0x0, NULL, HFILL }},
303
16
        { &hf_hpsw_domain,
304
16
          { "Domain", "hpsw.domain", FT_STRING, BASE_NONE,
305
16
            NULL, 0x0, NULL, HFILL }},
306
16
        { &hf_hpsw_field_8,
307
16
          { "Field 8", "hpsw.field_8", FT_UINT16, BASE_HEX,
308
16
            NULL, 0x0, NULL, HFILL }},
309
16
        { &hf_hpsw_field_9,
310
16
          { "Field 9", "hpsw.field_9", FT_UINT16, BASE_HEX,
311
16
            NULL, 0x0, NULL, HFILL }},
312
16
        { &hf_hpsw_field_10,
313
16
          { "Field 10", "hpsw.field_10", FT_UINT32, BASE_HEX,
314
16
            NULL, 0x0, NULL, HFILL }},
315
16
        { &hf_hpsw_neighbor_mac_addr,
316
16
          { "MAC Addr", "hpsw.neighbor_mac_addr", FT_ETHER, BASE_NONE,
317
16
            NULL, 0x0, NULL, HFILL }},
318
16
        { &hf_hpsw_field_12,
319
16
          { "Field 12", "hpsw.field_12", FT_UINT8, BASE_HEX,
320
16
            NULL, 0x0, NULL, HFILL }},
321
16
        { &hf_hpsw_own_mac_addr,
322
16
          { "Own MAC Addr", "hpsw.own_mac_addr", FT_ETHER, BASE_NONE,
323
16
            NULL, 0x0, NULL, HFILL }},
324
16
        { &hf_hpsw_device_id,
325
16
          { "Device ID", "hpsw.device_id", FT_ETHER, BASE_NONE,
326
16
            NULL, 0x0, NULL, HFILL }},
327
16
        { &hf_hpsw_device_id_data,
328
16
          { "Data", "hpsw.device_id_data", FT_BYTES, BASE_NONE,
329
16
            NULL, 0x0, NULL, HFILL }},
330
16
        { &hf_hpsw_data,
331
16
          { "Data", "hpsw.data", FT_BYTES, BASE_NONE,
332
16
            NULL, 0x0, NULL, HFILL }},
333
16
    };
334
335
16
    static int *ett[] = {
336
16
        &ett_hpsw,
337
16
        &ett_hpsw_tlv
338
16
    };
339
340
16
    static ei_register_info ei[] = {
341
16
        { &ei_hpsw_tlvlength_bad, { "hpsw.tlv_len.bad", PI_PROTOCOL, PI_WARN, "Bad length", EXPFILL }},
342
16
    };
343
344
16
    expert_module_t* expert_hpsw;
345
346
16
    proto_hpsw = proto_register_protocol( "HP Switch Protocol", "HPSW", "hpsw");
347
16
    proto_register_field_array(proto_hpsw, hf, array_length(hf));
348
16
    proto_register_subtree_array(ett, array_length(ett));
349
16
    expert_hpsw = expert_register_protocol(proto_hpsw);
350
16
    expert_register_field_array(expert_hpsw, ei, array_length(ei));
351
352
16
    hpsw_handle = register_dissector("hpsw", dissect_hpsw, proto_hpsw);
353
16
}
354
355
void
356
proto_reg_handoff_hpsw(void)
357
16
{
358
16
    dissector_add_uint("hpext.dxsap", HPEXT_HPSW, hpsw_handle);
359
16
}
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
 */