From d06781ee9b8283d5f02103eee6e65861689fe27b Mon Sep 17 00:00:00 2001 From: Constantine Gavrilov Date: Mon, 28 Feb 2022 16:49:15 +0200 Subject: [PATCH] NVMe: fix decoding of bad CQE status. --- epan/dissectors/packet-nvme.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/epan/dissectors/packet-nvme.c b/epan/dissectors/packet-nvme.c index faf4e74f84..50e1f2b3cd 100644 --- a/epan/dissectors/packet-nvme.c +++ b/epan/dissectors/packet-nvme.c @@ -776,6 +776,17 @@ typedef enum { NVME_CQE_SC_CMD_WRITE_TO_RO_REGION = 0x82, } nvme_cqe_sc_cmd_t; +typedef enum { + NVMEOF_CQE_SC_CMD_INCOMPAT_FORMAT = 0x80, + NVMEOF_CQE_SC_CMD_CONT_BUSY = 0x81, + NVMEOF_CQE_SC_CMD_CNCT_INV_PARAMS = 0x82, + NVMEOF_CQE_SC_CMD_CNCT_RESTART_DISC = 0x83, + NVMEOF_CQE_SC_CMD_CNCT_INV_HOST = 0x84, + NVMEOF_CQE_SC_CMD_INV_QUEUE_TYPE = 0x85, + NVMEOF_CQE_SC_CMD_DISC_RESTART = 0x90, + NVMEOF_CQE_SC_CMD_AUTH_REQ = 0x91, +} nvmeof_cqe_sc_cmd_t; + typedef enum { NVME_CQE_SC_MEDIA_WRITE_FAULT = 0x80, NVME_CQE_SC_MEDIA_READ_FAULT = 0x81, @@ -895,6 +906,18 @@ static const value_string nvme_cqe_sc_cmd_tbl[] = { { 0, NULL }, }; +static const value_string nvmeof_cqe_sc_cmd_tbl[] = { + { NVMEOF_CQE_SC_CMD_INCOMPAT_FORMAT, "Incompatible Format" }, + { NVMEOF_CQE_SC_CMD_CONT_BUSY, "Controller Busy" }, + { NVMEOF_CQE_SC_CMD_CNCT_INV_PARAMS, "Connect Invalid Parameters" }, + { NVMEOF_CQE_SC_CMD_CNCT_RESTART_DISC, "Connect Restart Discovery" }, + { NVMEOF_CQE_SC_CMD_CNCT_INV_HOST, "Connect Invalid Host" }, + { NVMEOF_CQE_SC_CMD_INV_QUEUE_TYPE, "Invalid Queue Type" }, + { NVMEOF_CQE_SC_CMD_DISC_RESTART, "Discover Restart" }, + { NVMEOF_CQE_SC_CMD_AUTH_REQ, "Authentication Required" }, + { 0, NULL }, +}; + static const value_string nvme_cqe_sc_media_tbl[] = { { NVME_CQE_SC_MEDIA_WRITE_FAULT, "Write Fault" }, { NVME_CQE_SC_MEDIA_READ_FAULT, "Unrecovered Read Error" }, @@ -4190,11 +4213,12 @@ nvme_is_io_queue_opcode(guint8 opcode) (opcode == NVME_IOQ_OPC_RESV_RELEASE)); } -static const char *get_cqe_sc_string(guint sct, guint sc) +static const char *get_cqe_sc_string(guint sct, guint sc, gboolean nvmeof) { switch (sct) { case NVME_CQE_SCT_GENERIC: return val_to_str_const(sc, nvme_cqe_sc_gen_tbl, "Unknown Status Code"); - case NVME_CQE_SCT_COMMAND: return val_to_str_const(sc, nvme_cqe_sc_cmd_tbl, "Unknown Status Code"); + case NVME_CQE_SCT_COMMAND: return (nvmeof) ? val_to_str_const(sc, nvmeof_cqe_sc_cmd_tbl, "Unknown Fabrics Status Code") : + val_to_str_const(sc, nvme_cqe_sc_cmd_tbl, "Unknown Status Code"); case NVME_CQE_SCT_MEDIA: return val_to_str_const(sc, nvme_cqe_sc_media_tbl, "Unknown Status Code"); case NVME_CQE_SCT_PATH: return val_to_str_const(sc, nvme_cqe_sc_path_tbl, "Unknown Status Code"); case NVME_CQE_SCT_VENDOR: return "Vendor Error"; @@ -4330,7 +4354,7 @@ static void dissect_nvme_cqe_common(tvbuff_t *nvme_tvb, proto_tree *cqe_tree, gu proto_tree_add_item(grp, hf_nvme_cqe_status[1], nvme_tvb, off+14, 2, ENC_LITTLE_ENDIAN); ti = proto_tree_add_item(grp, hf_nvme_cqe_status[2], nvme_tvb, off+14, 2, ENC_LITTLE_ENDIAN); - proto_item_append_text(ti, " (%s)", get_cqe_sc_string((val & 0xE00) >> 1, (val & 0x1FE) >> 9)); + proto_item_append_text(ti, " (%s)", get_cqe_sc_string((val & 0xE00) >> 9, (val & 0x1FE) >> 1, nvmeof)); for (i = 3; i < array_length(hf_nvme_cqe_status); i++) proto_tree_add_item(grp, hf_nvme_cqe_status[i], nvme_tvb, off+14, 2, ENC_LITTLE_ENDIAN);