Commit 92d02194 authored by Boaz Brickner's avatar Boaz Brickner

Add OriginalLength to Packet. Now you can tell what was the length of the...

Add OriginalLength to Packet. Now you can tell what was the length of the packet off wire and not just the captured part.
parent 6c3b1f0d
......@@ -59,7 +59,7 @@ namespace PcapDotNet.Core.Test
const string DestinationMac = "77:88:99:AA:BB:CC";
const int NumPacketsToSend = 10;
using (PacketCommunicator communicator = OpenLiveDevice())
using (PacketCommunicator communicator = OpenLiveDevice(100))
{
communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac);
......@@ -72,7 +72,7 @@ namespace PcapDotNet.Core.Test
Assert.AreEqual<uint>(0, communicator.TotalStatistics.PacketsCaptured);
MoreAssert.IsInRange(TimeSpan.FromSeconds(0.99), TimeSpan.FromSeconds(1.075), finishedWaiting - startWaiting);
Packet sentPacket = _random.NextEthernetPacket(24, SourceMac, DestinationMac);
Packet sentPacket = _random.NextEthernetPacket(200, 300, SourceMac, DestinationMac);
DateTime startSendingTime = DateTime.Now;
......@@ -86,7 +86,8 @@ namespace PcapDotNet.Core.Test
result = communicator.ReceivePacket(out packet);
Assert.AreEqual(PacketCommunicatorReceiveResult.Ok, result);
Assert.AreEqual(sentPacket.Length, packet.Length);
Assert.AreEqual(100, packet.Length);
Assert.AreEqual<uint>(200, packet.OriginalLength);
MoreAssert.IsInRange(startSendingTime - TimeSpan.FromSeconds(1), endSendingTime + TimeSpan.FromSeconds(30), packet.Timestamp);
}
Assert.AreEqual<uint>(NumPacketsToSend, communicator.TotalStatistics.PacketsCaptured);
......@@ -843,7 +844,7 @@ namespace PcapDotNet.Core.Test
}
}
public static PacketCommunicator OpenLiveDevice()
public static PacketCommunicator OpenLiveDevice(int snapshotLength)
{
NetworkInterface networkInterface =
NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(
......@@ -873,7 +874,7 @@ namespace PcapDotNet.Core.Test
}
}
PacketCommunicator communicator = device.Open();
PacketCommunicator communicator = device.Open(snapshotLength, PacketDeviceOpenAttributes.Promiscuous, 1000);
try
{
MoreAssert.AreSequenceEqual(new[] {DataLinkKind.Ethernet, DataLinkKind.Docsis}.Select(kind => new PcapDataLink(kind)), communicator.SupportedDataLinks);
......@@ -900,7 +901,7 @@ namespace PcapDotNet.Core.Test
Assert.IsTrue(communicator.IsFileSystemByteOrder);
Assert.AreEqual(PacketCommunicatorMode.Capture, communicator.Mode);
Assert.IsFalse(communicator.NonBlocking);
Assert.AreEqual(PacketDevice.DefaultSnapshotLength, communicator.SnapshotLength);
Assert.AreEqual(snapshotLength, communicator.SnapshotLength);
return communicator;
}
catch (Exception)
......@@ -910,6 +911,11 @@ namespace PcapDotNet.Core.Test
}
}
public static PacketCommunicator OpenLiveDevice()
{
return OpenLiveDevice(PacketDevice.DefaultSnapshotLength);
}
private static readonly Random _random = new Random();
}
}
\ No newline at end of file
......@@ -310,7 +310,7 @@ Packet^ PacketCommunicator::CreatePacket(const pcap_pkthdr& packetHeader, const
PacketTimestamp::PcapTimestampToDateTime(packetHeader.ts, timestamp);
array<Byte>^ managedPacketData = MarshalingServices::UnmanagedToManagedByteArray(packetData, 0, packetHeader.caplen);
return gcnew Packet(managedPacketData, timestamp, dataLink);
return gcnew Packet(managedPacketData, timestamp, dataLink, packetHeader.len);
}
PacketCommunicatorReceiveResult PacketCommunicator::RunPcapNextEx(pcap_pkthdr** packetHeader, const unsigned char** packetData)
......
......@@ -9,6 +9,6 @@ using namespace PcapDotNet::Packets;
void PacketHeader::GetPcapHeader(pcap_pkthdr &header, Packet^ packet)
{
PacketTimestamp::DateTimeToPcapTimestamp(packet->Timestamp, header.ts);
header.len = packet->Length;
header.len = packet->OriginalLength;
header.caplen = packet->Length;
}
\ No newline at end of file
......@@ -79,6 +79,14 @@ namespace PcapDotNet.Packets.Test
}
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException), AllowDerivedTypes = false)]
public void PacketConstructorNullDataTest()
{
Packet packet = new Packet(null, DateTime.Now, DataLinkKind.Ethernet);
Assert.IsNull(packet);
}
[TestMethod]
public void PacketIListTest()
{
......
......@@ -31,13 +31,13 @@ namespace PcapDotNet.Packets.TestUtils
return random.NextEnum(EthernetType.None);
}
public static Packet NextEthernetPacket(this Random random, int packetSize, DateTime timestamp, MacAddress ethernetSource, MacAddress ethernetDestination)
public static Packet NextEthernetPacket(this Random random, int packetSize, DateTime timestamp, uint originalLength, MacAddress ethernetSource, MacAddress ethernetDestination)
{
if (packetSize < EthernetDatagram.HeaderLengthValue)
throw new ArgumentOutOfRangeException("packetSize", packetSize,
"Must be at least the ethernet header length (" + EthernetDatagram.HeaderLengthValue + ")");
return PacketBuilder.Build(timestamp,
return PacketBuilder.Build(timestamp, originalLength,
new EthernetLayer
{
Source = ethernetSource,
......@@ -47,24 +47,44 @@ namespace PcapDotNet.Packets.TestUtils
random.NextPayloadLayer(packetSize - EthernetDatagram.HeaderLengthValue));
}
public static Packet NextEthernetPacket(this Random random, int packetSize, DateTime timestamp, uint originalLength, string ethernetSource, string ethernetDestination)
{
return random.NextEthernetPacket(packetSize, timestamp, originalLength, new MacAddress(ethernetSource), new MacAddress(ethernetDestination));
}
public static Packet NextEthernetPacket(this Random random, int packetSize, DateTime timestamp, string ethernetSource, string ethernetDestination)
{
return random.NextEthernetPacket(packetSize, timestamp, new MacAddress(ethernetSource), new MacAddress(ethernetDestination));
return random.NextEthernetPacket(packetSize, timestamp, 0, ethernetSource, ethernetDestination);
}
public static Packet NextEthernetPacket(this Random random, int packetSize, uint originalLength, MacAddress ethernetSource, MacAddress ethernetDestination)
{
return random.NextEthernetPacket(packetSize, DateTime.Now, originalLength, ethernetSource, ethernetDestination);
}
public static Packet NextEthernetPacket(this Random random, int packetSize, MacAddress ethernetSource, MacAddress ethernetDestination)
{
return random.NextEthernetPacket(packetSize, DateTime.Now, ethernetSource, ethernetDestination);
return random.NextEthernetPacket(packetSize, 0, ethernetSource, ethernetDestination);
}
public static Packet NextEthernetPacket(this Random random, int packetSize, uint originalLength, string ethernetSource, string ethernetDestination)
{
return random.NextEthernetPacket(packetSize, DateTime.Now, originalLength, ethernetSource, ethernetDestination);
}
public static Packet NextEthernetPacket(this Random random, int packetSize, string ethernetSource, string ethernetDestination)
{
return random.NextEthernetPacket(packetSize, DateTime.Now, ethernetSource, ethernetDestination);
return random.NextEthernetPacket(packetSize, 0, ethernetSource, ethernetDestination);
}
public static Packet NextEthernetPacket(this Random random, int packetSize, uint originalLength)
{
return random.NextEthernetPacket(packetSize, DateTime.Now, originalLength, random.NextMacAddress(), random.NextMacAddress());
}
public static Packet NextEthernetPacket(this Random random, int packetSize)
{
return random.NextEthernetPacket(packetSize, DateTime.Now, random.NextMacAddress(), random.NextMacAddress());
return random.NextEthernetPacket(packetSize, 0);
}
}
}
\ No newline at end of file
......@@ -47,32 +47,74 @@ namespace PcapDotNet.Packets
/// <param name="data">The bytes of the packet. This array should not be changed after creating the packet until the packet is no longer used.</param>
/// <param name="timestamp">A timestamp of the packet - when it was captured.</param>
/// <param name="dataLink">The type of the datalink of the packet.</param>
public Packet(byte[] data, DateTime timestamp, DataLinkKind dataLink)
:this(data, timestamp, new DataLink(dataLink))
/// <param name="originalLength">
/// Length this packet (off wire).
/// If the value is less than the data size, it is ignored and the original length is considered to be equal to the data size.
/// </param>
public Packet(byte[] data, DateTime timestamp, IDataLink dataLink, uint originalLength)
{
if (data == null)
throw new ArgumentNullException("data");
_data = data;
_timestamp = timestamp;
_dataLink = dataLink;
OriginalLength = Math.Max((uint)_data.Length, originalLength);
}
/// <summary>
/// Create a packet from an array of bytes.
/// The original length is considered to be the actual size.
/// </summary>
/// <param name="data">The bytes of the packet. This array should not be changed after creating the packet until the packet is no longer used.</param>
/// <param name="timestamp">A timestamp of the packet - when it was captured.</param>
/// <param name="dataLink">The type of the datalink of the packet.</param>
public Packet(byte[] data, DateTime timestamp, IDataLink dataLink)
: this(data, timestamp, dataLink, 0)
{
}
/// <summary>
/// Create a packet from an array of bytes, assuming original length is equal to the data size.
/// </summary>
/// <param name="data">The bytes of the packet. This array should not be changed after creating the packet until the packet is no longer used.</param>
/// <param name="timestamp">A timestamp of the packet - when it was captured.</param>
/// <param name="dataLink">The type of the datalink of the packet.</param>
/// <param name="originalLength">
/// Length this packet (off wire).
/// If the value is less than the data size, it is ignored and the original length is considered to be equal to the data size.
/// </param>
public Packet(byte[] data, DateTime timestamp, DataLinkKind dataLink, uint originalLength)
: this(data, timestamp, new DataLink(dataLink), originalLength)
{
}
/// <summary>
/// Create a packet from an array of bytes, assuming original length is equal to the data size.
/// The original length is considered to be the actual size.
/// </summary>
/// <param name="data">The bytes of the packet. This array should not be changed after creating the packet until the packet is no longer used.</param>
/// <param name="timestamp">A timestamp of the packet - when it was captured.</param>
/// <param name="dataLink">The type of the datalink of the packet.</param>
public Packet(byte[] data, DateTime timestamp, DataLinkKind dataLink)
: this(data, timestamp, dataLink, 0)
{
_data = data;
_timestamp = timestamp;
_dataLink = dataLink;
}
/// <summary>
/// The number of bytes this packet take.
/// When capturing, represents the number of bytes captured.
/// </summary>
public int Length
{
get { return _data.Length; }
}
/// <summary>
/// Length this packet (off wire).
/// When capturing, can be bigger than the number of captured bytes represented in Length.
/// </summary>
public uint OriginalLength { get; private set; }
/// <summary>
/// The time this packet was captured.
/// </summary>
......
......@@ -48,22 +48,54 @@ namespace PcapDotNet.Packets
/// Builds a single packet using the given layers with the given timestamp.
/// </summary>
/// <param name="timestamp">The packet's timestamp.</param>
/// <param name="originalLength">
/// Length this packet (off wire).
/// If the value is less than the actual size, it is ignored and the original length is considered to be equal to the actual size.
/// </param>
/// <param name="layers">The layers to build the packet accordingly and by their order.</param>
/// <returns>A packet built from the given layers with the given timestamp.</returns>
public static Packet Build(DateTime timestamp, uint originalLength, params ILayer[] layers)
{
return new PacketBuilder(layers).Build(timestamp, originalLength);
}
/// <summary>
/// Builds a single packet using the given layers with the given timestamp.
/// The original length is considered to be the actual size.
/// </summary>
/// <param name="timestamp">The packet's timestamp.</param>
/// <param name="layers">The layers to build the packet accordingly and by their order.</param>
/// <returns>A packet built from the given layers with the given timestamp.</returns>
public static Packet Build(DateTime timestamp, params ILayer[] layers)
{
return new PacketBuilder(layers).Build(timestamp);
return Build(timestamp, 0, layers);
}
/// <summary>
/// Builds a single packet using the given layers with the given timestamp.
/// </summary>
/// <param name="timestamp">The packet's timestamp.</param>
/// <param name="originalLength">
/// Length this packet (off wire).
/// If the value is less than the actual size, it is ignored and the original length is considered to be equal to the actual size.
/// </param>
/// <param name="layers">The layers to build the packet accordingly and by their order.</param>
/// <returns>A packet built from the given layers with the given timestamp.</returns>
public static Packet Build(DateTime timestamp, uint originalLength, IEnumerable<ILayer> layers)
{
return new PacketBuilder(layers).Build(timestamp, originalLength);
}
/// <summary>
/// Builds a single packet using the given layers with the given timestamp.
/// The original length is considered to be the actual size.
/// </summary>
/// <param name="timestamp">The packet's timestamp.</param>
/// <param name="layers">The layers to build the packet accordingly and by their order.</param>
/// <returns>A packet built from the given layers with the given timestamp.</returns>
public static Packet Build(DateTime timestamp, IEnumerable<ILayer> layers)
{
return new PacketBuilder(layers).Build(timestamp);
return Build(timestamp, 0, layers);
}
/// <summary>
......@@ -102,8 +134,12 @@ namespace PcapDotNet.Packets
/// Builds a single packet using the builder's layers with the given timestamp.
/// </summary>
/// <param name="timestamp">The packet's timestamp.</param>
/// <param name="originalLength">
/// Length this packet (off wire).
/// If the value is less than the actual size, it is ignored and the original length is considered to be equal to the actual size.
/// </param>
/// <returns>A packet built from the builder's layers with the given timestamp.</returns>
public Packet Build(DateTime timestamp)
public Packet Build(DateTime timestamp, uint originalLength)
{
int[] layersLength = _layers.Select(layer => layer.Length).ToArray();
int length = layersLength.Sum();
......@@ -112,7 +148,18 @@ namespace PcapDotNet.Packets
WriteLayers(layersLength, buffer, length);
FinalizeLayers(buffer, length);
return new Packet(buffer, timestamp, _dataLink);
return new Packet(buffer, timestamp, _dataLink, originalLength);
}
/// <summary>
/// Builds a single packet using the builder's layers with the given timestamp.
/// The original length is considered to be the actual size.
/// </summary>
/// <param name="timestamp">The packet's timestamp.</param>
/// <returns>A packet built from the builder's layers with the given timestamp.</returns>
public Packet Build(DateTime timestamp)
{
return Build(timestamp, 0);
}
private void WriteLayers(int[] layersLength, byte[] buffer, int 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