Commit 182ae7e8 authored by Brickner_cp's avatar Brickner_cp

IPv6

parent 07592ef7
using System;
namespace PcapDotNet.Packets.Ip namespace PcapDotNet.Packets.Ip
{ {
/// <summary> /// <summary>
...@@ -5,13 +7,20 @@ namespace PcapDotNet.Packets.Ip ...@@ -5,13 +7,20 @@ namespace PcapDotNet.Packets.Ip
/// The option is read from buffer and can be of different length. /// The option is read from buffer and can be of different length.
/// </summary> /// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Option")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Option")]
public abstract class Option public abstract class Option : IEquatable<Option>
{ {
/// <summary> /// <summary>
/// The number of bytes this option will take. /// The number of bytes this option will take.
/// </summary> /// </summary>
public abstract int Length { get; } public abstract int Length { get; }
public sealed override bool Equals(object obj)
{
return Equals(obj as Option);
}
public abstract bool Equals(Option other);
internal abstract void Write(byte[] buffer, ref int offset); internal abstract void Write(byte[] buffer, ref int offset);
} }
} }
\ No newline at end of file
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
...@@ -10,7 +11,7 @@ namespace PcapDotNet.Packets.Ip ...@@ -10,7 +11,7 @@ namespace PcapDotNet.Packets.Ip
/// Represents a list of options (either IPv4 options, IPv6 options or TCP options). /// Represents a list of options (either IPv4 options, IPv6 options or TCP options).
/// </summary> /// </summary>
/// <typeparam name="T">The Option type this collection contains.</typeparam> /// <typeparam name="T">The Option type this collection contains.</typeparam>
public abstract class Options<T> where T : Option public abstract class Options<T> where T : Option, IEquatable<T>
{ {
/// <summary> /// <summary>
/// Returns the collection of options. /// Returns the collection of options.
......
...@@ -5,7 +5,7 @@ using PcapDotNet.Base; ...@@ -5,7 +5,7 @@ using PcapDotNet.Base;
namespace PcapDotNet.Packets.Ip namespace PcapDotNet.Packets.Ip
{ {
public abstract class V4Options<T> : Options<T> where T : V4Option public abstract class V4Options<T> : Options<T> where T : V4Option, IEquatable<T>
{ {
internal V4Options(byte[] buffer, int offset, int length, T end) internal V4Options(byte[] buffer, int offset, int length, T end)
: this(Read(buffer, offset, length, end), length) : this(Read(buffer, offset, length, end), length)
......
...@@ -58,9 +58,9 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -58,9 +58,9 @@ namespace PcapDotNet.Packets.IpV4
/// <summary> /// <summary>
/// Checks if the two options are exactly the same - including type and value. /// Checks if the two options are exactly the same - including type and value.
/// </summary> /// </summary>
public sealed override bool Equals(object obj) public sealed override bool Equals(Option other)
{ {
return Equals(obj as IpV4Option); return Equals(other as IpV4Option);
} }
/// <summary> /// <summary>
......
using System;
using PcapDotNet.Packets.Ip; using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.IpV6 namespace PcapDotNet.Packets.IpV6
...@@ -15,7 +16,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -15,7 +16,7 @@ namespace PcapDotNet.Packets.IpV6
/// +-----+---------------------------------------+ /// +-----+---------------------------------------+
/// </pre> /// </pre>
/// </summary> /// </summary>
public abstract class IpV6Option : Option public abstract class IpV6Option : Option, IEquatable<IpV6Option>
{ {
/// <summary> /// <summary>
/// The type of the IP option. /// The type of the IP option.
...@@ -27,14 +28,22 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -27,14 +28,22 @@ namespace PcapDotNet.Packets.IpV6
OptionType = type; OptionType = type;
} }
internal override void Write(byte[] buffer, ref int offset) public sealed override bool Equals(Option other)
{ {
buffer[offset++] = (byte)OptionType; return Equals(other as IpV6Option);
} }
public override int Length public bool Equals(IpV6Option other)
{ {
get { return sizeof(byte); } return other != null &&
OptionType == other.OptionType && Length == other.Length && EqualsData(other);
}
internal abstract bool EqualsData(IpV6Option other);
internal override void Write(byte[] buffer, ref int offset)
{
buffer[offset++] = (byte)OptionType;
} }
} }
...@@ -51,7 +60,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -51,7 +60,7 @@ namespace PcapDotNet.Packets.IpV6
/// +-----+---------------------------------------+ /// +-----+---------------------------------------+
/// </pre> /// </pre>
/// </summary> /// </summary>
public abstract class IpV6MobilityOption : Option public abstract class IpV6MobilityOption : Option, IEquatable<IpV6MobilityOption>
{ {
/// <summary> /// <summary>
/// The type of the IP option. /// The type of the IP option.
...@@ -74,5 +83,18 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -74,5 +83,18 @@ namespace PcapDotNet.Packets.IpV6
{ {
get { return sizeof(byte); } get { return sizeof(byte); }
} }
public sealed override bool Equals(Option option)
{
return Equals(option as IpV6MobilityOption);
}
public bool Equals(IpV6MobilityOption other)
{
return other != null &&
OptionType == other.OptionType && Length == other.Length && EqualsData(other);
}
internal abstract bool EqualsData(IpV6MobilityOption other);
} }
} }
\ No newline at end of file
...@@ -156,6 +156,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -156,6 +156,11 @@ namespace PcapDotNet.Packets.IpV6
return new IpV6OptionCalipso(domainOfInterpretation, sensitivityLevel, checksum, compartmentBitmap); return new IpV6OptionCalipso(domainOfInterpretation, sensitivityLevel, checksum, compartmentBitmap);
} }
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionCalipso);
}
internal override void WriteData(byte[] buffer, ref int offset) internal override void WriteData(byte[] buffer, ref int offset)
{ {
buffer.Write(ref offset, (uint)DomainOfInterpretation, Endianity.Big); buffer.Write(ref offset, (uint)DomainOfInterpretation, Endianity.Big);
...@@ -170,6 +175,13 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -170,6 +175,13 @@ namespace PcapDotNet.Packets.IpV6
{ {
} }
private bool EqualsData(IpV6OptionCalipso other)
{
return other != null &&
DomainOfInterpretation == other.DomainOfInterpretation && CompartmentLength == other.CompartmentLength &&
SensitivityLevel == other.SensitivityLevel && Checksum == other.Checksum && CompartmentBitmap.Equals(CompartmentBitmap);
}
private bool? _isChecksumCorrect; private bool? _isChecksumCorrect;
} }
} }
\ No newline at end of file
...@@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.IpV6
public override sealed int Length public override sealed int Length
{ {
get { return base.Length + sizeof (byte) + DataLength; } get { return sizeof(byte) + sizeof (byte) + DataLength; }
} }
internal abstract int DataLength { get; } internal abstract int DataLength { get; }
......
...@@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre> /// </pre>
/// </summary> /// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.EndpointIdentification)] [IpV6OptionTypeRegistration(IpV6OptionType.EndpointIdentification)]
public class IpV6OptionEndpointIdentification : IpV6OptionComplex, IIpV6OptionComplexFactory public sealed class IpV6OptionEndpointIdentification : IpV6OptionComplex, IIpV6OptionComplexFactory
{ {
private static class Offset private static class Offset
{ {
...@@ -64,6 +64,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -64,6 +64,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataMinimumLength + SourceEndpointIdentifier.Length + DestinationEndpointIdentifier.Length; } get { return OptionDataMinimumLength + SourceEndpointIdentifier.Length + DestinationEndpointIdentifier.Length; }
} }
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionEndpointIdentification);
}
internal override void WriteData(byte[] buffer, ref int offset) internal override void WriteData(byte[] buffer, ref int offset)
{ {
buffer.Write(ref offset, (byte)SourceEndpointIdentifier.Length); buffer.Write(ref offset, (byte)SourceEndpointIdentifier.Length);
...@@ -76,5 +81,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -76,5 +81,11 @@ namespace PcapDotNet.Packets.IpV6
: this(DataSegment.Empty, DataSegment.Empty) : this(DataSegment.Empty, DataSegment.Empty)
{ {
} }
private bool EqualsData(IpV6OptionEndpointIdentification other)
{
return other != null &&
SourceEndpointIdentifier.Equals(other.SourceEndpointIdentifier) && DestinationEndpointIdentifier.Equals(other.DestinationEndpointIdentifier);
}
} }
} }
\ No newline at end of file
...@@ -50,6 +50,10 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -50,6 +50,10 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; } get { return OptionDataLength; }
} }
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionHomeAddress);
}
internal override void WriteData(byte[] buffer, ref int offset) internal override void WriteData(byte[] buffer, ref int offset)
{ {
...@@ -60,5 +64,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -60,5 +64,11 @@ namespace PcapDotNet.Packets.IpV6
: this(IpV6Address.Zero) : this(IpV6Address.Zero)
{ {
} }
private bool EqualsData(IpV6OptionHomeAddress other)
{
return other != null &&
HomeAddress.Equals(other.HomeAddress);
}
} }
} }
\ No newline at end of file
...@@ -16,7 +16,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -16,7 +16,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre> /// </pre>
/// </summary> /// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.IlnpNonce)] [IpV6OptionTypeRegistration(IpV6OptionType.IlnpNonce)]
public class IpV6OptionIlnpNonce : IpV6OptionComplex, IIpV6OptionComplexFactory public sealed class IpV6OptionIlnpNonce : IpV6OptionComplex, IIpV6OptionComplexFactory
{ {
public IpV6OptionIlnpNonce(DataSegment nonce) public IpV6OptionIlnpNonce(DataSegment nonce)
: base(IpV6OptionType.IlnpNonce) : base(IpV6OptionType.IlnpNonce)
...@@ -39,6 +39,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -39,6 +39,11 @@ namespace PcapDotNet.Packets.IpV6
get { return Nonce.Length; } get { return Nonce.Length; }
} }
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionIlnpNonce);
}
internal override void WriteData(byte[] buffer, ref int offset) internal override void WriteData(byte[] buffer, ref int offset)
{ {
buffer.Write(ref offset, Nonce); buffer.Write(ref offset, Nonce);
...@@ -48,5 +53,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -48,5 +53,11 @@ namespace PcapDotNet.Packets.IpV6
: this(DataSegment.Empty) : this(DataSegment.Empty)
{ {
} }
private bool EqualsData(IpV6OptionIlnpNonce other)
{
return other != null &&
Nonce.Equals(other.Nonce);
}
} }
} }
\ No newline at end of file
...@@ -42,6 +42,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -42,6 +42,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; } get { return OptionDataLength; }
} }
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionJumboPayload);
}
internal override void WriteData(byte[] buffer, ref int offset) internal override void WriteData(byte[] buffer, ref int offset)
{ {
buffer.Write(ref offset, JumboPayloadLength, Endianity.Big); buffer.Write(ref offset, JumboPayloadLength, Endianity.Big);
...@@ -51,5 +56,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -51,5 +56,11 @@ namespace PcapDotNet.Packets.IpV6
: this(0) : this(0)
{ {
} }
private bool EqualsData(IpV6OptionJumboPayload other)
{
return other != null &&
JumboPayloadLength == other.JumboPayloadLength;
}
} }
} }
\ No newline at end of file
...@@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre> /// </pre>
/// </summary> /// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.LineIdentification)] [IpV6OptionTypeRegistration(IpV6OptionType.LineIdentification)]
public class IpV6OptionLineIdentificationDestination : IpV6OptionComplex, IIpV6OptionComplexFactory public sealed class IpV6OptionLineIdentificationDestination : IpV6OptionComplex, IIpV6OptionComplexFactory
{ {
private static class Offset private static class Offset
{ {
...@@ -68,6 +68,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -68,6 +68,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataMinimumLength + LineIdentification.Length; } get { return OptionDataMinimumLength + LineIdentification.Length; }
} }
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionLineIdentificationDestination);
}
internal override void WriteData(byte[] buffer, ref int offset) internal override void WriteData(byte[] buffer, ref int offset)
{ {
buffer.Write(ref offset, (byte)LineIdentification.Length); buffer.Write(ref offset, (byte)LineIdentification.Length);
...@@ -78,5 +83,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -78,5 +83,11 @@ namespace PcapDotNet.Packets.IpV6
: this(DataSegment.Empty) : this(DataSegment.Empty)
{ {
} }
private bool EqualsData(IpV6OptionLineIdentificationDestination other)
{
return other != null &&
LineIdentification.Equals(other.LineIdentification);
}
} }
} }
\ No newline at end of file
...@@ -27,7 +27,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -27,7 +27,7 @@ namespace PcapDotNet.Packets.IpV6
/// | 0 | 0 | /// | 0 | 0 |
/// +-----+-----+ /// +-----+-----+
/// </summary> /// </summary>
public class IpV6MobilityOptionPad1 : IpV6MobilityOption public sealed class IpV6MobilityOptionPad1 : IpV6MobilityOption
{ {
public const int OptionLength = sizeof(byte); public const int OptionLength = sizeof(byte);
...@@ -36,6 +36,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -36,6 +36,11 @@ namespace PcapDotNet.Packets.IpV6
{ {
} }
internal override bool EqualsData(IpV6MobilityOption other)
{
return true;
}
internal override IpV6MobilityOption CreateInstance(DataSegment data) internal override IpV6MobilityOption CreateInstance(DataSegment data)
{ {
throw new InvalidOperationException("Pad1 options shouldn't be registered."); throw new InvalidOperationException("Pad1 options shouldn't be registered.");
......
...@@ -16,7 +16,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -16,7 +16,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre> /// </pre>
/// </summary> /// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.PadN)] [IpV6OptionTypeRegistration(IpV6OptionType.PadN)]
public class IpV6OptionPadN : IpV6OptionComplex, IIpV6OptionComplexFactory public sealed class IpV6OptionPadN : IpV6OptionComplex, IIpV6OptionComplexFactory
{ {
public IpV6OptionPadN(int paddingDataLength) : base(IpV6OptionType.PadN) public IpV6OptionPadN(int paddingDataLength) : base(IpV6OptionType.PadN)
{ {
...@@ -35,6 +35,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -35,6 +35,11 @@ namespace PcapDotNet.Packets.IpV6
get { return PaddingDataLength; } get { return PaddingDataLength; }
} }
internal override bool EqualsData(IpV6Option other)
{
return true;
}
internal override void WriteData(byte[] buffer, ref int offset) internal override void WriteData(byte[] buffer, ref int offset)
{ {
offset += PaddingDataLength; offset += PaddingDataLength;
......
...@@ -16,7 +16,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -16,7 +16,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre> /// </pre>
/// </summary> /// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.QuickStart)] [IpV6OptionTypeRegistration(IpV6OptionType.QuickStart)]
public class IpV6OptionQuickStart : IpV6OptionComplex, IIpOptionQuickStart, IIpV6OptionComplexFactory public sealed class IpV6OptionQuickStart : IpV6OptionComplex, IIpOptionQuickStart, IIpV6OptionComplexFactory
{ {
public const int OptionDataLength = IpOptionQuickStartCommon.DataLength; public const int OptionDataLength = IpOptionQuickStartCommon.DataLength;
...@@ -61,6 +61,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -61,6 +61,11 @@ namespace PcapDotNet.Packets.IpV6
return new IpV6OptionQuickStart(function, rate, ttl, nonce); return new IpV6OptionQuickStart(function, rate, ttl, nonce);
} }
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionQuickStart);
}
internal override void WriteData(byte[] buffer, ref int offset) internal override void WriteData(byte[] buffer, ref int offset)
{ {
IpOptionQuickStartCommon.WriteData(buffer, ref offset, Function, Rate, Ttl, Nonce); IpOptionQuickStartCommon.WriteData(buffer, ref offset, Function, Rate, Ttl, Nonce);
...@@ -70,5 +75,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -70,5 +75,11 @@ namespace PcapDotNet.Packets.IpV6
: this(IpV4OptionQuickStartFunction.RateRequest, 0, 0, 0) : this(IpV4OptionQuickStartFunction.RateRequest, 0, 0, 0)
{ {
} }
private bool EqualsData(IpV6OptionQuickStart other)
{
return other != null &&
Function == other.Function && Rate == other.Rate && Ttl == other.Ttl && Nonce == other.Nonce;
}
} }
} }
\ No newline at end of file
...@@ -13,7 +13,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -13,7 +13,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre> /// </pre>
/// </summary> /// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.RouterAlert)] [IpV6OptionTypeRegistration(IpV6OptionType.RouterAlert)]
public class IpV6OptionRouterAlert : IpV6OptionComplex, IIpV6OptionComplexFactory public sealed class IpV6OptionRouterAlert : IpV6OptionComplex, IIpV6OptionComplexFactory
{ {
public const int OptionDataLength = sizeof(ushort); public const int OptionDataLength = sizeof(ushort);
...@@ -41,6 +41,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -41,6 +41,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; } get { return OptionDataLength; }
} }
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionRouterAlert);
}
internal override void WriteData(byte[] buffer, ref int offset) internal override void WriteData(byte[] buffer, ref int offset)
{ {
buffer.Write(ref offset, (ushort)RouterAlertType, Endianity.Big); buffer.Write(ref offset, (ushort)RouterAlertType, Endianity.Big);
...@@ -50,5 +55,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -50,5 +55,11 @@ namespace PcapDotNet.Packets.IpV6
: this(IpV6RouterAlertType.MulticastListenerDiscovery) : this(IpV6RouterAlertType.MulticastListenerDiscovery)
{ {
} }
private bool EqualsData(IpV6OptionRouterAlert other)
{
return other != null &&
RouterAlertType == other.RouterAlertType;
}
} }
} }
\ No newline at end of file
...@@ -19,7 +19,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -19,7 +19,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre> /// </pre>
/// </summary> /// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.RplOption)] [IpV6OptionTypeRegistration(IpV6OptionType.RplOption)]
public class IpV6OptionRoutingProtocolLowPowerAndLossyNetworks : IpV6OptionComplex, IIpV6OptionComplexFactory public sealed class IpV6OptionRoutingProtocolLowPowerAndLossyNetworks : IpV6OptionComplex, IIpV6OptionComplexFactory
{ {
private static class Offset private static class Offset
{ {
...@@ -109,6 +109,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -109,6 +109,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataMinimumLength + SubTlvs.Length; } get { return OptionDataMinimumLength + SubTlvs.Length; }
} }
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionRoutingProtocolLowPowerAndLossyNetworks);
}
internal override void WriteData(byte[] buffer, ref int offset) internal override void WriteData(byte[] buffer, ref int offset)
{ {
byte flags = (byte)((Down ? Mask.Down : 0) | (RankError ? Mask.RankError : 0) | (ForwardingError ? Mask.ForwardingError : 0)); byte flags = (byte)((Down ? Mask.Down : 0) | (RankError ? Mask.RankError : 0) | (ForwardingError ? Mask.ForwardingError : 0));
...@@ -122,5 +127,12 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -122,5 +127,12 @@ namespace PcapDotNet.Packets.IpV6
: this(false, false, false, 0, 0, DataSegment.Empty) : this(false, false, false, 0, 0, DataSegment.Empty)
{ {
} }
private bool EqualsData(IpV6OptionRoutingProtocolLowPowerAndLossyNetworks other)
{
return other != null &&
Down == other.Down && RankError == other.RankError && ForwardingError == other.ForwardingError && RplInstanceId == other.RplInstanceId &&
SenderRank == other.SenderRank && SubTlvs.Equals(SubTlvs);
}
} }
} }
\ No newline at end of file
...@@ -20,7 +20,12 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -20,7 +20,12 @@ namespace PcapDotNet.Packets.IpV6
public override sealed int Length public override sealed int Length
{ {
get { return base.Length; } get { return sizeof(byte); }
}
internal sealed override bool EqualsData(IpV6Option other)
{
return true;
} }
internal override sealed void Write(byte[] buffer, ref int offset) internal override sealed void Write(byte[] buffer, ref int offset)
......
...@@ -42,6 +42,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -42,6 +42,7 @@ namespace PcapDotNet.Packets.IpV6
/// 1 == indicates a hash assist value (HAV) field follows to aid in avoiding hash-based DPD collisions. /// 1 == indicates a hash assist value (HAV) field follows to aid in avoiding hash-based DPD collisions.
/// </summary> /// </summary>
public abstract bool HashIndicator { get; } public abstract bool HashIndicator { get; }
internal static IpV6Option CreateInstance(DataSegment data) internal static IpV6Option CreateInstance(DataSegment data)
{ {
if (data.Length < OptionDataMinimumLength) if (data.Length < OptionDataMinimumLength)
......
...@@ -23,7 +23,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -23,7 +23,7 @@ namespace PcapDotNet.Packets.IpV6
/// +-----+--------------------+ /// +-----+--------------------+
/// </pre> /// </pre>
/// </summary> /// </summary>
public class IpV6OptionSmfDpdDefault : IpV6OptionSmfDpdSequenceBased public sealed class IpV6OptionSmfDpdDefault : IpV6OptionSmfDpdSequenceBased
{ {
public IpV6OptionSmfDpdDefault(DataSegment taggerId, DataSegment identifier) public IpV6OptionSmfDpdDefault(DataSegment taggerId, DataSegment identifier)
: base(identifier) : base(identifier)
...@@ -49,9 +49,20 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -49,9 +49,20 @@ namespace PcapDotNet.Packets.IpV6
get { return IpV6TaggerIdType.Default; } get { return IpV6TaggerIdType.Default; }
} }
internal override bool EqualsTaggerId(IpV6OptionSmfDpdSequenceBased other)
{
return EqualsTaggerId(other as IpV6OptionSmfDpdDefault);
}
internal override void WriteTaggerId(byte[] buffer, ref int offset) internal override void WriteTaggerId(byte[] buffer, ref int offset)
{ {
buffer.Write(ref offset, TaggerId); buffer.Write(ref offset, TaggerId);
} }
private bool EqualsTaggerId(IpV6OptionSmfDpdDefault other)
{
return other != null &&
TaggerId.Equals(other.TaggerId);
}
} }
} }
\ No newline at end of file
...@@ -27,7 +27,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -27,7 +27,7 @@ namespace PcapDotNet.Packets.IpV6
/// +-----+--------------------+ /// +-----+--------------------+
/// </pre> /// </pre>
/// </summary> /// </summary>
public class IpV6OptionSmfDpdIpV4 : IpV6OptionSmfDpdSequenceBased public sealed class IpV6OptionSmfDpdIpV4 : IpV6OptionSmfDpdSequenceBased
{ {
public IpV6OptionSmfDpdIpV4(IpV4Address taggerId, DataSegment identifier) public IpV6OptionSmfDpdIpV4(IpV4Address taggerId, DataSegment identifier)
: base(identifier) : base(identifier)
...@@ -53,9 +53,20 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -53,9 +53,20 @@ namespace PcapDotNet.Packets.IpV6
get { return IpV6TaggerIdType.IpV4; } get { return IpV6TaggerIdType.IpV4; }
} }
internal override bool EqualsTaggerId(IpV6OptionSmfDpdSequenceBased other)
{
return EqualsTaggerId(other as IpV6OptionSmfDpdIpV4);
}
internal override void WriteTaggerId(byte[] buffer, ref int offset) internal override void WriteTaggerId(byte[] buffer, ref int offset)
{ {
buffer.Write(ref offset, TaggerId, Endianity.Big); buffer.Write(ref offset, TaggerId, Endianity.Big);
} }
private bool EqualsTaggerId(IpV6OptionSmfDpdIpV4 other)
{
return other != null &&
TaggerId.Equals(other.TaggerId);
}
} }
} }
\ No newline at end of file
...@@ -37,7 +37,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -37,7 +37,7 @@ namespace PcapDotNet.Packets.IpV6
/// +-----+--------------------+ /// +-----+--------------------+
/// </pre> /// </pre>
/// </summary> /// </summary>
public class IpV6OptionSmfDpdIpV6 : IpV6OptionSmfDpdSequenceBased public sealed class IpV6OptionSmfDpdIpV6 : IpV6OptionSmfDpdSequenceBased
{ {
public IpV6OptionSmfDpdIpV6(IpV6Address taggerId, DataSegment identifier) public IpV6OptionSmfDpdIpV6(IpV6Address taggerId, DataSegment identifier)
: base(identifier) : base(identifier)
...@@ -63,9 +63,20 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -63,9 +63,20 @@ namespace PcapDotNet.Packets.IpV6
get { return IpV6TaggerIdType.IpV6; } get { return IpV6TaggerIdType.IpV6; }
} }
internal override bool EqualsTaggerId(IpV6OptionSmfDpdSequenceBased other)
{
return EqualsTaggerId(other as IpV6OptionSmfDpdIpV6);
}
internal override void WriteTaggerId(byte[] buffer, ref int offset) internal override void WriteTaggerId(byte[] buffer, ref int offset)
{ {
buffer.Write(ref offset, TaggerId, Endianity.Big); buffer.Write(ref offset, TaggerId, Endianity.Big);
} }
private bool EqualsTaggerId(IpV6OptionSmfDpdIpV6 other)
{
return other != null &&
TaggerId.Equals(other.TaggerId);
}
} }
} }
\ No newline at end of file
...@@ -20,7 +20,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -20,7 +20,7 @@ namespace PcapDotNet.Packets.IpV6
/// +-----+--------------------+ /// +-----+--------------------+
/// </pre> /// </pre>
/// </summary> /// </summary>
public class IpV6OptionSmfDpdNull : IpV6OptionSmfDpdSequenceBased public sealed class IpV6OptionSmfDpdNull : IpV6OptionSmfDpdSequenceBased
{ {
public IpV6OptionSmfDpdNull(DataSegment identifier) public IpV6OptionSmfDpdNull(DataSegment identifier)
: base(identifier) : base(identifier)
...@@ -43,6 +43,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -43,6 +43,11 @@ namespace PcapDotNet.Packets.IpV6
get { return IpV6TaggerIdType.Null; } get { return IpV6TaggerIdType.Null; }
} }
internal override bool EqualsTaggerId(IpV6OptionSmfDpdSequenceBased other)
{
return true;
}
internal override void WriteTaggerId(byte[] buffer, ref int offset) internal override void WriteTaggerId(byte[] buffer, ref int offset)
{ {
} }
......
...@@ -78,12 +78,19 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -78,12 +78,19 @@ namespace PcapDotNet.Packets.IpV6
Identifier = identifier; Identifier = identifier;
} }
internal override int DataLength internal override sealed int DataLength
{ {
get { return OptionDataMinimumLength + TaggerIdLength + Identifier.Length; } get { return OptionDataMinimumLength + TaggerIdLength + Identifier.Length; }
} }
internal override void WriteData(byte[] buffer, ref int offset) internal sealed override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionSmfDpdSequenceBased);
}
internal abstract bool EqualsTaggerId(IpV6OptionSmfDpdSequenceBased other);
internal override sealed void WriteData(byte[] buffer, ref int offset)
{ {
byte taggerIdInfo = (byte)(((byte)TaggerIdType << Shift.TaggerIdType) & Mask.TaggerIdType); byte taggerIdInfo = (byte)(((byte)TaggerIdType << Shift.TaggerIdType) & Mask.TaggerIdType);
if (TaggerIdType != IpV6TaggerIdType.Null) if (TaggerIdType != IpV6TaggerIdType.Null)
...@@ -126,5 +133,12 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -126,5 +133,12 @@ namespace PcapDotNet.Packets.IpV6
return null; return null;
} }
} }
private bool EqualsData(IpV6OptionSmfDpdSequenceBased other)
{
return other != null &&
Identifier.Equals(other.Identifier) && TaggerIdType == other.TaggerIdType && EqualsTaggerId(other);
}
} }
} }
\ No newline at end of file
...@@ -18,7 +18,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -18,7 +18,7 @@ namespace PcapDotNet.Packets.IpV6
/// +-----+--------------+ /// +-----+--------------+
/// </pre> /// </pre>
/// </summary> /// </summary>
public class IpV6OptionSmfDpdSequenceHashAssistValue : IpV6OptionSmfDpd public sealed class IpV6OptionSmfDpdSequenceHashAssistValue : IpV6OptionSmfDpd
{ {
private static class Offset private static class Offset
{ {
...@@ -38,20 +38,31 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -38,20 +38,31 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public DataSegment HashAssistValue { get; private set; } public DataSegment HashAssistValue { get; private set; }
public override bool HashIndicator
{
get { return true; }
}
internal override int DataLength internal override int DataLength
{ {
get { return HashAssistValue.Length; } get { return HashAssistValue.Length; }
} }
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionSmfDpdSequenceHashAssistValue);
}
internal override void WriteData(byte[] buffer, ref int offset) internal override void WriteData(byte[] buffer, ref int offset)
{ {
buffer.Write(ref offset, (byte)(HashAssistValue[0] | 0x80)); buffer.Write(ref offset, (byte)(HashAssistValue[0] | 0x80));
buffer.Write(ref offset, HashAssistValue.Subsegment(1, HashAssistValue.Length - 1)); buffer.Write(ref offset, HashAssistValue.Subsegment(1, HashAssistValue.Length - 1));
} }
public override bool HashIndicator private bool EqualsData(IpV6OptionSmfDpdSequenceHashAssistValue other)
{ {
get { return true; } return other != null &&
HashAssistValue.Equals(other.HashAssistValue);
} }
} }
} }
\ No newline at end of file
...@@ -13,7 +13,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -13,7 +13,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre> /// </pre>
/// </summary> /// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.TunnelEncapsulationLimit)] [IpV6OptionTypeRegistration(IpV6OptionType.TunnelEncapsulationLimit)]
public class IpV6OptionTunnelEncapsulationLimit : IpV6OptionComplex, IIpV6OptionComplexFactory public sealed class IpV6OptionTunnelEncapsulationLimit : IpV6OptionComplex, IIpV6OptionComplexFactory
{ {
public const int OptionDataLength = sizeof(byte); public const int OptionDataLength = sizeof(byte);
...@@ -41,6 +41,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -41,6 +41,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; } get { return OptionDataLength; }
} }
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionTunnelEncapsulationLimit);
}
internal override void WriteData(byte[] buffer, ref int offset) internal override void WriteData(byte[] buffer, ref int offset)
{ {
buffer.Write(ref offset, TunnelEncapsulationLimit); buffer.Write(ref offset, TunnelEncapsulationLimit);
...@@ -50,5 +55,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -50,5 +55,11 @@ namespace PcapDotNet.Packets.IpV6
: this(0) : this(0)
{ {
} }
private bool EqualsData(IpV6OptionTunnelEncapsulationLimit other)
{
return other != null &&
TunnelEncapsulationLimit == other.TunnelEncapsulationLimit;
}
} }
} }
\ No newline at end of file
...@@ -120,7 +120,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -120,7 +120,7 @@ namespace PcapDotNet.Packets.IpV6
} }
} }
public abstract class V6Options<T> : Options<T> where T : Option public abstract class V6Options<T> : Options<T> where T : Option, IEquatable<T>
{ {
public V6Options(IList<T> options, bool isValid) public V6Options(IList<T> options, bool isValid)
: base(options, isValid, null) : base(options, isValid, null)
......
...@@ -58,9 +58,9 @@ namespace PcapDotNet.Packets.Transport ...@@ -58,9 +58,9 @@ namespace PcapDotNet.Packets.Transport
/// <summary> /// <summary>
/// Checks if the two options are exactly the same - including type and value. /// Checks if the two options are exactly the same - including type and value.
/// </summary> /// </summary>
public sealed override bool Equals(object obj) public sealed override bool Equals(Option other)
{ {
return Equals(obj as TcpOption); return Equals(other as TcpOption);
} }
/// <summary> /// <summary>
......
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