Commit d9417fcb authored by Brickner_cp's avatar Brickner_cp

GRE

parent b1f027ad
......@@ -73,7 +73,8 @@ namespace PcapDotNet.Packets.Test
PacketBuilder packetBuilder = new PacketBuilder(ethernetLayer, ipV4Layer, greLayer);
Packet packet = packetBuilder.Build(DateTime.Now);
Assert.IsTrue(packet.IsValid, "IsValid");
if (greLayer.Checksum == null)
Assert.IsTrue(packet.IsValid, "IsValid");
// Ethernet
ethernetLayer.EtherType = EthernetType.IpV4;
......@@ -95,7 +96,7 @@ namespace PcapDotNet.Packets.Test
GreLayer actualGreLayer = (GreLayer)actualGre.ExtractLayer();
if (greLayer.ChecksumPresent && greLayer.Checksum == null)
{
//Assert.IsTrue(actualGre.IsChecksumCorrect);
Assert.IsTrue(actualGre.IsChecksumCorrect);
greLayer.Checksum = actualGre.Checksum;
}
Assert.AreEqual(greLayer, actualGreLayer, "Layer");
......@@ -105,6 +106,12 @@ namespace PcapDotNet.Packets.Test
Assert.IsTrue(actualGre.RoutingPresent ^ (greLayer.Routing == null && greLayer.RoutingOffset == null));
Assert.IsTrue(actualGre.SequenceNumberPresent ^ (greLayer.SequenceNumber == null));
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
get { return ReadUShort(Offset.Checksum, Endianity.Big); }
}
public bool IsChecksumCorrect
{
get
{
if (_isChecksumCorrect == null)
_isChecksumCorrect = (CalculateChecksum() == Checksum);
return _isChecksumCorrect.Value;
}
}
/// <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.
/// 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
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>
/// 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.
......@@ -194,28 +226,7 @@ namespace PcapDotNet.Packets.Gre
get
{
if (_routing == null && RoutingPresent)
{
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);
}
ParseRouting();
return _routing;
}
......@@ -250,8 +261,7 @@ namespace PcapDotNet.Packets.Gre
protected override bool CalculateIsValid()
{
throw new NotImplementedException();
return (Length >= HeaderMinimumLength && Length >= HeaderLength);
return (Length >= HeaderMinimumLength && Length >= HeaderLength && (!ChecksumPresent || IsChecksumCorrect));
}
internal GreDatagram(byte[] buffer, int offset, int length)
......@@ -332,6 +342,38 @@ namespace PcapDotNet.Packets.Gre
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)
{
uint sum = Sum16Bits(buffer, offset, Math.Min(Offset.Checksum, length)) +
......@@ -343,6 +385,8 @@ namespace PcapDotNet.Packets.Gre
private IpV4Datagram _ipV4;
private ReadOnlyCollection<GreSourceRouteEntry> _routing;
private bool _isValidRouting = true;
private bool? _isChecksumCorrect;
private int? _activeSourceRouteEntryIndex;
}
/// <summary>
......@@ -391,7 +435,7 @@ namespace PcapDotNet.Packets.Gre
protected abstract byte OffsetInPayload { get; }
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)
{
......@@ -429,7 +473,7 @@ namespace PcapDotNet.Packets.Gre
buffer.Write(offset + Offset.AddressFamily, (ushort)AddressFamily, Endianity.Big);
buffer.Write(offset + Offset.SreOffset, OffsetInPayload);
buffer.Write(offset + Offset.SreLength, (byte)PayloadLength);
WriteRoutingInformation(buffer, offset + HeaderLength);
WritePayload(buffer, offset + HeaderLength);
offset += Length;
}
......@@ -494,7 +538,7 @@ namespace PcapDotNet.Packets.Gre
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)
buffer.Write(ref offset, address, Endianity.Big);
......@@ -572,7 +616,7 @@ namespace PcapDotNet.Packets.Gre
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)
buffer.Write(ref offset, asNumber, Endianity.Big);
......@@ -619,7 +663,7 @@ namespace PcapDotNet.Packets.Gre
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);
}
......
......@@ -409,6 +409,9 @@ namespace PcapDotNet.Packets.IpV4
case IpV4Protocol.InternetControlMessageProtocol:
return Icmp.IsValid;
case IpV4Protocol.Gre:
return Gre.IsValid;
default:
// Todo check more protocols
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