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

3226 lines
90 KiB
C

/* packet-scsi-osd.c
* Dissector for the SCSI OSD (object based storage) commandset
*
* Ronnie sahlberg 2006
* Joe Breher 2006
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 2002 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <glib.h>
#include <epan/strutil.h>
#include <epan/packet.h>
#include <epan/emem.h>
#include <epan/conversation.h>
#include <epan/tap.h>
#include "packet-scsi.h"
#include "packet-fc.h"
#include "packet-scsi-osd.h"
static int proto_scsi_osd = -1;
int hf_scsi_osd_opcode = -1;
static int hf_scsi_osd_add_cdblen = -1;
static int hf_scsi_osd_svcaction = -1;
static int hf_scsi_osd_option = -1;
static int hf_scsi_osd_option_dpo = -1;
static int hf_scsi_osd_option_fua = -1;
static int hf_scsi_osd_getsetattrib = -1;
static int hf_scsi_osd_timestamps_control = -1;
static int hf_scsi_osd_formatted_capacity = -1;
static int hf_scsi_osd_get_attributes_page = -1;
static int hf_scsi_osd_get_attributes_allocation_length = -1;
static int hf_scsi_osd_get_attributes_list_length= -1;
static int hf_scsi_osd_get_attributes_list_offset= -1;
static int hf_scsi_osd_retrieved_attributes_offset = -1;
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_set_attributes_list_length= -1;
static int hf_scsi_osd_set_attributes_list_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 int hf_scsi_osd_permissions = -1;
static int hf_scsi_osd_permissions_read = -1;
static int hf_scsi_osd_permissions_write = -1;
static int hf_scsi_osd_permissions_get_attr = -1;
static int hf_scsi_osd_permissions_set_attr = -1;
static int hf_scsi_osd_permissions_create = -1;
static int hf_scsi_osd_permissions_remove = -1;
static int hf_scsi_osd_permissions_obj_mgmt = -1;
static int hf_scsi_osd_permissions_append = -1;
static int hf_scsi_osd_permissions_dev_mgmt = -1;
static int hf_scsi_osd_permissions_global = -1;
static int hf_scsi_osd_permissions_pol_sec = -1;
static int hf_scsi_osd_object_descriptor_type = -1;
static int hf_scsi_osd_object_descriptor= -1;
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_length= -1;
static int hf_scsi_osd_starting_byte_address = -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 int hf_scsi_osd_key_to_set = -1;
static int hf_scsi_osd_set_key_version = -1;
static int hf_scsi_osd_key_identifier = -1;
static int hf_scsi_osd_seed = -1;
static int hf_scsi_osd_collection_fcr = -1;
static int hf_scsi_osd_collection_object_id = -1;
static int hf_scsi_osd_requested_collection_object_id = -1;
static int hf_scsi_osd_partition_created_in = -1;
static int hf_scsi_osd_partition_removed_in = -1;
static int hf_scsi_osd_flush_scope = -1;
static int hf_scsi_osd_flush_collection_scope = -1;
static int hf_scsi_osd_flush_partition_scope = -1;
static int hf_scsi_osd_flush_osd_scope = -1;
static int hf_scsi_osd_attributes_list_type = -1;
static int hf_scsi_osd_attributes_list_length = -1;
static int hf_scsi_osd_attributes_page = -1;
static int hf_scsi_osd_attribute_number = -1;
static int hf_scsi_osd_attribute_length = -1;
static int hf_scsi_osd_user_object_logical_length = -1;
static gint ett_osd_option = -1;
static gint ett_osd_partition = -1;
static gint ett_osd_attribute_parameters= -1;
static gint ett_osd_capability = -1;
static gint ett_osd_permission_bitmask = -1;
static gint ett_osd_security_parameters = -1;
#define PAGE_NUMBER_PARTITION 0x30000000
#define PAGE_NUMBER_COLLECTION 0x60000000
#define PAGE_NUMBER_ROOT 0x90000000
#define AP_USER_OBJECT_INFO 0x00000001
/* There will be one such structure create for each conversation ontop of which
* there is an OSD session
*/
typedef struct _scsi_osd_conv_info_t {
emem_tree_t *luns;
} scsi_osd_conv_info_t;
/* there will be one such structure created for each lun for each conversation
* that is handled by the OSD dissector
*/
typedef struct _scsi_osd_lun_info_t {
emem_tree_t *partitions;
} scsi_osd_lun_info_t;
typedef void (*scsi_osd_dissector_t)(tvbuff_t *tvb, packet_info *pinfo,
proto_tree *tree, guint offset,
gboolean isreq, gboolean iscdb,
guint32 payload_len, scsi_task_data_t *cdata,
scsi_osd_conv_info_t *conv_info,
scsi_osd_lun_info_t *lun_info
);
/* One such structure is created per conversation/lun/partition to
* keep track of when partitions are created/used/destroyed
*/
typedef struct _partition_info_t {
int created_in;
int removed_in;
} partition_info_t;
/* This is a set of extra data specific to OSD that we need to attach to every
* task.
*/
typedef struct _scsi_osd_extra_data_t {
guint16 svcaction;
guint8 gsatype;
union {
struct { /* gsatype: attribute list */
guint32 get_list_length;
guint32 get_list_offset;
guint32 get_list_allocation_length;
guint32 retrieved_list_offset;
guint32 set_list_length;
guint32 set_list_offset;
} al;
} u;
} scsi_osd_extra_data_t;
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
attribute_1_82(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
int offset=0;
/* user object id */
proto_tree_add_item(tree, hf_scsi_osd_user_object_logical_length, tvb, offset, 8, 0);
offset+=8;
}
typedef void (*attribute_dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
typedef struct _attribute_page_numbers_t {
guint32 number;
const char *name;
attribute_dissector dissector;
} attribute_page_numbers_t;
static const attribute_page_numbers_t user_object_info_attributes[] = {
{0x82, "User object logical length", attribute_1_82},
{0, NULL, NULL}
};
typedef struct _attribute_pages_t {
guint32 page;
const attribute_page_numbers_t *attributes;
} attribute_pages_t;
static const attribute_pages_t attribute_pages[] = {
{AP_USER_OBJECT_INFO, user_object_info_attributes},
{0,NULL}
};
static const value_string attributes_page_vals[] = {
{AP_USER_OBJECT_INFO, "User Object Information"},
{0, NULL}
};
static const value_string attributes_list_type_vals[] = {
{0x01, "Retrieve attributes for this OSD object"},
{0x09, "Retrieve/Set attributes for this OSD object"},
{0x0f, "Retrieve attributes for a CREATE command"},
{0,NULL}
};
/* 7.1.3.1 */
static void
dissect_osd_attributes_list(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree)
{
guint8 type;
guint16 length, attribute_length;
guint32 page, number;
int start_offset=offset;
proto_item *item;
const attribute_pages_t *ap;
const attribute_page_numbers_t *apn;
tvbuff_t *next_tvb;
/* list type */
type=tvb_get_guint8(tvb, offset)&0x0f;
proto_tree_add_item(tree, hf_scsi_osd_attributes_list_type, tvb, offset, 1, 0);
offset++;
/* a reserved byte */
offset++;
/* length */
length=tvb_get_ntohs(tvb, offset);
proto_tree_add_item(tree, hf_scsi_osd_attributes_list_length, tvb, offset, 2, 0);
offset+=2;
/* if type is 1 length will be zero and we have to cycle over
* all remaining bytes. 7.1.3.1
*/
if(type==1){
length=tvb_length_remaining(tvb, offset);
}
while( (offset-start_offset)<(length+4) ){
switch(type){
case 0x01: /* retrieving attributes 7.1.3.2 */
/* attributes page */
page=tvb_get_ntohl(tvb, offset);
proto_tree_add_item(tree, hf_scsi_osd_attributes_page, tvb, offset, 4, 0);
offset+=4;
/* attribute number */
number=tvb_get_ntohl(tvb, offset);
item=proto_tree_add_item(tree, hf_scsi_osd_attribute_number, tvb, offset, 4, 0);
offset+=4;
/* find the proper attributes page */
apn=NULL;
for(ap=attribute_pages;ap->attributes;ap++){
if(ap->page==page){
apn=ap->attributes;
break;
}
}
if(!apn){
proto_tree_add_text(tree, tvb, offset, length, "Unknown attribute page. can not decode attribute value");
break;
}
/* find the specific attribute */
for(;apn->name;apn++){
if(apn->number==number){
break;
}
}
if(!apn->name){
proto_tree_add_text(tree, tvb, offset, length, "Unknown attribute. can not decode attribute value");
break;
}
/* found it */
proto_item_append_text(item, " (%s)", apn->name);
break;
case 0x0f: /* create attributes 7.1.3.4 */
/* user object id */
dissect_osd_user_object_id(tvb, offset, tree);
offset+=8;
/* fallthrough to the next case */
case 0x09: /* retrieved/set attributes 7.1.3.3 */
/* attributes page */
page=tvb_get_ntohl(tvb, offset);
proto_tree_add_item(tree, hf_scsi_osd_attributes_page, tvb, offset, 4, 0);
offset+=4;
/* attribute number */
number=tvb_get_ntohl(tvb, offset);
item=proto_tree_add_item(tree, hf_scsi_osd_attribute_number, tvb, offset, 4, 0);
offset+=4;
/* attribute length */
attribute_length=tvb_get_ntohs(tvb, offset);
proto_tree_add_item(tree, hf_scsi_osd_attribute_length, tvb, offset, 2, 0);
offset+=2;
/* find the proper attributes page */
apn=NULL;
for(ap=attribute_pages;ap->attributes;ap++){
if(ap->page==page){
apn=ap->attributes;
break;
}
}
if(!apn){
proto_tree_add_text(tree, tvb, offset, length, "Unknown attribute page. can not decode attribute value");
offset+=attribute_length;
break;
}
/* find the specific attribute */
for(;apn->name;apn++){
if(apn->number==number){
break;
}
}
if(!apn->name){
proto_tree_add_text(tree, tvb, offset, length, "Unknown attribute. can not decode attribute value");
offset+=attribute_length;
break;
}
/* found it */
proto_item_append_text(item, " (%s)", apn->name);
if(attribute_length==0){
/* nothing to dissect */
offset+=attribute_length;
break;
}
next_tvb=tvb_new_subset(tvb, offset, attribute_length, attribute_length);
apn->dissector(next_tvb, pinfo, tree);
offset+=attribute_length;
break;
default:
proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "Don't know how to decode this attribute list type:0x%02x",type);
return;
}
}
}
static const true_false_string option_dpo_tfs = {
"DPO is SET",
"Dpo is NOT set"
};
static const true_false_string option_fua_tfs = {
"FUA is SET",
"Fua is NOT set"
};
/* OSD2 5.2.4 */
static void
dissect_osd_option(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
{
proto_tree *tree=NULL;
proto_item *it=NULL;
guint8 option;
option=tvb_get_guint8(tvb, offset);
if(parent_tree){
it=proto_tree_add_item(parent_tree, hf_scsi_osd_option, tvb, offset, 1, 0);
tree = proto_item_add_subtree(it, ett_osd_option);
}
proto_tree_add_item(tree, hf_scsi_osd_option_dpo, tvb, offset, 1, 0);
if(option&0x10){
proto_item_append_text(tree, " DPO");
}
proto_tree_add_item(tree, hf_scsi_osd_option_fua, tvb, offset, 1, 0);
if(option&0x08){
proto_item_append_text(tree, " FUA");
}
}
static const value_string scsi_osd_getsetattrib_vals[] = {
{2, "Get an attributes page and set an attribute value"},
{3, "Get and set attributes using a list"},
{0, NULL},
};
/* OSD2 5.2.2.1 */
static void
dissect_osd_getsetattrib(tvbuff_t *tvb, int offset, proto_tree *tree, scsi_task_data_t *cdata)
{
if(cdata && cdata->itlq && cdata->itlq->extra_data){
scsi_osd_extra_data_t *extra_data=cdata->itlq->extra_data;
extra_data->gsatype=(tvb_get_guint8(tvb, offset)>>4)&0x03;
}
proto_tree_add_item(tree, hf_scsi_osd_getsetattrib, tvb, offset, 1, 0);
}
static const value_string scsi_osd_timestamps_control_vals[] = {
{0x00, "Timestamps shall be updated"},
{0x7f, "Timestamps shall not be updated"},
{0, NULL},
};
/* OSD2 5.2.8 */
static void
dissect_osd_timestamps_control(tvbuff_t *tvb, int offset, proto_tree *tree)
{
proto_tree_add_item(tree, hf_scsi_osd_timestamps_control, tvb, offset, 1, 0);
}
static void
dissect_osd_formatted_capacity(tvbuff_t *tvb, int offset, proto_tree *tree)
{
proto_tree_add_item(tree, hf_scsi_osd_formatted_capacity, tvb, offset, 8, 0);
}
static void
dissect_osd_attribute_parameters(tvbuff_t *tvb, int offset, proto_tree *parent_tree, scsi_task_data_t *cdata)
{
guint8 gsatype=0;
proto_item *item=NULL;
proto_tree *tree=NULL;
scsi_osd_extra_data_t *extra_data=NULL;
if(parent_tree){
item = proto_tree_add_text(parent_tree, tvb, offset, 28,
"Attribute Parameters");
tree = proto_item_add_subtree(item, ett_osd_attribute_parameters);
}
if(cdata && cdata->itlq && cdata->itlq->extra_data){
extra_data=cdata->itlq->extra_data;
gsatype=extra_data->gsatype;
} else {
return;
}
switch(gsatype){
case 2: /* 5.2.2.2 attribute page */
proto_tree_add_item(tree, hf_scsi_osd_get_attributes_page, tvb, offset, 4, 0);
offset+=4;
proto_tree_add_item(tree, hf_scsi_osd_get_attributes_allocation_length, tvb, offset, 4, 0);
offset+=4;
proto_tree_add_item(tree, hf_scsi_osd_retrieved_attributes_offset, tvb, offset, 4, 0);
offset+=4;
proto_tree_add_item(tree, hf_scsi_osd_set_attributes_page, tvb, offset, 4, 0);
offset+=4;
proto_tree_add_item(tree, hf_scsi_osd_set_attribute_number, tvb, offset, 4, 0);
offset+=4;
proto_tree_add_item(tree, hf_scsi_osd_set_attribute_length, tvb, offset, 4, 0);
offset+=4;
proto_tree_add_item(tree, hf_scsi_osd_set_attributes_offset, tvb, offset, 4, 0);
offset+=4;
break;
case 3: /* 5.2.2.3 attribute list */
proto_tree_add_item(tree, hf_scsi_osd_get_attributes_list_length, tvb, offset, 4, 0);
extra_data->u.al.get_list_length=tvb_get_ntohl(tvb, offset);
offset+=4;
/* 4.12.5 */
extra_data->u.al.get_list_offset=tvb_get_ntohl(tvb, offset);
extra_data->u.al.get_list_offset=(extra_data->u.al.get_list_offset&0x0fffffff)<<((extra_data->u.al.get_list_offset>>28)&0x0f);
extra_data->u.al.get_list_offset<<=8;
proto_tree_add_uint(tree, hf_scsi_osd_get_attributes_list_offset, tvb, offset, 4, extra_data->u.al.get_list_offset);
offset+=4;
proto_tree_add_item(tree, hf_scsi_osd_get_attributes_allocation_length, tvb, offset, 4, 0);
extra_data->u.al.get_list_allocation_length=tvb_get_ntohl(tvb, offset);
offset+=4;
/* 4.12.5 */
extra_data->u.al.retrieved_list_offset=tvb_get_ntohl(tvb, offset);
extra_data->u.al.retrieved_list_offset=(extra_data->u.al.retrieved_list_offset&0x0fffffff)<<((extra_data->u.al.retrieved_list_offset>>28)&0x0f);
extra_data->u.al.retrieved_list_offset<<=8;
proto_tree_add_uint(tree, hf_scsi_osd_retrieved_attributes_offset, tvb, offset, 4, extra_data->u.al.retrieved_list_offset);
offset+=4;
proto_tree_add_item(tree, hf_scsi_osd_set_attributes_list_length, tvb, offset, 4, 0);
extra_data->u.al.set_list_length=tvb_get_ntohl(tvb, offset);
offset+=4;
proto_tree_add_item(tree, hf_scsi_osd_set_attributes_list_offset, tvb, offset, 4, 0);
extra_data->u.al.set_list_offset=tvb_get_ntohl(tvb, offset);
offset+=4;
/* 4 reserved bytes */
offset+=4;
break;
}
}
static void
dissect_osd_attribute_data_out(packet_info *pinfo, tvbuff_t *tvb, int offset _U_, proto_tree *tree, scsi_task_data_t *cdata)
{
guint8 gsatype=0;
scsi_osd_extra_data_t *extra_data=NULL;
if(cdata && cdata->itlq && cdata->itlq->extra_data){
extra_data=cdata->itlq->extra_data;
gsatype=extra_data->gsatype;
} else {
return;
}
switch(gsatype){
case 2: /* 5.2.2.2 attribute page */
/*qqq*/
break;
case 3: /* 5.2.2.3 attribute list */
if(extra_data->u.al.get_list_length){
dissect_osd_attributes_list(pinfo, tvb, extra_data->u.al.get_list_offset, tree);
}
if(extra_data->u.al.set_list_length){
proto_tree_add_text(tree, tvb, extra_data->u.al.set_list_offset, extra_data->u.al.set_list_length, "Set Attributes Data");
}
break;
}
}
static void
dissect_osd_attribute_data_in(packet_info *pinfo, tvbuff_t *tvb, int offset _U_, proto_tree *tree, scsi_task_data_t *cdata)
{
guint8 gsatype=0;
scsi_osd_extra_data_t *extra_data=NULL;
if(cdata && cdata->itlq && cdata->itlq->extra_data){
extra_data=cdata->itlq->extra_data;
gsatype=extra_data->gsatype;
} else {
return;
}
switch(gsatype){
case 2: /* 5.2.2.2 attribute page */
/*qqq*/
break;
case 3: /* 5.2.2.3 attribute list */
if(extra_data->u.al.get_list_allocation_length){
dissect_osd_attributes_list(pinfo, tvb, extra_data->u.al.retrieved_list_offset, tree);
}
break;
}
}
static const value_string scsi_osd_capability_format_vals[] = {
{0x00, "No Capability"},
{0x01, "SCSI OSD Capabilities"},
{0, NULL},
};
static const value_string scsi_osd_object_type_vals[] = {
{0x01, "ROOT"},
{0x02, "PARTITION"},
{0x40, "COLLECTION"},
{0x80, "USER"},
{0, NULL},
};
static const value_string scsi_osd_object_descriptor_type_vals[] = {
{0, "NONE: the object descriptor field shall be ignored"},
{1, "U/C: a single collection or user object"},
{2, "PAR: a single partition, including partition zero"},
{0, NULL},
};
static const true_false_string permissions_read_tfs = {
"READ is SET",
"Read is NOT set"
};
static const true_false_string permissions_write_tfs = {
"WRITE is SET",
"Write is NOT set"
};
static const true_false_string permissions_get_attr_tfs = {
"GET_ATTR is SET",
"Get_attr is NOT set"
};
static const true_false_string permissions_set_attr_tfs = {
"SET_ATTR is SET",
"Set_attr is NOT set"
};
static const true_false_string permissions_create_tfs = {
"CREATE is SET",
"Create is NOT set"
};
static const true_false_string permissions_remove_tfs = {
"REMOVE is SET",
"Remove is NOT set"
};
static const true_false_string permissions_obj_mgmt_tfs = {
"OBJ_MGMT is SET",
"Obj_mgmt is NOT set"
};
static const true_false_string permissions_append_tfs = {
"APPEND is SET",
"Append is NOT set"
};
static const true_false_string permissions_dev_mgmt_tfs = {
"DEV_MGMT is SET",
"Dev_mgmt is NOT set"
};
static const true_false_string permissions_global_tfs = {
"GLOBAL is SET",
"Global is NOT set"
};
static const true_false_string permissions_pol_sec_tfs = {
"POL/SEC is SET",
"Pol/sec is NOT set"
};
/* OSD 4.9.2.2.1 */
static void
dissect_osd_permissions(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
{
proto_tree *tree=NULL;
proto_item *it=NULL;
guint16 permissions;
permissions=tvb_get_ntohs(tvb, offset);
if(parent_tree){
it=proto_tree_add_item(parent_tree, hf_scsi_osd_permissions, tvb, offset, 2, 0);
tree = proto_item_add_subtree(it, ett_osd_permission_bitmask);
}
proto_tree_add_item(tree, hf_scsi_osd_permissions_read, tvb, offset, 2, 0);
if(permissions&0x8000){
proto_item_append_text(tree, " READ");
}
proto_tree_add_item(tree, hf_scsi_osd_permissions_write, tvb, offset, 2, 0);
if(permissions&0x4000){
proto_item_append_text(tree, " WRITE");
}
proto_tree_add_item(tree, hf_scsi_osd_permissions_get_attr, tvb, offset, 2, 0);
if(permissions&0x2000){
proto_item_append_text(tree, " GET_ATTR");
}
proto_tree_add_item(tree, hf_scsi_osd_permissions_set_attr, tvb, offset, 2, 0);
if(permissions&0x1000){
proto_item_append_text(tree, " SET_ATTR");
}
proto_tree_add_item(tree, hf_scsi_osd_permissions_create, tvb, offset, 2, 0);
if(permissions&0x0800){
proto_item_append_text(tree, " CREATE");
}
proto_tree_add_item(tree, hf_scsi_osd_permissions_remove, tvb, offset, 2, 0);
if(permissions&0x0400){
proto_item_append_text(tree, " REMOVE");
}
proto_tree_add_item(tree, hf_scsi_osd_permissions_obj_mgmt, tvb, offset, 2, 0);
if(permissions&0x0200){
proto_item_append_text(tree, " OBJ_MGMT");
}
proto_tree_add_item(tree, hf_scsi_osd_permissions_append, tvb, offset, 2, 0);
if(permissions&0x0100){
proto_item_append_text(tree, " APPEND");
}
proto_tree_add_item(tree, hf_scsi_osd_permissions_dev_mgmt, tvb, offset, 2, 0);
if(permissions&0x0080){
proto_item_append_text(tree, " DEV_MGMT");
}
proto_tree_add_item(tree, hf_scsi_osd_permissions_global, tvb, offset, 2, 0);
if(permissions&0x0040){
proto_item_append_text(tree, " GLOBAL");
}
proto_tree_add_item(tree, hf_scsi_osd_permissions_pol_sec, tvb, offset, 2, 0);
if(permissions&0x0020){
proto_item_append_text(tree, " POL/SEC");
}
}
/* 4.9.2.2 */
static void
dissect_osd_capability(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
{
proto_item *item=NULL;
proto_tree *tree=NULL;
if(parent_tree){
item = proto_tree_add_text(parent_tree, tvb, offset, 80,
"Capability");
tree = proto_item_add_subtree(item, ett_osd_capability);
}
/* 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++;
/* permission bitmask */
dissect_osd_permissions(tvb, offset, tree);
offset+=5;
/* a reserved byte */
offset++;
/* object descriptor type */
proto_tree_add_item(tree, hf_scsi_osd_object_descriptor_type, tvb, offset, 1, 0);
offset++;
/* object descriptor */
proto_tree_add_item(tree, hf_scsi_osd_object_descriptor, tvb, offset, 24, 0);
offset+=24;
}
/* 5.2.6 */
static void
dissect_osd_security_parameters(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
{
proto_item *item=NULL;
proto_tree *tree=NULL;
if(parent_tree){
item = proto_tree_add_text(parent_tree, tvb, offset, 40,
"Security Parameters");
tree = proto_item_add_subtree(item, ett_osd_security_parameters);
}
/* request integrity check value */
proto_tree_add_item(tree, hf_scsi_osd_ricv, tvb, offset, 20, 0);
offset+=20;
/* request nonce */
proto_tree_add_item(tree, hf_scsi_osd_request_nonce, tvb, offset, 12, 0);
offset+=12;
/* data in integrity check value offset */
proto_tree_add_item(tree, hf_scsi_osd_diicvo, tvb, offset, 4, 0);
offset+=4;
/* data out integrity check value offset */
proto_tree_add_item(tree, hf_scsi_osd_doicvo, tvb, offset, 4, 0);
offset+=4;
}
static void
dissect_osd_format_osd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info _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++;
/* 23 reserved bytes */
offset+=23;
/* formatted capacity */
dissect_osd_formatted_capacity(tvb, offset, tree);
offset+=8;
/* 8 reserved bytes */
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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for format osd */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* no data in for format osd */
}
}
static void
dissect_osd_partition_id(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree, int hf_index, scsi_osd_lun_info_t *lun_info, gboolean is_created, gboolean is_removed)
{
proto_item *item=NULL;
guint32 partition_id[2];
/* partition id */
item=proto_tree_add_item(tree, hf_index, tvb, offset, 8, 0);
partition_id[0]=tvb_get_ntohl(tvb, offset);
partition_id[1]=tvb_get_ntohl(tvb, offset+4);
if(!partition_id[0] && !partition_id[1]){
proto_item_append_text(item, " (ROOT partition)");
} else {
partition_info_t *part_info;
emem_tree_key_t pikey[2];
proto_tree *partition_tree=NULL;
pikey[0].length=2;
pikey[0].key=partition_id;
pikey[1].length=0;
part_info=se_tree_lookup32_array(lun_info->partitions, &pikey[0]);
if(!part_info){
part_info=se_alloc(sizeof(partition_info_t));
part_info->created_in=0;
part_info->removed_in=0;
pikey[0].length=2;
pikey[0].key=partition_id;
pikey[1].length=0;
se_tree_insert32_array(lun_info->partitions, &pikey[0], part_info);
}
if(is_created){
part_info->created_in=pinfo->fd->num;
}
if(is_removed){
part_info->removed_in=pinfo->fd->num;
}
if(item){
partition_tree=proto_item_add_subtree(item, ett_osd_partition);
}
if(part_info->created_in){
proto_item *tmp_item;
tmp_item=proto_tree_add_uint(partition_tree, hf_scsi_osd_partition_created_in, tvb, 0, 0, part_info->created_in);
PROTO_ITEM_SET_GENERATED(tmp_item);
}
if(part_info->removed_in){
proto_item *tmp_item;
tmp_item=proto_tree_add_uint(partition_tree, hf_scsi_osd_partition_removed_in, tvb, 0, 0, part_info->removed_in);
PROTO_ITEM_SET_GENERATED(tmp_item);
}
}
offset+=8;
}
static void
dissect_osd_create_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* 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_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_requested_partition_id, lun_info, TRUE, FALSE);
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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for create partition */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* 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_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* 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(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for LIST */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
guint64 additional_length;
gboolean is_root;
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* 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(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
} 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, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* 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(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for create */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* no data in for create */
}
}
static void
dissect_osd_remove_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* 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(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, TRUE);
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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for remove partition */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* no data in for remove partition */
}
}
static const value_string key_to_set_vals[] = {
{1, "Root"},
{2, "Partition"},
{3, "Working"},
{0, NULL},
};
static void
dissect_osd_key_to_set(tvbuff_t *tvb, int offset, proto_tree *tree)
{
proto_tree_add_item(tree, hf_scsi_osd_key_to_set, tvb, offset, 1, 0);
}
static void
dissect_osd_set_key_version(tvbuff_t *tvb, int offset, proto_tree *tree)
{
proto_tree_add_item(tree, hf_scsi_osd_set_key_version, tvb, offset, 1, 0);
}
static void
dissect_osd_key_identifier(tvbuff_t *tvb, int offset, proto_tree *tree)
{
proto_tree_add_item(tree, hf_scsi_osd_key_identifier, tvb, offset, 7, 0);
}
static void
dissect_osd_seed(tvbuff_t *tvb, int offset, proto_tree *tree)
{
proto_tree_add_item(tree, hf_scsi_osd_seed, tvb, offset, 20, 0);
}
static void
dissect_osd_set_key(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* dissecting the CDB dissection starts at byte 10 of the CDB */
if(isreq && iscdb){
/* a reserved byte */
offset++;
/* getset attributes byte and key to set*/
dissect_osd_getsetattrib(tvb, offset, tree, cdata);
dissect_osd_key_to_set(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(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
offset+=8;
/* key version */
dissect_osd_set_key_version(tvb, offset, tree);
offset++;
/* key identifier */
dissect_osd_key_identifier(tvb, offset, tree);
offset+=7;
/* seed */
dissect_osd_seed(tvb, offset, tree);
offset+=20;
/* 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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for set key */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* no data in for set key */
}
}
static void
dissect_osd_remove(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* 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(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
offset+=8;
/* user object id */
dissect_osd_user_object_id(tvb, offset, tree);
offset+=8;
/* 20 reserved bytes */
offset+=20;
/* 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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for remove */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* no data in for remove */
}
}
static const true_false_string collection_fcr_tfs = {
"FCR is SET",
"Fcr is NOR set"
};
static void
dissect_osd_collection_fcr(tvbuff_t *tvb, int offset, proto_tree *tree)
{
proto_tree_add_item(tree, hf_scsi_osd_collection_fcr, tvb, offset, 1, 0);
}
static void
dissect_osd_collection_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
{
/* collection object id */
proto_tree_add_item(tree, hf_scsi_osd_collection_object_id, tvb, offset, 8, 0);
offset+=8;
}
static void
dissect_osd_remove_collection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* 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);
dissect_osd_collection_fcr(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(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
offset+=8;
/* collection object id */
dissect_osd_collection_object_id(tvb, offset, tree);
offset+=8;
/* 20 reserved bytes */
offset+=20;
/* 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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for remove collection */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* no data in for remove collection */
}
}
static void
dissect_osd_length(tvbuff_t *tvb, int offset, proto_tree *tree)
{
/* length */
proto_tree_add_item(tree, hf_scsi_osd_length, tvb, offset, 8, 0);
offset+=8;
}
static void
dissect_osd_starting_byte_address(tvbuff_t *tvb, int offset, proto_tree *tree)
{
/* starting_byte_address */
proto_tree_add_item(tree, hf_scsi_osd_starting_byte_address, tvb, offset, 8, 0);
offset+=8;
}
static void
dissect_osd_write(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* 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);
offset++;
/* timestamps control */
dissect_osd_timestamps_control(tvb, offset, tree);
offset++;
/* 3 reserved bytes */
offset+=3;
/* partiton id */
dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
offset+=8;
/* user object id */
dissect_osd_user_object_id(tvb, offset, tree);
offset+=8;
/* 4 reserved bytes */
offset+=4;
/* length */
dissect_osd_length(tvb, offset, tree);
offset+=8;
/* starting byte address */
dissect_osd_starting_byte_address(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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* xxx should dissect the data ? */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* no data in for WRITE */
}
}
static void
dissect_osd_requested_collection_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
{
/* requested collection object id */
proto_tree_add_item(tree, hf_scsi_osd_requested_collection_object_id, tvb, offset, 8, 0);
offset+=8;
}
static void
dissect_osd_create_collection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* 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);
dissect_osd_collection_fcr(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(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
offset+=8;
/* requested collection object id */
dissect_osd_requested_collection_object_id(tvb, offset, tree);
offset+=8;
/* 20 reserved bytes */
offset+=20;
/* 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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for create collection */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* no data in for create collection */
}
}
static const value_string flush_scope_vals[] = {
{0, "User object data and attributes"},
{1, "User object attributes only"},
{0, NULL}
};
static void
dissect_osd_flush_scope(tvbuff_t *tvb, int offset, proto_tree *tree)
{
/* flush scope */
proto_tree_add_item(tree, hf_scsi_osd_flush_scope, tvb, offset, 1, 0);
offset++;
}
static void
dissect_osd_flush(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* dissecting the CDB dissection starts at byte 10 of the CDB */
if(isreq && iscdb){
/* options byte */
dissect_osd_flush_scope(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(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
offset+=8;
/* user object id */
dissect_osd_user_object_id(tvb, offset, tree);
offset+=8;
/* 20 reserved bytes */
offset+=20;
/* 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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for flush */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* no data in for flush */
}
}
static const value_string flush_collection_scope_vals[] = {
{0, "List of user objects contained in the collection"},
{1, "Collection attributes only"},
{2, "List of user objects and collection attributes"},
{0, NULL}
};
static void
dissect_osd_flush_collection_scope(tvbuff_t *tvb, int offset, proto_tree *tree)
{
/* flush collection scope */
proto_tree_add_item(tree, hf_scsi_osd_flush_collection_scope, tvb, offset, 1, 0);
offset++;
}
static void
dissect_osd_flush_collection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* dissecting the CDB dissection starts at byte 10 of the CDB */
if(isreq && iscdb){
/* options byte */
dissect_osd_flush_collection_scope(tvb, offset, tree);
offset++;
/* getset attributes byte */
dissect_osd_getsetattrib(tvb, offset, tree, cdata);
dissect_osd_collection_fcr(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(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
offset+=8;
/* collection object id */
dissect_osd_collection_object_id(tvb, offset, tree);
offset+=8;
/* 20 reserved bytes */
offset+=20;
/* 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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for flush collection */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* no data in for flush collection */
}
}
static void
dissect_osd_append(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* 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(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
offset+=8;
/* user object id */
dissect_osd_user_object_id(tvb, offset, tree);
offset+=8;
/* 4 reserved bytes */
offset+=4;
/* length */
dissect_osd_length(tvb, offset, tree);
offset+=8;
/* 8 reserved bytes */
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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* xxx should dissect the data ? */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* no data in for append */
}
}
static void
dissect_osd_create_and_write(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* 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(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
offset+=8;
/* requested user_object id */
dissect_osd_requested_user_object_id(tvb, offset, tree);
offset+=8;
/* 4 reserved bytes */
offset+=4;
/* length */
dissect_osd_length(tvb, offset, tree);
offset+=8;
/* starting byte address */
dissect_osd_starting_byte_address(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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* should we dissect the data? */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* no data in for create and write*/
}
}
static const value_string flush_osd_scope_vals[] = {
{0, "List of partitions contained in the OSD logical unit"},
{1, "Root object attributes only"},
{2, "Everything"},
{0, NULL}
};
static void
dissect_osd_flush_osd_scope(tvbuff_t *tvb, int offset, proto_tree *tree)
{
/* flush osd scope */
proto_tree_add_item(tree, hf_scsi_osd_flush_osd_scope, tvb, offset, 1, 0);
offset++;
}
static void
dissect_osd_flush_osd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info _U_)
{
/* dissecting the CDB dissection starts at byte 10 of the CDB */
if(isreq && iscdb){
/* options byte */
dissect_osd_flush_osd_scope(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++;
/* 39 reserved bytes */
offset+=39;
/* 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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for flush osd */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* no data in for flush osd */
}
}
static const value_string flush_partition_scope_vals[] = {
{0, "List of user objects and collections in the partition"},
{1, "Partition attributes only"},
{2, "Everything"},
{0, NULL}
};
static void
dissect_osd_flush_partition_scope(tvbuff_t *tvb, int offset, proto_tree *tree)
{
/* flush partition scope */
proto_tree_add_item(tree, hf_scsi_osd_flush_partition_scope, tvb, offset, 1, 0);
offset++;
}
static void
dissect_osd_flush_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* dissecting the CDB dissection starts at byte 10 of the CDB */
if(isreq && iscdb){
/* options byte */
dissect_osd_flush_partition_scope(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(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for flush partition */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* no data in for flush partition */
}
}
static void
dissect_osd_get_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* 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(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, TRUE);
offset+=8;
/* user_object id */
dissect_osd_user_object_id(tvb, offset, tree);
offset+=8;
/* 20 reserved bytes */
offset+=20;
/* 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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for get attributes */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* no data in for get attributes */
}
}
static void
dissect_osd_list_collection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* dissecting the CDB dissection starts at byte 10 of the CDB */
if(isreq && iscdb){
/* one reserved byte */
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(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
offset+=8;
/* collection object id */
dissect_osd_collection_object_id(tvb, offset, tree);
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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for list collection */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* XXX dissect the data */
}
}
static void
dissect_osd_read(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* 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);
offset++;
/* timestamps control */
dissect_osd_timestamps_control(tvb, offset, tree);
offset++;
/* 3 reserved bytes */
offset+=3;
/* partiton id */
dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
offset+=8;
/* user object id */
dissect_osd_user_object_id(tvb, offset, tree);
offset+=8;
/* 4 reserved bytes */
offset+=4;
/* length */
dissect_osd_length(tvb, offset, tree);
offset+=8;
/* starting byte address */
dissect_osd_starting_byte_address(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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for READ */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* xxx should dissect the data ? */
}
}
static void
dissect_osd_set_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len _U_, scsi_task_data_t *cdata _U_,
scsi_osd_conv_info_t *conv_info _U_,
scsi_osd_lun_info_t *lun_info)
{
/* 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(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, TRUE);
offset+=8;
/* user_object id */
dissect_osd_user_object_id(tvb, offset, tree);
offset+=8;
/* 20 reserved bytes */
offset+=20;
/* 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){
/* attribute data out */
dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata);
/* no data out for set attributes */
}
/* dissecting the DATA IN */
if(!isreq && !iscdb){
/* attribute data in */
dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata);
/* no data in for set attributes */
}
}
/* OSD Service Actions */
#define OSD_FORMAT_OSD 0x8801
#define OSD_CREATE 0x8802
#define OSD_LIST 0x8803
#define OSD_READ 0x8805
#define OSD_WRITE 0x8806
#define OSD_APPEND 0x8807
#define OSD_FLUSH 0x8808
#define OSD_REMOVE 0x880a
#define OSD_CREATE_PARTITION 0x880b
#define OSD_REMOVE_PARTITION 0x880c
#define OSD_GET_ATTRIBUTES 0x880e
#define OSD_SET_ATTRIBUTES 0x880f
#define OSD_CREATE_AND_WRITE 0x8812
#define OSD_CREATE_COLLECTION 0x8815
#define OSD_REMOVE_COLLECTION 0x8816
#define OSD_LIST_COLLECTION 0x8817
#define OSD_SET_KEY 0x8818
#define OSD_FLUSH_COLLECTION 0x881a
#define OSD_FLUSH_PARTITION 0x881b
#define OSD_FLUSH_OSD 0x881c
static const value_string scsi_osd_svcaction_vals[] = {
{OSD_FORMAT_OSD, "Format OSD"},
{OSD_CREATE, "Create"},
{OSD_LIST, "List"},
{OSD_READ, "Read"},
{OSD_WRITE, "Write"},
{OSD_APPEND, "Append"},
{OSD_FLUSH, "Flush"},
{OSD_REMOVE, "Remove"},
{OSD_CREATE_PARTITION, "Create Partition"},
{OSD_REMOVE_PARTITION, "Remove Partition"},
{OSD_GET_ATTRIBUTES, "Get Attributes"},
{OSD_SET_ATTRIBUTES, "Set Attributes"},
{OSD_CREATE_AND_WRITE, "Create And Write"},
{OSD_CREATE_COLLECTION, "Create Collection"},
{OSD_REMOVE_COLLECTION, "Remove Collection"},
{OSD_LIST_COLLECTION, "List Collection"},
{OSD_SET_KEY, "Set Key"},
{OSD_FLUSH_COLLECTION, "Flush Collection"},
{OSD_FLUSH_PARTITION, "Flush Partition"},
{OSD_FLUSH_OSD, "Flush OSD"},
{0, NULL},
};
/* OSD Service Action dissectors */
typedef struct _scsi_osd_svcaction_t {
guint16 svcaction;
scsi_osd_dissector_t dissector;
} 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_READ, dissect_osd_read},
{OSD_WRITE, dissect_osd_write},
{OSD_APPEND, dissect_osd_append},
{OSD_FLUSH, dissect_osd_flush},
{OSD_REMOVE, dissect_osd_remove},
{OSD_CREATE_PARTITION, dissect_osd_create_partition},
{OSD_REMOVE_PARTITION, dissect_osd_remove_partition},
{OSD_GET_ATTRIBUTES, dissect_osd_get_attributes},
{OSD_SET_ATTRIBUTES, dissect_osd_set_attributes},
{OSD_CREATE_AND_WRITE, dissect_osd_create_and_write},
{OSD_CREATE_COLLECTION, dissect_osd_create_collection},
{OSD_REMOVE_COLLECTION, dissect_osd_remove_collection},
{OSD_LIST_COLLECTION, dissect_osd_list_collection},
{OSD_SET_KEY, dissect_osd_set_key},
{OSD_FLUSH_COLLECTION, dissect_osd_flush_collection},
{OSD_FLUSH_PARTITION, dissect_osd_flush_partition},
{OSD_FLUSH_OSD, dissect_osd_flush_osd},
{0, NULL},
};
static scsi_osd_dissector_t
find_svcaction_dissector(guint16 svcaction)
{
const scsi_osd_svcaction_t *sa=scsi_osd_svcaction;
while(sa&&sa->dissector){
if(sa->svcaction==svcaction){
return sa->dissector;
}
sa++;
}
return NULL;
}
static void
dissect_osd_opcode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset, gboolean isreq, gboolean iscdb,
guint payload_len, scsi_task_data_t *cdata)
{
guint16 svcaction=0;
scsi_osd_dissector_t dissector;
scsi_osd_conv_info_t *conv_info=NULL;
scsi_osd_lun_info_t *lun_info=NULL;
if(!tree) {
return;
}
/* We must have an itl an itlq and a conversation */
if(!cdata || !cdata->itl || !cdata->itl->conversation || !cdata->itlq){
return;
}
/* make sure we have a conversation info for this */
conv_info=conversation_get_proto_data(cdata->itl->conversation, proto_scsi_osd);
if(!conv_info){
conv_info=se_alloc(sizeof(scsi_osd_conv_info_t));
conv_info->luns=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SCSI OSD luns tree");
conversation_add_proto_data(cdata->itl->conversation, proto_scsi_osd, conv_info);
}
/* make sure we have a lun_info structure for this */
lun_info=se_tree_lookup32(conv_info->luns, cdata->itlq->lun);
if(!lun_info){
lun_info=se_alloc(sizeof(scsi_osd_lun_info_t));
lun_info->partitions=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SCSI OSD partitions tree");
se_tree_insert32(conv_info->luns, cdata->itlq->lun, (void *)lun_info);
}
/* dissecting the CDB */
if (isreq && iscdb) {
proto_tree_add_item (tree, hf_scsi_control, tvb, offset, 1, 0);
offset++;
/* 5 reserved bytes */
offset+=5;
proto_tree_add_item (tree, hf_scsi_osd_add_cdblen, tvb, offset, 1, 0);
offset++;
svcaction=tvb_get_ntohs(tvb, offset);
if(cdata && cdata->itlq){
/* We must store the service action for this itlq
* so we can indentify what the data contains
*/
if((!pinfo->fd->flags.visited) && (!cdata->itlq->extra_data)){
scsi_osd_extra_data_t *extra_data;
extra_data=se_alloc(sizeof(scsi_osd_extra_data_t));
extra_data->svcaction=svcaction;
extra_data->gsatype=0;
cdata->itlq->extra_data=extra_data;
}
}
proto_tree_add_item (tree, hf_scsi_osd_svcaction, tvb, offset, 2, 0);
offset+=2;
if(check_col(pinfo->cinfo, COL_INFO)){
col_append_str(pinfo->cinfo, COL_INFO,
val_to_str(svcaction, scsi_osd_svcaction_vals, "Unknown OSD Serviceaction"));
}
dissector=find_svcaction_dissector(svcaction);
if(dissector){
(*dissector)(tvb, pinfo, tree, offset, isreq, iscdb, payload_len, cdata, conv_info, lun_info);
}
return;
}
/* If it was not a CDB, try to find the service action and pass it
* off to the service action dissector
*/
if(cdata && cdata->itlq && cdata->itlq->extra_data){
scsi_osd_extra_data_t *extra_data=cdata->itlq->extra_data;
svcaction=extra_data->svcaction;
}
if(check_col(pinfo->cinfo, COL_INFO)){
col_append_str(pinfo->cinfo, COL_INFO,
val_to_str(svcaction, scsi_osd_svcaction_vals, "Unknown OSD Serviceaction"));
}
if(svcaction){
proto_item *it;
it=proto_tree_add_uint_format(tree, hf_scsi_osd_svcaction, tvb, 0, 0, svcaction, "Service Action: 0x%04x", svcaction);
PROTO_ITEM_SET_GENERATED(it);
}
dissector=find_svcaction_dissector(svcaction);
if(dissector){
(*dissector)(tvb, pinfo, tree, offset, isreq, iscdb, payload_len, cdata, conv_info, lun_info);
}
}
/* OSD Commands */
const value_string scsi_osd_vals[] = {
{SCSI_SPC_INQUIRY , "Inquiry"},
{SCSI_SPC_LOGSELECT , "Log Select"},
{SCSI_SPC_LOGSENSE , "Log Sense"},
{SCSI_SPC_MODESELECT10 , "Mode Select(10)"},
{SCSI_SPC_MODESENSE10 , "Mode Sense(10)"},
{SCSI_SPC_PERSRESVIN , "Persistent Reserve In"},
{SCSI_SPC_PERSRESVOUT , "Persistent Reserve Out"},
{SCSI_SPC_REPORTLUNS , "Report LUNs"},
{SCSI_OSD_OPCODE , "OSD Command" },
{0, NULL},
};
scsi_cdb_table_t scsi_osd_table[256] = {
/*OSD 0x00*/{NULL},
/*OSD 0x01*/{NULL},
/*OSD 0x02*/{NULL},
/*OSD 0x03*/{NULL},
/*OSD 0x04*/{NULL},
/*OSD 0x05*/{NULL},
/*OSD 0x06*/{NULL},
/*OSD 0x07*/{NULL},
/*OSD 0x08*/{NULL},
/*OSD 0x09*/{NULL},
/*OSD 0x0a*/{NULL},
/*OSD 0x0b*/{NULL},
/*OSD 0x0c*/{NULL},
/*OSD 0x0d*/{NULL},
/*OSD 0x0e*/{NULL},
/*OSD 0x0f*/{NULL},
/*OSD 0x10*/{NULL},
/*OSD 0x11*/{NULL},
/*OSD 0x12*/{dissect_spc_inquiry},
/*OSD 0x13*/{NULL},
/*OSD 0x14*/{NULL},
/*OSD 0x15*/{NULL},
/*OSD 0x16*/{NULL},
/*OSD 0x17*/{NULL},
/*OSD 0x18*/{NULL},
/*OSD 0x19*/{NULL},
/*OSD 0x1a*/{NULL},
/*OSD 0x1b*/{NULL},
/*OSD 0x1c*/{NULL},
/*OSD 0x1d*/{NULL},
/*OSD 0x1e*/{NULL},
/*OSD 0x1f*/{NULL},
/*OSD 0x20*/{NULL},
/*OSD 0x21*/{NULL},
/*OSD 0x22*/{NULL},
/*OSD 0x23*/{NULL},
/*OSD 0x24*/{NULL},
/*OSD 0x25*/{NULL},
/*OSD 0x26*/{NULL},
/*OSD 0x27*/{NULL},
/*OSD 0x28*/{NULL},
/*OSD 0x29*/{NULL},
/*OSD 0x2a*/{NULL},
/*OSD 0x2b*/{NULL},
/*OSD 0x2c*/{NULL},
/*OSD 0x2d*/{NULL},
/*OSD 0x2e*/{NULL},
/*OSD 0x2f*/{NULL},
/*OSD 0x30*/{NULL},
/*OSD 0x31*/{NULL},
/*OSD 0x32*/{NULL},
/*OSD 0x33*/{NULL},
/*OSD 0x34*/{NULL},
/*OSD 0x35*/{NULL},
/*OSD 0x36*/{NULL},
/*OSD 0x37*/{NULL},
/*OSD 0x38*/{NULL},
/*OSD 0x39*/{NULL},
/*OSD 0x3a*/{NULL},
/*OSD 0x3b*/{NULL},
/*OSD 0x3c*/{NULL},
/*OSD 0x3d*/{NULL},
/*OSD 0x3e*/{NULL},
/*OSD 0x3f*/{NULL},
/*OSD 0x40*/{NULL},
/*OSD 0x41*/{NULL},
/*OSD 0x42*/{NULL},
/*OSD 0x43*/{NULL},
/*OSD 0x44*/{NULL},
/*OSD 0x45*/{NULL},
/*OSD 0x46*/{NULL},
/*OSD 0x47*/{NULL},
/*OSD 0x48*/{NULL},
/*OSD 0x49*/{NULL},
/*OSD 0x4a*/{NULL},
/*OSD 0x4b*/{NULL},
/*OSD 0x4c*/{dissect_spc_logselect},
/*OSD 0x4d*/{dissect_spc_logsense},
/*OSD 0x4e*/{NULL},
/*OSD 0x4f*/{NULL},
/*OSD 0x50*/{NULL},
/*OSD 0x51*/{NULL},
/*OSD 0x52*/{NULL},
/*OSD 0x53*/{NULL},
/*OSD 0x54*/{NULL},
/*OSD 0x55*/{dissect_spc_modeselect10},
/*OSD 0x56*/{NULL},
/*OSD 0x57*/{NULL},
/*OSD 0x58*/{NULL},
/*OSD 0x59*/{NULL},
/*OSD 0x5a*/{dissect_spc_modesense10},
/*OSD 0x5b*/{NULL},
/*OSD 0x5c*/{NULL},
/*OSD 0x5d*/{NULL},
/*OSD 0x5e*/{dissect_spc_persistentreservein},
/*OSD 0x5f*/{dissect_spc_persistentreserveout},
/*OSD 0x60*/{NULL},
/*OSD 0x61*/{NULL},
/*OSD 0x62*/{NULL},
/*OSD 0x63*/{NULL},
/*OSD 0x64*/{NULL},
/*OSD 0x65*/{NULL},
/*OSD 0x66*/{NULL},
/*OSD 0x67*/{NULL},
/*OSD 0x68*/{NULL},
/*OSD 0x69*/{NULL},
/*OSD 0x6a*/{NULL},
/*OSD 0x6b*/{NULL},
/*OSD 0x6c*/{NULL},
/*OSD 0x6d*/{NULL},
/*OSD 0x6e*/{NULL},
/*OSD 0x6f*/{NULL},
/*OSD 0x70*/{NULL},
/*OSD 0x71*/{NULL},
/*OSD 0x72*/{NULL},
/*OSD 0x73*/{NULL},
/*OSD 0x74*/{NULL},
/*OSD 0x75*/{NULL},
/*OSD 0x76*/{NULL},
/*OSD 0x77*/{NULL},
/*OSD 0x78*/{NULL},
/*OSD 0x79*/{NULL},
/*OSD 0x7a*/{NULL},
/*OSD 0x7b*/{NULL},
/*OSD 0x7c*/{NULL},
/*OSD 0x7d*/{NULL},
/*OSD 0x7e*/{NULL},
/*OSD 0x7f*/{dissect_osd_opcode},
/*OSD 0x80*/{NULL},
/*OSD 0x81*/{NULL},
/*OSD 0x82*/{NULL},
/*OSD 0x83*/{NULL},
/*OSD 0x84*/{NULL},
/*OSD 0x85*/{NULL},
/*OSD 0x86*/{NULL},
/*OSD 0x87*/{NULL},
/*OSD 0x88*/{NULL},
/*OSD 0x89*/{NULL},
/*OSD 0x8a*/{NULL},
/*OSD 0x8b*/{NULL},
/*OSD 0x8c*/{NULL},
/*OSD 0x8d*/{NULL},
/*OSD 0x8e*/{NULL},
/*OSD 0x8f*/{NULL},
/*OSD 0x90*/{NULL},
/*OSD 0x91*/{NULL},
/*OSD 0x92*/{NULL},
/*OSD 0x93*/{NULL},
/*OSD 0x94*/{NULL},
/*OSD 0x95*/{NULL},
/*OSD 0x96*/{NULL},
/*OSD 0x97*/{NULL},
/*OSD 0x98*/{NULL},
/*OSD 0x99*/{NULL},
/*OSD 0x9a*/{NULL},
/*OSD 0x9b*/{NULL},
/*OSD 0x9c*/{NULL},
/*OSD 0x9d*/{NULL},
/*OSD 0x9e*/{NULL},
/*OSD 0x9f*/{NULL},
/*OSD 0xa0*/{dissect_spc_reportluns},
/*OSD 0xa1*/{NULL},
/*OSD 0xa2*/{NULL},
/*OSD 0xa3*/{NULL},
/*OSD 0xa4*/{NULL},
/*OSD 0xa5*/{NULL},
/*OSD 0xa6*/{NULL},
/*OSD 0xa7*/{NULL},
/*OSD 0xa8*/{NULL},
/*OSD 0xa9*/{NULL},
/*OSD 0xaa*/{NULL},
/*OSD 0xab*/{NULL},
/*OSD 0xac*/{NULL},
/*OSD 0xad*/{NULL},
/*OSD 0xae*/{NULL},
/*OSD 0xaf*/{NULL},
/*OSD 0xb0*/{NULL},
/*OSD 0xb1*/{NULL},
/*OSD 0xb2*/{NULL},
/*OSD 0xb3*/{NULL},
/*OSD 0xb4*/{NULL},
/*OSD 0xb5*/{NULL},
/*OSD 0xb6*/{NULL},
/*OSD 0xb7*/{NULL},
/*OSD 0xb8*/{NULL},
/*OSD 0xb9*/{NULL},
/*OSD 0xba*/{NULL},
/*OSD 0xbb*/{NULL},
/*OSD 0xbc*/{NULL},
/*OSD 0xbd*/{NULL},
/*OSD 0xbe*/{NULL},
/*OSD 0xbf*/{NULL},
/*OSD 0xc0*/{NULL},
/*OSD 0xc1*/{NULL},
/*OSD 0xc2*/{NULL},
/*OSD 0xc3*/{NULL},
/*OSD 0xc4*/{NULL},
/*OSD 0xc5*/{NULL},
/*OSD 0xc6*/{NULL},
/*OSD 0xc7*/{NULL},
/*OSD 0xc8*/{NULL},
/*OSD 0xc9*/{NULL},
/*OSD 0xca*/{NULL},
/*OSD 0xcb*/{NULL},
/*OSD 0xcc*/{NULL},
/*OSD 0xcd*/{NULL},
/*OSD 0xce*/{NULL},
/*OSD 0xcf*/{NULL},
/*OSD 0xd0*/{NULL},
/*OSD 0xd1*/{NULL},
/*OSD 0xd2*/{NULL},
/*OSD 0xd3*/{NULL},
/*OSD 0xd4*/{NULL},
/*OSD 0xd5*/{NULL},
/*OSD 0xd6*/{NULL},
/*OSD 0xd7*/{NULL},
/*OSD 0xd8*/{NULL},
/*OSD 0xd9*/{NULL},
/*OSD 0xda*/{NULL},
/*OSD 0xdb*/{NULL},
/*OSD 0xdc*/{NULL},
/*OSD 0xdd*/{NULL},
/*OSD 0xde*/{NULL},
/*OSD 0xdf*/{NULL},
/*OSD 0xe0*/{NULL},
/*OSD 0xe1*/{NULL},
/*OSD 0xe2*/{NULL},
/*OSD 0xe3*/{NULL},
/*OSD 0xe4*/{NULL},
/*OSD 0xe5*/{NULL},
/*OSD 0xe6*/{NULL},
/*OSD 0xe7*/{NULL},
/*OSD 0xe8*/{NULL},
/*OSD 0xe9*/{NULL},
/*OSD 0xea*/{NULL},
/*OSD 0xeb*/{NULL},
/*OSD 0xec*/{NULL},
/*OSD 0xed*/{NULL},
/*OSD 0xee*/{NULL},
/*OSD 0xef*/{NULL},
/*OSD 0xf0*/{NULL},
/*OSD 0xf1*/{NULL},
/*OSD 0xf2*/{NULL},
/*OSD 0xf3*/{NULL},
/*OSD 0xf4*/{NULL},
/*OSD 0xf5*/{NULL},
/*OSD 0xf6*/{NULL},
/*OSD 0xf7*/{NULL},
/*OSD 0xf8*/{NULL},
/*OSD 0xf9*/{NULL},
/*OSD 0xfa*/{NULL},
/*OSD 0xfb*/{NULL},
/*OSD 0xfc*/{NULL},
/*OSD 0xfd*/{NULL},
/*OSD 0xfe*/{NULL},
/*OSD 0xff*/{NULL}
};
void
proto_register_scsi_osd(void)
{
static hf_register_info hf[] = {
{ &hf_scsi_osd_opcode,
{"OSD Opcode", "scsi.osd.opcode", FT_UINT8, BASE_HEX,
VALS (scsi_osd_vals), 0x0, NULL, HFILL}},
{ &hf_scsi_osd_add_cdblen,
{"Additional CDB Length", "scsi.osd.addcdblen", FT_UINT8, BASE_DEC,
NULL, 0x0, NULL, HFILL}},
{ &hf_scsi_osd_svcaction,
{"Service Action", "scsi.osd.svcaction", FT_UINT16, BASE_HEX,
VALS(scsi_osd_svcaction_vals), 0x0, NULL, HFILL}},
{ &hf_scsi_osd_option,
{"Options Byte", "scsi.osd.option", FT_UINT8, BASE_HEX,
NULL, 0x0, NULL, HFILL}},
{ &hf_scsi_osd_option_dpo,
{"DPO", "scsi.osd.option.dpo", FT_BOOLEAN, 8,
TFS(&option_dpo_tfs), 0x10, NULL, HFILL}},
{ &hf_scsi_osd_option_fua,
{"FUA", "scsi.osd.option.fua", FT_BOOLEAN, 8,
TFS(&option_fua_tfs), 0x08, NULL, HFILL}},
{ &hf_scsi_osd_getsetattrib,
{"GET/SET CDBFMT", "scsi.osd.getset", FT_UINT8, BASE_HEX,
VALS(scsi_osd_getsetattrib_vals), 0x30, NULL, HFILL}},
{ &hf_scsi_osd_timestamps_control,
{"Timestamps Control", "scsi.osd.timestamps_control", FT_UINT8, BASE_HEX,
VALS(scsi_osd_timestamps_control_vals), 0x0, NULL, HFILL}},
{ &hf_scsi_osd_formatted_capacity,
{"Formatted Capacity", "scsi.osd.formatted_capacity", FT_UINT64, BASE_DEC,
NULL, 0x0, NULL, HFILL}},
{ &hf_scsi_osd_get_attributes_page,
{"Get Attributes Page", "scsi.osd.get_attributes_page", FT_UINT32, BASE_HEX,
NULL, 0x0, NULL, HFILL}},
{ &hf_scsi_osd_get_attributes_list_length,
{"Get Attributes List Length", "scsi.osd.get_attributes_list_length", FT_UINT32, BASE_HEX,
NULL, 0x0, NULL, HFILL}},
{ &hf_scsi_osd_get_attributes_list_offset,
{"Get Attributes List Offset", "scsi.osd.get_attributes_list_offset", FT_UINT32, BASE_HEX,
NULL, 0x0, NULL, HFILL}},
{ &hf_scsi_osd_set_attributes_list_length,
{"Set Attributes List Length", "scsi.osd.set_attributes_list_length", FT_UINT32, BASE_HEX,
NULL, 0x0, NULL, HFILL}},
{ &hf_scsi_osd_set_attributes_list_offset,
{"Set Attributes List Offset", "scsi.osd.set_attributes_list_offset", FT_UINT32, BASE_HEX,
NULL, 0x0, NULL, HFILL}},
{ &hf_scsi_osd_get_attributes_allocation_length,
{"Get Attributes Allocation Length", "scsi.osd.get_attributes_allocation_length", FT_UINT32, BASE_HEX,
NULL, 0x0, NULL, HFILL}},
{ &hf_scsi_osd_retrieved_attributes_offset,
{"Retrieved Attributes Offset", "scsi.osd.retrieved_attributes_offset", FT_UINT32, BASE_HEX,
NULL, 0x0, NULL, HFILL}},
{ &hf_scsi_osd_set_attributes_page,
{"Set Attributes Page", "scsi.osd.set_attributes_page", FT_UINT32, BASE_HEX,
NULL, 0x0, NULL, HFILL}},
{ &hf_scsi_osd_set_attribute_length,
{"Set Attribute Length", "scsi.osd.set_attribute_length", FT_UINT32, BASE_HEX,
NULL, 0x0, NULL, HFILL}},
{ &hf_scsi_osd_set_attribute_number,
{"Set Attribute Number", "scsi.osd.set_attribute_number", FT_UINT32, BASE_HEX,
NULL, 0x0, NULL, HFILL}},
{ &hf_scsi_osd_set_attributes_offset,
{"Set Attributes Offset", "scsi.osd.set_attributes_offset", FT_UINT32, BASE_HEX,
NULL, 0x0, NULL, HFILL}},
{ &hf_scsi_osd_capability_format,
{"Capability Format", "scsi.osd.capability_format", FT_UINT8, BASE_HEX,
VALS(scsi_osd_capability_format_vals), 0x0f, NULL, HFILL}},
{ &hf_scsi_osd_key_version,
{"Key Version", "scsi.osd.key_version", FT_UINT8, BASE_HEX,
NULL, 0xf0, NULL, HFILL}},
{ &hf_scsi_osd_icva,
{"Integrity Check Value Algorithm", "scsi.osd.icva", FT_UINT8, BASE_HEX,
NULL, 0x0f, NULL, HFILL}},
{ &hf_scsi_osd_security_method,
{"Security Method", "scsi.osd.security_method", FT_UINT8, BASE_HEX,
NULL, 0x0f, NULL, HFILL}},
{ &hf_scsi_osd_capability_expiration_time,
{"Capability Expiration Time", "scsi.osd.capability_expiration_time", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_audit,
{"Audit", "scsi.osd.audit", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_capability_discriminator,
{"Capability Discriminator", "scsi.osd.capability_descriminator", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_object_created_time,
{"Object Created Time", "scsi.osd.object_created_time", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_object_type,
{"Object Type", "scsi.osd.object_type", FT_UINT8, BASE_HEX,
VALS(scsi_osd_object_type_vals), 0, NULL, HFILL}},
{ &hf_scsi_osd_permissions,
{"Permissions", "scsi.osd.permissions", FT_UINT16, BASE_HEX,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_permissions_read,
{"READ", "scsi.osd.permissions.read", FT_BOOLEAN, 16,
TFS(&permissions_read_tfs), 0x8000, NULL, HFILL}},
{ &hf_scsi_osd_permissions_write,
{"WRITE", "scsi.osd.permissions.write", FT_BOOLEAN, 16,
TFS(&permissions_write_tfs), 0x4000, NULL, HFILL}},
{ &hf_scsi_osd_permissions_get_attr,
{"GET_ATTR", "scsi.osd.permissions.get_attr", FT_BOOLEAN, 16,
TFS(&permissions_get_attr_tfs), 0x2000, NULL, HFILL}},
{ &hf_scsi_osd_permissions_set_attr,
{"SET_ATTR", "scsi.osd.permissions.set_attr", FT_BOOLEAN, 16,
TFS(&permissions_set_attr_tfs), 0x1000, NULL, HFILL}},
{ &hf_scsi_osd_permissions_create,
{"CREATE", "scsi.osd.permissions.create", FT_BOOLEAN, 16,
TFS(&permissions_create_tfs), 0x0800, NULL, HFILL}},
{ &hf_scsi_osd_permissions_remove,
{"REMOVE", "scsi.osd.permissions.remove", FT_BOOLEAN, 16,
TFS(&permissions_remove_tfs), 0x0400, NULL, HFILL}},
{ &hf_scsi_osd_permissions_obj_mgmt,
{"OBJ_MGMT", "scsi.osd.permissions.obj_mgmt", FT_BOOLEAN, 16,
TFS(&permissions_obj_mgmt_tfs), 0x0200, NULL, HFILL}},
{ &hf_scsi_osd_permissions_append,
{"APPEND", "scsi.osd.permissions.append", FT_BOOLEAN, 16,
TFS(&permissions_append_tfs), 0x0100, NULL, HFILL}},
{ &hf_scsi_osd_permissions_dev_mgmt,
{"DEV_MGMT", "scsi.osd.permissions.dev_mgmt", FT_BOOLEAN, 16,
TFS(&permissions_dev_mgmt_tfs), 0x0080, NULL, HFILL}},
{ &hf_scsi_osd_permissions_global,
{"GLOBAL", "scsi.osd.permissions.global", FT_BOOLEAN, 16,
TFS(&permissions_global_tfs), 0x0040, NULL, HFILL}},
{ &hf_scsi_osd_permissions_pol_sec,
{"POL/SEC", "scsi.osd.permissions.pol_sec", FT_BOOLEAN, 16,
TFS(&permissions_pol_sec_tfs), 0x0020, NULL, HFILL}},
{ &hf_scsi_osd_object_descriptor_type,
{"Object Descriptor Type", "scsi.osd.object_descriptor_type", FT_UINT8, BASE_HEX,
VALS(scsi_osd_object_descriptor_type_vals), 0xf0, NULL, HFILL}},
{ &hf_scsi_osd_object_descriptor,
{"Object Descriptor", "scsi.osd.object_descriptor", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_ricv,
{"Request Integrity Check value", "scsi.osd.ricv", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_request_nonce,
{"Request Nonce", "scsi.osd.request_nonce", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_diicvo,
{"Data-In Integrity Check Value Offset", "scsi.osd.diicvo", FT_UINT32, BASE_DEC,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_doicvo,
{"Data-Out Integrity Check Value Offset", "scsi.osd.doicvo", FT_UINT32, BASE_DEC,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_requested_partition_id,
{"Requested Partition Id", "scsi.osd.requested_partition_id", FT_UINT64, BASE_HEX,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_sortorder,
{"Sort Order", "scsi.osd.sort_order", FT_UINT8, BASE_DEC,
VALS(scsi_osd_sort_order_vals), 0x0f, NULL, HFILL}},
{ &hf_scsi_osd_partition_id,
{"Partition Id", "scsi.osd.partition_id", FT_UINT64, BASE_HEX,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_list_identifier,
{"List Identifier", "scsi.osd.list_identifier", FT_UINT32, BASE_DEC,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_allocation_length,
{"Allocation Length", "scsi.osd.allocation_length", FT_UINT64, BASE_DEC,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_length,
{"Length", "scsi.osd.length", FT_UINT64, BASE_DEC,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_starting_byte_address,
{"Starting Byte Address", "scsi.osd.starting_byte_address", FT_UINT64, BASE_DEC,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_initial_object_id,
{"Initial Object Id", "scsi.osd.initial_object_id", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_additional_length,
{"Additional Length", "scsi.osd.additional_length", FT_UINT64, BASE_DEC,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_continuation_object_id,
{"Continuation Object Id", "scsi.osd.continuation_object_id", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_user_object_id,
{"User Object Id", "scsi.osd.user_object_id", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_list_flags_lstchg,
{"LSTCHG", "scsi.osd.list.lstchg", FT_BOOLEAN, 8,
TFS(&list_lstchg_tfs), 0x02, NULL, HFILL}},
{ &hf_scsi_osd_list_flags_root,
{"ROOT", "scsi.osd.list.root", FT_BOOLEAN, 8,
TFS(&list_root_tfs), 0x01, NULL, HFILL}},
{ &hf_scsi_osd_requested_user_object_id,
{"Requested User Object Id", "scsi.osd.requested_user_object_id", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_number_of_user_objects,
{"Number Of User Objects", "scsi.osd.number_of_user_objects", FT_UINT16, BASE_DEC,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_key_to_set,
{"Key to Set", "scsi.osd.key_to_set", FT_UINT8, BASE_DEC,
VALS(key_to_set_vals), 0x03, NULL, HFILL}},
{ &hf_scsi_osd_set_key_version,
{"Key Version", "scsi.osd.set_key_version", FT_UINT8, BASE_DEC,
NULL, 0x0f, NULL, HFILL}},
{ &hf_scsi_osd_key_identifier,
{"Key Identifier", "scsi.osd.key_identifier", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_seed,
{"Seed", "scsi.osd.seed", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_collection_fcr,
{"FCR", "scsi.osd.collection.fcr", FT_BOOLEAN, 8,
TFS(&collection_fcr_tfs), 0x01, NULL, HFILL}},
{ &hf_scsi_osd_collection_object_id,
{"Collection Object Id", "scsi.osd.collection_object_id", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_requested_collection_object_id,
{"Requested Collection Object Id", "scsi.osd.requested_collection_object_id", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_partition_created_in,
{ "Created In", "scsi.osd.partition.created_in", FT_FRAMENUM, BASE_NONE,
NULL, 0x0, "The frame this partition was created", HFILL }},
{ &hf_scsi_osd_partition_removed_in,
{ "Removed In", "scsi.osd.partition.removed_in", FT_FRAMENUM, BASE_NONE,
NULL, 0x0, "The frame this partition was removed", HFILL }},
{ &hf_scsi_osd_flush_scope,
{"Flush Scope", "scsi.osd.flush.scope", FT_UINT8, BASE_DEC,
VALS(flush_scope_vals), 0x03, NULL, HFILL}},
{ &hf_scsi_osd_flush_collection_scope,
{"Flush Collection Scope", "scsi.osd.flush_collection.scope", FT_UINT8, BASE_DEC,
VALS(flush_collection_scope_vals), 0x03, NULL, HFILL}},
{ &hf_scsi_osd_flush_partition_scope,
{"Flush Partition Scope", "scsi.osd.flush_partition.scope", FT_UINT8, BASE_DEC,
VALS(flush_partition_scope_vals), 0x03, NULL, HFILL}},
{ &hf_scsi_osd_flush_osd_scope,
{"Flush OSD Scope", "scsi.osd.flush_osd.scope", FT_UINT8, BASE_DEC,
VALS(flush_osd_scope_vals), 0x03, NULL, HFILL}},
{ &hf_scsi_osd_attributes_list_type,
{"Attributes List Type", "scsi.osd.attributes_list.type", FT_UINT8, BASE_HEX,
VALS(attributes_list_type_vals), 0x0f, NULL, HFILL}},
{ &hf_scsi_osd_attributes_list_length,
{"Attributes List Length", "scsi.osd.attributes_list.length", FT_UINT16, BASE_DEC,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_attributes_page,
{"Attributes Page", "scsi.osd.attributes.page", FT_UINT32, BASE_HEX,
VALS(attributes_page_vals), 0, NULL, HFILL}},
{ &hf_scsi_osd_attribute_number,
{"Attribute Number", "scsi.osd.attribute.number", FT_UINT32, BASE_HEX,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_attribute_length,
{"Attribute Length", "scsi.osd.attribute.length", FT_UINT16, BASE_DEC,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_osd_user_object_logical_length,
{"User Object Logical Length", "scsi.osd.user_object.logical_length", FT_UINT64, BASE_DEC,
NULL, 0, NULL, HFILL}},
};
/* Setup protocol subtree array */
static gint *ett[] = {
&ett_osd_option,
&ett_osd_partition,
&ett_osd_attribute_parameters,
&ett_osd_capability,
&ett_osd_permission_bitmask,
&ett_osd_security_parameters,
};
/* Register the protocol name and description */
proto_scsi_osd = proto_register_protocol("SCSI_OSD", "SCSI_OSD", "scsi_osd");
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array(proto_scsi_osd, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_scsi_osd(void)
{
}