QSIG fully implemented
[obnox/wireshark/wip.git] / epan / dissectors / packet-fcp.c
index 1ce32a66c481354dffce0cfa8225f636d09bea23..e12e2ab708c8ea0b43d765bbb011c312e36fd651 100644 (file)
@@ -46,9 +46,9 @@
 #include <epan/packet.h>
 #include <epan/conversation.h>
 #include <epan/etypes.h>
+#include "packet-scsi.h"
 #include "packet-fc.h"
 #include "packet-fcp.h"
-#include "packet-scsi.h"
 
 /* Initialize the protocol and registered fields */
 static int proto_fcp         = -1;
@@ -61,6 +61,7 @@ static int hf_fcp_addlcdblen = -1;
 static int hf_fcp_rddata     = -1;
 static int hf_fcp_wrdata     = -1;
 static int hf_fcp_dl         = -1;
+static int hf_fcp_bidir_dl   = -1;
 static int hf_fcp_data_ro    = -1;
 static int hf_fcp_burstlen   = -1;
 static int hf_fcp_rspflags   = -1;
@@ -190,7 +191,7 @@ dissect_task_mgmt_flags (packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *
 
        if (!flags)
                proto_item_append_text(item, " (No values set)");
-                               
+
        proto_tree_add_boolean(tree, hf_fcp_mgmt_flags_obsolete, tvb, offset, 1, flags);
        if (flags&0x80){
                proto_item_append_text(item, "  OBSOLETE");
@@ -397,7 +398,7 @@ dissect_fcp_cmnd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, pro
     int offset = 0;
     int len,
         add_len = 0;
-    guint8 flags, lun0;
+    guint8 flags, rwflags, lun0;
         guint16 lun=0xffff;
     tvbuff_t *cdb_tvb;
     int tvb_len, tvb_rlen;
@@ -434,12 +435,15 @@ dissect_fcp_cmnd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, pro
                           1, 0);
       lun=tvb_get_guint8(tvb, offset+1);
     }
-    fchdr->itlq->lun=lun;
+
+    if (fchdr->itlq)
+        fchdr->itlq->lun=lun;
 
     itl=(itl_nexus_t *)se_tree_lookup32(fcp_conv_data->luns, lun);
     if(!itl){
         itl=se_alloc(sizeof(itl_nexus_t));
         itl->cmdset=0xff;
+       itl->conversation=conversation;
         se_tree_insert32(fcp_conv_data->luns, lun, itl);
     }
 
@@ -447,6 +451,15 @@ dissect_fcp_cmnd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, pro
     proto_tree_add_item(tree, hf_fcp_taskattr, tvb, offset+9, 1, 0);
     dissect_task_mgmt_flags(pinfo, tree, tvb, offset+10);
     proto_tree_add_item(tree, hf_fcp_addlcdblen, tvb, offset+11, 1, 0);
+    rwflags=tvb_get_guint8(tvb, offset+11);
+    if(fchdr->itlq){
+       if(rwflags&0x02){
+           fchdr->itlq->task_flags|=SCSI_DATA_READ;
+       }
+       if(rwflags&0x01){
+           fchdr->itlq->task_flags|=SCSI_DATA_WRITE;
+       }
+    }
     proto_tree_add_item(tree, hf_fcp_rddata, tvb, offset+11, 1, 0);
     proto_tree_add_item(tree, hf_fcp_wrdata, tvb, offset+11, 1, 0);
 
@@ -461,12 +474,26 @@ dissect_fcp_cmnd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, pro
 
     proto_tree_add_item(tree, hf_fcp_dl, tvb, offset+12+16+add_len,
                         4, 0);
+    if(fchdr->itlq){
+       fchdr->itlq->data_length=tvb_get_ntohl(tvb, offset+12+16+add_len);
+    }
+
+    if( ((rwflags&0x03)==0x03)
+    &&  tvb_length_remaining(tvb, offset+12+16+add_len+4)>=4){
+       proto_tree_add_item(tree, hf_fcp_bidir_dl, tvb, offset+12+16+add_len+4,
+                        4, 0);
+       if(fchdr->itlq){
+           fchdr->itlq->bidir_data_length=tvb_get_ntohl(tvb, offset+12+16+add_len+4);
+       }
+
+    }
+
 }
 
 static void
-dissect_fcp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, conversation_t *conversation, fc_hdr *fchdr, itl_nexus_t *itl)
+dissect_fcp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, conversation_t *conversation _U_, fc_hdr *fchdr, itl_nexus_t *itl)
 {
-    dissect_scsi_payload(tvb, pinfo, parent_tree, FALSE, fchdr->itlq, itl);
+    dissect_scsi_payload(tvb, pinfo, parent_tree, FALSE, fchdr->itlq, itl, fchdr->relative_offset);
 }
 
 /* fcp-3  9.5 table 24 */
@@ -485,7 +512,7 @@ dissect_fcp_rspinfo(tvbuff_t *tvb, proto_tree *tree, int offset)
 }
 
 static void
-dissect_fcp_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, proto_tree *tree, conversation_t *conversation, fc_hdr *fchdr, itl_nexus_t *itl)
+dissect_fcp_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, proto_tree *tree, conversation_t *conversation _U_, fc_hdr *fchdr, itl_nexus_t *itl)
 {
     guint32 offset = 0;
     gint32 snslen = 0,
@@ -545,7 +572,7 @@ dissect_fcp_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, prot
         /* rsp_info */
         if(rsplen){
             tvbuff_t *rspinfo_tvb;
-       
+
             rspinfo_tvb=tvb_new_subset(tvb, offset, MIN(rsplen, tvb_length_remaining(tvb, offset)), rsplen);
             dissect_fcp_rspinfo(tvb, tree, 0);
 
@@ -555,7 +582,7 @@ dissect_fcp_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, prot
         /* sense info */
         if(snslen){
             tvbuff_t *sns_tvb;
-       
+
             sns_tvb=tvb_new_subset(tvb, offset, MIN(snslen, tvb_length_remaining(tvb, offset)), snslen);
             dissect_scsi_snsinfo (sns_tvb, pinfo, parent_tree, 0,
                                   snslen,
@@ -713,6 +740,8 @@ proto_register_fcp (void)
           {"WRDATA", "fcp.wrdata", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL}},
         { &hf_fcp_dl,
           {"FCP_DL", "fcp.dl", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
+        { &hf_fcp_bidir_dl,
+          {"FCP_BIDIRECTIONAL_READ_DL", "fcp.bidir_dl", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
         { &hf_fcp_data_ro,
           {"FCP_DATA_RO", "fcp.data_ro", FT_UINT32, BASE_DEC, NULL, 0x0, "",
            HFILL}},
@@ -743,35 +772,35 @@ proto_register_fcp (void)
         { &hf_fcp_scsistatus,
           {"SCSI Status", "fcp.status", FT_UINT8, BASE_HEX,
            VALS (scsi_status_val), 0x0, "", HFILL}},
-       { &hf_fcp_mgmt_flags_obsolete, 
+       { &hf_fcp_mgmt_flags_obsolete,
          { "Obsolete", "fcp.mgmt.flags.obsolete", FT_BOOLEAN, 8, TFS(&fcp_mgmt_flags_obsolete_tfs), 0x80, "", HFILL }},
-       { &hf_fcp_mgmt_flags_clear_aca, 
+       { &hf_fcp_mgmt_flags_clear_aca,
          { "Clear ACA", "fcp.mgmt.flags.clear_aca", FT_BOOLEAN, 8, TFS(&fcp_mgmt_flags_clear_aca_tfs), 0x40, "", HFILL }},
-       { &hf_fcp_mgmt_flags_target_reset, 
+       { &hf_fcp_mgmt_flags_target_reset,
          { "Target Reset", "fcp.mgmt.flags.target_reset", FT_BOOLEAN, 8, TFS(&fcp_mgmt_flags_target_reset_tfs), 0x20, "", HFILL }},
-       { &hf_fcp_mgmt_flags_lu_reset, 
+       { &hf_fcp_mgmt_flags_lu_reset,
          { "LU Reset", "fcp.mgmt.flags.lu_reset", FT_BOOLEAN, 8, TFS(&fcp_mgmt_flags_lu_reset_tfs), 0x10, "", HFILL }},
-       { &hf_fcp_mgmt_flags_rsvd, 
+       { &hf_fcp_mgmt_flags_rsvd,
          { "Rsvd", "fcp.mgmt.flags.rsvd", FT_BOOLEAN, 8, TFS(&fcp_mgmt_flags_rsvd_tfs), 0x08, "", HFILL }},
-       { &hf_fcp_mgmt_flags_clear_task_set, 
+       { &hf_fcp_mgmt_flags_clear_task_set,
          { "Clear Task Set", "fcp.mgmt.flags.clear_task_set", FT_BOOLEAN, 8, TFS(&fcp_mgmt_flags_clear_task_set_tfs), 0x04, "", HFILL }},
-       { &hf_fcp_mgmt_flags_abort_task_set, 
+       { &hf_fcp_mgmt_flags_abort_task_set,
          { "Abort Task Set", "fcp.mgmt.flags.abort_task_set", FT_BOOLEAN, 8, TFS(&fcp_mgmt_flags_abort_task_set_tfs), 0x02, "", HFILL }},
-       { &hf_fcp_rsp_flags_bidi, 
+       { &hf_fcp_rsp_flags_bidi,
          { "Bidi Rsp", "fcp.rsp.flags.bidi", FT_BOOLEAN, 8, TFS(&fcp_rsp_flags_bidi_tfs), 0x80, "", HFILL }},
-       { &hf_fcp_rsp_flags_bidi_rru, 
+       { &hf_fcp_rsp_flags_bidi_rru,
          { "Bidi Read Resid Under", "fcp.rsp.flags.bidi_rru", FT_BOOLEAN, 8, TFS(&fcp_rsp_flags_bidi_rru_tfs), 0x40, "", HFILL }},
-       { &hf_fcp_rsp_flags_bidi_rro, 
+       { &hf_fcp_rsp_flags_bidi_rro,
          { "Bidi Read Resid Over", "fcp.rsp.flags.bidi_rro", FT_BOOLEAN, 8, TFS(&fcp_rsp_flags_bidi_rro_tfs), 0x20, "", HFILL }},
-       { &hf_fcp_rsp_flags_conf_req, 
+       { &hf_fcp_rsp_flags_conf_req,
          { "Conf Req", "fcp.rsp.flags.conf_req", FT_BOOLEAN, 8, TFS(&fcp_rsp_flags_conf_req_tfs), 0x10, "", HFILL }},
-       { &hf_fcp_rsp_flags_resid_under, 
+       { &hf_fcp_rsp_flags_resid_under,
          { "Resid Under", "fcp.rsp.flags.resid_under", FT_BOOLEAN, 8, TFS(&fcp_rsp_flags_resid_under_tfs), 0x08, "", HFILL }},
-       { &hf_fcp_rsp_flags_resid_over, 
+       { &hf_fcp_rsp_flags_resid_over,
          { "Resid Over", "fcp.rsp.flags.resid_over", FT_BOOLEAN, 8, TFS(&fcp_rsp_flags_resid_over_tfs), 0x04, "", HFILL }},
-       { &hf_fcp_rsp_flags_sns_vld, 
+       { &hf_fcp_rsp_flags_sns_vld,
          { "SNS Vld", "fcp.rsp.flags.sns_vld", FT_BOOLEAN, 8, TFS(&fcp_rsp_flags_sns_vld_tfs), 0x02, "", HFILL }},
-       { &hf_fcp_rsp_flags_res_vld, 
+       { &hf_fcp_rsp_flags_res_vld,
          { "RES Vld", "fcp.rsp.flags.res_vld", FT_BOOLEAN, 8, TFS(&fcp_rsp_flags_res_vld_tfs), 0x01, "", HFILL }},
         { &hf_fcp_request_in,
           { "Request In", "fcp.request_in", FT_FRAMENUM, BASE_NONE, NULL,