Commit 182ae7e8 authored by Brickner_cp's avatar Brickner_cp

IPv6

parent 07592ef7
using System;
namespace PcapDotNet.Packets.Ip
{
/// <summary>
......@@ -5,13 +7,20 @@ namespace PcapDotNet.Packets.Ip
/// The option is read from buffer and can be of different length.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Option")]
public abstract class Option
public abstract class Option : IEquatable<Option>
{
/// <summary>
/// The number of bytes this option will take.
/// </summary>
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);
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
......@@ -10,7 +11,7 @@ namespace PcapDotNet.Packets.Ip
/// Represents a list of options (either IPv4 options, IPv6 options or TCP options).
/// </summary>
/// <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>
/// Returns the collection of options.
......
......@@ -5,7 +5,7 @@ using PcapDotNet.Base;
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)
: this(Read(buffer, offset, length, end), length)
......
......@@ -58,9 +58,9 @@ namespace PcapDotNet.Packets.IpV4
/// <summary>
/// Checks if the two options are exactly the same - including type and value.
/// </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>
......
using System;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.IpV6
......@@ -15,7 +16,7 @@ namespace PcapDotNet.Packets.IpV6
/// +-----+---------------------------------------+
/// </pre>
/// </summary>
public abstract class IpV6Option : Option
public abstract class IpV6Option : Option, IEquatable<IpV6Option>
{
/// <summary>
/// The type of the IP option.
......@@ -27,14 +28,22 @@ namespace PcapDotNet.Packets.IpV6
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
/// +-----+---------------------------------------+
/// </pre>
/// </summary>
public abstract class IpV6MobilityOption : Option
public abstract class IpV6MobilityOption : Option, IEquatable<IpV6MobilityOption>
{
/// <summary>
/// The type of the IP option.
......@@ -74,5 +83,18 @@ namespace PcapDotNet.Packets.IpV6
{
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
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)
{
buffer.Write(ref offset, (uint)DomainOfInterpretation, Endianity.Big);
......@@ -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;
}
}
\ No newline at end of file
......@@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.IpV6
public override sealed int Length
{
get { return base.Length + sizeof (byte) + DataLength; }
get { return sizeof(byte) + sizeof (byte) + DataLength; }
}
internal abstract int DataLength { get; }
......
......@@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.EndpointIdentification)]
public class IpV6OptionEndpointIdentification : IpV6OptionComplex, IIpV6OptionComplexFactory
public sealed class IpV6OptionEndpointIdentification : IpV6OptionComplex, IIpV6OptionComplexFactory
{
private static class Offset
{
......@@ -64,6 +64,11 @@ namespace PcapDotNet.Packets.IpV6
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)
{
buffer.Write(ref offset, (byte)SourceEndpointIdentifier.Length);
......@@ -76,5 +81,11 @@ namespace PcapDotNet.Packets.IpV6
: 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
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionHomeAddress);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
......@@ -60,5 +64,11 @@ namespace PcapDotNet.Packets.IpV6
: 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
/// </pre>
/// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.IlnpNonce)]
public class IpV6OptionIlnpNonce : IpV6OptionComplex, IIpV6OptionComplexFactory
public sealed class IpV6OptionIlnpNonce : IpV6OptionComplex, IIpV6OptionComplexFactory
{
public IpV6OptionIlnpNonce(DataSegment nonce)
: base(IpV6OptionType.IlnpNonce)
......@@ -39,6 +39,11 @@ namespace PcapDotNet.Packets.IpV6
get { return Nonce.Length; }
}
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionIlnpNonce);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, Nonce);
......@@ -48,5 +53,11 @@ namespace PcapDotNet.Packets.IpV6
: 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
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionJumboPayload);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, JumboPayloadLength, Endianity.Big);
......@@ -51,5 +56,11 @@ namespace PcapDotNet.Packets.IpV6
: 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
/// </pre>
/// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.LineIdentification)]
public class IpV6OptionLineIdentificationDestination : IpV6OptionComplex, IIpV6OptionComplexFactory
public sealed class IpV6OptionLineIdentificationDestination : IpV6OptionComplex, IIpV6OptionComplexFactory
{
private static class Offset
{
......@@ -68,6 +68,11 @@ namespace PcapDotNet.Packets.IpV6
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)
{
buffer.Write(ref offset, (byte)LineIdentification.Length);
......@@ -78,5 +83,11 @@ namespace PcapDotNet.Packets.IpV6
: 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
/// | 0 | 0 |
/// +-----+-----+
/// </summary>
public class IpV6MobilityOptionPad1 : IpV6MobilityOption
public sealed class IpV6MobilityOptionPad1 : IpV6MobilityOption
{
public const int OptionLength = sizeof(byte);
......@@ -36,6 +36,11 @@ namespace PcapDotNet.Packets.IpV6
{
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return true;
}
internal override IpV6MobilityOption CreateInstance(DataSegment data)
{
throw new InvalidOperationException("Pad1 options shouldn't be registered.");
......
......@@ -16,7 +16,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.PadN)]
public class IpV6OptionPadN : IpV6OptionComplex, IIpV6OptionComplexFactory
public sealed class IpV6OptionPadN : IpV6OptionComplex, IIpV6OptionComplexFactory
{
public IpV6OptionPadN(int paddingDataLength) : base(IpV6OptionType.PadN)
{
......@@ -35,6 +35,11 @@ namespace PcapDotNet.Packets.IpV6
get { return PaddingDataLength; }
}
internal override bool EqualsData(IpV6Option other)
{
return true;
}
internal override void WriteData(byte[] buffer, ref int offset)
{
offset += PaddingDataLength;
......
......@@ -16,7 +16,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.QuickStart)]
public class IpV6OptionQuickStart : IpV6OptionComplex, IIpOptionQuickStart, IIpV6OptionComplexFactory
public sealed class IpV6OptionQuickStart : IpV6OptionComplex, IIpOptionQuickStart, IIpV6OptionComplexFactory
{
public const int OptionDataLength = IpOptionQuickStartCommon.DataLength;
......@@ -61,6 +61,11 @@ namespace PcapDotNet.Packets.IpV6
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)
{
IpOptionQuickStartCommon.WriteData(buffer, ref offset, Function, Rate, Ttl, Nonce);
......@@ -70,5 +75,11 @@ namespace PcapDotNet.Packets.IpV6
: 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
/// </pre>
/// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.RouterAlert)]
public class IpV6OptionRouterAlert : IpV6OptionComplex, IIpV6OptionComplexFactory
public sealed class IpV6OptionRouterAlert : IpV6OptionComplex, IIpV6OptionComplexFactory
{
public const int OptionDataLength = sizeof(ushort);
......@@ -41,6 +41,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionRouterAlert);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, (ushort)RouterAlertType, Endianity.Big);
......@@ -50,5 +55,11 @@ namespace PcapDotNet.Packets.IpV6
: 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
/// </pre>
/// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.RplOption)]
public class IpV6OptionRoutingProtocolLowPowerAndLossyNetworks : IpV6OptionComplex, IIpV6OptionComplexFactory
public sealed class IpV6OptionRoutingProtocolLowPowerAndLossyNetworks : IpV6OptionComplex, IIpV6OptionComplexFactory
{
private static class Offset
{
......@@ -109,6 +109,11 @@ namespace PcapDotNet.Packets.IpV6
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)
{
byte flags = (byte)((Down ? Mask.Down : 0) | (RankError ? Mask.RankError : 0) | (ForwardingError ? Mask.ForwardingError : 0));
......@@ -122,5 +127,12 @@ namespace PcapDotNet.Packets.IpV6
: 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
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)
......
......@@ -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.
/// </summary>
public abstract bool HashIndicator { get; }
internal static IpV6Option CreateInstance(DataSegment data)
{
if (data.Length < OptionDataMinimumLength)
......
......@@ -23,7 +23,7 @@ namespace PcapDotNet.Packets.IpV6
/// +-----+--------------------+
/// </pre>
/// </summary>
public class IpV6OptionSmfDpdDefault : IpV6OptionSmfDpdSequenceBased
public sealed class IpV6OptionSmfDpdDefault : IpV6OptionSmfDpdSequenceBased
{
public IpV6OptionSmfDpdDefault(DataSegment taggerId, DataSegment identifier)
: base(identifier)
......@@ -49,9 +49,20 @@ namespace PcapDotNet.Packets.IpV6
get { return IpV6TaggerIdType.Default; }
}
internal override bool EqualsTaggerId(IpV6OptionSmfDpdSequenceBased other)
{
return EqualsTaggerId(other as IpV6OptionSmfDpdDefault);
}
internal override void WriteTaggerId(byte[] buffer, ref int offset)
{
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
/// +-----+--------------------+
/// </pre>
/// </summary>
public class IpV6OptionSmfDpdIpV4 : IpV6OptionSmfDpdSequenceBased
public sealed class IpV6OptionSmfDpdIpV4 : IpV6OptionSmfDpdSequenceBased
{
public IpV6OptionSmfDpdIpV4(IpV4Address taggerId, DataSegment identifier)
: base(identifier)
......@@ -53,9 +53,20 @@ namespace PcapDotNet.Packets.IpV6
get { return IpV6TaggerIdType.IpV4; }
}
internal override bool EqualsTaggerId(IpV6OptionSmfDpdSequenceBased other)
{
return EqualsTaggerId(other as IpV6OptionSmfDpdIpV4);
}
internal override void WriteTaggerId(byte[] buffer, ref int offset)
{
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
/// +-----+--------------------+
/// </pre>
/// </summary>
public class IpV6OptionSmfDpdIpV6 : IpV6OptionSmfDpdSequenceBased
public sealed class IpV6OptionSmfDpdIpV6 : IpV6OptionSmfDpdSequenceBased
{
public IpV6OptionSmfDpdIpV6(IpV6Address taggerId, DataSegment identifier)
: base(identifier)
......@@ -63,9 +63,20 @@ namespace PcapDotNet.Packets.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)
{
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
/// +-----+--------------------+
/// </pre>
/// </summary>
public class IpV6OptionSmfDpdNull : IpV6OptionSmfDpdSequenceBased
public sealed class IpV6OptionSmfDpdNull : IpV6OptionSmfDpdSequenceBased
{
public IpV6OptionSmfDpdNull(DataSegment identifier)
: base(identifier)
......@@ -43,6 +43,11 @@ namespace PcapDotNet.Packets.IpV6
get { return IpV6TaggerIdType.Null; }
}
internal override bool EqualsTaggerId(IpV6OptionSmfDpdSequenceBased other)
{
return true;
}
internal override void WriteTaggerId(byte[] buffer, ref int offset)
{
}
......
......@@ -78,12 +78,19 @@ namespace PcapDotNet.Packets.IpV6
Identifier = identifier;
}
internal override int DataLength
internal override sealed int DataLength
{
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);
if (TaggerIdType != IpV6TaggerIdType.Null)
......@@ -126,5 +133,12 @@ namespace PcapDotNet.Packets.IpV6
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
/// +-----+--------------+
/// </pre>
/// </summary>
public class IpV6OptionSmfDpdSequenceHashAssistValue : IpV6OptionSmfDpd
public sealed class IpV6OptionSmfDpdSequenceHashAssistValue : IpV6OptionSmfDpd
{
private static class Offset
{
......@@ -38,20 +38,31 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
public DataSegment HashAssistValue { get; private set; }
public override bool HashIndicator
{
get { return true; }
}
internal override int DataLength
{
get { return HashAssistValue.Length; }
}
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionSmfDpdSequenceHashAssistValue);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, (byte)(HashAssistValue[0] | 0x80));
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
/// </pre>
/// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.TunnelEncapsulationLimit)]
public class IpV6OptionTunnelEncapsulationLimit : IpV6OptionComplex, IIpV6OptionComplexFactory
public sealed class IpV6OptionTunnelEncapsulationLimit : IpV6OptionComplex, IIpV6OptionComplexFactory
{
public const int OptionDataLength = sizeof(byte);
......@@ -41,6 +41,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionTunnelEncapsulationLimit);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, TunnelEncapsulationLimit);
......@@ -50,5 +55,11 @@ namespace PcapDotNet.Packets.IpV6
: this(0)
{
}
private bool EqualsData(IpV6OptionTunnelEncapsulationLimit other)
{
return other != null &&
TunnelEncapsulationLimit == other.TunnelEncapsulationLimit;
}
}
}
\ No newline at end of file
......@@ -37,10 +37,21 @@ namespace PcapDotNet.Packets.IpV6
get { return Data.Length; }
}
internal override bool EqualsData(IpV6Option other)
{
return EqualsData(other as IpV6OptionUnknown);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, Data);
}
private bool EqualsData(IpV6OptionUnknown other)
{
return other != null &&
Data.Equals(other.Data);
}
}
/// <summary>
......@@ -110,6 +121,11 @@ namespace PcapDotNet.Packets.IpV6
get { return PaddingDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return true;
}
internal override void WriteData(byte[] buffer, ref int offset)
{
offset += PaddingDataLength;
......@@ -164,6 +180,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionBindingRefreshAdvice);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, RefreshInterval, Endianity.Big);
......@@ -173,6 +194,12 @@ namespace PcapDotNet.Packets.IpV6
: this(0)
{
}
private bool EqualsData(IpV6MobilityOptionBindingRefreshAdvice other)
{
return other != null &&
RefreshInterval == other.RefreshInterval;
}
}
/// <summary>
......@@ -222,10 +249,21 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal sealed override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionIpV6Address);
}
internal override sealed void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, Address, Endianity.Big);
}
private bool EqualsData(IpV6MobilityOptionIpV6Address other)
{
return other != null &&
other.Address.Equals(other.Address);
}
}
/// <summary>
......@@ -337,6 +375,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionNonceIndices);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, HomeNonceIndex, Endianity.Big);
......@@ -347,6 +390,12 @@ namespace PcapDotNet.Packets.IpV6
: this(0, 0)
{
}
private bool EqualsData(IpV6MobilityOptionNonceIndices other)
{
return other != null &&
HomeNonceIndex == other.HomeNonceIndex && CareOfNonceIndex == other.CareOfNonceIndex;
}
}
/// <summary>
......@@ -478,6 +527,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal sealed override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionNetworkPrefix);
}
internal override sealed void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.PrefixLength, PrefixLength);
......@@ -498,6 +552,12 @@ namespace PcapDotNet.Packets.IpV6
networkPrefix = data.ReadIpV6Address(Offset.NetworkPrefix, Endianity.Big);
return true;
}
private bool EqualsData(IpV6MobilityOptionNetworkPrefix other)
{
return other != null &&
PrefixLength == other.PrefixLength && NetworkPrefix.Equals(other.NetworkPrefix);
}
}
......@@ -673,11 +733,6 @@ namespace PcapDotNet.Packets.IpV6
LinkLayerAddress = linkLayerAddress;
}
private IpV6MobilityOptionLinkLayerAddress()
: this(IpV6MobilityLinkLayerAddressCode.Wildcard, DataSegment.Empty)
{
}
public IpV6MobilityLinkLayerAddressCode Code { get; private set; }
/// <summary>
......@@ -701,12 +756,29 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataMinimumLength + LinkLayerAddress.Length; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionLinkLayerAddress);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.OptionCode, (byte)Code);
LinkLayerAddress.Write(buffer, offset + Offset.LinkLayerAddress);
offset += DataLength;
}
private IpV6MobilityOptionLinkLayerAddress()
: this(IpV6MobilityLinkLayerAddressCode.Wildcard, DataSegment.Empty)
{
}
private bool EqualsData(IpV6MobilityOptionLinkLayerAddress other)
{
return other != null &&
Code == other.Code && LinkLayerAddress.Equals(other.LinkLayerAddress);
}
}
/// <summary>
......@@ -782,6 +854,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataMinimumLength + Identifier.Length; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionMobileNodeIdentifier);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.Subtype, (byte)Subtype);
......@@ -793,6 +870,12 @@ namespace PcapDotNet.Packets.IpV6
: this(IpV6MobileNodeIdentifierSubtype.NetworkAccessIdentifier, DataSegment.Empty)
{
}
private bool EqualsData(IpV6MobilityOptionMobileNodeIdentifier other)
{
return other != null &&
Subtype == other.Subtype && Identifier.Equals(other.Identifier);
}
}
/// <summary>
......@@ -922,6 +1005,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataMinimumLength + AuthenticationData.Length; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionAuthentication);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.Subtype, (byte)Subtype);
......@@ -934,6 +1022,13 @@ namespace PcapDotNet.Packets.IpV6
: this(IpV6AuthenticationSubtype.HomeAgent, 0, DataSegment.Empty)
{
}
private bool EqualsData(IpV6MobilityOptionAuthentication other)
{
return other != null &&
Subtype == other.Subtype && MobilitySecurityParameterIndex == other.MobilitySecurityParameterIndex &&
AuthenticationData.Equals(other.AuthenticationData);
}
}
/// <summary>
......@@ -979,10 +1074,21 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override sealed bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionULong);
}
internal override sealed void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, Value, Endianity.Big);
}
private bool EqualsData(IpV6MobilityOptionULong other)
{
return other != null &&
Value == other.Value;
}
}
/// <summary>
......@@ -1045,6 +1151,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal sealed override bool EqualsData(IpV6MobilityOption other)
{
return true;
}
internal override sealed void WriteData(byte[] buffer, ref int offset)
{
}
......@@ -1104,11 +1215,21 @@ namespace PcapDotNet.Packets.IpV6
get { return Value.Length; }
}
internal override sealed bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionSingleDataSegmentField);
}
internal override sealed void WriteData(byte[] buffer, ref int offset)
{
Value.Write(buffer, ref offset);
}
private bool EqualsData(IpV6MobilityOptionSingleDataSegmentField other)
{
return other != null &&
Value.Equals(other.Value);
}
}
/// <summary>
......@@ -1421,8 +1542,9 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataMinimumLength + MobileNodeIdentity.Length; }
}
private IpV6MobilityOptionDnsUpdate() : this(IpV6DnsUpdateStatus.DnsUpdatePerformed, false, DataSegment.Empty)
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionDnsUpdate);
}
internal override void WriteData(byte[] buffer, ref int offset)
......@@ -1435,6 +1557,17 @@ namespace PcapDotNet.Packets.IpV6
buffer.Write(offset + Offset.MobileNodeIdentity, MobileNodeIdentity);
offset += DataLength;
}
private IpV6MobilityOptionDnsUpdate()
: this(IpV6DnsUpdateStatus.DnsUpdatePerformed, false, DataSegment.Empty)
{
}
private bool EqualsData(IpV6MobilityOptionDnsUpdate other)
{
return other != null &&
Status == other.Status && Remove == other.Remove && MobileNodeIdentity.Equals(other.MobileNodeIdentity);
}
}
/// <summary>
......@@ -1552,6 +1685,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataMinimumLength + Data.Length; }
}
internal sealed override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionVendorSpecific);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.VendorId, VendorId, Endianity.Big);
......@@ -1564,6 +1702,12 @@ namespace PcapDotNet.Packets.IpV6
: this(0, 0, DataSegment.Empty)
{
}
private bool EqualsData(IpV6MobilityOptionVendorSpecific other)
{
return other != null &&
VendorId == other.VendorId && SubType == other.SubType && Data.Equals(other.Data);
}
}
/// <summary>
......@@ -1707,6 +1851,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataMinimumLength + Authenticator.Length; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionBindingAuthorizationDataForFmIpV6);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.SecurityParameterIndex, SecurityParameterIndex, Endianity.Big);
......@@ -1718,6 +1867,12 @@ namespace PcapDotNet.Packets.IpV6
: this(0, DataSegment.Empty)
{
}
private bool EqualsData(IpV6MobilityOptionBindingAuthorizationDataForFmIpV6 other)
{
return other != null &&
SecurityParameterIndex == other.SecurityParameterIndex && Authenticator.Equals(other.Authenticator);
}
}
/// <summary>
......@@ -1766,11 +1921,22 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal sealed override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionReservedByteValueByte);
}
internal override sealed void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.Value, Value);
offset += DataLength;
}
private bool EqualsData(IpV6MobilityOptionReservedByteValueByte other)
{
return other != null &&
Value == other.Value;
}
}
/// <summary>
......@@ -1946,7 +2112,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.MobileNodeLinkLayerIdentifier)]
public class IpV6MobilityOptionMobileNodeLinkLayerIdentifier : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionMobileNodeLinkLayerIdentifier : IpV6MobilityOptionComplex
{
private static class Offset
{
......@@ -1980,6 +2146,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataMinimumLength + LinkLayerIdentifier.Length; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionMobileNodeLinkLayerIdentifier);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.LinkLayerIdentifier, LinkLayerIdentifier);
......@@ -1990,6 +2161,12 @@ namespace PcapDotNet.Packets.IpV6
: this(DataSegment.Empty)
{
}
private bool EqualsData(IpV6MobilityOptionMobileNodeLinkLayerIdentifier other)
{
return other != null &&
LinkLayerIdentifier.Equals(other.LinkLayerIdentifier);
}
}
/// <summary>
......@@ -2104,7 +2281,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.RestartCounter)]
public class IpV6MobilityOptionRestartCounter : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionRestartCounter : IpV6MobilityOptionComplex
{
public const int OptionDataLength = sizeof(uint);
......@@ -2133,6 +2310,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionRestartCounter);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, RestartCounter, Endianity.Big);
......@@ -2142,6 +2324,12 @@ namespace PcapDotNet.Packets.IpV6
: this(0)
{
}
private bool EqualsData(IpV6MobilityOptionRestartCounter other)
{
return other != null &&
RestartCounter == other.RestartCounter;
}
}
/// <summary>
......@@ -2160,7 +2348,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.IpV4AddressAcknowledgement)]
public class IpV6MobilityOptionIpV4AddressAcknowledgement : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionIpV4AddressAcknowledgement : IpV6MobilityOptionComplex
{
public const byte MaxPrefixLength = 0x3F;
......@@ -2233,6 +2421,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionIpV4AddressAcknowledgement);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.Status, (byte)Status);
......@@ -2245,6 +2438,12 @@ namespace PcapDotNet.Packets.IpV6
: this(IpV6AddressAcknowledgementStatus.Success, 0, IpV4Address.Zero)
{
}
private bool EqualsData(IpV6MobilityOptionIpV4AddressAcknowledgement other)
{
return other != null &&
Status == other.Status && PrefixLength == other.PrefixLength && HomeAddress.Equals(other.HomeAddress);
}
}
/// <summary>
......@@ -2304,7 +2503,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.IpV4HomeAddress)]
public class IpV6MobilityOptionIpV4HomeAddress : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionIpV4HomeAddress : IpV6MobilityOptionComplex
{
public const byte MaxPrefixLength = 0x3F;
......@@ -2381,6 +2580,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionIpV4HomeAddress);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
byte prefixLengthAndRequestPrefix = (byte)(PrefixLength << Shift.PrefixLength);
......@@ -2396,6 +2600,12 @@ namespace PcapDotNet.Packets.IpV6
: this(0, false, IpV4Address.Zero)
{
}
private bool EqualsData(IpV6MobilityOptionIpV4HomeAddress other)
{
return other != null &&
PrefixLength == other.PrefixLength && RequestPrefix == other.RequestPrefix && HomeAddress.Equals(other.HomeAddress);
}
}
/// <summary>
......@@ -2414,7 +2624,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.NatDetection)]
public class IpV6MobilityOptionNatDetection : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionNatDetection : IpV6MobilityOptionComplex
{
public const uint RecommendedRefreshTime = 110;
......@@ -2469,6 +2679,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionNatDetection);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
byte udpEncapsulationRequired = 0;
......@@ -2484,10 +2699,16 @@ namespace PcapDotNet.Packets.IpV6
: this(false, 0)
{
}
private bool EqualsData(IpV6MobilityOptionNatDetection other)
{
return other != null &&
UdpEncapsulationRequired == other.UdpEncapsulationRequired && RefreshTime == other.RefreshTime;
}
}
/// <summary>
/// RFC 5555.
/// RFC 5555, 5844.
/// <pre>
/// +-----+-------------+--------------+
/// | Bit | 0-7 | 8-15 |
......@@ -2496,53 +2717,101 @@ namespace PcapDotNet.Packets.IpV6
/// +-----+-------------+--------------+
/// | 16 | Reserved |
/// +-----+----------------------------+
/// | 32 | IPv4 Care-of address |
/// | 32 | IPv4 address |
/// | | |
/// +-----+----------------------------+
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.IpV4CareOfAddress)]
public class IpV6MobilityOptionIpV4CareOfAddress : IpV6MobilityOptionComplex
public abstract class IpV6MobilityOptionIpV4Address : IpV6MobilityOptionComplex
{
private static class Offset
{
public const int CareOfAddress = sizeof(ushort);
public const int Address = sizeof(ushort);
}
public const int OptionDataLength = Offset.CareOfAddress + IpV4Address.SizeOf;
public const int OptionDataLength = Offset.Address + IpV4Address.SizeOf;
public IpV6MobilityOptionIpV4CareOfAddress(IpV4Address careOfAddress)
: base(IpV6MobilityOptionType.IpV4CareOfAddress)
internal IpV6MobilityOptionIpV4Address(IpV6MobilityOptionType type, IpV4Address address)
: base(type)
{
CareOfAddress = careOfAddress;
Address = address;
}
/// <summary>
/// Contains the mobile node's IPv4 care-of address.
/// The IPv4 care-of address is used when the mobile node is located in an IPv4-only network.
/// </summary>
public IpV4Address CareOfAddress { get; private set; }
internal IpV4Address Address { get; private set; }
internal override IpV6MobilityOption CreateInstance(DataSegment data)
internal static bool Read(DataSegment data, out IpV4Address address)
{
if (data.Length != OptionDataLength)
return null;
{
address = IpV4Address.Zero;
return false;
}
IpV4Address careOfAddress = data.ReadIpV4Address(Offset.CareOfAddress, Endianity.Big);
return new IpV6MobilityOptionIpV4CareOfAddress(careOfAddress);
address = data.ReadIpV4Address(Offset.Address, Endianity.Big);
return true;
}
internal override int DataLength
internal override sealed int DataLength
{
get { return OptionDataLength; }
}
internal override void WriteData(byte[] buffer, ref int offset)
internal sealed override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionIpV4Address);
}
internal override sealed void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.CareOfAddress, CareOfAddress, Endianity.Big);
buffer.Write(offset + Offset.Address, Address, Endianity.Big);
offset += OptionDataLength;
}
private bool EqualsData(IpV6MobilityOptionIpV4Address other)
{
return other != null &&
Address.Equals(other.Address);
}
}
/// <summary>
/// RFC 5555.
/// <pre>
/// +-----+-------------+--------------+
/// | Bit | 0-7 | 8-15 |
/// +-----+-------------+--------------+
/// | 0 | Option Type | Opt Data Len |
/// +-----+-------------+--------------+
/// | 16 | Reserved |
/// +-----+----------------------------+
/// | 32 | IPv4 Care-of address |
/// | | |
/// +-----+----------------------------+
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.IpV4CareOfAddress)]
public sealed class IpV6MobilityOptionIpV4CareOfAddress : IpV6MobilityOptionIpV4Address
{
public IpV6MobilityOptionIpV4CareOfAddress(IpV4Address careOfAddress)
: base(IpV6MobilityOptionType.IpV4CareOfAddress, careOfAddress)
{
}
/// <summary>
/// Contains the mobile node's IPv4 care-of address.
/// The IPv4 care-of address is used when the mobile node is located in an IPv4-only network.
/// </summary>
public IpV4Address CareOfAddress { get { return Address; } }
internal override IpV6MobilityOption CreateInstance(DataSegment data)
{
IpV4Address careOfAddress;
if (!Read(data, out careOfAddress))
return null;
return new IpV6MobilityOptionIpV4CareOfAddress(careOfAddress);
}
private IpV6MobilityOptionIpV4CareOfAddress()
: this(IpV4Address.Zero)
{
......@@ -2565,7 +2834,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.GreKey)]
public class IpV6MobilityOptionGreKey : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionGreKey : IpV6MobilityOptionComplex
{
private static class Offset
{
......@@ -2601,6 +2870,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionGreKey);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.GreKeyIdentifier, GreKeyIdentifier, Endianity.Big);
......@@ -2611,7 +2885,13 @@ namespace PcapDotNet.Packets.IpV6
: this(0)
{
}
}
private bool EqualsData(IpV6MobilityOptionGreKey other)
{
return other != null &&
GreKeyIdentifier == other.GreKeyIdentifier;
}
}
/// <summary>
/// RFC 5845.
......@@ -2719,6 +2999,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionIpV6AddressPrefix);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.Code, (byte)Code);
......@@ -2731,6 +3016,12 @@ namespace PcapDotNet.Packets.IpV6
: this(IpV6MobilityIpV6AddressPrefixCode.NewCareOfAddress, 0, IpV6Address.Zero)
{
}
private bool EqualsData(IpV6MobilityOptionIpV6AddressPrefix other)
{
return other != null &&
Code == other.Code && PrefixLength == other.PrefixLength && AddressOrPrefix.Equals(other.AddressOrPrefix);
}
}
/// <summary>
......@@ -2880,6 +3171,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataMinimumLength + (IpV4CareOfAddress.HasValue ? IpV4Address.SizeOf : (IpV6CareOfAddress.HasValue ? IpV6Address.SizeOf : 0)); }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionBindingIdentifier);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.BindingId, BindingId, Endianity.Big);
......@@ -2921,6 +3217,13 @@ namespace PcapDotNet.Packets.IpV6
IpV4CareOfAddress = ipV4CareOfAddress;
IpV6CareOfAddress = ipV6CareOfAddress;
}
private bool EqualsData(IpV6MobilityOptionBindingIdentifier other)
{
return other != null &&
BindingId == other.BindingId && Status == other.Status && SimultaneousHomeAndForeignBinding == other.SimultaneousHomeAndForeignBinding &&
Priority == other.Priority && IpV4CareOfAddress.Equals(other.IpV4CareOfAddress) && IpV6CareOfAddress.Equals(other.IpV6CareOfAddress);
}
}
/// <summary>
......@@ -2939,7 +3242,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.IpV4HomeAddressRequest)]
public class IpV6MobilityOptionIpV4HomeAddressRequest : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionIpV4HomeAddressRequest : IpV6MobilityOptionComplex
{
public const byte MaxPrefixLength = 0x3F;
......@@ -2997,6 +3300,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionIpV4HomeAddressRequest);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.PrefixLength, (byte)(PrefixLength << Shift.PrefixLength));
......@@ -3008,6 +3316,12 @@ namespace PcapDotNet.Packets.IpV6
: this(0, IpV4Address.Zero)
{
}
private bool EqualsData(IpV6MobilityOptionIpV4HomeAddressRequest other)
{
return other != null &&
PrefixLength == other.PrefixLength && HomeAddress.Equals(other.HomeAddress);
}
}
/// <summary>
......@@ -3062,7 +3376,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.IpV4HomeAddressReply)]
public class IpV6MobilityOptionIpV4HomeAddressReply : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionIpV4HomeAddressReply : IpV6MobilityOptionComplex
{
public const byte MaxPrefixLength = 0x3F;
......@@ -3129,6 +3443,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionIpV4HomeAddressReply);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.Status, (byte)Status);
......@@ -3141,6 +3460,12 @@ namespace PcapDotNet.Packets.IpV6
: this(IpV6IpV4HomeAddressReplyStatus.Success, 0, IpV4Address.Zero)
{
}
private bool EqualsData(IpV6MobilityOptionIpV4HomeAddressReply other)
{
return other != null &&
Status == other.Status && PrefixLength == other.PrefixLength && HomeAddress.Equals(other.HomeAddress);
}
}
/// <summary>
......@@ -3159,46 +3484,27 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.IpV4DefaultRouterAddress)]
public class IpV6MobilityOptionIpV4DefaultRouterAddress : IpV6MobilityOptionComplex
{
private static class Offset
public class IpV6MobilityOptionIpV4DefaultRouterAddress : IpV6MobilityOptionIpV4Address
{
public const int DefaultRouterAddress = sizeof(ushort);
}
public const int OptionDataLength = Offset.DefaultRouterAddress + IpV4Address.SizeOf;
public IpV6MobilityOptionIpV4DefaultRouterAddress(IpV4Address defaultRouterAddress)
: base(IpV6MobilityOptionType.IpV4DefaultRouterAddress)
: base(IpV6MobilityOptionType.IpV4DefaultRouterAddress, defaultRouterAddress)
{
DefaultRouterAddress = defaultRouterAddress;
}
/// <summary>
/// The mobile node's default router address.
/// </summary>
public IpV4Address DefaultRouterAddress { get; private set; }
public IpV4Address DefaultRouterAddress { get { return Address; } }
internal override IpV6MobilityOption CreateInstance(DataSegment data)
{
if (data.Length != OptionDataLength)
IpV4Address defaultRouterAddress;
if (!Read(data, out defaultRouterAddress))
return null;
IpV4Address defaultRouterAddress = data.ReadIpV4Address(Offset.DefaultRouterAddress, Endianity.Big);
return new IpV6MobilityOptionIpV4DefaultRouterAddress(defaultRouterAddress);
}
internal override int DataLength
{
get { return OptionDataLength; }
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.DefaultRouterAddress, DefaultRouterAddress, Endianity.Big);
offset += OptionDataLength;
}
private IpV6MobilityOptionIpV4DefaultRouterAddress()
: this(IpV4Address.Zero)
{
......@@ -3218,7 +3524,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.IpV4DhcpSupportMode)]
public class IpV6MobilityOptionIpV4DhcpSupportMode : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionIpV4DhcpSupportMode : IpV6MobilityOptionComplex
{
private static class Offset
{
......@@ -3259,6 +3565,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionIpV4DhcpSupportMode);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
if (IsServer)
......@@ -3270,6 +3581,12 @@ namespace PcapDotNet.Packets.IpV6
: this(false)
{
}
private bool EqualsData(IpV6MobilityOptionIpV4DhcpSupportMode other)
{
return other != null &&
IsServer == other.IsServer;
}
}
/// <summary>
......@@ -3345,7 +3662,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.ContextRequest)]
public class IpV6MobilityOptionContextRequest : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionContextRequest : IpV6MobilityOptionComplex
{
public IpV6MobilityOptionContextRequest(params IpV6MobilityOptionContextRequestEntry[] requests)
: this(requests.AsReadOnly())
......@@ -3398,6 +3715,11 @@ namespace PcapDotNet.Packets.IpV6
get { return _dataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionContextRequest);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
foreach (var request in Requests)
......@@ -3409,6 +3731,12 @@ namespace PcapDotNet.Packets.IpV6
{
}
private bool EqualsData(IpV6MobilityOptionContextRequest other)
{
return other != null &&
Requests.SequenceEqual(other.Requests);
}
private readonly int _dataLength;
}
......@@ -3445,7 +3773,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.LocalMobilityAnchorAddress)]
public class IpV6MobilityOptionLocalMobilityAnchorAddress : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionLocalMobilityAnchorAddress : IpV6MobilityOptionComplex
{
private static class Offset
{
......@@ -3529,6 +3857,11 @@ namespace PcapDotNet.Packets.IpV6
}
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionLocalMobilityAnchorAddress);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.Code, (byte)Code);
......@@ -3552,6 +3885,13 @@ namespace PcapDotNet.Packets.IpV6
: this(IpV6Address.Zero)
{
}
private bool EqualsData(IpV6MobilityOptionLocalMobilityAnchorAddress other)
{
return other != null &&
Code == other.Code && LocalMobilityAnchorAddressIpV4.Equals(other.LocalMobilityAnchorAddressIpV4) &&
LocalMobilityAnchorAddressIpV6.Equals(other.LocalMobilityAnchorAddressIpV6);
}
}
/// <summary>
......@@ -3572,7 +3912,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.MobileNodeLinkLocalAddressInterfaceIdentifier)]
public class IpV6MobilityOptionMobileNodeLinkLocalAddressInterfaceIdentifier : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionMobileNodeLinkLocalAddressInterfaceIdentifier : IpV6MobilityOptionComplex
{
private static class Offset
{
......@@ -3606,6 +3946,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionMobileNodeLinkLocalAddressInterfaceIdentifier);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.InterfaceIdentifier, InterfaceIdentifier, Endianity.Big);
......@@ -3616,6 +3961,12 @@ namespace PcapDotNet.Packets.IpV6
: this(0)
{
}
private bool EqualsData(IpV6MobilityOptionMobileNodeLinkLocalAddressInterfaceIdentifier other)
{
return other != null &&
InterfaceIdentifier == other.InterfaceIdentifier;
}
}
/// <summary>
......@@ -3631,7 +3982,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.TransientBinding)]
public class IpV6MobilityOptionTransientBinding : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionTransientBinding : IpV6MobilityOptionComplex
{
private static class Offset
{
......@@ -3680,6 +4031,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionTransientBinding);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
if (LatePathSwitch)
......@@ -3692,6 +4048,12 @@ namespace PcapDotNet.Packets.IpV6
: this(false, 0)
{
}
private bool EqualsData(IpV6MobilityOptionTransientBinding other)
{
return other != null &&
LatePathSwitch == other.LatePathSwitch && Lifetime == other.Lifetime;
}
}
/// <summary>
......@@ -3708,7 +4070,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.FlowSummary)]
public class IpV6MobilityOptionFlowSummary : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionFlowSummary : IpV6MobilityOptionComplex
{
public const int OptionDataMinimumLength = sizeof(ushort);
......@@ -3757,6 +4119,11 @@ namespace PcapDotNet.Packets.IpV6
get { return FlowIdentifiers.Count * sizeof(ushort); }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionFlowSummary);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
foreach (ushort flowIdentifier in FlowIdentifiers)
......@@ -3767,6 +4134,12 @@ namespace PcapDotNet.Packets.IpV6
: this(new ushort[1])
{
}
private bool EqualsData(IpV6MobilityOptionFlowSummary other)
{
return other != null &&
FlowIdentifiers.SequenceEqual(other.FlowIdentifiers);
}
}
/// <summary>
......@@ -3813,13 +4186,18 @@ namespace PcapDotNet.Packets.IpV6
/// <summary>
/// RFC 6089.
/// </summary>
public abstract class IpV6FlowIdentificationSubOption : Option
public abstract class IpV6FlowIdentificationSubOption : Option, IEquatable<IpV6FlowIdentificationSubOption>
{
/// <summary>
/// The type of the option.
/// </summary>
public IpV6FlowIdentificationSubOptionType OptionType { get; private set; }
public override int Length
{
get { return sizeof(byte); }
}
internal abstract IpV6FlowIdentificationSubOption CreateInstance(DataSegment data);
protected IpV6FlowIdentificationSubOption(IpV6FlowIdentificationSubOptionType type)
......@@ -3827,14 +4205,22 @@ namespace PcapDotNet.Packets.IpV6
OptionType = type;
}
internal override void Write(byte[] buffer, ref int offset)
public override sealed bool Equals(Option other)
{
buffer[offset++] = (byte)OptionType;
return Equals(other as IpV6FlowIdentificationSubOption);
}
public override int Length
public bool Equals(IpV6FlowIdentificationSubOption other)
{
get { return sizeof(byte); }
return other != null &&
OptionType == other.OptionType && Length == other.Length && EqualsData(other);
}
internal abstract bool EqualsData(IpV6FlowIdentificationSubOption other);
internal override void Write(byte[] buffer, ref int offset)
{
buffer[offset++] = (byte)OptionType;
}
}
......@@ -3860,6 +4246,11 @@ namespace PcapDotNet.Packets.IpV6
get { return base.Length; }
}
internal override sealed bool EqualsData(IpV6FlowIdentificationSubOption other)
{
return true;
}
internal override sealed void Write(byte[] buffer, ref int offset)
{
base.Write(buffer, ref offset);
......@@ -3938,7 +4329,7 @@ namespace PcapDotNet.Packets.IpV6
/// <summary>
/// RFC 6089.
/// </summary>
public class IpV6FlowIdentificationSubOptions : V6Options<IpV6FlowIdentificationSubOption>
public sealed class IpV6FlowIdentificationSubOptions : V6Options<IpV6FlowIdentificationSubOption>
{
/// <summary>
/// Creates options from a list of options.
......@@ -4063,7 +4454,7 @@ namespace PcapDotNet.Packets.IpV6
public IpV6FlowIdentificationSubOptionType OptionType { get; private set; }
}
public class IpV6FlowIdentificationSubOptionPad1 : IpV6FlowIdentificationSubOptionSimple
public sealed class IpV6FlowIdentificationSubOptionPad1 : IpV6FlowIdentificationSubOptionSimple
{
public const int OptionLength = sizeof(byte);
......@@ -4089,7 +4480,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6FlowIdentificationSubOptionTypeRegistration(IpV6FlowIdentificationSubOptionType.PadN)]
public class IpV6FlowIdentificationSubOptionPadN : IpV6FlowIdentificationSubOptionComplex
public sealed class IpV6FlowIdentificationSubOptionPadN : IpV6FlowIdentificationSubOptionComplex
{
public IpV6FlowIdentificationSubOptionPadN(int paddingDataLength)
: base(IpV6FlowIdentificationSubOptionType.PadN)
......@@ -4109,6 +4500,11 @@ namespace PcapDotNet.Packets.IpV6
get { return PaddingDataLength; }
}
internal override bool EqualsData(IpV6FlowIdentificationSubOption other)
{
return true;
}
internal override void WriteData(byte[] buffer, ref int offset)
{
offset += PaddingDataLength;
......@@ -4133,7 +4529,7 @@ namespace PcapDotNet.Packets.IpV6
/// +-----+----------------------------+
/// </pre>
/// </summary>
public class IpV6FlowIdentificationSubOptionUnknown : IpV6FlowIdentificationSubOptionComplex
public sealed class IpV6FlowIdentificationSubOptionUnknown : IpV6FlowIdentificationSubOptionComplex
{
public IpV6FlowIdentificationSubOptionUnknown(IpV6FlowIdentificationSubOptionType type, DataSegment data)
: base(type)
......@@ -4153,10 +4549,21 @@ namespace PcapDotNet.Packets.IpV6
get { return Data.Length; }
}
internal override bool EqualsData(IpV6FlowIdentificationSubOption other)
{
return EqualsData(other as IpV6FlowIdentificationSubOptionUnknown);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, Data);
}
private bool EqualsData(IpV6FlowIdentificationSubOptionUnknown other)
{
return other != null &&
Data.Equals(other.Data);
}
}
/// <summary>
......@@ -4173,7 +4580,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6FlowIdentificationSubOptionTypeRegistration(IpV6FlowIdentificationSubOptionType.BindingReference)]
public class IpV6FlowIdentificationSubOptionBindingReference : IpV6FlowIdentificationSubOptionComplex
public sealed class IpV6FlowIdentificationSubOptionBindingReference : IpV6FlowIdentificationSubOptionComplex
{
public IpV6FlowIdentificationSubOptionBindingReference(IList<ushort> bindingIds)
: this(bindingIds.AsReadOnly())
......@@ -4218,6 +4625,11 @@ namespace PcapDotNet.Packets.IpV6
get { return BindingIds.Count * sizeof(ushort); }
}
internal override bool EqualsData(IpV6FlowIdentificationSubOption other)
{
return EqualsData(other as IpV6FlowIdentificationSubOptionBindingReference);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
foreach (ushort bindingId in BindingIds)
......@@ -4228,6 +4640,12 @@ namespace PcapDotNet.Packets.IpV6
: this(new ushort[0])
{
}
private bool EqualsData(IpV6FlowIdentificationSubOptionBindingReference other)
{
return other != null &&
BindingIds.SequenceEqual(other.BindingIds);
}
}
/// <summary>
......@@ -4262,7 +4680,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6FlowIdentificationSubOptionTypeRegistration(IpV6FlowIdentificationSubOptionType.TrafficSelector)]
public class IpV6FlowIdentificationSubOptionTrafficSelector : IpV6FlowIdentificationSubOptionComplex
public sealed class IpV6FlowIdentificationSubOptionTrafficSelector : IpV6FlowIdentificationSubOptionComplex
{
private static class Offset
{
......@@ -4304,6 +4722,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataMinimumLength + TrafficSelector.Length; }
}
internal override bool EqualsData(IpV6FlowIdentificationSubOption other)
{
return EqualsData(other as IpV6FlowIdentificationSubOptionTrafficSelector);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.TrafficSelectorFormat, (byte)TrafficSelectorFormat);
......@@ -4315,6 +4738,12 @@ namespace PcapDotNet.Packets.IpV6
: this(IpV6FlowIdentificationTrafficSelectorFormat.IpV4Binary, DataSegment.Empty)
{
}
private bool EqualsData(IpV6FlowIdentificationSubOptionTrafficSelector other)
{
return other != null &&
TrafficSelectorFormat == other.TrafficSelectorFormat && TrafficSelector.Equals(other.TrafficSelector);
}
}
/// <summary>
......@@ -4337,7 +4766,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.FlowIdentification)]
public class IpV6MobilityOptionFlowIdentification : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionFlowIdentification : IpV6MobilityOptionComplex
{
private static class Offset
{
......@@ -4409,6 +4838,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataMinimumLength + SubOptions.BytesLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionFlowIdentification);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.FlowIdentifier, FlowIdentifier, Endianity.Big);
......@@ -4422,7 +4856,13 @@ namespace PcapDotNet.Packets.IpV6
: this(0, 0, IpV6FlowIdentificationStatus.FlowBindingSuccessful, IpV6FlowIdentificationSubOptions.None)
{
}
}
private bool EqualsData(IpV6MobilityOptionFlowIdentification other)
{
return other != null &&
FlowIdentifier == other.FlowIdentifier && Priority == other.Priority && Status == other.Status && SubOptions.Equals(other.SubOptions);
}
}
/// <summary>
/// RFC 6463.
......@@ -4437,7 +4877,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.RedirectCapability)]
public class IpV6MobilityOptionRedirectCapability : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionRedirectCapability : IpV6MobilityOptionComplex
{
public const int OptionDataLength = sizeof(ushort);
......@@ -4459,6 +4899,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return true;
}
internal override void WriteData(byte[] buffer, ref int offset)
{
offset += DataLength;
......@@ -4482,7 +4927,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.Redirect)]
public class IpV6MobilityOptionRedirect : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionRedirect : IpV6MobilityOptionComplex
{
private static class Offset
{
......@@ -4557,6 +5002,11 @@ namespace PcapDotNet.Packets.IpV6
}
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionRedirect);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
if (LocalMobilityAddressIpV4.HasValue)
......@@ -4582,6 +5032,12 @@ namespace PcapDotNet.Packets.IpV6
: this(IpV6Address.Zero)
{
}
private bool EqualsData(IpV6MobilityOptionRedirect other)
{
return other != null &&
LocalMobilityAddressIpV4.Equals(other.LocalMobilityAddressIpV4) && LocalMobilityAddressIpV6.Equals(other.LocalMobilityAddressIpV6);
}
}
/// <summary>
......@@ -4603,7 +5059,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.LoadInformation)]
public class IpV6MobilityOptionLoadInformation : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionLoadInformation : IpV6MobilityOptionComplex
{
private static class Offset
{
......@@ -4673,6 +5129,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionLoadInformation);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.Priority, Priority, Endianity.Big);
......@@ -4687,6 +5148,13 @@ namespace PcapDotNet.Packets.IpV6
: this(0, 0, 0, 0, 0)
{
}
private bool EqualsData(IpV6MobilityOptionLoadInformation other)
{
return other != null &&
Priority == other.Priority && SessionsInUse == other.SessionsInUse && MaximumSessions == other.MaximumSessions &&
UsedCapacity == other.UsedCapacity && MaximumCapacity == other.MaximumCapacity;
}
}
/// <summary>
......@@ -4703,7 +5171,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.AlternateIpV4CareOfAddress)]
public class IpV6MobilityOptionAlternateIpV4CareOfAddress : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionAlternateIpV4CareOfAddress : IpV6MobilityOptionComplex
{
public const int OptionDataLength = IpV4Address.SizeOf;
......@@ -4732,6 +5200,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionAlternateIpV4CareOfAddress);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, AlternateCareOfAddress, Endianity.Big);
......@@ -4741,6 +5214,12 @@ namespace PcapDotNet.Packets.IpV6
: this(IpV4Address.Zero)
{
}
private bool EqualsData(IpV6MobilityOptionAlternateIpV4CareOfAddress other)
{
return other != null &&
AlternateCareOfAddress.Equals(other.AlternateCareOfAddress);
}
}
/// <summary>
......@@ -4770,7 +5249,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.MobileNodeGroupIdentifier)]
public class IpV6MobilityOptionMobileNodeGroupIdentifier : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionMobileNodeGroupIdentifier : IpV6MobilityOptionComplex
{
private static class Offset
{
......@@ -4816,6 +5295,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionMobileNodeGroupIdentifier);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.SubType, (byte)SubType);
......@@ -4827,6 +5311,12 @@ namespace PcapDotNet.Packets.IpV6
: this(IpV6MobileNodeGroupIdentifierSubType.BulkBindingUpdateGroup, 0)
{
}
private bool EqualsData(IpV6MobilityOptionMobileNodeGroupIdentifier other)
{
return other != null &&
SubType == other.SubType && MobileNodeGroupIdentifier == other.MobileNodeGroupIdentifier;
}
}
/// <summary>
......@@ -4851,7 +5341,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.MobileAccessGatewayIpV6Address)]
public class IpV6MobilityOptionMobileAccessGatewayIpV6Address : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionMobileAccessGatewayIpV6Address : IpV6MobilityOptionComplex
{
public const byte AddressLength = 128;
......@@ -4890,6 +5380,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionMobileAccessGatewayIpV6Address);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.AddressLength, AddressLength);
......@@ -4901,6 +5396,12 @@ namespace PcapDotNet.Packets.IpV6
: this(IpV6Address.Zero)
{
}
private bool EqualsData(IpV6MobilityOptionMobileAccessGatewayIpV6Address other)
{
return other != null &&
Address.Equals(other.Address);
}
}
/// <summary>
......@@ -4917,7 +5418,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.AccessNetworkIdentifier)]
public class IpV6MobilityOptionAccessNetworkIdentifier : IpV6MobilityOptionComplex
public sealed class IpV6MobilityOptionAccessNetworkIdentifier : IpV6MobilityOptionComplex
{
public IpV6MobilityOptionAccessNetworkIdentifier(IpV6AccessNetworkIdentifierSubOptions subOptions)
: base(IpV6MobilityOptionType.AccessNetworkIdentifier)
......@@ -4940,6 +5441,11 @@ namespace PcapDotNet.Packets.IpV6
get { return SubOptions.BytesLength; }
}
internal override bool EqualsData(IpV6MobilityOption other)
{
return EqualsData(other as IpV6MobilityOptionAccessNetworkIdentifier);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
SubOptions.Write(buffer, offset);
......@@ -4950,6 +5456,12 @@ namespace PcapDotNet.Packets.IpV6
: this(IpV6AccessNetworkIdentifierSubOptions.None)
{
}
private bool EqualsData(IpV6MobilityOptionAccessNetworkIdentifier other)
{
return other != null &&
SubOptions.Equals(other.SubOptions);
}
}
/// <summary>
......@@ -5101,7 +5613,7 @@ namespace PcapDotNet.Packets.IpV6
/// <summary>
/// RFC 6757.
/// </summary>
public abstract class IpV6AccessNetworkIdentifierSubOption : Option
public abstract class IpV6AccessNetworkIdentifierSubOption : Option, IEquatable<IpV6AccessNetworkIdentifierSubOption>
{
/// <summary>
/// The type of the option.
......@@ -5120,8 +5632,21 @@ namespace PcapDotNet.Packets.IpV6
get { return sizeof(byte) + sizeof(byte) + DataLength; }
}
public bool Equals(IpV6AccessNetworkIdentifierSubOption other)
{
return other != null &&
OptionType == other.OptionType && Length == other.Length && EqualsData(other);
}
public override sealed bool Equals(Option other)
{
return Equals(other as IpV6AccessNetworkIdentifierSubOption);
}
internal abstract int DataLength { get; }
internal abstract bool EqualsData(IpV6AccessNetworkIdentifierSubOption other);
internal override void Write(byte[] buffer, ref int offset)
{
buffer[offset++] = (byte)OptionType;
......@@ -5157,7 +5682,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6AccessNetworkIdentifierSubOptionTypeRegistration(IpV6AccessNetworkIdentifierSubOptionType.NetworkIdentifier)]
public class IpV6AccessNetworkIdentifierSubOptionNetworkIdentifier : IpV6AccessNetworkIdentifierSubOption
public sealed class IpV6AccessNetworkIdentifierSubOptionNetworkIdentifier : IpV6AccessNetworkIdentifierSubOption
{
private static class Offset
{
......@@ -5239,6 +5764,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataMinimumLength + NetworkName.Length + AccessPointName.Length; }
}
internal override bool EqualsData(IpV6AccessNetworkIdentifierSubOption other)
{
return EqualsData(other as IpV6AccessNetworkIdentifierSubOptionNetworkIdentifier);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
if (IsNetworkNameUtf8)
......@@ -5257,6 +5787,12 @@ namespace PcapDotNet.Packets.IpV6
: this(false, DataSegment.Empty, DataSegment.Empty)
{
}
private bool EqualsData(IpV6AccessNetworkIdentifierSubOptionNetworkIdentifier other)
{
return other != null &&
IsNetworkNameUtf8 == other.IsNetworkNameUtf8 && NetworkName.Equals(other.NetworkName) && AccessPointName.Equals(other.AccessPointName);
}
}
/// <summary>
......@@ -5272,7 +5808,7 @@ namespace PcapDotNet.Packets.IpV6
/// +-----+-----------------------+
/// </pre>
/// </summary>
public class IpV6AccessNetworkIdentifierSubOptionUnknown : IpV6AccessNetworkIdentifierSubOption
public sealed class IpV6AccessNetworkIdentifierSubOptionUnknown : IpV6AccessNetworkIdentifierSubOption
{
public IpV6AccessNetworkIdentifierSubOptionUnknown(IpV6AccessNetworkIdentifierSubOptionType type, DataSegment data)
: base(type)
......@@ -5292,10 +5828,21 @@ namespace PcapDotNet.Packets.IpV6
get { return Data.Length; }
}
internal override bool EqualsData(IpV6AccessNetworkIdentifierSubOption other)
{
return EqualsData(other as IpV6AccessNetworkIdentifierSubOptionUnknown);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, Data);
}
private bool EqualsData(IpV6AccessNetworkIdentifierSubOptionUnknown other)
{
return other != null &&
Data.Equals(other.Data);
}
}
/// <summary>
......@@ -5319,7 +5866,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6AccessNetworkIdentifierSubOptionTypeRegistration(IpV6AccessNetworkIdentifierSubOptionType.GeoLocation)]
public class IpV6AccessNetworkIdentifierSubOptionGeoLocation : IpV6AccessNetworkIdentifierSubOption
public sealed class IpV6AccessNetworkIdentifierSubOptionGeoLocation : IpV6AccessNetworkIdentifierSubOption
{
private static class Offset
{
......@@ -5382,6 +5929,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataLength; }
}
internal override bool EqualsData(IpV6AccessNetworkIdentifierSubOption other)
{
return EqualsData(other as IpV6AccessNetworkIdentifierSubOptionGeoLocation);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.LatitudeDegrees, LatitudeDegrees, Endianity.Big);
......@@ -5402,6 +5954,12 @@ namespace PcapDotNet.Packets.IpV6
return (isPositive ? 1 : -1) *
(integerPart + (((double)fractionPart) / (1 << 15)));
}
private bool EqualsData(IpV6AccessNetworkIdentifierSubOptionGeoLocation other)
{
return other != null &&
LatitudeDegrees == other.LatitudeDegrees && LongitudeDegrees == other.LongitudeDegrees;
}
}
/// <summary>
......@@ -5445,7 +6003,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[IpV6AccessNetworkIdentifierSubOptionTypeRegistration(IpV6AccessNetworkIdentifierSubOptionType.OperatorIdentifier)]
public class IpV6AccessNetworkIdentifierSubOptionOperatorIdentifier : IpV6AccessNetworkIdentifierSubOption
public sealed class IpV6AccessNetworkIdentifierSubOptionOperatorIdentifier : IpV6AccessNetworkIdentifierSubOption
{
private static class Offset
{
......@@ -5489,6 +6047,11 @@ namespace PcapDotNet.Packets.IpV6
get { return OptionDataMinimumLength + Identifier.Length; }
}
internal override bool EqualsData(IpV6AccessNetworkIdentifierSubOption other)
{
return EqualsData(other as IpV6AccessNetworkIdentifierSubOptionOperatorIdentifier);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.IdentifierType, (byte)IdentifierType);
......@@ -5500,5 +6063,11 @@ namespace PcapDotNet.Packets.IpV6
: this(IpV6AccessNetworkIdentifierOperatorIdentifierType.PrivateEnterpriseNumber, DataSegment.Empty)
{
}
private bool EqualsData(IpV6AccessNetworkIdentifierSubOptionOperatorIdentifier other)
{
return other != null &&
IdentifierType == other.IdentifierType && Identifier.Equals(other.Identifier);
}
}
}
......@@ -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)
: base(options, isValid, null)
......
......@@ -58,9 +58,9 @@ namespace PcapDotNet.Packets.Transport
/// <summary>
/// Checks if the two options are exactly the same - including type and value.
/// </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>
......
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