Commit 937a67fb authored by Boaz Brickner's avatar Boaz Brickner

Merge pull request #60 from bricknerb/master

Add OriginalLength to Packet.
parents 6c3b1f0d 92d02194
......@@ -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