Commit c41e8e21 authored by Brickner_cp's avatar Brickner_cp

Added Extension Method for PacketCommunicator to work with IEnumerable (and LINQ).

parent ec2e5e6e
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
<CodeCoverageItem binaryFile="C:\TFS\tfs06.codeplex.com\PcapDotNet\PcapDotNet\bin\Debug\PcapDotNet.Base.dll" pdbFile="C:\TFS\tfs06.codeplex.com\PcapDotNet\PcapDotNet\bin\Debug\PcapDotNet.Base.pdb" instrumentInPlace="true" /> <CodeCoverageItem binaryFile="C:\TFS\tfs06.codeplex.com\PcapDotNet\PcapDotNet\bin\Debug\PcapDotNet.Base.dll" pdbFile="C:\TFS\tfs06.codeplex.com\PcapDotNet\PcapDotNet\bin\Debug\PcapDotNet.Base.pdb" instrumentInPlace="true" />
<CodeCoverageItem binaryFile="c:\TFS\tfs06.codeplex.com\PcapDotNet\PcapDotNet\bin\Debug\PcapDotNet.Core.dll" pdbFile="c:\TFS\tfs06.codeplex.com\PcapDotNet\PcapDotNet\bin\Debug\PcapDotNet.Core.pdb" instrumentInPlace="true" /> <CodeCoverageItem binaryFile="c:\TFS\tfs06.codeplex.com\PcapDotNet\PcapDotNet\bin\Debug\PcapDotNet.Core.dll" pdbFile="c:\TFS\tfs06.codeplex.com\PcapDotNet\PcapDotNet\bin\Debug\PcapDotNet.Core.pdb" instrumentInPlace="true" />
<CodeCoverageItem binaryFile="C:\TFS\tfs06.codeplex.com\PcapDotNet\PcapDotNet\bin\Debug\PcapDotNet.Packets.dll" pdbFile="C:\TFS\tfs06.codeplex.com\PcapDotNet\PcapDotNet\bin\Debug\PcapDotNet.Packets.pdb" instrumentInPlace="true" /> <CodeCoverageItem binaryFile="C:\TFS\tfs06.codeplex.com\PcapDotNet\PcapDotNet\bin\Debug\PcapDotNet.Packets.dll" pdbFile="C:\TFS\tfs06.codeplex.com\PcapDotNet\PcapDotNet\bin\Debug\PcapDotNet.Packets.pdb" instrumentInPlace="true" />
<CodeCoverageItem binaryFile="C:\TFS\tfs06.codeplex.com\PcapDotNet\PcapDotNet\bin\Debug\PcapDotNet.Core.Extensions.dll" pdbFile="C:\TFS\tfs06.codeplex.com\PcapDotNet\PcapDotNet\bin\Debug\PcapDotNet.Core.Extensions.pdb" instrumentInPlace="true" />
</Regular> </Regular>
</CodeCoverage> </CodeCoverage>
<TestTypeSpecific> <TestTypeSpecific>
......
...@@ -45,6 +45,25 @@ namespace PcapDotNet.Core.Extensions ...@@ -45,6 +45,25 @@ namespace PcapDotNet.Core.Extensions
break; break;
} }
} }
/// <summary>
/// Collect a group of packets.
/// Similar to ReceivePackets() except instead of calling a callback the packets are returned as an IEnumerable.
/// Loops until the IEnumerable break (or until an error occurs).
/// <seealso cref="PacketCommunicator.ReceivePackets"/>
/// <seealso cref="PacketCommunicator.ReceiveSomePackets"/>
/// </summary>
/// <param name="communicator">The PacketCommunicator to work on</param>
/// <returns>An IEnumerable of Packets to process.</returns>
/// <exception cref="System.InvalidOperationException">Thrown if the mode is not Capture or an error occurred.</exception>
/// <remarks>
/// <para>Only the first bytes of data from the packet might be in the received packet (which won't necessarily be the entire packet; to capture the entire packet, you will have to provide a value for snapshortLength in your call to PacketDevice.Open() that is sufficiently large to get all of the packet's data - a value of 65536 should be sufficient on most if not all networks).</para>
/// <para>If a break is called on the returned Enumerable, the packet that was handled while breaking the enumerable may not be the last packet read. More packets might be read. This is because this method actually loops over calls to ReceiveSomePackets()</para>
/// </remarks>
public static IEnumerable<Packet> ReceivePackets(this PacketCommunicator communicator)
{
return communicator.ReceivePackets(-1);
}
} }
} }
...@@ -4,6 +4,7 @@ using System.IO; ...@@ -4,6 +4,7 @@ using System.IO;
using System.Net; using System.Net;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using PcapDotNet.Core.Extensions;
using PcapDotNet.Packets; using PcapDotNet.Packets;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using PcapDotNet.Packets.TestUtils; using PcapDotNet.Packets.TestUtils;
...@@ -102,26 +103,26 @@ namespace PcapDotNet.Core.Test ...@@ -102,26 +103,26 @@ namespace PcapDotNet.Core.Test
} }
[TestMethod] [TestMethod]
public void GetSomePacketsTest() public void ReceiveSomePacketsTest()
{ {
const int NumPacketsToSend = 100; const int NumPacketsToSend = 100;
const int PacketSize = 100; const int PacketSize = 100;
// Test normal mode // Test normal mode
TestGetSomePackets(0, 0, int.MaxValue, PacketSize, false, PacketCommunicatorReceiveResult.Ok, 0, 1, 1.02); TestReceiveSomePackets(0, 0, int.MaxValue, PacketSize, false, PacketCommunicatorReceiveResult.Ok, 0, 1, 1.02);
TestGetSomePackets(NumPacketsToSend, NumPacketsToSend, int.MaxValue, PacketSize, false, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend, 0, 0.02); TestReceiveSomePackets(NumPacketsToSend, NumPacketsToSend, int.MaxValue, PacketSize, false, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend, 0, 0.02);
TestGetSomePackets(NumPacketsToSend, 0, int.MaxValue, PacketSize, false, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend, 0, 0.02); TestReceiveSomePackets(NumPacketsToSend, 0, int.MaxValue, PacketSize, false, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend, 0, 0.02);
TestGetSomePackets(NumPacketsToSend, -1, int.MaxValue, PacketSize, false, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend, 0, 0.02); TestReceiveSomePackets(NumPacketsToSend, -1, int.MaxValue, PacketSize, false, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend, 0, 0.02);
TestGetSomePackets(NumPacketsToSend, NumPacketsToSend + 1, int.MaxValue, PacketSize, false, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend, 0, 0.02); TestReceiveSomePackets(NumPacketsToSend, NumPacketsToSend + 1, int.MaxValue, PacketSize, false, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend, 0, 0.02);
// Test non blocking // Test non blocking
TestGetSomePackets(0, 0, int.MaxValue, PacketSize, true, PacketCommunicatorReceiveResult.Ok, 0, 0, 0.02); TestReceiveSomePackets(0, 0, int.MaxValue, PacketSize, true, PacketCommunicatorReceiveResult.Ok, 0, 0, 0.02);
TestGetSomePackets(NumPacketsToSend, NumPacketsToSend, int.MaxValue, PacketSize, true, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend, 0, 0.02); TestReceiveSomePackets(NumPacketsToSend, NumPacketsToSend, int.MaxValue, PacketSize, true, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend, 0, 0.02);
// Test break loop // Test break loop
TestGetSomePackets(NumPacketsToSend, NumPacketsToSend, NumPacketsToSend / 2, PacketSize, false, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend / 2, 0, 0.02); TestReceiveSomePackets(NumPacketsToSend, NumPacketsToSend, NumPacketsToSend / 2, PacketSize, false, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend / 2, 0, 0.02);
TestGetSomePackets(NumPacketsToSend, NumPacketsToSend, NumPacketsToSend / 2, PacketSize, true, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend / 2, 0, 0.02); TestReceiveSomePackets(NumPacketsToSend, NumPacketsToSend, NumPacketsToSend / 2, PacketSize, true, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend / 2, 0, 0.02);
TestGetSomePackets(NumPacketsToSend, NumPacketsToSend, 0, PacketSize, false, PacketCommunicatorReceiveResult.BreakLoop, 0, 0, 0.02); TestReceiveSomePackets(NumPacketsToSend, NumPacketsToSend, 0, PacketSize, false, PacketCommunicatorReceiveResult.BreakLoop, 0, 0, 0.02);
} }
[TestMethod] [TestMethod]
...@@ -146,6 +147,28 @@ namespace PcapDotNet.Core.Test ...@@ -146,6 +147,28 @@ namespace PcapDotNet.Core.Test
TestReceivePackets(NumPacketsToSend, NumPacketsToSend, NumPacketsToSend / 2, 2, PacketSize, PacketCommunicatorReceiveResult.BreakLoop, NumPacketsToSend / 2, 0, 0.02); TestReceivePackets(NumPacketsToSend, NumPacketsToSend, NumPacketsToSend / 2, 2, PacketSize, PacketCommunicatorReceiveResult.BreakLoop, NumPacketsToSend / 2, 0, 0.02);
} }
// [TestMethod]
// public void ReceivePacketsEnumerableTest()
// {
// const int NumPacketsToSend = 100;
// const int PacketSize = 100;
//
// // Normal
// TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend, int.MaxValue, 2, PacketSize, NumPacketsToSend, 0, 0.02);
//
// // Wait for less packets
// TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend / 2, int.MaxValue, 2, PacketSize, NumPacketsToSend / 2, 0, 0.02);
//
// // Wait for more packets
// TestReceivePacketsEnumerable(NumPacketsToSend, 0, int.MaxValue, 2, PacketSize, NumPacketsToSend, 2, 2.02);
// TestReceivePacketsEnumerable(NumPacketsToSend, -1, int.MaxValue, 2, PacketSize, NumPacketsToSend, 2, 2.02);
// TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend + 1, int.MaxValue, 2, PacketSize, NumPacketsToSend, 2, 2.02);
//
// // Break loop
// TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend, 0, 2, PacketSize, 0, 0, 0.02);
// TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend, NumPacketsToSend / 2, 2, PacketSize, NumPacketsToSend / 2, 0, 0.02);
// }
[TestMethod] [TestMethod]
[Timeout(10 * 1000)] [Timeout(10 * 1000)]
public void ReceivePacketsGcCollectTest() public void ReceivePacketsGcCollectTest()
...@@ -634,8 +657,8 @@ namespace PcapDotNet.Core.Test ...@@ -634,8 +657,8 @@ namespace PcapDotNet.Core.Test
} }
} }
private static void TestGetSomePackets(int numPacketsToSend, int numPacketsToGet, int numPacketsToBreakLoop, int packetSize, bool nonBlocking, private static void TestReceiveSomePackets(int numPacketsToSend, int numPacketsToGet, int numPacketsToBreakLoop, int packetSize, bool nonBlocking,
PacketCommunicatorReceiveResult expectedResult, int expectedNumPackets, double expectedMinSeconds, double expectedMaxSeconds) PacketCommunicatorReceiveResult expectedResult, int expectedNumPackets, double expectedMinSeconds, double expectedMaxSeconds)
{ {
string TestDescription = "NumPacketsToSend=" + numPacketsToSend + ". NumPacketsToGet=" + numPacketsToGet + string TestDescription = "NumPacketsToSend=" + numPacketsToSend + ". NumPacketsToGet=" + numPacketsToGet +
". NumPacketsToBreakLoop=" + numPacketsToBreakLoop + ". PacketSize=" + packetSize + ". NumPacketsToBreakLoop=" + numPacketsToBreakLoop + ". PacketSize=" + packetSize +
...@@ -717,6 +740,52 @@ namespace PcapDotNet.Core.Test ...@@ -717,6 +740,52 @@ namespace PcapDotNet.Core.Test
} }
} }
private static void TestReceivePacketsEnumerable(int numPacketsToSend, int numPacketsToWait, int numPacketsToBreakLoop, double secondsToWait,
int packetSize, int expectedNumPackets, double expectedMinSeconds, double expectedMaxSeconds)
{
string TestDescription = "NumPacketsToSend=" + numPacketsToSend + ". NumPacketsToWait=" + numPacketsToWait +
". NumPacketsToBreakLoop=" + numPacketsToBreakLoop + ". SecondsToWait=" +
secondsToWait + ". PacketSize=" + packetSize;
const string SourceMac = "11:22:33:44:55:66";
const string DestinationMac = "77:88:99:AA:BB:CC";
using (PacketCommunicator communicator = OpenLiveDevice())
{
communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac);
Packet sentPacket = _random.NextEthernetPacket(packetSize, SourceMac, DestinationMac);
for (int i = 0; i != numPacketsToSend; ++i)
communicator.SendPacket(sentPacket);
int actualPacketsReceived = 0;
Thread thread = new Thread(delegate()
{
if (numPacketsToBreakLoop == 0)
communicator.Break();
foreach (Packet packet in communicator.ReceivePackets(numPacketsToWait))
{
Assert.AreEqual(sentPacket, packet);
++actualPacketsReceived;
if (actualPacketsReceived == numPacketsToBreakLoop)
break;
}
});
DateTime startWaiting = DateTime.Now;
thread.Start();
if (!thread.Join(TimeSpan.FromSeconds(secondsToWait)))
thread.Abort();
DateTime finishedWaiting = DateTime.Now;
Assert.AreEqual(expectedNumPackets, actualPacketsReceived, TestDescription);
MoreAssert.IsInRange(expectedMinSeconds, expectedMaxSeconds, (finishedWaiting - startWaiting).TotalSeconds, TestDescription);
}
}
public static PacketCommunicator OpenLiveDevice() public static PacketCommunicator OpenLiveDevice()
{ {
IList<LivePacketDevice> devices = LivePacketDevice.AllLocalMachine; IList<LivePacketDevice> devices = LivePacketDevice.AllLocalMachine;
......
...@@ -66,6 +66,10 @@ ...@@ -66,6 +66,10 @@
<Project>{83E805C9-4D29-4E34-A27E-5A78690FBD2B}</Project> <Project>{83E805C9-4D29-4E34-A27E-5A78690FBD2B}</Project>
<Name>PcapDotNet.Base</Name> <Name>PcapDotNet.Base</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\PcapDotNet.Core.Extensions\PcapDotNet.Core.Extensions.csproj">
<Project>{322040C2-3DC1-4D0C-8E0F-F05290AFE023}</Project>
<Name>PcapDotNet.Core.Extensions</Name>
</ProjectReference>
<ProjectReference Include="..\PcapDotNet.Core\PcapDotNet.Core.vcproj"> <ProjectReference Include="..\PcapDotNet.Core\PcapDotNet.Core.vcproj">
<Project>{89C63BE1-AF9A-472E-B256-A4F56B1655A7}</Project> <Project>{89C63BE1-AF9A-472E-B256-A4F56B1655A7}</Project>
<Name>PcapDotNet.Core</Name> <Name>PcapDotNet.Core</Name>
......
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