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 20 struct nvme_q_ctx { 21 wmem_tree_t *pending_cmds; 22 wmem_tree_t *done_cmds; 23 wmem_tree_t *data_requests; 24 wmem_tree_t *data_responses; 25 guint16 qid; 26 }; 27 28 struct nvme_cmd_ctx { 29 guint32 cmd_pkt_num; /* pkt number of the cmd */ 30 guint32 cqe_pkt_num; /* pkt number of the cqe */ 31 32 guint32 data_req_pkt_num; 33 guint32 data_resp_pkt_num; 34 35 nstime_t cmd_start_time; 36 nstime_t cmd_end_time; 37 gboolean fabric; /* indicate whether cmd fabric type or not */ 38 39 union { 40 struct { 41 guint16 cns; 42 } cmd_identify; 43 struct { 44 guint16 lsi; 45 guint8 lid; 46 guint8 lsp; 47 guint64 off; 48 guint8 uid_idx; 49 } get_logpage; 50 struct { 51 guint8 fid; 52 } set_features; 53 struct { 54 guint8 fctype; /* fabric cmd type */ 55 struct { 56 guint8 offset; 57 } prop_get; 58 } fabric_cmd; 59 } cmd_ctx; 60 guint8 opcode; 61 }; 62 63 extern int hf_nvmeof_cmd_pkt; 64 extern int hf_nvmeof_data_req; 65 66 const gchar *get_nvmeof_cmd_string(guint8 fctype); 67 68 void 69 nvme_publish_qid(proto_tree *tree, int field_index, guint16 qid); 70 71 void 72 nvme_publish_cmd_latency(proto_tree *tree, struct nvme_cmd_ctx *cmd_ctx, 73 int field_index); 74 void 75 nvme_publish_to_cmd_link(proto_tree *tree, tvbuff_t *tvb, 76 int hf_index, struct nvme_cmd_ctx *cmd_ctx); 77 void 78 nvme_publish_to_cqe_link(proto_tree *tree, tvbuff_t *tvb, 79 int hf_index, struct nvme_cmd_ctx *cmd_ctx); 80 void 81 nvme_publish_to_data_req_link(proto_tree *tree, tvbuff_t *tvb, 82 int hf_index, struct nvme_cmd_ctx *cmd_ctx); 83 void 84 nvme_publish_to_data_resp_link(proto_tree *tree, tvbuff_t *tvb, 85 int hf_index, struct nvme_cmd_ctx *cmd_ctx); 86 void nvme_update_cmd_end_info(packet_info *pinfo, struct nvme_cmd_ctx *cmd_ctx); 87 88 void 89 nvme_add_cmd_to_pending_list(packet_info *pinfo, struct nvme_q_ctx *q_ctx, 90 struct nvme_cmd_ctx *cmd_ctx, 91 void *ctx, guint16 cmd_id); 92 void* nvme_lookup_cmd_in_pending_list(struct nvme_q_ctx *q_ctx, guint16 cmd_id); 93 94 struct keyed_data_req 95 { 96 guint64 addr; 97 guint32 key; 98 guint32 size; 99 }; 100 101 void 102 dissect_nvmeof_fabric_cmd(tvbuff_t *nvme_tvb, packet_info *pinfo, proto_tree *nvme_tree, 103 struct nvme_q_ctx *q_ctx, struct nvme_cmd_ctx *cmd, guint off, gboolean link_data_req); 104 void 105 dissect_nvmeof_cmd_data(tvbuff_t *data_tvb, packet_info *pinfo, proto_tree *data_tree, 106 guint offset, struct nvme_cmd_ctx *cmd, guint len); 107 void 108 dissect_nvmeof_fabric_cqe(tvbuff_t *nvme_tvb, packet_info *pinfo, 109 proto_tree *nvme_tree, 110 struct nvme_cmd_ctx *cmd_ctx, guint off); 111 112 void 113 nvme_add_data_request(struct nvme_q_ctx *q_ctx, struct nvme_cmd_ctx *cmd_ctx, 114 struct keyed_data_req *req); 115 116 struct nvme_cmd_ctx* 117 nvme_lookup_data_request(struct nvme_q_ctx *q_ctx, struct keyed_data_req *req); 118 119 void 120 nvme_add_data_response(struct nvme_q_ctx *q_ctx, 121 struct nvme_cmd_ctx *cmd_ctx, guint32 rkey, guint32 frame_num); 122 struct nvme_cmd_ctx* 123 nvme_lookup_data_response(struct nvme_q_ctx *q_ctx, 124 guint32 rkey, guint32 frame_num); 125 126 void 127 nvme_add_cmd_cqe_to_done_list(struct nvme_q_ctx *q_ctx, 128 struct nvme_cmd_ctx *cmd_ctx, guint16 cmd_id); 129 void* 130 nvme_lookup_cmd_in_done_list(packet_info *pinfo, struct nvme_q_ctx *q_ctx, 131 guint16 cmd_id); 132 133 void dissect_nvme_cmd_sgl(tvbuff_t *cmd_tvb, proto_tree *cmd_tree, int field_index, 134 struct nvme_q_ctx *q_ctx, struct nvme_cmd_ctx *cmd_ctx, guint cmd_off, gboolean visited); 135 136 void 137 dissect_nvme_cmd(tvbuff_t *nvme_tvb, packet_info *pinfo, proto_tree *root_tree, 138 struct nvme_q_ctx *q_ctx, struct nvme_cmd_ctx *cmd_ctx); 139 140 void nvme_update_transfer_request(packet_info *pinfo, struct nvme_cmd_ctx *cmd_ctx, struct nvme_q_ctx *q_ctx); 141 142 void 143 dissect_nvme_data_response(tvbuff_t *nvme_tvb, packet_info *pinfo, proto_tree *root_tree, 144 struct nvme_q_ctx *q_ctx, struct nvme_cmd_ctx *cmd_ctx, guint len, gboolean is_inline); 145 146 void 147 dissect_nvme_cqe(tvbuff_t *nvme_tvb, packet_info *pinfo, proto_tree *root_tree, 148 struct nvme_q_ctx *q_ctx, struct nvme_cmd_ctx *cmd_ctx); 149 150 /** 151 * Returns string representation of opcode according 152 * to opcode and queue id 153 */ 154 const gchar * 155 nvme_get_opcode_string(guint8 opcode, guint16 qid); 156 157 /* 158 * Tells if opcode can be an opcode of io queue. 159 * Used to "Guess" queue type for nvme-tcp in case that "connect" 160 * command was not recorded 161 */ 162 int 163 nvme_is_io_queue_opcode(guint8 opcode); 164 165 #endif 166 167 /* 168 * Editor modelines - https://www.wireshark.org/tools/modelines.html 169 * 170 * Local variables: 171 * c-basic-offset: 4 172 * tab-width: 8 173 * indent-tabs-mode: nil 174 * End: 175 * 176 * vi: set shiftwidth=4 tabstop=8 expandtab: 177 * :indentSize=4:tabSize=8:noTabs=true: 178 */ 179