/// <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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }