Wireshark 4.7.3
The Wireshark network protocol analyzer
Loading...
Searching...
No Matches
packet-nvme.h
1/* packet-nvme.h
2 * data structures for NVMe Dissection
3 * Copyright 2016
4 * Code by Parav Pandit
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#ifndef _PACKET_NVME_H_
13#define _PACKET_NVME_H_
14
15#define NVME_CMD_SIZE 64
16#define NVME_CQE_SIZE 16
17
18#define NVME_FABRIC_OPC 0x7F
19#define NVME_FCTYPE_PROP_SET 0x0
20#define NVME_FCTYPE_CONNECT 0x1
21#define NVME_FCTYPE_PROP_GET 0x4
22#define NVME_FCTYPE_AUTH_SEND 0x5
23#define NVME_FCTYPE_AUTH_RECV 0x6
24#define NVME_FCTYPE_DISCONNECT 0x8
25
26/*
27 * NVMe Admin command opcodes. Promoted here from packet-nvme.c so transports
28 * that reuse the admin-command decode (e.g. NVMe-MI over MCTP) can share both
29 * the opcode constants and the dissector below. The 0x14-0x8c entries (plus
30 * the Prohibited-only ones below, e.g. 0x19/0x1a) are the Admin opcodes that
31 * NVMe-MI 2.1 Figure 134 permits, respectively prohibits, over the Management
32 * Interface.
33 */
34#define NVME_AQ_OPC_DELETE_SQ 0x00
35#define NVME_AQ_OPC_CREATE_SQ 0x01
36#define NVME_AQ_OPC_GET_LOG_PAGE 0x02
37#define NVME_AQ_OPC_DELETE_CQ 0x04
38#define NVME_AQ_OPC_CREATE_CQ 0x05
39#define NVME_AQ_OPC_IDENTIFY 0x06
40#define NVME_AQ_OPC_ABORT 0x08
41#define NVME_AQ_OPC_SET_FEATURES 0x09
42#define NVME_AQ_OPC_GET_FEATURES 0x0a
43#define NVME_AQ_OPC_ASYNC_EVE_REQ 0x0c
44#define NVME_AQ_OPC_NS_MGMT 0x0d
45#define NVME_AQ_OPC_FW_COMMIT 0x10
46#define NVME_AQ_OPC_FW_IMG_DOWNLOAD 0x11
47#define NVME_AQ_OPC_SELF_TEST 0x14
48#define NVME_AQ_OPC_NS_ATTACH 0x15
49#define NVME_AQ_OPC_KEEP_ALIVE 0x18
50#define NVME_AQ_OPC_DIRECTIVE_SEND 0x19
51#define NVME_AQ_OPC_DIRECTIVE_RECV 0x1a
52#define NVME_AQ_OPC_VIRT_MGMT 0x1c
53#define NVME_AQ_OPC_MI_SEND 0x1d
54#define NVME_AQ_OPC_MI_RECV 0x1e
55#define NVME_AQ_OPC_CAP_MGMT 0x20
56#define NVME_AQ_OPC_DISC_INFO_MGMT 0x21
57#define NVME_AQ_OPC_FABRIC_ZONING_RECV 0x22
58#define NVME_AQ_OPC_LOCKDOWN 0x24
59#define NVME_AQ_OPC_FABRIC_ZONING_LOOKUP 0x25
60#define NVME_AQ_OPC_CLEAR_EXP_NVM_CFG 0x28
61#define NVME_AQ_OPC_FABRIC_ZONING_SEND 0x29
62#define NVME_AQ_OPC_CREATE_EXP_NVM_SUBSYS 0x2a
63#define NVME_AQ_OPC_MANAGE_EXP_NVM_SUBSYS 0x2d
64#define NVME_AQ_OPC_MANAGE_EXP_NS 0x31
65#define NVME_AQ_OPC_MANAGE_EXP_PORT 0x35
66#define NVME_AQ_OPC_CROSS_CTRL_RESET 0x38
67#define NVME_AQ_OPC_SEND_DISC_LOG_PAGE 0x39
68#define NVME_AQ_OPC_TRACK_SEND 0x3d
69#define NVME_AQ_OPC_TRACK_RECV 0x3e
70#define NVME_AQ_OPC_MIGRATION_SEND 0x41
71#define NVME_AQ_OPC_MIGRATION_RECV 0x42
72#define NVME_AQ_OPC_CTRL_DATA_QUEUE 0x45
73#define NVME_AQ_OPC_DBBUF_CONFIG 0x7c
74#define NVME_AQ_OPC_FORMAT_NVM 0x80
75#define NVME_AQ_OPC_SECURITY_SEND 0x81
76#define NVME_AQ_OPC_SECURITY_RECV 0x82
77#define NVME_AQ_OPC_SANITIZE 0x84
78#define NVME_AQ_OPC_LOAD_PROGRAM 0x85
79#define NVME_AQ_OPC_GET_LBA_STATUS 0x86
80#define NVME_AQ_OPC_PROG_ACTIVATION_MGMT 0x88
81#define NVME_AQ_OPC_MEM_RANGE_SET_MGMT 0x89
82#define NVME_AQ_OPC_SANITIZE_NS 0x8c
83
84#define NVME_IDENTIFY_CNS_IDENTIFY_NS 0x0
85#define NVME_IDENTIFY_CNS_IDENTIFY_CTRL 0x1
86#define NVME_IDENTIFY_CNS_IDENTIFY_NSLIST 0x2
87#define NVME_IDENTIFY_CNS_NSID_DESC_LIST 0x3
88#define NVME_IDENTIFY_CNS_NVM_SET_LIST 0x4
89#define NVME_IDENTIFY_CNS_CS_IND_NS 0x8
90#define NVME_IDENTIFY_CNS_NS_ALLOC_LIST 0x10
91#define NVME_IDENTIFY_CNS_NS_ALLOC 0x11
92#define NVME_IDENTIFY_CNS_CTRL_LIST_NS 0x12
93#define NVME_IDENTIFY_CNS_CTRL_LIST 0x13
94#define NVME_IDENTIFY_CNS_PRI_CTRL_CAP 0x14
95#define NVME_IDENTIFY_CNS_SEC_CTRL_LIST 0x15
96#define NVME_IDENTIFY_CNS_NS_GRAN_LIST 0x16
97#define NVME_IDENTIFY_CNS_UUID_LIST 0x17
98
99
101 wmem_tree_t *pending_cmds;
102 wmem_tree_t *done_cmds;
103 wmem_tree_t *data_requests;
104 wmem_tree_t *data_responses;
105 wmem_tree_t *data_offsets;
106 uint16_t qid;
107};
108
109#define NVME_CMD_MAX_TRS (16)
110
112 uint32_t cmd_pkt_num; /* pkt number of the cmd */
113 uint32_t cqe_pkt_num; /* pkt number of the cqe */
114
115 uint32_t data_req_pkt_num;
116 uint32_t data_tr_pkt_num[NVME_CMD_MAX_TRS];
117 uint32_t first_tr_psn;
118
119 nstime_t cmd_start_time;
120 nstime_t cmd_end_time;
121 uint32_t tr_bytes; /* bytes transferred so far */
122 bool fabric; /* indicate whether cmd fabric type or not */
123
124 union {
125 struct {
126 uint16_t cns;
127 } cmd_identify;
128 struct {
129 uint64_t off;
130 unsigned records;
131 unsigned tr_rcrd_id;
132 unsigned tr_off;
133 unsigned tr_sub_entries;
134 /* Number of Dwords (NUMDL in Command Dword 10 31:16 and NUMDU in
135 * Command Dword 11 15:0, one 0's based value across the dword
136 * boundary). Kept so a response decoder can tell "this window
137 * holds the whole transfer the host asked for" from "the rest is
138 * in a later window" -- without it a short descriptor list is
139 * indistinguishable from a partial NVMe-MI window. */
140 uint32_t numd;
141 /* Log Specific Identifier (Command Dword 11 31:16). The
142 * Endurance Group Information and Predictable Latency Per NVM Set
143 * log pages identify their subject only here -- neither response
144 * echoes it back (NVMe Base 2.3 Figures 221/222 and 223/224) -- so
145 * the response cannot be labelled without carrying it over from
146 * the request. */
147 uint16_t lsi;
148 uint8_t lid;
149 uint8_t tr_type;
150 } get_logpage;
151 struct {
152 uint8_t fid;
153 } set_features;
154 struct {
155 /* Dword 11: Security Send Transfer Length (the exact payload
156 * byte count) or Security Receive Allocation Length (an upper
157 * bound on it). Used to tell a partial transfer window apart
158 * from a complete payload. 0 when the request was not seen. */
159 uint32_t xfer_len;
160 /* Security Send/Receive Dword 10 selectors, saved on the
161 * request so the data payload (request data for Send, response
162 * data for Receive) can be dispatched to the right security-
163 * protocol dissector. */
164 uint16_t spsp; /* SP Specific (SPSP1:SPSP0); the ComID for TCG */
165 uint8_t secp; /* Security Protocol */
166 } security;
167 struct {
168 union {
169 struct {
170 uint8_t offset;
171 } prop_get;
172 struct {
173 uint16_t qid;
174 } cnct;
175 };
176 uint8_t fctype; /* fabric cmd type */
177 } fabric_cmd;
178 } cmd_ctx;
179 uint8_t opcode;
180};
181
182extern int hf_nvmeof_cmd_pkt;
183extern int hf_nvmeof_data_req;
184
185const char *get_nvmeof_cmd_string(uint8_t fctype);
186
187void
188nvme_publish_qid(proto_tree *tree, int field_index, uint16_t qid);
189
190void
191nvme_publish_cmd_latency(proto_tree *tree, struct nvme_cmd_ctx *cmd_ctx,
192 int field_index);
193void
194nvme_publish_to_cmd_link(proto_tree *tree, tvbuff_t *tvb,
195 int hf_index, struct nvme_cmd_ctx *cmd_ctx);
196void
197nvme_publish_to_cqe_link(proto_tree *tree, tvbuff_t *tvb,
198 int hf_index, struct nvme_cmd_ctx *cmd_ctx);
199void
200nvme_publish_to_data_req_link(proto_tree *tree, tvbuff_t *tvb,
201 int hf_index, struct nvme_cmd_ctx *cmd_ctx);
202void
203nvme_publish_to_data_resp_link(proto_tree *tree, tvbuff_t *tvb,
204 int hf_index, struct nvme_cmd_ctx *cmd_ctx);
205void
206nvme_publish_link(proto_tree *tree, tvbuff_t *tvb, int hf_index,
207 uint32_t pkt_no, bool zero_ok);
208
209void nvme_update_cmd_end_info(packet_info *pinfo, struct nvme_cmd_ctx *cmd_ctx);
210
211void
212nvme_add_cmd_to_pending_list(packet_info *pinfo, struct nvme_q_ctx *q_ctx,
213 struct nvme_cmd_ctx *cmd_ctx,
214 void *ctx, uint16_t cmd_id);
215void* nvme_lookup_cmd_in_pending_list(struct nvme_q_ctx *q_ctx, uint16_t cmd_id);
216
218{
219 uint64_t addr;
220 uint32_t key;
221 uint32_t size;
222};
223
224void
225dissect_nvmeof_fabric_cmd(tvbuff_t *nvme_tvb, packet_info *pinfo, proto_tree *nvme_tree,
226 struct nvme_q_ctx *q_ctx, struct nvme_cmd_ctx *cmd, unsigned off, bool link_data_req);
227void
228dissect_nvmeof_cmd_data(tvbuff_t *data_tvb, packet_info *pinfo, proto_tree *data_tree,
229 unsigned pkt_off, struct nvme_q_ctx *q_ctx, struct nvme_cmd_ctx *cmd, unsigned len);
230void
231dissect_nvmeof_fabric_cqe(tvbuff_t *nvme_tvb, packet_info *pinfo,
232 proto_tree *nvme_tree,
233 struct nvme_cmd_ctx *cmd_ctx, unsigned off);
234
235void
236nvme_add_data_request(struct nvme_q_ctx *q_ctx, struct nvme_cmd_ctx *cmd_ctx,
237 struct keyed_data_req *req);
238
239struct nvme_cmd_ctx*
240nvme_lookup_data_request(struct nvme_q_ctx *q_ctx, struct keyed_data_req *req);
241
242void
243nvme_add_data_tr_pkt(struct nvme_q_ctx *q_ctx,
244 struct nvme_cmd_ctx *cmd_ctx, uint32_t rkey, uint32_t frame_num);
245struct nvme_cmd_ctx*
246nvme_lookup_data_tr_pkt(struct nvme_q_ctx *q_ctx,
247 uint32_t rkey, uint32_t frame_num);
248
249void
250nvme_add_data_tr_off(struct nvme_q_ctx *q_ctx, uint32_t off, uint32_t frame_num);
251
252uint32_t
253nvme_lookup_data_tr_off(struct nvme_q_ctx *q_ctx, uint32_t frame_num);
254
255void
256nvme_add_cmd_cqe_to_done_list(struct nvme_q_ctx *q_ctx,
257 struct nvme_cmd_ctx *cmd_ctx, uint16_t cmd_id);
258void*
259nvme_lookup_cmd_in_done_list(packet_info *pinfo, struct nvme_q_ctx *q_ctx,
260 uint16_t cmd_id);
261
262void dissect_nvme_cmd_sgl(tvbuff_t *cmd_tvb, proto_tree *cmd_tree, int field_index,
263 struct nvme_q_ctx *q_ctx, struct nvme_cmd_ctx *cmd_ctx, unsigned cmd_off, bool visited);
264
265void
266dissect_nvme_cmd(tvbuff_t *nvme_tvb, packet_info *pinfo, proto_tree *root_tree,
267 struct nvme_q_ctx *q_ctx, struct nvme_cmd_ctx *cmd_ctx);
268
269void nvme_update_transfer_request(packet_info *pinfo, struct nvme_cmd_ctx *cmd_ctx, struct nvme_q_ctx *q_ctx);
270
271void
272dissect_nvme_data_response(tvbuff_t *nvme_tvb, packet_info *pinfo, proto_tree *root_tree,
273 struct nvme_q_ctx *q_ctx, struct nvme_cmd_ctx *cmd_ctx, unsigned len, bool is_inline);
274
275void
276dissect_nvme_cqe(tvbuff_t *nvme_tvb, packet_info *pinfo, proto_tree *root_tree,
277 struct nvme_q_ctx *q_ctx, struct nvme_cmd_ctx *cmd_ctx);
278
283const char *
284nvme_get_opcode_string(uint8_t opcode, uint16_t qid);
285
286/* CSTS.SHST shutdown-status names; shared with the NVMe-MI CHDS decode. */
287extern const value_string shst_table[];
288
297void
298nvme_dissect_admin_sqe_cdws(tvbuff_t *sqe_tvb, packet_info *pinfo,
299 proto_tree *tree, struct nvme_cmd_ctx *cmd_ctx);
300
309void
310nvme_dissect_admin_cqe_dw0(tvbuff_t *nvme_tvb, int dw0_off, proto_tree *cqe_tree,
311 uint16_t status, struct nvme_cmd_ctx *cmd_ctx);
312
319void
320nvme_dissect_cqe_status(tvbuff_t *nvme_tvb, packet_info *pinfo, int status_off,
321 proto_tree *cqe_tree);
322
323/*
324 * Passed as the 'data' void-pointer through the "nvme.security.secp"
325 * dissector table to security-protocol payload dissectors (e.g. TCG
326 * Storage). The payload tvb starts at logical offset 0 of the security
327 * protocol transfer; a later window (offset > 0) is never dispatched, and
328 * neither is a first window already known to be short (a Security Send
329 * whose length is below its Dword 11 Transfer Length). A Security Receive
330 * is always dispatched: its Dword 11 Allocation Length is only an upper
331 * bound, so a short payload there may well be a complete response.
332 * Sub-dissectors must reject a NULL data pointer (external callers such as
333 * Lua may drive the table directly).
334 */
336 bool send; /* true = Security Send payload (host to controller) */
337 uint8_t secp; /* Security Protocol */
338 uint16_t spsp; /* SP Specific (SPSP1:SPSP0); the ComID for TCG */
339};
340
351bool
352nvme_dissect_admin_data_resp(tvbuff_t *nvme_tvb, packet_info *pinfo,
353 proto_tree *cmd_tree, struct nvme_cmd_ctx *cmd_ctx,
354 unsigned off, unsigned len);
355
356/*
357 * Tells if opcode can be an opcode of io queue.
358 * Used to "Guess" queue type for nvme-tcp in case that "connect"
359 * command was not recorded
360 */
361int
362nvme_is_io_queue_opcode(uint8_t opcode);
363
364#endif
365
366/*
367 * Editor modelines - https://www.wireshark.org/tools/modelines.html
368 *
369 * Local variables:
370 * c-basic-offset: 4
371 * tab-width: 8
372 * indent-tabs-mode: nil
373 * End:
374 *
375 * vi: set shiftwidth=4 tabstop=8 expandtab:
376 * :indentSize=4:tabSize=8:noTabs=true:
377 */
struct _packet_info packet_info
Represents the metadata and indexing information for a single captured frame.
struct _wmem_tree_t wmem_tree_t
Opaque type representing a red-black tree in the wmem system.
Definition wmem_tree.h:49
Definition packet-nvme.h:218
Definition nstime.h:26
Definition packet-nvme.h:111
Definition packet-nvme.h:100
Definition packet-nvme.h:335
struct _value_string value_string
Mapping between a 32-bit integer value and its string representation.