diff options
-rw-r--r-- | epan/dissectors/packet-iscsi.c | 90 | ||||
-rw-r--r-- | epan/dissectors/packet-scsi-osd.c | 184 |
2 files changed, 250 insertions, 24 deletions
diff --git a/epan/dissectors/packet-iscsi.c b/epan/dissectors/packet-iscsi.c index 081a184e46..8e747cc2fd 100644 --- a/epan/dissectors/packet-iscsi.c +++ b/epan/dissectors/packet-iscsi.c @@ -101,7 +101,9 @@ static int hf_iscsi_response_frame = -1; static int hf_iscsi_AHS = -1; static int hf_iscsi_AHS_length = -1; static int hf_iscsi_AHS_type = -1; -static int hf_iscsi_AHS_specific = -1; +static int hf_iscsi_AHS_blob = -1; +static int hf_iscsi_AHS_read_data_length = -1; +static int hf_iscsi_AHS_extended_cdb = -1; static int hf_iscsi_Padding = -1; static int hf_iscsi_ping_data = -1; static int hf_iscsi_immediate_data = -1; @@ -753,8 +755,8 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off guint immediate_data_length=0; guint immediate_data_offset=0; itl_nexus_t *itl=NULL; - guint16 ahs_length=0; - guint8 ahs_type=0; + guint ahs_cdb_length=0; + guint ahs_cdb_offset=0; if(paddedDataSegmentLength & 3) paddedDataSegmentLength += 4 - (paddedDataSegmentLength & 3); @@ -975,17 +977,51 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off proto_tree_add_item(ti, hf_iscsi_ExpectedDataTransferLength, tvb, offset + 20, 4, FALSE); proto_tree_add_item(ti, hf_iscsi_CmdSN, tvb, offset + 24, 4, FALSE); proto_tree_add_item(ti, hf_iscsi_ExpStatSN, tvb, offset + 28, 4, FALSE); - { - if(ahsLen > 0) { - ahs_length=tvb_get_ntohs(tvb, offset+48); - proto_tree_add_item(ti, hf_iscsi_AHS_length, tvb, offset + 48, 2, FALSE); - ahs_type=tvb_get_guint8(tvb, offset+50); - proto_tree_add_item(ti, hf_iscsi_AHS_type, tvb, offset + 50, 1, FALSE); - proto_tree_add_item(ti, hf_iscsi_AHS_specific, tvb, offset + 51, 1, FALSE); - proto_tree_add_item(ti, hf_iscsi_AHS, tvb, offset + 52, ahsLen-4, FALSE); + if(ahsLen > 0) { + int ahs_offset=offset+48; + guint16 ahs_length=0; + guint8 ahs_type=0; + + while(ahs_offset<(offset+48+ahsLen)){ + + ahs_length=tvb_get_ntohs(tvb, ahs_offset); + proto_tree_add_item(ti, hf_iscsi_AHS_length, tvb, ahs_offset, 2, FALSE); + ahs_offset+=2; + + ahs_type=tvb_get_guint8(tvb, ahs_offset); + proto_tree_add_item(ti, hf_iscsi_AHS_type, tvb, ahs_offset, 1, FALSE); + ahs_offset++; + + switch(ahs_type){ + case 0x01: /* extended CDB */ + /* additional cdb */ + ahs_cdb_offset=ahs_offset+1; + ahs_cdb_length=ahs_length-1; + proto_tree_add_item(ti, hf_iscsi_AHS_extended_cdb, tvb, ahs_cdb_offset, ahs_cdb_length, FALSE); + ahs_offset+=ahs_length; + break; + case 0x02: /* bidirectional read data length */ + /* skip reserved byte */ + ahs_offset++; + /* read data length */ + proto_tree_add_item(ti, hf_iscsi_AHS_read_data_length, tvb, ahs_offset, 4, FALSE); + ahs_offset+=4; + break; + default: + proto_tree_add_item(ti, hf_iscsi_AHS_blob, tvb, ahs_offset, ahs_length, FALSE); + ahs_offset+=ahs_length; + } + + /* strip off padding bytes */ + if(ahs_offset&0x0003){ + ahs_offset=(ahs_offset+3)&0xfffc; + } + } - offset = handleHeaderDigest(iscsi_session, ti, tvb, offset, 48 + ahsLen); + } + offset = handleHeaderDigest(iscsi_session, ti, tvb, offset, 48 + ahsLen); + immediate_data_offset=offset; offset = handleDataSegment(ti, tvb, offset, data_segment_len, end_offset, hf_iscsi_immediate_data); immediate_data_length=offset-immediate_data_offset; @@ -1511,21 +1547,21 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off tvb_len=tvb_length_remaining(tvb, cdb_offset); tvb_rlen=tvb_reported_length_remaining(tvb, cdb_offset); scsi_opcode=tvb_get_guint8(tvb, cdb_offset); - if(ahs_type==1 && ahs_length && ahs_length<1024){ + if(ahs_cdb_length && ahs_cdb_length<1024){ char *cdb_buf; /* We have a variable length CDB where bytes >16 is transported * in the AHS. */ - cdb_buf=ep_alloc(16+ahs_length-1); + cdb_buf=ep_alloc(16+ahs_cdb_length); /* the 16 first bytes of the cdb */ tvb_memcpy(tvb, cdb_buf, cdb_offset, 16); - /* hte remainder of the cdb from the ahs */ - tvb_memcpy(tvb, cdb_buf+16, cdb_offset+20, ahs_length-1); + /* the remainder of the cdb from the ahs */ + tvb_memcpy(tvb, cdb_buf+16, ahs_cdb_offset, ahs_cdb_length); cdb_tvb = tvb_new_real_data(cdb_buf, - ahs_length+16-1, - ahs_length+16-1); + ahs_cdb_length+16, + ahs_cdb_length+16); tvb_set_child_real_data_tvbuff(tvb, cdb_tvb); @@ -2419,15 +2455,25 @@ proto_register_iscsi(void) FT_UINT16, BASE_DEC, NULL, 0, "Length of Additional header segment", HFILL } }, + { &hf_iscsi_AHS_read_data_length, + { "Bidirectional Read Data Length", "iscsi.ahs.bidir.length", + FT_UINT32, BASE_DEC, NULL, 0, + "", HFILL } + }, { &hf_iscsi_AHS_type, { "AHS Type", "iscsi.ahs.type", FT_UINT8, BASE_DEC, VALS(ahs_type_vals), 0, "Type of Additional header segment", HFILL } }, - { &hf_iscsi_AHS_specific, - { "AHS Specific", "iscsi.ahs", - FT_UINT8, BASE_HEX, NULL, 0, - "Specific qualifier of Additional header segment", HFILL } + { &hf_iscsi_AHS_extended_cdb, + { "AHS Extended CDB", "iscsi.ahs.extended_cdb", + FT_BYTES, BASE_HEX, NULL, 0, + "", HFILL } + }, + { &hf_iscsi_AHS_blob, + { "Unknown AHS blob", "iscsi.ahs.unknown_blob", + FT_BYTES, BASE_HEX, NULL, 0, + "", HFILL } }, { &hf_iscsi_Padding, { "Padding", "iscsi.padding", diff --git a/epan/dissectors/packet-scsi-osd.c b/epan/dissectors/packet-scsi-osd.c index 0b6ba26327..74ea55822b 100644 --- a/epan/dissectors/packet-scsi-osd.c +++ b/epan/dissectors/packet-scsi-osd.c @@ -78,6 +78,13 @@ 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; @@ -362,7 +369,7 @@ dissect_osd_requested_partition_id(tvbuff_t *tvb, int offset, proto_tree *tree) static void dissect_osd_partition_id(tvbuff_t *tvb, int offset, proto_tree *tree) { - /* request partition id */ + /* partition id */ proto_tree_add_item(tree, hf_scsi_osd_partition_id, tvb, offset, 8, 0); offset+=8; } @@ -460,6 +467,40 @@ dissect_osd_initial_object_id(tvbuff_t *tvb, int offset, proto_tree *tree) } 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_) @@ -521,8 +562,123 @@ dissect_osd_list(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, /* dissecting the DATA IN */ if(!isreq && !iscdb){ + guint64 additional_length; + gboolean is_root; + /* dissection of the LIST DATA-IN */ -/* qqq to be added ... */ + /* 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 */ } } @@ -530,10 +686,12 @@ dissect_osd_list(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, /* 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}, @@ -546,6 +704,7 @@ 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}, @@ -1042,6 +1201,27 @@ proto_register_scsi_osd(void) { &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 */ |