Commit 0bea8462 authored by Brickner_cp's avatar Brickner_cp

IPv6

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