예제 #1
0
        public void MergeFrom(HealthCheck other)
        {
            if (other == null)
            {
                return;
            }
            if (other.Name.Length != 0)
            {
                Name = other.Name;
            }
            if (other.interval_ != null)
            {
                if (interval_ == null)
                {
                    Interval = new global::Google.Protobuf.WellKnownTypes.Duration();
                }
                Interval.MergeFrom(other.Interval);
            }
            if (other.timeout_ != null)
            {
                if (timeout_ == null)
                {
                    Timeout = new global::Google.Protobuf.WellKnownTypes.Duration();
                }
                Timeout.MergeFrom(other.Timeout);
            }
            if (other.UnhealthyThreshold != 0L)
            {
                UnhealthyThreshold = other.UnhealthyThreshold;
            }
            if (other.HealthyThreshold != 0L)
            {
                HealthyThreshold = other.HealthyThreshold;
            }
            switch (other.OptionsCase)
            {
            case OptionsOneofCase.TcpOptions:
                if (TcpOptions == null)
                {
                    TcpOptions = new global::Yandex.Cloud.Loadbalancer.V1.HealthCheck.Types.TcpOptions();
                }
                TcpOptions.MergeFrom(other.TcpOptions);
                break;

            case OptionsOneofCase.HttpOptions:
                if (HttpOptions == null)
                {
                    HttpOptions = new global::Yandex.Cloud.Loadbalancer.V1.HealthCheck.Types.HttpOptions();
                }
                HttpOptions.MergeFrom(other.HttpOptions);
                break;
            }

            _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
        }
예제 #2
0
        public override int GetHashCode()
        {
            int hash = 1;

            if (Name.Length != 0)
            {
                hash ^= Name.GetHashCode();
            }
            if (interval_ != null)
            {
                hash ^= Interval.GetHashCode();
            }
            if (timeout_ != null)
            {
                hash ^= Timeout.GetHashCode();
            }
            if (UnhealthyThreshold != 0L)
            {
                hash ^= UnhealthyThreshold.GetHashCode();
            }
            if (HealthyThreshold != 0L)
            {
                hash ^= HealthyThreshold.GetHashCode();
            }
            if (optionsCase_ == OptionsOneofCase.TcpOptions)
            {
                hash ^= TcpOptions.GetHashCode();
            }
            if (optionsCase_ == OptionsOneofCase.HttpOptions)
            {
                hash ^= HttpOptions.GetHashCode();
            }
            hash ^= (int)optionsCase_;
            if (_unknownFields != null)
            {
                hash ^= _unknownFields.GetHashCode();
            }
            return(hash);
        }
예제 #3
0
        private void TcpOpen()
        {
            VirtualNetwork.Instance.PostTraceMessage("TCP OPEN: " + _remote_ip.ToString() + " " + _remote_port.ToString());
            InputBuffer = new Queue <byte>();
            _connection_wait_handle.Reset();

            TcpOptions tcpOptions = new TcpOptions(
                new TcpOptionMaximumSegmentSize(MAX_SEGMENT_SIZE),
                new TcpOptionWindowScale(WINDOW_SCALE)
                );

            SendTcpCtrlPacket(0, TcpControlBits.Synchronize, tcpOptions); // ACK = false, SYNC = true, FIN = false
            _current_state = TCP_STATE.SYN_SENT;
            _connection_wait_handle.WaitOne(TCP_OPEN_TIMEOUT, true);      // wait for connection process finish
            if (_current_state == TCP_STATE.ESTABLISHED)
            {
                VirtualNetwork.Instance.PostTraceMessage("TCP OPEN: " + _remote_ip.ToString() + " " + _remote_port.ToString() + " - SUCCESSFUL");
            }
            else
            {
                VirtualNetwork.Instance.PostTraceMessage("TCP OPEN: " + _remote_ip.ToString() + " " + _remote_port.ToString() + " - FAILED");
            }
        }
        private static void CompareTcpOptions(XElement element, TcpOptions options)
        {
            int currentOptionIndex = 0;
            foreach (var field in element.Fields())
            {
                if (currentOptionIndex >= options.Count)
                {
                    Assert.IsFalse(options.IsValid, "Options IsValid");
                    Assert.IsTrue(
                        field.Show().StartsWith("Unknown (0x0a) ") || // Unknown in Wireshark but known (and invalid) in Pcap.Net
                        field.Show().Contains("bytes says option goes past end of options") ||
                        field.Show().Contains(") (with too-short option length = "),
                        "Options show: " + field.Show());
                    Assert.AreEqual(options.Count, currentOptionIndex, "Options Count");
                    return;
                }

                TcpOption option = options[currentOptionIndex];
                switch (field.Name())
                {
                    case "":
                        switch (option.OptionType)
                        {
                            case TcpOptionType.SelectiveNegativeAcknowledgements: // TODO: Support Selective Negative Acknowledgements.
                                Assert.IsTrue(field.Show().StartsWith(option.GetWiresharkString()));
                                field.AssertNoFields();
                                break;
                            
                            case (TcpOptionType)78: // TODO: Support Riverbed.
                                break;

                            default:
                                field.AssertShow(option.GetWiresharkString());
                                break;
                        }

                        switch (option.OptionType)
                        {
                            case TcpOptionType.WindowScale:
                                TcpOptionWindowScale windowScale = (TcpOptionWindowScale)option;
                                foreach (var subField in field.Fields())
                                {
                                    switch (subField.Name())
                                    {
                                        case "tcp.option_kind":
                                            subField.AssertShowDecimal((byte)windowScale.OptionType);
                                            break;

                                        case "tcp.option_len":
                                            subField.AssertShowDecimal(windowScale.Length);
                                            break;

                                        case "tcp.options.wscale.shift":
                                            subField.AssertShowDecimal(windowScale.ScaleFactorLog);
                                            break;

                                        case "tcp.options.wscale.multiplier":
                                            subField.AssertShowDecimal(1L << (windowScale.ScaleFactorLog % 32));
                                            break;

                                        default:
                                            throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name());
                                    }
                                }
                                break;

                            case TcpOptionType.SelectiveAcknowledgment:
                                var selectiveAcknowledgmentOption = (TcpOptionSelectiveAcknowledgment)option;
                                int blockIndex = 0;
                                foreach (var subField in field.Fields())
                                {
                                    switch (subField.Name())
                                    {
                                        case "tcp.options.sack":
                                            subField.AssertShowDecimal(true);
                                            break;

                                        case "tcp.options.sack_le":
                                            subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks[blockIndex].LeftEdge);
                                            break;

                                        case "tcp.options.sack_re":
                                            subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks[blockIndex].RightEdge);
                                            ++blockIndex;
                                            break;

                                        default:
                                            throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name());
                                    }
                                }
                                break;

                            case TcpOptionType.Timestamp:
                                var timestampOption = (TcpOptionTimestamp)option;
                                foreach (var subField in field.Fields())
                                {
                                    switch (subField.Name())
                                    {
                                        case "tcp.option_kind":
                                            subField.AssertShowDecimal((byte)option.OptionType);
                                            break;

                                        case "tcp.option_len":
                                            subField.AssertShowDecimal(option.Length);
                                            break;

                                        case "tcp.options.timestamp.tsval":
                                            subField.AssertShowDecimal(timestampOption.TimestampValue);
                                            break;

                                        case "tcp.options.timestamp.tsecr":
                                            subField.AssertShowDecimal(timestampOption.TimestampEchoReply);
                                            break;

                                        default:
                                            throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name());
                                    }
                                }
                                break;

                            default:
                                field.AssertNoFields();
                                break;
                        }
                        ++currentOptionIndex;
                        break;

                    case "tcp.options.mss":
                        Assert.AreEqual(TcpOptionType.MaximumSegmentSize, option.OptionType);
                        field.AssertShowDecimal(true);
                        field.AssertNoFields();
                        break;

                    case "tcp.options.mss_val":
                        field.AssertShowDecimal(((TcpOptionMaximumSegmentSize)option).MaximumSegmentSize);
                        field.AssertNoFields();
                        ++currentOptionIndex;
                        break;

                    case "tcp.options.echo":
                        Assert.IsTrue(option is TcpOptionEchoReply || option is TcpOptionEcho);
                        field.AssertShowDecimal(1);
                        field.AssertNoFields();
                        break;

                    case "tcp.options.cc":
                        Assert.IsTrue(option is TcpOptionConnectionCountBase);
                        field.AssertShowDecimal(1);
                        field.AssertNoFields();
                        break;

                    case "tcp.options.scps.vector":
                        Assert.AreEqual((TcpOptionType)20, option.OptionType);
                        if (field.Show() == "0")
                            ++currentOptionIndex;
                        ++currentOptionIndex;
                        break;

                    case "tcp.options.scps":
                        Assert.AreEqual((TcpOptionType)20, option.OptionType);
                        Assert.IsFalse(field.Fields().Any());
                        break;

                    case "tcp.options.snack": // TODO: Support Selective Negative Acknowledgements.
                    case "tcp.options.snack.offset":
                    case "tcp.options.snack.size":
                        Assert.AreEqual(TcpOptionType.SelectiveNegativeAcknowledgements, option.OptionType);
                        field.AssertNoFields();
                        break;

                    case "tcp.options.sack_perm":
                        Assert.AreEqual(TcpOptionType.SelectiveAcknowledgmentPermitted, option.OptionType);
                        field.AssertNoFields();
                        ++currentOptionIndex;
                        break;

                    case "tcp.options.rvbd.probe":
                        Assert.AreEqual((TcpOptionType)76, option.OptionType);
                        // TODO: Support Riverbed.
                        ++currentOptionIndex;
                        break;

                    case "tcp.options.rvbd.trpy":
                        Assert.AreEqual((TcpOptionType)78, option.OptionType);
                        // TODO: Support Riverbed.
                        ++currentOptionIndex;
                        break;

                    default:
                        throw new InvalidOperationException("Invalid tcp options field " + field.Name());
                }
            }
        }
예제 #5
0
        internal static void WriteHeader(byte[] buffer, int offset,
                                         ushort sourcePort, ushort destinationPort,
                                         uint sequenceNumber, uint acknowledgmentNumber,
                                         TcpControlBits controlBits, ushort window, ushort urgentPointer,
                                         TcpOptions options)
        {
            int headerLength = HeaderMinimumLength + options.BytesLength;

            WriteHeader(buffer, offset, sourcePort, destinationPort);
            buffer.Write(offset + Offset.SequenceNumber, sequenceNumber, Endianity.Big);
            buffer.Write(offset + Offset.AcknowledgmentNumber, acknowledgmentNumber, Endianity.Big);
            buffer.Write(offset + Offset.HeaderLengthAndFlags, (ushort)(((ushort)((headerLength / 4) << 12)) | (ushort)controlBits), Endianity.Big);
            buffer.Write(offset + Offset.Window, window, Endianity.Big);
            buffer.Write(offset + Offset.UrgentPointer, urgentPointer, Endianity.Big);
            options.Write(buffer, offset + Offset.Options);
        }
        private static void CompareTcpOptions(XElement element, TcpOptions options)
        {
            int currentOptionIndex = 0;
            foreach (var field in element.Fields())
            {
                if (field.Name() == "_ws.expert")
                    continue;
                if (currentOptionIndex >= options.Count)
                {
                    Assert.IsFalse(options.IsValid, "Options IsValid");
                    Assert.IsTrue(
                        field.Show().StartsWith("Unknown (0x09) ") || // Unknown in Wireshark but known (and invalid) in Pcap.Net.
                        field.Show().StartsWith("Unknown (0x0a) ") || // Unknown in Wireshark but known (and invalid) in Pcap.Net.
                        field.Show().StartsWith("Unknown (0x19) ") || // Unknown in Wireshark but known (and invalid) in Pcap.Net.
                        field.Show().StartsWith("Unknown (0x2d) ") || // Unknown in Wireshark and unknown and invalid in Pcap.Net.
                        field.Show().StartsWith("Unknown (0xa9) ") || // Unknown in Wireshark and unknown and invalid in Pcap.Net.
                        field.Show().StartsWith("Echo reply (with option length = ") ||
                        field.Show().Contains("bytes says option goes past end of options") ||
                        field.Show().Contains(") (with too-short option length = ") ||
                        field.Show().EndsWith(" (length byte past end of options)"),
                        "Options show: " + field.Show());
                    Assert.AreEqual(options.Count, currentOptionIndex, "Options Count");
                    return;
                }

                TcpOption option = options[currentOptionIndex];
                switch (field.Name())
                {
                    case "":
                        switch (option.OptionType)
                        {
                            case TcpOptionType.WindowScale:
                                TcpOptionWindowScale windowScale = (TcpOptionWindowScale)option;
                                byte scaleFactorLog = windowScale.ScaleFactorLog;
                                field.AssertShow(string.Format("Window scale: {0} (multiply by {1})", scaleFactorLog, (1L << (scaleFactorLog % 32))));
                                foreach (var subField in field.Fields())
                                {
                                    if (HandleOptionCommonFields(subField, option))
                                        continue;
                                    switch (subField.Name())
                                    {
                                        case "tcp.options.wscale.shift":
                                            subField.AssertShowDecimal(windowScale.ScaleFactorLog);
                                            break;

                                        case "tcp.options.wscale.multiplier":
                                            subField.AssertShowDecimal(1L << (windowScale.ScaleFactorLog % 32));
                                            break;

                                        default:
                                            throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                                    }
                                }
                                break;

                            case TcpOptionType.SelectiveAcknowledgment:
                                var selectiveAcknowledgmentOption = (TcpOptionSelectiveAcknowledgment)option;
                                IEnumerable<TcpOptionSelectiveAcknowledgmentBlock> blocks = selectiveAcknowledgmentOption.Blocks;
                                field.AssertShow("SACK:" + (blocks.Count() == 0
                                                                ? string.Empty
                                                                : ((TcpOptionSelectiveAcknowledgment)option).Blocks.SequenceToString(" ", " ")));
                                int blockIndex = 0;
                                foreach (var subField in field.Fields())
                                {
                                    if (HandleOptionCommonFields(subField, option))
                                        continue;
                                    subField.AssertNoFields();
                                    switch (subField.Name())
                                    {
                                        case "tcp.options.sack":
                                            subField.AssertShowDecimal(true);
                                            break;

                                        case "tcp.options.sack_le":
                                            subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks[blockIndex].LeftEdge);
                                            break;

                                        case "tcp.options.sack_re":
                                            subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks[blockIndex].RightEdge);
                                            ++blockIndex;
                                            break;

                                        case "tcp.options.sack.count":
                                            subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks.Count);
                                            break;

                                        default:
                                            throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                                    }
                                }
                                break;

                            case TcpOptionType.Timestamp:
                                var timestampOption = (TcpOptionTimestamp)option;
                                field.AssertShow("Timestamps: TSval " + timestampOption.TimestampValue + ", TSecr " + timestampOption.TimestampEchoReply);
                                foreach (var subField in field.Fields())
                                {
                                    if (HandleOptionCommonFields(subField, option))
                                        continue;
                                    subField.AssertNoFields();
                                    switch (subField.Name())
                                    {
                                        case "tcp.options.timestamp.tsval":
                                            subField.AssertShowDecimal(timestampOption.TimestampValue);
                                            break;

                                        case "tcp.options.timestamp.tsecr":
                                            subField.AssertShowDecimal(timestampOption.TimestampEchoReply);
                                            break;

                                        default:
                                            throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                                    }
                                }
                                break;

                            case TcpOptionType.ConnectionCount:
                                field.AssertShow("CC: " + ((TcpOptionConnectionCount)option).ConnectionCount);
                                foreach (var subField in field.Fields())
                                {
                                    if (HandleOptionCommonFields(subField, option))
                                        continue;
                                    subField.AssertNoFields();
                                    switch (subField.Name())
                                    {
                                        default:
                                            throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                                    }
                                }
                                break;

                            case TcpOptionType.Echo:
                                field.AssertShow("Echo: " + ((TcpOptionEcho)option).Info);
                                foreach (var subField in field.Fields())
                                {
                                    if (HandleOptionCommonFields(subField, option))
                                        continue;
                                    subField.AssertNoFields();
                                    switch (subField.Name())
                                    {
                                        default:
                                            throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                                    }
                                }
                                break;

                            case TcpOptionType.ConnectionCountNew:
                                field.AssertShow("CC.NEW: " + ((TcpOptionConnectionCountNew)option).ConnectionCount);
                                foreach (var subField in field.Fields())
                                {
                                    if (HandleOptionCommonFields(subField, option))
                                        continue;
                                    subField.AssertNoFields();
                                    switch (subField.Name())
                                    {
                                        default:
                                            throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                                    }
                                }
                                break;

                            case TcpOptionType.EndOfOptionList:
                                field.AssertShow("End of Option List (EOL)");
                                foreach (var subField in field.Fields())
                                {
                                    if (HandleOptionCommonFields(subField, option))
                                        continue;
                                    switch (subField.Name())
                                    {
                                        default:
                                            subField.AssertNoFields();
                                            throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                                    }
                                }
                                break;

                            case TcpOptionType.ConnectionCountEcho:
                                field.AssertShow("CC.ECHO: " + ((TcpOptionConnectionCountEcho)option).ConnectionCount);
                                foreach (var subField in field.Fields())
                                {
                                    if (HandleOptionCommonFields(subField, option))
                                        continue;
                                    subField.AssertNoFields();
                                    switch (subField.Name())
                                    {
                                        default:
                                            throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                                    }
                                }
                                break;

                            case TcpOptionType.Md5Signature:
                                field.AssertShow("TCP MD5 signature");
                                foreach (var subField in field.Fields())
                                {
                                    if (HandleOptionCommonFields(subField, option))
                                        continue;
                                    switch (subField.Name())
                                    {
                                        case "tcp.options.type":
                                            subField.AssertShowDecimal((byte)TcpOptionType.Md5Signature);
                                            break;

                                        default:
                                            subField.AssertNoFields();
                                            throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                                    }
                                }
                                break;

                            case TcpOptionType.NoOperation:
                                field.AssertShow("No-Operation (NOP)");
                                foreach (var subField in field.Fields())
                                {
                                    if (HandleOptionCommonFields(subField, option))
                                        continue;
                                    throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                                }
                                break;

                            case TcpOptionType.EchoReply:
                                field.AssertShow("Echo reply: " + ((TcpOptionEchoReply)option).Info);
                                foreach (var subField in field.Fields())
                                {
                                    if (HandleOptionCommonFields(subField, option))
                                        continue;
                                    throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                                }
                                break;

                            case TcpOptionType.SelectiveAcknowledgmentPermitted:
                                field.AssertShow("SACK permitted");
                                field.AssertNoFields();
                                break;

                            case TcpOptionType.SelectiveNegativeAcknowledgements: // TODO: Support Selective Negative Acknowledgements.
                                Assert.IsTrue(field.Show().StartsWith("SACK permitted"));
                                field.AssertNoFields();
                                break;

                            case (TcpOptionType)20:
                                // TODO: Support 20.
                                field.AssertShow("SCPS capabilities" + (option.Length >= 4
                                                                            ? string.Empty
                                                                            : " (with option length = " + option.Length + " bytes; should be >= 4)"));
                                break;

                            case (TcpOptionType)22:
                                field.AssertShow("SCPS record boundary (with option length = " + option.Length + " bytes; should be 2)");
                                // TODO: Support 22.
                                break;

                            case (TcpOptionType)23:
                                field.AssertShow("SCPS corruption experienced (with option length = " + option.Length + " bytes; should be 2)");
                                // TODO: Support 23.
                                break;

                            case (TcpOptionType)30:
                                // TODO: Support 30.
                                Assert.IsTrue(field.Show().StartsWith("Multipath TCP"));
                                break;

                            case (TcpOptionType)78:
                                field.AssertShow("Riverbed Transparency (with option length = " + option.Length + " bytes; should be 16)");
                                // TODO: Support 78 - Support Riverbed.
                                break;

                            case TcpOptionType.PartialOrderConnectionPermitted: // 9.
                            case TcpOptionType.PartialOrderServiceProfile:      // 10.
                            case TcpOptionType.AlternateChecksumRequest:        // 14.
                            case TcpOptionType.AlternateChecksumData:           // 15.
                            case TcpOptionType.Mood:                            // 25.
                            case TcpOptionType.TcpAuthentication:               // 29.
                                field.AssertShow(string.Format("Unknown (0x{0}) ({1} bytes)", ((byte)option.OptionType).ToString("x2"), option.Length));
                                field.AssertNoFields();
                                break;

                            default:
                                field.AssertNoFields();
                                field.AssertShow("Unknown (0x" + ((byte)option.OptionType).ToString("x") + ") (" + option.Length + " bytes)");
                                break;
                        }
                        ++currentOptionIndex;
                        break;

                    case "tcp.options.mss":
                        Assert.AreEqual(TcpOptionType.MaximumSegmentSize, option.OptionType);
                        var maximumSegmentSize = (TcpOptionMaximumSegmentSize)option;
                        field.AssertShowname("Maximum segment size: " + maximumSegmentSize.MaximumSegmentSize + " bytes");
                        foreach (var subField in field.Fields())
                        {
                            if (HandleOptionCommonFields(subField, option))
                                continue;
                            subField.AssertNoFields();
                            switch (subField.Name())
                            {
                                case "tcp.options.mss_val":
                                    subField.AssertShowDecimal(maximumSegmentSize.MaximumSegmentSize);
                                    break;

                                default:
                                    throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name());
                            }
                        }
                        ++currentOptionIndex;
                        break;

                    case "tcp.options.mss_val":
                        field.AssertShowDecimal(((TcpOptionMaximumSegmentSize)option).MaximumSegmentSize);
                        field.AssertNoFields();
                        ++currentOptionIndex;
                        break;

                    case "tcp.options.echo":
                        Assert.IsTrue(option is TcpOptionEchoReply || option is TcpOptionEcho);
                        field.AssertShowDecimal(1);
                        field.AssertNoFields();
                        break;

                    case "tcp.options.cc":
                        Assert.IsTrue(option is TcpOptionConnectionCountBase);
                        field.AssertShowDecimal(1);
                        field.AssertNoFields();
                        break;

                    case "tcp.options.scps.vector":
                        // TODO: Support 20.
                        Assert.AreEqual((TcpOptionType)20, option.OptionType);
//                        if (field.Show() == "0")
//                            ++currentOptionIndex;
                        ++currentOptionIndex;
                        break;

                    case "tcp.options.scps":
                        // TODO: Support 20.
                        Assert.AreEqual((TcpOptionType)20, option.OptionType);
                        Assert.IsFalse(field.Fields().Any());
                        break;

                    case "tcp.options.snack": // TODO: Support Selective Negative Acknowledgements.
                    case "tcp.options.snack.offset":
                    case "tcp.options.snack.size":
                        Assert.AreEqual(TcpOptionType.SelectiveNegativeAcknowledgements, option.OptionType);
                        field.AssertNoFields();
                        break;

                    case "tcp.options.sack_perm":
                        Assert.AreEqual(TcpOptionType.SelectiveAcknowledgmentPermitted, option.OptionType);
                        foreach (var subField in field.Fields())
                        {
                            if (HandleOptionCommonFields(subField, option))
                                continue;
                            subField.AssertNoFields();
                            throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name());
                        }
                        ++currentOptionIndex;
                        break;

                    case "tcp.options.rvbd.probe":
                        Assert.AreEqual((TcpOptionType)76, option.OptionType);
                        // TODO: Support Riverbed.
                        ++currentOptionIndex;
                        break;

                    case "tcp.options.rvbd.trpy":
                        Assert.AreEqual((TcpOptionType)78, option.OptionType);
                        // TODO: Support Riverbed.
                        ++currentOptionIndex;
                        break;

                    case "tcp.options.experimental":
                        Assert.IsTrue(new []{(TcpOptionType)253, (TcpOptionType)254}.Contains(option.OptionType));
                        // TODO: Support Experimental.
                        ++currentOptionIndex;
                        break;

                    default:
                        throw new InvalidOperationException("Invalid tcp options field " + field.Name());
                }
            }
        }
예제 #7
0
        private static void CompareTcpOptions(XElement element, TcpOptions options)
        {
            int currentOptionIndex = 0;

            foreach (var field in element.Fields())
            {
                if (currentOptionIndex >= options.Count)
                {
                    Assert.IsFalse(options.IsValid, "Options IsValid");
                    Assert.IsTrue(
                        field.Show().StartsWith("Unknown (0x0a) ") || // Unknown in Wireshark but known (and invalid) in Pcap.Net
                        field.Show().Contains("bytes says option goes past end of options") ||
                        field.Show().Contains(") (with too-short option length = "),
                        "Options show: " + field.Show());
                    Assert.AreEqual(options.Count, currentOptionIndex, "Options Count");
                    return;
                }

                TcpOption option = options[currentOptionIndex];
                switch (field.Name())
                {
                case "":
                    switch (option.OptionType)
                    {
                    case TcpOptionType.SelectiveNegativeAcknowledgements:         // TODO: Support Selective Negative Acknowledgements.
                        Assert.IsTrue(field.Show().StartsWith(option.GetWiresharkString()));
                        field.AssertNoFields();
                        break;

                    case (TcpOptionType)78:         // TODO: Support Riverbed.
                        break;

                    default:
                        field.AssertShow(option.GetWiresharkString());
                        break;
                    }

                    switch (option.OptionType)
                    {
                    case TcpOptionType.WindowScale:
                        TcpOptionWindowScale windowScale = (TcpOptionWindowScale)option;
                        foreach (var subField in field.Fields())
                        {
                            switch (subField.Name())
                            {
                            case "tcp.option_kind":
                                subField.AssertShowDecimal((byte)windowScale.OptionType);
                                break;

                            case "tcp.option_len":
                                subField.AssertShowDecimal(windowScale.Length);
                                break;

                            case "tcp.options.wscale.shift":
                                subField.AssertShowDecimal(windowScale.ScaleFactorLog);
                                break;

                            case "tcp.options.wscale.multiplier":
                                subField.AssertShowDecimal(1L << (windowScale.ScaleFactorLog % 32));
                                break;

                            default:
                                throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name());
                            }
                        }
                        break;

                    case TcpOptionType.SelectiveAcknowledgment:
                        var selectiveAcknowledgmentOption = (TcpOptionSelectiveAcknowledgment)option;
                        int blockIndex = 0;
                        foreach (var subField in field.Fields())
                        {
                            switch (subField.Name())
                            {
                            case "tcp.options.sack":
                                subField.AssertShowDecimal(true);
                                break;

                            case "tcp.options.sack_le":
                                subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks[blockIndex].LeftEdge);
                                break;

                            case "tcp.options.sack_re":
                                subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks[blockIndex].RightEdge);
                                ++blockIndex;
                                break;

                            default:
                                throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name());
                            }
                        }
                        break;

                    case TcpOptionType.Timestamp:
                        var timestampOption = (TcpOptionTimestamp)option;
                        foreach (var subField in field.Fields())
                        {
                            switch (subField.Name())
                            {
                            case "tcp.option_kind":
                                subField.AssertShowDecimal((byte)option.OptionType);
                                break;

                            case "tcp.option_len":
                                subField.AssertShowDecimal(option.Length);
                                break;

                            case "tcp.options.timestamp.tsval":
                                subField.AssertShowDecimal(timestampOption.TimestampValue);
                                break;

                            case "tcp.options.timestamp.tsecr":
                                subField.AssertShowDecimal(timestampOption.TimestampEchoReply);
                                break;

                            default:
                                throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name());
                            }
                        }
                        break;

                    default:
                        field.AssertNoFields();
                        break;
                    }
                    ++currentOptionIndex;
                    break;

                case "tcp.options.mss":
                    Assert.AreEqual(TcpOptionType.MaximumSegmentSize, option.OptionType);
                    field.AssertShowDecimal(true);
                    field.AssertNoFields();
                    break;

                case "tcp.options.mss_val":
                    field.AssertShowDecimal(((TcpOptionMaximumSegmentSize)option).MaximumSegmentSize);
                    field.AssertNoFields();
                    ++currentOptionIndex;
                    break;

                case "tcp.options.echo":
                    Assert.IsTrue(option is TcpOptionEchoReply || option is TcpOptionEcho);
                    field.AssertShowDecimal(1);
                    field.AssertNoFields();
                    break;

                case "tcp.options.cc":
                    Assert.IsTrue(option is TcpOptionConnectionCountBase);
                    field.AssertShowDecimal(1);
                    field.AssertNoFields();
                    break;

                case "tcp.options.scps.vector":
                    Assert.AreEqual((TcpOptionType)20, option.OptionType);
                    if (field.Show() == "0")
                    {
                        ++currentOptionIndex;
                    }
                    ++currentOptionIndex;
                    break;

                case "tcp.options.scps":
                    Assert.AreEqual((TcpOptionType)20, option.OptionType);
                    Assert.IsFalse(field.Fields().Any());
                    break;

                case "tcp.options.snack":     // TODO: Support Selective Negative Acknowledgements.
                case "tcp.options.snack.offset":
                case "tcp.options.snack.size":
                    Assert.AreEqual(TcpOptionType.SelectiveNegativeAcknowledgements, option.OptionType);
                    field.AssertNoFields();
                    break;

                case "tcp.options.sack_perm":
                    Assert.AreEqual(TcpOptionType.SelectiveAcknowledgmentPermitted, option.OptionType);
                    field.AssertNoFields();
                    ++currentOptionIndex;
                    break;

                case "tcp.options.rvbd.probe":
                    Assert.AreEqual((TcpOptionType)76, option.OptionType);
                    // TODO: Support Riverbed.
                    ++currentOptionIndex;
                    break;

                case "tcp.options.rvbd.trpy":
                    Assert.AreEqual((TcpOptionType)78, option.OptionType);
                    // TODO: Support Riverbed.
                    ++currentOptionIndex;
                    break;

                default:
                    throw new InvalidOperationException("Invalid tcp options field " + field.Name());
                }
            }
        }
        private static void CompareTcpOptions(XElement element, TcpOptions options)
        {
            int currentOptionIndex = 0;

            foreach (var field in element.Fields())
            {
                if (field.Name() == "_ws.expert")
                {
                    continue;
                }
                if (currentOptionIndex >= options.Count)
                {
                    Assert.IsFalse(options.IsValid, "Options IsValid");
                    Assert.IsTrue(
                        field.Show().StartsWith("Unknown (0x09) ") || // Unknown in Wireshark but known (and invalid) in Pcap.Net.
                        field.Show().StartsWith("Unknown (0x0a) ") || // Unknown in Wireshark but known (and invalid) in Pcap.Net.
                        field.Show().StartsWith("Unknown (0x19) ") || // Unknown in Wireshark but known (and invalid) in Pcap.Net.
                        field.Show().StartsWith("Unknown (0x2d) ") || // Unknown in Wireshark and unknown and invalid in Pcap.Net.
                        field.Show().StartsWith("Unknown (0xa9) ") || // Unknown in Wireshark and unknown and invalid in Pcap.Net.
                        field.Show().StartsWith("Echo reply (with option length = ") ||
                        field.Show().Contains("bytes says option goes past end of options") ||
                        field.Show().Contains(") (with too-short option length = ") ||
                        field.Show().EndsWith(" (length byte past end of options)"),
                        "Options show: " + field.Show());
                    Assert.AreEqual(options.Count, currentOptionIndex, "Options Count");
                    return;
                }

                TcpOption option = options[currentOptionIndex];
                switch (field.Name())
                {
                case "":
                    switch (option.OptionType)
                    {
                    case TcpOptionType.WindowScale:
                        TcpOptionWindowScale windowScale = (TcpOptionWindowScale)option;
                        byte scaleFactorLog = windowScale.ScaleFactorLog;
                        field.AssertShow(string.Format("Window scale: {0} (multiply by {1})", scaleFactorLog, (1L << (scaleFactorLog % 32))));
                        foreach (var subField in field.Fields())
                        {
                            if (HandleOptionCommonFields(subField, option))
                            {
                                continue;
                            }
                            switch (subField.Name())
                            {
                            case "tcp.options.wscale.shift":
                                subField.AssertShowDecimal(windowScale.ScaleFactorLog);
                                break;

                            case "tcp.options.wscale.multiplier":
                                subField.AssertShowDecimal(1L << (windowScale.ScaleFactorLog % 32));
                                break;

                            default:
                                throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                            }
                        }
                        break;

                    case TcpOptionType.SelectiveAcknowledgment:
                        var selectiveAcknowledgmentOption = (TcpOptionSelectiveAcknowledgment)option;
                        IEnumerable <TcpOptionSelectiveAcknowledgmentBlock> blocks = selectiveAcknowledgmentOption.Blocks;
                        field.AssertShow("SACK:" + (blocks.Count() == 0
                                                                ? string.Empty
                                                                : ((TcpOptionSelectiveAcknowledgment)option).Blocks.SequenceToString(" ", " ")));
                        int blockIndex = 0;
                        foreach (var subField in field.Fields())
                        {
                            if (HandleOptionCommonFields(subField, option))
                            {
                                continue;
                            }
                            subField.AssertNoFields();
                            switch (subField.Name())
                            {
                            case "tcp.options.sack":
                                subField.AssertShowDecimal(true);
                                break;

                            case "tcp.options.sack_le":
                                subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks[blockIndex].LeftEdge);
                                break;

                            case "tcp.options.sack_re":
                                subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks[blockIndex].RightEdge);
                                ++blockIndex;
                                break;

                            case "tcp.options.sack.count":
                                subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks.Count);
                                break;

                            default:
                                throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                            }
                        }
                        break;

                    case TcpOptionType.Timestamp:
                        var timestampOption = (TcpOptionTimestamp)option;
                        field.AssertShow("Timestamps: TSval " + timestampOption.TimestampValue + ", TSecr " + timestampOption.TimestampEchoReply);
                        foreach (var subField in field.Fields())
                        {
                            if (HandleOptionCommonFields(subField, option))
                            {
                                continue;
                            }
                            subField.AssertNoFields();
                            switch (subField.Name())
                            {
                            case "tcp.options.timestamp.tsval":
                                subField.AssertShowDecimal(timestampOption.TimestampValue);
                                break;

                            case "tcp.options.timestamp.tsecr":
                                subField.AssertShowDecimal(timestampOption.TimestampEchoReply);
                                break;

                            default:
                                throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                            }
                        }
                        break;

                    case TcpOptionType.ConnectionCount:
                        field.AssertShow("CC: " + ((TcpOptionConnectionCount)option).ConnectionCount);
                        foreach (var subField in field.Fields())
                        {
                            if (HandleOptionCommonFields(subField, option))
                            {
                                continue;
                            }
                            subField.AssertNoFields();
                            switch (subField.Name())
                            {
                            default:
                                throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                            }
                        }
                        break;

                    case TcpOptionType.Echo:
                        field.AssertShow("Echo: " + ((TcpOptionEcho)option).Info);
                        foreach (var subField in field.Fields())
                        {
                            if (HandleOptionCommonFields(subField, option))
                            {
                                continue;
                            }
                            subField.AssertNoFields();
                            switch (subField.Name())
                            {
                            default:
                                throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                            }
                        }
                        break;

                    case TcpOptionType.ConnectionCountNew:
                        field.AssertShow("CC.NEW: " + ((TcpOptionConnectionCountNew)option).ConnectionCount);
                        foreach (var subField in field.Fields())
                        {
                            if (HandleOptionCommonFields(subField, option))
                            {
                                continue;
                            }
                            subField.AssertNoFields();
                            switch (subField.Name())
                            {
                            default:
                                throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                            }
                        }
                        break;

                    case TcpOptionType.EndOfOptionList:
                        field.AssertShow("End of Option List (EOL)");
                        foreach (var subField in field.Fields())
                        {
                            if (HandleOptionCommonFields(subField, option))
                            {
                                continue;
                            }
                            switch (subField.Name())
                            {
                            default:
                                subField.AssertNoFields();
                                throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                            }
                        }
                        break;

                    case TcpOptionType.ConnectionCountEcho:
                        field.AssertShow("CC.ECHO: " + ((TcpOptionConnectionCountEcho)option).ConnectionCount);
                        foreach (var subField in field.Fields())
                        {
                            if (HandleOptionCommonFields(subField, option))
                            {
                                continue;
                            }
                            subField.AssertNoFields();
                            switch (subField.Name())
                            {
                            default:
                                throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                            }
                        }
                        break;

                    case TcpOptionType.Md5Signature:
                        field.AssertShow("TCP MD5 signature");
                        foreach (var subField in field.Fields())
                        {
                            if (HandleOptionCommonFields(subField, option))
                            {
                                continue;
                            }
                            switch (subField.Name())
                            {
                            case "tcp.options.type":
                                subField.AssertShowDecimal((byte)TcpOptionType.Md5Signature);
                                break;

                            default:
                                subField.AssertNoFields();
                                throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                            }
                        }
                        break;

                    case TcpOptionType.NoOperation:
                        field.AssertShow("No-Operation (NOP)");
                        foreach (var subField in field.Fields())
                        {
                            if (HandleOptionCommonFields(subField, option))
                            {
                                continue;
                            }
                            throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                        }
                        break;

                    case TcpOptionType.EchoReply:
                        field.AssertShow("Echo reply: " + ((TcpOptionEchoReply)option).Info);
                        foreach (var subField in field.Fields())
                        {
                            if (HandleOptionCommonFields(subField, option))
                            {
                                continue;
                            }
                            throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
                        }
                        break;

                    case TcpOptionType.SelectiveAcknowledgmentPermitted:
                        field.AssertShow("SACK permitted");
                        field.AssertNoFields();
                        break;

                    case TcpOptionType.SelectiveNegativeAcknowledgements:         // TODO: Support Selective Negative Acknowledgements.
                        Assert.IsTrue(field.Show().StartsWith("SACK permitted"));
                        field.AssertNoFields();
                        break;

                    case (TcpOptionType)20:
                        // TODO: Support 20.
                        field.AssertShow("SCPS capabilities" + (option.Length >= 4
                                                                            ? string.Empty
                                                                            : " (with option length = " + option.Length + " bytes; should be >= 4)"));
                        break;

                    case (TcpOptionType)22:
                        field.AssertShow("SCPS record boundary (with option length = " + option.Length + " bytes; should be 2)");
                        // TODO: Support 22.
                        break;

                    case (TcpOptionType)23:
                        field.AssertShow("SCPS corruption experienced (with option length = " + option.Length + " bytes; should be 2)");
                        // TODO: Support 23.
                        break;

                    case (TcpOptionType)30:
                        // TODO: Support 30.
                        Assert.IsTrue(field.Show().StartsWith("Multipath TCP"));
                        break;

                    case (TcpOptionType)78:
                        field.AssertShow("Riverbed Transparency (with option length = " + option.Length + " bytes; should be 16)");
                        // TODO: Support 78 - Support Riverbed.
                        break;

                    case TcpOptionType.PartialOrderConnectionPermitted:         // 9.
                    case TcpOptionType.PartialOrderServiceProfile:              // 10.
                    case TcpOptionType.AlternateChecksumRequest:                // 14.
                    case TcpOptionType.AlternateChecksumData:                   // 15.
                    case TcpOptionType.Mood:                                    // 25.
                    case TcpOptionType.TcpAuthentication:                       // 29.
                        field.AssertShow(string.Format("Unknown (0x{0}) ({1} bytes)", ((byte)option.OptionType).ToString("x2"), option.Length));
                        field.AssertNoFields();
                        break;

                    default:
                        field.AssertNoFields();
                        field.AssertShow("Unknown (0x" + ((byte)option.OptionType).ToString("x") + ") (" + option.Length + " bytes)");
                        break;
                    }
                    ++currentOptionIndex;
                    break;

                case "tcp.options.mss":
                    Assert.AreEqual(TcpOptionType.MaximumSegmentSize, option.OptionType);
                    var maximumSegmentSize = (TcpOptionMaximumSegmentSize)option;
                    field.AssertShowname("Maximum segment size: " + maximumSegmentSize.MaximumSegmentSize + " bytes");
                    foreach (var subField in field.Fields())
                    {
                        if (HandleOptionCommonFields(subField, option))
                        {
                            continue;
                        }
                        subField.AssertNoFields();
                        switch (subField.Name())
                        {
                        case "tcp.options.mss_val":
                            subField.AssertShowDecimal(maximumSegmentSize.MaximumSegmentSize);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name());
                        }
                    }
                    ++currentOptionIndex;
                    break;

                case "tcp.options.mss_val":
                    field.AssertShowDecimal(((TcpOptionMaximumSegmentSize)option).MaximumSegmentSize);
                    field.AssertNoFields();
                    ++currentOptionIndex;
                    break;

                case "tcp.options.echo":
                    Assert.IsTrue(option is TcpOptionEchoReply || option is TcpOptionEcho);
                    field.AssertShowDecimal(1);
                    field.AssertNoFields();
                    break;

                case "tcp.options.cc":
                    Assert.IsTrue(option is TcpOptionConnectionCountBase);
                    field.AssertShowDecimal(1);
                    field.AssertNoFields();
                    break;

                case "tcp.options.scps.vector":
                    // TODO: Support 20.
                    Assert.AreEqual((TcpOptionType)20, option.OptionType);
//                        if (field.Show() == "0")
//                            ++currentOptionIndex;
                    ++currentOptionIndex;
                    break;

                case "tcp.options.scps":
                    // TODO: Support 20.
                    Assert.AreEqual((TcpOptionType)20, option.OptionType);
                    Assert.IsFalse(field.Fields().Any());
                    break;

                case "tcp.options.snack":     // TODO: Support Selective Negative Acknowledgements.
                case "tcp.options.snack.offset":
                case "tcp.options.snack.size":
                    Assert.AreEqual(TcpOptionType.SelectiveNegativeAcknowledgements, option.OptionType);
                    field.AssertNoFields();
                    break;

                case "tcp.options.sack_perm":
                    Assert.AreEqual(TcpOptionType.SelectiveAcknowledgmentPermitted, option.OptionType);
                    foreach (var subField in field.Fields())
                    {
                        if (HandleOptionCommonFields(subField, option))
                        {
                            continue;
                        }
                        subField.AssertNoFields();
                        throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name());
                    }
                    ++currentOptionIndex;
                    break;

                case "tcp.options.rvbd.probe":
                    Assert.AreEqual((TcpOptionType)76, option.OptionType);
                    // TODO: Support Riverbed.
                    ++currentOptionIndex;
                    break;

                case "tcp.options.rvbd.trpy":
                    Assert.AreEqual((TcpOptionType)78, option.OptionType);
                    // TODO: Support Riverbed.
                    ++currentOptionIndex;
                    break;

                case "tcp.options.experimental":
                    Assert.IsTrue(new [] { (TcpOptionType)253, (TcpOptionType)254 }.Contains(option.OptionType));
                    // TODO: Support Experimental.
                    ++currentOptionIndex;
                    break;

                default:
                    throw new InvalidOperationException("Invalid tcp options field " + field.Name());
                }
            }
        }
예제 #9
0
        void SendTcpCtrlPacket(uint AcknowledgmentNumber, TcpControlBits CtrlBits, TcpOptions TcpOptions)
        {
            _last_acknowledgment_number = AcknowledgmentNumber;
            EthernetLayer ethernetLayer =
                new EthernetLayer
            {
                Source      = _adapter.MAC,
                Destination = _remote_mac,
                EtherType   = EthernetType.None,   // Will be filled automatically.
            };

            VLanTaggedFrameLayer vlanLayer =
                new VLanTaggedFrameLayer
            {
                PriorityCodePoint        = ClassOfService.Background,
                CanonicalFormatIndicator = false,
                VLanIdentifier           = _adapter.VLAN,
                EtherType = EthernetType.None,
            };

            IpV4Layer ipV4Layer =
                new IpV4Layer
            {
                Source             = _adapter.IP,
                CurrentDestination = _remote_ip,
                Fragmentation      = new IpV4Fragmentation(IpV4FragmentationOptions.DoNotFragment, 0),
                HeaderChecksum     = null, // Will be filled automatically.
                Identification     = _current_ip_id++,
                Options            = IpV4Options.None,
                Protocol           = null, // Will be filled automatically.
                Ttl           = TTL,
                TypeOfService = 0,
            };

            TcpLayer tcpLayer =
                new TcpLayer
            {
                SourcePort           = _local_port,
                DestinationPort      = _remote_port,
                Checksum             = null, // Will be filled automatically.
                SequenceNumber       = _current_sequence_number,
                AcknowledgmentNumber = _last_acknowledgment_number,
                ControlBits          = CtrlBits,
                Window        = _local_tcp_window_size,
                UrgentPointer = 0,
                Options       = TcpOptions
            };

            if (_adapter.VLAN > 1)
            {
                VirtualNetwork.Instance.SendPacket(PacketBuilder.Build(DateTime.Now, ethernetLayer, vlanLayer, ipV4Layer, tcpLayer));
            }
            else
            {
                VirtualNetwork.Instance.SendPacket(PacketBuilder.Build(DateTime.Now, ethernetLayer, ipV4Layer, tcpLayer));
            }

            if (CtrlBits != TcpControlBits.Acknowledgment)
            {
                _current_sequence_number++;
                _next_ack_num = _current_sequence_number;
            }
        }