scsi: unusual scsi protocols can request multiple AHS fields for iscsi so decode...
[obnox/wireshark/wip.git] / epan / dissectors / packet-scsi-osd.c
index 2a256f40d4b41763a5fa123be6f71d2f9b00970f..74ea55822b6a55506067acdfcb4d8dc8a955d8f7 100644 (file)
@@ -72,7 +72,19 @@ static int hf_scsi_osd_ricv          = -1;
 static int hf_scsi_osd_request_nonce   = -1;
 static int hf_scsi_osd_diicvo          = -1;
 static int hf_scsi_osd_doicvo          = -1;
-
+static int hf_scsi_osd_requested_partition_id  = -1;
+static int hf_scsi_osd_sortorder       = -1;
+static int hf_scsi_osd_partition_id    = -1;
+static int hf_scsi_osd_list_identifier = -1;
+static int hf_scsi_osd_allocation_length= -1;
+static int hf_scsi_osd_initial_object_id= -1;
+static int hf_scsi_osd_additional_length= -1;
+static int hf_scsi_osd_continuation_object_id= -1;
+static int hf_scsi_osd_list_flags_lstchg= -1;
+static int hf_scsi_osd_list_flags_root= -1;
+static int hf_scsi_osd_user_object_id= -1;
+static int hf_scsi_osd_requested_user_object_id        = -1;
+static int hf_scsi_osd_number_of_user_objects  = -1;
 
 static gint ett_osd_option             = -1;
 
@@ -346,10 +358,342 @@ dissect_osd_format_osd(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
 }
 
 
+static void
+dissect_osd_requested_partition_id(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+       /* request partition id */
+       proto_tree_add_item(tree, hf_scsi_osd_requested_partition_id, tvb, offset, 8, 0);
+       offset+=8;
+}
+
+static void
+dissect_osd_partition_id(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+       /* partition id */
+       proto_tree_add_item(tree, hf_scsi_osd_partition_id, tvb, offset, 8, 0);
+       offset+=8;
+}
+
+
+
+static void
+dissect_osd_create_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
+                        guint offset, gboolean isreq, gboolean iscdb,
+                        guint payload_len _U_, scsi_task_data_t *cdata _U_)
+{
+       /* dissecting the CDB   dissection starts at byte 10 of the CDB */
+       if(isreq && iscdb){
+               /* options byte */
+               dissect_osd_option(tvb, offset, tree);
+               offset++;
+
+               /* getset attributes byte */
+               dissect_osd_getsetattrib(tvb, offset, tree, cdata);
+               offset++;
+
+               /* timestamps control */
+               dissect_osd_timestamps_control(tvb, offset, tree);
+               offset++;
+
+               /* 3 reserved bytes */
+               offset+=3;
+
+               /* requested partiton id */
+               dissect_osd_requested_partition_id(tvb, offset, tree);
+               offset+=8;
+
+               /* 28 reserved bytes */
+               offset+=28;
+
+               /* attribute parameters */
+               dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
+               offset+=28;
+
+               /* capability */
+               dissect_osd_capability(tvb, offset, tree);
+               offset+=80;
+
+               /* security parameters */
+               dissect_osd_security_parameters(tvb, offset, tree);
+               offset+=40;
+       }
+
+       /* dissecting the DATA OUT */
+       if(isreq && !iscdb){
+               /* no data out for create partition */
+       }
+
+       /* dissecting the DATA IN */
+       if(!isreq && !iscdb){
+               /* no data in for create partition */
+       }
+       
+}
+
+static const value_string scsi_osd_sort_order_vals[] = {
+    {0x00,     "Ascending numeric value"},
+    {0, NULL},
+};
+static void
+dissect_osd_sortorder(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+       /* sort order */
+       proto_tree_add_item(tree, hf_scsi_osd_sortorder, tvb, offset, 1, 0);
+       offset++;
+}
+
+static void
+dissect_osd_list_identifier(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+       /* list identifier */
+       proto_tree_add_item(tree, hf_scsi_osd_list_identifier, tvb, offset, 4, 0);
+       offset+=4;
+}
+
+static void
+dissect_osd_allocation_length(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+       /* allocation length */
+       proto_tree_add_item(tree, hf_scsi_osd_allocation_length, tvb, offset, 8, 0);
+       offset+=8;
+}
+
+static void
+dissect_osd_initial_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+       /* initial object id */
+       proto_tree_add_item(tree, hf_scsi_osd_initial_object_id, tvb, offset, 8, 0);
+       offset+=8;
+}
+
+static void
+dissect_osd_additional_length(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+       /* additional length */
+       proto_tree_add_item(tree, hf_scsi_osd_additional_length, tvb, offset, 8, 0);
+       offset+=8;
+}
+
+
+static void
+dissect_osd_continuation_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+       /* continuation object id */
+       proto_tree_add_item(tree, hf_scsi_osd_continuation_object_id, tvb, offset, 8, 0);
+       offset+=8;
+}
+
+static const true_false_string list_lstchg_tfs = {
+       "List has CHANGED since the first List command",
+       "List has NOT changed since first command"
+};
+static const true_false_string list_root_tfs = {
+       "Objects are from root and are PARTITION IDs",
+       "Objects are from a partition and are USER OBJECTs"
+};
+
+static void
+dissect_osd_user_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+       /* user object id */
+       proto_tree_add_item(tree, hf_scsi_osd_user_object_id, tvb, offset, 8, 0);
+       offset+=8;
+}
+
+static void
+dissect_osd_list(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
+                        guint offset, gboolean isreq, gboolean iscdb,
+                        guint payload_len _U_, scsi_task_data_t *cdata _U_)
+{
+       /* dissecting the CDB   dissection starts at byte 10 of the CDB */
+       if(isreq && iscdb){
+               /* options byte */
+               dissect_osd_option(tvb, offset, tree);
+               offset++;
+
+               /* getset attributes byte / sort order */
+               dissect_osd_getsetattrib(tvb, offset, tree, cdata);
+               dissect_osd_sortorder(tvb, offset, tree);
+               offset++;
+
+               /* timestamps control */
+               dissect_osd_timestamps_control(tvb, offset, tree);
+               offset++;
+
+               /* 3 reserved bytes */
+               offset+=3;
+
+               /* partiton id */
+               dissect_osd_partition_id(tvb, offset, tree);
+               offset+=8;
+
+               /* 8 reserved bytes */
+               offset+=8;
+
+               /* list identifier */
+               dissect_osd_list_identifier(tvb, offset, tree);
+               offset+=4;
+
+               /* allocation length */
+               dissect_osd_allocation_length(tvb, offset, tree);
+               offset+=8;
+
+               /* initial object id */
+               dissect_osd_initial_object_id(tvb, offset, tree);
+               offset+=8;
+
+               /* attribute parameters */
+               dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
+               offset+=28;
+
+               /* capability */
+               dissect_osd_capability(tvb, offset, tree);
+               offset+=80;
+
+               /* security parameters */
+               dissect_osd_security_parameters(tvb, offset, tree);
+               offset+=40;
+       }
+
+       /* dissecting the DATA OUT */
+       if(isreq && !iscdb){
+               /* no data out for LIST */
+       }
+
+       /* dissecting the DATA IN */
+       if(!isreq && !iscdb){
+               guint64 additional_length;
+               gboolean is_root;
+
+               /* dissection of the LIST DATA-IN */
+               /* additional length */
+               additional_length=tvb_get_ntoh64(tvb, offset);
+               dissect_osd_additional_length(tvb, offset, tree);
+               offset+=8;
+
+               /* continuation object id */
+               dissect_osd_continuation_object_id(tvb, offset, tree);
+               offset+=8;
+
+               /* list identifier */
+               dissect_osd_list_identifier(tvb, offset, tree);
+               offset+=4;
+
+               /* 3 reserved bytes */
+               offset+=3;
+
+               /* LSTCHG and ROOT flags */
+               proto_tree_add_item(tree, hf_scsi_osd_list_flags_lstchg, tvb, offset, 1, 0);
+               proto_tree_add_item(tree, hf_scsi_osd_list_flags_root, tvb, offset, 1, 0);
+               is_root=tvb_get_guint8(tvb, offset)&0x01;
+               offset++;
+
+
+               /* list of user object ids or partition ids */
+               while(additional_length > (offset-8)){
+                       if(is_root){
+                               dissect_osd_partition_id(tvb, offset, tree);
+                       } else {
+                               dissect_osd_user_object_id(tvb, offset, tree);
+                       }
+                       offset+=8;
+               }
+       }
+       
+}
+
+static void
+dissect_osd_requested_user_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+       /* request user object id */
+       proto_tree_add_item(tree, hf_scsi_osd_requested_user_object_id, tvb, offset, 8, 0);
+       offset+=8;
+}
+
+static void
+dissect_osd_number_of_user_objects(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+       /* number_of_user_objects */
+       proto_tree_add_item(tree, hf_scsi_osd_number_of_user_objects, tvb, offset, 2, 0);
+       offset+=2;
+}
+
+static void
+dissect_osd_create(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
+                        guint offset, gboolean isreq, gboolean iscdb,
+                        guint payload_len _U_, scsi_task_data_t *cdata _U_)
+{
+       /* dissecting the CDB   dissection starts at byte 10 of the CDB */
+       if(isreq && iscdb){
+               /* options byte */
+               dissect_osd_option(tvb, offset, tree);
+               offset++;
+
+               /* getset attributes byte */
+               dissect_osd_getsetattrib(tvb, offset, tree, cdata);
+               offset++;
+
+               /* timestamps control */
+               dissect_osd_timestamps_control(tvb, offset, tree);
+               offset++;
+
+               /* 3 reserved bytes */
+               offset+=3;
+
+               /* partiton id */
+               dissect_osd_partition_id(tvb, offset, tree);
+               offset+=8;
+
+               /* requested user_object id */
+               dissect_osd_requested_user_object_id(tvb, offset, tree);
+               offset+=8;
+
+               /* 4 reserved bytes */
+               offset+=4;
+
+               /* number of user objects */
+               dissect_osd_number_of_user_objects(tvb, offset, tree);
+               offset+=2;
+
+               /* 14 reserved bytes */
+               offset+=14;
+
+               /* attribute parameters */
+               dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
+               offset+=28;
+
+               /* capability */
+               dissect_osd_capability(tvb, offset, tree);
+               offset+=80;
+
+               /* security parameters */
+               dissect_osd_security_parameters(tvb, offset, tree);
+               offset+=40;
+       }
+
+       /* dissecting the DATA OUT */
+       if(isreq && !iscdb){
+               /* no data out for create */
+       }
+
+       /* dissecting the DATA IN */
+       if(!isreq && !iscdb){
+               /* no data in for create */
+       }
+       
+}
+
+
 /* OSD Service Actions */
 #define OSD_FORMAT_OSD         0x8801
+#define OSD_CREATE             0x8802
+#define OSD_LIST               0x8803
+#define OSD_CREATE_PARTITION   0x880b
 static const value_string scsi_osd_svcaction_vals[] = {
     {OSD_FORMAT_OSD,           "Format OSD"},
+    {OSD_CREATE,               "Create"},
+    {OSD_LIST,                 "List"},
+    {OSD_CREATE_PARTITION,     "Create Partition"},
     {0, NULL},
 };
 
@@ -360,6 +704,9 @@ typedef struct _scsi_osd_svcaction_t {
 } scsi_osd_svcaction_t;
 static const scsi_osd_svcaction_t scsi_osd_svcaction[] = {
     {OSD_FORMAT_OSD,           dissect_osd_format_osd},
+    {OSD_CREATE,               dissect_osd_create},
+    {OSD_LIST,                 dissect_osd_list},
+    {OSD_CREATE_PARTITION,     dissect_osd_create_partition},
     {0, NULL},
 };
 
@@ -836,6 +1183,45 @@ proto_register_scsi_osd(void)
         { &hf_scsi_osd_doicvo,
           {"Data-Out Integrity Check Value Offset", "scsi.osd.doicvo", FT_UINT32, BASE_DEC,
            NULL, 0, "", HFILL}},
+        { &hf_scsi_osd_requested_partition_id,
+          {"Requested Partition Id", "scsi.osd.requested_partition_id", FT_BYTES, BASE_HEX,
+           NULL, 0, "", HFILL}},
+        { &hf_scsi_osd_sortorder,
+          {"Sort Order", "scsi.osd.sort_order", FT_UINT8, BASE_DEC,
+           VALS(scsi_osd_sort_order_vals), 0x0f, "", HFILL}},
+        { &hf_scsi_osd_partition_id,
+          {"Partition Id", "scsi.osd.partition_id", FT_BYTES, BASE_HEX,
+           NULL, 0, "", HFILL}},
+        { &hf_scsi_osd_list_identifier,
+          {"List Identifier", "scsi.osd.list_identifier", FT_UINT32, BASE_DEC,
+           NULL, 0, "", HFILL}},
+        { &hf_scsi_osd_allocation_length,
+          {"Allocation Length", "scsi.osd.allocation_length", FT_UINT64, BASE_DEC,
+           NULL, 0, "", HFILL}},
+        { &hf_scsi_osd_initial_object_id,
+          {"Initial Object Id", "scsi.osd.initial_object_id", FT_BYTES, BASE_HEX,
+           NULL, 0, "", HFILL}},
+       { &hf_scsi_osd_additional_length,
+          {"Additional Length", "scsi.osd.additional_length", FT_UINT64, BASE_DEC,
+           NULL, 0, "", HFILL}},
+        { &hf_scsi_osd_continuation_object_id,
+          {"Continuation Object Id", "scsi.osd.continuation_object_id", FT_BYTES, BASE_HEX,
+           NULL, 0, "", HFILL}},
+        { &hf_scsi_osd_user_object_id,
+          {"User Object Id", "scsi.osd.user_object_id", FT_BYTES, BASE_HEX,
+           NULL, 0, "", HFILL}},
+        { &hf_scsi_osd_list_flags_lstchg,
+          {"LSTCHG", "scsi.osd.list.lstchg", FT_BOOLEAN, 8,
+           TFS(&list_lstchg_tfs), 0x02, "", HFILL}},
+        { &hf_scsi_osd_list_flags_root,
+          {"ROOT", "scsi.osd.list.root", FT_BOOLEAN, 8,
+           TFS(&list_root_tfs), 0x01, "", HFILL}},
+        { &hf_scsi_osd_requested_user_object_id,
+          {"Requested User Object Id", "scsi.osd.requested_user_object_id", FT_BYTES, BASE_HEX,
+           NULL, 0, "", HFILL}},
+       { &hf_scsi_osd_number_of_user_objects,
+          {"Number Of User Objects", "scsi.osd.number_of_user_objects", FT_UINT16, BASE_DEC,
+           NULL, 0, "", HFILL}},
        };
 
        /* Setup protocol subtree array */