示例#1
0
        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);
        }
示例#2
0
        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);
            }
        }
示例#4
0
        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);
        }