Commit 0bea8462 authored by Brickner_cp's avatar Brickner_cp

IPv6

parent 60cd47eb
......@@ -206,6 +206,7 @@ namespace PcapDotNet.Packets.TestUtils
case IpV6MobilityHeaderType.LocalizedRoutingAcknowledgement: // 18
return new IpV6ExtensionHeaderMobilityLocalizedRoutingAcknowledgement(nextHeader, checksum, random.NextUShort(), random.NextBool(),
random.NextEnum<IpV6MobilityLocalizedRoutingAcknowledgementStatus>(),
random.NextUShort(), random.NextIpV6MobilityOptions());
default:
......@@ -246,7 +247,7 @@ namespace PcapDotNet.Packets.TestUtils
case IpV6OptionType.Calipso:
return new IpV6OptionCalipso(random.NextEnum<IpV6CalipsoDomainOfInterpretation>(), random.NextByte(), random.NextUShort(),
random.NextDataSegment(random.NextByte() * sizeof(int)));
random.NextDataSegment(random.NextInt(0, IpV6OptionCalipso.CompartmentBitmapMaxLength + 1) / 4 * sizeof(int)));
case IpV6OptionType.SmfDpd:
if (random.NextBool())
......
......@@ -701,7 +701,8 @@ namespace PcapDotNet.Packets
/// <param name="endianity">The endianity to use when converting the value to bytes.</param>
public static void Write(this byte[] buffer, ref int offset, ulong value, Endianity endianity)
{
buffer.Write(offset, (long)value, endianity);
buffer.Write(offset, value, endianity);
offset += sizeof(ulong);
}
/// <summary>
......
......@@ -854,8 +854,8 @@ namespace PcapDotNet.Packets.IpV6
return null;
ushort careOfNonceIndex = messageData.ReadUShort(MessageDataOffset.CareOfNonceIndex, Endianity.Big);
ushort careOfInitCookie = messageData.ReadUShort(MessageDataOffset.CareOfInitCookie, Endianity.Big);
ushort careOfKeygenToken = messageData.ReadUShort(MessageDataOffset.CareOfKeygenToken, Endianity.Big);
ulong careOfInitCookie = messageData.ReadULong(MessageDataOffset.CareOfInitCookie, Endianity.Big);
ulong careOfKeygenToken = messageData.ReadULong(MessageDataOffset.CareOfKeygenToken, Endianity.Big);
IpV6MobilityOptions options = new IpV6MobilityOptions(messageData.Subsegment(MessageDataOffset.Options, messageData.Length - MessageDataOffset.Options));
return new IpV6ExtensionHeaderMobilityCareOfTest(nextHeader, checksum, careOfNonceIndex, careOfInitCookie, careOfKeygenToken, options);
}
......@@ -2950,10 +2950,13 @@ namespace PcapDotNet.Packets.IpV6
internal override sealed void WriteMessageData(byte[] buffer, int offset)
{
buffer.Write(offset + MessageDataOffset.SequenceNumber, SequenceNumber, Endianity.Big);
WriteMessageDataBetweenSequenceNumberAndLifetime(buffer, offset);
buffer.Write(offset + MessageDataOffset.Lifetime, Lifetime, Endianity.Big);
MobilityOptions.Write(buffer, offset + MessageDataOffset.Options);
}
internal abstract void WriteMessageDataBetweenSequenceNumberAndLifetime(byte[] buffer, int offset);
private bool EqualsMessageData(IpV6ExtensionHeaderMobilityLocalizedRouting other)
{
return other != null &&
......@@ -3016,6 +3019,10 @@ namespace PcapDotNet.Packets.IpV6
{
return true;
}
internal override void WriteMessageDataBetweenSequenceNumberAndLifetime(byte[] buffer, int offset)
{
}
}
/// <summary>
......@@ -3046,6 +3053,7 @@ namespace PcapDotNet.Packets.IpV6
private static class MessageDataOffset
{
public const int Unsolicited = sizeof(ushort);
public const int Status = Unsolicited + sizeof(byte);
}
private static class MessageDataMask
......@@ -3053,10 +3061,11 @@ namespace PcapDotNet.Packets.IpV6
public const byte Unsolicited = 0x80;
}
public IpV6ExtensionHeaderMobilityLocalizedRoutingAcknowledgement(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool unsolicited,
public IpV6ExtensionHeaderMobilityLocalizedRoutingAcknowledgement(IpV4Protocol nextHeader, ushort checksum, ushort sequenceNumber, bool unsolicited, IpV6MobilityLocalizedRoutingAcknowledgementStatus status,
ushort lifetime, IpV6MobilityOptions options)
: base(nextHeader, checksum, sequenceNumber, lifetime, options)
{
Status = status;
Unsolicited = unsolicited;
}
......@@ -3067,6 +3076,8 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
public bool Unsolicited { get; private set; }
public IpV6MobilityLocalizedRoutingAcknowledgementStatus Status { get; private set; }
/// <summary>
/// Identifies the particular mobility message in question.
/// An unrecognized MH Type field causes an error indication to be sent.
......@@ -3085,8 +3096,9 @@ namespace PcapDotNet.Packets.IpV6
return null;
bool unsolicited = messageData.ReadBool(MessageDataOffset.Unsolicited, MessageDataMask.Unsolicited);
IpV6MobilityLocalizedRoutingAcknowledgementStatus status = (IpV6MobilityLocalizedRoutingAcknowledgementStatus)messageData[MessageDataOffset.Status];
return new IpV6ExtensionHeaderMobilityLocalizedRoutingAcknowledgement(nextHeader, checksum, sequenceNumber, unsolicited, lifetime, options);
return new IpV6ExtensionHeaderMobilityLocalizedRoutingAcknowledgement(nextHeader, checksum, sequenceNumber, unsolicited, status, lifetime, options);
}
internal override bool EqualsMessageDataLocalizedRoutingExtraFields(IpV6ExtensionHeaderMobilityLocalizedRouting other)
......@@ -3094,10 +3106,38 @@ namespace PcapDotNet.Packets.IpV6
return EqualsMessageDataLocalizedRoutingExtraFields(other as IpV6ExtensionHeaderMobilityLocalizedRoutingAcknowledgement);
}
internal override void WriteMessageDataBetweenSequenceNumberAndLifetime(byte[] buffer, int offset)
{
if (Unsolicited)
buffer.Write(offset + MessageDataOffset.Unsolicited, MessageDataMask.Unsolicited);
buffer.Write(offset + MessageDataOffset.Status, (byte)Status);
}
private bool EqualsMessageDataLocalizedRoutingExtraFields(IpV6ExtensionHeaderMobilityLocalizedRoutingAcknowledgement other)
{
return other != null &&
Unsolicited == other.Unsolicited;
Unsolicited == other.Unsolicited && Status == other.Status;
}
}
/// <summary>
/// RFC-ietf-netext-pmip-lr-10.
/// </summary>
public enum IpV6MobilityLocalizedRoutingAcknowledgementStatus : byte
{
/// <summary>
/// Success.
/// </summary>
Success = 0,
/// <summary>
/// Localized Routing Not Allowed.
/// </summary>
LocalizedRoutingNotAllowed = 128,
/// <summary>
/// MN not attached.
/// </summary>
MobileNodeNotAttached = 129,
}
}
\ No newline at end of file
......@@ -72,7 +72,7 @@ namespace PcapDotNet.Packets.IpV6
if ((routingData.Length - RoutingDataMinimumLength) % IpV6Address.SizeOf != 0)
return null;
int numAddresses = (routingData.Length - RoutingDataMinimumLength) / 8;
int numAddresses = (routingData.Length - RoutingDataMinimumLength) / IpV6Address.SizeOf;
IpV6Address[] addresses = new IpV6Address[numAddresses];
for (int i = 0; i != numAddresses; ++i)
addresses[i] = routingData.ReadIpV6Address(RoutingDataOffset.Addresses + i * IpV6Address.SizeOf, Endianity.Big);
......
......@@ -37,15 +37,16 @@ namespace PcapDotNet.Packets.IpV6
}
public const int OptionDataMinimumLength = Offset.CompartmentBitmap;
public const int CompartmentBitmapMaxLength = byte.MaxValue - OptionDataMinimumLength;
public IpV6OptionCalipso(IpV6CalipsoDomainOfInterpretation domainOfInterpretation, byte sensitivityLevel, ushort checksum, DataSegment compartmentBitmap)
: base(IpV6OptionType.Calipso)
{
if (compartmentBitmap.Length % sizeof(int) != 0)
throw new ArgumentException(string.Format("Compartment Bitmap length must divide by {0}.", sizeof(int)), "compartmentBitmap");
if (compartmentBitmap.Length / sizeof(int) > byte.MaxValue)
if (compartmentBitmap.Length > CompartmentBitmapMaxLength)
{
throw new ArgumentOutOfRangeException(string.Format("Compartment Bitmap length must not be bigger than {0}.", byte.MaxValue * sizeof(int)),
throw new ArgumentOutOfRangeException(string.Format("Compartment Bitmap length must not be bigger than {0}.", CompartmentBitmapMaxLength),
"compartmentBitmap");
}
......
using System;
namespace PcapDotNet.Packets.IpV6
{
/// <summary>
......@@ -30,6 +32,9 @@ namespace PcapDotNet.Packets.IpV6
internal override sealed void Write(byte[] buffer, ref int offset)
{
base.Write(buffer, ref offset);
// TODO: Get rid of this.
if (DataLength > byte.MaxValue)
throw new InvalidOperationException("DataLength is " + DataLength);
buffer[offset++] = (byte)DataLength;
WriteData(buffer, ref offset);
}
......
......@@ -3698,7 +3698,7 @@ namespace PcapDotNet.Packets.IpV6
return null;
byte requestLength = data[offset++];
if (offset + requestLength >= data.Length)
if (offset + requestLength > data.Length)
return null;
DataSegment requestOption = data.Subsegment(offset, requestLength);
......
......@@ -179,7 +179,9 @@ namespace PcapDotNet.Packets.IpV6
{
if (paddingSize == 0)
return this;
return new IpV6MobilityOptions(OptionsCollection.Concat(paddingSize == 1 ? (IpV6MobilityOption)new IpV6MobilityOptionPad1() : new IpV6MobilityOptionPadN(paddingSize - 2)));
return new IpV6MobilityOptions(
OptionsCollection.Concat(paddingSize == 1 ? (IpV6MobilityOption)new IpV6MobilityOptionPad1() : new IpV6MobilityOptionPadN(paddingSize - 2)),
IsValid);
}
private IpV6MobilityOptions(Tuple<IList<IpV6MobilityOption>, bool> optionsAndIsValid)
......@@ -187,7 +189,12 @@ namespace PcapDotNet.Packets.IpV6
{
}
internal static Tuple<IList<IpV6MobilityOption>, bool> Read(DataSegment data)
private IpV6MobilityOptions(IEnumerable<IpV6MobilityOption> options, bool isValid)
: this(new Tuple<IList<IpV6MobilityOption>, bool>(options.ToList(), isValid))
{
}
private static Tuple<IList<IpV6MobilityOption>, bool> Read(DataSegment data)
{
int offset = 0;
List<IpV6MobilityOption> options = new List<IpV6MobilityOption>();
......@@ -235,8 +242,6 @@ namespace PcapDotNet.Packets.IpV6
return prototype.CreateInstance(data);
}
private static readonly Dictionary<IpV6MobilityOptionType, IpV6MobilityOption> _prototypes = InitializePrototypes();
private static Dictionary<IpV6MobilityOptionType, IpV6MobilityOption> InitializePrototypes()
{
var prototypes =
......@@ -261,6 +266,7 @@ namespace PcapDotNet.Packets.IpV6
return registraionAttributes.First();
}
private static readonly Dictionary<IpV6MobilityOptionType, IpV6MobilityOption> _prototypes = InitializePrototypes();
private static readonly IpV6MobilityOptions _none = new IpV6MobilityOptions();
}
}
\ No newline at end of file
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