Commit 12ccada5 authored by Brickner_cp's avatar Brickner_cp

TCP

parent af11fe38
...@@ -39,6 +39,11 @@ namespace PcapDotNet.Core.Test ...@@ -39,6 +39,11 @@ namespace PcapDotNet.Core.Test
TcpOptionTimeStamp timeStampOption = (TcpOptionTimeStamp)option; TcpOptionTimeStamp timeStampOption = (TcpOptionTimeStamp)option;
return "Timestamps: TSval " + timeStampOption.TimeStampValue + ", TSecr " + timeStampOption.TimeStampEchoReply; return "Timestamps: TSval " + timeStampOption.TimeStampValue + ", TSecr " + timeStampOption.TimeStampEchoReply;
case TcpOptionType.PartialOrderServiceProfile:
return "Unknown (0x0a) (3 bytes)";
case TcpOptionType.PartialOrderConnectionPermitted:
return "Unknown (0x09) (2 bytes)";
default: default:
throw new InvalidOperationException("Illegal option type " + option.OptionType); throw new InvalidOperationException("Illegal option type " + option.OptionType);
...@@ -57,6 +62,8 @@ namespace PcapDotNet.Core.Test ...@@ -57,6 +62,8 @@ namespace PcapDotNet.Core.Test
case TcpOptionType.Echo: case TcpOptionType.Echo:
case TcpOptionType.EchoReply: case TcpOptionType.EchoReply:
case TcpOptionType.TimeStamp: case TcpOptionType.TimeStamp:
case TcpOptionType.PartialOrderServiceProfile:
case TcpOptionType.PartialOrderConnectionPermitted:
break; break;
case TcpOptionType.SelectiveAcknowledgment: case TcpOptionType.SelectiveAcknowledgment:
......
...@@ -251,15 +251,17 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -251,15 +251,17 @@ namespace PcapDotNet.Packets.TestUtils
impossibleOptionTypes.Add(TcpOptionType.EchoReply); impossibleOptionTypes.Add(TcpOptionType.EchoReply);
if (maximumOptionLength < TcpOptionTimeStamp.OptionLength) if (maximumOptionLength < TcpOptionTimeStamp.OptionLength)
impossibleOptionTypes.Add(TcpOptionType.TimeStamp); impossibleOptionTypes.Add(TcpOptionType.TimeStamp);
if (maximumOptionLength < TcpOptionPartialOrderServiceProfile.OptionLength)
impossibleOptionTypes.Add(TcpOptionType.PartialOrderServiceProfile);
if (maximumOptionLength < TcpOptionPartialOrderConnectionPermitted.OptionLength)
impossibleOptionTypes.Add(TcpOptionType.PartialOrderConnectionPermitted);
impossibleOptionTypes.Add(TcpOptionType.AlternateChecksumData); impossibleOptionTypes.Add(TcpOptionType.AlternateChecksumData);
impossibleOptionTypes.Add(TcpOptionType.AlternateChecksumRequest); impossibleOptionTypes.Add(TcpOptionType.AlternateChecksumRequest);
impossibleOptionTypes.Add(TcpOptionType.Cc); impossibleOptionTypes.Add(TcpOptionType.Cc);
impossibleOptionTypes.Add(TcpOptionType.CcEcho); impossibleOptionTypes.Add(TcpOptionType.CcEcho);
impossibleOptionTypes.Add(TcpOptionType.CcNew); impossibleOptionTypes.Add(TcpOptionType.CcNew);
impossibleOptionTypes.Add(TcpOptionType.Md5Signature); impossibleOptionTypes.Add(TcpOptionType.Md5Signature);
impossibleOptionTypes.Add(TcpOptionType.PartialOrderConnectionPermitted);
impossibleOptionTypes.Add(TcpOptionType.PartialOrderServiceProfile);
impossibleOptionTypes.Add(TcpOptionType.QuickStartResponse); impossibleOptionTypes.Add(TcpOptionType.QuickStartResponse);
impossibleOptionTypes.Add(TcpOptionType.UserTimeout); impossibleOptionTypes.Add(TcpOptionType.UserTimeout);
...@@ -297,6 +299,12 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -297,6 +299,12 @@ namespace PcapDotNet.Packets.TestUtils
case TcpOptionType.TimeStamp: case TcpOptionType.TimeStamp:
return new TcpOptionTimeStamp(random.NextUInt(), random.NextUInt()); return new TcpOptionTimeStamp(random.NextUInt(), random.NextUInt());
case TcpOptionType.PartialOrderServiceProfile:
return new TcpOptionPartialOrderServiceProfile(random.NextBool(), random.NextBool());
case TcpOptionType.PartialOrderConnectionPermitted:
return new TcpOptionPartialOrderConnectionPermitted();
default: default:
throw new InvalidOperationException("optionType = " + optionType); throw new InvalidOperationException("optionType = " + optionType);
} }
......
...@@ -113,6 +113,8 @@ ...@@ -113,6 +113,8 @@
<Compile Include="Transport\TcpOptionEcho.cs" /> <Compile Include="Transport\TcpOptionEcho.cs" />
<Compile Include="Transport\TcpOptionEchoReply.cs" /> <Compile Include="Transport\TcpOptionEchoReply.cs" />
<Compile Include="Transport\TcpOptionMaximumSegmentSize.cs" /> <Compile Include="Transport\TcpOptionMaximumSegmentSize.cs" />
<Compile Include="Transport\TcpOptionPartialOrderConnectionPermitted.cs" />
<Compile Include="Transport\TcpOptionPartialOrderServiceProfile.cs" />
<Compile Include="Transport\TcpOptions.cs" /> <Compile Include="Transport\TcpOptions.cs" />
<Compile Include="Transport\TcpOptionSelectiveAcknowledgment.cs" /> <Compile Include="Transport\TcpOptionSelectiveAcknowledgment.cs" />
<Compile Include="Transport\TcpOptionSelectiveAcknowledgmentBlock.cs" /> <Compile Include="Transport\TcpOptionSelectiveAcknowledgmentBlock.cs" />
......
using System;
namespace PcapDotNet.Packets.Transport
{
/// <summary>
/// TCP POC-permitted Option (RFC 1693)
/// +-----------+-------------+
/// | Kind=9 | Length=2 |
/// +-----------+-------------+
/// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.PartialOrderConnectionPermitted)]
public class TcpOptionPartialOrderConnectionPermitted : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionPartialOrderConnectionPermitted>
{
/// <summary>
/// The number of bytes this option take.
/// </summary>
public const int OptionLength = 2;
public const int OptionValueLength = OptionLength - OptionHeaderLength;
public TcpOptionPartialOrderConnectionPermitted()
: base(TcpOptionType.PartialOrderConnectionPermitted)
{
}
/// <summary>
/// The number of bytes this option will take.
/// </summary>
public override int Length
{
get { return OptionLength; }
}
/// <summary>
/// True iff this option may appear at most once in a datagram.
/// </summary>
public override bool IsAppearsAtMostOnce
{
get { return true; }
}
public bool Equals(TcpOptionPartialOrderConnectionPermitted other)
{
return other != null;
}
public override bool Equals(TcpOption other)
{
return Equals(other as TcpOptionPartialOrderConnectionPermitted);
}
/// <summary>
/// Tries to read the option from a buffer starting from the option value (after the type and length).
/// </summary>
/// <param name="buffer">The buffer to read the option from.</param>
/// <param name="offset">The offset to the first byte to read the buffer. Will be incremented by the number of bytes read.</param>
/// <param name="valueLength">The number of bytes the option value should take according to the length field that was already read.</param>
/// <returns>On success - the complex option read. On failure - null.</returns>
public Option CreateInstance(byte[] buffer, ref int offset, byte valueLength)
{
if (valueLength != OptionValueLength)
return null;
return _instance;
}
private static readonly TcpOptionPartialOrderConnectionPermitted _instance = new TcpOptionPartialOrderConnectionPermitted();
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Transport
{
/// <summary>
/// TCP POC-service-profile Option (RFC 1693).
///
/// 1 bit 1 bit 6 bits
/// +----------+----------+------------+----------+--------+
/// | Kind=10 | Length=3 | Start_flag | End_flag | Filler |
/// +----------+----------+------------+----------+--------+
///
/// Contains two 1-bit flags necessary to handle the case where the service profile does not fit in a single TCP segment.
/// The "Start_flag" indicates that the information in the data section represents the beginning of the service profile
/// and the "End_flag" represents the converse.
/// For service profiles which fit completely in a single segment, both flags will be set to 1.
/// Otherwise, the Start_flag is set in the initial segment and the End_flag in the final segment
/// allowing the peer entity to reconstrcut the entire service profile (using the normal sequence numbers in the segment header).
/// The "Filler" field serves merely to complete the third byte of the option.
/// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.PartialOrderServiceProfile)]
public class TcpOptionPartialOrderServiceProfile : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionPartialOrderServiceProfile>
{
private const byte NoFlags = 0x00;
private const byte StartFlag = 0x80;
private const byte EndFlag = 0x40;
/// <summary>
/// The number of bytes this option take.
/// </summary>
public const int OptionLength = 3;
public const int OptionValueLength = OptionLength - OptionHeaderLength;
public TcpOptionPartialOrderServiceProfile(bool isStart, bool isEnd)
: base(TcpOptionType.PartialOrderServiceProfile)
{
IsStart = isStart;
IsEnd = isEnd;
}
public TcpOptionPartialOrderServiceProfile()
: this(true, true)
{
}
public bool IsStart { get; private set; }
public bool IsEnd { get; private set; }
/// <summary>
/// The number of bytes this option will take.
/// </summary>
public override int Length
{
get { return OptionLength; }
}
/// <summary>
/// True iff this option may appear at most once in a datagram.
/// </summary>
public override bool IsAppearsAtMostOnce
{
get { return true; }
}
public bool Equals(TcpOptionPartialOrderServiceProfile other)
{
if (other == null)
return false;
return (IsStart == other.IsStart) &&
(IsEnd == other.IsEnd);
}
public override bool Equals(TcpOption other)
{
return Equals(other as TcpOptionPartialOrderServiceProfile);
}
/// <summary>
/// Tries to read the option from a buffer starting from the option value (after the type and length).
/// </summary>
/// <param name="buffer">The buffer to read the option from.</param>
/// <param name="offset">The offset to the first byte to read the buffer. Will be incremented by the number of bytes read.</param>
/// <param name="valueLength">The number of bytes the option value should take according to the length field that was already read.</param>
/// <returns>On success - the complex option read. On failure - null.</returns>
public Option CreateInstance(byte[] buffer, ref int offset, byte valueLength)
{
if (valueLength != OptionValueLength)
return null;
byte data = buffer.ReadByte(ref offset);
return new TcpOptionPartialOrderServiceProfile((data & StartFlag) == StartFlag, (data & EndFlag) == EndFlag);
}
internal override void Write(byte[] buffer, ref int offset)
{
base.Write(buffer, ref offset);
byte data = (byte)((IsStart ? StartFlag : NoFlags) | (IsEnd ? EndFlag : NoFlags));
buffer.Write(ref offset, data);
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment