public void Test_Constructor() { var dev = new CaptureFileReaderDevice("../../CaptureFiles/80211_ack_frame.pcap"); dev.Open(); var rawCapture = dev.GetNextPacket(); dev.Close(); Packet p = Packet.ParsePacket(rawCapture.LinkLayerType, rawCapture.Data); AckFrame frame = (AckFrame)p.PayloadPacket; Assert.AreEqual(0, frame.FrameControl.ProtocolVersion); Assert.AreEqual(FrameControlField.FrameSubTypes.ControlACK, frame.FrameControl.SubType); Assert.IsFalse(frame.FrameControl.ToDS); Assert.IsFalse(frame.FrameControl.FromDS); Assert.IsFalse(frame.FrameControl.MoreFragments); Assert.IsFalse(frame.FrameControl.Retry); Assert.IsFalse(frame.FrameControl.PowerManagement); Assert.IsFalse(frame.FrameControl.MoreData); Assert.IsFalse(frame.FrameControl.Protected); Assert.IsFalse(frame.FrameControl.Order); Assert.AreEqual(0, frame.Duration.Field); //this need expanding on in the future Assert.AreEqual("F8DB7F491342", frame.ReceiverAddress.ToString().ToUpper()); Assert.AreEqual(0xD2F5BE07, frame.FrameCheckSequence); Assert.AreEqual(10, frame.FrameSize); }
public void Test_Constructor_ConstructWithValues() { AckFrame frame = new AckFrame(PhysicalAddress.Parse("111111111111")); frame.FrameControl.ToDS = false; frame.FrameControl.FromDS = true; frame.FrameControl.MoreFragments = true; frame.Duration.Field = 0x1234; frame.UpdateFrameCheckSequence(); UInt32 fcs = frame.FrameCheckSequence; //serialize the frame into a byte buffer var bytes = frame.Bytes; var bas = new ByteArraySegment(bytes); //create a new frame that should be identical to the original AckFrame recreatedFrame = MacFrame.ParsePacket(bas) as AckFrame; recreatedFrame.UpdateFrameCheckSequence(); Assert.AreEqual(FrameControlField.FrameSubTypes.ControlACK, recreatedFrame.FrameControl.SubType); Assert.IsFalse(recreatedFrame.FrameControl.ToDS); Assert.IsTrue(recreatedFrame.FrameControl.FromDS); Assert.IsTrue(recreatedFrame.FrameControl.MoreFragments); Assert.AreEqual("111111111111", recreatedFrame.ReceiverAddress.ToString().ToUpper()); Assert.AreEqual(fcs, recreatedFrame.FrameCheckSequence); }
public void Test_Constructor_ConstructWithValues () { AckFrame frame = new AckFrame (PhysicalAddress.Parse ("111111111111")); frame.FrameControl.ToDS = false; frame.FrameControl.FromDS = true; frame.FrameControl.MoreFragments = true; frame.Duration.Field = 0x1234; frame.UpdateFrameCheckSequence (); UInt32 fcs = frame.FrameCheckSequence; //serialize the frame into a byte buffer var bytes = frame.Bytes; var bas = new ByteArraySegment (bytes); //create a new frame that should be identical to the original AckFrame recreatedFrame = MacFrame.ParsePacket (bas) as AckFrame; recreatedFrame.UpdateFrameCheckSequence (); Assert.AreEqual (FrameControlField.FrameSubTypes.ControlACK, recreatedFrame.FrameControl.SubType); Assert.IsFalse (recreatedFrame.FrameControl.ToDS); Assert.IsTrue (recreatedFrame.FrameControl.FromDS); Assert.IsTrue (recreatedFrame.FrameControl.MoreFragments); Assert.AreEqual ("111111111111", recreatedFrame.ReceiverAddress.ToString ().ToUpper ()); Assert.AreEqual (fcs, recreatedFrame.FrameCheckSequence); }
public void TestAckFrameEmptyBody() { Dictionary <string, string> headers = new Dictionary <string, string>(); headers.Add(StompHeaders.ID, "id"); //test for null body AckFrame ackFrame = new AckFrame(null, headers); StringAssert.AreEqualIgnoringCase( string.Format(MESSAGE_TEMPLATE, "ACK", "id:id", "\0"), ackFrame.AsStompMessage()); //test for empty body AckFrame ackFrameEmptyBody = new AckFrame("", headers); StringAssert.AreEqualIgnoringCase(string.Format(MESSAGE_TEMPLATE, "ACK", "id:id", "\0"), ackFrameEmptyBody.AsStompMessage()); }
/// <summary> /// Process a ack frame to remove packets that were acknowledged from the history /// </summary> /// <param name="frame">The AckFrame to process</param> /// <returns>Number of packet ack</returns> public UInt32 ProcessAckFrame(AckFrame frame) { UInt32 ack = 0; UInt32 endOfRange = (UInt32)(frame.LargestAcknowledged.Value - frame.FirstAckRange.Value); HistoryMutex.WaitOne(); for (UInt32 i = (UInt32)frame.LargestAcknowledged.Value; i > endOfRange; i--) { History.Remove(i); ack++; } foreach ((VariableLengthInteger, VariableLengthInteger)tuple in frame.AckRanges) { endOfRange -= (UInt32)tuple.Item1.Value; for (UInt32 j = 0; j < (UInt32)tuple.Item2.Value; j++) { History.Remove(endOfRange); endOfRange--; ack++; } } HistoryMutex.ReleaseMutex(); return(ack); }
public void TestEncodeDecode() { AckFrame af = new AckFrame { LargestAcknowledged = new VariableLengthInteger(32767), Delay = new VariableLengthInteger(500), AckRangeCount = new VariableLengthInteger(1), FirstAckRange = new VariableLengthInteger(10), AckRanges = new List <(VariableLengthInteger, VariableLengthInteger)> { (new VariableLengthInteger(3), new VariableLengthInteger(40)) }, ECT0 = new VariableLengthInteger(1345), ECT1 = new VariableLengthInteger(1234), ECN_CE = new VariableLengthInteger(84), }; byte[] b = af.Encode(); AckFrame afDecoded = new AckFrame(); Assert.AreEqual(b.Length * 8, afDecoded.Decode(b, 0)); Assert.AreEqual((UInt64)32767, afDecoded.LargestAcknowledged.Value); Assert.AreEqual((UInt64)500, afDecoded.Delay.Value); Assert.AreEqual((UInt64)1, afDecoded.AckRangeCount.Value); Assert.AreEqual((UInt64)10, afDecoded.FirstAckRange.Value); Assert.AreEqual((UInt64)1345, afDecoded.ECT0.Value); Assert.AreEqual((UInt64)1234, afDecoded.ECT1.Value); Assert.AreEqual((UInt64)84, afDecoded.ECN_CE.Value); Assert.AreEqual(1, afDecoded.AckRanges.Count); Assert.AreEqual((UInt64)3, afDecoded.AckRanges[0].Item1.Value); Assert.AreEqual((UInt64)40, afDecoded.AckRanges[0].Item2.Value); }
public void Test_ConstructorWithCorruptBuffer() { //buffer is way too short for frame. We are just checking it doesn't throw Byte[] corruptBuffer = new Byte[] { 0x01 }; AckFrame frame = new AckFrame(new ByteArraySegment(corruptBuffer)); Assert.IsFalse(frame.FCSValid); }
/// <summary> /// Read a received packet and process its frames. /// </summary> /// <param name="packet">The received packet</param> public void ReadPacket(Packet packet) { // Process every new packet if (!_packetManager.IsPacketOld(packet)) { packet.DecodeFrames(); foreach (Frame frame in packet.Frames) { if (frame is StreamFrame) { StreamFrame sf = frame as StreamFrame; Logger.Write($"Received StreamFrame in packet number {packet.PacketNumber} with message: {System.Text.Encoding.UTF8.GetString(sf.Data)}"); QuicStream stream; try { stream = GetStream(sf.StreamID.Value); } catch (ArgumentException) { stream = CreateStream(0x00); } stream.AddFrameToRead(sf); } if (frame is AckFrame) { AckFrame af = frame as AckFrame; Logger.Write($"Received AckFrame in packet #{packet.PacketNumber}"); _packetManager.ProcessAckFrame(af); } } // Store received PacketNumber for further implementation of acknowledgement procedure _received.Add(packet.PacketNumber); } else { // The packet was sent again so we send another ack for it packet.IsAckEliciting = true; } // Generate a new Ack Frame and send it directly // Even if the packet is old, we send a new ack for this ; the ack packet may not have been received if (packet.IsAckEliciting) { AckFrame ack = new AckFrame(new List <UInt32>() { packet.PacketNumber }, 100); AddFrame(ack); SendCurrentPacket(); Logger.Write($"Acked packet #{packet.PacketNumber}"); } }
public void TestConstructor() { List <UInt32> l = new List <UInt32>() { 1, 2, 4, 6, 5, 10, 11, 12, 13 }; AckFrame af = new AckFrame(l, 500); Assert.AreEqual((UInt64)2, af.AckRangeCount.Value); Assert.AreEqual((UInt64)13, af.LargestAcknowledged.Value); Assert.AreEqual((UInt64)4, af.FirstAckRange.Value); Assert.AreEqual((UInt64)500, af.Delay.Value); Assert.AreEqual((UInt64)0, af.ECT0.Value); Assert.AreEqual((UInt64)0, af.ECT1.Value); Assert.AreEqual((UInt64)0, af.ECN_CE.Value); }
public void Test_ConstructorWithCorruptBuffer () { //buffer is way too short for frame. We are just checking it doesn't throw byte[] corruptBuffer = new byte[]{0x01}; AckFrame frame = new AckFrame(new ByteArraySegment(corruptBuffer)); Assert.IsFalse(frame.FCSValid); }
/// <summary> /// Parses the <see cref="Kavprot.Packets.Utils.ByteArraySegment"/> into a MacFrame. /// </summary> /// <returns> /// The parsed MacFrame or null if it could not be parsed. /// </returns> /// <param name='bas'> /// The bytes of the packet. bas.Offset should point to the first byte in the mac frame. /// </param> /// <remarks>If the provided bytes contain the FCS then call <see cref="MacFrame.ParsePacketWithFcs"/> instead. The presence of the /// FCS is usually determined by configuration of the device used to capture the packets.</remarks> public static MacFrame ParsePacket(ByteArraySegment bas) { if (bas.Length < MacFields.FrameControlLength) { //there isn't enough data to even try and work out what type of packet it is return(null); } //this is a bit ugly as we will end up parsing the framecontrol field twice, once here and once //inside the packet constructor. Could create the framecontrol and pass it to the packet but I think that is equally ugly FrameControlField frameControl = new FrameControlField( EndianBitConverter.Big.ToUInt16(bas.Bytes, bas.Offset)); MacFrame macFrame = null; switch (frameControl.SubType) { case FrameControlField.FrameSubTypes.ManagementAssociationRequest: { macFrame = new AssociationRequestFrame(bas); break; } case FrameControlField.FrameSubTypes.ManagementAssociationResponse: { macFrame = new AssociationResponseFrame(bas); break; } case FrameControlField.FrameSubTypes.ManagementReassociationRequest: { macFrame = new ReassociationRequestFrame(bas); break; } case FrameControlField.FrameSubTypes.ManagementReassociationResponse: { macFrame = new AssociationResponseFrame(bas); break; } case FrameControlField.FrameSubTypes.ManagementProbeRequest: { macFrame = new ProbeRequestFrame(bas); break; } case FrameControlField.FrameSubTypes.ManagementProbeResponse: { macFrame = new ProbeResponseFrame(bas); break; } case FrameControlField.FrameSubTypes.ManagementReserved0: break; //TODO case FrameControlField.FrameSubTypes.ManagementReserved1: break; //TODO case FrameControlField.FrameSubTypes.ManagementBeacon: { macFrame = new BeaconFrame(bas); break; } case FrameControlField.FrameSubTypes.ManagementATIM: break; //TODO case FrameControlField.FrameSubTypes.ManagementDisassociation: { macFrame = new DisassociationFrame(bas); break; } case FrameControlField.FrameSubTypes.ManagementAuthentication: { macFrame = new AuthenticationFrame(bas); break; } case FrameControlField.FrameSubTypes.ManagementDeauthentication: { macFrame = new DeauthenticationFrame(bas); break; } case FrameControlField.FrameSubTypes.ManagementAction: { macFrame = new ActionFrame(bas); break; } case FrameControlField.FrameSubTypes.ManagementReserved3: break; //TODO case FrameControlField.FrameSubTypes.ControlBlockAcknowledgmentRequest: { macFrame = new BlockAcknowledgmentRequestFrame(bas); break; } case FrameControlField.FrameSubTypes.ControlBlockAcknowledgment: { macFrame = new BlockAcknowledgmentFrame(bas); break; } case FrameControlField.FrameSubTypes.ControlPSPoll: break; //TODO case FrameControlField.FrameSubTypes.ControlRTS: { macFrame = new RtsFrame(bas); break; } case FrameControlField.FrameSubTypes.ControlCTS: { macFrame = new CtsFrame(bas); break; } case FrameControlField.FrameSubTypes.ControlACK: { macFrame = new AckFrame(bas); break; } case FrameControlField.FrameSubTypes.ControlCFEnd: { macFrame = new ContentionFreeEndFrame(bas); break; } case FrameControlField.FrameSubTypes.ControlCFEndCFACK: break; //TODO case FrameControlField.FrameSubTypes.Data: case FrameControlField.FrameSubTypes.DataCFACK: case FrameControlField.FrameSubTypes.DataCFPoll: case FrameControlField.FrameSubTypes.DataCFAckCFPoll: { macFrame = new DataDataFrame(bas); break; } case FrameControlField.FrameSubTypes.DataNullFunctionNoData: case FrameControlField.FrameSubTypes.DataCFAckNoData: case FrameControlField.FrameSubTypes.DataCFPollNoData: case FrameControlField.FrameSubTypes.DataCFAckCFPollNoData: { macFrame = new NullDataFrame(bas); break; } case FrameControlField.FrameSubTypes.QosData: case FrameControlField.FrameSubTypes.QosDataAndCFAck: case FrameControlField.FrameSubTypes.QosDataAndCFPoll: case FrameControlField.FrameSubTypes.QosDataAndCFAckAndCFPoll: { macFrame = new QosDataFrame(bas); break; } case FrameControlField.FrameSubTypes.QosNullData: case FrameControlField.FrameSubTypes.QosCFAck: case FrameControlField.FrameSubTypes.QosCFPoll: case FrameControlField.FrameSubTypes.QosCFAckAndCFPoll: { macFrame = new QosNullDataFrame(bas); break; } default: //this is an unsupported (and unknown) packet type break; } return(macFrame); }
public INetworkPacket Deserialize(BinaryReader reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } INetworkPacket packet = null; var start1 = reader.ReadByte(); switch (start1) { case Constants.MBUS_FRAME_ACK_START: { packet = new AckFrame(); } break; case Constants.MBUS_FRAME_SHORT_START: { //if (stream.Length != 5) // return false; if (start1 != Constants.MBUS_FRAME_SHORT_START) { return(packet); } var control = reader.ReadByte(); var address = reader.ReadByte(); var crc = reader.ReadByte(); if (crc != new byte[] { control, address }.CheckSum()) { return(packet); } var stop = reader.ReadByte(); if (stop != Constants.MBUS_FRAME_STOP) { return(packet); } packet = new ShortFrame(control, address); } break; case Constants.MBUS_FRAME_LONG_START: { const int MBUS_FRAME_FIXED_SIZE_LONG = 6; var length1 = reader.ReadByte(); var length2 = reader.ReadByte(); if (length1 < 3) { return(packet); } if (length1 != length2) { return(packet); } //if (stream.Length < length1 + MBUS_FRAME_FIXED_SIZE_LONG) // return false; var start2 = reader.ReadByte(); if (start2 != Constants.MBUS_FRAME_LONG_START) { return(packet); } var control = reader.ReadByte(); var address = reader.ReadByte(); var controlInformation = reader.ReadByte(); var data = reader.ReadBytes(length1 - 3); if (data.Length != length1 - 3) { return(packet); } var crc = reader.ReadByte(); var stop = reader.ReadByte(); if (crc != new byte[] { control, address, controlInformation }.Merge(data).CheckSum()) { return(packet); } if (length1 - 3 == 0) { packet = new ControlFrame(control, controlInformation, address); } else if ((ControlInformation)controlInformation == ControlInformation.RESP_VARIABLE) { packet = new VariableDataLongFrame(control, controlInformation, address, data, length1); } else if ((ControlInformation)controlInformation == ControlInformation.RESP_FIXED) { packet = new FixedDataLongFrame(control, controlInformation, address, data, length1); } else { throw new NotImplementedException(); } } break; } return(packet); }
private static int Serialize(AckFrame frame, BinaryWriter writer) { writer.Write(Constants.MBUS_FRAME_ACK_START); return(1); }
public Frame GetFrame() { Frame result; var frameType = _array.PeekByte(); switch (frameType) { case 0x00: result = new PaddingFrame(); break; case 0x01: result = new PingFrame(); break; case 0x02: result = new AckFrame(); break; case 0x03: result = new AckFrame(); break; case 0x04: result = new ResetStreamFrame(); break; case 0x05: result = new StopSendingFrame(); break; case 0x06: result = new CryptoFrame(); break; case 0x07: result = new NewTokenFrame(); break; case 0x08: result = new StreamFrame(); break; case 0x09: result = new StreamFrame(); break; case 0x0a: result = new StreamFrame(); break; case 0x0b: result = new StreamFrame(); break; case 0x0c: result = new StreamFrame(); break; case 0x0d: result = new StreamFrame(); break; case 0x0e: result = new StreamFrame(); break; case 0x0f: result = new StreamFrame(); break; case 0x10: result = new MaxDataFrame(); break; case 0x11: result = new MaxStreamDataFrame(); break; case 0x12: result = new MaxStreamsFrame(); break; case 0x13: result = new MaxStreamsFrame(); break; case 0x14: result = new DataBlockedFrame(); break; case 0x15: result = new StreamDataBlockedFrame(); break; case 0x16: result = new StreamsBlockedFrame(); break; case 0x17: result = new StreamsBlockedFrame(); break; case 0x18: result = new NewConnectionIdFrame(); break; case 0x19: result = new RetireConnectionIdFrame(); break; case 0x1a: result = new PathChallengeFrame(); break; case 0x1b: result = new PathResponseFrame(); break; case 0x1c: result = new ConnectionCloseFrame(); break; case 0x1d: result = new ConnectionCloseFrame(); break; default: result = null; break; } if (result != null) { result.Decode(_array); } return(result); }
public void AckFrame(MessageFrame frame) { var ack = new AckFrame(_ackExtensionId, frame.SequenceNumber); _connection.Send(ack); }
/// <summary> /// Handles receiving and sending frames on the given stream. /// </summary> /// <param name="stream">The stream to receive and send frames on</param> /// <param name="notifyHandler">Function to invoke when a NOTIFY frame is received</param> public void HandleStream(Stream stream, Func <NotifyFrame, IList <SpoeAction> > notifyHandler) { if (stream == null) { throw new ApplicationException("Start method requires 'stream' parameter."); } if (notifyHandler == null) { throw new ApplicationException("Start method requires 'notifyHandler' parameter."); } var fragments = new FragmentCatalogue(); string[] haproxyCapabilities = new string[0]; while (true) { bool sendAgentDisconnect = false; string disconnectReason = string.Empty; Status disconnectStatus = Status.Normal; bool closeConnection = false; Frame frame = null; var responseFrames = new ConcurrentQueue <Frame>(); try { byte[] frameBytes = GetBytesForNextFrame(stream); frame = ParseFrame(frameBytes); if (this.EnableLogging) { if (frame != null) { this.LogFunc(frame.ToString()); } } switch (frame.Type) { case FrameType.HaproxyHello: var agentHelloFrame = HandleHandshake(frame); responseFrames.Enqueue(agentHelloFrame); // if this is only a SPOP health check (option spop-check), then close the connection if (((KeyValueListPayload)frame.Payload).KeyValueItems.Any(item => item.Key == "healthcheck" && (bool)item.Value.Value)) { closeConnection = true; } else { string haproxyCapabilitiesString = (string)((KeyValueListPayload)frame.Payload).KeyValueItems.First(item => item.Key == "capabilities").Value.Value; haproxyCapabilities = haproxyCapabilitiesString.Split(','); } break; case FrameType.HaproxyDisconnect: sendAgentDisconnect = true; disconnectStatus = Status.Normal; disconnectReason = "HAProxy disconnected"; break; case FrameType.Notify: if (frame.Metadata.Flags.Fin) { var actions = notifyHandler((NotifyFrame)frame); var ackFrame = new AckFrame( frame.Metadata.StreamId.Value, frame.Metadata.FrameId.Value, actions ?? new List <SpoeAction>()); // fragment if necessary if (haproxyCapabilities.Contains("fragmentation")) { List <Frame> fragmentedFrames = ((AckFrame)ackFrame).FragmentFrame(this.MaxFrameSize); foreach (var f in fragmentedFrames) { responseFrames.Enqueue(f); } } else { responseFrames.Enqueue(ackFrame); } } else { fragments.Push( frame.Metadata.StreamId.Value, frame.Metadata.FrameId.Value, frameBytes); } break; case FrameType.Unset: if (frame.Metadata.Flags.Abort) { fragments.Discard(frame.Metadata.StreamId.Value, frame.Metadata.FrameId.Value); } else { // The Unset frame continues the data, but we only need // to append its payload, not its metadata fragments.Push( frame.Metadata.StreamId.Value, frame.Metadata.FrameId.Value, frame.Payload.Bytes); if (frame.Metadata.Flags.Fin) { byte[] data = fragments.Pop(frame.Metadata.StreamId.Value, frame.Metadata.FrameId.Value); Frame newNotifyFrame = ParseFrame(data); newNotifyFrame.Metadata.Flags.Fin = true; if (this.EnableLogging) { this.LogFunc(newNotifyFrame.ToString()); } var actions = notifyHandler((NotifyFrame)newNotifyFrame); var ackFrame = new AckFrame( frame.Metadata.StreamId.Value, frame.Metadata.FrameId.Value, actions ?? new List <SpoeAction>()); // fragment if necessary if (haproxyCapabilities.Contains("fragmentation")) { var fragmentedFrames = ((AckFrame)ackFrame).FragmentFrame(this.MaxFrameSize); foreach (var f in fragmentedFrames) { responseFrames.Enqueue(f); } } else { responseFrames.Enqueue(ackFrame); } } } break; } } catch (Exception ex) { this.LogFunc(ex.ToString()); sendAgentDisconnect = true; disconnectStatus = Status.UnknownError; disconnectReason = ex.Message; closeConnection = true; } if (this.EnableLogging) { if (responseFrames.Any()) { foreach (var rf in responseFrames) { this.LogFunc(rf.ToString()); } } } if (responseFrames.Any()) { Frame dequeuedFrame; while (responseFrames.TryDequeue(out dequeuedFrame)) { stream.Write(dequeuedFrame.Bytes, 0, dequeuedFrame.Bytes.Length); } } if (sendAgentDisconnect) { Frame disconnectFrame = Disconnect(disconnectStatus, disconnectReason); if (this.EnableLogging) { this.LogFunc(disconnectFrame.ToString()); } stream.Write(disconnectFrame.Bytes, 0, disconnectFrame.Bytes.Length); closeConnection = true; } if (closeConnection) { if (this.EnableLogging) { this.LogFunc("Closing connection."); } stream.Close(); break; } } }