Commit d9417fcb authored by Brickner_cp's avatar Brickner_cp

GRE

parent b1f027ad
...@@ -73,7 +73,8 @@ namespace PcapDotNet.Packets.Test ...@@ -73,7 +73,8 @@ namespace PcapDotNet.Packets.Test
PacketBuilder packetBuilder = new PacketBuilder(ethernetLayer, ipV4Layer, greLayer); PacketBuilder packetBuilder = new PacketBuilder(ethernetLayer, ipV4Layer, greLayer);
Packet packet = packetBuilder.Build(DateTime.Now); Packet packet = packetBuilder.Build(DateTime.Now);
Assert.IsTrue(packet.IsValid, "IsValid"); if (greLayer.Checksum == null)
Assert.IsTrue(packet.IsValid, "IsValid");
// Ethernet // Ethernet
ethernetLayer.EtherType = EthernetType.IpV4; ethernetLayer.EtherType = EthernetType.IpV4;
...@@ -95,7 +96,7 @@ namespace PcapDotNet.Packets.Test ...@@ -95,7 +96,7 @@ namespace PcapDotNet.Packets.Test
GreLayer actualGreLayer = (GreLayer)actualGre.ExtractLayer(); GreLayer actualGreLayer = (GreLayer)actualGre.ExtractLayer();
if (greLayer.ChecksumPresent && greLayer.Checksum == null) if (greLayer.ChecksumPresent && greLayer.Checksum == null)
{ {
//Assert.IsTrue(actualGre.IsChecksumCorrect); Assert.IsTrue(actualGre.IsChecksumCorrect);
greLayer.Checksum = actualGre.Checksum; greLayer.Checksum = actualGre.Checksum;
} }
Assert.AreEqual(greLayer, actualGreLayer, "Layer"); Assert.AreEqual(greLayer, actualGreLayer, "Layer");
...@@ -105,6 +106,12 @@ namespace PcapDotNet.Packets.Test ...@@ -105,6 +106,12 @@ namespace PcapDotNet.Packets.Test
Assert.IsTrue(actualGre.RoutingPresent ^ (greLayer.Routing == null && greLayer.RoutingOffset == null)); Assert.IsTrue(actualGre.RoutingPresent ^ (greLayer.Routing == null && greLayer.RoutingOffset == null));
Assert.IsTrue(actualGre.SequenceNumberPresent ^ (greLayer.SequenceNumber == null)); Assert.IsTrue(actualGre.SequenceNumberPresent ^ (greLayer.SequenceNumber == null));
Assert.IsTrue(!actualGre.StrictSourceRoute || actualGre.RoutingPresent); Assert.IsTrue(!actualGre.StrictSourceRoute || actualGre.RoutingPresent);
if (actualGre.RoutingPresent)
{
Assert.IsNotNull(actualGre.ActiveSourceRouteEntryIndex);
if (actualGre.ActiveSourceRouteEntryIndex < actualGre.Routing.Count)
Assert.IsNotNull(actualGre.ActiveSourceRouteEntry);
}
} }
} }
} }
......
...@@ -146,6 +146,16 @@ namespace PcapDotNet.Packets.Gre ...@@ -146,6 +146,16 @@ namespace PcapDotNet.Packets.Gre
get { return ReadUShort(Offset.Checksum, Endianity.Big); } get { return ReadUShort(Offset.Checksum, Endianity.Big); }
} }
public bool IsChecksumCorrect
{
get
{
if (_isChecksumCorrect == null)
_isChecksumCorrect = (CalculateChecksum() == Checksum);
return _isChecksumCorrect.Value;
}
}
/// <summary> /// <summary>
/// The offset field indicates the octet offset from the start of the Routing field to the first octet of the active Source Route Entry to be examined. /// The offset field indicates the octet offset from the start of the Routing field to the first octet of the active Source Route Entry to be examined.
/// This field is present if the Routing Present or the Checksum Present bit is set to 1, and contains valid information only if the Routing Present bit is set to 1. /// This field is present if the Routing Present or the Checksum Present bit is set to 1, and contains valid information only if the Routing Present bit is set to 1.
...@@ -155,6 +165,28 @@ namespace PcapDotNet.Packets.Gre ...@@ -155,6 +165,28 @@ namespace PcapDotNet.Packets.Gre
get { return ReadUShort(Offset.RoutingOffset, Endianity.Big); } get { return ReadUShort(Offset.RoutingOffset, Endianity.Big); }
} }
public int? ActiveSourceRouteEntryIndex
{
get
{
if (_activeSourceRouteEntryIndex == null && RoutingPresent)
ParseRouting();
return _activeSourceRouteEntryIndex;
}
}
public GreSourceRouteEntry ActiveSourceRouteEntry
{
get
{
int? activeSourceRouteEntryIndex = ActiveSourceRouteEntryIndex;
if (activeSourceRouteEntryIndex == null || activeSourceRouteEntryIndex == Routing.Count)
return null;
return Routing[activeSourceRouteEntryIndex.Value];
}
}
/// <summary> /// <summary>
/// The Key field contains a four octet number which was inserted by the encapsulator. /// The Key field contains a four octet number which was inserted by the encapsulator.
/// It may be used by the receiver to authenticate the source of the packet. /// It may be used by the receiver to authenticate the source of the packet.
...@@ -194,28 +226,7 @@ namespace PcapDotNet.Packets.Gre ...@@ -194,28 +226,7 @@ namespace PcapDotNet.Packets.Gre
get get
{ {
if (_routing == null && RoutingPresent) if (_routing == null && RoutingPresent)
{ ParseRouting();
List<GreSourceRouteEntry> entries = new List<GreSourceRouteEntry>();
int entryOffset = StartOffset + OffsetRouting;
int totalLength = StartOffset + Length;
while (totalLength >= entryOffset)
{
GreSourceRouteEntry entry;
if (!GreSourceRouteEntry.TryReadEntry(Buffer, ref entryOffset, totalLength - entryOffset, out entry))
{
_isValidRouting = false;
break;
}
if (entry == null)
break;
entries.Add(entry);
}
_routing = new ReadOnlyCollection<GreSourceRouteEntry>(entries);
}
return _routing; return _routing;
} }
...@@ -250,8 +261,7 @@ namespace PcapDotNet.Packets.Gre ...@@ -250,8 +261,7 @@ namespace PcapDotNet.Packets.Gre
protected override bool CalculateIsValid() protected override bool CalculateIsValid()
{ {
throw new NotImplementedException(); return (Length >= HeaderMinimumLength && Length >= HeaderLength && (!ChecksumPresent || IsChecksumCorrect));
return (Length >= HeaderMinimumLength && Length >= HeaderLength);
} }
internal GreDatagram(byte[] buffer, int offset, int length) internal GreDatagram(byte[] buffer, int offset, int length)
...@@ -332,6 +342,38 @@ namespace PcapDotNet.Packets.Gre ...@@ -332,6 +342,38 @@ namespace PcapDotNet.Packets.Gre
get { return OffsetSequenceNumber + (SequenceNumberPresent ? sizeof(uint) : 0); } get { return OffsetSequenceNumber + (SequenceNumberPresent ? sizeof(uint) : 0); }
} }
private void ParseRouting()
{
List<GreSourceRouteEntry> entries = new List<GreSourceRouteEntry>();
int routingStartOffset = StartOffset + OffsetRouting;
int entryOffset = routingStartOffset;
int totalLength = StartOffset + Length;
while (totalLength >= entryOffset)
{
GreSourceRouteEntry entry;
if (entryOffset == routingStartOffset + RoutingOffset)
_activeSourceRouteEntryIndex = entries.Count;
if (!GreSourceRouteEntry.TryReadEntry(Buffer, ref entryOffset, totalLength - entryOffset, out entry))
{
_isValidRouting = false;
break;
}
if (entry == null)
break;
entries.Add(entry);
}
_routing = new ReadOnlyCollection<GreSourceRouteEntry>(entries);
}
private ushort CalculateChecksum()
{
return CalculateChecksum(Buffer, StartOffset, Length);
}
private static ushort CalculateChecksum(byte[] buffer, int offset, int length) private static ushort CalculateChecksum(byte[] buffer, int offset, int length)
{ {
uint sum = Sum16Bits(buffer, offset, Math.Min(Offset.Checksum, length)) + uint sum = Sum16Bits(buffer, offset, Math.Min(Offset.Checksum, length)) +
...@@ -343,6 +385,8 @@ namespace PcapDotNet.Packets.Gre ...@@ -343,6 +385,8 @@ namespace PcapDotNet.Packets.Gre
private IpV4Datagram _ipV4; private IpV4Datagram _ipV4;
private ReadOnlyCollection<GreSourceRouteEntry> _routing; private ReadOnlyCollection<GreSourceRouteEntry> _routing;
private bool _isValidRouting = true; private bool _isValidRouting = true;
private bool? _isChecksumCorrect;
private int? _activeSourceRouteEntryIndex;
} }
/// <summary> /// <summary>
...@@ -391,7 +435,7 @@ namespace PcapDotNet.Packets.Gre ...@@ -391,7 +435,7 @@ namespace PcapDotNet.Packets.Gre
protected abstract byte OffsetInPayload { get; } protected abstract byte OffsetInPayload { get; }
protected abstract bool EqualsPayloads(GreSourceRouteEntry other); protected abstract bool EqualsPayloads(GreSourceRouteEntry other);
protected abstract void WriteRoutingInformation(byte[] buffer, int offset); protected abstract void WritePayload(byte[] buffer, int offset);
internal static bool TryReadEntry(byte[] buffer, ref int offset, int length, out GreSourceRouteEntry entry) internal static bool TryReadEntry(byte[] buffer, ref int offset, int length, out GreSourceRouteEntry entry)
{ {
...@@ -429,7 +473,7 @@ namespace PcapDotNet.Packets.Gre ...@@ -429,7 +473,7 @@ namespace PcapDotNet.Packets.Gre
buffer.Write(offset + Offset.AddressFamily, (ushort)AddressFamily, Endianity.Big); buffer.Write(offset + Offset.AddressFamily, (ushort)AddressFamily, Endianity.Big);
buffer.Write(offset + Offset.SreOffset, OffsetInPayload); buffer.Write(offset + Offset.SreOffset, OffsetInPayload);
buffer.Write(offset + Offset.SreLength, (byte)PayloadLength); buffer.Write(offset + Offset.SreLength, (byte)PayloadLength);
WriteRoutingInformation(buffer, offset + HeaderLength); WritePayload(buffer, offset + HeaderLength);
offset += Length; offset += Length;
} }
...@@ -494,7 +538,7 @@ namespace PcapDotNet.Packets.Gre ...@@ -494,7 +538,7 @@ namespace PcapDotNet.Packets.Gre
return Addresses.SequenceEqual(((GreSourceRouteEntryIp)other).Addresses); return Addresses.SequenceEqual(((GreSourceRouteEntryIp)other).Addresses);
} }
protected override void WriteRoutingInformation(byte[] buffer, int offset) protected override void WritePayload(byte[] buffer, int offset)
{ {
foreach (IpV4Address address in Addresses) foreach (IpV4Address address in Addresses)
buffer.Write(ref offset, address, Endianity.Big); buffer.Write(ref offset, address, Endianity.Big);
...@@ -572,7 +616,7 @@ namespace PcapDotNet.Packets.Gre ...@@ -572,7 +616,7 @@ namespace PcapDotNet.Packets.Gre
get { return (byte)(NextAsNumberIndex * sizeof(ushort)); } get { return (byte)(NextAsNumberIndex * sizeof(ushort)); }
} }
protected override void WriteRoutingInformation(byte[] buffer, int offset) protected override void WritePayload(byte[] buffer, int offset)
{ {
foreach (ushort asNumber in AsNumbers) foreach (ushort asNumber in AsNumbers)
buffer.Write(ref offset, asNumber, Endianity.Big); buffer.Write(ref offset, asNumber, Endianity.Big);
...@@ -619,7 +663,7 @@ namespace PcapDotNet.Packets.Gre ...@@ -619,7 +663,7 @@ namespace PcapDotNet.Packets.Gre
return Data.Equals(((GreSourceRouteEntryUnknown)other).Data); return Data.Equals(((GreSourceRouteEntryUnknown)other).Data);
} }
protected override void WriteRoutingInformation(byte[] buffer, int offset) protected override void WritePayload(byte[] buffer, int offset)
{ {
buffer.Write(offset, Data); buffer.Write(offset, Data);
} }
......
...@@ -409,6 +409,9 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -409,6 +409,9 @@ namespace PcapDotNet.Packets.IpV4
case IpV4Protocol.InternetControlMessageProtocol: case IpV4Protocol.InternetControlMessageProtocol:
return Icmp.IsValid; return Icmp.IsValid;
case IpV4Protocol.Gre:
return Gre.IsValid;
default: default:
// Todo check more protocols // Todo check more protocols
return true; return true;
......
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