forked from osmocom/wireshark
nvme-tcp: Add C2H/H2C TermReq dissection
Section 7.4.10.4 and 7.4.10.5 of the spec. Change-Id: I175f98ca8265eb369344d5dcaff7bdf0943372c3 Signed-off-by: Dmitry Radivonchik <mitya@oktetlabs.ru> Reviewed-on: https://code.wireshark.org/review/34470 Reviewed-by: Jaap Keuter <jaap.keuter@xs4all.nl> Petri-Dish: Jaap Keuter <jaap.keuter@xs4all.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
3ebf2e2d51
commit
b66b3c63a9
|
@ -81,6 +81,28 @@ static const value_string nvme_tcp_pdu_type_vals[] = {
|
|||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static const value_string nvme_tcp_termreq_fes[] = {
|
||||
{0x0, "Reserved" },
|
||||
{0x1, "Invalid PDU Header Field" },
|
||||
{0x2, "PDU Sequence Error" },
|
||||
{0x3, "Header Digest Error" },
|
||||
{0x4, "Data Transfer Out of Range" },
|
||||
{0x5, "R2T Limit Exceeded" },
|
||||
{0x6, "Unsupported Parameter" },
|
||||
{0, NULL },
|
||||
};
|
||||
|
||||
enum nvme_tcp_fatal_error_status
|
||||
{
|
||||
NVME_TCP_FES_INVALID_PDU_HDR = 0x01,
|
||||
NVME_TCP_FES_PDU_SEQ_ERR = 0x02,
|
||||
NVME_TCP_FES_HDR_DIGEST_ERR = 0x03,
|
||||
NVME_TCP_FES_DATA_OUT_OF_RANGE = 0x04,
|
||||
NVME_TCP_FES_R2T_LIMIT_EXCEEDED = 0x05,
|
||||
NVME_TCP_FES_DATA_LIMIT_EXCEEDED = 0x05,
|
||||
NVME_TCP_FES_UNSUPPORTED_PARAM = 0x06,
|
||||
};
|
||||
|
||||
enum nvme_tcp_pdu_flags {
|
||||
NVME_TCP_F_HDGST = (1 << 0),
|
||||
NVME_TCP_F_DDGST = (1 << 1),
|
||||
|
@ -189,6 +211,22 @@ static int hf_nvme_tcp_icresp_cpda = -1;
|
|||
static int hf_nvme_tcp_icresp_digest = -1;
|
||||
static int hf_nvme_tcp_icresp_maxdata = -1;
|
||||
|
||||
/* NVMe tcp c2h/h2c termreq fields */
|
||||
static int hf_nvme_tcp_c2htermreq = -1;
|
||||
static int hf_nvme_tcp_c2htermreq_fes = -1;
|
||||
static int hf_nvme_tcp_c2htermreq_phfo = -1;
|
||||
static int hf_nvme_tcp_c2htermreq_phd = -1;
|
||||
static int hf_nvme_tcp_c2htermreq_upfo = -1;
|
||||
static int hf_nvme_tcp_c2htermreq_reserved = -1;
|
||||
static int hf_nvme_tcp_c2htermreq_data = -1;
|
||||
static int hf_nvme_tcp_h2ctermreq = -1;
|
||||
static int hf_nvme_tcp_h2ctermreq_fes = -1;
|
||||
static int hf_nvme_tcp_h2ctermreq_phfo = -1;
|
||||
static int hf_nvme_tcp_h2ctermreq_phd = -1;
|
||||
static int hf_nvme_tcp_h2ctermreq_upfo = -1;
|
||||
static int hf_nvme_tcp_h2ctermreq_reserved = -1;
|
||||
static int hf_nvme_tcp_h2ctermreq_data = -1;
|
||||
|
||||
/* NVMe fabrics command */
|
||||
static int hf_nvme_fabrics_cmd = -1;
|
||||
static int hf_nvme_fabrics_cmd_opc = -1;
|
||||
|
@ -884,6 +922,84 @@ dissect_nvme_tcp_h2c_data(tvbuff_t *tvb,
|
|||
&cmd_ctx->n_cmd_ctx, data_length);
|
||||
}
|
||||
|
||||
static void
|
||||
dissect_nvme_tcp_h2ctermreq(tvbuff_t *tvb, packet_info *pinfo,
|
||||
proto_tree *tree, guint32 packet_len, int offset)
|
||||
{
|
||||
proto_item *tf;
|
||||
proto_item *h2ctermreq_tree;
|
||||
guint16 fes;
|
||||
|
||||
col_set_str(pinfo->cinfo, COL_INFO,
|
||||
"Host to Controller Termination Request");
|
||||
tf = proto_tree_add_item(tree, hf_nvme_tcp_h2ctermreq,
|
||||
tvb, offset, 8, ENC_NA);
|
||||
h2ctermreq_tree = proto_item_add_subtree(tf, ett_nvme_tcp);
|
||||
|
||||
proto_tree_add_item(h2ctermreq_tree, hf_nvme_tcp_h2ctermreq_fes,
|
||||
tvb, offset + 8, 2, ENC_LITTLE_ENDIAN);
|
||||
fes = tvb_get_guint16(tvb, offset + 8, ENC_LITTLE_ENDIAN);
|
||||
switch (fes) {
|
||||
case NVME_TCP_FES_INVALID_PDU_HDR:
|
||||
proto_tree_add_item(h2ctermreq_tree, hf_nvme_tcp_h2ctermreq_phfo,
|
||||
tvb, offset + 10, 4, ENC_LITTLE_ENDIAN);
|
||||
break;
|
||||
case NVME_TCP_FES_HDR_DIGEST_ERR:
|
||||
proto_tree_add_item(h2ctermreq_tree, hf_nvme_tcp_h2ctermreq_phd,
|
||||
tvb, offset + 10, 4, ENC_LITTLE_ENDIAN);
|
||||
break;
|
||||
case NVME_TCP_FES_UNSUPPORTED_PARAM:
|
||||
proto_tree_add_item(h2ctermreq_tree, hf_nvme_tcp_h2ctermreq_upfo,
|
||||
tvb, offset + 10, 4, ENC_LITTLE_ENDIAN);
|
||||
break;
|
||||
default:
|
||||
proto_tree_add_item(h2ctermreq_tree, hf_nvme_tcp_h2ctermreq_reserved,
|
||||
tvb, offset + 10, 4, ENC_LITTLE_ENDIAN);
|
||||
break;
|
||||
}
|
||||
proto_tree_add_item(h2ctermreq_tree, hf_nvme_tcp_h2ctermreq_data,
|
||||
tvb, offset + 24, packet_len - 24, ENC_NA);
|
||||
}
|
||||
|
||||
static void
|
||||
dissect_nvme_tcp_c2htermreq(tvbuff_t *tvb, packet_info *pinfo,
|
||||
proto_tree *tree, guint32 packet_len, int offset)
|
||||
{
|
||||
proto_item *tf;
|
||||
proto_item *c2htermreq_tree;
|
||||
guint16 fes;
|
||||
|
||||
col_set_str(pinfo->cinfo, COL_INFO,
|
||||
"Controller to Host Termination Request");
|
||||
tf = proto_tree_add_item(tree, hf_nvme_tcp_c2htermreq,
|
||||
tvb, offset, 8, ENC_NA);
|
||||
c2htermreq_tree = proto_item_add_subtree(tf, ett_nvme_tcp);
|
||||
|
||||
proto_tree_add_item(tree, hf_nvme_tcp_c2htermreq_fes, tvb, offset + 8, 2,
|
||||
ENC_LITTLE_ENDIAN);
|
||||
fes = tvb_get_guint16(tvb, offset + 8, ENC_LITTLE_ENDIAN);
|
||||
switch (fes) {
|
||||
case NVME_TCP_FES_INVALID_PDU_HDR:
|
||||
proto_tree_add_item(c2htermreq_tree, hf_nvme_tcp_c2htermreq_phfo,
|
||||
tvb, offset + 10, 4, ENC_LITTLE_ENDIAN);
|
||||
break;
|
||||
case NVME_TCP_FES_HDR_DIGEST_ERR:
|
||||
proto_tree_add_item(c2htermreq_tree, hf_nvme_tcp_c2htermreq_phd,
|
||||
tvb, offset + 10, 4, ENC_LITTLE_ENDIAN);
|
||||
break;
|
||||
case NVME_TCP_FES_UNSUPPORTED_PARAM:
|
||||
proto_tree_add_item(c2htermreq_tree, hf_nvme_tcp_c2htermreq_upfo,
|
||||
tvb, offset + 10, 4, ENC_LITTLE_ENDIAN);
|
||||
break;
|
||||
default:
|
||||
proto_tree_add_item(c2htermreq_tree, hf_nvme_tcp_c2htermreq_reserved,
|
||||
tvb, offset + 10, 4, ENC_LITTLE_ENDIAN);
|
||||
break;
|
||||
}
|
||||
proto_tree_add_item(c2htermreq_tree, hf_nvme_tcp_c2htermreq_data,
|
||||
tvb, offset + 24, packet_len - 24, ENC_NA);
|
||||
}
|
||||
|
||||
static void
|
||||
dissect_nvme_tcp_cqe(tvbuff_t *tvb,
|
||||
packet_info *pinfo,
|
||||
|
@ -1121,7 +1237,11 @@ dissect_nvme_tcp_pdu(tvbuff_t *tvb,
|
|||
dissect_nvme_tcp_r2t(tvb, pinfo, nvme_tcp_pdu_offset, nvme_tcp_tree);
|
||||
break;
|
||||
case nvme_tcp_h2c_term:
|
||||
dissect_nvme_tcp_h2ctermreq(tvb, pinfo, tree, plen, offset);
|
||||
break;
|
||||
case nvme_tcp_c2h_term:
|
||||
dissect_nvme_tcp_c2htermreq(tvb, pinfo, tree, plen, offset);
|
||||
break;
|
||||
default:
|
||||
proto_tree_add_item(nvme_tcp_tree, hf_nvme_tcp_unknown_data, tvb,
|
||||
offset, plen, ENC_NA);
|
||||
|
@ -1226,6 +1346,51 @@ void proto_register_nvme_tcp(void) {
|
|||
{ "Maximum data capsules per r2t supported",
|
||||
"nvme-tcp.icresp.maxdata",
|
||||
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
|
||||
/* NVMe tcp c2h/h2c termreq fields */
|
||||
{ &hf_nvme_tcp_c2htermreq,
|
||||
{ "C2HTermReq", "nvme-tcp.c2htermreq",
|
||||
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
|
||||
{ &hf_nvme_tcp_c2htermreq_fes,
|
||||
{ "Fatal error status", "nvme-tcp.c2htermreq.fes",
|
||||
FT_UINT16, BASE_HEX, VALS(nvme_tcp_termreq_fes),
|
||||
0xffff, NULL, HFILL } },
|
||||
{ &hf_nvme_tcp_c2htermreq_phfo,
|
||||
{ "PDU header field offset", "nvme-tcp.c2htermreq.phfo",
|
||||
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
|
||||
{ &hf_nvme_tcp_c2htermreq_phd,
|
||||
{ "PDU header digest", "nvme-tcp.c2htermreq.phd",
|
||||
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
|
||||
{ &hf_nvme_tcp_c2htermreq_upfo,
|
||||
{ "Unsupported pararmeter field offset", "nvme-tcp.c2htermreq.upfo",
|
||||
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
|
||||
{ &hf_nvme_tcp_c2htermreq_reserved,
|
||||
{ "Reserved", "nvme-tcp.c2htermreq.reserved",
|
||||
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
|
||||
{ &hf_nvme_tcp_c2htermreq_data,
|
||||
{ "Terminated PDU header", "nvme-tcp.c2htermreq.data",
|
||||
FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } },
|
||||
{ &hf_nvme_tcp_h2ctermreq,
|
||||
{ "H2CTermReq", "nvme-tcp.h2ctermreq",
|
||||
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
|
||||
{ &hf_nvme_tcp_h2ctermreq_fes,
|
||||
{ "Fatal error status", "nvme-tcp.h2ctermreq.fes",
|
||||
FT_UINT16, BASE_HEX, VALS(nvme_tcp_termreq_fes),
|
||||
0xffff, NULL, HFILL } },
|
||||
{ &hf_nvme_tcp_h2ctermreq_phfo,
|
||||
{ "PDU header field offset", "nvme-tcp.h2ctermreq.phfo",
|
||||
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
|
||||
{ &hf_nvme_tcp_h2ctermreq_phd,
|
||||
{ "PDU header digest", "nvme-tcp.h2ctermreq.phd",
|
||||
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
|
||||
{ &hf_nvme_tcp_h2ctermreq_upfo,
|
||||
{ "Unsupported pararmeter field offset", "nvme-tcp.h2ctermreq.upfo",
|
||||
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
|
||||
{ &hf_nvme_tcp_h2ctermreq_reserved,
|
||||
{ "Reserved", "nvme-tcp.h2ctermreq.reserved",
|
||||
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
|
||||
{ &hf_nvme_tcp_h2ctermreq_data,
|
||||
{ "Terminated PDU header", "nvme-tcp.h2ctermreq.data",
|
||||
FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } },
|
||||
/* NVMe fabrics command */
|
||||
{ &hf_nvme_fabrics_cmd,
|
||||
{ "NVM Express Fabrics (Cmd)", "nvme-tcp.cmd",
|
||||
|
|
Loading…
Reference in New Issue