Commit cc68ffec authored by Brickner_cp's avatar Brickner_cp

IPv6

Code coverage 94.16%
parent 791fb2ce
...@@ -115,5 +115,23 @@ namespace PcapDotNet.Packets.Test ...@@ -115,5 +115,23 @@ namespace PcapDotNet.Packets.Test
PacketBuilder.Build(DateTime.Now, new EthernetLayer(), new IpV6Layer(), new PayloadLayer()); PacketBuilder.Build(DateTime.Now, new EthernetLayer(), new IpV6Layer(), new PayloadLayer());
Assert.Fail(); Assert.Fail();
} }
[TestMethod]
public void IpV6OptionCalipsoChecksum()
{
Packet packet = PacketBuilder.Build(
DateTime.Now,
new EthernetLayer(),
new IpV6Layer()
{
ExtensionHeaders = new IpV6ExtensionHeaders(
new IpV6ExtensionHeaderDestinationOptions(
IpV4Protocol.Udp,
new IpV6Options(new IpV6OptionCalipso(IpV6CalipsoDomainOfInterpretation.Null, 0, null, DataSegment.Empty)))),
},
new UdpLayer());
Assert.IsTrue(packet.IsValid);
Assert.IsTrue(((IpV6OptionCalipso)((IpV6ExtensionHeaderDestinationOptions)packet.Ethernet.IpV6.ExtensionHeaders[0]).Options[0]).IsChecksumCorrect);
}
} }
} }
\ No newline at end of file
...@@ -93,12 +93,19 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -93,12 +93,19 @@ namespace PcapDotNet.Packets.IpV6
IpV4Protocol nextHeader; IpV4Protocol nextHeader;
if (NextHeader == null) if (NextHeader == null)
{ {
if (nextLayer == null) if (!ExtensionHeaders.IsNullOrEmpty())
throw new ArgumentException("Can't determine protocol automatically from next layer because there is no next layer"); {
IIpV4NextLayer ipV4NextLayer = nextLayer as IIpV4NextLayer; nextHeader = ExtensionHeaders[0].Protocol;
if (ipV4NextLayer == null) }
throw new ArgumentException("Can't determine protocol automatically from next layer (" + nextLayer.GetType() + ")"); else
nextHeader = ipV4NextLayer.PreviousLayerProtocol; {
if (nextLayer == null)
throw new ArgumentException("Can't determine protocol automatically from next layer because there is no next layer");
IIpV4NextLayer ipV4NextLayer = nextLayer as IIpV4NextLayer;
if (ipV4NextLayer == null)
throw new ArgumentException("Can't determine protocol automatically from next layer (" + nextLayer.GetType() + ")");
nextHeader = ipV4NextLayer.PreviousLayerProtocol;
}
} }
else else
{ {
......
...@@ -25,7 +25,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -25,7 +25,7 @@ namespace PcapDotNet.Packets.IpV6
/// </pre> /// </pre>
/// </summary> /// </summary>
[IpV6OptionTypeRegistration(IpV6OptionType.Calipso)] [IpV6OptionTypeRegistration(IpV6OptionType.Calipso)]
public class IpV6OptionCalipso : IpV6OptionComplex, IIpV6OptionComplexFactory public sealed class IpV6OptionCalipso : IpV6OptionComplex, IIpV6OptionComplexFactory
{ {
private static class Offset private static class Offset
{ {
...@@ -39,7 +39,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -39,7 +39,7 @@ namespace PcapDotNet.Packets.IpV6
public const int OptionDataMinimumLength = Offset.CompartmentBitmap; public const int OptionDataMinimumLength = Offset.CompartmentBitmap;
public const int CompartmentBitmapMaxLength = byte.MaxValue - OptionDataMinimumLength; 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)
...@@ -52,8 +52,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -52,8 +52,11 @@ namespace PcapDotNet.Packets.IpV6
DomainOfInterpretation = domainOfInterpretation; DomainOfInterpretation = domainOfInterpretation;
SensitivityLevel = sensitivityLevel; SensitivityLevel = sensitivityLevel;
Checksum = checksum;
CompartmentBitmap = compartmentBitmap; CompartmentBitmap = compartmentBitmap;
if (checksum.HasValue)
Checksum = checksum.Value;
else
Checksum = CalculateChecksum(DomainOfInterpretation, SensitivityLevel, CompartmentBitmap);
} }
/// <summary> /// <summary>
...@@ -66,7 +69,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -66,7 +69,7 @@ namespace PcapDotNet.Packets.IpV6
/// The minimum value is zero, which is used only when the information in this packet is not in any compartment. /// The minimum value is zero, which is used only when the information in this packet is not in any compartment.
/// (In that situation, the CALIPSO Sensitivity Label has no need for a Compartment Bitmap). /// (In that situation, the CALIPSO Sensitivity Label has no need for a Compartment Bitmap).
/// </summary> /// </summary>
public byte CompartmentLength { get { return (byte)(CompartmentLengthInBytes / sizeof(int)); } } public byte CompartmentLength { get { return CalculateCompartmentLength(CompartmentBitmap); } }
/// <summary> /// <summary>
/// Specifies the size of the Compartment Bitmap field in bytes. /// Specifies the size of the Compartment Bitmap field in bytes.
...@@ -105,12 +108,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -105,12 +108,7 @@ namespace PcapDotNet.Packets.IpV6
{ {
if (_isChecksumCorrect == null) if (_isChecksumCorrect == null)
{ {
byte[] domainOfInterpretationBytes = new byte[sizeof(uint)]; ushort expectedValue = CalculateChecksum(DomainOfInterpretation, SensitivityLevel, CompartmentBitmap);
domainOfInterpretationBytes.Write(0, (uint)DomainOfInterpretation, Endianity.Big);
ushort expectedValue =
PppFrameCheckSequenceCalculator.CalculateFcs16(
new byte[0].Concat((byte)OptionType, (byte)DataLength).Concat(domainOfInterpretationBytes)
.Concat<byte>(CompartmentLength, SensitivityLevel, 0, 0).Concat(CompartmentBitmap));
_isChecksumCorrect = (Checksum == expectedValue); _isChecksumCorrect = (Checksum == expectedValue);
} }
...@@ -134,11 +132,6 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -134,11 +132,6 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
public DataSegment CompartmentBitmap { get; private set; } public DataSegment CompartmentBitmap { get; private set; }
internal override int DataLength
{
get { return OptionDataMinimumLength + CompartmentLengthInBytes; }
}
public IpV6Option CreateInstance(DataSegment data) public IpV6Option CreateInstance(DataSegment data)
{ {
if (data.Length < OptionDataMinimumLength) if (data.Length < OptionDataMinimumLength)
...@@ -157,6 +150,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -157,6 +150,11 @@ namespace PcapDotNet.Packets.IpV6
return new IpV6OptionCalipso(domainOfInterpretation, sensitivityLevel, checksum, compartmentBitmap); return new IpV6OptionCalipso(domainOfInterpretation, sensitivityLevel, checksum, compartmentBitmap);
} }
internal override int DataLength
{
get { return OptionDataMinimumLength + CompartmentLengthInBytes; }
}
internal override bool EqualsData(IpV6Option other) internal override bool EqualsData(IpV6Option other)
{ {
return EqualsData(other as IpV6OptionCalipso); return EqualsData(other as IpV6OptionCalipso);
...@@ -183,6 +181,24 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -183,6 +181,24 @@ namespace PcapDotNet.Packets.IpV6
SensitivityLevel == other.SensitivityLevel && Checksum == other.Checksum && CompartmentBitmap.Equals(CompartmentBitmap); SensitivityLevel == other.SensitivityLevel && Checksum == other.Checksum && CompartmentBitmap.Equals(CompartmentBitmap);
} }
private static byte CalculateCompartmentLength(DataSegment compartmentBitmap)
{
return (byte)(compartmentBitmap.Length / sizeof(int));
}
private static ushort CalculateChecksum(IpV6CalipsoDomainOfInterpretation domainOfInterpretation, byte sensitivityLevel, DataSegment compartmentBitmap)
{
byte[] domainOfInterpretationBytes = new byte[sizeof(uint)];
domainOfInterpretationBytes.Write(0, (uint)domainOfInterpretation, Endianity.Big);
ushort checksum =
PppFrameCheckSequenceCalculator.CalculateFcs16(
new byte[0].Concat((byte)IpV6OptionType.Calipso,
(byte)(OptionDataMinimumLength + compartmentBitmap.Length)).Concat(
domainOfInterpretationBytes)
.Concat<byte>(CalculateCompartmentLength(compartmentBitmap), sensitivityLevel, 0, 0).Concat(compartmentBitmap));
return checksum;
}
private bool? _isChecksumCorrect; private bool? _isChecksumCorrect;
} }
} }
\ No newline at end of file
...@@ -19,6 +19,11 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -19,6 +19,11 @@ namespace PcapDotNet.Packets.IpV6
{ {
} }
public IpV6Options(params IpV6Option[] options)
: this((IList<IpV6Option>)options)
{
}
public IpV6Options(DataSegment data) public IpV6Options(DataSegment data)
: this(Read(data)) : this(Read(data))
{ {
......
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