Commit 07592ef7 authored by Brickner_cp's avatar Brickner_cp

IPv6

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