Commit 44e35af5 authored by Brickner_cp's avatar Brickner_cp

GRE

parent e6ce2bec
...@@ -93,6 +93,11 @@ namespace PcapDotNet.Packets.Test ...@@ -93,6 +93,11 @@ namespace PcapDotNet.Packets.Test
// GRE // GRE
GreDatagram actualGre = packet.Ethernet.IpV4.Gre; GreDatagram actualGre = packet.Ethernet.IpV4.Gre;
GreLayer actualGreLayer = (GreLayer)actualGre.ExtractLayer(); GreLayer actualGreLayer = (GreLayer)actualGre.ExtractLayer();
if (greLayer.ChecksumPresent && greLayer.Checksum == null)
{
//Assert.IsTrue(actualGre.IsChecksumCorrect);
greLayer.Checksum = actualGre.Checksum;
}
Assert.AreEqual(greLayer, actualGreLayer, "Layer"); Assert.AreEqual(greLayer, actualGreLayer, "Layer");
} }
} }
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
using PcapDotNet.Base; using PcapDotNet.Base;
using PcapDotNet.Packets; using PcapDotNet.Packets;
...@@ -582,7 +583,66 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -582,7 +583,66 @@ namespace PcapDotNet.Packets.TestUtils
// GRE // GRE
public static GreLayer NextGreLayer(this Random random) public static GreLayer NextGreLayer(this Random random)
{ {
return new GreLayer(); bool isChecksum = random.NextBool();
bool isRouting = random.NextBool();
GreSourceRouteEntry[] routing = null;
ushort? routingOffset = null;
bool strictSourceRoute = false;
if (isRouting)
{
strictSourceRoute = random.NextBool();
routing = new GreSourceRouteEntry[random.Next(5)];
GreSourceRouteEntryAddressFamily family = random.NextEnum(GreSourceRouteEntryAddressFamily.None);
for (int i = 0; i != routing.Length; ++i)
{
switch (family)
{
case GreSourceRouteEntryAddressFamily.AsSourceRoute:
{
ushort[] asNumbers = new ushort[random.Next(5)];
for (int j = 0; j != asNumbers.Length; ++j)
asNumbers[j] = random.NextUShort();
routing[i] = new GreSourceRouteEntryAs(asNumbers.AsReadOnly(), asNumbers.IsEmpty() ? 0 : random.Next(asNumbers.Length));
break;
}
case GreSourceRouteEntryAddressFamily.IpSourceRoute:
{
IpV4Address[] ips = new IpV4Address[random.Next(5)];
for (int j = 0; j != ips.Length; ++j)
ips[j] = random.NextIpV4Address();
routing[i] = new GreSourceRouteEntryIp(ips.AsReadOnly(), ips.IsEmpty() ? 0 : random.Next(ips.Length));
break;
}
default:
throw new InvalidOperationException("Unknown family " + family);
}
}
routingOffset = 0;
if (!routing.IsEmpty())
{
int routingIndex = random.Next(routing.Length);
for (int i = 0; i != routingIndex; ++i)
routingOffset += (ushort)routing[i].Length;
}
}
return new GreLayer
{
Version = random.NextEnum<GreVersion>(),
ProtocolType = random.NextEnum(EthernetType.None),
ChecksumPresent = isChecksum,
Checksum = isChecksum && random.NextBool() ? (ushort?)random.NextUShort() : null,
Key = random.NextBool() ? (uint?)random.NextUInt() : null,
SequenceNumber = random.NextBool() ? (uint?)random.NextUInt() : null,
RecursionControl = random.NextByte(8),
Routing = routing == null ? null : routing.AsReadOnly(),
RoutingOffset = routingOffset,
StrictSourceRoute = strictSourceRoute,
};
} }
// ICMP // ICMP
......
...@@ -2,6 +2,7 @@ using System; ...@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using PcapDotNet.Base;
using PcapDotNet.Packets.Ethernet; using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.IpV4; using PcapDotNet.Packets.IpV4;
...@@ -197,10 +198,11 @@ namespace PcapDotNet.Packets.Gre ...@@ -197,10 +198,11 @@ namespace PcapDotNet.Packets.Gre
List<GreSourceRouteEntry> entries = new List<GreSourceRouteEntry>(); List<GreSourceRouteEntry> entries = new List<GreSourceRouteEntry>();
int entryOffset = StartOffset + OffsetRouting; int entryOffset = StartOffset + OffsetRouting;
while (Length >= entryOffset) int totalLength = StartOffset + Length;
while (totalLength >= entryOffset)
{ {
GreSourceRouteEntry entry; GreSourceRouteEntry entry;
if (!GreSourceRouteEntry.TryReadEntry(Buffer, ref entryOffset, Length - entryOffset, out entry)) if (!GreSourceRouteEntry.TryReadEntry(Buffer, ref entryOffset, totalLength - entryOffset, out entry))
{ {
_isValidRouting = false; _isValidRouting = false;
break; break;
...@@ -283,9 +285,14 @@ namespace PcapDotNet.Packets.Gre ...@@ -283,9 +285,14 @@ namespace PcapDotNet.Packets.Gre
buffer.Write(offset + Offset.ProtocolType, (ushort)protocolType, Endianity.Big); buffer.Write(offset + Offset.ProtocolType, (ushort)protocolType, Endianity.Big);
offset += Offset.RoutingOffset; offset += Offset.Checksum;
if (routingOffset != null) if (checksumPresent || routing != null)
buffer.Write(ref offset, routingOffset.Value, Endianity.Big); {
offset += sizeof(ushort);
if (routingOffset != null)
buffer.Write(offset, routingOffset.Value, Endianity.Big);
offset += sizeof(ushort);
}
if (key != null) if (key != null)
buffer.Write(ref offset, key.Value, Endianity.Big); buffer.Write(ref offset, key.Value, Endianity.Big);
...@@ -349,7 +356,7 @@ namespace PcapDotNet.Packets.Gre ...@@ -349,7 +356,7 @@ namespace PcapDotNet.Packets.Gre
/// +-----+------------------------------------------+ /// +-----+------------------------------------------+
/// </pre> /// </pre>
/// </summary> /// </summary>
public abstract class GreSourceRouteEntry public abstract class GreSourceRouteEntry : IEquatable<GreSourceRouteEntry>
{ {
public abstract GreSourceRouteEntryAddressFamily AddressFamily { get; } public abstract GreSourceRouteEntryAddressFamily AddressFamily { get; }
...@@ -369,7 +376,21 @@ namespace PcapDotNet.Packets.Gre ...@@ -369,7 +376,21 @@ namespace PcapDotNet.Packets.Gre
public abstract int PayloadLength { get; } public abstract int PayloadLength { get; }
public bool Equals(GreSourceRouteEntry other)
{
return AddressFamily == other.AddressFamily &&
Length == other.Length &&
OffsetInPayload == other.OffsetInPayload &&
EqualsPayloads(other);
}
public override bool Equals(object obj)
{
return Equals(obj as GreSourceRouteEntry);
}
protected abstract byte OffsetInPayload { get; } protected abstract byte OffsetInPayload { get; }
protected abstract bool EqualsPayloads(GreSourceRouteEntry other);
protected abstract void WriteRoutingInformation(byte[] buffer, int offset); protected abstract void WriteRoutingInformation(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)
...@@ -379,7 +400,7 @@ namespace PcapDotNet.Packets.Gre ...@@ -379,7 +400,7 @@ namespace PcapDotNet.Packets.Gre
return false; return false;
// Address Family // Address Family
GreSourceRouteEntryAddressFamily addressFamily = (GreSourceRouteEntryAddressFamily)buffer.ReadUShort(ref offset, Endianity.Big); GreSourceRouteEntryAddressFamily addressFamily = (GreSourceRouteEntryAddressFamily)buffer.ReadUShort(offset, Endianity.Big);
// SRE Length // SRE Length
byte sreLength = buffer[offset + Offset.SreLength]; byte sreLength = buffer[offset + Offset.SreLength];
...@@ -407,8 +428,9 @@ namespace PcapDotNet.Packets.Gre ...@@ -407,8 +428,9 @@ 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, Length, Endianity.Big); buffer.Write(offset + Offset.SreLength, (byte)PayloadLength);
WriteRoutingInformation(buffer, offset + HeaderLength); WriteRoutingInformation(buffer, offset + HeaderLength);
offset += Length;
} }
private static bool TryReadEntry(byte[] buffer, int payloadOffset, int payloadLength, GreSourceRouteEntryAddressFamily addressFamily, int offsetInPayload, out GreSourceRouteEntry entry) private static bool TryReadEntry(byte[] buffer, int payloadOffset, int payloadLength, GreSourceRouteEntryAddressFamily addressFamily, int offsetInPayload, out GreSourceRouteEntry entry)
...@@ -450,6 +472,13 @@ namespace PcapDotNet.Packets.Gre ...@@ -450,6 +472,13 @@ namespace PcapDotNet.Packets.Gre
public class GreSourceRouteEntryIp : GreSourceRouteEntry public class GreSourceRouteEntryIp : GreSourceRouteEntry
{ {
public GreSourceRouteEntryIp(ReadOnlyCollection<IpV4Address> addresses, int nextAddressIndex)
{
_addresses = addresses;
_nextAddressIndex = nextAddressIndex;
}
public override GreSourceRouteEntryAddressFamily AddressFamily public override GreSourceRouteEntryAddressFamily AddressFamily
{ {
get { return GreSourceRouteEntryAddressFamily.IpSourceRoute; } get { return GreSourceRouteEntryAddressFamily.IpSourceRoute; }
...@@ -457,7 +486,12 @@ namespace PcapDotNet.Packets.Gre ...@@ -457,7 +486,12 @@ namespace PcapDotNet.Packets.Gre
public override int PayloadLength public override int PayloadLength
{ {
get { return IpV4Address.SizeOf; } get { return Addresses.Count * IpV4Address.SizeOf; }
}
protected override bool EqualsPayloads(GreSourceRouteEntry other)
{
return Addresses.SequenceEqual(((GreSourceRouteEntryIp)other).Addresses);
} }
protected override void WriteRoutingInformation(byte[] buffer, int offset) protected override void WriteRoutingInformation(byte[] buffer, int offset)
...@@ -487,9 +521,8 @@ namespace PcapDotNet.Packets.Gre ...@@ -487,9 +521,8 @@ namespace PcapDotNet.Packets.Gre
} }
internal GreSourceRouteEntryIp(IpV4Address[] addresses, int nextAddressIndex) internal GreSourceRouteEntryIp(IpV4Address[] addresses, int nextAddressIndex)
:this(addresses.AsReadOnly(), nextAddressIndex)
{ {
_addresses = new ReadOnlyCollection<IpV4Address>(addresses);
_nextAddressIndex = nextAddressIndex;
} }
private readonly ReadOnlyCollection<IpV4Address> _addresses; private readonly ReadOnlyCollection<IpV4Address> _addresses;
...@@ -498,6 +531,12 @@ namespace PcapDotNet.Packets.Gre ...@@ -498,6 +531,12 @@ namespace PcapDotNet.Packets.Gre
public class GreSourceRouteEntryAs : GreSourceRouteEntry public class GreSourceRouteEntryAs : GreSourceRouteEntry
{ {
public GreSourceRouteEntryAs(ReadOnlyCollection<ushort> asNumbers, int nextAsNumberIndex)
{
_asNumbers = asNumbers;
_nextAsNumberIndex = nextAsNumberIndex;
}
public override GreSourceRouteEntryAddressFamily AddressFamily public override GreSourceRouteEntryAddressFamily AddressFamily
{ {
get { return GreSourceRouteEntryAddressFamily.AsSourceRoute; } get { return GreSourceRouteEntryAddressFamily.AsSourceRoute; }
...@@ -505,7 +544,12 @@ namespace PcapDotNet.Packets.Gre ...@@ -505,7 +544,12 @@ namespace PcapDotNet.Packets.Gre
public override int PayloadLength public override int PayloadLength
{ {
get { return sizeof(ushort); } get { return AsNumbers.Count * sizeof(ushort); }
}
protected override bool EqualsPayloads(GreSourceRouteEntry other)
{
return AsNumbers.SequenceEqual(((GreSourceRouteEntryAs)other).AsNumbers);
} }
public ReadOnlyCollection<ushort> AsNumbers public ReadOnlyCollection<ushort> AsNumbers
...@@ -535,9 +579,8 @@ namespace PcapDotNet.Packets.Gre ...@@ -535,9 +579,8 @@ namespace PcapDotNet.Packets.Gre
} }
internal GreSourceRouteEntryAs(ushort[] asNumbers, int nextAsNumberIndex) internal GreSourceRouteEntryAs(ushort[] asNumbers, int nextAsNumberIndex)
: this(asNumbers.AsReadOnly(), nextAsNumberIndex)
{ {
_asNumbers = new ReadOnlyCollection<ushort>(asNumbers);
_nextAsNumberIndex = nextAsNumberIndex;
} }
private readonly ReadOnlyCollection<ushort> _asNumbers; private readonly ReadOnlyCollection<ushort> _asNumbers;
...@@ -571,6 +614,11 @@ namespace PcapDotNet.Packets.Gre ...@@ -571,6 +614,11 @@ namespace PcapDotNet.Packets.Gre
get { return (byte)Offset; } get { return (byte)Offset; }
} }
protected override bool EqualsPayloads(GreSourceRouteEntry other)
{
return Data.Equals(((GreSourceRouteEntryUnknown)other).Data);
}
protected override void WriteRoutingInformation(byte[] buffer, int offset) protected override void WriteRoutingInformation(byte[] buffer, int offset)
{ {
buffer.Write(offset, Data); buffer.Write(offset, 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