/// <summary> /// Parse a payload byte buffer into a payload data structure. /// </summary> /// <param name="inBuffer">Incoming byte buffer to parse</param> /// <param name="payload">Reference to the payload data structure in which to put the parsed data</param> /// <returns>Daedalus return code</returns> public DaedalusGlobal.ReturnCodes parsePayload(byte[] inBuffer, int startIndex, out Dictionary <string, DaedalusGlobal.PayloadElement> payload) { payload = new Dictionary <string, DaedalusGlobal.PayloadElement>(); //if (payload == null) //{ // throw new ArgumentNullException("payload", "Payload object passed to " + this.GetType().ToString() + ".parsePayload() as null, should be a instantiated Dictionary."); //} DaedalusGlobal.ReturnCodes returnCode = DaedalusGlobal.ReturnCodes.Valid; payload.Add("hash", new DaedalusGlobal.PayloadElement() { elementName = "hash", elementOffset = 0, elementSize = 20, //elementData = new UserHash(inBuffer, DecryptedDaedalusPacket.elementCommandPayload.ElementStaticOffset) elementData = new UserHash(inBuffer, startIndex) }); payload.Add("actionTaken", new DaedalusGlobal.PayloadElement() { elementName = "actionTaken", elementOffset = (ushort)(payload["hash"].elementSize + payload["hash"].elementOffset), elementSize = 1, //elementData = (ReadHashActions)inBuffer[DecryptedDaedalusPacket.elementCommandPayload.ElementStaticOffset + payload["hash"].elementSize] elementData = (ReadHashActions)inBuffer[startIndex + payload["hash"].elementSize] }); return(returnCode); }
public DaedalusGlobal.ReturnCodes payloadToByteBuffer(Dictionary <string, DaedalusGlobal.PayloadElement> payload, out byte[] outputBuffer) { if (payload == null) { throw new ArgumentNullException("payload", "Payload object passed to " + this.GetType().ToString() + ".payloadToByteBuffer() as null, should be a instantiated Dictionary."); } DaedalusGlobal.ReturnCodes returnCode = DaedalusGlobal.ReturnCodes.Valid; // Make sure the payload has the fields required by this command in it if (payload.ContainsKey("hash") && payload.ContainsKey("actionTaken")) { int payloadLength = payload.Sum(x => x.Value.elementSize); outputBuffer = new byte[payloadLength]; byte[] hash = ((UserHash)(payload["hash"].elementData)).getByteBuffer(); Array.Copy(hash, outputBuffer, UserHash.hashSize); outputBuffer[payload["actionTaken"].elementOffset] = (byte)payload["actionTaken"].elementData; } else { outputBuffer = null; return(DaedalusGlobal.ReturnCodes.PayloadFieldMissing); } return(returnCode); }
private void cmdSendCommand_Click(object sender, EventArgs e) { // Decrypted packet that we're going to send out DecryptedDaedalusPacket outPacket = new DecryptedDaedalusPacket(); // Should probably invert this and only allow the fields to be set via a constructor (readonly) outPacket.commandType = getDaedalusCommandTypeFromComboBox(cboProtocolCommand); unchecked { outPacket.packetIndex = packetIndex++; } outPacket.command = outPacket.commandType.getCommand(); outPacket.commandVersion = Byte.Parse((string)Invoke((Func <object>)(() => txtCommandVersion.Text))); string payloadString = (string)Invoke((Func <object>)(() => txtPacketPayload.Text)); byte[] payloadBuffer = GlobalHelpers.GlobalMethods.XXHexStringToByteArray(payloadString.Replace(" ", "")); Dictionary <string, DaedalusGlobal.PayloadElement> payload; DaedalusGlobal.ReturnCodes rc = outPacket.commandType.parsePayload(payloadBuffer, 0, out payload); outPacket.payload = payload; if (rc == DaedalusGlobal.ReturnCodes.Valid) { outPacket.setPacketLengthFieldValue(); // At this point the decrypted packet should be ready to go // Build encrypted packet here EncryptedDaedalusPacket encPacket = new EncryptedDaedalusPacket(outPacket, AESKey); string IPString = (string)Invoke((Func <object>)(() => txtDestinationIP.Text)); IPEndPoint destinationEndPoint = new IPEndPoint(IPAddress.Parse(IPString), DaedalusGlobal.DaedalusPort); //lock (commLocker) //{ lock (selectedNetworkInterfaceLocker) { comm.outPackets.Add(new NetPacket { destination = destinationEndPoint, source = new IPEndPoint(getDefaultIPv4AddressFromInterface(selectedNetworkInterface), DaedalusGlobal.DaedalusPort), transportType = TransportType.Tcp, payload = encPacket.toByteBuffer() }); } //} } else { throw new ArgumentException("Packet payload incorrectly formatted for this command type."); } }
internal DecryptedDaedalusPacket toDecryptedDaedalusPacket(out DaedalusGlobal.ReturnCodes returnCode) { DaedalusGlobal.ReturnCodes rc; int start; int len; // Build a clear text packet from the decrypted data if (DecryptedDaedalusPacket.IsValidPacket(decryptedPayload, out rc, out start, out len)) { returnCode = DaedalusGlobal.ReturnCodes.Valid; return(new DecryptedDaedalusPacket(decryptedPayload, start, len, out rc)); } else { returnCode = rc; return(null); } }
internal static bool IsValidPacket(byte[] inBuffer, out DaedalusGlobal.ReturnCodes returnCode, out int validatedPacketStart, out int validatedPacketLength) { // Try to find the SOH that starts the packet int startIndex = inBuffer.FirstIndexOfSequence(new byte[] { GlobalConstants.SOH }, 0); // If we couldn't find an SOH, there's no packet if (startIndex == -1) { #if DEBUG GlobalMethods.TestLog("Packet " + BitConverter.ToString(inBuffer) + " could not find SOH."); #endif returnCode = DaedalusGlobal.ReturnCodes.InvalidPacketStructure; validatedPacketStart = int.MaxValue; validatedPacketLength = int.MaxValue; return(false); } // Decode packetLength from the next two bytes // Note packetLength is number of bytes between end of packetLength and CRC // Yes, I did that on purpose ushort inPacketLength = BitConverter.ToUInt16(inBuffer, startIndex + elementSTX.ElementSize); // Check to make sure bufferLength can fit a whole packet if (inBuffer.Length < (startIndex + inPacketLength + elementSTX.ElementSize + elementCRC.ElementSize + elementEOT.ElementSize)) { #if DEBUG GlobalMethods.TestLog("Packet " + BitConverter.ToString(inBuffer) + " failed length check. Length was " + inBuffer.Length + ", should have been at least " + (startIndex + inPacketLength + elementSTX.ElementSize + elementCRC.ElementSize + elementEOT.ElementSize + 1).ToString()); #endif returnCode = DaedalusGlobal.ReturnCodes.InvalidPacketStructure; validatedPacketStart = int.MaxValue; validatedPacketLength = int.MaxValue; return(false); } // CRC position should be packetLength from index 3, which is just after packetLength int CRCIndex = startIndex + elementSTX.ElementSize + elementPacketLength.ElementSize + inPacketLength; // Check for an ETX character right before the CRC and EOT after the CRC if (((inBuffer[CRCIndex - 1]) != GlobalConstants.ETX) || ((inBuffer[CRCIndex + 2]) != GlobalConstants.EOT)) { #if DEBUG GlobalMethods.TestLog("Packet " + BitConverter.ToString(inBuffer) + " failed ETX/EOT check. Byte at ETX position was " + inBuffer[CRCIndex - 1].ToString("X") + ", should be 0x03. Byte at EOT position was " + inBuffer[CRCIndex + 2].ToString("X") + ", should have been 0x04."); #endif returnCode = DaedalusGlobal.ReturnCodes.InvalidPacketStructure; validatedPacketStart = int.MaxValue; validatedPacketLength = int.MaxValue; return(false); } // Read in CRC of input packet ushort CRCIn = BitConverter.ToUInt16(inBuffer, CRCIndex); // Calculate CRC from content of input packet, STX to ETX, inclusive ushort CRCCalc = CRC16.calc_crc(inBuffer, startIndex, elementSTX.ElementSize + elementPacketLength.ElementSize + inPacketLength); // If the CRC check failed... if (CRCIn != CRCCalc) { #if DEBUG GlobalMethods.TestLog("Packet " + BitConverter.ToString(inBuffer) + " failed CRC verification. Calculated CRC was " + CRCCalc.ToString("X") + ", input CRC was " + CRCIn.ToString("X")); #endif returnCode = DaedalusGlobal.ReturnCodes.IncorrectCRC; validatedPacketStart = int.MaxValue; validatedPacketLength = int.MaxValue; return(false); } #if DEBUG GlobalMethods.TestLog("Packet " + BitConverter.ToString(inBuffer) + " verified."); #endif returnCode = DaedalusGlobal.ReturnCodes.Valid; validatedPacketStart = (int)startIndex; validatedPacketLength = (int)(elementSTX.ElementSize + elementPacketLength.ElementSize + inPacketLength + elementCRC.ElementSize + elementEOT.ElementSize); return(true); }