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); }
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); }
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()); } } }
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()); } } }
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()); } } }
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; } }