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-hyperscsi.c
Line
Count
Source
1
/* packet-hyperscsi.c
2
 * Routines for disassembly of the Hyper SCSI protocol.
3
 *
4
 * Wireshark - Network traffic analyzer
5
 * By Gerald Combs <gerald@wireshark.org>
6
 * Copyright 1998 Gerald Combs
7
 * Copyright 2002 Richard Sharpe <rsharpe@richardsharpe.com>
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/tfs.h>
16
#include <wsutil/array.h>
17
18
void proto_register_hyperscsi(void);
19
void proto_reg_handoff_hyperscsi(void);
20
21
static int proto_hyperscsi;
22
23
static int hf_hs_cmd;
24
static int hf_hs_ver;
25
static int hf_hs_res;
26
static int hf_hs_tagno;
27
static int hf_hs_lastfrag;
28
static int hf_hs_fragno;
29
30
static int ett_hyperscsi;
31
static int ett_hs_hdr;
32
static int ett_hs_pdu;
33
34
static dissector_handle_t hs_handle;
35
36
static const true_false_string tfs_lastfrag = {
37
  "Last Fragment",
38
  "Not Last Fragment"
39
};
40
41
#define HSCSI_OPCODE_REQUEST                  0x00
42
#define HSCSI_OPCODE_REPLY                    0x01
43
#define HSCSI_OPCODE_DEV_DISCOVERY            0x10
44
#define HSCSI_OPCODE_ADN_REQUEST              0x11
45
#define HSCSI_OPCODE_ADN_REPLY                0x12
46
#define HSCSI_OPCODE_DISCONNECT               0x13
47
#define HSCSI_OPCODE_ACK_SNR                  0x20
48
#define HSCSI_OPCODE_ACK_REPLY                0x21
49
#define HSCSI_OPCODE_ADDR_REPORT              0x30
50
#define HSCSI_OPCODE_ADDR_REPLY               0x31
51
#define HSCSI_OPCODE_LOCAL_REQUEST            0x32
52
#define HSCSI_OPCODE_LOCAL_REPLY              0x33
53
#define HSCSI_OPCODE_REMOTE_REQUEST           0x34
54
#define HSCSI_OPCODE_REMOTE_REPLY             0x35
55
56
static const value_string hscsi_opcodes[] = {
57
  { HSCSI_OPCODE_REQUEST,         "Command Block Encap Request"},
58
  { HSCSI_OPCODE_REPLY,           "Command Block Encap Reply"},
59
  { HSCSI_OPCODE_DEV_DISCOVERY,   "Device Discovery Reply"},
60
  { HSCSI_OPCODE_ADN_REQUEST,     "Auth/Device Neg Request"},
61
  { HSCSI_OPCODE_ADN_REPLY,       "Auth/Device Neg Reply"},
62
  { HSCSI_OPCODE_DISCONNECT,      "Disconnect Request"},
63
  { HSCSI_OPCODE_ACK_SNR,         "Flow Control Setup/Ack Request"},
64
  { HSCSI_OPCODE_ACK_REPLY,       "Flow Control Ack Reply"},
65
  { 0, NULL}
66
};
67
68
4
#define OPCODE_MASK 0x7F
69
70
static int
71
dissect_hyperscsi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
72
4
{
73
4
  unsigned   hs_hdr1, hs_hdr2, hs_hdr3;
74
4
  uint8_t    hs_res;
75
4
  uint16_t   hs_tagno;
76
4
  uint16_t   hs_fragno;
77
4
  int        offset = 0;
78
4
  proto_tree *hs_hdr_tree, *hs_pdu_tree;
79
4
  proto_tree *hs_tree;
80
4
  proto_item *ti;
81
4
  uint8_t    hs_cmd, hs_ver;
82
83
4
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "HyperSCSI");
84
4
  col_clear(pinfo->cinfo, COL_INFO);
85
86
4
  ti = proto_tree_add_item(tree, proto_hyperscsi, tvb, offset, -1, ENC_NA);
87
4
  hs_tree = proto_item_add_subtree(ti, ett_hyperscsi);
88
89
4
  hs_hdr1 = tvb_get_uint8(tvb, offset);
90
4
  offset++;
91
4
  hs_hdr2 = tvb_get_uint8(tvb, offset);
92
4
  offset++;
93
4
  hs_hdr3 = tvb_get_uint8(tvb, offset);
94
4
  offset++;
95
96
4
  hs_res = hs_hdr1 >> 4;
97
4
  hs_tagno = ((hs_hdr1 & 0x0F) << 5 ) | (hs_hdr2 >> 3);
98
4
  hs_fragno = ((hs_hdr2 &0X03) << 8 ) | hs_hdr3;
99
100
  /*
101
   * Add the header ... three bytes
102
   */
103
104
4
  if (tree) {
105
3
    hs_hdr_tree = proto_tree_add_subtree(hs_tree, tvb, 0, 3, ett_hs_hdr, NULL, "HyperSCSI Header");
106
107
    /*
108
     * Now, add the header items
109
     */
110
111
3
    proto_tree_add_uint(hs_hdr_tree, hf_hs_res, tvb, 0, 1, hs_res);
112
3
    proto_tree_add_uint(hs_hdr_tree, hf_hs_tagno, tvb, 0, 2, hs_tagno);
113
3
    proto_tree_add_item(hs_hdr_tree, hf_hs_lastfrag, tvb, 1, 1, ENC_BIG_ENDIAN);
114
3
    proto_tree_add_uint(hs_hdr_tree, hf_hs_fragno, tvb, 1, 2, hs_fragno);
115
116
3
  }
117
118
  /*
119
   * Now, add the PDU
120
   */
121
122
4
  hs_ver = tvb_get_uint8(tvb, offset++);
123
124
4
  hs_cmd = tvb_get_uint8(tvb, offset);
125
126
4
  hs_cmd &= OPCODE_MASK;
127
128
4
  col_append_str(pinfo->cinfo, COL_INFO,
129
4
                   val_to_str(pinfo->pool, hs_cmd, hscsi_opcodes, "Unknown HyperSCSI Request or Response (%u)"));
130
131
4
  if (tree) {
132
3
    hs_pdu_tree = proto_tree_add_subtree(hs_tree, tvb, 3, -1, ett_hs_pdu, NULL, "HyperSCSI PDU");
133
134
3
    proto_tree_add_uint(hs_pdu_tree, hf_hs_ver, tvb, 3, 1, hs_ver);
135
136
3
    proto_tree_add_uint(hs_pdu_tree, hf_hs_cmd, tvb, 4, 1, hs_cmd);
137
3
  }
138
139
4
  return tvb_captured_length(tvb);
140
4
}
141
142
void
143
proto_register_hyperscsi(void)
144
16
{
145
146
16
  static hf_register_info hf[] = {
147
16
    { &hf_hs_res,
148
16
      { "Reserved", "hyperscsi.reserved", FT_UINT8, BASE_DEC, NULL, 0x0,
149
16
        NULL, HFILL}},
150
151
16
    { &hf_hs_tagno,
152
16
      { "Tag No", "hyperscsi.tagno", FT_UINT16, BASE_DEC, NULL, 0x0,
153
16
        NULL, HFILL }},
154
155
16
    { &hf_hs_lastfrag,
156
16
      { "Last Fragment", "hyperscsi.lastfrag", FT_BOOLEAN, 8, TFS(&tfs_lastfrag), 0x04, NULL, HFILL}},
157
158
16
    { &hf_hs_fragno,
159
16
      { "Fragment No", "hyperscsi.fragno", FT_UINT16, BASE_DEC, NULL, 0x0,
160
16
        NULL, HFILL}},
161
162
16
    { &hf_hs_ver,
163
16
      { "HyperSCSI Version", "hyperscsi.version", FT_UINT8, BASE_DEC, NULL,
164
16
        0x0, NULL, HFILL}},
165
166
16
    { &hf_hs_cmd,
167
16
      { "HyperSCSI Command", "hyperscsi.cmd", FT_UINT8, BASE_DEC, VALS(hscsi_opcodes), 0x0,
168
16
        NULL, HFILL}},
169
16
  };
170
171
16
  static int *ett[] = {
172
16
    &ett_hyperscsi,
173
16
    &ett_hs_hdr,
174
16
    &ett_hs_pdu,
175
16
  };
176
177
16
  proto_hyperscsi = proto_register_protocol("HyperSCSI", "HyperSCSI", "hyperscsi");
178
16
  proto_register_field_array(proto_hyperscsi, hf, array_length(hf));
179
16
  proto_register_subtree_array(ett, array_length(ett));
180
181
16
  hs_handle = register_dissector("hyperscsi", dissect_hyperscsi, proto_hyperscsi);
182
16
}
183
184
/* XXX <epan/etypes.h> */
185
16
#define ETHERTYPE_HYPERSCSI 0x889A
186
187
void
188
proto_reg_handoff_hyperscsi(void)
189
16
{
190
16
  dissector_add_uint("ethertype", ETHERTYPE_HYPERSCSI, hs_handle);
191
192
16
}
193
194
/*
195
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
196
 *
197
 * Local Variables:
198
 * c-basic-offset: 2
199
 * tab-width: 8
200
 * indent-tabs-mode: nil
201
 * End:
202
 *
203
 * ex: set shiftwidth=2 tabstop=8 expandtab:
204
 * :indentSize=2:tabSize=8:noTabs=true:
205
 */