Example #1
0
        internal static TextRequestPDU GetSendTargetsRequest(ConnectionParameters connection)
        {
            ISCSISession   session = connection.Session;
            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);
        }
Example #2
0
        internal static LogoutRequestPDU GetLogoutRequest(ConnectionParameters connection)
        {
            ISCSISession     session = connection.Session;
            LogoutRequestPDU request = new LogoutRequestPDU();

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

            return(request);
        }
Example #3
0
        internal static NOPOutPDU GetPingResponse(NOPInPDU request, ConnectionParameters connection)
        {
            ISCSISession session  = connection.Session;
            NOPOutPDU    response = new NOPOutPDU();

            // If the Initiator Task Tag contains 0xffffffff, the I bit MUST be set to 1 and the CmdSN is not advanced after this PDU is sent.
            response.ImmediateDelivery = true;
            // RFC 3720: The NOP-Out MUST have the Initiator Task Tag set to a valid value only if a response in the form of NOP-In is requested.
            // Otherwise, the Initiator Task Tag MUST be set to 0xffffffff
            response.InitiatorTaskTag  = 0xFFFFFFFF;
            response.CmdSN             = session.GetNextCmdSN(false);
            response.TargetTransferTag = request.TargetTransferTag;
            // p.s. the Data Segment (of the request sent by the target) MUST NOT contain any data
            return(response);
        }
Example #4
0
        internal static NOPOutPDU GetPingRequest(ConnectionParameters connection)
        {
            ISCSISession session = connection.Session;
            // 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);
        }
Example #5
0
        internal static LoginRequestPDU GetSingleStageLoginRequest(string initiatorName, string targetName, ConnectionParameters connection)
        {
            ISCSISession    session = connection.Session;
            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;
            KeyValuePairList <string, string> loginParameters = new KeyValuePairList <string, string>();

            loginParameters.Add("InitiatorName", initiatorName);
            if (targetName == null)
            {
                loginParameters.Add("SessionType", "Discovery");
            }
            else
            {
                loginParameters.Add("SessionType", "Normal");
                loginParameters.Add("TargetName", targetName);
            }
            loginParameters.Add("DataDigest", "None");
            loginParameters.Add("MaxRecvDataSegmentLength", connection.InitiatorMaxRecvDataSegmentLength.ToString());
            if (targetName != null)
            {
                loginParameters.Add("MaxConnections", ISCSIClient.DesiredParameters.MaxConnections.ToString());
                loginParameters.Add("InitialR2T", ISCSIClient.DesiredParameters.InitialR2T ? "Yes" : "No");
                loginParameters.Add("ImmediateData", ISCSIClient.DesiredParameters.ImmediateData ? "Yes" : "No");
                loginParameters.Add("MaxBurstLength", ISCSIClient.DesiredParameters.MaxBurstLength.ToString());
                loginParameters.Add("FirstBurstLength", ISCSIClient.DesiredParameters.FirstBurstLength.ToString());
                loginParameters.Add("MaxOutstandingR2T", ISCSIClient.DesiredParameters.MaxOutstandingR2T.ToString());
                loginParameters.Add("DataPDUInOrder", ISCSIClient.DesiredParameters.DataPDUInOrder ? "Yes" : "No");
                loginParameters.Add("DataSequenceInOrder", ISCSIClient.DesiredParameters.DataSequenceInOrder ? "Yes" : "No");
                loginParameters.Add("ErrorRecoveryLevel", ISCSIClient.DesiredParameters.ErrorRecoveryLevel.ToString());
            }
            loginParameters.Add("DefaultTime2Wait", ISCSIClient.DesiredParameters.DefaultTime2Wait.ToString());
            loginParameters.Add("DefaultTime2Retain", ISCSIClient.DesiredParameters.DefaultTime2Retain.ToString());
            request.LoginParameters = loginParameters;
            return(request);
        }
Example #6
0
        internal static SCSICommandPDU GetReportLUNsCommand(ConnectionParameters connection, uint allocationLength)
        {
            ISCSISession session = connection.Session;
            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);
        }
Example #7
0
        internal static SCSICommandPDU GetReadCapacity10Command(ConnectionParameters connection, ushort LUN)
        {
            ISCSISession session = connection.Session;
            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);
        }
Example #8
0
        internal static SCSICommandPDU GetRead16Command(ConnectionParameters connection, ushort LUN, ulong sectorIndex, uint sectorCount, int bytesPerSector)
        {
            ISCSISession session = connection.Session;
            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);
        }
Example #9
0
        internal static LoginRequestPDU GetSecondStageLoginRequest(LoginResponsePDU firstStageResponse, ConnectionParameters connection, bool isDiscovery)
        {
            ISCSISession    session = connection.Session;
            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;
            KeyValuePairList <string, string> loginParameters = new KeyValuePairList <string, string>();

            loginParameters.Add("HeaderDigest", "None");
            loginParameters.Add("DataDigest", "None");
            loginParameters.Add("MaxRecvDataSegmentLength", connection.InitiatorMaxRecvDataSegmentLength.ToString());
            if (!isDiscovery)
            {
                loginParameters.Add("MaxConnections", ISCSIClient.DesiredParameters.MaxConnections.ToString());
                loginParameters.Add("InitialR2T", ISCSIClient.DesiredParameters.InitialR2T ? "Yes" : "No");
                loginParameters.Add("ImmediateData", ISCSIClient.DesiredParameters.ImmediateData ? "Yes" : "No");
                loginParameters.Add("MaxBurstLength", ISCSIClient.DesiredParameters.MaxBurstLength.ToString());
                loginParameters.Add("FirstBurstLength", ISCSIClient.DesiredParameters.FirstBurstLength.ToString());
                loginParameters.Add("MaxOutstandingR2T", ISCSIClient.DesiredParameters.MaxOutstandingR2T.ToString());
                loginParameters.Add("DataPDUInOrder", ISCSIClient.DesiredParameters.DataPDUInOrder ? "Yes" : "No");
                loginParameters.Add("DataSequenceInOrder", ISCSIClient.DesiredParameters.DataSequenceInOrder ? "Yes" : "No");
                loginParameters.Add("ErrorRecoveryLevel", ISCSIClient.DesiredParameters.ErrorRecoveryLevel.ToString());
            }
            loginParameters.Add("DefaultTime2Wait", ISCSIClient.DesiredParameters.DefaultTime2Wait.ToString());
            loginParameters.Add("DefaultTime2Retain", ISCSIClient.DesiredParameters.DefaultTime2Retain.ToString());
            request.LoginParameters = loginParameters;
            return(request);
        }
Example #10
0
        /// <param name="targetName">Set to null for discovery session</param>
        internal static LoginRequestPDU GetFirstStageLoginRequest(string initiatorName, string targetName, ConnectionParameters connection)
        {
            ISCSISession    session = connection.Session;
            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;
            KeyValuePairList <string, string> loginParameters = new KeyValuePairList <string, string>();

            loginParameters.Add("InitiatorName", initiatorName);
            loginParameters.Add("AuthMethod", "None");
            if (targetName == null)
            {
                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.
                loginParameters.Add("SessionType", "Normal");
                loginParameters.Add("TargetName", targetName);
            }
            request.LoginParameters = loginParameters;
            return(request);
        }
Example #11
0
        internal static SCSICommandPDU GetWrite16Command(ConnectionParameters connection, ushort LUN, ulong sectorIndex, byte[] data, int bytesPerSector)
        {
            ISCSISession session = connection.Session;
            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);
        }
Example #12
0
        internal static void UpdateOperationalParameters(KeyValuePairList <string, string> loginParameters, ConnectionParameters connection)
        {
            ISCSISession session = connection.Session;
            string       value   = loginParameters.ValueOf("MaxRecvDataSegmentLength");

            if (value != null)
            {
                connection.TargetMaxRecvDataSegmentLength = Convert.ToInt32(value);
            }

            value = loginParameters.ValueOf("MaxConnections");
            if (value != null)
            {
                session.MaxConnections = Convert.ToInt32(value);
            }
            else
            {
                session.MaxConnections = ISCSIClient.DesiredParameters.MaxConnections;
            }

            value = loginParameters.ValueOf("InitialR2T");
            if (value != null)
            {
                session.InitialR2T = (value == "Yes") ? true : false;
            }
            else
            {
                session.InitialR2T = ISCSIClient.DesiredParameters.InitialR2T;
            }

            value = loginParameters.ValueOf("ImmediateData");
            if (value != null)
            {
                session.ImmediateData = (value == "Yes") ? true : false;
            }
            else
            {
                session.ImmediateData = ISCSIClient.DesiredParameters.ImmediateData;
            }

            value = loginParameters.ValueOf("MaxBurstLength");
            if (value != null)
            {
                session.MaxBurstLength = Convert.ToInt32(value);
            }
            else
            {
                session.MaxBurstLength = ISCSIClient.DesiredParameters.MaxBurstLength;
            }

            value = loginParameters.ValueOf("FirstBurstLength");
            if (value != null)
            {
                session.FirstBurstLength = Convert.ToInt32(value);
            }
            else
            {
                session.FirstBurstLength = ISCSIClient.DesiredParameters.FirstBurstLength;
            }

            value = loginParameters.ValueOf("DefaultTime2Wait");
            if (value != null)
            {
                session.DefaultTime2Wait = Convert.ToInt32(value);
            }
            else
            {
                session.DefaultTime2Wait = ISCSIClient.DesiredParameters.DefaultTime2Wait;
            }

            value = loginParameters.ValueOf("DefaultTime2Retain");
            if (value != null)
            {
                session.DefaultTime2Retain = Convert.ToInt32(value);
            }
            else
            {
                session.DefaultTime2Retain = ISCSIClient.DesiredParameters.DefaultTime2Retain;
            }

            value = loginParameters.ValueOf("MaxOutstandingR2T");
            if (value != null)
            {
                session.MaxOutstandingR2T = Convert.ToInt32(value);
            }
            else
            {
                session.MaxOutstandingR2T = ISCSIClient.DesiredParameters.MaxOutstandingR2T;
            }

            value = loginParameters.ValueOf("DataPDUInOrder");
            if (value != null)
            {
                session.DataPDUInOrder = (value == "Yes") ? true : false;
            }
            else
            {
                session.DataPDUInOrder = ISCSIClient.DesiredParameters.DataPDUInOrder;
            }

            value = loginParameters.ValueOf("DataSequenceInOrder");
            if (value != null)
            {
                session.DataSequenceInOrder = (value == "Yes") ? true : false;
            }
            else
            {
                session.DataSequenceInOrder = ISCSIClient.DesiredParameters.DataSequenceInOrder;
            }

            value = loginParameters.ValueOf("ErrorRecoveryLevel");
            if (value != null)
            {
                session.ErrorRecoveryLevel = Convert.ToInt32(value);
            }
            else
            {
                session.ErrorRecoveryLevel = ISCSIClient.DesiredParameters.ErrorRecoveryLevel;
            }
        }