private Smb2Packet DecodeSingleResponsePacket( byte[] messageBytes, bool ignoreCompoundFlag, ulong realSessionId, uint realTreeId, out int consumedLength, out int expectedLength ) { Packet_Header smb2Header; bool isLeaseBreakPacket = false; int offset = 0; smb2Header = TypeMarshal.ToStruct<Packet_Header>(messageBytes, ref offset); if (smb2Header.Command == Smb2Command.OPLOCK_BREAK) { ushort structureSize = TypeMarshal.ToStruct<ushort>(messageBytes, ref offset); if (structureSize == (ushort)OplockLeaseBreakStructureSize.LeaseBreakNotification || structureSize == (ushort)OplockLeaseBreakStructureSize.LeaseBreakResponse || structureSize == 9) // Add this condition temporally to handle LeaseBreakResponse is error response (i.e. structureSize == 9), but this will still hide the condition when OplockBreakResponse is error response { isLeaseBreakPacket = true; } } Smb2SinglePacket packet = null; ushort structSize = BitConverter.ToUInt16(messageBytes, Smb2Consts.Smb2HeaderLen); switch (smb2Header.Command) { case Smb2Command.CANCEL: packet = new Smb2CancelResponsePacket(); break; case Smb2Command.CHANGE_NOTIFY: packet = new Smb2ChangeNotifyResponsePacket(); break; case Smb2Command.CLOSE: packet = new Smb2CloseResponsePacket(); break; case Smb2Command.CREATE: packet = new Smb2CreateResponsePacket(); break; case Smb2Command.ECHO: packet = new Smb2EchoResponsePacket(); break; case Smb2Command.FLUSH: packet = new Smb2FlushResponsePacket(); break; case Smb2Command.IOCTL: packet = new Smb2IOCtlResponsePacket(); break; case Smb2Command.LOCK: packet = new Smb2LockResponsePacket(); break; case Smb2Command.LOGOFF: packet = new Smb2LogOffResponsePacket(); break; case Smb2Command.NEGOTIATE: packet = new Smb2NegotiateResponsePacket(); break; case Smb2Command.OPLOCK_BREAK: if (smb2Header.MessageId == ulong.MaxValue) { if (!isLeaseBreakPacket) { packet = new Smb2OpLockBreakNotificationPacket(); } else { packet = new Smb2LeaseBreakNotificationPacket(); } } else { if (!isLeaseBreakPacket) { packet = new Smb2OpLockBreakResponsePacket(); } else { packet = new Smb2LeaseBreakResponsePacket(); } } break; case Smb2Command.QUERY_DIRECTORY: packet = new Smb2QueryDirectoryResponePacket(); break; case Smb2Command.QUERY_INFO: packet = new Smb2QueryInfoResponsePacket(); break; case Smb2Command.READ: packet = new Smb2ReadResponsePacket(); break; case Smb2Command.SESSION_SETUP: packet = new Smb2SessionSetupResponsePacket(); break; case Smb2Command.SET_INFO: packet = new Smb2SetInfoResponsePacket(); break; case Smb2Command.TREE_CONNECT: packet = new Smb2TreeConnectResponsePacket(); break; case Smb2Command.TREE_DISCONNECT: packet = new Smb2TreeDisconnectResponsePacket(); break; case Smb2Command.WRITE: packet = new Smb2WriteResponsePacket(); break; default: throw new InvalidOperationException("Received an unknown packet! the type of the packet is " + smb2Header.Command.ToString()); } if (IsErrorPacket(smb2Header)) { var error = new Smb2ErrorResponsePacket(); error.FromBytes(messageBytes, out consumedLength, out expectedLength); packet.Header = error.Header; packet.Error = error; } else { packet.FromBytes(messageBytes, out consumedLength, out expectedLength); } //if ignoreCompoundFlag is false, means the process of decoding this packet //is not part of the process of decoding a compound packet. We will update //context here. if (!ignoreCompoundFlag) { // TODO } return packet; }
public Smb2LeaseBreakNotificationPacket CreateLeaseBreakNotificationResponse( Smb2Endpoint endpoint, LEASE_BREAK_Notification_Packet_Flags_Values flags, byte[] leaseKey, LeaseStateValues currentLeaseState, LeaseStateValues newLeaseState ) { Smb2LeaseBreakNotificationPacket packet = new Smb2LeaseBreakNotificationPacket(); packet.Header.Flags = Packet_Header_Flags_Values.FLAGS_SERVER_TO_REDIR; packet.Header.Command = Smb2Command.OPLOCK_BREAK; packet.Header.MessageId = ulong.MaxValue; packet.Header.ProtocolId = Smb2Consts.Smb2ProtocolId; packet.Header.Signature = new byte[Smb2Consts.SignatureSize]; packet.Header.StructureSize = Packet_Header_StructureSize_Values.V1; packet.Endpoint = endpoint; packet.PayLoad.AccessMaskHint = LEASE_BREAK_Notification_Packet_AccessMaskHint_Values.V1; packet.PayLoad.BreakReason = LEASE_BREAK_Notification_Packet_BreakReason_Values.V1; packet.PayLoad.CurrentLeaseState = currentLeaseState; packet.PayLoad.Flags = LEASE_BREAK_Notification_Packet_Flags_Values.SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED; packet.PayLoad.LeaseKey = leaseKey; packet.PayLoad.NewLeaseState = newLeaseState; packet.PayLoad.Reserved = LEASE_BREAK_Notification_Packet_Reserved_Values.V1; packet.PayLoad.ShareMaskHint = LEASE_BREAK_Notification_Packet_ShareMaskHint_Values.V1; packet.PayLoad.StructureSize = LEASE_BREAK_Notification_Packet_StructureSize_Values.V1; packet.Sign(); return packet; }