Commit 0abdb7bc authored by Brickner_cp's avatar Brickner_cp

293 warnings left.

parent 8c832eed
......@@ -62,6 +62,13 @@ namespace PcapDotNet.Packets
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)
{
return new DataSegment(array, offset, length);
......
......@@ -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
{
get
......
......@@ -80,11 +80,25 @@ namespace PcapDotNet.Packets.Ip
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()
{
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()
{
return GetEnumerator();
......
......@@ -32,8 +32,38 @@ namespace PcapDotNet.Packets.IpV6
public const int AuthenticationData = SequenceNumber + sizeof(uint);
}
/// <summary>
/// The minimum number of bytes the extension header takes.
/// </summary>
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)
: base(nextHeader)
{
......@@ -92,6 +122,56 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
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)
{
if (extensionHeaderData.Length < MinimumLength)
......@@ -115,7 +195,7 @@ namespace PcapDotNet.Packets.IpV6
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)
{
......@@ -128,38 +208,6 @@ namespace PcapDotNet.Packets.IpV6
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)
{
buffer.Write(offset + Offset.NextHeader, (byte)NextHeader);
......
......@@ -56,8 +56,31 @@ namespace PcapDotNet.Packets.IpV6
public const int PayloadData = SequenceNumber + sizeof(uint);
}
/// <summary>
/// The minimum number of bytes the extension header takes.
/// </summary>
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)
: base(null)
{
......@@ -66,26 +89,41 @@ namespace PcapDotNet.Packets.IpV6
EncryptedDataAndAuthenticationData = encryptedDataAndAuthenticationData;
}
/// <summary>
/// Identifies the type of this extension header.
/// </summary>
public override IpV4Protocol Protocol
{
get { return IpV4Protocol.EncapsulatingSecurityPayload; }
}
/// <summary>
/// The number of bytes this extension header takes.
/// </summary>
public override int Length
{
get { return MinimumLength + EncryptedDataAndAuthenticationData.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 IpV6ExtensionHeaderEncapsulatingSecurityPayload);
}
/// <summary>
/// True iff the given extension header is equal to this extension header.
/// </summary>
public bool Equals(IpV6ExtensionHeaderEncapsulatingSecurityPayload other)
{
return other != null &&
......@@ -93,6 +131,9 @@ namespace PcapDotNet.Packets.IpV6
EncryptedDataAndAuthenticationData.Equals(other.EncryptedDataAndAuthenticationData);
}
/// <summary>
/// Returns a hash code of the extension header.
/// </summary>
public override int GetHashCode()
{
return Sequence.GetHashCode(SecurityParametersIndex, SequenceNumber, EncryptedDataAndAuthenticationData);
......@@ -134,7 +175,7 @@ namespace PcapDotNet.Packets.IpV6
public uint SequenceNumber { get; private set; }
/// <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>
/// 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.
......
......@@ -36,10 +36,32 @@ namespace PcapDotNet.Packets.IpV6
public const int FragmentOffset = 3;
}
/// <summary>
/// The number of bytes the extension header data takes.
/// </summary>
public const int ExtensionHeaderDataLength = DataOffset.Identification + sizeof(uint);
/// <summary>
/// The maximum value for the fragment offset.
/// </summary>
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)
: base(nextHeader)
{
......@@ -68,11 +90,17 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
public uint Identification { get; private set; }
/// <summary>
/// Identifies the type of this extension header.
/// </summary>
public override IpV4Protocol Protocol
{
get { return IpV4Protocol.FragmentHeaderForIpV6; }
}
/// <summary>
/// True iff the extension header parsing didn't encounter an issue.
/// </summary>
public override bool IsValid
{
get { return true; }
......
......@@ -41,6 +41,48 @@ namespace PcapDotNet.Packets.IpV6
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,
bool keyManagementMobilityCapability, bool mobileRouter, bool proxyRegistration,
bool tlvHeaderFormat, ushort sequenceNumber, ushort lifetime, IpV6MobilityOptions options)
......
......@@ -42,6 +42,9 @@ namespace PcapDotNet.Packets.IpV6
public const byte KeyManagementMobilityCapability = 0x80;
}
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
public const int MinimumMessageDataLength = MessageDataOffset.Options;
/// <summary>
......
......@@ -40,8 +40,31 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = HomeAddress + IpV6Address.SizeOf;
}
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
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,
IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options)
......
......@@ -28,18 +28,27 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = 2;
}
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
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)
: base(nextHeader, checksum, options, MessageDataOffset.Options)
{
}
internal override int MessageDataLength
{
get { return MinimumMessageDataLength + MobilityOptions.BytesLength; }
}
/// <summary>
/// Identifies the particular mobility message in question.
/// An unrecognized MH Type field causes an error indication to be sent.
......@@ -49,6 +58,11 @@ namespace PcapDotNet.Packets.IpV6
get { return IpV6MobilityHeaderType.BindingRefreshRequest; }
}
internal override int MessageDataLength
{
get { return MinimumMessageDataLength + MobilityOptions.BytesLength; }
}
internal static IpV6ExtensionHeaderMobilityBindingRefreshRequest ParseMessageData(IpV4Protocol nextHeader, ushort checksum, DataSegment messageData)
{
if (messageData.Length < MinimumMessageDataLength)
......
......@@ -39,6 +39,9 @@ namespace PcapDotNet.Packets.IpV6
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;
private static class MessageDataMask
......
......@@ -47,6 +47,73 @@ namespace PcapDotNet.Packets.IpV6
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,
bool linkLocalAddressCompatibility, bool keyManagementMobilityCapability, bool mapRegistration,
bool mobileRouter, bool proxyRegistrationFlag, bool forcingUdpEncapsulation, bool tlvHeaderFormat,
......
......@@ -47,21 +47,11 @@ namespace PcapDotNet.Packets.IpV6
public const byte KeyManagementMobilityCapability = 0x10;
}
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
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>
/// 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>
......@@ -107,6 +97,19 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
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)
{
return EqualsMessageData(other as IpV6ExtensionHeaderMobilityBindingUpdateBase);
......
......@@ -42,8 +42,25 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = CareOfKeygenToken + sizeof(ulong);
}
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
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,
ulong careOfKeygenToken, IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options)
......
......@@ -34,8 +34,23 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = CareOfInitCookie + sizeof(ulong);
}
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
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)
: base(nextHeader, checksum, options, MessageDataOffset.Options)
{
......
......@@ -29,8 +29,26 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = sizeof(ushort);
}
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
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)
: base(nextHeader, checksum, options, MessageDataOffset.Options)
{
......
......@@ -33,8 +33,27 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = Code + sizeof(byte);
}
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
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,
IpV6MobilityHandoverAcknowledgeCode code, IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options)
......
......@@ -41,11 +41,35 @@ namespace PcapDotNet.Packets.IpV6
public const byte Buffer = 0x40;
}
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
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,
bool buffer, IpV6HandoverInitiateMessageCode code,
IpV6MobilityOptions options)
bool buffer, IpV6HandoverInitiateMessageCode code, IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options)
{
SequenceNumber = sequenceNumber;
......
......@@ -41,8 +41,29 @@ namespace PcapDotNet.Packets.IpV6
public const byte IsResponse = 0x01;
}
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
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,
uint sequenceNumber, IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.MobilityOptions)
......
......@@ -36,8 +36,23 @@ namespace PcapDotNet.Packets.IpV6
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;
/// <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,
IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.HomeAgentAddresses + homeAgentAddresses.Count * IpV6Address.SizeOf)
......@@ -45,6 +60,18 @@ namespace PcapDotNet.Packets.IpV6
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)
: this(nextHeader, checksum, (ReadOnlyCollection<IpV6Address>)homeAgentAddresses.AsReadOnly(), options)
{
......
......@@ -42,8 +42,25 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = HomeKeygenToken + sizeof(ulong);
}
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
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,
IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options)
......
......@@ -34,8 +34,23 @@ namespace PcapDotNet.Packets.IpV6
public const int Options = HomeInitCookie + sizeof(ulong);
}
/// <summary>
/// The minimum number of bytes the message data takes.
/// </summary>
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)
: base(nextHeader, checksum, options, MessageDataOffset.Options)
{
......
......@@ -40,16 +40,11 @@ namespace PcapDotNet.Packets.IpV6
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 IpV6ExtensionHeaderMobilityLocalizedRouting(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, ushort lifetime,
IpV6MobilityOptions options)
: base(nextHeader, checksum, options, MessageDataOffset.Options)
{
SequenceNumber = sequenceNumber;
Lifetime = lifetime;
}
/// <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 acknowledgement, copied from the sequence number field of the LRI message being responded to.
......@@ -65,6 +60,14 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
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
{
get { return MinimumMessageDataLength + MobilityOptions.BytesLength; }
......
......@@ -39,8 +39,31 @@ namespace PcapDotNet.Packets.IpV6
public const byte Unsolicited = 0x80;
}
public IpV6ExtensionHeaderMobilityLocalizedRoutingAcknowledgement(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool unsolicited, IpV6MobilityLocalizedRoutingAcknowledgementStatus status,
ushort lifetime, IpV6MobilityOptions options)
/// <summary>
/// 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)
{
Status = status;
......@@ -54,6 +77,9 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
public bool Unsolicited { get; private set; }
/// <summary>
/// The acknowledgement status.
/// </summary>
public IpV6MobilityLocalizedRoutingAcknowledgementStatus Status { get; private set; }
/// <summary>
......
......@@ -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.
/// </param>
/// <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.
/// In acknowledgement, copied from the sequence number field of the LRI message being responded to.
/// A monotonically increasing integer. Set by a sending node in a request message, and used to match a reply to the request.
/// </param>
/// <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.
/// 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 name="options">
/// Zero or more TLV-encoded mobility options.
......
......@@ -58,10 +58,37 @@ namespace PcapDotNet.Packets.IpV6
public const int PadSize = 4;
}
/// <summary>
/// The minimum number of bytes the routing data takes.
/// </summary>
public const int RoutingDataMinimumLength = RoutingDataOffset.Addresses;
/// <summary>
/// The maximum common prefix length.
/// </summary>
public const byte MaxCommonPrefixLength = IpV6Address.SizeOf - 1;
/// <summary>
/// The maximum padding size.
/// </summary>
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,
byte commonPrefixLengthForLastAddress, params IpV6Address[] addresses)
: base(nextHeader, segmentsLeft)
......@@ -108,6 +135,9 @@ namespace PcapDotNet.Packets.IpV6
}
}
/// <summary>
/// Identifier of a particular Routing header variant.
/// </summary>
public override IpV6RoutingType RoutingType
{
get { return IpV6RoutingType.RplSourceRouteHeader; }
......@@ -130,6 +160,9 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
public byte PadSize { get; private set; }
/// <summary>
/// Routing addresses.
/// </summary>
public ReadOnlyCollection<IpV6Address> Addresses { get; private set; }
internal override int RoutingDataLength
......
......@@ -44,19 +44,36 @@ namespace PcapDotNet.Packets.IpV6
public const int Addresses = Reserved + sizeof(uint);
}
/// <summary>
/// The minimum number of bytes the routing data takes.
/// </summary>
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)
: base(nextHeader, segmentsLeft)
{
Addresses = addresses.AsReadOnly();
}
/// <summary>
/// Identifier of a particular Routing header variant.
/// </summary>
public override IpV6RoutingType RoutingType
{
get { return IpV6RoutingType.SourceRoute; }
}
/// <summary>
/// Routing addresses.
/// </summary>
public ReadOnlyCollection<IpV6Address> Addresses { get; private set; }
internal override int RoutingDataLength
......
......@@ -27,19 +27,33 @@ namespace PcapDotNet.Packets.IpV6
public const int Data = HeaderExtensionLength + sizeof(byte);
}
/// <summary>
/// The minimum number of bytes the extension header takes.
/// </summary>
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)
{
return other != null &&
Protocol == other.Protocol && NextHeader == other.NextHeader && EqualsData(other);
}
/// <summary>
/// Returns a hash code of the extension header.
/// </summary>
public sealed override int GetHashCode()
{
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 int GetDataHashCode();
......@@ -60,8 +74,8 @@ namespace PcapDotNet.Packets.IpV6
internal abstract void WriteData(byte[] buffer, int offset);
public sealed override int Length { get { return Offset.Data + DataLength; } }
internal abstract int DataLength { get; }
internal static bool IsStandard(IpV4Protocol nextHeader)
{
switch (nextHeader)
......@@ -77,6 +91,7 @@ namespace PcapDotNet.Packets.IpV6
return false;
}
}
internal static IpV6ExtensionHeader CreateInstanceStandard(IpV4Protocol nextHeader, DataSegment extensionHeaderData, out int numBytesRead)
{
numBytesRead = 0;
......
......@@ -14,7 +14,7 @@ namespace PcapDotNet.Packets.IpV6
public class IpV6ExtensionHeaders : IEnumerable<IpV6ExtensionHeader>, IEquatable<IpV6ExtensionHeaders>
{
/// <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.
/// Assumes the collection won't be modified.
/// </summary>
......@@ -34,39 +34,86 @@ namespace PcapDotNet.Packets.IpV6
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)
: 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)
: 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)
: 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()
{
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()
{
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]
{
get { return Headers[index]; }
}
/// <summary>
/// The extension headers.
/// </summary>
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; }
/// <summary>
/// The protocol of the first extension header or null if there are no extension headers.
/// </summary>
public IpV4Protocol? FirstHeader
{
get
......@@ -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
{
get
......@@ -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
{
get
......@@ -97,21 +150,33 @@ namespace PcapDotNet.Packets.IpV6
}
}
/// <summary>
/// An empty list of extension headers.
/// </summary>
public static IpV6ExtensionHeaders 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)
{
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)
{
return other != null && this.SequenceEqual(other);
}
/// <summary>
/// A hash code based on all the extension headers.
/// </summary>
public override int GetHashCode()
{
return this.SequenceGetHashCode();
......
......@@ -144,28 +144,27 @@ namespace PcapDotNet.Packets.IpV6
public override string ToString()
{
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)
{
return ToString(format, CultureInfo.InvariantCulture);
}
/// <summary>
/// Translates the address to a string given the format provider.
/// </summary>
public string ToString(IFormatProvider provider)
{
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)
{
StringBuilder stringBuilder = new StringBuilder(39);
......
......@@ -39,6 +39,9 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
public const int HeaderLength = 40;
/// <summary>
/// Maximum flow label value.
/// </summary>
public const int MaxFlowLabel = 0xFFFFF;
private static class Offset
......@@ -65,6 +68,7 @@ namespace PcapDotNet.Packets.IpV6
public const int Version = 4;
public const int TrafficClass = 4;
}
/// <summary>
/// The version (6).
/// </summary>
......@@ -107,6 +111,9 @@ namespace PcapDotNet.Packets.IpV6
get { return ReadUShort(Offset.PayloadLength, Endianity.Big); }
}
/// <summary>
/// The actual payload length
/// </summary>
public ushort RealPayloadLength
{
get
......@@ -151,6 +158,9 @@ namespace PcapDotNet.Packets.IpV6
get { return ReadIpV6Address(Offset.DestinationAddress, Endianity.Big); }
}
/// <summary>
/// The IPv6 extension headers.
/// </summary>
public IpV6ExtensionHeaders ExtensionHeaders
{
get
......@@ -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)
: base(buffer, offset, length)
......@@ -228,12 +246,6 @@ namespace PcapDotNet.Packets.IpV6
extensionHeaders.Write(buffer, offset + HeaderLength);
}
protected override bool CalculateIsValid()
{
ParseExtensionHeaders();
return _isValid;
}
private IpV6ExtensionHeaders _extensionHeaders;
private bool _isValid = true;
}
......
......@@ -59,6 +59,9 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
public IpV6Address CurrentDestination { get; set; }
/// <summary>
/// The IPv6 extension headers.
/// </summary>
public IpV6ExtensionHeaders ExtensionHeaders { get; set; }
/// <summary>
......
......@@ -32,8 +32,24 @@ namespace PcapDotNet.Packets.IpV6
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;
/// <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)
: base(IpV6AccessNetworkIdentifierSubOptionType.GeoLocation)
{
......@@ -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));
}
/// <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)
{
if (latitudeDegreesReal < -90 || latitudeDegreesReal > 90)
......
......@@ -42,8 +42,39 @@ namespace PcapDotNet.Packets.IpV6
public const byte IsNetworkNameUtf8 = 0x80;
}
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
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)
: base(IpV6AccessNetworkIdentifierSubOptionType.NetworkIdentifier)
{
......
......@@ -28,8 +28,19 @@ namespace PcapDotNet.Packets.IpV6
public const int Identifier = IdentifierType + sizeof(byte);
}
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
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)
: base(IpV6AccessNetworkIdentifierSubOptionType.OperatorIdentifier)
{
......
......@@ -31,6 +31,11 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
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)
: base(IpV6FlowIdentificationSubOptionType.TrafficSelector)
{
......
......@@ -35,6 +35,9 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
public IpV6AccessNetworkIdentifierSubOptions SubOptions { get; private set; }
/// <summary>
/// True iff parsing of this option didn't encounter issues.
/// </summary>
public override bool IsValid
{
get { return SubOptions.IsValid; }
......
......@@ -34,8 +34,22 @@ namespace PcapDotNet.Packets.IpV6
public const int AuthenticationData = MobilitySecurityParameterIndex + sizeof(uint);
}
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
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)
: base(IpV6MobilityOptionType.Authentication)
{
......
......@@ -27,8 +27,21 @@ namespace PcapDotNet.Packets.IpV6
public const int Authenticator = SecurityParameterIndex + sizeof(uint);
}
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
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)
: base(IpV6MobilityOptionType.BindingAuthorizationDataForFmIpV6)
{
......
......@@ -64,16 +64,25 @@ namespace PcapDotNet.Packets.IpV6
Option.Write(buffer, ref offset);
}
/// <summary>
/// Two entries are equal iff their type and option are equal.
/// </summary>
public override bool Equals(object obj)
{
return Equals(obj as IpV6MobilityOptionContextRequestEntry);
}
/// <summary>
/// Two entries are equal iff their request type and option are equal.
/// </summary>
public bool Equals(IpV6MobilityOptionContextRequestEntry other)
{
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()
{
return Sequence.GetHashCode(RequestType, Option);
......
......@@ -32,8 +32,28 @@ namespace PcapDotNet.Packets.IpV6
public const byte Remove = 0x80;
}
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
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)
: base(IpV6MobilityOptionType.DnsUpdate)
{
......
......@@ -33,8 +33,35 @@ namespace PcapDotNet.Packets.IpV6
public const int SubOptions = Status + sizeof(byte);
}
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
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,
IpV6FlowIdentificationSubOptions subOptions)
: base(IpV6MobilityOptionType.FlowIdentification)
......@@ -82,6 +109,9 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
public IpV6FlowIdentificationSubOptions SubOptions { get; private set; }
/// <summary>
/// True iff parsing of this option didn't encounter issues.
/// </summary>
public override bool IsValid
{
get { return SubOptions.IsValid; }
......
......@@ -25,8 +25,11 @@ namespace PcapDotNet.Packets.IpV6
/// </pre>
/// </summary>
[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;
private static class Offset
......@@ -36,8 +39,20 @@ namespace PcapDotNet.Packets.IpV6
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;
/// <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)
: base(IpV6MobilityOptionType.IpV6AddressPrefix)
{
......
......@@ -28,8 +28,16 @@ namespace PcapDotNet.Packets.IpV6
public const int LinkLayerAddress = OptionCode + sizeof(byte);
}
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
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)
: base(IpV6MobilityOptionType.LinkLayerAddress)
{
......@@ -37,6 +45,9 @@ namespace PcapDotNet.Packets.IpV6
LinkLayerAddress = linkLayerAddress;
}
/// <summary>
/// The type of link layer address option.
/// </summary>
public IpV6MobilityLinkLayerAddressCode Code { get; private set; }
/// <summary>
......
......@@ -32,8 +32,24 @@ namespace PcapDotNet.Packets.IpV6
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);
/// <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)
: base(IpV6MobilityOptionType.LoadInformation)
{
......
......@@ -28,25 +28,26 @@ namespace PcapDotNet.Packets.IpV6
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 IpV6MobilityOptionLocalMobilityAnchorAddress(IpV6LocalMobilityAnchorAddressCode code, IpV4Address localMobilityAnchorAddress)
: this(code, localMobilityAnchorAddress, null)
{
}
public IpV6MobilityOptionLocalMobilityAnchorAddress(IpV6LocalMobilityAnchorAddressCode code, IpV6Address localMobilityAnchorAddress)
: this(code, null, localMobilityAnchorAddress)
{
}
/// <summary>
/// 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(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)
: this(IpV6LocalMobilityAnchorAddressCode.IpV6, localMobilityAnchorAddress)
: this(IpV6LocalMobilityAnchorAddressCode.IpV6, null, localMobilityAnchorAddress)
{
}
......
......@@ -31,15 +31,11 @@ namespace PcapDotNet.Packets.IpV6
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 IpV6MobilityOptionNetworkPrefix(IpV6MobilityOptionType type, byte prefixLength, IpV6Address networkPrefix)
: base(type)
{
PrefixLength = prefixLength;
NetworkPrefix = networkPrefix;
}
/// <summary>
/// Indicates the prefix length of the IPv6 prefix contained in the option.
/// </summary>
......@@ -50,6 +46,13 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
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
{
get { return OptionDataLength; }
......
......@@ -35,13 +35,24 @@ namespace PcapDotNet.Packets.IpV6
public const byte IsIpV4 = 0x40;
}
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
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)
: 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)
: this(null, localMobilityAddress)
{
......
......@@ -28,8 +28,22 @@ namespace PcapDotNet.Packets.IpV6
public const int LatePathSwitch = 0x01;
}
/// <summary>
/// The number of bytes this option data takes.
/// </summary>
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)
: base(IpV6MobilityOptionType.TransientBinding)
{
......
......@@ -34,8 +34,23 @@ namespace PcapDotNet.Packets.IpV6
public const int Data = SubType + sizeof(byte);
}
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
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)
: base(IpV6MobilityOptionType.VendorSpecific)
{
......
......@@ -36,9 +36,52 @@ namespace PcapDotNet.Packets.IpV6
public const int CompartmentBitmap = Checksum + sizeof(ushort);
}
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.CompartmentBitmap;
/// <summary>
/// The maximum length for the compartment bitmap.
/// </summary>
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)
: base(IpV6OptionType.Calipso)
{
......@@ -60,7 +103,7 @@ namespace PcapDotNet.Packets.IpV6
}
/// <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>
public IpV6CalipsoDomainOfInterpretation DomainOfInterpretation { get; private set; }
......@@ -102,6 +145,9 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
public ushort Checksum { get; private set; }
/// <summary>
/// True iff the checksum is correct.
/// </summary>
public bool IsChecksumCorrect
{
get
......@@ -132,6 +178,11 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
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)
{
if (data.Length < OptionDataMinimumLength)
......
......@@ -32,8 +32,22 @@ namespace PcapDotNet.Packets.IpV6
public const int SourceEndpointIdentifier = DestinationEndpointIdentifierLength + sizeof(byte);
}
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
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)
: base(IpV6OptionType.EndpointIdentification)
{
......@@ -41,10 +55,23 @@ namespace PcapDotNet.Packets.IpV6
DestinationEndpointIdentifier = destinationEndpointIdentifier;
}
/// <summary>
/// The endpoint identifier of the source.
/// Nimrod EIDs begin with the five bits 00100.
/// </summary>
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; }
/// <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)
{
if (data.Length < OptionDataMinimumLength)
......
......@@ -47,6 +47,11 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
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)
{
if (data.Length != OptionDataLength)
......
......@@ -39,6 +39,11 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
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)
{
if (data.Length != OptionDataLength)
......
......@@ -30,8 +30,19 @@ namespace PcapDotNet.Packets.IpV6
public const int LineIdentification = LineIdentificationLength + sizeof(byte);
}
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
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)
: base(IpV6OptionType.LineIdentification)
{
......@@ -50,6 +61,11 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
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)
{
if (data.Length < OptionDataMinimumLength)
......
......@@ -40,8 +40,35 @@ namespace PcapDotNet.Packets.IpV6
public const byte ForwardingError = 0x20;
}
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
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,
DataSegment subTlvs)
: base(IpV6OptionType.RplOption)
......@@ -91,6 +118,11 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
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)
{
if (data.Length < OptionDataMinimumLength)
......
......@@ -29,13 +29,11 @@ namespace PcapDotNet.Packets.IpV6
public const int HashIndicator = 0x80;
}
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.HashIndicator + sizeof(byte);
protected IpV6OptionSmfDpd()
: base(IpV6OptionType.SmfDpd)
{
}
/// <summary>
/// Identifying DPD marking type.
/// 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
/// </summary>
public abstract bool HashIndicator { get; }
internal IpV6OptionSmfDpd()
: base(IpV6OptionType.SmfDpd)
{
}
internal static IpV6Option CreateInstance(DataSegment data)
{
if (data.Length < OptionDataMinimumLength)
......
......@@ -29,12 +29,28 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
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)
: base(identifier)
{
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; }
/// <summary>
......
......@@ -39,12 +39,28 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
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)
: base(identifier)
{
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; }
/// <summary>
......
......@@ -76,7 +76,7 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
public abstract IpV6TaggerIdType TaggerIdType { get; }
protected IpV6OptionSmfDpdSequenceBased(DataSegment identifier)
internal IpV6OptionSmfDpdSequenceBased(DataSegment identifier)
{
Identifier = identifier;
}
......
......@@ -35,6 +35,11 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
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)
{
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