Commit 1830bbda authored by Brickner_cp's avatar Brickner_cp

TCP

parent 4c59dc64
...@@ -4,15 +4,15 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -4,15 +4,15 @@ namespace PcapDotNet.Packets.IpV4
/// This interface is used to create all complex options. /// This interface is used to create all complex options.
/// Every complex option should implement such a factory to create itself from a buffer. /// Every complex option should implement such a factory to create itself from a buffer.
/// </summary> /// </summary>
internal interface IIpv4OptionComplexFactory // internal interface IIpv4OptionComplexFactory
{ // {
/// <summary> // /// <summary>
/// Tries to read the option from a buffer starting from the option value (after the type and length). // /// Tries to read the option from a buffer starting from the option value (after the type and length).
/// </summary> // /// </summary>
/// <param name="buffer">The buffer to read the option from.</param> // /// <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="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> // /// <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> // /// <returns>On success - the complex option read. On failure - null.</returns>
IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength); // IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength);
} // }
} }
\ No newline at end of file
...@@ -93,8 +93,8 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -93,8 +93,8 @@ namespace PcapDotNet.Packets.IpV4
case IpV4OptionType.NoOperation: case IpV4OptionType.NoOperation:
return Nop; return Nop;
default: default:
return IpV4OptionComplex.ReadOptionComplex(optionType, buffer, ref offset, offsetEnd - offset); return OptionComplexFactory<IpV4OptionType>.Read(optionType, buffer, ref offset, offsetEnd - offset);
} }
} }
......
...@@ -31,8 +31,8 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -31,8 +31,8 @@ namespace PcapDotNet.Packets.IpV4
/// LEVEL AUTHORITY /// LEVEL AUTHORITY
/// FLAGS /// FLAGS
/// </summary> /// </summary>
[IpV4OptionTypeRegistration(IpV4OptionType.BasicSecurity)] [OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.BasicSecurity)]
public class IpV4OptionBasicSecurity : IpV4OptionComplex, IIpv4OptionComplexFactory, IEquatable<IpV4OptionBasicSecurity> public class IpV4OptionBasicSecurity : IpV4OptionComplex, IOptionComplexFactory, IEquatable<IpV4OptionBasicSecurity>
{ {
/// <summary> /// <summary>
/// The minimum number of bytes this option take. /// The minimum number of bytes this option take.
...@@ -169,7 +169,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -169,7 +169,7 @@ namespace PcapDotNet.Packets.IpV4
/// <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="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> /// <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> /// <returns>On success - the complex option read. On failure - null.</returns>
public IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength) public Option CreateInstance(byte[] buffer, ref int offset, byte valueLength)
{ {
if (valueLength < OptionValueMinimumLength) if (valueLength < OptionValueMinimumLength)
return null; return null;
......
...@@ -16,32 +16,6 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -16,32 +16,6 @@ namespace PcapDotNet.Packets.IpV4
/// </summary> /// </summary>
public const int OptionHeaderLength = 2; public const int OptionHeaderLength = 2;
internal sealed class IpV4OptionTypeRegistrationAttribute : Attribute
{
public IpV4OptionTypeRegistrationAttribute(IpV4OptionType optionType)
{
OptionType = optionType;
}
public IpV4OptionType OptionType { get; set; }
}
internal static IpV4OptionComplex ReadOptionComplex(IpV4OptionType optionType, byte[] buffer, ref int offset, int length)
{
if (length < 1)
return null;
byte optionLength = buffer[offset++];
if (length + 1 < optionLength)
return null;
byte optionValueLength = (byte)(optionLength - OptionHeaderLength);
IIpv4OptionComplexFactory prototype;
if (!_complexOptions.TryGetValue(optionType, out prototype))
return null;
return prototype.CreateInstance(buffer, ref offset, optionValueLength);
}
internal override void Write(byte[] buffer, ref int offset) internal override void Write(byte[] buffer, ref int offset)
{ {
base.Write(buffer, ref offset); base.Write(buffer, ref offset);
...@@ -55,31 +29,5 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -55,31 +29,5 @@ namespace PcapDotNet.Packets.IpV4
: base(type) : base(type)
{ {
} }
private static Dictionary<IpV4OptionType, IIpv4OptionComplexFactory> InitializeComplexOptions()
{
var complexOptions =
from type in Assembly.GetExecutingAssembly().GetTypes()
where typeof(IIpv4OptionComplexFactory).IsAssignableFrom(type) &&
GetRegistrationAttribute(type) != null
select new
{
GetRegistrationAttribute(type).OptionType,
Option = (IIpv4OptionComplexFactory)Activator.CreateInstance(type)
};
return complexOptions.ToDictionary(option => option.OptionType, option => option.Option);
}
private static IpV4OptionTypeRegistrationAttribute GetRegistrationAttribute(Type type)
{
var registraionAttributes = type.GetCustomAttributes(typeof(IpV4OptionTypeRegistrationAttribute), false);
if (registraionAttributes.Length == 0)
return null;
return ((IpV4OptionTypeRegistrationAttribute)registraionAttributes[0]);
}
private static readonly Dictionary<IpV4OptionType, IIpv4OptionComplexFactory> _complexOptions = InitializeComplexOptions();
} }
} }
\ No newline at end of file
...@@ -42,8 +42,8 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -42,8 +42,8 @@ namespace PcapDotNet.Packets.IpV4
/// Must be copied on fragmentation. /// Must be copied on fragmentation.
/// Appears at most once in a datagram. /// Appears at most once in a datagram.
/// </summary> /// </summary>
[IpV4OptionTypeRegistration(IpV4OptionType.LooseSourceRouting)] [OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.LooseSourceRouting)]
public class IpV4OptionLooseSourceRouting : IpV4OptionRoute, IIpv4OptionComplexFactory public class IpV4OptionLooseSourceRouting : IpV4OptionRoute, IOptionComplexFactory
{ {
/// <summary> /// <summary>
/// Constructs the option from the given values. /// Constructs the option from the given values.
...@@ -70,7 +70,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -70,7 +70,7 @@ namespace PcapDotNet.Packets.IpV4
/// <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="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> /// <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> /// <returns>On success - the complex option read. On failure - null.</returns>
public IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength) public Option CreateInstance(byte[] buffer, ref int offset, byte valueLength)
{ {
IpV4Address[] addresses; IpV4Address[] addresses;
byte pointedAddressIndex; byte pointedAddressIndex;
......
...@@ -15,8 +15,8 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -15,8 +15,8 @@ namespace PcapDotNet.Packets.IpV4
/// | QS Nonce | R | /// | QS Nonce | R |
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/// </summary> /// </summary>
[IpV4OptionTypeRegistration(IpV4OptionType.QuickStart)] [OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.QuickStart)]
public class IpV4OptionQuickStart : IpV4OptionComplex, IIpv4OptionComplexFactory, IEquatable<IpV4OptionQuickStart> public class IpV4OptionQuickStart : IpV4OptionComplex, IOptionComplexFactory, IEquatable<IpV4OptionQuickStart>
{ {
/// <summary> /// <summary>
/// The number of bytes this option take. /// The number of bytes this option take.
...@@ -220,7 +220,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -220,7 +220,7 @@ namespace PcapDotNet.Packets.IpV4
/// <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="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> /// <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> /// <returns>On success - the complex option read. On failure - null.</returns>
public IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength) public Option CreateInstance(byte[] buffer, ref int offset, byte valueLength)
{ {
if (valueLength != OptionValueLength) if (valueLength != OptionValueLength)
return null; return null;
......
...@@ -39,8 +39,8 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -39,8 +39,8 @@ namespace PcapDotNet.Packets.IpV4
/// Not copied on fragmentation, goes in first fragment only. /// Not copied on fragmentation, goes in first fragment only.
/// Appears at most once in a datagram. /// Appears at most once in a datagram.
/// </summary> /// </summary>
[IpV4OptionTypeRegistration(IpV4OptionType.RecordRoute)] [OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.RecordRoute)]
public class IpV4OptionRecordRoute : IpV4OptionRoute, IIpv4OptionComplexFactory public class IpV4OptionRecordRoute : IpV4OptionRoute, IOptionComplexFactory
{ {
/// <summary> /// <summary>
/// Constructs the option from the given values. /// Constructs the option from the given values.
...@@ -77,7 +77,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -77,7 +77,7 @@ namespace PcapDotNet.Packets.IpV4
/// <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="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> /// <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> /// <returns>On success - the complex option read. On failure - null.</returns>
public IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength) public Option CreateInstance(byte[] buffer, ref int offset, byte valueLength)
{ {
IpV4Address[] addresses; IpV4Address[] addresses;
byte pointedAddressIndex; byte pointedAddressIndex;
......
...@@ -23,8 +23,8 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -23,8 +23,8 @@ namespace PcapDotNet.Packets.IpV4
/// |10010100|00000100| 2 octet value | /// |10010100|00000100| 2 octet value |
/// +--------+--------+--------+--------+ /// +--------+--------+--------+--------+
/// </summary> /// </summary>
[IpV4OptionTypeRegistration(IpV4OptionType.RouterAlert)] [OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.RouterAlert)]
public class IpV4OptionRouterAlert : IpV4OptionComplex, IIpv4OptionComplexFactory, IEquatable<IpV4OptionRouterAlert> public class IpV4OptionRouterAlert : IpV4OptionComplex, IOptionComplexFactory, IEquatable<IpV4OptionRouterAlert>
{ {
/// <summary> /// <summary>
/// The number of bytes this option take. /// The number of bytes this option take.
...@@ -111,7 +111,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -111,7 +111,7 @@ namespace PcapDotNet.Packets.IpV4
/// <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="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> /// <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> /// <returns>On success - the complex option read. On failure - null.</returns>
public IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength) public Option CreateInstance(byte[] buffer, ref int offset, byte valueLength)
{ {
if (valueLength != OptionHeaderLength) if (valueLength != OptionHeaderLength)
return null; return null;
......
...@@ -14,19 +14,14 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -14,19 +14,14 @@ namespace PcapDotNet.Packets.IpV4
/// Must be copied on fragmentation. /// Must be copied on fragmentation.
/// Appears at most once in a datagram. /// Appears at most once in a datagram.
/// </summary> /// </summary>
[IpV4OptionTypeRegistration(IpV4OptionType.StreamIdentifier)] [OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.StreamIdentifier)]
public class IpV4OptionStreamIdentifier : IpV4OptionComplex, IIpv4OptionComplexFactory, IEquatable<IpV4OptionStreamIdentifier> public class IpV4OptionStreamIdentifier : IpV4OptionComplex, IOptionComplexFactory, IEquatable<IpV4OptionStreamIdentifier>
{ {
/// <summary> /// <summary>
/// The number of bytes this option take. /// The number of bytes this option take.
/// </summary> /// </summary>
public const int OptionLength = 4; public const int OptionLength = 4;
/// <summary>
/// The number of bytes this option's value take.
/// </summary>
public const int OptionValueLength = OptionLength - OptionHeaderLength;
/// <summary> /// <summary>
/// Create the option according to the given identifier. /// Create the option according to the given identifier.
/// </summary> /// </summary>
...@@ -102,7 +97,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -102,7 +97,7 @@ namespace PcapDotNet.Packets.IpV4
/// <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="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> /// <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> /// <returns>On success - the complex option read. On failure - null.</returns>
public IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength) public Option CreateInstance(byte[] buffer, ref int offset, byte valueLength)
{ {
if (valueLength != OptionHeaderLength) if (valueLength != OptionHeaderLength)
return null; return null;
......
...@@ -43,8 +43,8 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -43,8 +43,8 @@ namespace PcapDotNet.Packets.IpV4
/// Must be copied on fragmentation. /// Must be copied on fragmentation.
/// Appears at most once in a datagram. /// Appears at most once in a datagram.
/// </summary> /// </summary>
[IpV4OptionTypeRegistration(IpV4OptionType.StrictSourceRouting)] [OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.StrictSourceRouting)]
public class IpV4OptionStrictSourceRouting : IpV4OptionRoute, IIpv4OptionComplexFactory public class IpV4OptionStrictSourceRouting : IpV4OptionRoute, IOptionComplexFactory
{ {
/// <summary> /// <summary>
/// Create the option according to the given values. /// Create the option according to the given values.
...@@ -69,7 +69,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -69,7 +69,7 @@ namespace PcapDotNet.Packets.IpV4
/// <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="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> /// <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> /// <returns>On success - the complex option read. On failure - null.</returns>
public IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength) public Option CreateInstance(byte[] buffer, ref int offset, byte valueLength)
{ {
IpV4Address[] addresses; IpV4Address[] addresses;
byte pointedAddressIndex; byte pointedAddressIndex;
......
...@@ -52,10 +52,10 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -52,10 +52,10 @@ namespace PcapDotNet.Packets.IpV4
/// </summary> /// </summary>
public abstract class IpV4OptionTimestamp : IpV4OptionComplex, IEquatable<IpV4OptionTimestamp> public abstract class IpV4OptionTimestamp : IpV4OptionComplex, IEquatable<IpV4OptionTimestamp>
{ {
[IpV4OptionTypeRegistration(IpV4OptionType.InternetTimestamp)] [OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.InternetTimestamp)]
internal class IpV4OptionTimestampFactory : IIpv4OptionComplexFactory internal class IpV4OptionTimestampFactory : IOptionComplexFactory
{ {
public IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength) public Option CreateInstance(byte[] buffer, ref int offset, byte valueLength)
{ {
if (valueLength < OptionValueMinimumLength || valueLength % 4 != 2) if (valueLength < OptionValueMinimumLength || valueLength % 4 != 2)
return null; return null;
......
...@@ -24,8 +24,8 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -24,8 +24,8 @@ namespace PcapDotNet.Packets.IpV4
/// C (class): 2 (Debugging and Measurement) /// C (class): 2 (Debugging and Measurement)
/// Number: 18 (F+C+Number = 82) /// Number: 18 (F+C+Number = 82)
/// </summary> /// </summary>
[IpV4OptionTypeRegistration(IpV4OptionType.TraceRoute)] [OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.TraceRoute)]
public class IpV4OptionTraceRoute : IpV4OptionComplex, IIpv4OptionComplexFactory, IEquatable<IpV4OptionTraceRoute> public class IpV4OptionTraceRoute : IpV4OptionComplex, IOptionComplexFactory, IEquatable<IpV4OptionTraceRoute>
{ {
/// <summary> /// <summary>
/// The number of bytes this option take. /// The number of bytes this option take.
...@@ -173,7 +173,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -173,7 +173,7 @@ namespace PcapDotNet.Packets.IpV4
/// <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="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> /// <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> /// <returns>On success - the complex option read. On failure - null.</returns>
public IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength) public Option CreateInstance(byte[] buffer, ref int offset, byte valueLength)
{ {
if (valueLength != OptionValueLength) if (valueLength != OptionValueLength)
return null; return null;
......
using System;
namespace PcapDotNet.Packets
{
internal sealed class OptionTypeRegistrationAttribute : Attribute
{
public OptionTypeRegistrationAttribute(Type optionTypeType, object optionType)
{
OptionTypeType = optionTypeType;
OptionType = optionType;
}
public object OptionType { get; private set; }
public Type OptionTypeType { get; private set; }
}
}
\ No newline at end of file
...@@ -109,8 +109,11 @@ ...@@ -109,8 +109,11 @@
<Compile Include="Transport\TcpDatagram.cs" /> <Compile Include="Transport\TcpDatagram.cs" />
<Compile Include="Transport\TcpFlags.cs" /> <Compile Include="Transport\TcpFlags.cs" />
<Compile Include="Transport\TcpOption.cs" /> <Compile Include="Transport\TcpOption.cs" />
<Compile Include="Transport\TcpOptionComplex.cs" />
<Compile Include="Transport\TcpOptionMaximumSegmentSize.cs" />
<Compile Include="Transport\TcpOptions.cs" /> <Compile Include="Transport\TcpOptions.cs" />
<Compile Include="Transport\TcpOptionSimple.cs" /> <Compile Include="Transport\TcpOptionSimple.cs" />
<Compile Include="Transport\TcpOptionType.cs" />
<Compile Include="Transport\TransportDatagram.cs" /> <Compile Include="Transport\TransportDatagram.cs" />
<Compile Include="Transport\UdpDatagram.cs" /> <Compile Include="Transport\UdpDatagram.cs" />
</ItemGroup> </ItemGroup>
......
...@@ -2,13 +2,7 @@ using System; ...@@ -2,13 +2,7 @@ using System;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
public enum TcpOptionType : byte public abstract class TcpOption : Option, IEquatable<TcpOption>
{
EndOfOptionList = 0,
NoOperation = 1
}
public abstract class TcpOption : Option
{ {
public static TcpOption End public static TcpOption End
{ {
...@@ -25,12 +19,30 @@ namespace PcapDotNet.Packets.Transport ...@@ -25,12 +19,30 @@ namespace PcapDotNet.Packets.Transport
OptionType = optionType; OptionType = optionType;
} }
public TcpOptionType OptionType { get; private set; }
public override bool Equivalent(Option other) public override bool Equivalent(Option other)
{ {
return OptionType == ((TcpOption)other).OptionType; return OptionType == ((TcpOption)other).OptionType;
} }
public TcpOptionType OptionType { get; private set; } /// <summary>
/// Checks if the two options are exactly the same - including type and value.
/// </summary>
public virtual bool Equals(TcpOption other)
{
if (other == null)
return false;
return Equivalent(other);
}
/// <summary>
/// Checks if the two options are exactly the same - including type and value.
/// </summary>
public override bool Equals(object obj)
{
return Equals(obj as TcpOption);
}
internal override Option Read(byte[] buffer, ref int offset, int length) internal override Option Read(byte[] buffer, ref int offset, int length)
{ {
......
namespace PcapDotNet.Packets.Transport
{
public abstract class TcpOptionComplex : TcpOption
{
public const int OptionHeaderLength = 2;
internal override void Write(byte[] buffer, ref int offset)
{
base.Write(buffer, ref offset);
buffer[offset++] = (byte)Length;
}
protected TcpOptionComplex(TcpOptionType type)
: base(type)
{
}
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Transport
{
/// <summary>
/// Maximum Segment Size (RFC 793)
/// +--------+--------+---------+--------+
/// |00000010|00000100| max seg size |
/// +--------+--------+---------+--------+
/// Kind=2 Length=4
///
/// If this option is present, then it communicates the maximum receive segment size at the TCP which sends this segment.
/// This field must only be sent in the initial connection request (i.e., in segments with the SYN control bit set).
/// If this option is not used, any segment size is allowed.
/// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.MaximumSegmentSize)]
public class TcpOptionMaximumSegmentSize : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionMaximumSegmentSize>
{
/// <summary>
/// The number of bytes this option take.
/// </summary>
public const int OptionLength = 4;
public TcpOptionMaximumSegmentSize(ushort maximumSegmentSize)
: base(TcpOptionType.MaximumSegmentSize)
{
MaximumSegmentSize = maximumSegmentSize;
}
public TcpOptionMaximumSegmentSize()
: this(0)
{
}
public ushort MaximumSegmentSize { 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(TcpOptionMaximumSegmentSize other)
{
if (other == null)
return false;
return MaximumSegmentSize == other.MaximumSegmentSize;
}
public override bool Equals(TcpOption other)
{
return Equals(other as TcpOptionMaximumSegmentSize);
}
public override int GetHashCode()
{
return base.GetHashCode() ^
MaximumSegmentSize.GetHashCode();
}
/// <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 != OptionHeaderLength)
return null;
ushort maximumSegmentSize = buffer.ReadUShort(ref offset, Endianity.Big);
return new TcpOptionMaximumSegmentSize(maximumSegmentSize);
}
internal override void Write(byte[] buffer, ref int offset)
{
base.Write(buffer, ref offset);
buffer.Write(ref offset, MaximumSegmentSize, Endianity.Big);
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Transport
{
public enum TcpOptionType : byte
{
EndOfOptionList = 0,
NoOperation = 1,
MaximumSegmentSize = 2,
WindowScale = 3,
SackPermitted = 4,
Sack = 5,
Echo = 6,
EchoReply = 7,
TimeStamp = 8,
PartialOrderConnectionPermitted = 9,
PartialOrderServiceProfile = 10,
Cc = 11,
CcNew = 12,
CcEcho = 13,
AlternateChecksumRequest = 14,
AlternateChecksumData = 15,
Md5Signature = 19,
QuickStartResponse = 27,
UserTimeout = 28,
}
}
\ 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