Commit 0155b99b authored by Brickner_cp's avatar Brickner_cp

Ethernet Trailer

parent b0b58a33
...@@ -120,7 +120,7 @@ namespace PcapDotNet.Core.Test ...@@ -120,7 +120,7 @@ namespace PcapDotNet.Core.Test
const int PacketSize = 100; const int PacketSize = 100;
// Normal // Normal
TestReceivePackets(NumPacketsToSend, NumPacketsToSend, int.MaxValue, 2, PacketSize, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend, 0, 0.041); TestReceivePackets(NumPacketsToSend, NumPacketsToSend, int.MaxValue, 2, PacketSize, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend, 0, 0.063);
// Wait for less packets // Wait for less packets
TestReceivePackets(NumPacketsToSend, NumPacketsToSend / 2, int.MaxValue, 2, PacketSize, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend / 2, 0, 0.02); TestReceivePackets(NumPacketsToSend, NumPacketsToSend / 2, int.MaxValue, 2, PacketSize, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend / 2, 0, 0.02);
...@@ -132,7 +132,7 @@ namespace PcapDotNet.Core.Test ...@@ -132,7 +132,7 @@ namespace PcapDotNet.Core.Test
// Break loop // Break loop
TestReceivePackets(NumPacketsToSend, NumPacketsToSend, 0, 2, PacketSize, PacketCommunicatorReceiveResult.BreakLoop, 0, 0, 0.027); TestReceivePackets(NumPacketsToSend, NumPacketsToSend, 0, 2, PacketSize, PacketCommunicatorReceiveResult.BreakLoop, 0, 0, 0.027);
TestReceivePackets(NumPacketsToSend, NumPacketsToSend, NumPacketsToSend / 2, 2, PacketSize, PacketCommunicatorReceiveResult.BreakLoop, NumPacketsToSend / 2, 0, 0.031); TestReceivePackets(NumPacketsToSend, NumPacketsToSend, NumPacketsToSend / 2, 2, PacketSize, PacketCommunicatorReceiveResult.BreakLoop, NumPacketsToSend / 2, 0, 0.032);
} }
[TestMethod] [TestMethod]
...@@ -148,11 +148,11 @@ namespace PcapDotNet.Core.Test ...@@ -148,11 +148,11 @@ namespace PcapDotNet.Core.Test
TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend / 2, int.MaxValue, 2, PacketSize, NumPacketsToSend / 2, 0, 0.032); TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend / 2, int.MaxValue, 2, PacketSize, NumPacketsToSend / 2, 0, 0.032);
// Wait for more packets // Wait for more packets
TestReceivePacketsEnumerable(NumPacketsToSend, -1, int.MaxValue, 2, PacketSize, NumPacketsToSend, 2, 2.031); TestReceivePacketsEnumerable(NumPacketsToSend, -1, int.MaxValue, 2, PacketSize, NumPacketsToSend, 2, 2.14);
TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend + 1, int.MaxValue, 2, PacketSize, NumPacketsToSend, 2, 2.13); TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend + 1, int.MaxValue, 2, PacketSize, NumPacketsToSend, 2, 2.13);
// Break loop // Break loop
TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend, 0, 2, PacketSize, 0, 0, 0.02); TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend, 0, 2, PacketSize, 0, 0, 0.032);
TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend, NumPacketsToSend / 2, 2, PacketSize, NumPacketsToSend / 2, 0, 0.031); TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend, NumPacketsToSend / 2, 2, PacketSize, NumPacketsToSend / 2, 0, 0.031);
} }
......
...@@ -90,6 +90,14 @@ namespace PcapDotNet.Core.Test ...@@ -90,6 +90,14 @@ namespace PcapDotNet.Core.Test
//ComparePacketsToWireshark(new[] { packet }); //ComparePacketsToWireshark(new[] { packet });
} }
[TestMethod]
public void CompareEthernetTrailerToWiresharkTest()
{
const string PacketString = "001120cf0900000c29566988080045000029627b00008006de80c0a8640bc0a81477a42cc03bdd3c481c6cfcd72050104278a5a90000000e01bf0101";
Packet packet = Packet.FromHexadecimalString(PacketString, DateTime.Now, DataLinkKind.Ethernet);
ComparePacketsToWireshark(packet);
}
private enum PacketType private enum PacketType
{ {
Ethernet, Ethernet,
...@@ -169,11 +177,17 @@ namespace PcapDotNet.Core.Test ...@@ -169,11 +177,17 @@ namespace PcapDotNet.Core.Test
yield return CreateRandomPacket(random); yield return CreateRandomPacket(random);
} }
private static void ComparePacketsToWireshark(params Packet[] packets)
{
ComparePacketsToWireshark((IEnumerable<Packet>)packets);
}
private static void ComparePacketsToWireshark(IEnumerable<Packet> packets) private static void ComparePacketsToWireshark(IEnumerable<Packet> packets)
{ {
string pcapFilename = Path.GetTempPath() + "temp." + new Random().NextByte() + ".pcap"; string pcapFilename = Path.GetTempPath() + "temp." + new Random().NextByte() + ".pcap";
// const bool isRetry = true; const bool IsRetry
const bool IsRetry = false; // = true;
= false;
#pragma warning disable 162 #pragma warning disable 162
// ReSharper disable ConditionIsAlwaysTrueOrFalse // ReSharper disable ConditionIsAlwaysTrueOrFalse
// ReSharper disable HeuristicUnreachableCode // ReSharper disable HeuristicUnreachableCode
...@@ -183,7 +197,7 @@ namespace PcapDotNet.Core.Test ...@@ -183,7 +197,7 @@ namespace PcapDotNet.Core.Test
} }
else else
{ {
const byte RetryNumber = 55; const byte RetryNumber = 244;
pcapFilename = Path.GetTempPath() + "temp." + RetryNumber + ".pcap"; pcapFilename = Path.GetTempPath() + "temp." + RetryNumber + ".pcap";
List<Packet> packetsList = new List<Packet>(); List<Packet> packetsList = new List<Packet>();
new OfflinePacketDevice(pcapFilename).Open().ReceivePackets(1000, packetsList.Add); new OfflinePacketDevice(pcapFilename).Open().ReceivePackets(1000, packetsList.Add);
...@@ -397,6 +411,10 @@ namespace PcapDotNet.Core.Test ...@@ -397,6 +411,10 @@ namespace PcapDotNet.Core.Test
break; break;
case "eth.trailer": case "eth.trailer":
if (ethernetDatagram.Trailer != null)
field.AssertValue(ethernetDatagram.Trailer);
break;
case "": case "":
break; break;
......
...@@ -254,19 +254,26 @@ namespace PcapDotNet.Packets.Test ...@@ -254,19 +254,26 @@ namespace PcapDotNet.Packets.Test
MaxResponseTime = TimeSpan.FromSeconds(1), MaxResponseTime = TimeSpan.FromSeconds(1),
QueryInterval = TimeSpan.FromSeconds(1), QueryInterval = TimeSpan.FromSeconds(1),
}); });
buffer = new byte[queryVersion3.Length + 1]; Assert.IsTrue(queryVersion3.IsValid, "IsValid");
buffer = new byte[queryVersion3.Length + 2];
queryVersion3.Buffer.BlockCopy(0, buffer, 0, queryVersion3.Length); queryVersion3.Buffer.BlockCopy(0, buffer, 0, queryVersion3.Length);
buffer[EthernetDatagram.HeaderLength + 3] += 2;
buffer[EthernetDatagram.HeaderLength + 11] -= 2;
Packet bigQueryVersion3 = new Packet(buffer, queryVersion3.Timestamp, queryVersion3.DataLink); Packet bigQueryVersion3 = new Packet(buffer, queryVersion3.Timestamp, queryVersion3.DataLink);
Assert.IsTrue(bigQueryVersion3.Ethernet.IpV4.Igmp.IsChecksumCorrect); Assert.IsTrue(bigQueryVersion3.Ethernet.IpV4.Igmp.IsChecksumCorrect);
Assert.IsFalse(bigQueryVersion3.IsValid); Assert.IsTrue(bigQueryVersion3.Ethernet.IpV4.IsHeaderChecksumCorrect, "IpV4.IsHeaderChecksumCorrect");
Assert.IsFalse(bigQueryVersion3.IsValid, "bigQueryVersion3.IsValid");
// Big report version 1 // Big report version 1
Packet reportVersion1 = PacketBuilder.Build(DateTime.Now, new EthernetLayer(), new IpV4Layer(), new IgmpReportVersion1Layer()); Packet reportVersion1 = PacketBuilder.Build(DateTime.Now, new EthernetLayer(), new IpV4Layer(), new IgmpReportVersion1Layer());
buffer = new byte[reportVersion1.Length + 1]; buffer = new byte[reportVersion1.Length + 2];
reportVersion1.Buffer.BlockCopy(0, buffer, 0, reportVersion1.Length); reportVersion1.Buffer.BlockCopy(0, buffer, 0, reportVersion1.Length);
buffer[EthernetDatagram.HeaderLength + 3] += 2;
buffer[EthernetDatagram.HeaderLength + 11] -= 2;
Packet bigReportVersion1 = new Packet(buffer, reportVersion1.Timestamp, reportVersion1.DataLink); Packet bigReportVersion1 = new Packet(buffer, reportVersion1.Timestamp, reportVersion1.DataLink);
Assert.IsTrue(bigReportVersion1.Ethernet.IpV4.Igmp.IsChecksumCorrect); Assert.IsTrue(bigReportVersion1.Ethernet.IpV4.Igmp.IsChecksumCorrect);
Assert.IsTrue(bigReportVersion1.Ethernet.IpV4.IsHeaderChecksumCorrect);
Assert.IsFalse(bigReportVersion1.IsValid); Assert.IsFalse(bigReportVersion1.IsValid);
// Non zero max response code for report version 1 // Non zero max response code for report version 1
...@@ -276,6 +283,7 @@ namespace PcapDotNet.Packets.Test ...@@ -276,6 +283,7 @@ namespace PcapDotNet.Packets.Test
buffer.Write(EthernetDatagram.HeaderLength + IpV4Datagram.HeaderMinimumLength + 2, (ushort)0xedfe, Endianity.Big); buffer.Write(EthernetDatagram.HeaderLength + IpV4Datagram.HeaderMinimumLength + 2, (ushort)0xedfe, Endianity.Big);
Packet nonZeroMaxResponseCodeReportVersion1 = new Packet(buffer, reportVersion1.Timestamp, reportVersion1.DataLink); Packet nonZeroMaxResponseCodeReportVersion1 = new Packet(buffer, reportVersion1.Timestamp, reportVersion1.DataLink);
Assert.IsTrue(nonZeroMaxResponseCodeReportVersion1.Ethernet.IpV4.Igmp.IsChecksumCorrect); Assert.IsTrue(nonZeroMaxResponseCodeReportVersion1.Ethernet.IpV4.Igmp.IsChecksumCorrect);
Assert.IsTrue(nonZeroMaxResponseCodeReportVersion1.Ethernet.IpV4.IsHeaderChecksumCorrect);
Assert.IsFalse(nonZeroMaxResponseCodeReportVersion1.IsValid); Assert.IsFalse(nonZeroMaxResponseCodeReportVersion1.IsValid);
// Big report version 2 // Big report version 2
...@@ -285,10 +293,13 @@ namespace PcapDotNet.Packets.Test ...@@ -285,10 +293,13 @@ namespace PcapDotNet.Packets.Test
MaxResponseTime = TimeSpan.FromSeconds(1) MaxResponseTime = TimeSpan.FromSeconds(1)
}); });
buffer = new byte[reportVersion2.Length + 1]; buffer = new byte[reportVersion2.Length + 2];
reportVersion2.Buffer.BlockCopy(0, buffer, 0, reportVersion2.Length); reportVersion2.Buffer.BlockCopy(0, buffer, 0, reportVersion2.Length);
buffer[EthernetDatagram.HeaderLength + 3] += 2;
buffer[EthernetDatagram.HeaderLength + 11] -= 2;
Packet bigReportVersion2 = new Packet(buffer, reportVersion2.Timestamp, reportVersion2.DataLink); Packet bigReportVersion2 = new Packet(buffer, reportVersion2.Timestamp, reportVersion2.DataLink);
Assert.IsTrue(bigReportVersion2.Ethernet.IpV4.Igmp.IsChecksumCorrect); Assert.IsTrue(bigReportVersion2.Ethernet.IpV4.Igmp.IsChecksumCorrect);
Assert.IsTrue(bigReportVersion2.Ethernet.IpV4.IsHeaderChecksumCorrect);
Assert.IsFalse(bigReportVersion2.IsValid); Assert.IsFalse(bigReportVersion2.IsValid);
// non zero max response code report version 3 // non zero max response code report version 3
...@@ -309,13 +320,17 @@ namespace PcapDotNet.Packets.Test ...@@ -309,13 +320,17 @@ namespace PcapDotNet.Packets.Test
buffer.Write(EthernetDatagram.HeaderLength + IpV4Datagram.HeaderMinimumLength + 2, (ushort)0xdbfd, Endianity.Big); buffer.Write(EthernetDatagram.HeaderLength + IpV4Datagram.HeaderMinimumLength + 2, (ushort)0xdbfd, Endianity.Big);
Packet nonZeroMaxResponseCodeReportVersion3 = new Packet(buffer, reportVersion3.Timestamp, reportVersion3.DataLink); Packet nonZeroMaxResponseCodeReportVersion3 = new Packet(buffer, reportVersion3.Timestamp, reportVersion3.DataLink);
Assert.IsTrue(nonZeroMaxResponseCodeReportVersion3.Ethernet.IpV4.Igmp.IsChecksumCorrect); Assert.IsTrue(nonZeroMaxResponseCodeReportVersion3.Ethernet.IpV4.Igmp.IsChecksumCorrect);
Assert.IsTrue(nonZeroMaxResponseCodeReportVersion3.Ethernet.IpV4.IsHeaderChecksumCorrect);
Assert.IsFalse(nonZeroMaxResponseCodeReportVersion3.IsValid); Assert.IsFalse(nonZeroMaxResponseCodeReportVersion3.IsValid);
// big report version 3 // big report version 3
buffer = new byte[reportVersion3.Length + 1]; buffer = new byte[reportVersion3.Length + 2];
reportVersion3.Buffer.BlockCopy(0, buffer, 0, reportVersion3.Length); reportVersion3.Buffer.BlockCopy(0, buffer, 0, reportVersion3.Length);
buffer[EthernetDatagram.HeaderLength + 3] += 2;
buffer[EthernetDatagram.HeaderLength + 11] -= 2;
Packet bigReportVersion3 = new Packet(buffer, reportVersion3.Timestamp, reportVersion3.DataLink); Packet bigReportVersion3 = new Packet(buffer, reportVersion3.Timestamp, reportVersion3.DataLink);
Assert.IsTrue(bigReportVersion3.Ethernet.IpV4.Igmp.IsChecksumCorrect); Assert.IsTrue(bigReportVersion3.Ethernet.IpV4.Igmp.IsChecksumCorrect);
Assert.IsTrue(bigReportVersion3.Ethernet.IpV4.IsHeaderChecksumCorrect);
Assert.IsFalse(bigReportVersion3.IsValid); Assert.IsFalse(bigReportVersion3.IsValid);
// invalid group record report version 3 // invalid group record report version 3
...@@ -325,6 +340,7 @@ namespace PcapDotNet.Packets.Test ...@@ -325,6 +340,7 @@ namespace PcapDotNet.Packets.Test
buffer.Write(EthernetDatagram.HeaderLength + IpV4Datagram.HeaderMinimumLength + 2, (ushort)0xdbfd, Endianity.Big); buffer.Write(EthernetDatagram.HeaderLength + IpV4Datagram.HeaderMinimumLength + 2, (ushort)0xdbfd, Endianity.Big);
Packet invalidGroupRecordReportVersion3 = new Packet(buffer, reportVersion3.Timestamp, reportVersion3.DataLink); Packet invalidGroupRecordReportVersion3 = new Packet(buffer, reportVersion3.Timestamp, reportVersion3.DataLink);
Assert.IsTrue(invalidGroupRecordReportVersion3.Ethernet.IpV4.Igmp.IsChecksumCorrect); Assert.IsTrue(invalidGroupRecordReportVersion3.Ethernet.IpV4.Igmp.IsChecksumCorrect);
Assert.IsTrue(invalidGroupRecordReportVersion3.Ethernet.IpV4.IsHeaderChecksumCorrect);
Assert.IsFalse(invalidGroupRecordReportVersion3.IsValid); Assert.IsFalse(invalidGroupRecordReportVersion3.IsValid);
} }
......
...@@ -196,7 +196,7 @@ namespace PcapDotNet.Packets ...@@ -196,7 +196,7 @@ namespace PcapDotNet.Packets
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param> /// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <returns>The value converted from the read bytes according to the endianity.</returns> /// <returns>The value converted from the read bytes according to the endianity.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "ushort")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "ushort")]
protected ushort ReadUShort(int offset, Endianity endianity) internal ushort ReadUShort(int offset, Endianity endianity)
{ {
return Buffer.ReadUShort(StartOffset + offset, endianity); return Buffer.ReadUShort(StartOffset + offset, endianity);
} }
......
...@@ -95,6 +95,20 @@ namespace PcapDotNet.Packets.Ethernet ...@@ -95,6 +95,20 @@ namespace PcapDotNet.Packets.Ethernet
get { return PayloadDatagrams.Payload; } get { return PayloadDatagrams.Payload; }
} }
public Datagram Trailer
{
get
{
Datagram payloadByEtherType = PayloadByEtherType;
if (payloadByEtherType == null)
return null;
int payloadLength = PayloadByEtherType.Length;
int fcs = Length >= 68 ? 4 : 0;
return new Datagram(Buffer, HeaderLength + payloadLength, Math.Max(0, Length - HeaderLength - payloadLength - fcs));
}
}
/// <summary> /// <summary>
/// The Ethernet payload as an IPv4 datagram. /// The Ethernet payload as an IPv4 datagram.
/// </summary> /// </summary>
...@@ -131,7 +145,8 @@ namespace PcapDotNet.Packets.Ethernet ...@@ -131,7 +145,8 @@ namespace PcapDotNet.Packets.Ethernet
if (Length < HeaderLength) if (Length < HeaderLength)
return false; return false;
return PayloadDatagrams.Get(EtherType).IsValid; Datagram payloadByEtherType = PayloadByEtherType;
return payloadByEtherType == null ? true : payloadByEtherType.IsValid;
} }
private EthernetPayloadDatagrams PayloadDatagrams private EthernetPayloadDatagrams PayloadDatagrams
...@@ -145,6 +160,11 @@ namespace PcapDotNet.Packets.Ethernet ...@@ -145,6 +160,11 @@ namespace PcapDotNet.Packets.Ethernet
} }
} }
private Datagram PayloadByEtherType
{
get { return PayloadDatagrams.Get(EtherType); }
}
private static readonly MacAddress _broadcastAddress = new MacAddress("FF:FF:FF:FF:FF:FF"); private static readonly MacAddress _broadcastAddress = new MacAddress("FF:FF:FF:FF:FF:FF");
private EthernetPayloadDatagrams _payloadDatagrams; private EthernetPayloadDatagrams _payloadDatagrams;
} }
......
...@@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Ethernet ...@@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Ethernet
return IpV4; return IpV4;
default: default:
return Payload; return null;
} }
} }
...@@ -33,7 +33,7 @@ namespace PcapDotNet.Packets.Ethernet ...@@ -33,7 +33,7 @@ namespace PcapDotNet.Packets.Ethernet
get get
{ {
if (_ipV4 == null && _payload != null) if (_ipV4 == null && _payload != null)
_ipV4 = new IpV4Datagram(_payload.Buffer, _payload.StartOffset, _payload.Length); _ipV4 = new IpV4Datagram(_payload.Buffer, _payload.StartOffset, IpV4Datagram.GetTotalLength(_payload));
return _ipV4; return _ipV4;
} }
} }
......
...@@ -352,11 +352,12 @@ namespace PcapDotNet.Packets.Gre ...@@ -352,11 +352,12 @@ namespace PcapDotNet.Packets.Gre
/// <returns>true iff the datagram is valid.</returns> /// <returns>true iff the datagram is valid.</returns>
protected override bool CalculateIsValid() protected override bool CalculateIsValid()
{ {
Datagram payloadByProtocolType = PayloadDatagrams.Get(ProtocolType);
return (Length >= HeaderMinimumLength && Length >= HeaderLength && return (Length >= HeaderMinimumLength && Length >= HeaderLength &&
IsValidRouting && FutureUseBits == 0 && IsValidRouting && FutureUseBits == 0 &&
(Version == GreVersion.EnhancedGre || Version == GreVersion.Gre && !AcknowledgmentSequenceNumberPresent) && (Version == GreVersion.EnhancedGre || Version == GreVersion.Gre && !AcknowledgmentSequenceNumberPresent) &&
(!ChecksumPresent || IsChecksumCorrect) && (!ChecksumPresent || IsChecksumCorrect) &&
PayloadDatagrams.Get(ProtocolType).IsValid); (payloadByProtocolType == null || payloadByProtocolType.IsValid));
} }
internal GreDatagram(byte[] buffer, int offset, int length) internal GreDatagram(byte[] buffer, int offset, int length)
......
...@@ -319,6 +319,18 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -319,6 +319,18 @@ namespace PcapDotNet.Packets.IpV4
} }
} }
internal static int GetTotalLength(Datagram ipV4Datagram)
{
if (ipV4Datagram.Length < HeaderMinimumLength)
return ipV4Datagram.Length;
ushort totalLength = ipV4Datagram.ReadUShort(Offset.TotalLength, Endianity.Big);
if (ipV4Datagram.Length < totalLength)
return ipV4Datagram.Length;
return totalLength;
}
internal IpV4Datagram(byte[] buffer, int offset, int length) internal IpV4Datagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length) : base(buffer, offset, length)
{ {
......
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