Commit 07592ef7 authored by Brickner_cp's avatar Brickner_cp

IPv6

parent b7799fc9
...@@ -59,7 +59,7 @@ namespace PcapDotNet.Packets.Test ...@@ -59,7 +59,7 @@ namespace PcapDotNet.Packets.Test
EtherType = EthernetType EtherType = EthernetType
}; };
Random random = new Random(); Random random = new Random(1);
for (int i = 0; i != 1000; ++i) for (int i = 0; i != 1000; ++i)
{ {
......
...@@ -85,7 +85,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -85,7 +85,7 @@ namespace PcapDotNet.Packets.IpV6
return null; return null;
DataSegment data = extensionHeaderData.Subsegment(Offset.Data, length - Offset.Data); DataSegment data = extensionHeaderData.Subsegment(Offset.Data, length - Offset.Data);
numBytesRead = data.Length; numBytesRead = length;
switch (nextHeader) switch (nextHeader)
{ {
......
...@@ -245,7 +245,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -245,7 +245,7 @@ namespace PcapDotNet.Packets.IpV6
public override sealed bool IsValid public override sealed bool IsValid
{ {
get { return MobilityOptions.IsValid && Length % 8 == 0; } get { return MobilityOptions.IsValid; }
} }
private static class DataOffset private static class DataOffset
...@@ -257,9 +257,15 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -257,9 +257,15 @@ namespace PcapDotNet.Packets.IpV6
public const int MinimumDataLength = DataOffset.MessageData; public const int MinimumDataLength = DataOffset.MessageData;
public IpV6ExtensionHeaderMobility(IpV4Protocol nextHeader, ushort checksum, IpV6MobilityOptions mobilityOptions) public IpV6ExtensionHeaderMobility(IpV4Protocol nextHeader, ushort checksum, IpV6MobilityOptions mobilityOptions, int? messageDataMobilityOptionsOffset)
: base(nextHeader) : base(nextHeader)
{ {
if (messageDataMobilityOptionsOffset.HasValue)
{
int mobilityOptionsExtraBytes = (messageDataMobilityOptionsOffset.Value - 2) % 8;
if (mobilityOptions.BytesLength % 8 != mobilityOptionsExtraBytes)
mobilityOptions = mobilityOptions.Pad((8 + mobilityOptionsExtraBytes - (mobilityOptions.BytesLength % 8)) % 8);
}
Checksum = checksum; Checksum = checksum;
MobilityOptions = mobilityOptions; MobilityOptions = mobilityOptions;
} }
...@@ -435,7 +441,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -435,7 +441,7 @@ namespace PcapDotNet.Packets.IpV6
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
public IpV6ExtensionHeaderMobilityBindingRefreshRequest(IpV4Protocol nextHeader, ushort checksum, IpV6MobilityOptions options) public IpV6ExtensionHeaderMobilityBindingRefreshRequest(IpV4Protocol nextHeader, ushort checksum, IpV6MobilityOptions options)
: base(nextHeader, checksum, options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
} }
...@@ -508,7 +514,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -508,7 +514,7 @@ namespace PcapDotNet.Packets.IpV6
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
public IpV6ExtensionHeaderMobilityHomeTestInit(IpV4Protocol nextHeader, ushort checksum, ulong homeInitCookie, IpV6MobilityOptions options) public IpV6ExtensionHeaderMobilityHomeTestInit(IpV4Protocol nextHeader, ushort checksum, ulong homeInitCookie, IpV6MobilityOptions options)
: base(nextHeader, checksum, options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
HomeInitCookie = homeInitCookie; HomeInitCookie = homeInitCookie;
} }
...@@ -595,7 +601,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -595,7 +601,7 @@ namespace PcapDotNet.Packets.IpV6
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
public IpV6ExtensionHeaderMobilityCareOfTestInit(IpV4Protocol nextHeader, ushort checksum, ulong careOfInitCookie, IpV6MobilityOptions options) public IpV6ExtensionHeaderMobilityCareOfTestInit(IpV4Protocol nextHeader, ushort checksum, ulong careOfInitCookie, IpV6MobilityOptions options)
: base(nextHeader, checksum, options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
CareOfInitCookie = careOfInitCookie; CareOfInitCookie = careOfInitCookie;
} }
...@@ -690,7 +696,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -690,7 +696,7 @@ namespace PcapDotNet.Packets.IpV6
public IpV6ExtensionHeaderMobilityHomeTest(IpV4Protocol nextHeader, ushort checksum, ushort homeNonceIndex, ulong homeInitCookie, ulong homeKeygenToken, public IpV6ExtensionHeaderMobilityHomeTest(IpV4Protocol nextHeader, ushort checksum, ushort homeNonceIndex, ulong homeInitCookie, ulong homeKeygenToken,
IpV6MobilityOptions options) IpV6MobilityOptions options)
: base(nextHeader, checksum, options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
HomeNonceIndex = homeNonceIndex; HomeNonceIndex = homeNonceIndex;
HomeInitCookie = homeInitCookie; HomeInitCookie = homeInitCookie;
...@@ -801,7 +807,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -801,7 +807,7 @@ namespace PcapDotNet.Packets.IpV6
public IpV6ExtensionHeaderMobilityCareOfTest(IpV4Protocol nextHeader, ushort checksum, ushort careOfNonceIndex, ulong careOfInitCookie, public IpV6ExtensionHeaderMobilityCareOfTest(IpV4Protocol nextHeader, ushort checksum, ushort careOfNonceIndex, ulong careOfInitCookie,
ulong careOfKeygenToken, IpV6MobilityOptions options) ulong careOfKeygenToken, IpV6MobilityOptions options)
: base(nextHeader, checksum, options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
CareOfNonceIndex = careOfNonceIndex; CareOfNonceIndex = careOfNonceIndex;
CareOfInitCookie = careOfInitCookie; CareOfInitCookie = careOfInitCookie;
...@@ -918,7 +924,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -918,7 +924,7 @@ namespace PcapDotNet.Packets.IpV6
public IpV6ExtensionHeaderMobilityBindingUpdateBase(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool acknowledge, public IpV6ExtensionHeaderMobilityBindingUpdateBase(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool acknowledge,
bool homeRegistration, bool linkLocalAddressCompatibility, bool keyManagementMobilityCapability, bool homeRegistration, bool linkLocalAddressCompatibility, bool keyManagementMobilityCapability,
ushort lifetime, IpV6MobilityOptions options) ushort lifetime, IpV6MobilityOptions options)
: base(nextHeader, checksum, options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
SequenceNumber = sequenceNumber; SequenceNumber = sequenceNumber;
Acknowledge = acknowledge; Acknowledge = acknowledge;
...@@ -1431,7 +1437,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -1431,7 +1437,7 @@ namespace PcapDotNet.Packets.IpV6
public IpV6ExtensionHeaderMobilityBindingAcknowledgementBase(IpV4Protocol nextHeader, ushort checksum, IpV6BindingAcknowledgementStatus status, public IpV6ExtensionHeaderMobilityBindingAcknowledgementBase(IpV4Protocol nextHeader, ushort checksum, IpV6BindingAcknowledgementStatus status,
bool keyManagementMobilityCapability, ushort sequenceNumber, ushort lifetime, bool keyManagementMobilityCapability, ushort sequenceNumber, ushort lifetime,
IpV6MobilityOptions options) IpV6MobilityOptions options)
: base(nextHeader, checksum, options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
Status = status; Status = status;
KeyManagementMobilityCapability = keyManagementMobilityCapability; KeyManagementMobilityCapability = keyManagementMobilityCapability;
...@@ -1638,7 +1644,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -1638,7 +1644,7 @@ namespace PcapDotNet.Packets.IpV6
public IpV6ExtensionHeaderMobilityBindingError(IpV4Protocol nextHeader, ushort checksum, IpV6BindingErrorStatus status, IpV6Address homeAddress, public IpV6ExtensionHeaderMobilityBindingError(IpV4Protocol nextHeader, ushort checksum, IpV6BindingErrorStatus status, IpV6Address homeAddress,
IpV6MobilityOptions options) IpV6MobilityOptions options)
: base(nextHeader, checksum, options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
Status = status; Status = status;
HomeAddress = homeAddress; HomeAddress = homeAddress;
...@@ -1844,7 +1850,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -1844,7 +1850,7 @@ namespace PcapDotNet.Packets.IpV6
public const int MinimumMessageDataLength = MessageDataOffset.Options; public const int MinimumMessageDataLength = MessageDataOffset.Options;
public IpV6ExtensionHeaderMobilityFastNeighborAdvertisement(IpV4Protocol nextHeader, ushort checksum, IpV6MobilityOptions options) public IpV6ExtensionHeaderMobilityFastNeighborAdvertisement(IpV4Protocol nextHeader, ushort checksum, IpV6MobilityOptions options)
: base(nextHeader, checksum, options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
} }
...@@ -1902,8 +1908,10 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -1902,8 +1908,10 @@ namespace PcapDotNet.Packets.IpV6
public sealed class IpV6ExtensionHeaderMobilityExperimental : IpV6ExtensionHeaderMobility public sealed class IpV6ExtensionHeaderMobilityExperimental : IpV6ExtensionHeaderMobility
{ {
public IpV6ExtensionHeaderMobilityExperimental(IpV4Protocol nextHeader, ushort checksum, DataSegment messageData) public IpV6ExtensionHeaderMobilityExperimental(IpV4Protocol nextHeader, ushort checksum, DataSegment messageData)
: base(nextHeader, checksum, IpV6MobilityOptions.None) : base(nextHeader, checksum, IpV6MobilityOptions.None, null)
{ {
if (messageData.Length % 8 != 4)
throw new ArgumentException("Message data size must be an integral product of 8 bytes plus 4 bytes", "messageData");
MessageData = messageData; MessageData = messageData;
} }
...@@ -1982,7 +1990,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -1982,7 +1990,7 @@ namespace PcapDotNet.Packets.IpV6
public IpV6ExtensionHeaderMobilityHomeAgentSwitchMessage(IpV4Protocol nextHeader, ushort checksum, ReadOnlyCollection<IpV6Address> homeAgentAddresses, public IpV6ExtensionHeaderMobilityHomeAgentSwitchMessage(IpV4Protocol nextHeader, ushort checksum, ReadOnlyCollection<IpV6Address> homeAgentAddresses,
IpV6MobilityOptions options) IpV6MobilityOptions options)
: base(nextHeader, checksum, options) : base(nextHeader, checksum, options, MessageDataOffset.HomeAgentAddresses + homeAgentAddresses.Count * IpV6Address.SizeOf)
{ {
HomeAgentAddresses = homeAgentAddresses; HomeAgentAddresses = homeAgentAddresses;
} }
...@@ -2092,7 +2100,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -2092,7 +2100,7 @@ namespace PcapDotNet.Packets.IpV6
public IpV6ExtensionHeaderMobilityHeartbeatMessage(IpV4Protocol nextHeader, ushort checksum, bool isUnsolicitedHeartbeatResponse, bool isResponse, public IpV6ExtensionHeaderMobilityHeartbeatMessage(IpV4Protocol nextHeader, ushort checksum, bool isUnsolicitedHeartbeatResponse, bool isResponse,
uint sequenceNumber, IpV6MobilityOptions options) uint sequenceNumber, IpV6MobilityOptions options)
: base(nextHeader, checksum, options) : base(nextHeader, checksum, options, MessageDataOffset.MobilityOptions)
{ {
IsUnsolicitedHeartbeatResponse = isUnsolicitedHeartbeatResponse; IsUnsolicitedHeartbeatResponse = isUnsolicitedHeartbeatResponse;
IsResponse = isResponse; IsResponse = isResponse;
...@@ -2217,7 +2225,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -2217,7 +2225,7 @@ namespace PcapDotNet.Packets.IpV6
public IpV6ExtensionHeaderMobilityHandoverInitiateMessage(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool assignedAddressConfiguration, public IpV6ExtensionHeaderMobilityHandoverInitiateMessage(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool assignedAddressConfiguration,
bool buffer, IpV6HandoverInitiateMessageCode code, bool buffer, IpV6HandoverInitiateMessageCode code,
IpV6MobilityOptions options) IpV6MobilityOptions options)
: base(nextHeader, checksum, options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
SequenceNumber = sequenceNumber; SequenceNumber = sequenceNumber;
AssignedAddressConfiguration = assignedAddressConfiguration; AssignedAddressConfiguration = assignedAddressConfiguration;
...@@ -2381,7 +2389,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -2381,7 +2389,7 @@ namespace PcapDotNet.Packets.IpV6
public IpV6ExtensionHeaderMobilityHandoverAcknowledgeMessage(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, public IpV6ExtensionHeaderMobilityHandoverAcknowledgeMessage(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber,
IpV6MobilityHandoverAcknowledgeCode code, IpV6MobilityOptions options) IpV6MobilityHandoverAcknowledgeCode code, IpV6MobilityOptions options)
: base(nextHeader, checksum, options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
SequenceNumber = sequenceNumber; SequenceNumber = sequenceNumber;
Code = code; Code = code;
...@@ -2502,7 +2510,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -2502,7 +2510,7 @@ namespace PcapDotNet.Packets.IpV6
public IpV6ExtensionHeaderMobilityBindingRevocationMessage(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool proxyBinding, public IpV6ExtensionHeaderMobilityBindingRevocationMessage(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool proxyBinding,
bool ipV4HomeAddressBindingOnly, bool global, IpV6MobilityOptions options) bool ipV4HomeAddressBindingOnly, bool global, IpV6MobilityOptions options)
: base(nextHeader, checksum, options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
SequenceNumber = sequenceNumber; SequenceNumber = sequenceNumber;
ProxyBinding = proxyBinding; ProxyBinding = proxyBinding;
...@@ -2890,7 +2898,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -2890,7 +2898,7 @@ namespace PcapDotNet.Packets.IpV6
public IpV6ExtensionHeaderMobilityLocalizedRouting(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, ushort lifetime, public IpV6ExtensionHeaderMobilityLocalizedRouting(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, ushort lifetime,
IpV6MobilityOptions options) IpV6MobilityOptions options)
: base(nextHeader, checksum, options) : base(nextHeader, checksum, options, MessageDataOffset.Options)
{ {
SequenceNumber = sequenceNumber; SequenceNumber = sequenceNumber;
Lifetime = lifetime; Lifetime = lifetime;
......
...@@ -44,7 +44,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -44,7 +44,7 @@ namespace PcapDotNet.Packets.IpV6
: base(nextHeader) : base(nextHeader)
{ {
if (options.BytesLength % 8 != 6) if (options.BytesLength % 8 != 6)
throw new ArgumentException("Options length in bytes must be an integral product of 8 + 6.", "options"); options = options.Pad((14 - options.BytesLength % 8) % 8);
Options = options; Options = options;
} }
......
...@@ -14,7 +14,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -14,7 +14,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre> /// </pre>
/// </summary> /// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.JumboPayload)] [IpV6OptionTypeRegistration(IpV6OptionType.JumboPayload)]
public class IpV6OptionJumboPayload : IpV6OptionComplex, IIpV6OptionComplexFactory public sealed class IpV6OptionJumboPayload : IpV6OptionComplex, IIpV6OptionComplexFactory
{ {
public const int OptionDataLength = sizeof(uint); public const int OptionDataLength = sizeof(uint);
......
...@@ -18,7 +18,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -18,7 +18,7 @@ namespace PcapDotNet.Packets.IpV6
public const int OptionDataLength = sizeof(byte); public const int OptionDataLength = sizeof(byte);
public IpV6OptionTunnelEncapsulationLimit(byte tunnelEncapsulationLimit) public IpV6OptionTunnelEncapsulationLimit(byte tunnelEncapsulationLimit)
: base(IpV6OptionType.JumboPayload) : base(IpV6OptionType.TunnelEncapsulationLimit)
{ {
TunnelEncapsulationLimit = tunnelEncapsulationLimit; TunnelEncapsulationLimit = tunnelEncapsulationLimit;
} }
......
...@@ -15,7 +15,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -15,7 +15,7 @@ namespace PcapDotNet.Packets.IpV6
public sealed class IpV6Options : Options<IpV6Option> public sealed class IpV6Options : Options<IpV6Option>
{ {
public IpV6Options(IList<IpV6Option> options) public IpV6Options(IList<IpV6Option> options)
: base(AddPadding(options), true, null) : base(options, true, null)
{ {
} }
...@@ -29,22 +29,14 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -29,22 +29,14 @@ namespace PcapDotNet.Packets.IpV6
{ {
} }
private IpV6Options(Tuple<IList<IpV6Option>, bool> optionsAndIsValid) internal IpV6Options Pad(int paddingSize)
: base(AddPadding(optionsAndIsValid.Item1), optionsAndIsValid.Item2, null)
{
}
private static IList<IpV6Option> AddPadding(IList<IpV6Option> options)
{ {
int optionsLength = options.Sum(option => option.Length); if (paddingSize == 0)
if (optionsLength % 8 == 6) return this;
return options; return new IpV6Options(OptionsCollection.Concat(paddingSize == 1 ? (IpV6Option)new IpV6OptionPad1() : new IpV6OptionPadN(paddingSize - 2)));
int paddingLength = (14 - optionsLength % 8) % 8;
return options.Concat(paddingLength == 1 ? (IpV6Option)new IpV6OptionPad1() : new IpV6OptionPadN(paddingLength - 2)).ToArray();
} }
public static Tuple<IList<IpV6Option>, bool> Read(DataSegment data) internal static Tuple<IList<IpV6Option>, bool> Read(DataSegment data)
{ {
int offset = 0; int offset = 0;
List<IpV6Option> options = new List<IpV6Option>(); List<IpV6Option> options = new List<IpV6Option>();
...@@ -89,6 +81,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -89,6 +81,11 @@ namespace PcapDotNet.Packets.IpV6
return optionsLength; return optionsLength;
} }
private IpV6Options(Tuple<IList<IpV6Option>, bool> optionsAndIsValid)
: base(optionsAndIsValid.Item1, optionsAndIsValid.Item2, null)
{
}
private static IpV6Option CreateOption(IpV6OptionType optionType, DataSegment data) private static IpV6Option CreateOption(IpV6OptionType optionType, DataSegment data)
{ {
IIpV6OptionComplexFactory factory; IIpV6OptionComplexFactory factory;
...@@ -147,6 +144,15 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -147,6 +144,15 @@ namespace PcapDotNet.Packets.IpV6
{ {
} }
/// <summary>
/// Creates options from a list of options.
/// </summary>
/// <param name="options">The list of options.</param>
public IpV6MobilityOptions(IEnumerable<IpV6MobilityOption> options)
: this(options.ToArray())
{
}
/// <summary> /// <summary>
/// Creates options from a list of options. /// Creates options from a list of options.
/// </summary> /// </summary>
...@@ -156,25 +162,32 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -156,25 +162,32 @@ namespace PcapDotNet.Packets.IpV6
{ {
} }
/// <summary>
/// No options instance.
/// </summary>
public static IpV6MobilityOptions None
{
get { return _none; }
}
internal IpV6MobilityOptions(DataSegment data) internal IpV6MobilityOptions(DataSegment data)
: this(Read(data)) : this(Read(data))
{ {
} }
private IpV6MobilityOptions(Tuple<IList<IpV6MobilityOption>, bool> optionsAndIsValid) internal IpV6MobilityOptions Pad(int paddingSize)
: base(optionsAndIsValid.Item1, optionsAndIsValid.Item2)
{ {
if (paddingSize == 0)
return this;
return new IpV6MobilityOptions(OptionsCollection.Concat(paddingSize == 1 ? (IpV6MobilityOption)new IpV6MobilityOptionPad1() : new IpV6MobilityOptionPadN(paddingSize - 2)));
} }
/// <summary> private IpV6MobilityOptions(Tuple<IList<IpV6MobilityOption>, bool> optionsAndIsValid)
/// No options instance. : base(optionsAndIsValid.Item1, optionsAndIsValid.Item2)
/// </summary>
public static IpV6MobilityOptions None
{ {
get { return _none; }
} }
public static Tuple<IList<IpV6MobilityOption>, bool> Read(DataSegment data) internal static Tuple<IList<IpV6MobilityOption>, bool> Read(DataSegment data)
{ {
int offset = 0; int offset = 0;
List<IpV6MobilityOption> options = new List<IpV6MobilityOption>(); List<IpV6MobilityOption> options = new List<IpV6MobilityOption>();
......
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