scsi osd updates
authorsahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>
Sat, 30 Sep 2006 09:34:58 +0000 (09:34 +0000)
committersahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>
Sat, 30 Sep 2006 09:34:58 +0000 (09:34 +0000)
iscsi: when iscsi transfers a cdb that is alrger than 16 bytes,  the first 16 bytes are transferred in the normal place in the header and ther remainder of the cdb is transported inside the AHS.

reassemble these cdb into a proper tvb before passing it to the scsi dissector

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@19376 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dissectors/packet-iscsi.c
epan/dissectors/packet-scsi-osd.c

index 24b5ca6d57c47b51c5340b94ec3b0ebd0d3f1152..9e7bc0dbdefd588c4c07f0cd8bd301879ede3014 100644 (file)
@@ -67,6 +67,12 @@ static enum_val_t iscsi_protocol_versions[] = {
     { NULL, NULL, 0 }
 };
 
+static const value_string ahs_type_vals[] = {
+    {1, "Extended CDB"},
+    {2, "Expected Bidirection Read Data Length"},
+    {0, NULL}
+};
+
 static dissector_handle_t iscsi_handle=NULL;
 
 static gint iscsi_protocol_version = ISCSI_PROTOCOL_DRAFT13;
@@ -93,6 +99,9 @@ static int hf_iscsi_data_in_frame = -1;
 static int hf_iscsi_data_out_frame = -1;
 static int hf_iscsi_response_frame = -1;
 static int hf_iscsi_AHS = -1;
+static int hf_iscsi_AHS_length = -1;
+static int hf_iscsi_AHS_type = -1;
+static int hf_iscsi_AHS_specific = -1;
 static int hf_iscsi_Padding = -1;
 static int hf_iscsi_ping_data = -1;
 static int hf_iscsi_immediate_data = -1;
@@ -744,6 +753,8 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
     guint immediate_data_length=0;
     guint immediate_data_offset=0;
     itl_nexus_t *itl=NULL;
+    guint16 ahs_length=0;
+    guint8 ahs_type=0;
 
     if(paddedDataSegmentLength & 3)
        paddedDataSegmentLength += 4 - (paddedDataSegmentLength & 3);
@@ -966,8 +977,12 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
            proto_tree_add_item(ti, hf_iscsi_ExpStatSN, tvb, offset + 28, 4, FALSE);
            {
                if(ahsLen > 0) {
-                   /* FIXME - disssect AHS? */
-                   proto_tree_add_item(ti, hf_iscsi_AHS, tvb, offset + 48, ahsLen, FALSE);
+                   ahs_length=tvb_get_ntohs(tvb, offset+48);
+                   proto_tree_add_item(ti, hf_iscsi_AHS_length, tvb, offset + 48, 2, FALSE);
+                   ahs_type=tvb_get_guint8(tvb, offset+50);
+                   proto_tree_add_item(ti, hf_iscsi_AHS_type, tvb, offset + 50, 1, FALSE);
+                   proto_tree_add_item(ti, hf_iscsi_AHS_specific, tvb, offset + 51, 1, FALSE);
+                   proto_tree_add_item(ti, hf_iscsi_AHS, tvb, offset + 52, ahsLen-4, FALSE);
                }
                offset = handleHeaderDigest(iscsi_session, ti, tvb, offset, 48 + ahsLen);
            }
@@ -1496,16 +1511,34 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
        tvb_len=tvb_length_remaining(tvb, cdb_offset);
        tvb_rlen=tvb_reported_length_remaining(tvb, cdb_offset);
        scsi_opcode=tvb_get_guint8(tvb, cdb_offset);
-       /* cdb 0x7f is variable length so dont clamp the cdb tvb */
-       if(scsi_opcode!=0x7f){
+       if(ahs_type==1 && ahs_length && ahs_length<1024){
+               char *cdb_buf;
+
+               /* We have a variable length CDB where bytes >16 is transported
+                * in the AHS.
+                */
+               cdb_buf=ep_alloc(16+ahs_length);
+               /* the 16 first bytes of the cdb */
+               tvb_memcpy(tvb, cdb_buf, cdb_offset, 16);
+               /* hte remainder of the cdb from the ahs */
+               tvb_memcpy(tvb, cdb_buf+16, cdb_offset+20, ahs_length);
+
+               cdb_tvb = tvb_new_real_data(cdb_buf,
+                                         ahs_length+16,
+                                         ahs_length+16);
+
+               tvb_set_child_real_data_tvbuff(tvb, cdb_tvb);
+
+               add_new_data_source(pinfo, cdb_tvb, "CDB+AHS");
+       } else {
                if(tvb_len>16){
                    tvb_len=16;
                }
                if(tvb_rlen>16){
                    tvb_rlen=16;
                }
+               cdb_tvb=tvb_new_subset(tvb, cdb_offset, tvb_len, tvb_rlen);
        }
-       cdb_tvb=tvb_new_subset(tvb, cdb_offset, tvb_len, tvb_rlen);
         dissect_scsi_cdb(cdb_tvb, pinfo, tree, SCSI_DEV_UNKNOWN, &cdata->itlq, itl);
        /* we dont want the immediata below to overwrite our CDB info */
        if (check_col(pinfo->cinfo, COL_INFO)) {
@@ -2379,6 +2412,21 @@ proto_register_iscsi(void)
            FT_BYTES, BASE_HEX, NULL, 0,
            "Additional header segment", HFILL }
        },
+       { &hf_iscsi_AHS_length,
+         { "AHS Length", "iscsi.ahs.length",
+           FT_UINT16, BASE_DEC, NULL, 0,
+           "Length of Additional header segment", HFILL }
+       },
+       { &hf_iscsi_AHS_type,
+         { "AHS Type", "iscsi.ahs.type",
+           FT_UINT8, BASE_DEC, VALS(ahs_type_vals), 0,
+           "Type of Additional header segment", HFILL }
+       },
+       { &hf_iscsi_AHS_specific,
+         { "AHS Specific", "iscsi.ahs",
+           FT_UINT8, BASE_HEX, NULL, 0,
+           "Specific qualifier of Additional header segment", HFILL }
+       },
        { &hf_iscsi_Padding,
          { "Padding", "iscsi.padding",
            FT_BYTES, BASE_HEX, NULL, 0,
index 106b39d22b4ec4cd09bedb80488c7ed4aaf1daef..e3dea683a99221038521409113f1661a079123d6 100644 (file)
@@ -56,6 +56,15 @@ static int hf_scsi_osd_set_attributes_page   = -1;
 static int hf_scsi_osd_set_attribute_length    = -1;
 static int hf_scsi_osd_set_attribute_number    = -1;
 static int hf_scsi_osd_set_attributes_offset   = -1;
+static int hf_scsi_osd_capability_format       = -1;
+static int hf_scsi_osd_key_version     = -1;
+static int hf_scsi_osd_icva            = -1;
+static int hf_scsi_osd_security_method = -1;
+static int hf_scsi_osd_capability_expiration_time= -1;
+static int hf_scsi_osd_audit= -1;
+static int hf_scsi_osd_capability_discriminator        = -1;
+static int hf_scsi_osd_object_created_time= -1;
+static int hf_scsi_osd_object_type     = -1;
 
 
 static gint ett_osd_option             = -1;
@@ -175,10 +184,60 @@ dissect_osd_attribute_parameters(tvbuff_t *tvb, int offset, proto_tree *tree, sc
        }
 }
 
+
+static const value_string scsi_osd_capability_format_vals[] = {
+    {0x00,     "No Capability"},
+    {0x01,     "SCSI OSD2 Capabilities"},
+    {0, NULL},
+};
+static const value_string scsi_osd_object_type_vals[] = {
+    {0x01,     "ROOT"},
+    {0x02,     "PARTITION"},
+    {0x40,     "COLLECTION"},
+    {0x80,     "USER"},
+    {0, NULL},
+};
+
 /* 4.9.2.2 */
 static void
 dissect_osd_capability(tvbuff_t *tvb, int offset, proto_tree *tree)
 {
+       /* capability format */
+       proto_tree_add_item(tree, hf_scsi_osd_capability_format, tvb, offset, 1, 0);
+       offset++;
+
+       /* key version and icva */
+       proto_tree_add_item(tree, hf_scsi_osd_key_version, tvb, offset, 1, 0);
+       proto_tree_add_item(tree, hf_scsi_osd_icva, tvb, offset, 1, 0);
+       offset++;
+
+       /* security method */
+       proto_tree_add_item(tree, hf_scsi_osd_security_method, tvb, offset, 1, 0);
+       offset++;
+
+       /* a reserved byte */
+       offset++;
+
+       /* capability expiration time */
+       proto_tree_add_item(tree, hf_scsi_osd_capability_expiration_time, tvb, offset, 6, 0);
+       offset+=6;
+
+       /* audit */
+       proto_tree_add_item(tree, hf_scsi_osd_audit, tvb, offset, 20, 0);
+       offset+=20;
+
+       /* capability discriminator */
+       proto_tree_add_item(tree, hf_scsi_osd_capability_discriminator, tvb, offset, 12, 0);
+       offset+=12;
+
+       /* object created time */
+       proto_tree_add_item(tree, hf_scsi_osd_object_created_time, tvb, offset, 6, 0);
+       offset+=6;
+
+       /* object type */
+       proto_tree_add_item(tree, hf_scsi_osd_object_type, tvb, offset, 1, 0);
+       offset++;
+
 /*qqq*/
 }
 
@@ -680,6 +739,33 @@ proto_register_scsi_osd(void)
         { &hf_scsi_osd_set_attributes_offset,
           {"Set Attributes Offset", "scsi.osd.set_attributes_offset", FT_UINT32, BASE_HEX,
            NULL, 0x0, "", HFILL}},
+        { &hf_scsi_osd_capability_format,
+          {"Capability Format", "scsi.osd.capability_format", FT_UINT8, BASE_HEX,
+           VALS(scsi_osd_capability_format_vals), 0x0f, "", HFILL}},
+        { &hf_scsi_osd_key_version,
+          {"Key Version", "scsi.osd.key_version", FT_UINT8, BASE_HEX,
+           NULL, 0xf0, "", HFILL}},
+        { &hf_scsi_osd_icva,
+          {"Integrity Check Value Algorithm", "scsi.osd.icva", FT_UINT8, BASE_HEX,
+           NULL, 0x0f, "", HFILL}},
+        { &hf_scsi_osd_security_method,
+          {"Security Method", "scsi.osd.security_method", FT_UINT8, BASE_HEX,
+           NULL, 0x0f, "", HFILL}},
+        { &hf_scsi_osd_capability_expiration_time,
+          {"Capability Expiration Time", "scsi.osd.capability_expiration_time", FT_BYTES, BASE_HEX,
+           NULL, 0, "", HFILL}},
+        { &hf_scsi_osd_audit,
+          {"Audit", "scsi.osd.audit", FT_BYTES, BASE_HEX,
+           NULL, 0, "", HFILL}},
+        { &hf_scsi_osd_capability_discriminator,
+          {"Capability Discriminator", "scsi.osd.capability_descriminator", FT_BYTES, BASE_HEX,
+           NULL, 0, "", HFILL}},
+        { &hf_scsi_osd_object_created_time,
+          {"Object Created Time", "scsi.osd.object_created_time", FT_BYTES, BASE_HEX,
+           NULL, 0, "", HFILL}},
+        { &hf_scsi_osd_object_type,
+          {"Object Type", "scsi.osd.object_type", FT_UINT8, BASE_HEX,
+           VALS(scsi_osd_object_type_vals), 0, "", HFILL}},
        };
 
        /* Setup protocol subtree array */