Commit 0abdb7bc authored by Brickner_cp's avatar Brickner_cp

293 warnings left.

parent 8c832eed
...@@ -62,6 +62,13 @@ namespace PcapDotNet.Packets ...@@ -62,6 +62,13 @@ namespace PcapDotNet.Packets
return array.Compare(offset, other, otherOffset, count) == 0; return array.Compare(offset, other, otherOffset, count) == 0;
} }
/// <summary>
/// Creates a DataSegment of the given byte array starting from a given offset in the segment taking a given number of bytes.
/// </summary>
/// <param name="array">The array to build the data segment on.</param>
/// <param name="offset">The offset in the array to start taking.</param>
/// <param name="length">The number of bytes to take from the array.</param>
/// <returns>A new DataSegment that is part of the given array.</returns>
public static DataSegment SubSegment(this byte[] array, int offset, int length) public static DataSegment SubSegment(this byte[] array, int offset, int length)
{ {
return new DataSegment(array, offset, length); return new DataSegment(array, offset, length);
......
...@@ -49,6 +49,9 @@ namespace PcapDotNet.Packets.Ethernet ...@@ -49,6 +49,9 @@ namespace PcapDotNet.Packets.Ethernet
} }
} }
/// <summary>
/// A sequence of bytes that includes the trailer bytes and the framce check sequence bytes.
/// </summary>
public DataSegment TrailerWithFrameCheckSequence public DataSegment TrailerWithFrameCheckSequence
{ {
get get
......
...@@ -80,11 +80,25 @@ namespace PcapDotNet.Packets.Ip ...@@ -80,11 +80,25 @@ namespace PcapDotNet.Packets.Ip
return Sequence.GetHashCode(BytesLength, OptionsCollection.SequenceGetHashCode()); return Sequence.GetHashCode(BytesLength, OptionsCollection.SequenceGetHashCode());
} }
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
/// </returns>
/// <filterpriority>1</filterpriority>
public IEnumerator<T> GetEnumerator() public IEnumerator<T> GetEnumerator()
{ {
return OptionsCollection.GetEnumerator(); return OptionsCollection.GetEnumerator();
} }
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
/// <returns>
/// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
/// </returns>
/// <filterpriority>2</filterpriority>
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator()
{ {
return GetEnumerator(); return GetEnumerator();
......
...@@ -32,8 +32,38 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -32,8 +32,38 @@ namespace PcapDotNet.Packets.IpV6
public const int AuthenticationData = SequenceNumber + sizeof(uint); public const int AuthenticationData = SequenceNumber + sizeof(uint);
} }
/// <summary>
/// The minimum number of bytes the extension header takes.
/// </summary>
public const int MinimumLength = Offset.AuthenticationData; public const int MinimumLength = Offset.AuthenticationData;
/// <summary>
/// Creates an instance from next header, security parameter index, sequence number and authenticator.
/// </summary>
/// <param name="nextHeader">
/// Identifies the type of header immediately following this extension header.
/// </param>
/// <param name="securityParametersIndex">
/// The SPI is an arbitrary 32-bit value that, in combination with the destination IP address and security protocol (AH),
/// uniquely identifies the Security Association for this datagram.
/// The set of SPI values in the range 1 through 255 are reserved by the Internet Assigned Numbers Authority (IANA) for future use;
/// a reserved SPI value will not normally be assigned by IANA unless the use of the assigned SPI value is specified in an RFC.
/// It is ordinarily selected by the destination system upon establishment of an SA.
/// </param>
/// <param name="sequenceNumber">
/// Contains a monotonically increasing counter value (sequence number).
/// It is mandatory and is always present even if the receiver does not elect to enable the anti-replay service for a specific SA.
/// Processing of the Sequence Number field is at the discretion of the receiver, i.e., the sender must always transmit this field,
/// but the receiver need not act upon it.
/// </param>
/// <param name="authenticationData">
/// This is a variable-length field that contains the Integrity Check Value (ICV) for this packet.
/// The field must be an integral multiple of 32 bits in length.
/// This field may include explicit padding.
/// This padding is included to ensure that the length of the AH header is an integral multiple of 32 bits (IPv4) or 64 bits (IPv6).
/// All implementations must support such padding.
/// The authentication algorithm specification must specify the length of the ICV and the comparison rules and processing steps for validation.
/// </param>
public IpV6ExtensionHeaderAuthentication(IpV4Protocol nextHeader, uint securityParametersIndex, uint sequenceNumber, DataSegment authenticationData) public IpV6ExtensionHeaderAuthentication(IpV4Protocol nextHeader, uint securityParametersIndex, uint sequenceNumber, DataSegment authenticationData)
: base(nextHeader) : base(nextHeader)
{ {
...@@ -92,6 +122,56 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -92,6 +122,56 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public DataSegment AuthenticationData { get; private set; } public DataSegment AuthenticationData { get; private set; }
/// <summary>
/// Identifies the type of this extension header.
/// </summary>
public override IpV4Protocol Protocol
{
get { return IpV4Protocol.AuthenticationHeader; }
}
/// <summary>
/// The number of bytes this extension header takes.
/// </summary>
public override int Length
{
get { return MinimumLength + AuthenticationData.Length; }
}
/// <summary>
/// True iff the extension header parsing didn't encounter an issue.
/// </summary>
public override bool IsValid
{
get { return true; }
}
/// <summary>
/// True iff the given extension header is equal to this extension header.
/// </summary>
public override bool Equals(IpV6ExtensionHeader other)
{
return Equals(other as IpV6ExtensionHeaderAuthentication);
}
/// <summary>
/// True iff the given extension header is equal to this extension header.
/// </summary>
public bool Equals(IpV6ExtensionHeaderAuthentication other)
{
return other != null &&
NextHeader == other.NextHeader && SecurityParametersIndex == other.SecurityParametersIndex && SequenceNumber == other.SequenceNumber &&
AuthenticationData.Equals(other.AuthenticationData);
}
/// <summary>
/// Returns a hash code of the extension header.
/// </summary>
public override int GetHashCode()
{
return Sequence.GetHashCode(NextHeader, SecurityParametersIndex, SequenceNumber, AuthenticationData);
}
internal static IpV6ExtensionHeaderAuthentication CreateInstance(DataSegment extensionHeaderData, out int numBytesRead) internal static IpV6ExtensionHeaderAuthentication CreateInstance(DataSegment extensionHeaderData, out int numBytesRead)
{ {
if (extensionHeaderData.Length < MinimumLength) if (extensionHeaderData.Length < MinimumLength)
...@@ -115,7 +195,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -115,7 +195,7 @@ namespace PcapDotNet.Packets.IpV6
return new IpV6ExtensionHeaderAuthentication(nextHeader, securityParametersIndex, sequenceNumber, authenticationData); return new IpV6ExtensionHeaderAuthentication(nextHeader, securityParametersIndex, sequenceNumber, authenticationData);
} }
public static void GetNextNextHeaderAndLength(DataSegment extensionHeader, out IpV4Protocol? nextNextHeader, out int extensionHeaderLength) internal static void GetNextNextHeaderAndLength(DataSegment extensionHeader, out IpV4Protocol? nextNextHeader, out int extensionHeaderLength)
{ {
if (extensionHeader.Length < MinimumLength) if (extensionHeader.Length < MinimumLength)
{ {
...@@ -128,38 +208,6 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -128,38 +208,6 @@ namespace PcapDotNet.Packets.IpV6
extensionHeaderLength = (extensionHeader[Offset.PayloadLength] + 2) * 4; extensionHeaderLength = (extensionHeader[Offset.PayloadLength] + 2) * 4;
} }
public override IpV4Protocol Protocol
{
get { return IpV4Protocol.AuthenticationHeader; }
}
public override int Length
{
get { return MinimumLength + AuthenticationData.Length; }
}
public override bool IsValid
{
get { return true; }
}
public override bool Equals(IpV6ExtensionHeader other)
{
return Equals(other as IpV6ExtensionHeaderAuthentication);
}
public bool Equals(IpV6ExtensionHeaderAuthentication other)
{
return other != null &&
NextHeader == other.NextHeader && SecurityParametersIndex == other.SecurityParametersIndex && SequenceNumber == other.SequenceNumber &&
AuthenticationData.Equals(other.AuthenticationData);
}
public override int GetHashCode()
{
return Sequence.GetHashCode(NextHeader, SecurityParametersIndex, SequenceNumber, AuthenticationData);
}
internal override void Write(byte[] buffer, ref int offset) internal override void Write(byte[] buffer, ref int offset)
{ {
buffer.Write(offset + Offset.NextHeader, (byte)NextHeader); buffer.Write(offset + Offset.NextHeader, (byte)NextHeader);
......
...@@ -56,8 +56,31 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -56,8 +56,31 @@ namespace PcapDotNet.Packets.IpV6
public const int PayloadData = SequenceNumber + sizeof(uint); public const int PayloadData = SequenceNumber + sizeof(uint);
} }
/// <summary>
/// The minimum number of bytes the extension header takes.
/// </summary>
public const int MinimumLength = Offset.PayloadData; public const int MinimumLength = Offset.PayloadData;
/// <summary>
/// Creates an instance from security parameter index, sequence number and encrypted data and authentication data.
/// </summary>
/// <param name="securityParametersIndex">
/// The SPI is an arbitrary 32-bit value that, in combination with the destination IP address and security protocol (ESP),
/// uniquely identifies the Security Association for this datagram.
/// The set of SPI values in the range 1 through 255 are reserved by the Internet Assigned Numbers Authority (IANA) for future use;
/// a reserved SPI value will not normally be assigned by IANA unless the use of the assigned SPI value is specified in an RFC.
/// It is ordinarily selected by the destination system upon establishment of an SA (see the Security Architecture document for more details).
/// The SPI field is mandatory.
/// </param>
/// <param name="sequenceNumber">
/// Contains a monotonically increasing counter value (sequence number).
/// It is mandatory and is always present even if the receiver does not elect to enable the anti-replay service for a specific SA.
/// Processing of the Sequence Number field is at the discretion of the receiver, i.e., the sender must always transmit this field,
/// but the receiver need not act upon it.
/// </param>
/// <param name="encryptedDataAndAuthenticationData">
/// Contains the encrypted Payload Data, Padding, Pad Length and Next Header and the Authentication Data.
/// </param>
public IpV6ExtensionHeaderEncapsulatingSecurityPayload(uint securityParametersIndex, uint sequenceNumber, DataSegment encryptedDataAndAuthenticationData) public IpV6ExtensionHeaderEncapsulatingSecurityPayload(uint securityParametersIndex, uint sequenceNumber, DataSegment encryptedDataAndAuthenticationData)
: base(null) : base(null)
{ {
...@@ -66,26 +89,41 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -66,26 +89,41 @@ namespace PcapDotNet.Packets.IpV6
EncryptedDataAndAuthenticationData = encryptedDataAndAuthenticationData; EncryptedDataAndAuthenticationData = encryptedDataAndAuthenticationData;
} }
/// <summary>
/// Identifies the type of this extension header.
/// </summary>
public override IpV4Protocol Protocol public override IpV4Protocol Protocol
{ {
get { return IpV4Protocol.EncapsulatingSecurityPayload; } get { return IpV4Protocol.EncapsulatingSecurityPayload; }
} }
/// <summary>
/// The number of bytes this extension header takes.
/// </summary>
public override int Length public override int Length
{ {
get { return MinimumLength + EncryptedDataAndAuthenticationData.Length; } get { return MinimumLength + EncryptedDataAndAuthenticationData.Length; }
} }
/// <summary>
/// True iff the extension header parsing didn't encounter an issue.
/// </summary>
public override bool IsValid public override bool IsValid
{ {
get { return true; } get { return true; }
} }
/// <summary>
/// True iff the given extension header is equal to this extension header.
/// </summary>
public override bool Equals(IpV6ExtensionHeader other) public override bool Equals(IpV6ExtensionHeader other)
{ {
return Equals(other as IpV6ExtensionHeaderEncapsulatingSecurityPayload); return Equals(other as IpV6ExtensionHeaderEncapsulatingSecurityPayload);
} }
/// <summary>
/// True iff the given extension header is equal to this extension header.
/// </summary>
public bool Equals(IpV6ExtensionHeaderEncapsulatingSecurityPayload other) public bool Equals(IpV6ExtensionHeaderEncapsulatingSecurityPayload other)
{ {
return other != null && return other != null &&
...@@ -93,6 +131,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -93,6 +131,9 @@ namespace PcapDotNet.Packets.IpV6
EncryptedDataAndAuthenticationData.Equals(other.EncryptedDataAndAuthenticationData); EncryptedDataAndAuthenticationData.Equals(other.EncryptedDataAndAuthenticationData);
} }
/// <summary>
/// Returns a hash code of the extension header.
/// </summary>
public override int GetHashCode() public override int GetHashCode()
{ {
return Sequence.GetHashCode(SecurityParametersIndex, SequenceNumber, EncryptedDataAndAuthenticationData); return Sequence.GetHashCode(SecurityParametersIndex, SequenceNumber, EncryptedDataAndAuthenticationData);
...@@ -134,7 +175,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -134,7 +175,7 @@ namespace PcapDotNet.Packets.IpV6
public uint SequenceNumber { get; private set; } public uint SequenceNumber { get; private set; }
/// <summary> /// <summary>
/// Contains the encrupted Payload Data, Padding, Pad Length and Next Header and the Authentication Data. /// Contains the encrypted Payload Data, Padding, Pad Length and Next Header and the Authentication Data.
/// <para> /// <para>
/// Payload Data is a variable-length field containing data described by the Next Header field. /// Payload Data is a variable-length field containing data described by the Next Header field.
/// The Payload Data field is mandatory and is an integral number of bytes in length. /// The Payload Data field is mandatory and is an integral number of bytes in length.
......
...@@ -36,10 +36,32 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -36,10 +36,32 @@ namespace PcapDotNet.Packets.IpV6
public const int FragmentOffset = 3; public const int FragmentOffset = 3;
} }
/// <summary>
/// The number of bytes the extension header data takes.
/// </summary>
public const int ExtensionHeaderDataLength = DataOffset.Identification + sizeof(uint); public const int ExtensionHeaderDataLength = DataOffset.Identification + sizeof(uint);
/// <summary>
/// The maximum value for the fragment offset.
/// </summary>
public const ushort MaxFragmentOffset = 0x1FFF; public const ushort MaxFragmentOffset = 0x1FFF;
/// <summary>
/// Creates an instance from next header, fragment offset, more fragments and identification.
/// </summary>
/// <param name="nextHeader">Identifies the type of header immediately following this extension header.</param>
/// <param name="fragmentOffset">
/// The offset, in 8-octet units, of the data following this header, relative to the start of the Fragmentable Part of the original packet.
/// </param>
/// <param name="moreFragments">
/// True - more fragments.
/// False - last fragment.
/// </param>
/// <param name="identification">
/// For every packet that is to be fragmented, the source node generates an Identification value.
/// The Identification must be different than that of any other fragmented packet sent recently with the same Source Address and Destination Address.
/// If a Routing header is present, the Destination Address of concern is that of the final destination.
/// </param>
public IpV6ExtensionHeaderFragmentData(IpV4Protocol nextHeader, ushort fragmentOffset, bool moreFragments, uint identification) public IpV6ExtensionHeaderFragmentData(IpV4Protocol nextHeader, ushort fragmentOffset, bool moreFragments, uint identification)
: base(nextHeader) : base(nextHeader)
{ {
...@@ -68,11 +90,17 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -68,11 +90,17 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public uint Identification { get; private set; } public uint Identification { get; private set; }
/// <summary>
/// Identifies the type of this extension header.
/// </summary>
public override IpV4Protocol Protocol public override IpV4Protocol Protocol
{ {
get { return IpV4Protocol.FragmentHeaderForIpV6; } get { return IpV4Protocol.FragmentHeaderForIpV6; }
} }
/// <summary>
/// True iff the extension header parsing didn't encounter an issue.
/// </summary>
public override bool IsValid public override bool IsValid
{ {
get { return true; } get { return true; }
......
...@@ -41,6 +41,48 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -41,6 +41,48 @@ namespace PcapDotNet.Packets.IpV6
public const byte TlvHeaderFormat = 0x10; public const byte TlvHeaderFormat = 0x10;
} }
/// <summary>
/// Creates an instance from next header, checksum, status, key management mobility capability, mobile router, proxy registration, TLV header format,
/// sequence number, lifetime and options.
/// </summary>
/// <param name="nextHeader">Identifies the type of header immediately following this extension header.</param>
/// <param name="checksum">
/// Contains the checksum of the Mobility Header.
/// The checksum is calculated from the octet string consisting of a "pseudo-header"
/// followed by the entire Mobility Header starting with the Payload Proto field.
/// The checksum is the 16-bit one's complement of the one's complement sum of this string.
/// </param>
/// <param name="status">
/// Indicating the disposition of the Binding Update.
/// Values of the Status field less than 128 indicate that the Binding Update was accepted by the receiving node.
/// Values greater than or equal to 128 indicate that the Binding Update was rejected by the receiving node.
/// </param>
/// <param name="keyManagementMobilityCapability">
/// If this is cleared, the protocol used by the home agent for establishing the IPsec security associations between the mobile node and the home agent
/// does not survive movements.
/// It may then have to be rerun.
/// (Note that the IPsec security associations themselves are expected to survive movements.)
/// </param>
/// <param name="mobileRouter">
/// Indicates that the Home Agent that processed the Binding Update supports Mobile Routers.
/// True only if the corresponding Binding Update had the Mobile Router set to true.
/// </param>
/// <param name="proxyRegistration">
/// Indicates that the local mobility anchor that processed the corresponding Proxy Binding Update message supports proxy registrations.
/// True only if the corresponding Proxy Binding Update had the Proxy Registration set to true.
/// </param>
/// <param name="tlvHeaderFormat">
/// Indicates that the sender of the Proxy Binding Acknowledgement, the LMA, supports tunneling IPv6-or-IPv4 in IPv4 using TLV-header format.
/// </param>
/// <param name="sequenceNumber">
/// Copied from the Sequence Number field in the Binding Update.
/// It is used by the mobile node in matching this Binding Acknowledgement with an outstanding Binding Update.
/// </param>
/// <param name="lifetime">
/// The granted lifetime, in time units of 4 seconds for Binding Acknowledgement and 1 second for Fast Binding Acknowledgement,
/// for which this node should retain the entry for this mobile node in its Binding Cache.
/// </param>
/// <param name="options">Zero or more TLV-encoded mobility options.</param>
public IpV6ExtensionHeaderMobilityBindingAcknowledgement(IpV4Protocol nextHeader, ushort checksum, IpV6BindingAcknowledgementStatus status, public IpV6ExtensionHeaderMobilityBindingAcknowledgement(IpV4Protocol nextHeader, ushort checksum, IpV6BindingAcknowledgementStatus status,
bool keyManagementMobilityCapability, bool mobileRouter, bool proxyRegistration, bool keyManagementMobilityCapability, bool mobileRouter, bool proxyRegistration,
bool tlvHeaderFormat, ushort sequenceNumber, ushort lifetime, IpV6MobilityOptions options) bool tlvHeaderFormat, ushort sequenceNumber, ushort lifetime, IpV6MobilityOptions options)
......
...@@ -42,6 +42,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -42,6 +42,9 @@ namespace PcapDotNet.Packets.IpV6
public const byte KeyManagementMobilityCapability = 0x80; public const byte KeyManagementMobilityCapability = 0x80;
} }
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
/// <summary> /// <summary>
......
...@@ -40,8 +40,31 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -40,8 +40,31 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = HomeAddress + IpV6Address.SizeOf; public const int Options = HomeAddress + IpV6Address.SizeOf;
} }
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
/// <summary>
/// Creates an instance from next header, checksum, status, home address and options.
/// </summary>
/// <param name="nextHeader">
/// Identifies the type of header immediately following this extension header.
/// </param>
/// <param name="checksum">
/// Contains the checksum of the Mobility Header.
/// The checksum is calculated from the octet string consisting of a "pseudo-header"
/// followed by the entire Mobility Header starting with the Payload Proto field.
/// The checksum is the 16-bit one's complement of the one's complement sum of this string.
/// </param>
/// <param name="status">Indicating the reason for this message.</param>
/// <param name="homeAddress">
/// The home address that was contained in the Home Address destination option.
/// The mobile node uses this information to determine which binding does not exist, in cases where the mobile node has several home addresses.
/// </param>
/// <param name="options">
/// Zero or more TLV-encoded mobility options.
/// </param>
public IpV6ExtensionHeaderMobilityBindingError(IpV4Protocol nextHeader, ushort checksum, IpV6BindingErrorStatus status, IpV6Address homeAddress, public IpV6ExtensionHeaderMobilityBindingError(IpV4Protocol nextHeader, ushort checksum, IpV6BindingErrorStatus status, IpV6Address homeAddress,
IpV6MobilityOptions options) IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
......
...@@ -28,18 +28,27 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -28,18 +28,27 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = 2; public const int Options = 2;
} }
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
/// <summary>
/// Creates an instance from next header, checksum and options.
/// </summary>
/// <param name="nextHeader">Identifies the type of header immediately following this extension header.</param>
/// <param name="checksum">
/// Contains the checksum of the Mobility Header.
/// The checksum is calculated from the octet string consisting of a "pseudo-header"
/// followed by the entire Mobility Header starting with the Payload Proto field.
/// The checksum is the 16-bit one's complement of the one's complement sum of this string.
/// </param>
/// <param name="options">Zero or more TLV-encoded mobility options.</param>
public IpV6ExtensionHeaderMobilityBindingRefreshRequest(IpV4Protocol nextHeader, ushort checksum, IpV6MobilityOptions options) public IpV6ExtensionHeaderMobilityBindingRefreshRequest(IpV4Protocol nextHeader, ushort checksum, IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
} }
internal override int MessageDataLength
{
get { return MinimumMessageDataLength + MobilityOptions.BytesLength; }
}
/// <summary> /// <summary>
/// Identifies the particular mobility message in question. /// Identifies the particular mobility message in question.
/// An unrecognized MH Type field causes an error indication to be sent. /// An unrecognized MH Type field causes an error indication to be sent.
...@@ -49,6 +58,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -49,6 +58,11 @@ namespace PcapDotNet.Packets.IpV6
get { return IpV6MobilityHeaderType.BindingRefreshRequest; } get { return IpV6MobilityHeaderType.BindingRefreshRequest; }
} }
internal override int MessageDataLength
{
get { return MinimumMessageDataLength + MobilityOptions.BytesLength; }
}
internal static IpV6ExtensionHeaderMobilityBindingRefreshRequest ParseMessageData(IpV4Protocol nextHeader, ushort checksum, DataSegment messageData) internal static IpV6ExtensionHeaderMobilityBindingRefreshRequest ParseMessageData(IpV4Protocol nextHeader, ushort checksum, DataSegment messageData)
{ {
if (messageData.Length < MinimumMessageDataLength) if (messageData.Length < MinimumMessageDataLength)
......
...@@ -39,6 +39,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -39,6 +39,9 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = Global + sizeof(byte) + sizeof(byte); public const int Options = Global + sizeof(byte) + sizeof(byte);
} }
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
private static class MessageDataMask private static class MessageDataMask
......
...@@ -47,6 +47,73 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -47,6 +47,73 @@ namespace PcapDotNet.Packets.IpV6
public const byte BulkBindingUpdate = 0x40; public const byte BulkBindingUpdate = 0x40;
} }
/// <summary>
/// Creates an instance from next header, checksum, sequence number, acknowledge, home registration, link local address compatibility,
/// key management mobiltiy capability, map registration, mobile router, proxy registration flag, forcing UDP encapsulation, TLV header format,
/// bulk binding update, lifetime and options.
/// </summary>
/// <param name="nextHeader">Identifies the type of header immediately following this extension header.</param>
/// <param name="checksum">
/// Contains the checksum of the Mobility Header.
/// The checksum is calculated from the octet string consisting of a "pseudo-header"
/// followed by the entire Mobility Header starting with the Payload Proto field.
/// The checksum is the 16-bit one's complement of the one's complement sum of this string.
/// </param>
/// <param name="sequenceNumber">
/// Used by the receiving node to sequence Binding Updates and by the sending node to match a returned Binding Acknowledgement with this Binding Update.
/// </param>
/// <param name="acknowledge">
/// Set by the sending mobile node to request a Binding Acknowledgement be returned upon receipt of the Binding Update.
/// For Fast Binding Update this must be set to one to request that PAR send a Fast Binding Acknowledgement message.
/// </param>
/// <param name="homeRegistration">
/// Set by the sending mobile node to request that the receiving node should act as this node's home agent.
/// The destination of the packet carrying this message must be that of a router sharing the same subnet prefix as the home address
/// of the mobile node in the binding.
/// For Fast Binding Update this must be set to one.
/// </param>
/// <param name="linkLocalAddressCompatibility">
/// Set when the home address reported by the mobile node has the same interface identifier as the mobile node's link-local address.
/// </param>
/// <param name="keyManagementMobilityCapability">
/// If this is cleared, the protocol used for establishing the IPsec security associations between the mobile node and the home agent
/// does not survive movements.
/// It may then have to be rerun. (Note that the IPsec security associations themselves are expected to survive movements.)
/// If manual IPsec configuration is used, the bit must be cleared.
/// </param>
/// <param name="mapRegistration">
/// Indicates MAP registration.
/// When a mobile node registers with the MAP, the MapRegistration and Acknowledge must be set to distinguish this registration
/// from a Binding Update being sent to the Home Agent or a correspondent node.
/// </param>
/// <param name="mobileRouter">
/// Indicates to the Home Agent that the Binding Update is from a Mobile Router.
/// If false, the Home Agent assumes that the Mobile Router is behaving as a Mobile Node,
/// and it must not forward packets destined for the Mobile Network to the Mobile Router.
/// </param>
/// <param name="proxyRegistrationFlag">
/// Indicates to the local mobility anchor that the Binding Update message is a proxy registration.
/// Must be true for proxy registrations and must be false direct registrations sent by a mobile node.
/// </param>
/// <param name="forcingUdpEncapsulation">
/// Indicates a request for forcing UDP encapsulation regardless of whether a NAT is present on the path between the mobile node and the home agent.
/// May be set by the mobile node if it is required to use UDP encapsulation regardless of the presence of a NAT.
/// </param>
/// <param name="tlvHeaderFormat">
/// Indicates that the mobile access gateway requests the use of the TLV header for encapsulating IPv6 or IPv4 packets in IPv4.
/// </param>
/// <param name="bulkBindingUpdate">
/// If true, it informs the local mobility anchor to enable bulk binding update support for the mobility session associated with this message.
/// If false, the local mobility anchor must exclude the mobility session associated with this message from any bulk-binding-related operations
/// and any binding update, or binding revocation operations with bulk-specific scope will not be relevant to that mobility session.
/// This flag is relevant only for Proxy Mobile IPv6 and therefore must be set to false when the ProxyRegistrationFlag is false.
/// </param>
/// <param name="lifetime">
/// The number of time units remaining before the binding must be considered expired.
/// A value of zero indicates that the Binding Cache entry for the mobile node must be deleted.
/// One time unit is 4 seconds for Binding Update and 1 second for Fast Binding Update.
/// </param>
/// <param name="options">Zero or more TLV-encoded mobility options.</param>
public IpV6ExtensionHeaderMobilityBindingUpdate(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool acknowledge, bool homeRegistration, public IpV6ExtensionHeaderMobilityBindingUpdate(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool acknowledge, bool homeRegistration,
bool linkLocalAddressCompatibility, bool keyManagementMobilityCapability, bool mapRegistration, bool linkLocalAddressCompatibility, bool keyManagementMobilityCapability, bool mapRegistration,
bool mobileRouter, bool proxyRegistrationFlag, bool forcingUdpEncapsulation, bool tlvHeaderFormat, bool mobileRouter, bool proxyRegistrationFlag, bool forcingUdpEncapsulation, bool tlvHeaderFormat,
......
...@@ -47,21 +47,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -47,21 +47,11 @@ namespace PcapDotNet.Packets.IpV6
public const byte KeyManagementMobilityCapability = 0x10; public const byte KeyManagementMobilityCapability = 0x10;
} }
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
public IpV6ExtensionHeaderMobilityBindingUpdateBase(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool acknowledge,
bool homeRegistration, bool linkLocalAddressCompatibility, bool keyManagementMobilityCapability,
ushort lifetime, IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options)
{
SequenceNumber = sequenceNumber;
Acknowledge = acknowledge;
HomeRegistration = homeRegistration;
LinkLocalAddressCompatibility = linkLocalAddressCompatibility;
KeyManagementMobilityCapability = keyManagementMobilityCapability;
Lifetime = lifetime;
}
/// <summary> /// <summary>
/// Used by the receiving node to sequence Binding Updates and by the sending node to match a returned Binding Acknowledgement with this Binding Update. /// Used by the receiving node to sequence Binding Updates and by the sending node to match a returned Binding Acknowledgement with this Binding Update.
/// </summary> /// </summary>
...@@ -107,6 +97,19 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -107,6 +97,19 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public ushort Lifetime { get; private set; } public ushort Lifetime { get; private set; }
internal IpV6ExtensionHeaderMobilityBindingUpdateBase(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool acknowledge,
bool homeRegistration, bool linkLocalAddressCompatibility, bool keyManagementMobilityCapability,
ushort lifetime, IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options)
{
SequenceNumber = sequenceNumber;
Acknowledge = acknowledge;
HomeRegistration = homeRegistration;
LinkLocalAddressCompatibility = linkLocalAddressCompatibility;
KeyManagementMobilityCapability = keyManagementMobilityCapability;
Lifetime = lifetime;
}
internal sealed override bool EqualsMessageData(IpV6ExtensionHeaderMobility other) internal sealed override bool EqualsMessageData(IpV6ExtensionHeaderMobility other)
{ {
return EqualsMessageData(other as IpV6ExtensionHeaderMobilityBindingUpdateBase); return EqualsMessageData(other as IpV6ExtensionHeaderMobilityBindingUpdateBase);
......
...@@ -42,8 +42,25 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -42,8 +42,25 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = CareOfKeygenToken + sizeof(ulong); public const int Options = CareOfKeygenToken + sizeof(ulong);
} }
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
/// <summary>
/// Creates an instance from next header, checksum, care of nonce index, care of init cookie, care of keygen token and options.
/// </summary>
/// <param name="nextHeader">Identifies the type of header immediately following this extension header.</param>
/// <param name="checksum">
/// Contains the checksum of the Mobility Header.
/// The checksum is calculated from the octet string consisting of a "pseudo-header"
/// followed by the entire Mobility Header starting with the Payload Proto field.
/// The checksum is the 16-bit one's complement of the one's complement sum of this string.
/// </param>
/// <param name="careOfNonceIndex">Will be echoed back by the mobile node to the correspondent node in a subsequent Binding Update.</param>
/// <param name="careOfInitCookie">Contains the care-of init cookie.</param>
/// <param name="careOfKeygenToken">Contains the 64-bit care-of keygen token used in the return routability procedure.</param>
/// <param name="options">Zero or more TLV-encoded mobility options.</param>
public IpV6ExtensionHeaderMobilityCareOfTest(IpV4Protocol nextHeader, ushort checksum, ushort careOfNonceIndex, ulong careOfInitCookie, public IpV6ExtensionHeaderMobilityCareOfTest(IpV4Protocol nextHeader, ushort checksum, ushort careOfNonceIndex, ulong careOfInitCookie,
ulong careOfKeygenToken, IpV6MobilityOptions options) ulong careOfKeygenToken, IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
......
...@@ -34,8 +34,23 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -34,8 +34,23 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = CareOfInitCookie + sizeof(ulong); public const int Options = CareOfInitCookie + sizeof(ulong);
} }
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
/// <summary>
/// Creates an instance from next header, checksum, care of init cookie and options.
/// </summary>
/// <param name="nextHeader">Identifies the type of header immediately following this extension header.</param>
/// <param name="checksum">
/// Contains the checksum of the Mobility Header.
/// The checksum is calculated from the octet string consisting of a "pseudo-header"
/// followed by the entire Mobility Header starting with the Payload Proto field.
/// The checksum is the 16-bit one's complement of the one's complement sum of this string.
/// </param>
/// <param name="careOfInitCookie">Contains a random value, the care-of init cookie.</param>
/// <param name="options">Zero or more TLV-encoded mobility options.</param>
public IpV6ExtensionHeaderMobilityCareOfTestInit(IpV4Protocol nextHeader, ushort checksum, ulong careOfInitCookie, IpV6MobilityOptions options) public IpV6ExtensionHeaderMobilityCareOfTestInit(IpV4Protocol nextHeader, ushort checksum, ulong careOfInitCookie, IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
......
...@@ -29,8 +29,26 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -29,8 +29,26 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = sizeof(ushort); public const int Options = sizeof(ushort);
} }
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
/// <summary>
/// Creates an instance from next header, checksum and options.
/// </summary>
/// <param name="nextHeader">
/// Identifies the type of header immediately following this extension header.
/// </param>
/// <param name="checksum">
/// Contains the checksum of the Mobility Header.
/// The checksum is calculated from the octet string consisting of a "pseudo-header"
/// followed by the entire Mobility Header starting with the Payload Proto field.
/// The checksum is the 16-bit one's complement of the one's complement sum of this string.
/// </param>
/// <param name="options">
/// Zero or more TLV-encoded mobility options.
/// </param>
public IpV6ExtensionHeaderMobilityFastNeighborAdvertisement(IpV4Protocol nextHeader, ushort checksum, IpV6MobilityOptions options) public IpV6ExtensionHeaderMobilityFastNeighborAdvertisement(IpV4Protocol nextHeader, ushort checksum, IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
......
...@@ -33,8 +33,27 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -33,8 +33,27 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = Code + sizeof(byte); public const int Options = Code + sizeof(byte);
} }
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
/// <summary>
/// Creates an instance from next header, checksum, sequence number, code and options.
/// </summary>
/// <param name="nextHeader">Identifies the type of header immediately following this extension header.</param>
/// <param name="checksum">
/// Contains the checksum of the Mobility Header.
/// The checksum is calculated from the octet string consisting of a "pseudo-header"
/// followed by the entire Mobility Header starting with the Payload Proto field.
/// The checksum is the 16-bit one's complement of the one's complement sum of this string.
/// </param>
/// <param name="sequenceNumber">
/// Copied from the corresponding field in the Handover Initiate message to which this message is a response,
/// to enable the receiver to match this Handover Acknowledge message with an outstanding Handover Initiate message.
/// </param>
/// <param name="code">Describes whether the handover was accepted or not and more details.</param>
/// <param name="options">Zero or more TLV-encoded mobility options.</param>
public IpV6ExtensionHeaderMobilityHandoverAcknowledgeMessage(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, public IpV6ExtensionHeaderMobilityHandoverAcknowledgeMessage(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber,
IpV6MobilityHandoverAcknowledgeCode code, IpV6MobilityOptions options) IpV6MobilityHandoverAcknowledgeCode code, IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
......
...@@ -41,11 +41,35 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -41,11 +41,35 @@ namespace PcapDotNet.Packets.IpV6
public const byte Buffer = 0x40; public const byte Buffer = 0x40;
} }
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
/// <summary>
/// Creates an instance from next header, checksum, sequence number, assigned address configuration, buffer, code and options.
/// </summary>
/// <param name="nextHeader">Identifies the type of header immediately following this extension header.</param>
/// <param name="checksum">
/// Contains the checksum of the Mobility Header.
/// The checksum is calculated from the octet string consisting of a "pseudo-header"
/// followed by the entire Mobility Header starting with the Payload Proto field.
/// The checksum is the 16-bit one's complement of the one's complement sum of this string.
/// </param>
/// <param name="sequenceNumber">Must be set by the sender so replies can be matched to this message.</param>
/// <param name="assignedAddressConfiguration">
/// Assigned address configuration flag.
/// When set to true, this message requests a new CoA to be returned by the destination.
/// May be set when Code = 0. Must be false when Code = 1.
/// </param>
/// <param name="buffer">
/// When set, the destination should buffer any packets toward the node indicated in the options of this message.
/// Used when Code = 0, should be set to false when Code = 1.
/// </param>
/// <param name="code">Describes whether the source ip address is a previous care of address.</param>
/// <param name="options">Zero or more TLV-encoded mobility options.</param>
public IpV6ExtensionHeaderMobilityHandoverInitiateMessage(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool assignedAddressConfiguration, public IpV6ExtensionHeaderMobilityHandoverInitiateMessage(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool assignedAddressConfiguration,
bool buffer, IpV6HandoverInitiateMessageCode code, bool buffer, IpV6HandoverInitiateMessageCode code, IpV6MobilityOptions options)
IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
SequenceNumber = sequenceNumber; SequenceNumber = sequenceNumber;
......
...@@ -41,8 +41,29 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -41,8 +41,29 @@ namespace PcapDotNet.Packets.IpV6
public const byte IsResponse = 0x01; public const byte IsResponse = 0x01;
} }
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
public const int MinimumMessageDataLength = MessageDataOffset.MobilityOptions; public const int MinimumMessageDataLength = MessageDataOffset.MobilityOptions;
/// <summary>
/// Creates an instance from next header, checksum, is unsolicited heartbeat response, is response, sequence number and options.
/// </summary>
/// <param name="nextHeader">Identifies the type of header immediately following this extension header.</param>
/// <param name="checksum">
/// Contains the checksum of the Mobility Header.
/// The checksum is calculated from the octet string consisting of a "pseudo-header"
/// followed by the entire Mobility Header starting with the Payload Proto field.
/// The checksum is the 16-bit one's complement of the one's complement sum of this string.
/// </param>
/// <param name="isUnsolicitedHeartbeatResponse">Set to true in Unsolicited Heartbeat Response.</param>
/// <param name="isResponse">
/// Indicates whether the message is a request or a response.
/// When it's set to false, it indicates that the Heartbeat message is a request.
/// When it's set to true, it indicates that the Heartbeat message is a response.
/// </param>
/// <param name="sequenceNumber">Sequence number used for matching the request to the reply.</param>
/// <param name="options">Zero or more TLV-encoded mobility options.</param>
public IpV6ExtensionHeaderMobilityHeartbeatMessage(IpV4Protocol nextHeader, ushort checksum, bool isUnsolicitedHeartbeatResponse, bool isResponse, public IpV6ExtensionHeaderMobilityHeartbeatMessage(IpV4Protocol nextHeader, ushort checksum, bool isUnsolicitedHeartbeatResponse, bool isResponse,
uint sequenceNumber, IpV6MobilityOptions options) uint sequenceNumber, IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.MobilityOptions) : base(nextHeader, checksum, options, MessageDataOffset.MobilityOptions)
......
...@@ -36,8 +36,23 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -36,8 +36,23 @@ namespace PcapDotNet.Packets.IpV6
public const int HomeAgentAddresses = NumberOfAddresses + sizeof(byte) + sizeof(byte); public const int HomeAgentAddresses = NumberOfAddresses + sizeof(byte) + sizeof(byte);
} }
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
public const int MinimumMessageDataLength = MessageDataOffset.HomeAgentAddresses; public const int MinimumMessageDataLength = MessageDataOffset.HomeAgentAddresses;
/// <summary>
/// Creates an instance from next header, checksum, home agent addresses and options.
/// </summary>
/// <param name="nextHeader">Identifies the type of header immediately following this extension header.</param>
/// <param name="checksum">
/// Contains the checksum of the Mobility Header.
/// The checksum is calculated from the octet string consisting of a "pseudo-header"
/// followed by the entire Mobility Header starting with the Payload Proto field.
/// The checksum is the 16-bit one's complement of the one's complement sum of this string.
/// </param>
/// <param name="homeAgentAddresses">A list of alternate home agent addresses for the mobile node.</param>
/// <param name="options">Zero or more TLV-encoded mobility options.</param>
public IpV6ExtensionHeaderMobilityHomeAgentSwitchMessage(IpV4Protocol nextHeader, ushort checksum, ReadOnlyCollection<IpV6Address> homeAgentAddresses, public IpV6ExtensionHeaderMobilityHomeAgentSwitchMessage(IpV4Protocol nextHeader, ushort checksum, ReadOnlyCollection<IpV6Address> homeAgentAddresses,
IpV6MobilityOptions options) IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.HomeAgentAddresses + homeAgentAddresses.Count * IpV6Address.SizeOf) : base(nextHeader, checksum, options, MessageDataOffset.HomeAgentAddresses + homeAgentAddresses.Count * IpV6Address.SizeOf)
...@@ -45,6 +60,18 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -45,6 +60,18 @@ namespace PcapDotNet.Packets.IpV6
HomeAgentAddresses = homeAgentAddresses; HomeAgentAddresses = homeAgentAddresses;
} }
/// <summary>
/// Creates an instance from next header, checksum, home agent addresses and options.
/// </summary>
/// <param name="nextHeader">Identifies the type of header immediately following this extension header.</param>
/// <param name="checksum">
/// Contains the checksum of the Mobility Header.
/// The checksum is calculated from the octet string consisting of a "pseudo-header"
/// followed by the entire Mobility Header starting with the Payload Proto field.
/// The checksum is the 16-bit one's complement of the one's complement sum of this string.
/// </param>
/// <param name="homeAgentAddresses">A list of alternate home agent addresses for the mobile node.</param>
/// <param name="options">Zero or more TLV-encoded mobility options.</param>
public IpV6ExtensionHeaderMobilityHomeAgentSwitchMessage(IpV4Protocol nextHeader, ushort checksum, IList<IpV6Address> homeAgentAddresses, IpV6MobilityOptions options) public IpV6ExtensionHeaderMobilityHomeAgentSwitchMessage(IpV4Protocol nextHeader, ushort checksum, IList<IpV6Address> homeAgentAddresses, IpV6MobilityOptions options)
: this(nextHeader, checksum, (ReadOnlyCollection<IpV6Address>)homeAgentAddresses.AsReadOnly(), options) : this(nextHeader, checksum, (ReadOnlyCollection<IpV6Address>)homeAgentAddresses.AsReadOnly(), options)
{ {
......
...@@ -42,8 +42,25 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -42,8 +42,25 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = HomeKeygenToken + sizeof(ulong); public const int Options = HomeKeygenToken + sizeof(ulong);
} }
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
/// <summary>
/// Creates an instance from next header, checksum, home nonce index, home init cookie, home keygen token and options.
/// </summary>
/// <param name="nextHeader">Identifies the type of header immediately following this extension header.</param>
/// <param name="checksum">
/// Contains the checksum of the Mobility Header.
/// The checksum is calculated from the octet string consisting of a "pseudo-header"
/// followed by the entire Mobility Header starting with the Payload Proto field.
/// The checksum is the 16-bit one's complement of the one's complement sum of this string.
/// </param>
/// <param name="homeNonceIndex">Will be echoed back by the mobile node to the correspondent node in a subsequent Binding Update.</param>
/// <param name="homeInitCookie">Contains the home init cookie.</param>
/// <param name="homeKeygenToken">Contains the 64-bit home keygen token used in the return routability procedure.</param>
/// <param name="options">Zero or more TLV-encoded mobility options.</param>
public IpV6ExtensionHeaderMobilityHomeTest(IpV4Protocol nextHeader, ushort checksum, ushort homeNonceIndex, ulong homeInitCookie, ulong homeKeygenToken, public IpV6ExtensionHeaderMobilityHomeTest(IpV4Protocol nextHeader, ushort checksum, ushort homeNonceIndex, ulong homeInitCookie, ulong homeKeygenToken,
IpV6MobilityOptions options) IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
......
...@@ -34,8 +34,23 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -34,8 +34,23 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = HomeInitCookie + sizeof(ulong); public const int Options = HomeInitCookie + sizeof(ulong);
} }
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
/// <summary>
/// Creates an instance from next header, checksum, home init cookie and options.
/// </summary>
/// <param name="nextHeader">Identifies the type of header immediately following this extension header.</param>
/// <param name="checksum">
/// Contains the checksum of the Mobility Header.
/// The checksum is calculated from the octet string consisting of a "pseudo-header"
/// followed by the entire Mobility Header starting with the Payload Proto field.
/// The checksum is the 16-bit one's complement of the one's complement sum of this string.
/// </param>
/// <param name="homeInitCookie">Contains a random value, the home init cookie.</param>
/// <param name="options">Zero or more TLV-encoded mobility options.</param>
public IpV6ExtensionHeaderMobilityHomeTestInit(IpV4Protocol nextHeader, ushort checksum, ulong homeInitCookie, IpV6MobilityOptions options) public IpV6ExtensionHeaderMobilityHomeTestInit(IpV4Protocol nextHeader, ushort checksum, ulong homeInitCookie, IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
......
...@@ -40,16 +40,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -40,16 +40,11 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = Lifetime + sizeof(ushort); public const int Options = Lifetime + sizeof(ushort);
} }
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
public IpV6ExtensionHeaderMobilityLocalizedRouting(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, ushort lifetime,
IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options)
{
SequenceNumber = sequenceNumber;
Lifetime = lifetime;
}
/// <summary> /// <summary>
/// In initiation, a monotonically increasing integer. Set by a sending node in a request message, and used to match a reply to the request. /// In initiation, a monotonically increasing integer. Set by a sending node in a request message, and used to match a reply to the request.
/// In acknowledgement, copied from the sequence number field of the LRI message being responded to. /// In acknowledgement, copied from the sequence number field of the LRI message being responded to.
...@@ -65,6 +60,14 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -65,6 +60,14 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public ushort Lifetime { get; private set; } public ushort Lifetime { get; private set; }
internal IpV6ExtensionHeaderMobilityLocalizedRouting(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, ushort lifetime,
IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options)
{
SequenceNumber = sequenceNumber;
Lifetime = lifetime;
}
internal override int MessageDataLength internal override int MessageDataLength
{ {
get { return MinimumMessageDataLength + MobilityOptions.BytesLength; } get { return MinimumMessageDataLength + MobilityOptions.BytesLength; }
......
...@@ -39,8 +39,31 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -39,8 +39,31 @@ namespace PcapDotNet.Packets.IpV6
public const byte Unsolicited = 0x80; public const byte Unsolicited = 0x80;
} }
public IpV6ExtensionHeaderMobilityLocalizedRoutingAcknowledgement(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool unsolicited, IpV6MobilityLocalizedRoutingAcknowledgementStatus status, /// <summary>
ushort lifetime, IpV6MobilityOptions options) /// Creates an instance from next header, checksum, sequence number, unsolicited, status, lifetime and options.
/// </summary>
/// <param name="nextHeader">Identifies the type of header immediately following this extension header.</param>
/// <param name="checksum">
/// Contains the checksum of the Mobility Header.
/// The checksum is calculated from the octet string consisting of a "pseudo-header"
/// followed by the entire Mobility Header starting with the Payload Proto field.
/// The checksum is the 16-bit one's complement of the one's complement sum of this string.
/// </param>
/// <param name="sequenceNumber">Copied from the sequence number field of the LRI message being responded to.</param>
/// <param name="unsolicited">
/// When true, the LRA message is sent unsolicited.
/// The Lifetime field indicates a new requested value.
/// The MAG must wait for the regular LRI message to confirm that the request is acceptable to the LMA.
/// </param>
/// <param name="status">The acknowledgement status.</param>
/// <param name="lifetime">
/// The time in seconds for which the local forwarding is supported.
/// Typically copied from the corresponding field in the LRI message.
/// </param>
/// <param name="options">Zero or more TLV-encoded mobility options.</param>
public IpV6ExtensionHeaderMobilityLocalizedRoutingAcknowledgement(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool unsolicited,
IpV6MobilityLocalizedRoutingAcknowledgementStatus status, ushort lifetime,
IpV6MobilityOptions options)
: base(nextHeader, checksum, sequenceNumber, lifetime, options) : base(nextHeader, checksum, sequenceNumber, lifetime, options)
{ {
Status = status; Status = status;
...@@ -54,6 +77,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -54,6 +77,9 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public bool Unsolicited { get; private set; } public bool Unsolicited { get; private set; }
/// <summary>
/// The acknowledgement status.
/// </summary>
public IpV6MobilityLocalizedRoutingAcknowledgementStatus Status { get; private set; } public IpV6MobilityLocalizedRoutingAcknowledgementStatus Status { get; private set; }
/// <summary> /// <summary>
......
...@@ -40,15 +40,12 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -40,15 +40,12 @@ namespace PcapDotNet.Packets.IpV6
/// The checksum is the 16-bit one's complement of the one's complement sum of this string. /// The checksum is the 16-bit one's complement of the one's complement sum of this string.
/// </param> /// </param>
/// <param name="sequenceNumber"> /// <param name="sequenceNumber">
/// In initiation, a monotonically increasing integer. Set by a sending node in a request message, and used to match a reply to the request. /// A monotonically increasing integer. Set by a sending node in a request message, and used to match a reply to the request.
/// In acknowledgement, copied from the sequence number field of the LRI message being responded to.
/// </param> /// </param>
/// <param name="lifetime"> /// <param name="lifetime">
/// In initiation, the requested time in seconds for which the sender wishes to have local forwarding. /// The requested time in seconds for which the sender wishes to have local forwarding.
/// A value of 0xffff (all ones) indicates an infinite lifetime. /// A value of 0xffff (all ones) indicates an infinite lifetime.
/// When set to 0, indicates a request to stop localized routing. /// When set to 0, indicates a request to stop localized routing.
/// In acknowledgement, the time in seconds for which the local forwarding is supported.
/// Typically copied from the corresponding field in the LRI message.
/// </param> /// </param>
/// <param name="options"> /// <param name="options">
/// Zero or more TLV-encoded mobility options. /// Zero or more TLV-encoded mobility options.
......
...@@ -58,10 +58,37 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -58,10 +58,37 @@ namespace PcapDotNet.Packets.IpV6
public const int PadSize = 4; public const int PadSize = 4;
} }
/// <summary>
/// The minimum number of bytes the routing data takes.
/// </summary>
public const int RoutingDataMinimumLength = RoutingDataOffset.Addresses; public const int RoutingDataMinimumLength = RoutingDataOffset.Addresses;
/// <summary>
/// The maximum common prefix length.
/// </summary>
public const byte MaxCommonPrefixLength = IpV6Address.SizeOf - 1; public const byte MaxCommonPrefixLength = IpV6Address.SizeOf - 1;
/// <summary>
/// The maximum padding size.
/// </summary>
public const byte MaxPadSize = IpV6Address.SizeOf - 1; public const byte MaxPadSize = IpV6Address.SizeOf - 1;
/// <summary>
/// Creates an instance from next header, segments left, common prefix length for non last addresses, common prefix length for last address and addresses.
/// </summary>
/// <param name="nextHeader">Identifies the type of header immediately following this extension header.</param>
/// <param name="segmentsLeft">
/// Number of route segments remaining, i.e., number of explicitly listed intermediate nodes still to be visited before reaching the final destination.
/// </param>
/// <param name="commonPrefixLengthForNonLastAddresses">
/// Number of prefix octets from each segment, except than the last segment, (i.e., segments 1 through n-1) that are elided.
/// For example, a header carrying full IPv6 addresses in Addresses[1..n-1] sets this to 0.
/// </param>
/// <param name="commonPrefixLengthForLastAddress">
/// Number of prefix octets from the last segment (i.e., segment n) that are elided.
/// For example, a header carrying a full IPv6 address in Addresses[n] sets this to 0.
/// </param>
/// <param name="addresses">Routing addresses.</param>
public IpV6ExtensionHeaderRoutingRpl(IpV4Protocol nextHeader, byte segmentsLeft, byte commonPrefixLengthForNonLastAddresses, public IpV6ExtensionHeaderRoutingRpl(IpV4Protocol nextHeader, byte segmentsLeft, byte commonPrefixLengthForNonLastAddresses,
byte commonPrefixLengthForLastAddress, params IpV6Address[] addresses) byte commonPrefixLengthForLastAddress, params IpV6Address[] addresses)
: base(nextHeader, segmentsLeft) : base(nextHeader, segmentsLeft)
...@@ -108,6 +135,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -108,6 +135,9 @@ namespace PcapDotNet.Packets.IpV6
} }
} }
/// <summary>
/// Identifier of a particular Routing header variant.
/// </summary>
public override IpV6RoutingType RoutingType public override IpV6RoutingType RoutingType
{ {
get { return IpV6RoutingType.RplSourceRouteHeader; } get { return IpV6RoutingType.RplSourceRouteHeader; }
...@@ -130,6 +160,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -130,6 +160,9 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public byte PadSize { get; private set; } public byte PadSize { get; private set; }
/// <summary>
/// Routing addresses.
/// </summary>
public ReadOnlyCollection<IpV6Address> Addresses { get; private set; } public ReadOnlyCollection<IpV6Address> Addresses { get; private set; }
internal override int RoutingDataLength internal override int RoutingDataLength
......
...@@ -44,19 +44,36 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -44,19 +44,36 @@ namespace PcapDotNet.Packets.IpV6
public const int Addresses = Reserved + sizeof(uint); public const int Addresses = Reserved + sizeof(uint);
} }
/// <summary>
/// The minimum number of bytes the routing data takes.
/// </summary>
public const int RoutingDataMinimumLength = RoutingDataOffset.Addresses; public const int RoutingDataMinimumLength = RoutingDataOffset.Addresses;
/// <summary>
/// Creates an instance from next header, segments left and addresses.
/// </summary>
/// <param name="nextHeader">Identifies the type of header immediately following this extension header.</param>
/// <param name="segmentsLeft">
/// Number of route segments remaining, i.e., number of explicitly listed intermediate nodes still to be visited before reaching the final destination.
/// </param>
/// <param name="addresses">Routing addresses.</param>
public IpV6ExtensionHeaderRoutingSourceRoute(IpV4Protocol nextHeader, byte segmentsLeft, params IpV6Address[] addresses) public IpV6ExtensionHeaderRoutingSourceRoute(IpV4Protocol nextHeader, byte segmentsLeft, params IpV6Address[] addresses)
: base(nextHeader, segmentsLeft) : base(nextHeader, segmentsLeft)
{ {
Addresses = addresses.AsReadOnly(); Addresses = addresses.AsReadOnly();
} }
/// <summary>
/// Identifier of a particular Routing header variant.
/// </summary>
public override IpV6RoutingType RoutingType public override IpV6RoutingType RoutingType
{ {
get { return IpV6RoutingType.SourceRoute; } get { return IpV6RoutingType.SourceRoute; }
} }
/// <summary>
/// Routing addresses.
/// </summary>
public ReadOnlyCollection<IpV6Address> Addresses { get; private set; } public ReadOnlyCollection<IpV6Address> Addresses { get; private set; }
internal override int RoutingDataLength internal override int RoutingDataLength
......
...@@ -27,19 +27,33 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -27,19 +27,33 @@ namespace PcapDotNet.Packets.IpV6
public const int Data = HeaderExtensionLength + sizeof(byte); public const int Data = HeaderExtensionLength + sizeof(byte);
} }
/// <summary>
/// The minimum number of bytes the extension header takes.
/// </summary>
public const int MinimumLength = 8; public const int MinimumLength = 8;
/// <summary>
/// True iff the given extension header is equal to this extension header.
/// </summary>
public sealed override bool Equals(IpV6ExtensionHeader other) public sealed override bool Equals(IpV6ExtensionHeader other)
{ {
return other != null && return other != null &&
Protocol == other.Protocol && NextHeader == other.NextHeader && EqualsData(other); Protocol == other.Protocol && NextHeader == other.NextHeader && EqualsData(other);
} }
/// <summary>
/// Returns a hash code of the extension header.
/// </summary>
public sealed override int GetHashCode() public sealed override int GetHashCode()
{ {
return Sequence.GetHashCode(Protocol, NextHeader, GetDataHashCode()); return Sequence.GetHashCode(Protocol, NextHeader, GetDataHashCode());
} }
/// <summary>
/// The number of bytes this extension header takes.
/// </summary>
public sealed override int Length { get { return Offset.Data + DataLength; } }
internal abstract bool EqualsData(IpV6ExtensionHeader other); internal abstract bool EqualsData(IpV6ExtensionHeader other);
internal abstract int GetDataHashCode(); internal abstract int GetDataHashCode();
...@@ -60,8 +74,8 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -60,8 +74,8 @@ namespace PcapDotNet.Packets.IpV6
internal abstract void WriteData(byte[] buffer, int offset); internal abstract void WriteData(byte[] buffer, int offset);
public sealed override int Length { get { return Offset.Data + DataLength; } }
internal abstract int DataLength { get; } internal abstract int DataLength { get; }
internal static bool IsStandard(IpV4Protocol nextHeader) internal static bool IsStandard(IpV4Protocol nextHeader)
{ {
switch (nextHeader) switch (nextHeader)
...@@ -77,6 +91,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -77,6 +91,7 @@ namespace PcapDotNet.Packets.IpV6
return false; return false;
} }
} }
internal static IpV6ExtensionHeader CreateInstanceStandard(IpV4Protocol nextHeader, DataSegment extensionHeaderData, out int numBytesRead) internal static IpV6ExtensionHeader CreateInstanceStandard(IpV4Protocol nextHeader, DataSegment extensionHeaderData, out int numBytesRead)
{ {
numBytesRead = 0; numBytesRead = 0;
......
...@@ -14,7 +14,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -14,7 +14,7 @@ namespace PcapDotNet.Packets.IpV6
public class IpV6ExtensionHeaders : IEnumerable<IpV6ExtensionHeader>, IEquatable<IpV6ExtensionHeaders> public class IpV6ExtensionHeaders : IEnumerable<IpV6ExtensionHeader>, IEquatable<IpV6ExtensionHeaders>
{ {
/// <summary> /// <summary>
/// Create an object from a ReadOnlyCollection of extension headers. /// Create an instance from a ReadOnlyCollection of extension headers.
/// Verifies that there's at most one Encapsulating Security Payload extension header and that it is the last extension header. /// Verifies that there's at most one Encapsulating Security Payload extension header and that it is the last extension header.
/// Assumes the collection won't be modified. /// Assumes the collection won't be modified.
/// </summary> /// </summary>
...@@ -34,39 +34,86 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -34,39 +34,86 @@ namespace PcapDotNet.Packets.IpV6
IsValid = true; IsValid = true;
} }
/// <summary>
/// Create an instance from an array of extension headers.
/// Verifies that there's at most one Encapsulating Security Payload extension header and that it is the last extension header.
/// Assumes the collection won't be modified.
/// </summary>
/// <param name="extensionHeaders">The extension headers.</param>
public IpV6ExtensionHeaders(params IpV6ExtensionHeader[] extensionHeaders) public IpV6ExtensionHeaders(params IpV6ExtensionHeader[] extensionHeaders)
: this(extensionHeaders.AsReadOnly()) : this(extensionHeaders.AsReadOnly())
{ {
} }
/// <summary>
/// Create an instance from a list of extension headers.
/// Verifies that there's at most one Encapsulating Security Payload extension header and that it is the last extension header.
/// Assumes the collection won't be modified.
/// </summary>
/// <param name="extensionHeaders">The extension headers.</param>
public IpV6ExtensionHeaders(IList<IpV6ExtensionHeader> extensionHeaders) public IpV6ExtensionHeaders(IList<IpV6ExtensionHeader> extensionHeaders)
: this(extensionHeaders.AsReadOnly()) : this(extensionHeaders.AsReadOnly())
{ {
} }
/// <summary>
/// Create an instance from an enumerable of extension headers.
/// Verifies that there's at most one Encapsulating Security Payload extension header and that it is the last extension header.
/// Assumes the collection won't be modified.
/// </summary>
/// <param name="extensionHeaders">The extension headers.</param>
public IpV6ExtensionHeaders(IEnumerable<IpV6ExtensionHeader> extensionHeaders) public IpV6ExtensionHeaders(IEnumerable<IpV6ExtensionHeader> extensionHeaders)
: this((IpV6ExtensionHeader[])extensionHeaders.ToArray()) : this((IpV6ExtensionHeader[])extensionHeaders.ToArray())
{ {
} }
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
/// </returns>
/// <filterpriority>1</filterpriority>
public IEnumerator<IpV6ExtensionHeader> GetEnumerator() public IEnumerator<IpV6ExtensionHeader> GetEnumerator()
{ {
return Headers.GetEnumerator(); return Headers.GetEnumerator();
} }
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
/// <returns>
/// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
/// </returns>
/// <filterpriority>2</filterpriority>
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator()
{ {
return GetEnumerator(); return GetEnumerator();
} }
/// <summary>
/// Returns the extension header in the 'index' place.
/// </summary>
/// <param name="index">The index of the extension header returned.</param>
/// <returns>The extension header in the 'index' place.</returns>
public IpV6ExtensionHeader this[int index] public IpV6ExtensionHeader this[int index]
{ {
get { return Headers[index]; } get { return Headers[index]; }
} }
/// <summary>
/// The extension headers.
/// </summary>
public ReadOnlyCollection<IpV6ExtensionHeader> Headers { get; private set; } public ReadOnlyCollection<IpV6ExtensionHeader> Headers { get; private set; }
/// <summary>
/// True iff a parsing issue wasn't encountered when parsing the extension headers.
/// </summary>
public bool IsValid { get; private set; } public bool IsValid { get; private set; }
/// <summary>
/// The protocol of the first extension header or null if there are no extension headers.
/// </summary>
public IpV4Protocol? FirstHeader public IpV4Protocol? FirstHeader
{ {
get get
...@@ -77,6 +124,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -77,6 +124,9 @@ namespace PcapDotNet.Packets.IpV6
} }
} }
/// <summary>
/// The protocol of the last extension header or null if there are no extension headers.
/// </summary>
public IpV4Protocol? LastHeader public IpV4Protocol? LastHeader
{ {
get get
...@@ -87,6 +137,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -87,6 +137,9 @@ namespace PcapDotNet.Packets.IpV6
} }
} }
/// <summary>
/// The next header of the last extension header or null if there are no extension headers.
/// </summary>
public IpV4Protocol? NextHeader public IpV4Protocol? NextHeader
{ {
get get
...@@ -97,21 +150,33 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -97,21 +150,33 @@ namespace PcapDotNet.Packets.IpV6
} }
} }
/// <summary>
/// An empty list of extension headers.
/// </summary>
public static IpV6ExtensionHeaders Empty public static IpV6ExtensionHeaders Empty
{ {
get { return _empty; } get { return _empty; }
} }
/// <summary>
/// True iff all the extension headers are equal to the given extension headers instance.
/// </summary>
public sealed override bool Equals(object obj) public sealed override bool Equals(object obj)
{ {
return Equals(obj as IpV6ExtensionHeaders); return Equals(obj as IpV6ExtensionHeaders);
} }
/// <summary>
/// True iff all the extension headers are equal to the given extension headers instance.
/// </summary>
public bool Equals(IpV6ExtensionHeaders other) public bool Equals(IpV6ExtensionHeaders other)
{ {
return other != null && this.SequenceEqual(other); return other != null && this.SequenceEqual(other);
} }
/// <summary>
/// A hash code based on all the extension headers.
/// </summary>
public override int GetHashCode() public override int GetHashCode()
{ {
return this.SequenceGetHashCode(); return this.SequenceGetHashCode();
......
...@@ -144,28 +144,27 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -144,28 +144,27 @@ namespace PcapDotNet.Packets.IpV6
public override string ToString() public override string ToString()
{ {
return ToString(CultureInfo.InvariantCulture); return ToString(CultureInfo.InvariantCulture);
string valueString = _value.ToString("X33", CultureInfo.InvariantCulture).Substring(1);
StringBuilder stringBuilder = new StringBuilder(39);
for (int i = 0; i != 8; ++i)
{
if (i != 0)
stringBuilder.Append(':');
stringBuilder.Append(valueString.Substring(i * 4, 4));
}
return stringBuilder.ToString();
} }
/// <summary>
/// Translates the address to a string given the format.
/// </summary>
public string ToString(string format) public string ToString(string format)
{ {
return ToString(format, CultureInfo.InvariantCulture); return ToString(format, CultureInfo.InvariantCulture);
} }
/// <summary>
/// Translates the address to a string given the format provider.
/// </summary>
public string ToString(IFormatProvider provider) public string ToString(IFormatProvider provider)
{ {
return ToString("X4", CultureInfo.InvariantCulture); return ToString("X4", CultureInfo.InvariantCulture);
} }
/// <summary>
/// Translates the address to a string given the format and format provider.
/// </summary>
public string ToString(string format, IFormatProvider provider) public string ToString(string format, IFormatProvider provider)
{ {
StringBuilder stringBuilder = new StringBuilder(39); StringBuilder stringBuilder = new StringBuilder(39);
......
...@@ -39,6 +39,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -39,6 +39,9 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public const int HeaderLength = 40; public const int HeaderLength = 40;
/// <summary>
/// Maximum flow label value.
/// </summary>
public const int MaxFlowLabel = 0xFFFFF; public const int MaxFlowLabel = 0xFFFFF;
private static class Offset private static class Offset
...@@ -65,6 +68,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -65,6 +68,7 @@ namespace PcapDotNet.Packets.IpV6
public const int Version = 4; public const int Version = 4;
public const int TrafficClass = 4; public const int TrafficClass = 4;
} }
/// <summary> /// <summary>
/// The version (6). /// The version (6).
/// </summary> /// </summary>
...@@ -107,6 +111,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -107,6 +111,9 @@ namespace PcapDotNet.Packets.IpV6
get { return ReadUShort(Offset.PayloadLength, Endianity.Big); } get { return ReadUShort(Offset.PayloadLength, Endianity.Big); }
} }
/// <summary>
/// The actual payload length
/// </summary>
public ushort RealPayloadLength public ushort RealPayloadLength
{ {
get get
...@@ -151,6 +158,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -151,6 +158,9 @@ namespace PcapDotNet.Packets.IpV6
get { return ReadIpV6Address(Offset.DestinationAddress, Endianity.Big); } get { return ReadIpV6Address(Offset.DestinationAddress, Endianity.Big); }
} }
/// <summary>
/// The IPv6 extension headers.
/// </summary>
public IpV6ExtensionHeaders ExtensionHeaders public IpV6ExtensionHeaders ExtensionHeaders
{ {
get get
...@@ -192,6 +202,14 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -192,6 +202,14 @@ namespace PcapDotNet.Packets.IpV6
}; };
} }
/// <summary>
/// The default validity check always returns true.
/// </summary>
protected override bool CalculateIsValid()
{
ParseExtensionHeaders();
return _isValid;
}
internal IpV6Datagram(byte[] buffer, int offset, int length) internal IpV6Datagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length) : base(buffer, offset, length)
...@@ -228,12 +246,6 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -228,12 +246,6 @@ namespace PcapDotNet.Packets.IpV6
extensionHeaders.Write(buffer, offset + HeaderLength); extensionHeaders.Write(buffer, offset + HeaderLength);
} }
protected override bool CalculateIsValid()
{
ParseExtensionHeaders();
return _isValid;
}
private IpV6ExtensionHeaders _extensionHeaders; private IpV6ExtensionHeaders _extensionHeaders;
private bool _isValid = true; private bool _isValid = true;
} }
......
...@@ -59,6 +59,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -59,6 +59,9 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public IpV6Address CurrentDestination { get; set; } public IpV6Address CurrentDestination { get; set; }
/// <summary>
/// The IPv6 extension headers.
/// </summary>
public IpV6ExtensionHeaders ExtensionHeaders { get; set; } public IpV6ExtensionHeaders ExtensionHeaders { get; set; }
/// <summary> /// <summary>
......
...@@ -32,8 +32,24 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -32,8 +32,24 @@ namespace PcapDotNet.Packets.IpV6
public const int LongitudeDegrees = LatitudeDegrees + UInt24.SizeOf; public const int LongitudeDegrees = LatitudeDegrees + UInt24.SizeOf;
} }
/// <summary>
/// The number of bytes this option data takes.
/// </summary>
public const int OptionDataLength = Offset.LongitudeDegrees + UInt24.SizeOf; public const int OptionDataLength = Offset.LongitudeDegrees + UInt24.SizeOf;
/// <summary>
/// Creates an instance from latitude and longtitude degrees using integer numbers encoded as a two's complement, fixed point number with 9 whole bits.
/// See <see cref="IpV6AccessNetworkIdentifierSubOptionGeoLocation.CreateFromRealValues"/> for using real numbers for the degrees.
/// </summary>
/// <param name="latitudeDegrees">
/// A 24-bit latitude degree value encoded as a two's complement, fixed point number with 9 whole bits.
/// Positive degrees correspond to the Northern Hemisphere and negative degrees correspond to the Southern Hemisphere.
/// The value ranges from -90 to +90 degrees.
/// </param>
/// <param name="longitudeDegrees">
/// A 24-bit longitude degree value encoded as a two's complement, fixed point number with 9 whole bits.
/// The value ranges from -180 to +180 degrees.
/// </param>
public IpV6AccessNetworkIdentifierSubOptionGeoLocation(UInt24 latitudeDegrees, UInt24 longitudeDegrees) public IpV6AccessNetworkIdentifierSubOptionGeoLocation(UInt24 latitudeDegrees, UInt24 longitudeDegrees)
: base(IpV6AccessNetworkIdentifierSubOptionType.GeoLocation) : base(IpV6AccessNetworkIdentifierSubOptionType.GeoLocation)
{ {
...@@ -49,6 +65,17 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -49,6 +65,17 @@ namespace PcapDotNet.Packets.IpV6
throw new ArgumentOutOfRangeException("longitudeDegrees", longitudeDegrees, string.Format("LongitudeDegreesReal is {0} and must be in [-180, 180] range.", longtitudeDegreesReal)); throw new ArgumentOutOfRangeException("longitudeDegrees", longitudeDegrees, string.Format("LongitudeDegreesReal is {0} and must be in [-180, 180] range.", longtitudeDegreesReal));
} }
/// <summary>
/// Creates an instance from latitude and longtitude degrees using real numbers.
/// </summary>
/// <param name="latitudeDegreesReal">
/// Positive degrees correspond to the Northern Hemisphere and negative degrees correspond to the Southern Hemisphere.
/// The value ranges from -90 to +90 degrees.
/// </param>
/// <param name="longtitudeDegreesReal">
/// The value ranges from -180 to +180 degrees.
/// </param>
/// <returns>An instance created from the given real degrees values.</returns>
public static IpV6AccessNetworkIdentifierSubOptionGeoLocation CreateFromRealValues(double latitudeDegreesReal, double longtitudeDegreesReal) public static IpV6AccessNetworkIdentifierSubOptionGeoLocation CreateFromRealValues(double latitudeDegreesReal, double longtitudeDegreesReal)
{ {
if (latitudeDegreesReal < -90 || latitudeDegreesReal > 90) if (latitudeDegreesReal < -90 || latitudeDegreesReal > 90)
......
...@@ -42,8 +42,39 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -42,8 +42,39 @@ namespace PcapDotNet.Packets.IpV6
public const byte IsNetworkNameUtf8 = 0x80; public const byte IsNetworkNameUtf8 = 0x80;
} }
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.NetworkName + sizeof(byte); public const int OptionDataMinimumLength = Offset.NetworkName + sizeof(byte);
/// <summary>
/// Creates an instance from is network name UTF8, network name and access point name.
/// </summary>
/// <param name="isNetworkNameUtf8">
/// Indicates whether the Network Name is encoded in UTF-8.
/// If true, then the Network Name is encoded using UTF-8.
/// If false, this indicates that the encoding is undefined and is determined by out-of-band mechanisms.
/// </param>
/// <param name="networkName">
/// The name of the access network to which the mobile node is attached.
/// The type of the Network Name is dependent on the access technology to which the mobile node is attached.
/// If it is 802.11 access, the Network Name must be the SSID of the network.
/// If the access network is 3GPP access, the Network Name is the PLMN Identifier of the network.
/// If the access network is 3GPP2 access, the Network Name is the Access Network Identifier.
///
/// When encoding the PLMN Identifier, both the Mobile Network Code (MNC) and Mobile Country Code (MCC) must be 3 digits.
/// If the MNC in use only has 2 digits, then it must be preceded with a '0'.
/// Encoding must be UTF-8.
/// </param>
/// <param name="accessPointName">
/// The name of the access point (physical device name) to which the mobile node is attached.
/// This is the identifier that uniquely identifies the access point.
/// While Network Name (e.g., SSID) identifies the operator's access network,
/// Access-Point Name identifies a specific network device in the network to which the mobile node is attached.
/// In some deployments, the Access-Point Name can be set to the Media Access Control (MAC) address of the device or some unique identifier
/// that can be used by the policy systems in the operator network to unambiguously identify the device.
/// The string is carried in UTF-8 representation.
/// </param>
public IpV6AccessNetworkIdentifierSubOptionNetworkIdentifier(bool isNetworkNameUtf8, DataSegment networkName, DataSegment accessPointName) public IpV6AccessNetworkIdentifierSubOptionNetworkIdentifier(bool isNetworkNameUtf8, DataSegment networkName, DataSegment accessPointName)
: base(IpV6AccessNetworkIdentifierSubOptionType.NetworkIdentifier) : base(IpV6AccessNetworkIdentifierSubOptionType.NetworkIdentifier)
{ {
......
...@@ -28,8 +28,19 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -28,8 +28,19 @@ namespace PcapDotNet.Packets.IpV6
public const int Identifier = IdentifierType + sizeof(byte); public const int Identifier = IdentifierType + sizeof(byte);
} }
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.Identifier; public const int OptionDataMinimumLength = Offset.Identifier;
/// <summary>
/// Creates an instance from identifier type and identifier.
/// </summary>
/// <param name="identifierType">Indicates the type of the Operator-Identifier.</param>
/// <param name="identifier">
/// Up to 253 octets of the Operator-Identifier.
/// The encoding of the identifier depends on the used Operator-Identifier Type.
/// </param>
public IpV6AccessNetworkIdentifierSubOptionOperatorIdentifier(IpV6AccessNetworkIdentifierOperatorIdentifierType identifierType, DataSegment identifier) public IpV6AccessNetworkIdentifierSubOptionOperatorIdentifier(IpV6AccessNetworkIdentifierOperatorIdentifierType identifierType, DataSegment identifier)
: base(IpV6AccessNetworkIdentifierSubOptionType.OperatorIdentifier) : base(IpV6AccessNetworkIdentifierSubOptionType.OperatorIdentifier)
{ {
......
...@@ -31,6 +31,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -31,6 +31,11 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public const int OptionDataMinimumLength = Offset.TrafficSelector; public const int OptionDataMinimumLength = Offset.TrafficSelector;
/// <summary>
/// Creates an instance from traffic selector format and traffic selector.
/// </summary>
/// <param name="trafficSelectorFormat">Indicates the Traffic Selector Format.</param>
/// <param name="trafficSelector">The traffic selector formatted according to TrafficSelectorFormat.</param>
public IpV6FlowIdentificationSubOptionTrafficSelector(IpV6FlowIdentificationTrafficSelectorFormat trafficSelectorFormat, DataSegment trafficSelector) public IpV6FlowIdentificationSubOptionTrafficSelector(IpV6FlowIdentificationTrafficSelectorFormat trafficSelectorFormat, DataSegment trafficSelector)
: base(IpV6FlowIdentificationSubOptionType.TrafficSelector) : base(IpV6FlowIdentificationSubOptionType.TrafficSelector)
{ {
......
...@@ -35,6 +35,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -35,6 +35,9 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public IpV6AccessNetworkIdentifierSubOptions SubOptions { get; private set; } public IpV6AccessNetworkIdentifierSubOptions SubOptions { get; private set; }
/// <summary>
/// True iff parsing of this option didn't encounter issues.
/// </summary>
public override bool IsValid public override bool IsValid
{ {
get { return SubOptions.IsValid; } get { return SubOptions.IsValid; }
......
...@@ -34,8 +34,22 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -34,8 +34,22 @@ namespace PcapDotNet.Packets.IpV6
public const int AuthenticationData = MobilitySecurityParameterIndex + sizeof(uint); public const int AuthenticationData = MobilitySecurityParameterIndex + sizeof(uint);
} }
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.AuthenticationData; public const int OptionDataMinimumLength = Offset.AuthenticationData;
/// <summary>
/// Creates an instance from subtype, mobility security parameter index and authentication data.
/// </summary>
/// <param name="subtype">A number assigned to identify the entity and/or mechanism to be used to authenticate the message.</param>
/// <param name="mobilitySecurityParameterIndex">
/// A number in the range [0-4294967296] used to index into the shared-key-based mobility security associations.
/// </param>
/// <param name="authenticationData">
/// Has the information to authenticate the relevant mobility entity.
/// This protects the message beginning at the Mobility Header up to and including the mobility SPI field.
/// </param>
public IpV6MobilityOptionAuthentication(IpV6AuthenticationSubtype subtype, uint mobilitySecurityParameterIndex, DataSegment authenticationData) public IpV6MobilityOptionAuthentication(IpV6AuthenticationSubtype subtype, uint mobilitySecurityParameterIndex, DataSegment authenticationData)
: base(IpV6MobilityOptionType.Authentication) : base(IpV6MobilityOptionType.Authentication)
{ {
......
...@@ -27,8 +27,21 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -27,8 +27,21 @@ namespace PcapDotNet.Packets.IpV6
public const int Authenticator = SecurityParameterIndex + sizeof(uint); public const int Authenticator = SecurityParameterIndex + sizeof(uint);
} }
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.Authenticator; public const int OptionDataMinimumLength = Offset.Authenticator;
/// <summary>
/// Creates an instance from security parameter index and authenticator.
/// </summary>
/// <param name="securityParameterIndex">
/// SPI = 0 is reserved for the Authenticator computed using SEND-based handover keys.
/// </param>
/// <param name="authenticator">
/// Contains a cryptographic value that can be used to determine that the message in question comes from the right authority.
/// Rules for calculating this value depends on the used authorization procedure.
/// </param>
public IpV6MobilityOptionBindingAuthorizationDataForFmIpV6(uint securityParameterIndex, DataSegment authenticator) public IpV6MobilityOptionBindingAuthorizationDataForFmIpV6(uint securityParameterIndex, DataSegment authenticator)
: base(IpV6MobilityOptionType.BindingAuthorizationDataForFmIpV6) : base(IpV6MobilityOptionType.BindingAuthorizationDataForFmIpV6)
{ {
......
...@@ -64,16 +64,25 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -64,16 +64,25 @@ namespace PcapDotNet.Packets.IpV6
Option.Write(buffer, ref offset); Option.Write(buffer, ref offset);
} }
/// <summary>
/// Two entries are equal iff their type and option are equal.
/// </summary>
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
return Equals(obj as IpV6MobilityOptionContextRequestEntry); return Equals(obj as IpV6MobilityOptionContextRequestEntry);
} }
/// <summary>
/// Two entries are equal iff their request type and option are equal.
/// </summary>
public bool Equals(IpV6MobilityOptionContextRequestEntry other) public bool Equals(IpV6MobilityOptionContextRequestEntry other)
{ {
return (other != null && RequestType.Equals(other.RequestType) && Option.Equals(other.Option)); return (other != null && RequestType.Equals(other.RequestType) && Option.Equals(other.Option));
} }
/// <summary>
/// A hash code based on the request type and option.
/// </summary>
public override int GetHashCode() public override int GetHashCode()
{ {
return Sequence.GetHashCode(RequestType, Option); return Sequence.GetHashCode(RequestType, Option);
......
...@@ -32,8 +32,28 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -32,8 +32,28 @@ namespace PcapDotNet.Packets.IpV6
public const byte Remove = 0x80; public const byte Remove = 0x80;
} }
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.MobileNodeIdentity; public const int OptionDataMinimumLength = Offset.MobileNodeIdentity;
/// <summary>
/// Creates an instance from status, remove and mobile node identity.
/// </summary>
/// <param name="status">
/// Indicating the result of the dynamic DNS update procedure.
/// This field must be set to 0 and ignored by the receiver when the DNS Update mobility option is included in a Binding Update message.
/// When the DNS Update mobility option is included in the Binding Acknowledgement message,
/// values of the Status field less than 128 indicate that the dynamic DNS update was performed successfully by the Home Agent.
/// Values greater than or equal to 128 indicate that the dynamic DNS update was not completed by the HA.
/// </param>
/// <param name="remove">
/// Whether the Mobile Node is requesting the HA to remove the DNS entry identified by the FQDN specified in this option and the HoA of the Mobile Node.
/// If false, the Mobile Node is requesting the HA to create or update a DNS entry with its HoA and the FQDN specified in the option.
/// </param>
/// <param name="mobileNodeIdentity">
/// The identity of the Mobile Node in FQDN format to be used by the Home Agent to send a Dynamic DNS update.
/// </param>
public IpV6MobilityOptionDnsUpdate(IpV6DnsUpdateStatus status, bool remove, DataSegment mobileNodeIdentity) public IpV6MobilityOptionDnsUpdate(IpV6DnsUpdateStatus status, bool remove, DataSegment mobileNodeIdentity)
: base(IpV6MobilityOptionType.DnsUpdate) : base(IpV6MobilityOptionType.DnsUpdate)
{ {
......
...@@ -33,8 +33,35 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -33,8 +33,35 @@ namespace PcapDotNet.Packets.IpV6
public const int SubOptions = Status + sizeof(byte); public const int SubOptions = Status + sizeof(byte);
} }
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.SubOptions; public const int OptionDataMinimumLength = Offset.SubOptions;
/// <summary>
/// Creates an instance from flow identifier, priority, status and sub options.
/// </summary>
/// <param name="flowIdentifier">
/// Includes the unique identifier for the flow binding.
/// This field is used to refer to an existing flow binding or to create a new flow binding.
/// The value of this field is set by the mobile node.
/// FID = 0 is reserved and must not be used.
/// </param>
/// <param name="priority">
/// Indicates the priority of a particular option.
/// This field is needed in cases where two different flow descriptions in two different options overlap.
/// The priority field decides which policy should be executed in those cases.
/// A lower number in this field indicates a higher priority.
/// Value '0' is reserved and must not be used.
/// Must be unique to each of the flows pertaining to a given MN.
/// In other words, two FIDs must not be associated with the same priority value.
/// </param>
/// <param name="status">
/// indicates the success or failure of the flow binding operation for the particular flow in the option.
/// This field is not relevant to the binding update message as a whole or to other flow identification options.
/// This field is only relevant when included in the Binding Acknowledgement message and must be ignored in the binding update message.
/// </param>
/// <param name="subOptions">Zero or more sub-options.</param>
public IpV6MobilityOptionFlowIdentification(ushort flowIdentifier, ushort priority, IpV6FlowIdentificationStatus status, public IpV6MobilityOptionFlowIdentification(ushort flowIdentifier, ushort priority, IpV6FlowIdentificationStatus status,
IpV6FlowIdentificationSubOptions subOptions) IpV6FlowIdentificationSubOptions subOptions)
: base(IpV6MobilityOptionType.FlowIdentification) : base(IpV6MobilityOptionType.FlowIdentification)
...@@ -82,6 +109,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -82,6 +109,9 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public IpV6FlowIdentificationSubOptions SubOptions { get; private set; } public IpV6FlowIdentificationSubOptions SubOptions { get; private set; }
/// <summary>
/// True iff parsing of this option didn't encounter issues.
/// </summary>
public override bool IsValid public override bool IsValid
{ {
get { return SubOptions.IsValid; } get { return SubOptions.IsValid; }
......
...@@ -25,8 +25,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -25,8 +25,11 @@ namespace PcapDotNet.Packets.IpV6
/// </pre> /// </pre>
/// </summary> /// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.IpV6AddressPrefix)] [IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.IpV6AddressPrefix)]
public class IpV6MobilityOptionIpV6AddressPrefix : IpV6MobilityOptionComplex public sealed class IpV6MobilityOptionIpV6AddressPrefix : IpV6MobilityOptionComplex
{ {
/// <summary>
/// The maximum value for prefix length.
/// </summary>
public const byte MaxPrefixLength = 128; public const byte MaxPrefixLength = 128;
private static class Offset private static class Offset
...@@ -36,8 +39,20 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -36,8 +39,20 @@ namespace PcapDotNet.Packets.IpV6
public const int AddressOrPrefix = PrefixLength + sizeof(byte); public const int AddressOrPrefix = PrefixLength + sizeof(byte);
} }
/// <summary>
/// The number of bytes this option data takes.
/// </summary>
public const int OptionDataLength = Offset.AddressOrPrefix + IpV6Address.SizeOf; public const int OptionDataLength = Offset.AddressOrPrefix + IpV6Address.SizeOf;
/// <summary>
/// Creates an instance from code, prefix length and address or prefix.
/// </summary>
/// <param name="code">Describes the kind of the address or the prefix.</param>
/// <param name="prefixLength">
/// Indicates the length of the IPv6 Address Prefix.
/// The value ranges from 0 to 128.
/// </param>
/// <param name="addressOrPrefix">The IP address/prefix defined by the Option-Code field.</param>
public IpV6MobilityOptionIpV6AddressPrefix(IpV6MobilityIpV6AddressPrefixCode code, byte prefixLength, IpV6Address addressOrPrefix) public IpV6MobilityOptionIpV6AddressPrefix(IpV6MobilityIpV6AddressPrefixCode code, byte prefixLength, IpV6Address addressOrPrefix)
: base(IpV6MobilityOptionType.IpV6AddressPrefix) : base(IpV6MobilityOptionType.IpV6AddressPrefix)
{ {
......
...@@ -28,8 +28,16 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -28,8 +28,16 @@ namespace PcapDotNet.Packets.IpV6
public const int LinkLayerAddress = OptionCode + sizeof(byte); public const int LinkLayerAddress = OptionCode + sizeof(byte);
} }
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.LinkLayerAddress; public const int OptionDataMinimumLength = Offset.LinkLayerAddress;
/// <summary>
/// Creates an instance from code and link layer address.
/// </summary>
/// <param name="code">The type of link layer address option.</param>
/// <param name="linkLayerAddress">Variable-length link-layer address.</param>
public IpV6MobilityOptionLinkLayerAddress(IpV6MobilityLinkLayerAddressCode code, DataSegment linkLayerAddress) public IpV6MobilityOptionLinkLayerAddress(IpV6MobilityLinkLayerAddressCode code, DataSegment linkLayerAddress)
: base(IpV6MobilityOptionType.LinkLayerAddress) : base(IpV6MobilityOptionType.LinkLayerAddress)
{ {
...@@ -37,6 +45,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -37,6 +45,9 @@ namespace PcapDotNet.Packets.IpV6
LinkLayerAddress = linkLayerAddress; LinkLayerAddress = linkLayerAddress;
} }
/// <summary>
/// The type of link layer address option.
/// </summary>
public IpV6MobilityLinkLayerAddressCode Code { get; private set; } public IpV6MobilityLinkLayerAddressCode Code { get; private set; }
/// <summary> /// <summary>
......
...@@ -32,8 +32,24 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -32,8 +32,24 @@ namespace PcapDotNet.Packets.IpV6
public const int MaximumCapacity = UsedCapacity + sizeof(uint); public const int MaximumCapacity = UsedCapacity + sizeof(uint);
} }
/// <summary>
/// The number of bytes this option data takes.
/// </summary>
public const int OptionDataLength = Offset.MaximumCapacity + sizeof(uint); public const int OptionDataLength = Offset.MaximumCapacity + sizeof(uint);
/// <summary>
/// Creates an instance from priority, sessions in use, maximum sessions, used capacity and maximum capacity.
/// </summary>
/// <param name="priority">
/// Represents the priority of an LMA.
/// The lower value, the higher the priority.
/// The priority only has meaning among a group of LMAs under the same administration, for example, determined by a common LMA FQDN, a domain name,
/// or a realm.
/// </param>
/// <param name="sessionsInUse">Represents the number of parallel mobility sessions the LMA has in use.</param>
/// <param name="maximumSessions">Represents the maximum number of parallel mobility sessions the LMA is willing to accept.</param>
/// <param name="usedCapacity">Represents the used bandwidth/throughput capacity of the LMA in kilobytes per second.</param>
/// <param name="maximumCapacity">Represents the maximum bandwidth/throughput capacity in kilobytes per second the LMA is willing to accept.</param>
public IpV6MobilityOptionLoadInformation(ushort priority, uint sessionsInUse, uint maximumSessions, uint usedCapacity, uint maximumCapacity) public IpV6MobilityOptionLoadInformation(ushort priority, uint sessionsInUse, uint maximumSessions, uint usedCapacity, uint maximumCapacity)
: base(IpV6MobilityOptionType.LoadInformation) : base(IpV6MobilityOptionType.LoadInformation)
{ {
......
...@@ -28,25 +28,26 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -28,25 +28,26 @@ namespace PcapDotNet.Packets.IpV6
public const int LocalMobilityAnchorAddress = Code + sizeof(byte) + sizeof(byte); public const int LocalMobilityAnchorAddress = Code + sizeof(byte) + sizeof(byte);
} }
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.LocalMobilityAnchorAddress; public const int OptionDataMinimumLength = Offset.LocalMobilityAnchorAddress;
public IpV6MobilityOptionLocalMobilityAnchorAddress(IpV6LocalMobilityAnchorAddressCode code, IpV4Address localMobilityAnchorAddress) /// <summary>
: this(code, localMobilityAnchorAddress, null) /// Creates an instance from IPv4 local mobility anchor address with IPv4 code.
{ /// </summary>
} /// <param name="localMobilityAnchorAddress">The LMA IPv4 address (IPv4-LMA).</param>
public IpV6MobilityOptionLocalMobilityAnchorAddress(IpV6LocalMobilityAnchorAddressCode code, IpV6Address localMobilityAnchorAddress)
: this(code, null, localMobilityAnchorAddress)
{
}
public IpV6MobilityOptionLocalMobilityAnchorAddress(IpV4Address localMobilityAnchorAddress) public IpV6MobilityOptionLocalMobilityAnchorAddress(IpV4Address localMobilityAnchorAddress)
: this(IpV6LocalMobilityAnchorAddressCode.IpV4, localMobilityAnchorAddress) : this(IpV6LocalMobilityAnchorAddressCode.IpV4, localMobilityAnchorAddress, null)
{ {
} }
/// <summary>
/// Creates an instance from IPv6 local mobility anchor address with IPv6 code.
/// </summary>
/// <param name="localMobilityAnchorAddress">The LMA IPv6 address (LMAA).</param>
public IpV6MobilityOptionLocalMobilityAnchorAddress(IpV6Address localMobilityAnchorAddress) public IpV6MobilityOptionLocalMobilityAnchorAddress(IpV6Address localMobilityAnchorAddress)
: this(IpV6LocalMobilityAnchorAddressCode.IpV6, localMobilityAnchorAddress) : this(IpV6LocalMobilityAnchorAddressCode.IpV6, null, localMobilityAnchorAddress)
{ {
} }
......
...@@ -31,15 +31,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -31,15 +31,11 @@ namespace PcapDotNet.Packets.IpV6
public const int NetworkPrefix = PrefixLength + sizeof(byte); public const int NetworkPrefix = PrefixLength + sizeof(byte);
} }
/// <summary>
/// The number of bytes this option data takes.
/// </summary>
public const int OptionDataLength = Offset.NetworkPrefix + IpV6Address.SizeOf; public const int OptionDataLength = Offset.NetworkPrefix + IpV6Address.SizeOf;
public IpV6MobilityOptionNetworkPrefix(IpV6MobilityOptionType type, byte prefixLength, IpV6Address networkPrefix)
: base(type)
{
PrefixLength = prefixLength;
NetworkPrefix = networkPrefix;
}
/// <summary> /// <summary>
/// Indicates the prefix length of the IPv6 prefix contained in the option. /// Indicates the prefix length of the IPv6 prefix contained in the option.
/// </summary> /// </summary>
...@@ -50,6 +46,13 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -50,6 +46,13 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public IpV6Address NetworkPrefix { get; private set; } public IpV6Address NetworkPrefix { get; private set; }
internal IpV6MobilityOptionNetworkPrefix(IpV6MobilityOptionType type, byte prefixLength, IpV6Address networkPrefix)
: base(type)
{
PrefixLength = prefixLength;
NetworkPrefix = networkPrefix;
}
internal sealed override int DataLength internal sealed override int DataLength
{ {
get { return OptionDataLength; } get { return OptionDataLength; }
......
...@@ -35,13 +35,24 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -35,13 +35,24 @@ namespace PcapDotNet.Packets.IpV6
public const byte IsIpV4 = 0x40; public const byte IsIpV4 = 0x40;
} }
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.LocalMobilityAddress; public const int OptionDataMinimumLength = Offset.LocalMobilityAddress;
/// <summary>
/// Creates an instance from an IPv4 local mobility address.
/// </summary>
/// <param name="localMobilityAddress">The IPv4 address of the r2LMA.</param>
public IpV6MobilityOptionRedirect(IpV4Address localMobilityAddress) public IpV6MobilityOptionRedirect(IpV4Address localMobilityAddress)
: this(localMobilityAddress, null) : this(localMobilityAddress, null)
{ {
} }
/// <summary>
/// Creates an instance from an IPv6 local mobility address.
/// </summary>
/// <param name="localMobilityAddress">The unicast IPv6 address of the r2LMA.</param>
public IpV6MobilityOptionRedirect(IpV6Address localMobilityAddress) public IpV6MobilityOptionRedirect(IpV6Address localMobilityAddress)
: this(null, localMobilityAddress) : this(null, localMobilityAddress)
{ {
......
...@@ -28,8 +28,22 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -28,8 +28,22 @@ namespace PcapDotNet.Packets.IpV6
public const int LatePathSwitch = 0x01; public const int LatePathSwitch = 0x01;
} }
/// <summary>
/// The number of bytes this option data takes.
/// </summary>
public const int OptionDataLength = Offset.Lifetime + sizeof(byte); public const int OptionDataLength = Offset.Lifetime + sizeof(byte);
/// <summary>
/// Creates an instance from late path switch and lifetime.
/// </summary>
/// <param name="latePathSwitch">
/// Indicates that the Local Mobility Anchor (LMA) applies late path switch according to the transient BCE state.
/// If true, the LMA continues to forward downlink packets towards the pMAG.
/// Different setting of this flag may be for future use.
/// </param>
/// <param name="lifetime">
/// Maximum lifetime of a Transient-L state in multiple of 100 ms.
/// </param>
public IpV6MobilityOptionTransientBinding(bool latePathSwitch, byte lifetime) public IpV6MobilityOptionTransientBinding(bool latePathSwitch, byte lifetime)
: base(IpV6MobilityOptionType.TransientBinding) : base(IpV6MobilityOptionType.TransientBinding)
{ {
......
...@@ -34,8 +34,23 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -34,8 +34,23 @@ namespace PcapDotNet.Packets.IpV6
public const int Data = SubType + sizeof(byte); public const int Data = SubType + sizeof(byte);
} }
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.Data; public const int OptionDataMinimumLength = Offset.Data;
/// <summary>
/// Creates an instance from vendor id, subtype and data.
/// </summary>
/// <param name="vendorId">
/// The SMI Network Management Private Enterprise Code of the IANA- maintained Private Enterprise Numbers registry.
/// See http://www.iana.org/assignments/enterprise-numbers/enterprise-numbers
/// </param>
/// <param name="subType">
/// Indicating the type of vendor-specific information carried in the option.
/// The administration of the Sub-type is done by the Vendor.
/// </param>
/// <param name="data">Vendor-specific data that is carried in this message.</param>
public IpV6MobilityOptionVendorSpecific(uint vendorId, byte subType, DataSegment data) public IpV6MobilityOptionVendorSpecific(uint vendorId, byte subType, DataSegment data)
: base(IpV6MobilityOptionType.VendorSpecific) : base(IpV6MobilityOptionType.VendorSpecific)
{ {
......
...@@ -36,9 +36,52 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -36,9 +36,52 @@ namespace PcapDotNet.Packets.IpV6
public const int CompartmentBitmap = Checksum + sizeof(ushort); public const int CompartmentBitmap = Checksum + sizeof(ushort);
} }
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.CompartmentBitmap; public const int OptionDataMinimumLength = Offset.CompartmentBitmap;
/// <summary>
/// The maximum length for the compartment bitmap.
/// </summary>
public const int CompartmentBitmapMaxLength = byte.MaxValue - OptionDataMinimumLength; public const int CompartmentBitmapMaxLength = byte.MaxValue - OptionDataMinimumLength;
/// <summary>
/// Creates an instance from domain of interpretation, sensitivity level, checksum and compartment bitmap.
/// </summary>
/// <param name="domainOfInterpretation">Identifies the rules under which this datagram must be handled and protected.</param>
/// <param name="sensitivityLevel">
/// Contains an opaque octet whose value indicates the relative sensitivity of the data contained in this datagram in the context of the indicated DOI.
/// The values of this field must be ordered, with 00000000 being the lowest Sensitivity Level and 11111111 being the highest Sensitivity Level.
/// However, in a typical deployment, not all 256 Sensitivity Levels will be in use.
/// So the set of valid Sensitivity Level values depends upon the CALIPSO DOI in use.
/// This sensitivity ordering rule is necessary so that Intermediate Systems (e.g., routers or MLS guards) will be able to apply MAC policy
/// with minimal per-packet computation and minimal configuration.
/// </param>
/// <param name="checksum">
/// Contains the a CRC-16 checksum as defined in RFC 1662.
/// The checksum is calculated over the entire CALIPSO option in this packet, including option header, zeroed-out checksum field, option contents,
/// and any required padding zero bits.
/// The checksum must always be computed on transmission and must always be verified on reception.
/// This checksum only provides protection against accidental corruption of the CALIPSO option in cases where neither the underlying medium
/// nor other mechanisms, such as the IP Authentication Header (AH), are available to protect the integrity of this option.
/// Note that the checksum field is always required, even when other integrity protection mechanisms (e.g., AH) are used.
/// If null is given, it would be automatically calculated.
/// </param>
/// <param name="compartmentBitmap">
/// Each bit represents one compartment within the DOI.
/// Each "1" bit within an octet in the Compartment Bitmap field represents a separate compartment under whose rules the data in this packet
/// must be protected.
/// Hence, each "0" bit indicates that the compartment corresponding with that bit is not applicable to the data in this packet.
/// The assignment of identity to individual bits within a Compartment Bitmap for a given DOI is left to the owner of that DOI.
/// This specification represents a Releasability on the wire as if it were an inverted Compartment.
/// So the Compartment Bitmap holds the sum of both logical Releasabilities and also logical Compartments for a given DOI value.
/// The encoding of the Releasabilities in this field is described elsewhere in this document.
/// The Releasability encoding is designed to permit the Compartment Bitmap evaluation to occur without the evaluator necessarily knowing
/// the human semantic associated with each bit in the Compartment Bitmap.
/// In turn, this facilitates the implementation and configuration of Mandatory Access Controls based on the Compartment Bitmap
/// within IPv6 routers or guard devices.
/// </param>
public IpV6OptionCalipso(IpV6CalipsoDomainOfInterpretation domainOfInterpretation, byte sensitivityLevel, ushort? checksum, DataSegment compartmentBitmap) public IpV6OptionCalipso(IpV6CalipsoDomainOfInterpretation domainOfInterpretation, byte sensitivityLevel, ushort? checksum, DataSegment compartmentBitmap)
: base(IpV6OptionType.Calipso) : base(IpV6OptionType.Calipso)
{ {
...@@ -60,7 +103,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -60,7 +103,7 @@ namespace PcapDotNet.Packets.IpV6
} }
/// <summary> /// <summary>
/// The DOI identifies the rules under which this datagram must be handled and protected. /// Identifies the rules under which this datagram must be handled and protected.
/// </summary> /// </summary>
public IpV6CalipsoDomainOfInterpretation DomainOfInterpretation { get; private set; } public IpV6CalipsoDomainOfInterpretation DomainOfInterpretation { get; private set; }
...@@ -102,6 +145,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -102,6 +145,9 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public ushort Checksum { get; private set; } public ushort Checksum { get; private set; }
/// <summary>
/// True iff the checksum is correct.
/// </summary>
public bool IsChecksumCorrect public bool IsChecksumCorrect
{ {
get get
...@@ -132,6 +178,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -132,6 +178,11 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public DataSegment CompartmentBitmap { get; private set; } public DataSegment CompartmentBitmap { get; private set; }
/// <summary>
/// Parses an option from the given data.
/// </summary>
/// <param name="data">The data to parse.</param>
/// <returns>The option if parsing was successful, null otherwise.</returns>
public IpV6Option CreateInstance(DataSegment data) public IpV6Option CreateInstance(DataSegment data)
{ {
if (data.Length < OptionDataMinimumLength) if (data.Length < OptionDataMinimumLength)
......
...@@ -32,8 +32,22 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -32,8 +32,22 @@ namespace PcapDotNet.Packets.IpV6
public const int SourceEndpointIdentifier = DestinationEndpointIdentifierLength + sizeof(byte); public const int SourceEndpointIdentifier = DestinationEndpointIdentifierLength + sizeof(byte);
} }
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.SourceEndpointIdentifier; public const int OptionDataMinimumLength = Offset.SourceEndpointIdentifier;
/// <summary>
/// Creates an instance from source endpoint identifier and destination endpoint identifier.
/// </summary>
/// <param name="sourceEndpointIdentifier">
/// The endpoint identifier of the source.
/// Nimrod EIDs begin with the five bits 00100.
/// </param>
/// <param name="destinationEndpointIdentifier">
/// The endpoint identifier of the destination.
/// Nimrod EIDs begin with the five bits 00100.
/// </param>
public IpV6OptionEndpointIdentification(DataSegment sourceEndpointIdentifier, DataSegment destinationEndpointIdentifier) public IpV6OptionEndpointIdentification(DataSegment sourceEndpointIdentifier, DataSegment destinationEndpointIdentifier)
: base(IpV6OptionType.EndpointIdentification) : base(IpV6OptionType.EndpointIdentification)
{ {
...@@ -41,10 +55,23 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -41,10 +55,23 @@ namespace PcapDotNet.Packets.IpV6
DestinationEndpointIdentifier = destinationEndpointIdentifier; DestinationEndpointIdentifier = destinationEndpointIdentifier;
} }
/// <summary>
/// The endpoint identifier of the source.
/// Nimrod EIDs begin with the five bits 00100.
/// </summary>
public DataSegment SourceEndpointIdentifier { get; private set; } public DataSegment SourceEndpointIdentifier { get; private set; }
/// <summary>
/// The endpoint identifier of the destination.
/// Nimrod EIDs begin with the five bits 00100.
/// </summary>
public DataSegment DestinationEndpointIdentifier { get; private set; } public DataSegment DestinationEndpointIdentifier { get; private set; }
/// <summary>
/// Parses an option from the given data.
/// </summary>
/// <param name="data">The data to parse.</param>
/// <returns>The option if parsing was successful, null otherwise.</returns>
public IpV6Option CreateInstance(DataSegment data) public IpV6Option CreateInstance(DataSegment data)
{ {
if (data.Length < OptionDataMinimumLength) if (data.Length < OptionDataMinimumLength)
......
...@@ -47,6 +47,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -47,6 +47,11 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public IpV6Address HomeAddress { get; private set; } public IpV6Address HomeAddress { get; private set; }
/// <summary>
/// Parses an option from the given data.
/// </summary>
/// <param name="data">The data to parse.</param>
/// <returns>The option if parsing was successful, null otherwise.</returns>
public IpV6Option CreateInstance(DataSegment data) public IpV6Option CreateInstance(DataSegment data)
{ {
if (data.Length != OptionDataLength) if (data.Length != OptionDataLength)
......
...@@ -39,6 +39,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -39,6 +39,11 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public uint JumboPayloadLength { get; private set; } public uint JumboPayloadLength { get; private set; }
/// <summary>
/// Parses an option from the given data.
/// </summary>
/// <param name="data">The data to parse.</param>
/// <returns>The option if parsing was successful, null otherwise.</returns>
public IpV6Option CreateInstance(DataSegment data) public IpV6Option CreateInstance(DataSegment data)
{ {
if (data.Length != OptionDataLength) if (data.Length != OptionDataLength)
......
...@@ -30,8 +30,19 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -30,8 +30,19 @@ namespace PcapDotNet.Packets.IpV6
public const int LineIdentification = LineIdentificationLength + sizeof(byte); public const int LineIdentification = LineIdentificationLength + sizeof(byte);
} }
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.LineIdentification; public const int OptionDataMinimumLength = Offset.LineIdentification;
/// <summary>
/// Creates an instance from line identification.
/// </summary>
/// <param name="lineIdentification">
/// Variable length data inserted by the AN describing the subscriber agent circuit identifier
/// corresponding to the logical access loop port of the AN from which the RS was initiated.
/// The line identification must be unique across all the ANs that share a link to the edge router.
/// </param>
public IpV6OptionLineIdentificationDestination(DataSegment lineIdentification) public IpV6OptionLineIdentificationDestination(DataSegment lineIdentification)
: base(IpV6OptionType.LineIdentification) : base(IpV6OptionType.LineIdentification)
{ {
...@@ -50,6 +61,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -50,6 +61,11 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public DataSegment LineIdentification { get; private set; } public DataSegment LineIdentification { get; private set; }
/// <summary>
/// Parses an option from the given data.
/// </summary>
/// <param name="data">The data to parse.</param>
/// <returns>The option if parsing was successful, null otherwise.</returns>
public IpV6Option CreateInstance(DataSegment data) public IpV6Option CreateInstance(DataSegment data)
{ {
if (data.Length < OptionDataMinimumLength) if (data.Length < OptionDataMinimumLength)
......
...@@ -40,8 +40,35 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -40,8 +40,35 @@ namespace PcapDotNet.Packets.IpV6
public const byte ForwardingError = 0x20; public const byte ForwardingError = 0x20;
} }
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.SubTlvs; public const int OptionDataMinimumLength = Offset.SubTlvs;
/// <summary>
/// Creates an instance from down, rank error, forwarding error, RPL instance id, sender rank and sub TLVs.
/// </summary>
/// <param name="down">
/// Indicating whether the packet is expected to progress Up or Down.
/// A router sets the Down flag when the packet is expected to progress Down (using DAO routes),
/// and clears it when forwarding toward the DODAG root (to a node with a lower Rank).
/// A host or RPL leaf node must set the Down flag to 0.
/// </param>
/// <param name="rankError">
/// Indicating whether a Rank error was detected.
/// A Rank error is detected when there is a mismatch in the relative Ranks and the direction as indicated in the Down flag.
/// A host or RPL leaf node must set the Rank Error flag to 0.
/// </param>
/// <param name="forwardingError">
/// Indicating that this node cannot forward the packet further towards the destination.
/// The Forward Error flag might be set by a child node that does not have a route to destination for a packet with the Down flag set.
/// A host or RPL leaf node must set the Forwarding error flag to 0.
/// </param>
/// <param name="rplInstanceId">Indicating the DODAG instance along which the packet is sent.</param>
/// <param name="senderRank">Set to zero by the source and to DAGRank(rank) by a router that forwards inside the RPL network.</param>
/// <param name="subTlvs">
/// A RPL device must skip over any unrecognized sub-TLVs and attempt to process any additional sub-TLVs that may appear after.
/// </param>
public IpV6OptionRoutingProtocolLowPowerAndLossyNetworks(bool down, bool rankError, bool forwardingError, byte rplInstanceId, ushort senderRank, public IpV6OptionRoutingProtocolLowPowerAndLossyNetworks(bool down, bool rankError, bool forwardingError, byte rplInstanceId, ushort senderRank,
DataSegment subTlvs) DataSegment subTlvs)
: base(IpV6OptionType.RplOption) : base(IpV6OptionType.RplOption)
...@@ -91,6 +118,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -91,6 +118,11 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public DataSegment SubTlvs { get; private set; } public DataSegment SubTlvs { get; private set; }
/// <summary>
/// Parses an option from the given data.
/// </summary>
/// <param name="data">The data to parse.</param>
/// <returns>The option if parsing was successful, null otherwise.</returns>
public IpV6Option CreateInstance(DataSegment data) public IpV6Option CreateInstance(DataSegment data)
{ {
if (data.Length < OptionDataMinimumLength) if (data.Length < OptionDataMinimumLength)
......
...@@ -29,13 +29,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -29,13 +29,11 @@ namespace PcapDotNet.Packets.IpV6
public const int HashIndicator = 0x80; public const int HashIndicator = 0x80;
} }
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.HashIndicator + sizeof(byte); public const int OptionDataMinimumLength = Offset.HashIndicator + sizeof(byte);
protected IpV6OptionSmfDpd()
: base(IpV6OptionType.SmfDpd)
{
}
/// <summary> /// <summary>
/// Identifying DPD marking type. /// Identifying DPD marking type.
/// 0 == sequence-based approach with optional TaggerId and a tuple-based sequence number. See <see cref="IpV6OptionSmfDpdSequenceBased"/>. /// 0 == sequence-based approach with optional TaggerId and a tuple-based sequence number. See <see cref="IpV6OptionSmfDpdSequenceBased"/>.
...@@ -43,6 +41,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -43,6 +41,11 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public abstract bool HashIndicator { get; } public abstract bool HashIndicator { get; }
internal IpV6OptionSmfDpd()
: base(IpV6OptionType.SmfDpd)
{
}
internal static IpV6Option CreateInstance(DataSegment data) internal static IpV6Option CreateInstance(DataSegment data)
{ {
if (data.Length < OptionDataMinimumLength) if (data.Length < OptionDataMinimumLength)
......
...@@ -29,12 +29,28 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -29,12 +29,28 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public sealed class IpV6OptionSmfDpdIpV4 : IpV6OptionSmfDpdSequenceBased public sealed class IpV6OptionSmfDpdIpV4 : IpV6OptionSmfDpdSequenceBased
{ {
/// <summary>
/// Creates an instance from tagger id and identifier.
/// </summary>
/// <param name="taggerId">
/// Used to differentiate multiple ingressing border gateways that may commonly apply the SMF_DPD option header to packets from a particular source.
/// </param>
/// <param name="identifier">
/// DPD packet Identifier.
/// When the TaggerId field is present, the Identifier can be considered a unique packet identifier
/// in the context of the TaggerId:srcAddr:dstAddr tuple.
/// When the TaggerId field is not present, then it is assumed that the source applied the SMF_DPD option
/// and the Identifier can be considered unique in the context of the IPv6 packet header srcAddr:dstAddr tuple.
/// </param>
public IpV6OptionSmfDpdIpV4(IpV4Address taggerId, DataSegment identifier) public IpV6OptionSmfDpdIpV4(IpV4Address taggerId, DataSegment identifier)
: base(identifier) : base(identifier)
{ {
TaggerId = taggerId; TaggerId = taggerId;
} }
/// <summary>
/// Used to differentiate multiple ingressing border gateways that may commonly apply the SMF_DPD option header to packets from a particular source.
/// </summary>
public IpV4Address TaggerId { get; private set; } public IpV4Address TaggerId { get; private set; }
/// <summary> /// <summary>
......
...@@ -39,12 +39,28 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -39,12 +39,28 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public sealed class IpV6OptionSmfDpdIpV6 : IpV6OptionSmfDpdSequenceBased public sealed class IpV6OptionSmfDpdIpV6 : IpV6OptionSmfDpdSequenceBased
{ {
/// <summary>
/// Creates an instance from tagger id and identifier.
/// </summary>
/// <param name="taggerId">
/// Used to differentiate multiple ingressing border gateways that may commonly apply the SMF_DPD option header to packets from a particular source.
/// </param>
/// <param name="identifier">
/// DPD packet Identifier.
/// When the TaggerId field is present, the Identifier can be considered a unique packet identifier
/// in the context of the TaggerId:srcAddr:dstAddr tuple.
/// When the TaggerId field is not present, then it is assumed that the source applied the SMF_DPD option
/// and the Identifier can be considered unique in the context of the IPv6 packet header srcAddr:dstAddr tuple.
/// </param>
public IpV6OptionSmfDpdIpV6(IpV6Address taggerId, DataSegment identifier) public IpV6OptionSmfDpdIpV6(IpV6Address taggerId, DataSegment identifier)
: base(identifier) : base(identifier)
{ {
TaggerId = taggerId; TaggerId = taggerId;
} }
/// <summary>
/// Used to differentiate multiple ingressing border gateways that may commonly apply the SMF_DPD option header to packets from a particular source.
/// </summary>
public IpV6Address TaggerId { get; private set; } public IpV6Address TaggerId { get; private set; }
/// <summary> /// <summary>
......
...@@ -76,7 +76,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -76,7 +76,7 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public abstract IpV6TaggerIdType TaggerIdType { get; } public abstract IpV6TaggerIdType TaggerIdType { get; }
protected IpV6OptionSmfDpdSequenceBased(DataSegment identifier) internal IpV6OptionSmfDpdSequenceBased(DataSegment identifier)
{ {
Identifier = identifier; Identifier = identifier;
} }
......
...@@ -35,6 +35,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -35,6 +35,11 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public byte TunnelEncapsulationLimit { get; private set; } public byte TunnelEncapsulationLimit { get; private set; }
/// <summary>
/// Parses an option from the given data.
/// </summary>
/// <param name="data">The data to parse.</param>
/// <returns>The option if parsing was successful, null otherwise.</returns>
public IpV6Option CreateInstance(DataSegment data) public IpV6Option CreateInstance(DataSegment data)
{ {
if (data.Length != OptionDataLength) if (data.Length != OptionDataLength)
......
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