public void TcpOptionSelectiveAcknowledgmentBlockTest() { TcpOptionSelectiveAcknowledgmentBlock block1 = new TcpOptionSelectiveAcknowledgmentBlock(); Assert.AreEqual <uint>(0, block1.LeftEdge); Assert.AreEqual <uint>(0, block1.RightEdge); block1 = new TcpOptionSelectiveAcknowledgmentBlock(1, 2); Assert.AreEqual <uint>(1, block1.LeftEdge); Assert.AreEqual <uint>(2, block1.RightEdge); TcpOptionSelectiveAcknowledgmentBlock block2 = new TcpOptionSelectiveAcknowledgmentBlock(); Assert.AreNotEqual(block1, block2); Assert.IsTrue(block1 != block2); Assert.IsFalse(block1 == block2); Assert.AreNotEqual(block1.ToString(), block2.ToString()); Assert.AreNotEqual(block1, 0); block2 = new TcpOptionSelectiveAcknowledgmentBlock(1, 2); Assert.AreEqual(block1, block2); Assert.IsFalse(block1 != block2); Assert.IsTrue(block1 == block2); }
public void TcpOptionSelectiveAcknowledgmentBlockTest() { TcpOptionSelectiveAcknowledgmentBlock block1 = new TcpOptionSelectiveAcknowledgmentBlock(); Assert.AreEqual<uint>(0, block1.LeftEdge); Assert.AreEqual<uint>(0, block1.RightEdge); block1 = new TcpOptionSelectiveAcknowledgmentBlock(1, 2); Assert.AreEqual<uint>(1, block1.LeftEdge); Assert.AreEqual<uint>(2, block1.RightEdge); TcpOptionSelectiveAcknowledgmentBlock block2 = new TcpOptionSelectiveAcknowledgmentBlock(); Assert.AreNotEqual(block1, block2); Assert.IsTrue(block1 != block2); Assert.IsFalse(block1 == block2); Assert.AreNotEqual(block1.ToString(), block2.ToString()); Assert.AreNotEqual(block1, 0); block2 = new TcpOptionSelectiveAcknowledgmentBlock(1, 2); Assert.AreEqual(block1, block2); Assert.IsFalse(block1 != block2); Assert.IsTrue(block1 == block2); }
public static TcpOption NextTcpOption(this Random random, int maximumOptionLength) { if (maximumOptionLength == 0) { throw new ArgumentOutOfRangeException("maximumOptionLength", maximumOptionLength, "option length must be positive"); } if (maximumOptionLength >= TcpOptionUnknown.OptionMinimumLength && random.Next(100) > 90) { return(random.NextTcpOptionUnknown(maximumOptionLength)); } List <TcpOptionType> impossibleOptionTypes = new List <TcpOptionType>(); if (maximumOptionLength < TcpOptionMaximumSegmentSize.OptionLength) { impossibleOptionTypes.Add(TcpOptionType.MaximumSegmentSize); } if (maximumOptionLength < TcpOptionWindowScale.OptionLength) { impossibleOptionTypes.Add(TcpOptionType.WindowScale); } if (maximumOptionLength < TcpOptionSelectiveAcknowledgment.OptionMinimumLength) { impossibleOptionTypes.Add(TcpOptionType.SelectiveAcknowledgment); } if (maximumOptionLength < TcpOptionSelectiveAcknowledgmentPermitted.OptionLength) { impossibleOptionTypes.Add(TcpOptionType.SelectiveAcknowledgmentPermitted); } if (maximumOptionLength < TcpOptionEcho.OptionLength) { impossibleOptionTypes.Add(TcpOptionType.Echo); } if (maximumOptionLength < TcpOptionEchoReply.OptionLength) { impossibleOptionTypes.Add(TcpOptionType.EchoReply); } if (maximumOptionLength < TcpOptionTimestamp.OptionLength) { impossibleOptionTypes.Add(TcpOptionType.Timestamp); } if (maximumOptionLength < TcpOptionPartialOrderServiceProfile.OptionLength) { impossibleOptionTypes.Add(TcpOptionType.PartialOrderServiceProfile); } if (maximumOptionLength < TcpOptionPartialOrderConnectionPermitted.OptionLength) { impossibleOptionTypes.Add(TcpOptionType.PartialOrderConnectionPermitted); } if (maximumOptionLength < TcpOptionConnectionCountBase.OptionLength) { impossibleOptionTypes.Add(TcpOptionType.ConnectionCount); impossibleOptionTypes.Add(TcpOptionType.ConnectionCountNew); impossibleOptionTypes.Add(TcpOptionType.ConnectionCountEcho); } if (maximumOptionLength < TcpOptionAlternateChecksumRequest.OptionLength) { impossibleOptionTypes.Add(TcpOptionType.AlternateChecksumRequest); } if (maximumOptionLength < TcpOptionAlternateChecksumData.OptionMinimumLength) { impossibleOptionTypes.Add(TcpOptionType.AlternateChecksumData); } if (maximumOptionLength < TcpOptionMd5Signature.OptionLength) { impossibleOptionTypes.Add(TcpOptionType.Md5Signature); } if (maximumOptionLength < TcpOptionMood.OptionMaximumLength) { impossibleOptionTypes.Add(TcpOptionType.Mood); } impossibleOptionTypes.Add(TcpOptionType.QuickStartResponse); impossibleOptionTypes.Add(TcpOptionType.UserTimeout); impossibleOptionTypes.Add(TcpOptionType.SelectiveNegativeAcknowledgements); // TODO: Support Selective Negative Acknowledgements. TcpOptionType optionType = random.NextEnum <TcpOptionType>(impossibleOptionTypes); switch (optionType) { case TcpOptionType.EndOfOptionList: return(TcpOption.End); case TcpOptionType.NoOperation: return(TcpOption.Nop); case TcpOptionType.MaximumSegmentSize: return(new TcpOptionMaximumSegmentSize(random.NextUShort())); case TcpOptionType.WindowScale: return(new TcpOptionWindowScale(random.NextByte())); case TcpOptionType.SelectiveAcknowledgment: int numBlocks = random.Next((maximumOptionLength - TcpOptionSelectiveAcknowledgment.OptionMinimumLength) / 8 + 1); TcpOptionSelectiveAcknowledgmentBlock[] blocks = new TcpOptionSelectiveAcknowledgmentBlock[numBlocks]; for (int i = 0; i != numBlocks; ++i) { blocks[i] = new TcpOptionSelectiveAcknowledgmentBlock(random.NextUInt(), random.NextUInt()); } return(new TcpOptionSelectiveAcknowledgment(blocks)); case TcpOptionType.SelectiveAcknowledgmentPermitted: return(new TcpOptionSelectiveAcknowledgmentPermitted()); case TcpOptionType.Echo: return(new TcpOptionEcho(random.NextUInt())); case TcpOptionType.EchoReply: return(new TcpOptionEchoReply(random.NextUInt())); case TcpOptionType.Timestamp: return(new TcpOptionTimestamp(random.NextUInt(), random.NextUInt())); case TcpOptionType.PartialOrderServiceProfile: return(new TcpOptionPartialOrderServiceProfile(random.NextBool(), random.NextBool())); case TcpOptionType.PartialOrderConnectionPermitted: return(new TcpOptionPartialOrderConnectionPermitted()); case TcpOptionType.ConnectionCount: return(new TcpOptionConnectionCount(random.NextUInt())); case TcpOptionType.ConnectionCountEcho: return(new TcpOptionConnectionCountEcho(random.NextUInt())); case TcpOptionType.ConnectionCountNew: return(new TcpOptionConnectionCountNew(random.NextUInt())); case TcpOptionType.AlternateChecksumRequest: return(new TcpOptionAlternateChecksumRequest(random.NextEnum <TcpOptionAlternateChecksumType>())); case TcpOptionType.AlternateChecksumData: return(new TcpOptionAlternateChecksumData(random.NextBytes(random.Next(maximumOptionLength - TcpOptionAlternateChecksumData.OptionMinimumLength + 1)))); case TcpOptionType.Md5Signature: return(new TcpOptionMd5Signature(random.NextBytes(TcpOptionMd5Signature.OptionValueLength))); case TcpOptionType.Mood: return(new TcpOptionMood(random.NextEnum(TcpOptionMoodEmotion.None))); default: throw new InvalidOperationException("optionType = " + optionType); } }
public static TcpOption NextTcpOption(this Random random, int maximumOptionLength) { if (maximumOptionLength == 0) throw new ArgumentOutOfRangeException("maximumOptionLength", maximumOptionLength, "option length must be positive"); if (maximumOptionLength >= TcpOptionUnknown.OptionMinimumLength && random.Next(100) > 90) return random.NextTcpOptionUnknown(maximumOptionLength); List<TcpOptionType> impossibleOptionTypes = new List<TcpOptionType>(); if (maximumOptionLength < TcpOptionMaximumSegmentSize.OptionLength) impossibleOptionTypes.Add(TcpOptionType.MaximumSegmentSize); if (maximumOptionLength < TcpOptionWindowScale.OptionLength) impossibleOptionTypes.Add(TcpOptionType.WindowScale); if (maximumOptionLength < TcpOptionSelectiveAcknowledgment.OptionMinimumLength) impossibleOptionTypes.Add(TcpOptionType.SelectiveAcknowledgment); if (maximumOptionLength < TcpOptionSelectiveAcknowledgmentPermitted.OptionLength) impossibleOptionTypes.Add(TcpOptionType.SelectiveAcknowledgmentPermitted); if (maximumOptionLength < TcpOptionEcho.OptionLength) impossibleOptionTypes.Add(TcpOptionType.Echo); if (maximumOptionLength < TcpOptionEchoReply.OptionLength) impossibleOptionTypes.Add(TcpOptionType.EchoReply); if (maximumOptionLength < TcpOptionTimestamp.OptionLength) impossibleOptionTypes.Add(TcpOptionType.Timestamp); if (maximumOptionLength < TcpOptionPartialOrderServiceProfile.OptionLength) impossibleOptionTypes.Add(TcpOptionType.PartialOrderServiceProfile); if (maximumOptionLength < TcpOptionPartialOrderConnectionPermitted.OptionLength) impossibleOptionTypes.Add(TcpOptionType.PartialOrderConnectionPermitted); if (maximumOptionLength < TcpOptionConnectionCountBase.OptionLength) { impossibleOptionTypes.Add(TcpOptionType.ConnectionCount); impossibleOptionTypes.Add(TcpOptionType.ConnectionCountNew); impossibleOptionTypes.Add(TcpOptionType.ConnectionCountEcho); } if (maximumOptionLength < TcpOptionAlternateChecksumRequest.OptionLength) impossibleOptionTypes.Add(TcpOptionType.AlternateChecksumRequest); if (maximumOptionLength < TcpOptionAlternateChecksumData.OptionMinimumLength) impossibleOptionTypes.Add(TcpOptionType.AlternateChecksumData); if (maximumOptionLength < TcpOptionMd5Signature.OptionLength) impossibleOptionTypes.Add(TcpOptionType.Md5Signature); if (maximumOptionLength < TcpOptionMood.OptionMaximumLength) impossibleOptionTypes.Add(TcpOptionType.Mood); if (maximumOptionLength < TcpOptionAuthentication.OptionMinimumLength) impossibleOptionTypes.Add(TcpOptionType.TcpAuthentication); impossibleOptionTypes.Add(TcpOptionType.QuickStartResponse); impossibleOptionTypes.Add(TcpOptionType.UserTimeout); impossibleOptionTypes.Add(TcpOptionType.SelectiveNegativeAcknowledgements); // TODO: Support Selective Negative Acknowledgements. TcpOptionType optionType = random.NextEnum<TcpOptionType>(impossibleOptionTypes); switch (optionType) { case TcpOptionType.EndOfOptionList: return TcpOption.End; case TcpOptionType.NoOperation: return TcpOption.Nop; case TcpOptionType.MaximumSegmentSize: return new TcpOptionMaximumSegmentSize(random.NextUShort()); case TcpOptionType.WindowScale: return new TcpOptionWindowScale(random.NextByte()); case TcpOptionType.SelectiveAcknowledgment: int numBlocks = random.Next((maximumOptionLength - TcpOptionSelectiveAcknowledgment.OptionMinimumLength) / 8 + 1); TcpOptionSelectiveAcknowledgmentBlock[] blocks = new TcpOptionSelectiveAcknowledgmentBlock[numBlocks]; for (int i = 0; i != numBlocks; ++i) blocks[i] = new TcpOptionSelectiveAcknowledgmentBlock(random.NextUInt(), random.NextUInt()); return new TcpOptionSelectiveAcknowledgment(blocks); case TcpOptionType.SelectiveAcknowledgmentPermitted: return new TcpOptionSelectiveAcknowledgmentPermitted(); case TcpOptionType.Echo: return new TcpOptionEcho(random.NextUInt()); case TcpOptionType.EchoReply: return new TcpOptionEchoReply(random.NextUInt()); case TcpOptionType.Timestamp: return new TcpOptionTimestamp(random.NextUInt(), random.NextUInt()); case TcpOptionType.PartialOrderServiceProfile: return new TcpOptionPartialOrderServiceProfile(random.NextBool(), random.NextBool()); case TcpOptionType.PartialOrderConnectionPermitted: return new TcpOptionPartialOrderConnectionPermitted(); case TcpOptionType.ConnectionCount: return new TcpOptionConnectionCount(random.NextUInt()); case TcpOptionType.ConnectionCountEcho: return new TcpOptionConnectionCountEcho(random.NextUInt()); case TcpOptionType.ConnectionCountNew: return new TcpOptionConnectionCountNew(random.NextUInt()); case TcpOptionType.AlternateChecksumRequest: return new TcpOptionAlternateChecksumRequest(random.NextEnum<TcpOptionAlternateChecksumType>()); case TcpOptionType.AlternateChecksumData: return new TcpOptionAlternateChecksumData(random.NextBytes(random.Next(maximumOptionLength - TcpOptionAlternateChecksumData.OptionMinimumLength + 1))); case TcpOptionType.Md5Signature: return new TcpOptionMd5Signature(random.NextBytes(TcpOptionMd5Signature.OptionValueLength)); case TcpOptionType.Mood: return new TcpOptionMood(random.NextEnum(TcpOptionMoodEmotion.None)); case TcpOptionType.TcpAuthentication: return new TcpOptionAuthentication(random.NextByte(), random.NextByte(), random.NextBytes(random.Next(maximumOptionLength - TcpOptionAuthentication.OptionMinimumLength + 1))); default: throw new InvalidOperationException("optionType = " + optionType); } }
/// <summary> /// Tries to read the option from a buffer starting from the option value (after the type and length). /// </summary> /// <param name="buffer">The buffer to read the option from.</param> /// <param name="offset">The offset to the first byte to read the buffer. Will be incremented by the number of bytes read.</param> /// <param name="valueLength">The number of bytes the option value should take according to the length field that was already read.</param> /// <returns>On success - the complex option read. On failure - null.</returns> Option IOptionComplexFactory.CreateInstance(byte[] buffer, ref int offset, byte valueLength) { if (valueLength < OptionValueMinimumLength || valueLength % TcpOptionSelectiveAcknowledgmentBlock.SizeOf != 0) return null; int numBlocks = valueLength / TcpOptionSelectiveAcknowledgmentBlock.SizeOf; TcpOptionSelectiveAcknowledgmentBlock[] blocks = new TcpOptionSelectiveAcknowledgmentBlock[numBlocks]; for (int i = 0; i != numBlocks; ++i) { blocks[i] = new TcpOptionSelectiveAcknowledgmentBlock(buffer.ReadUInt(ref offset, Endianity.Big), buffer.ReadUInt(ref offset, Endianity.Big)); } return new TcpOptionSelectiveAcknowledgment(blocks); }