예제 #1
0
        /// <param name="targetName">Set to null for discovery session</param>
        internal static LoginRequestPDU GetFirstStageLoginRequest(string initiatorName, string targetName, SessionParameters session, ConnectionParameters connection)
        {
            LoginRequestPDU request = new LoginRequestPDU();

            request.InitiatorTaskTag = session.GetNextTaskTag();
            request.ISID             = session.ISID;
            request.TSIH             = 0; // used on the first connection for a new session
            request.CID       = connection.CID;
            request.CmdSN     = session.GetNextCmdSN(false);
            request.ExpStatSN = 0;
            // The stage codes are:
            // 0 - SecurityNegotiation
            // 1 - LoginOperationalNegotiation
            // 3 - FullFeaturePhase
            request.CurrentStage = 0;
            request.NextStage    = 1;
            request.Transit      = true;
            request.VersionMax   = 0;
            request.VersionMin   = 0;
            request.LoginParameters.Add("InitiatorName", initiatorName);
            request.LoginParameters.Add("AuthMethod", "None");
            if (targetName == null)
            {
                request.LoginParameters.Add("SessionType", "Discovery");
            }
            else
            {
                // RFC 3720: For any connection within a session whose type is not "Discovery", the first Login Request MUST also include the TargetName key=value pair.
                request.LoginParameters.Add("SessionType", "Normal");
                request.LoginParameters.Add("TargetName", targetName);
            }
            return(request);
        }
예제 #2
0
        internal static LoginRequestPDU GetSecondStageLoginRequest(LoginResponsePDU firstStageResponse, SessionParameters session, ConnectionParameters connection, bool isDiscovery)
        {
            LoginRequestPDU request = new LoginRequestPDU();

            request.ISID             = firstStageResponse.ISID;
            request.TSIH             = firstStageResponse.TSIH;
            request.CID              = connection.CID;
            request.InitiatorTaskTag = session.GetNextTaskTag();
            request.CmdSN            = session.GetNextCmdSN(false);
            request.CurrentStage     = firstStageResponse.NextStage;
            request.NextStage        = 3;
            request.Transit          = true;
            request.VersionMax       = 0;
            request.VersionMin       = 0;
            request.LoginParameters.Add("HeaderDigest", "None");
            request.LoginParameters.Add("DataDigest", "None");
            request.LoginParameters.Add("MaxRecvDataSegmentLength", connection.InitiatorMaxRecvDataSegmentLength.ToString());
            if (!isDiscovery)
            {
                request.LoginParameters.Add("ErrorRecoveryLevel", ISCSIClient.OfferedErrorRecoveryLevel.ToString());
                request.LoginParameters.Add("InitialR2T", ISCSIClient.OfferedInitialR2T ? "Yes" : "No");
                request.LoginParameters.Add("ImmediateData", ISCSIClient.OfferedImmediateData ? "Yes" : "No");
                request.LoginParameters.Add("MaxBurstLength", ISCSIClient.OfferedMaxBurstLength.ToString());
                request.LoginParameters.Add("FirstBurstLength", ISCSIClient.OfferedFirstBurstLength.ToString());
                request.LoginParameters.Add("MaxConnections", ISCSIClient.OfferedMaxConnections.ToString());
                request.LoginParameters.Add("DataPDUInOrder", ISCSIClient.OfferedDataPDUInOrder ? "Yes" : "No");
                request.LoginParameters.Add("DataSequenceInOrder", ISCSIClient.OfferedDataSequenceInOrder ? "Yes" : "No");
                request.LoginParameters.Add("MaxOutstandingR2T", ISCSIClient.OfferedMaxOutstandingR2T.ToString());
            }
            request.LoginParameters.Add("DefaultTime2Wait", ISCSIClient.OfferedDefaultTime2Wait.ToString());
            request.LoginParameters.Add("DefaultTime2Retain", ISCSIClient.OfferedDefaultTime2Retain.ToString());

            return(request);
        }
예제 #3
0
        internal static TextRequestPDU GetSendTargetsRequest(SessionParameters session, ConnectionParameters connection)
        {
            TextRequestPDU request = new TextRequestPDU();

            request.Text              = "SendTargets=All";
            request.InitiatorTaskTag  = session.GetNextTaskTag();
            request.CmdSN             = session.GetNextCmdSN(true);
            request.Final             = true;
            request.TargetTransferTag = 0xFFFFFFFF;
            return(request);
        }
예제 #4
0
        internal static LogoutRequestPDU GetLogoutRequest(SessionParameters session, ConnectionParameters connection)
        {
            LogoutRequestPDU request = new LogoutRequestPDU();

            request.ReasonCode       = LogoutReasonCode.CloseTheSession;
            request.InitiatorTaskTag = session.GetNextTaskTag();
            request.CID   = connection.CID;
            request.CmdSN = session.GetNextCmdSN(true);

            return(request);
        }
예제 #5
0
        internal static NOPOutPDU GetPingRequest(SessionParameters session, ConnectionParameters connection)
        {
            // Microsoft iSCSI Target v3.1 expects that CmdSN won't be incremented after this request regardless of whether the ImmediateDelivery bit is set or not,
            // So we set the ImmediateDelivery bit to work around the issue.
            NOPOutPDU request = new NOPOutPDU();

            request.ImmediateDelivery = true;
            request.InitiatorTaskTag  = session.GetNextTaskTag();
            request.CmdSN             = session.GetNextCmdSN(false);
            // RFC 3720: The NOP-Out MUST only have the Target Transfer Tag set if it is issued in response to a NOP-In (with a valid Target Transfer Tag).
            // Otherwise, the Target Transfer Tag MUST be set to 0xffffffff.
            request.TargetTransferTag = 0xFFFFFFFF;
            return(request);
        }
예제 #6
0
        internal static SCSICommandPDU GetReportLUNsCommand(SessionParameters session, ConnectionParameters connection, uint allocationLength)
        {
            SCSICommandDescriptorBlock reportLUNs = SCSICommandDescriptorBlock.Create(SCSIOpCodeName.ReportLUNs);

            reportLUNs.TransferLength = allocationLength;

            SCSICommandPDU scsiCommand = new SCSICommandPDU();

            scsiCommand.CommandDescriptorBlock = reportLUNs.GetBytes();
            scsiCommand.InitiatorTaskTag       = session.GetNextTaskTag();
            scsiCommand.Final = true;
            scsiCommand.Read  = true;
            scsiCommand.CmdSN = session.GetNextCmdSN(true);
            scsiCommand.ExpectedDataTransferLength = allocationLength;
            return(scsiCommand);
        }
예제 #7
0
        internal static SCSICommandPDU GetReadCapacity10Command(SessionParameters session, ConnectionParameters connection, ushort LUN)
        {
            SCSICommandDescriptorBlock readCapacity10 = SCSICommandDescriptorBlock.Create(SCSIOpCodeName.ReadCapacity10);

            readCapacity10.TransferLength = ReadCapacity10Parameter.Length;

            SCSICommandPDU scsiCommand = new SCSICommandPDU();

            scsiCommand.CommandDescriptorBlock = readCapacity10.GetBytes();
            scsiCommand.InitiatorTaskTag       = session.GetNextTaskTag();
            scsiCommand.Final = true;
            scsiCommand.Read  = true;
            scsiCommand.LUN   = LUN;
            scsiCommand.CmdSN = session.GetNextCmdSN(true);
            scsiCommand.ExpectedDataTransferLength = ReadCapacity10Parameter.Length;
            return(scsiCommand);
        }
예제 #8
0
        internal static SCSICommandPDU GetRead16Command(SessionParameters session, ConnectionParameters connection, ushort LUN, ulong sectorIndex, uint sectorCount, int bytesPerSector)
        {
            SCSICommandDescriptorBlock read16 = SCSICommandDescriptorBlock.Create(SCSIOpCodeName.Read16);

            read16.LogicalBlockAddress64 = sectorIndex;
            read16.TransferLength        = sectorCount;

            SCSICommandPDU scsiCommand = new SCSICommandPDU();

            scsiCommand.CommandDescriptorBlock = read16.GetBytes();
            scsiCommand.LUN = LUN;
            scsiCommand.InitiatorTaskTag           = session.GetNextTaskTag();
            scsiCommand.Final                      = true;
            scsiCommand.Read                       = true;
            scsiCommand.CmdSN                      = session.GetNextCmdSN(true);
            scsiCommand.ExpectedDataTransferLength = (uint)(sectorCount * bytesPerSector);
            return(scsiCommand);
        }
예제 #9
0
        internal static LoginRequestPDU GetSingleStageLoginRequest(string initiatorName, string targetName, SessionParameters session, ConnectionParameters connection)
        {
            LoginRequestPDU request = new LoginRequestPDU();

            request.ISID             = session.ISID;
            request.TSIH             = session.TSIH;
            request.CID              = connection.CID;
            request.InitiatorTaskTag = session.GetNextTaskTag();
            request.CmdSN            = session.GetNextCmdSN(false);
            request.CurrentStage     = 1;
            request.NextStage        = 3;
            request.Transit          = true;
            request.VersionMax       = 0;
            request.VersionMin       = 0;
            request.LoginParameters.Add("InitiatorName", initiatorName);
            if (targetName == null)
            {
                request.LoginParameters.Add("SessionType", "Discovery");
            }
            else
            {
                request.LoginParameters.Add("SessionType", "Normal");
                request.LoginParameters.Add("TargetName", targetName);
            }
            request.LoginParameters.Add("DataDigest", "None");
            request.LoginParameters.Add("MaxRecvDataSegmentLength", connection.InitiatorMaxRecvDataSegmentLength.ToString());
            if (targetName != null)
            {
                request.LoginParameters.Add("ErrorRecoveryLevel", ISCSIClient.OfferedErrorRecoveryLevel.ToString());
                request.LoginParameters.Add("InitialR2T", ISCSIClient.OfferedInitialR2T ? "Yes" : "No");
                request.LoginParameters.Add("ImmediateData", ISCSIClient.OfferedImmediateData ? "Yes" : "No");
                request.LoginParameters.Add("MaxBurstLength", ISCSIClient.OfferedMaxBurstLength.ToString());
                request.LoginParameters.Add("FirstBurstLength", ISCSIClient.OfferedFirstBurstLength.ToString());
                request.LoginParameters.Add("MaxConnections", ISCSIClient.OfferedMaxConnections.ToString());
                request.LoginParameters.Add("DataPDUInOrder", ISCSIClient.OfferedDataPDUInOrder ? "Yes" : "No");
                request.LoginParameters.Add("DataSequenceInOrder", ISCSIClient.OfferedDataSequenceInOrder ? "Yes" : "No");
                request.LoginParameters.Add("MaxOutstandingR2T", ISCSIClient.OfferedMaxOutstandingR2T.ToString());
            }
            request.LoginParameters.Add("DefaultTime2Wait", ISCSIClient.OfferedDefaultTime2Wait.ToString());
            request.LoginParameters.Add("DefaultTime2Retain", ISCSIClient.OfferedDefaultTime2Retain.ToString());

            return(request);
        }
예제 #10
0
        internal static SCSICommandPDU GetWrite16Command(SessionParameters session, ConnectionParameters connection, ushort LUN, ulong sectorIndex, byte[] data, int bytesPerSector)
        {
            SCSICommandDescriptorBlock write16 = SCSICommandDescriptorBlock.Create(SCSIOpCodeName.Write16);

            write16.LogicalBlockAddress64 = sectorIndex;
            write16.TransferLength        = (uint)(data.Length / bytesPerSector);

            SCSICommandPDU scsiCommand = new SCSICommandPDU();

            scsiCommand.CommandDescriptorBlock = write16.GetBytes();
            if (session.ImmediateData)
            {
                int immediateDataLength = Math.Min(data.Length, session.FirstBurstLength);
                scsiCommand.Data = ByteReader.ReadBytes(data, 0, immediateDataLength);
            }
            scsiCommand.LUN = LUN;
            scsiCommand.InitiatorTaskTag           = session.GetNextTaskTag();
            scsiCommand.Final                      = true;
            scsiCommand.Write                      = true;
            scsiCommand.CmdSN                      = session.GetNextCmdSN(true);
            scsiCommand.ExpectedDataTransferLength = (uint)(data.Length);
            return(scsiCommand);
        }